summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CODEOWNERS4
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md12
-rw-r--r--.github/actions/godot-build/action.yml2
-rw-r--r--.github/workflows/ios_builds.yml2
-rw-r--r--.github/workflows/linux_builds.yml12
-rw-r--r--.github/workflows/macos_builds.yml8
-rw-r--r--.github/workflows/windows_builds.yml2
-rw-r--r--SConstruct66
-rw-r--r--core/SCsub3
-rw-r--r--core/config/project_settings.cpp2
-rw-r--r--core/core_bind.cpp43
-rw-r--r--core/core_bind.h8
-rw-r--r--core/core_constants.cpp8
-rw-r--r--core/debugger/engine_debugger.cpp6
-rw-r--r--core/debugger/engine_debugger.h4
-rw-r--r--core/debugger/local_debugger.cpp7
-rw-r--r--core/debugger/remote_debugger.cpp21
-rw-r--r--core/debugger/remote_debugger.h3
-rw-r--r--core/doc_data.cpp4
-rw-r--r--core/doc_data.h3
-rw-r--r--core/error/error_macros.cpp8
-rw-r--r--core/extension/extension_api_dump.cpp6
-rw-r--r--core/extension/gdnative_interface.h13
-rw-r--r--core/extension/native_extension.cpp32
-rw-r--r--core/extension/native_extension.h2
-rw-r--r--core/input/gamecontrollerdb.txt367
-rw-r--r--core/input/input.cpp1
-rw-r--r--core/input/input.h2
-rw-r--r--core/input/input_builders.py4
-rw-r--r--core/input/input_event.cpp19
-rw-r--r--core/input/input_event.h4
-rw-r--r--core/io/dir_access.cpp21
-rw-r--r--core/io/dir_access.h1
-rw-r--r--core/io/file_access.cpp5
-rw-r--r--core/io/image.cpp145
-rw-r--r--core/io/image.h18
-rw-r--r--core/io/marshalls.cpp47
-rw-r--r--core/io/resource_format_binary.cpp26
-rw-r--r--core/io/resource_format_binary.h2
-rw-r--r--core/io/resource_importer.cpp10
-rw-r--r--core/io/resource_importer.h2
-rw-r--r--core/io/resource_loader.cpp28
-rw-r--r--core/io/resource_loader.h3
-rw-r--r--core/io/xml_parser.cpp46
-rw-r--r--core/io/xml_parser.h9
-rw-r--r--core/math/basis.cpp13
-rw-r--r--core/math/expression.cpp2
-rw-r--r--core/math/octree.h1271
-rw-r--r--core/math/plane.h6
-rw-r--r--core/multiplayer/multiplayer_api.cpp8
-rw-r--r--core/multiplayer/multiplayer_api.h6
-rw-r--r--core/object/class_db.cpp48
-rw-r--r--core/object/class_db.h32
-rw-r--r--core/object/object.cpp2
-rw-r--r--core/object/object.h93
-rw-r--r--core/object/script_language.h2
-rw-r--r--core/object/script_language_extension.cpp2
-rw-r--r--core/object/script_language_extension.h15
-rw-r--r--core/object/worker_thread_pool.cpp463
-rw-r--r--core/object/worker_thread_pool.h146
-rw-r--r--core/os/keyboard.cpp2
-rw-r--r--core/os/os.cpp15
-rw-r--r--core/os/os.h2
-rw-r--r--core/register_core_types.cpp21
-rw-r--r--core/string/node_path.cpp15
-rw-r--r--core/string/node_path.h2
-rw-r--r--core/string/print_string.cpp95
-rw-r--r--core/string/print_string.h12
-rw-r--r--core/string/ustring.cpp393
-rw-r--r--core/string/ustring.h7
-rw-r--r--core/templates/local_vector.h9
-rw-r--r--core/templates/lru.h5
-rw-r--r--core/templates/safe_refcount.h5
-rw-r--r--core/templates/vector.h3
-rw-r--r--core/variant/binder_common.h23
-rw-r--r--core/variant/callable.cpp2
-rw-r--r--core/variant/type_info.h46
-rw-r--r--core/variant/variant_call.cpp35
-rw-r--r--core/variant/variant_internal.h7
-rw-r--r--core/variant/variant_utility.cpp17
-rw-r--r--doc/class.xsd37
-rw-r--r--doc/classes/@GlobalScope.xml187
-rw-r--r--doc/classes/AcceptDialog.xml4
-rw-r--r--doc/classes/AnimationNode.xml4
-rw-r--r--doc/classes/AnimationNodeAdd2.xml7
-rw-r--r--doc/classes/AnimationNodeAdd3.xml7
-rw-r--r--doc/classes/AnimationNodeBlend2.xml7
-rw-r--r--doc/classes/AnimationNodeBlend3.xml7
-rw-r--r--doc/classes/AnimationNodeBlendSpace1D.xml4
-rw-r--r--doc/classes/AnimationNodeBlendSpace2D.xml4
-rw-r--r--doc/classes/AnimationNodeOneShot.xml4
-rw-r--r--doc/classes/AnimationNodeStateMachineTransition.xml6
-rw-r--r--doc/classes/AnimationNodeSync.xml15
-rw-r--r--doc/classes/AnimationNodeTransition.xml5
-rw-r--r--doc/classes/AnimationTree.xml3
-rw-r--r--doc/classes/AudioStreamPlayer.xml1
-rw-r--r--doc/classes/AudioStreamPlayer2D.xml1
-rw-r--r--doc/classes/AudioStreamPlayer3D.xml1
-rw-r--r--doc/classes/BoneMap.xml56
-rw-r--r--doc/classes/Button.xml23
-rw-r--r--doc/classes/Camera3D.xml1
-rw-r--r--doc/classes/CanvasItem.xml78
-rw-r--r--doc/classes/CodeEdit.xml3
-rw-r--r--doc/classes/ColorPicker.xml25
-rw-r--r--doc/classes/ConfirmationDialog.xml3
-rw-r--r--doc/classes/Control.xml4
-rw-r--r--doc/classes/Decal.xml8
-rw-r--r--doc/classes/EditorExportPlugin.xml2
-rw-r--r--doc/classes/EditorFileDialog.xml6
-rw-r--r--doc/classes/EditorPlugin.xml22
-rw-r--r--doc/classes/EditorScenePostImportPlugin.xml6
-rw-r--r--doc/classes/FileDialog.xml10
-rw-r--r--doc/classes/Font.xml299
-rw-r--r--doc/classes/FontFile.xml (renamed from doc/classes/FontData.xml)254
-rw-r--r--doc/classes/FontVariation.xml76
-rw-r--r--doc/classes/GraphNode.xml21
-rw-r--r--doc/classes/HTTPRequest.xml4
-rw-r--r--doc/classes/Image.xml44
-rw-r--r--doc/classes/ImageTexture.xml26
-rw-r--r--doc/classes/Input.xml1
-rw-r--r--doc/classes/InputEventMouseMotion.xml4
-rw-r--r--doc/classes/ItemList.xml24
-rw-r--r--doc/classes/Label.xml26
-rw-r--r--doc/classes/Label3D.xml25
-rw-r--r--doc/classes/LabelSettings.xml39
-rw-r--r--doc/classes/Light3D.xml1
-rw-r--r--doc/classes/LightmapGI.xml2
-rw-r--r--doc/classes/LightmapGIData.xml2
-rw-r--r--doc/classes/LineEdit.xml21
-rw-r--r--doc/classes/LinkButton.xml23
-rw-r--r--doc/classes/MovieWriter.xml2
-rw-r--r--doc/classes/MultiMesh.xml3
-rw-r--r--doc/classes/MultiplayerSpawner.xml2
-rw-r--r--doc/classes/MultiplayerSynchronizer.xml52
-rw-r--r--doc/classes/Node3D.xml7
-rw-r--r--doc/classes/NodePath.xml6
-rw-r--r--doc/classes/PackedByteArray.xml10
-rw-r--r--doc/classes/ParticlesMaterial.xml45
-rw-r--r--doc/classes/Plane.xml6
-rw-r--r--doc/classes/PopupMenu.xml24
-rw-r--r--doc/classes/ProjectSettings.xml55
-rw-r--r--doc/classes/RenderingDevice.xml2
-rw-r--r--doc/classes/RenderingServer.xml79
-rw-r--r--doc/classes/ResourceFormatLoader.xml6
-rw-r--r--doc/classes/ResourceLoader.xml17
-rw-r--r--doc/classes/ResourceSaver.xml34
-rw-r--r--doc/classes/RichTextLabel.xml8
-rw-r--r--doc/classes/SceneTree.xml3
-rw-r--r--doc/classes/ScriptCreateDialog.xml1
-rw-r--r--doc/classes/ScriptLanguageExtension.xml9
-rw-r--r--doc/classes/SkeletonProfile.xml185
-rw-r--r--doc/classes/SkeletonProfileHumanoid.xml14
-rw-r--r--doc/classes/SpriteFrames.xml5
-rw-r--r--doc/classes/String.xml17
-rw-r--r--doc/classes/StyleBox.xml4
-rw-r--r--doc/classes/TabBar.xml24
-rw-r--r--doc/classes/TextEdit.xml26
-rw-r--r--doc/classes/TextLine.xml13
-rw-r--r--doc/classes/TextMesh.xml25
-rw-r--r--doc/classes/TextParagraph.xml35
-rw-r--r--doc/classes/TextServer.xml117
-rw-r--r--doc/classes/TextServerExtension.xml52
-rw-r--r--doc/classes/Theme.xml11
-rw-r--r--doc/classes/TileSet.xml2
-rw-r--r--doc/classes/Tree.xml24
-rw-r--r--doc/classes/TreeItem.xml32
-rw-r--r--doc/classes/Tween.xml40
-rw-r--r--doc/classes/VehicleBody3D.xml2
-rw-r--r--doc/classes/VehicleWheel3D.xml2
-rw-r--r--doc/classes/VideoStreamPlayer.xml2
-rw-r--r--doc/classes/Viewport.xml94
-rw-r--r--doc/classes/VoxelGI.xml1
-rw-r--r--doc/classes/WorkerThreadPool.xml53
-rw-r--r--doc/classes/XMLParser.xml2
-rw-r--r--doc/classes/XRCamera3D.xml2
-rw-r--r--doc/classes/XRController3D.xml2
-rw-r--r--doc/classes/XRInterface.xml2
-rw-r--r--doc/classes/XRInterfaceExtension.xml5
-rw-r--r--doc/classes/XROrigin3D.xml2
-rw-r--r--doc/classes/XRPositionalTracker.xml2
-rw-r--r--doc/classes/XRServer.xml2
-rwxr-xr-xdoc/tools/make_rst.py65
-rw-r--r--doc/translations/ar.po568
-rw-r--r--doc/translations/ca.po564
-rw-r--r--doc/translations/classes.pot554
-rw-r--r--doc/translations/cs.po571
-rw-r--r--doc/translations/de.po618
-rw-r--r--doc/translations/el.po568
-rw-r--r--doc/translations/es.po626
-rw-r--r--doc/translations/fa.po572
-rw-r--r--doc/translations/fi.po568
-rw-r--r--doc/translations/fil.po564
-rw-r--r--doc/translations/fr.po4113
-rw-r--r--doc/translations/gl.po564
-rw-r--r--doc/translations/hi.po564
-rw-r--r--doc/translations/hu.po564
-rw-r--r--doc/translations/id.po576
-rw-r--r--doc/translations/is.po564
-rw-r--r--doc/translations/it.po571
-rw-r--r--doc/translations/ja.po579
-rw-r--r--doc/translations/ko.po579
-rw-r--r--doc/translations/lt.po564
-rw-r--r--doc/translations/lv.po564
-rw-r--r--doc/translations/mr.po564
-rw-r--r--doc/translations/nb.po564
-rw-r--r--doc/translations/ne.po564
-rw-r--r--doc/translations/nl.po564
-rw-r--r--doc/translations/pl.po570
-rw-r--r--doc/translations/pt.po782
-rw-r--r--doc/translations/pt_BR.po575
-rw-r--r--doc/translations/ro.po564
-rw-r--r--doc/translations/ru.po687
-rw-r--r--doc/translations/sk.po564
-rw-r--r--doc/translations/sr_Cyrl.po564
-rw-r--r--doc/translations/sv.po564
-rw-r--r--doc/translations/th.po567
-rw-r--r--doc/translations/tl.po567
-rw-r--r--doc/translations/tr.po591
-rw-r--r--doc/translations/uk.po568
-rw-r--r--doc/translations/vi.po568
-rw-r--r--doc/translations/zh_CN.po9939
-rw-r--r--doc/translations/zh_TW.po568
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp20
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h6
-rw-r--r--drivers/gl_context/SCsub2
-rw-r--r--drivers/gles3/environment/fog.cpp66
-rw-r--r--drivers/gles3/environment/fog.h62
-rw-r--r--drivers/gles3/environment/gi.cpp7
-rw-r--r--drivers/gles3/environment/gi.h3
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp5
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h5
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp18
-rw-r--r--drivers/gles3/rasterizer_gles3.h9
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp55
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h18
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp569
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h266
-rw-r--r--drivers/gles3/shaders/SCsub2
-rw-r--r--drivers/gles3/storage/light_storage.cpp120
-rw-r--r--drivers/gles3/storage/light_storage.h25
-rw-r--r--drivers/gles3/storage/material_storage.cpp11
-rw-r--r--drivers/gles3/storage/material_storage.h48
-rw-r--r--drivers/gles3/storage/mesh_storage.cpp49
-rw-r--r--drivers/gles3/storage/mesh_storage.h13
-rw-r--r--drivers/gles3/storage/texture_storage.cpp55
-rw-r--r--drivers/gles3/storage/texture_storage.h29
-rw-r--r--drivers/gles3/storage/utilities.cpp353
-rw-r--r--drivers/gles3/storage/utilities.h159
-rw-r--r--drivers/unix/dir_access_unix.cpp25
-rw-r--r--drivers/unix/dir_access_unix.h4
-rw-r--r--drivers/unix/file_access_unix.cpp4
-rw-r--r--drivers/unix/file_access_unix.h1
-rw-r--r--drivers/unix/os_unix.cpp9
-rw-r--r--drivers/vulkan/SCsub8
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp640
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h29
-rw-r--r--drivers/vulkan/vulkan_context.cpp310
-rw-r--r--drivers/vulkan/vulkan_context.h23
-rw-r--r--editor/action_map_editor.cpp2
-rw-r--r--editor/animation_bezier_editor.cpp2
-rw-r--r--editor/animation_track_editor.cpp106
-rw-r--r--editor/animation_track_editor.h4
-rw-r--r--editor/code_editor.cpp98
-rw-r--r--editor/connections_dialog.cpp4
-rw-r--r--editor/create_dialog.cpp4
-rw-r--r--editor/debugger/editor_debugger_tree.cpp2
-rw-r--r--editor/debugger/editor_performance_profiler.cpp6
-rw-r--r--editor/debugger/editor_profiler.cpp2
-rw-r--r--editor/debugger/editor_visual_profiler.cpp10
-rw-r--r--editor/debugger/script_editor_debugger.cpp12
-rw-r--r--editor/dependency_editor.cpp8
-rw-r--r--editor/doc_tools.cpp66
-rw-r--r--editor/editor_asset_installer.cpp2
-rw-r--r--editor/editor_audio_buses.cpp4
-rw-r--r--editor/editor_build_profile.cpp797
-rw-r--r--editor/editor_build_profile.h173
-rw-r--r--editor/editor_data.cpp1
-rw-r--r--editor/editor_dir_dialog.cpp2
-rw-r--r--editor/editor_export.cpp14
-rw-r--r--editor/editor_export.h8
-rw-r--r--editor/editor_feature_profile.cpp6
-rw-r--r--editor/editor_file_dialog.cpp34
-rw-r--r--editor/editor_file_dialog.h2
-rw-r--r--editor/editor_file_system.cpp6
-rw-r--r--editor/editor_fonts.cpp543
-rw-r--r--editor/editor_help.cpp275
-rw-r--r--editor/editor_help.h3
-rw-r--r--editor/editor_help_search.cpp2
-rw-r--r--editor/editor_inspector.cpp62
-rw-r--r--editor/editor_inspector.h13
-rw-r--r--editor/editor_locale_dialog.cpp2
-rw-r--r--editor/editor_log.cpp22
-rw-r--r--editor/editor_log.h1
-rw-r--r--editor/editor_node.cpp273
-rw-r--r--editor/editor_node.h9
-rw-r--r--editor/editor_path.cpp2
-rw-r--r--editor/editor_plugin.cpp3
-rw-r--r--editor/editor_properties.cpp107
-rw-r--r--editor/editor_properties.h27
-rw-r--r--editor/editor_properties_array_dict.cpp9
-rw-r--r--editor/editor_resource_picker.cpp18
-rw-r--r--editor/editor_resource_preview.cpp6
-rw-r--r--editor/editor_run.cpp7
-rw-r--r--editor/editor_run_native.cpp4
-rw-r--r--editor/editor_settings.cpp14
-rw-r--r--editor/editor_settings.h2
-rw-r--r--editor/editor_settings_dialog.cpp2
-rw-r--r--editor/editor_spin_slider.cpp11
-rw-r--r--editor/editor_themes.cpp32
-rw-r--r--editor/export_template_manager.cpp16
-rw-r--r--editor/filesystem_dock.cpp8
-rw-r--r--editor/find_in_files.cpp4
-rw-r--r--editor/groups_editor.cpp6
-rw-r--r--editor/icons/BoneMapHumanBody.svg1
-rw-r--r--editor/icons/BoneMapHumanFace.svg1
-rw-r--r--editor/icons/BoneMapHumanLeftHand.svg1
-rw-r--r--editor/icons/BoneMapHumanRightHand.svg1
-rw-r--r--editor/icons/BoneMapperHandle.svg1
-rw-r--r--editor/icons/BoneMapperHandleCircle.svg1
-rw-r--r--editor/icons/BoneMapperHandleSelected.svg1
-rw-r--r--editor/icons/CodeFoldDownArrow.svg1
-rw-r--r--editor/icons/CodeFoldedRightArrow.svg1
-rw-r--r--editor/icons/ControlAlignFullRect.svg (renamed from editor/icons/ControlAlignWide.svg)0
-rw-r--r--editor/icons/CopyNodePath.svg2
-rw-r--r--editor/icons/Font.svg2
-rw-r--r--editor/icons/FontData.svg1
-rw-r--r--editor/icons/FontFile.svg1
-rw-r--r--editor/icons/FontVariation.svg1
-rw-r--r--editor/icons/LabelSettings.svg1
-rw-r--r--editor/icons/MainMovieWriteEnabled.svg1
-rw-r--r--editor/icons/TextEditorPlay.svg1
-rw-r--r--editor/import/dynamic_font_import_settings.cpp1018
-rw-r--r--editor/import/dynamic_font_import_settings.h90
-rw-r--r--editor/import/post_import_plugin_skeleton_renamer.cpp178
-rw-r--r--editor/import/post_import_plugin_skeleton_renamer.h46
-rw-r--r--editor/import/post_import_plugin_skeleton_rest_fixer.cpp418
-rw-r--r--editor/import/post_import_plugin_skeleton_rest_fixer.h46
-rw-r--r--editor/import/resource_importer_bmfont.cpp12
-rw-r--r--editor/import/resource_importer_dynamic_font.cpp193
-rw-r--r--editor/import/resource_importer_dynamic_font.h3
-rw-r--r--editor/import/resource_importer_imagefont.cpp15
-rw-r--r--editor/import/resource_importer_layered_texture.cpp2
-rw-r--r--editor/import/resource_importer_scene.cpp94
-rw-r--r--editor/import/resource_importer_scene.h4
-rw-r--r--editor/import/resource_importer_texture_atlas.cpp20
-rw-r--r--editor/import/resource_importer_wav.cpp64
-rw-r--r--editor/import/scene_import_settings.cpp60
-rw-r--r--editor/import/scene_import_settings.h1
-rw-r--r--editor/import_dock.cpp2
-rw-r--r--editor/inspector_dock.cpp4
-rw-r--r--editor/plugin_config_dialog.cpp2
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp4
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.cpp28
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.h2
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp46
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.h1
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp10
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp8
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp62
-rw-r--r--editor/plugins/asset_library_editor_plugin.h5
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp4
-rw-r--r--editor/plugins/bit_map_editor_plugin.cpp6
-rw-r--r--editor/plugins/bone_map_editor_plugin.cpp454
-rw-r--r--editor/plugins/bone_map_editor_plugin.h179
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp250
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h11
-rw-r--r--editor/plugins/control_editor_plugin.cpp36
-rw-r--r--editor/plugins/control_editor_plugin.h6
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/curve_editor_plugin.cpp11
-rw-r--r--editor/plugins/debugger_editor_plugin.cpp13
-rw-r--r--editor/plugins/debugger_editor_plugin.h1
-rw-r--r--editor/plugins/editor_preview_plugins.cpp75
-rw-r--r--editor/plugins/font_config_plugin.cpp979
-rw-r--r--editor/plugins/font_config_plugin.h261
-rw-r--r--editor/plugins/font_editor_plugin.cpp106
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.cpp19
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.cpp14
-rw-r--r--editor/plugins/gradient_editor_plugin.cpp1
-rw-r--r--editor/plugins/gradient_texture_2d_editor_plugin.cpp10
-rw-r--r--editor/plugins/lightmap_gi_editor_plugin.cpp2
-rw-r--r--editor/plugins/material_editor_plugin.cpp6
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp2
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp4
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp1
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp132
-rw-r--r--editor/plugins/node_3d_editor_plugin.h5
-rw-r--r--editor/plugins/occluder_instance_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/ot_features_plugin.cpp235
-rw-r--r--editor/plugins/ot_features_plugin.h102
-rw-r--r--editor/plugins/replication_editor_plugin.cpp4
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp12
-rw-r--r--editor/plugins/script_text_editor.cpp23
-rw-r--r--editor/plugins/shader_editor_plugin.cpp20
-rw-r--r--editor/plugins/shader_editor_plugin.h1
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp78
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.h3
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.cpp8
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp36
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h3
-rw-r--r--editor/plugins/style_box_editor_plugin.cpp2
-rw-r--r--editor/plugins/text_control_editor_plugin.cpp660
-rw-r--r--editor/plugins/text_control_editor_plugin.h115
-rw-r--r--editor/plugins/text_editor.cpp2
-rw-r--r--editor/plugins/texture_editor_plugin.cpp54
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp2
-rw-r--r--editor/plugins/theme_editor_plugin.cpp54
-rw-r--r--editor/plugins/theme_editor_plugin.h1
-rw-r--r--editor/plugins/theme_editor_preview.cpp4
-rw-r--r--editor/plugins/tiles/atlas_merging_dialog.cpp8
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp12
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp21
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp2
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp8
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp5
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp127
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h18
-rw-r--r--editor/progress_dialog.cpp4
-rw-r--r--editor/project_converter_3_to_4.cpp124
-rw-r--r--editor/project_export.cpp19
-rw-r--r--editor/project_manager.cpp53
-rw-r--r--editor/project_settings_editor.cpp2
-rw-r--r--editor/property_editor.cpp24
-rw-r--r--editor/property_selector.cpp2
-rw-r--r--editor/quick_open.cpp2
-rw-r--r--editor/rename_dialog.cpp2
-rw-r--r--editor/reparent_dialog.cpp2
-rw-r--r--editor/scene_create_dialog.cpp4
-rw-r--r--editor/scene_tree_dock.cpp8
-rw-r--r--editor/scene_tree_editor.cpp8
-rw-r--r--editor/scene_tree_editor.h1
-rw-r--r--editor/script_create_dialog.cpp8
-rw-r--r--editor/shader_create_dialog.cpp12
-rw-r--r--editor/translations/af.po172
-rw-r--r--editor/translations/ar.po568
-rw-r--r--editor/translations/az.po167
-rw-r--r--editor/translations/bg.po175
-rw-r--r--editor/translations/bn.po189
-rw-r--r--editor/translations/br.po162
-rw-r--r--editor/translations/ca.po322
-rw-r--r--editor/translations/cs.po183
-rw-r--r--editor/translations/da.po176
-rw-r--r--editor/translations/de.po625
-rw-r--r--editor/translations/editor.pot153
-rw-r--r--editor/translations/el.po183
-rw-r--r--editor/translations/en_Shaw.po162
-rw-r--r--editor/translations/eo.po174
-rw-r--r--editor/translations/es.po224
-rw-r--r--editor/translations/es_AR.po225
-rw-r--r--editor/translations/et.po176
-rw-r--r--editor/translations/eu.po169
-rw-r--r--editor/translations/fa.po193
-rw-r--r--editor/translations/fi.po188
-rw-r--r--editor/translations/fil.po161
-rw-r--r--editor/translations/fr.po1908
-rw-r--r--editor/translations/ga.po164
-rw-r--r--editor/translations/gl.po180
-rw-r--r--editor/translations/he.po181
-rw-r--r--editor/translations/hi.po172
-rw-r--r--editor/translations/hr.po172
-rw-r--r--editor/translations/hu.po177
-rw-r--r--editor/translations/id.po196
-rw-r--r--editor/translations/is.po165
-rw-r--r--editor/translations/it.po277
-rw-r--r--editor/translations/ja.po185
-rw-r--r--editor/translations/ka.po172
-rw-r--r--editor/translations/km.po155
-rw-r--r--editor/translations/ko.po195
-rw-r--r--editor/translations/lt.po172
-rw-r--r--editor/translations/lv.po172
-rw-r--r--editor/translations/mk.po230
-rw-r--r--editor/translations/ml.po155
-rw-r--r--editor/translations/mr.po162
-rw-r--r--editor/translations/ms.po172
-rw-r--r--editor/translations/nb.po172
-rw-r--r--editor/translations/nl.po183
-rw-r--r--editor/translations/pl.po246
-rw-r--r--editor/translations/pr.po172
-rw-r--r--editor/translations/pt.po1801
-rw-r--r--editor/translations/pt_BR.po531
-rw-r--r--editor/translations/ro.po173
-rw-r--r--editor/translations/ru.po230
-rw-r--r--editor/translations/si.po162
-rw-r--r--editor/translations/sk.po172
-rw-r--r--editor/translations/sl.po208
-rw-r--r--editor/translations/sq.po172
-rw-r--r--editor/translations/sr_Cyrl.po184
-rw-r--r--editor/translations/sr_Latn.po169
-rw-r--r--editor/translations/sv.po172
-rw-r--r--editor/translations/te.po157
-rw-r--r--editor/translations/th.po182
-rw-r--r--editor/translations/tl.po176
-rw-r--r--editor/translations/tr.po211
-rw-r--r--editor/translations/uk.po280
-rw-r--r--editor/translations/ur_PK.po172
-rw-r--r--editor/translations/vi.po173
-rw-r--r--editor/translations/zh_CN.po215
-rw-r--r--editor/translations/zh_HK.po176
-rw-r--r--editor/translations/zh_TW.po2345
-rw-r--r--main/main.cpp87
-rw-r--r--methods.py10
-rw-r--r--misc/dist/ios_xcode/libgodot.ios.debug.xcframework/Info.plist (renamed from misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist)0
-rw-r--r--misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64/empty (renamed from misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty)0
-rw-r--r--misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/empty (renamed from misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty)0
-rw-r--r--misc/dist/ios_xcode/libgodot.ios.release.xcframework/Info.plist (renamed from misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist)0
-rw-r--r--misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64/empty (renamed from misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty)0
-rw-r--r--misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/empty (renamed from misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty)0
-rw-r--r--misc/dist/macos/editor.entitlements (renamed from misc/dist/osx/editor.entitlements)0
-rw-r--r--misc/dist/macos_template.app/Contents/Info.plist (renamed from misc/dist/osx_template.app/Contents/Info.plist)0
-rw-r--r--misc/dist/macos_template.app/Contents/PkgInfo (renamed from misc/dist/osx_template.app/Contents/PkgInfo)0
-rw-r--r--misc/dist/macos_template.app/Contents/Resources/icon.icns (renamed from misc/dist/osx_template.app/Contents/Resources/icon.icns)bin67500 -> 67500 bytes
-rw-r--r--misc/dist/macos_tools.app/Contents/Info.plist (renamed from misc/dist/osx_tools.app/Contents/Info.plist)0
-rw-r--r--misc/dist/macos_tools.app/Contents/PkgInfo (renamed from misc/dist/osx_tools.app/Contents/PkgInfo)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/GDScript.icns (renamed from misc/dist/osx_tools.app/Contents/Resources/GDScript.icns)bin185973 -> 185973 bytes
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/Godot.icns (renamed from misc/dist/osx_tools.app/Contents/Resources/Godot.icns)bin271163 -> 271163 bytes
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/Project.icns (renamed from misc/dist/osx_tools.app/Contents/Resources/Project.icns)bin208221 -> 208221 bytes
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/Resource.icns (renamed from misc/dist/osx_tools.app/Contents/Resources/Resource.icns)bin176973 -> 176973 bytes
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/Scene.icns (renamed from misc/dist/osx_tools.app/Contents/Resources/Scene.icns)bin150612 -> 150612 bytes
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/Shader.icns (renamed from misc/dist/osx_tools.app/Contents/Resources/Shader.icns)bin162062 -> 162062 bytes
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/af.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/af.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/az.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/az.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/br.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/br.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/da.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/da.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/de.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/de.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/el.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/el.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/en.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/en.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/es.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/es.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/et.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/et.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/he.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/he.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/id.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/id.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/is.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/is.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/it.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/it.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/km.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/km.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/or.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/or.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/si.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/si.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/te.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/te.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/th.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/th.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/macos_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings (renamed from misc/dist/osx_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings)0
-rw-r--r--misc/dist/osx_template.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json7
-rw-r--r--misc/dist/osx_tools.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json7
-rwxr-xr-xmisc/scripts/install_vulkan_sdk_macos.sh14
-rw-r--r--modules/camera/SCsub4
-rw-r--r--modules/camera/camera_macos.h (renamed from modules/camera/camera_osx.h)12
-rw-r--r--modules/camera/camera_macos.mm (renamed from modules/camera/camera_osx.mm)36
-rw-r--r--modules/camera/config.py2
-rw-r--r--modules/camera/register_types.cpp8
-rw-r--r--modules/dds/texture_loader_dds.cpp4
-rw-r--r--modules/denoise/config.py2
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml159
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp48
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.h4
-rw-r--r--modules/gdscript/gdscript.cpp12
-rw-r--r--modules/gdscript/gdscript.h1
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp63
-rw-r--r--modules/gdscript/gdscript_cache.cpp2
-rw-r--r--modules/gdscript/gdscript_compiler.cpp41
-rw-r--r--modules/gdscript/gdscript_editor.cpp45
-rw-r--r--modules/gdscript/gdscript_parser.cpp343
-rw-r--r--modules/gdscript/gdscript_parser.h39
-rw-r--r--modules/gdscript/gdscript_vm.cpp8
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp4
-rw-r--r--modules/gdscript/tests/gdscript_test_runner.cpp2
-rw-r--r--modules/gdscript/tests/gdscript_test_runner.h2
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.gd4
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/variable_conflicts_for_variable.gd4
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/variable_conflicts_for_variable.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/variable_conflicts_variable.gd3
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/variable_conflicts_variable.out2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.gd19
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out7
-rw-r--r--modules/glslang/register_types.cpp34
-rw-r--r--modules/gltf/editor/editor_scene_importer_blend.cpp8
-rw-r--r--modules/gltf/gltf_document.cpp37
-rw-r--r--modules/gridmap/editor/grid_map_editor_plugin.cpp2
-rw-r--r--modules/lightmapper_rd/SCsub4
-rw-r--r--modules/lightmapper_rd/lightmapper_rd.cpp6
-rw-r--r--modules/minimp3/doc_classes/AudioStreamMP3.xml25
-rw-r--r--modules/mobile_vr/mobile_vr_interface.cpp2
-rw-r--r--modules/mono/SCsub2
-rw-r--r--modules/mono/build_scripts/make_android_mono_config.py2
-rw-r--r--modules/mono/build_scripts/mono_configure.py16
-rw-r--r--modules/mono/config.py4
-rw-r--r--modules/mono/csharp_script.cpp39
-rw-r--r--modules/mono/csharp_script.h3
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs3
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs4
-rw-r--r--modules/mono/editor/bindings_generator.cpp22
-rw-r--r--modules/mono/editor/bindings_generator.h1
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp16
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs43
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs16
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs24
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs22
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs18
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs28
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs28
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj2
-rw-r--r--modules/mono/glue/gd_glue.cpp22
-rw-r--r--modules/mono/glue/nodepath_glue.cpp5
-rw-r--r--modules/mono/godotsharp_dirs.cpp4
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp8
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h7
-rw-r--r--modules/mono/mono_gd/gd_mono_log.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_method_thunk.h2
-rw-r--r--modules/mono/mono_gd/support/ios_support.h4
-rw-r--r--modules/mono/mono_gd/support/ios_support.mm4
-rw-r--r--modules/mono/utils/macos_utils.cpp (renamed from modules/mono/utils/osx_utils.cpp)8
-rw-r--r--modules/mono/utils/macos_utils.h (renamed from modules/mono/utils/osx_utils.h)12
-rw-r--r--modules/mono/utils/path_utils.cpp12
-rw-r--r--modules/mono/utils/string_utils.cpp2
-rw-r--r--modules/noise/editor/noise_editor_plugin.cpp2
-rw-r--r--modules/openxr/SCsub6
-rw-r--r--modules/openxr/doc_classes/OpenXRInterface.xml4
-rw-r--r--modules/openxr/extensions/openxr_vulkan_extension.cpp2
-rw-r--r--modules/svg/image_loader_svg.cpp4
-rw-r--r--modules/text_server_adv/SCsub24
-rw-r--r--modules/text_server_adv/gdextension_build/SConstruct34
-rw-r--r--modules/text_server_adv/gdextension_build/methods.py2
-rw-r--r--modules/text_server_adv/gdextension_build/text_server_adv.gdextension4
-rw-r--r--modules/text_server_adv/text_server_adv.cpp989
-rw-r--r--modules/text_server_adv/text_server_adv.h71
-rw-r--r--modules/text_server_fb/gdextension_build/SConstruct10
-rw-r--r--modules/text_server_fb/gdextension_build/methods.py2
-rw-r--r--modules/text_server_fb/gdextension_build/text_server_fb.gdextension4
-rw-r--r--modules/text_server_fb/text_server_fb.cpp377
-rw-r--r--modules/text_server_fb/text_server_fb.h50
-rw-r--r--modules/theora/video_stream_theora.cpp2
-rw-r--r--modules/visual_script/editor/visual_script_editor.cpp26
-rw-r--r--modules/visual_script/editor/visual_script_property_selector.cpp2
-rw-r--r--modules/visual_script/visual_script.cpp3
-rw-r--r--modules/visual_script/visual_script.h1
-rw-r--r--modules/webrtc/webrtc_peer_connection_js.cpp2
-rw-r--r--modules/webrtc/webrtc_peer_connection_js.h2
-rw-r--r--platform/android/SCsub1
-rw-r--r--platform/android/detect.py8
-rw-r--r--platform/android/dir_access_jandroid.cpp304
-rw-r--r--platform/android/dir_access_jandroid.h72
-rw-r--r--platform/android/export/export_plugin.cpp124
-rw-r--r--platform/android/export/export_plugin.h4
-rw-r--r--platform/android/export/gradle_export_util.cpp4
-rw-r--r--platform/android/export/gradle_export_util.h2
-rw-r--r--platform/android/file_access_android.cpp12
-rw-r--r--platform/android/file_access_android.h8
-rw-r--r--platform/android/file_access_filesystem_jandroid.cpp283
-rw-r--r--platform/android/file_access_filesystem_jandroid.h97
-rw-r--r--platform/android/java/app/config.gradle6
-rw-r--r--platform/android/java/editor/build.gradle3
-rw-r--r--platform/android/java/editor/src/main/AndroidManifest.xml8
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt52
-rw-r--r--platform/android/java/editor/src/main/res/values/strings.xml2
-rw-r--r--platform/android/java/lib/AndroidManifest.xml2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java96
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java17
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt114
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt177
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt224
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt230
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt186
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessFlags.kt87
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt202
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/FileData.kt93
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/file/MediaStoreData.kt284
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java55
-rw-r--r--platform/android/java_godot_lib_jni.cpp15
-rw-r--r--platform/android/java_godot_lib_jni.h2
-rw-r--r--platform/android/os_android.cpp32
-rw-r--r--platform/android/os_android.h2
-rw-r--r--platform/ios/SCsub (renamed from platform/iphone/SCsub)18
-rw-r--r--platform/ios/api/api.cpp (renamed from platform/iphone/api/api.cpp)10
-rw-r--r--platform/ios/api/api.h (renamed from platform/iphone/api/api.h)12
-rw-r--r--platform/ios/app_delegate.h (renamed from platform/iphone/app_delegate.h)0
-rw-r--r--platform/ios/app_delegate.mm (renamed from platform/iphone/app_delegate.mm)18
-rw-r--r--platform/ios/detect.py (renamed from platform/iphone/detect.py)34
-rw-r--r--platform/ios/device_metrics.h (renamed from platform/iphone/device_metrics.h)0
-rw-r--r--platform/ios/device_metrics.m (renamed from platform/iphone/device_metrics.m)0
-rw-r--r--platform/ios/display_layer.h (renamed from platform/iphone/display_layer.h)0
-rw-r--r--platform/ios/display_layer.mm (renamed from platform/iphone/display_layer.mm)4
-rw-r--r--platform/ios/display_server_ios.h (renamed from platform/iphone/display_server_iphone.h)24
-rw-r--r--platform/ios/display_server_ios.mm (renamed from platform/iphone/display_server_iphone.mm)197
-rw-r--r--platform/ios/export/export.cpp (renamed from platform/iphone/export/export.cpp)2
-rw-r--r--platform/ios/export/export.h (renamed from platform/osx/export/export.h)8
-rw-r--r--platform/ios/export/export_plugin.cpp (renamed from platform/iphone/export/export_plugin.cpp)26
-rw-r--r--platform/ios/export/export_plugin.h (renamed from platform/iphone/export/export_plugin.h)6
-rw-r--r--platform/ios/export/godot_plugin_config.cpp (renamed from platform/iphone/export/godot_plugin_config.cpp)0
-rw-r--r--platform/ios/export/godot_plugin_config.h (renamed from platform/iphone/export/godot_plugin_config.h)4
-rw-r--r--platform/ios/godot_app_delegate.h (renamed from platform/iphone/godot_app_delegate.h)0
-rw-r--r--platform/ios/godot_app_delegate.m (renamed from platform/iphone/godot_app_delegate.m)0
-rw-r--r--platform/ios/godot_ios.mm (renamed from platform/iphone/godot_iphone.mm)23
-rw-r--r--platform/ios/godot_view.h (renamed from platform/iphone/godot_view.h)0
-rw-r--r--platform/ios/godot_view.mm (renamed from platform/iphone/godot_view.mm)46
-rw-r--r--platform/ios/godot_view_gesture_recognizer.h (renamed from platform/iphone/godot_view_gesture_recognizer.h)0
-rw-r--r--platform/ios/godot_view_gesture_recognizer.mm (renamed from platform/iphone/godot_view_gesture_recognizer.mm)0
-rw-r--r--platform/ios/godot_view_renderer.h (renamed from platform/iphone/godot_view_renderer.h)0
-rw-r--r--platform/ios/godot_view_renderer.mm (renamed from platform/iphone/godot_view_renderer.mm)10
-rw-r--r--platform/ios/ios.h (renamed from platform/iphone/ios.h)0
-rw-r--r--platform/ios/ios.mm (renamed from platform/iphone/ios.mm)0
-rw-r--r--platform/ios/joypad_ios.h (renamed from platform/iphone/joypad_iphone.h)12
-rw-r--r--platform/ios/joypad_ios.mm (renamed from platform/iphone/joypad_iphone.mm)18
-rw-r--r--platform/ios/keyboard_input_view.h (renamed from platform/iphone/keyboard_input_view.h)0
-rw-r--r--platform/ios/keyboard_input_view.mm (renamed from platform/iphone/keyboard_input_view.mm)12
-rw-r--r--platform/ios/logo.png (renamed from platform/iphone/logo.png)bin1297 -> 1297 bytes
-rw-r--r--platform/ios/main.m (renamed from platform/iphone/main.m)0
-rw-r--r--platform/ios/os_ios.h (renamed from platform/iphone/os_iphone.h)26
-rw-r--r--platform/ios/os_ios.mm (renamed from platform/iphone/os_iphone.mm)98
-rw-r--r--platform/ios/platform_config.h (renamed from platform/iphone/platform_config.h)0
-rw-r--r--platform/ios/tts_ios.h (renamed from platform/iphone/tts_ios.h)0
-rw-r--r--platform/ios/tts_ios.mm (renamed from platform/iphone/tts_ios.mm)0
-rw-r--r--platform/ios/view_controller.h (renamed from platform/iphone/view_controller.h)0
-rw-r--r--platform/ios/view_controller.mm (renamed from platform/iphone/view_controller.mm)20
-rw-r--r--platform/ios/vulkan_context_ios.h (renamed from platform/iphone/vulkan_context_iphone.h)14
-rw-r--r--platform/ios/vulkan_context_ios.mm (renamed from platform/iphone/vulkan_context_iphone.mm)12
-rw-r--r--platform/javascript/display_server_javascript.cpp4
-rw-r--r--platform/javascript/export/export_plugin.cpp9
-rw-r--r--platform/javascript/js/engine/config.js1
-rw-r--r--platform/linuxbsd/SCsub12
-rw-r--r--platform/linuxbsd/detect.py110
-rw-r--r--platform/linuxbsd/display_server_x11.cpp72
-rw-r--r--platform/linuxbsd/display_server_x11.h3
-rw-r--r--platform/linuxbsd/export/export.cpp7
-rw-r--r--platform/linuxbsd/godot_linuxbsd.cpp4
-rw-r--r--platform/macos/SCsub30
-rw-r--r--platform/macos/crash_handler_macos.h (renamed from platform/osx/crash_handler_osx.h)8
-rw-r--r--platform/macos/crash_handler_macos.mm (renamed from platform/osx/crash_handler_osx.mm)4
-rw-r--r--platform/macos/detect.py (renamed from platform/osx/detect.py)69
-rw-r--r--platform/macos/dir_access_macos.h (renamed from platform/osx/dir_access_osx.h)8
-rw-r--r--platform/macos/dir_access_macos.mm (renamed from platform/osx/dir_access_osx.mm)12
-rw-r--r--platform/macos/display_server_macos.h (renamed from platform/osx/display_server_osx.h)30
-rw-r--r--platform/macos/display_server_macos.mm (renamed from platform/osx/display_server_osx.mm)469
-rw-r--r--platform/macos/export/codesign.cpp (renamed from platform/osx/export/codesign.cpp)0
-rw-r--r--platform/macos/export/codesign.h (renamed from platform/osx/export/codesign.h)0
-rw-r--r--platform/macos/export/export.cpp (renamed from platform/osx/export/export.cpp)4
-rw-r--r--platform/macos/export/export.h (renamed from platform/iphone/export/export.h)8
-rw-r--r--platform/macos/export/export_plugin.cpp (renamed from platform/osx/export/export_plugin.cpp)98
-rw-r--r--platform/macos/export/export_plugin.h (renamed from platform/osx/export/export_plugin.h)18
-rw-r--r--platform/macos/export/lipo.cpp (renamed from platform/osx/export/lipo.cpp)0
-rw-r--r--platform/macos/export/lipo.h (renamed from platform/osx/export/lipo.h)0
-rw-r--r--platform/macos/export/macho.cpp (renamed from platform/osx/export/macho.cpp)0
-rw-r--r--platform/macos/export/macho.h (renamed from platform/osx/export/macho.h)0
-rw-r--r--platform/macos/export/plist.cpp (renamed from platform/osx/export/plist.cpp)0
-rw-r--r--platform/macos/export/plist.h (renamed from platform/osx/export/plist.h)0
-rw-r--r--platform/macos/gl_manager_macos_legacy.h (renamed from platform/osx/gl_manager_osx_legacy.h)18
-rw-r--r--platform/macos/gl_manager_macos_legacy.mm (renamed from platform/osx/gl_manager_osx_legacy.mm)42
-rw-r--r--platform/macos/godot_application.h (renamed from platform/osx/godot_application.h)0
-rw-r--r--platform/macos/godot_application.mm (renamed from platform/osx/godot_application.mm)4
-rw-r--r--platform/macos/godot_application_delegate.h (renamed from platform/osx/godot_application_delegate.h)1
-rw-r--r--platform/macos/godot_application_delegate.mm (renamed from platform/osx/godot_application_delegate.mm)81
-rw-r--r--platform/macos/godot_content_view.h (renamed from platform/osx/godot_content_view.h)1
-rw-r--r--platform/macos/godot_content_view.mm (renamed from platform/osx/godot_content_view.mm)135
-rw-r--r--platform/macos/godot_main_macos.mm (renamed from platform/osx/godot_main_osx.mm)19
-rw-r--r--platform/macos/godot_menu_item.h (renamed from platform/osx/godot_menu_item.h)0
-rw-r--r--platform/macos/godot_window.h (renamed from platform/osx/godot_window.h)0
-rw-r--r--platform/macos/godot_window.mm (renamed from platform/osx/godot_window.mm)12
-rw-r--r--platform/macos/godot_window_delegate.h (renamed from platform/osx/godot_window_delegate.h)0
-rw-r--r--platform/macos/godot_window_delegate.mm (renamed from platform/osx/godot_window_delegate.mm)66
-rw-r--r--platform/macos/joypad_macos.cpp (renamed from platform/osx/joypad_osx.cpp)32
-rw-r--r--platform/macos/joypad_macos.h (renamed from platform/osx/joypad_osx.h)14
-rw-r--r--platform/macos/key_mapping_macos.h (renamed from platform/osx/key_mapping_osx.h)12
-rw-r--r--platform/macos/key_mapping_macos.mm (renamed from platform/osx/key_mapping_osx.mm)24
-rw-r--r--platform/macos/logo.png (renamed from platform/osx/logo.png)bin7195 -> 7195 bytes
-rw-r--r--platform/macos/macos_terminal_logger.h (renamed from platform/osx/osx_terminal_logger.h)14
-rw-r--r--platform/macos/macos_terminal_logger.mm (renamed from platform/osx/osx_terminal_logger.mm)10
-rw-r--r--platform/macos/os_macos.h (renamed from platform/osx/os_osx.h)24
-rw-r--r--platform/macos/os_macos.mm (renamed from platform/osx/os_osx.mm)104
-rw-r--r--platform/macos/platform_config.h (renamed from platform/osx/platform_config.h)0
-rw-r--r--platform/macos/platform_macos_builders.py (renamed from platform/osx/platform_osx_builders.py)2
-rw-r--r--platform/macos/tts_macos.h (renamed from platform/osx/tts_osx.h)10
-rw-r--r--platform/macos/tts_macos.mm (renamed from platform/osx/tts_osx.mm)6
-rw-r--r--platform/macos/vulkan_context_macos.h (renamed from platform/osx/vulkan_context_osx.h)14
-rw-r--r--platform/macos/vulkan_context_macos.mm (renamed from platform/osx/vulkan_context_osx.mm)12
-rw-r--r--platform/osx/SCsub30
-rw-r--r--platform/uwp/export/export_plugin.cpp4
-rw-r--r--platform/windows/display_server_windows.cpp37
-rw-r--r--platform/windows/display_server_windows.h16
-rw-r--r--platform/windows/export/export.cpp7
-rw-r--r--platform/windows/godot_windows.cpp4
-rw-r--r--scene/2d/animated_sprite_2d.cpp5
-rw-r--r--scene/2d/camera_2d.cpp2
-rw-r--r--scene/2d/cpu_particles_2d.cpp6
-rw-r--r--scene/2d/gpu_particles_2d.cpp3
-rw-r--r--scene/2d/navigation_agent_2d.cpp9
-rw-r--r--scene/2d/path_2d.cpp15
-rw-r--r--scene/2d/tile_map.cpp1
-rw-r--r--scene/2d/tile_map.h2
-rw-r--r--scene/3d/bone_attachment_3d.cpp21
-rw-r--r--scene/3d/bone_attachment_3d.h6
-rw-r--r--scene/3d/cpu_particles_3d.cpp11
-rw-r--r--scene/3d/decal.cpp4
-rw-r--r--scene/3d/gpu_particles_3d.cpp2
-rw-r--r--scene/3d/label_3d.cpp130
-rw-r--r--scene/3d/label_3d.h32
-rw-r--r--scene/3d/lightmap_gi.cpp4
-rw-r--r--scene/3d/navigation_agent_3d.cpp11
-rw-r--r--scene/3d/node_3d.cpp31
-rw-r--r--scene/3d/node_3d.h6
-rw-r--r--scene/3d/path_3d.cpp91
-rw-r--r--scene/3d/path_3d.h11
-rw-r--r--scene/3d/skeleton_3d.cpp4
-rw-r--r--scene/3d/sprite_3d.cpp5
-rw-r--r--scene/3d/visual_instance_3d.cpp2
-rw-r--r--scene/3d/visual_instance_3d.h2
-rw-r--r--scene/3d/voxel_gi.cpp3
-rw-r--r--scene/animation/animation_blend_space_1d.cpp23
-rw-r--r--scene/animation/animation_blend_space_1d.h5
-rw-r--r--scene/animation/animation_blend_space_2d.cpp29
-rw-r--r--scene/animation/animation_blend_space_2d.h5
-rw-r--r--scene/animation/animation_blend_tree.cpp161
-rw-r--r--scene/animation/animation_blend_tree.h64
-rw-r--r--scene/animation/animation_node_state_machine.cpp78
-rw-r--r--scene/animation/animation_node_state_machine.h12
-rw-r--r--scene/animation/animation_player.cpp4
-rw-r--r--scene/animation/animation_tree.cpp38
-rw-r--r--scene/animation/animation_tree.h11
-rw-r--r--scene/gui/button.cpp87
-rw-r--r--scene/gui/button.h9
-rw-r--r--scene/gui/code_edit.cpp81
-rw-r--r--scene/gui/code_edit.h5
-rw-r--r--scene/gui/color_mode.cpp330
-rw-r--r--scene/gui/color_mode.h143
-rw-r--r--scene/gui/color_picker.cpp509
-rw-r--r--scene/gui/color_picker.h93
-rw-r--r--scene/gui/control.cpp48
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/gui/dialogs.cpp28
-rw-r--r--scene/gui/dialogs.h7
-rw-r--r--scene/gui/file_dialog.cpp113
-rw-r--r--scene/gui/file_dialog.h8
-rw-r--r--scene/gui/gradient_edit.cpp10
-rw-r--r--scene/gui/gradient_edit.h5
-rw-r--r--scene/gui/graph_edit.cpp2
-rw-r--r--scene/gui/graph_node.cpp72
-rw-r--r--scene/gui/graph_node.h5
-rw-r--r--scene/gui/grid_container.cpp5
-rw-r--r--scene/gui/item_list.cpp47
-rw-r--r--scene/gui/item_list.h5
-rw-r--r--scene/gui/label.cpp197
-rw-r--r--scene/gui/label.h16
-rw-r--r--scene/gui/line_edit.cpp136
-rw-r--r--scene/gui/line_edit.h12
-rw-r--r--scene/gui/link_button.cpp83
-rw-r--r--scene/gui/link_button.h9
-rw-r--r--scene/gui/popup_menu.cpp43
-rw-r--r--scene/gui/popup_menu.h4
-rw-r--r--scene/gui/rich_text_label.cpp257
-rw-r--r--scene/gui/rich_text_label.h10
-rw-r--r--scene/gui/scroll_container.cpp1
-rw-r--r--scene/gui/slider.cpp14
-rw-r--r--scene/gui/slider.h8
-rw-r--r--scene/gui/spin_box.cpp4
-rw-r--r--scene/gui/spin_box.h4
-rw-r--r--scene/gui/tab_bar.cpp47
-rw-r--r--scene/gui/tab_bar.h5
-rw-r--r--scene/gui/tab_container.cpp11
-rw-r--r--scene/gui/tab_container.h1
-rw-r--r--scene/gui/text_edit.cpp165
-rw-r--r--scene/gui/text_edit.h17
-rw-r--r--scene/gui/tree.cpp105
-rw-r--r--scene/gui/tree.h12
-rw-r--r--scene/gui/video_stream_player.h2
-rw-r--r--scene/main/canvas_item.cpp66
-rw-r--r--scene/main/canvas_item.h13
-rw-r--r--scene/main/node.cpp24
-rw-r--r--scene/main/scene_tree.cpp116
-rw-r--r--scene/main/scene_tree.h21
-rw-r--r--scene/main/viewport.cpp131
-rw-r--r--scene/main/viewport.h43
-rw-r--r--scene/multiplayer/multiplayer_spawner.cpp17
-rw-r--r--scene/multiplayer/multiplayer_spawner.h3
-rw-r--r--scene/multiplayer/multiplayer_synchronizer.cpp142
-rw-r--r--scene/multiplayer/multiplayer_synchronizer.h25
-rw-r--r--scene/multiplayer/scene_cache_interface.cpp25
-rw-r--r--scene/multiplayer/scene_cache_interface.h3
-rw-r--r--scene/multiplayer/scene_replication_interface.cpp210
-rw-r--r--scene/multiplayer/scene_replication_interface.h7
-rw-r--r--scene/multiplayer/scene_replication_state.cpp81
-rw-r--r--scene/multiplayer/scene_replication_state.h23
-rw-r--r--scene/multiplayer/scene_rpc_interface.cpp6
-rw-r--r--scene/register_scene_types.cpp25
-rw-r--r--scene/resources/bone_map.cpp181
-rw-r--r--scene/resources/bone_map.h70
-rw-r--r--scene/resources/default_theme/default_theme.cpp59
-rw-r--r--scene/resources/font.cpp2339
-rw-r--r--scene/resources/font.h266
-rw-r--r--scene/resources/gradient.h8
-rw-r--r--scene/resources/label_settings.cpp187
-rw-r--r--scene/resources/label_settings.h (renamed from editor/plugins/font_editor_plugin.h)74
-rw-r--r--scene/resources/mesh_library.cpp2
-rw-r--r--scene/resources/primitive_meshes.cpp118
-rw-r--r--scene/resources/primitive_meshes.h35
-rw-r--r--scene/resources/resource_format_text.cpp172
-rw-r--r--scene/resources/resource_format_text.h6
-rw-r--r--scene/resources/skeleton_profile.cpp793
-rw-r--r--scene/resources/skeleton_profile.h131
-rw-r--r--scene/resources/sprite_frames.cpp51
-rw-r--r--scene/resources/sprite_frames.h5
-rw-r--r--scene/resources/text_file.cpp2
-rw-r--r--scene/resources/text_line.cpp68
-rw-r--r--scene/resources/text_line.h12
-rw-r--r--scene/resources/text_paragraph.cpp167
-rw-r--r--scene/resources/text_paragraph.h18
-rw-r--r--scene/resources/texture.cpp36
-rw-r--r--scene/resources/texture.h5
-rw-r--r--scene/resources/tile_set.cpp17
-rw-r--r--scene/resources/visual_shader.cpp57
-rw-r--r--scene/resources/visual_shader.h11
-rw-r--r--scene/resources/visual_shader_particle_nodes.cpp6
-rw-r--r--scene/resources/world_3d.cpp1
-rw-r--r--servers/audio/audio_stream.cpp2
-rw-r--r--servers/movie_writer/movie_writer.cpp137
-rw-r--r--servers/movie_writer/movie_writer.h37
-rw-r--r--servers/movie_writer/movie_writer_mjpeg.h2
-rw-r--r--servers/movie_writer/movie_writer_pngwav.cpp168
-rw-r--r--servers/movie_writer/movie_writer_pngwav.h71
-rw-r--r--servers/register_server_types.cpp1
-rw-r--r--servers/rendering/SCsub1
-rw-r--r--servers/rendering/dummy/SCsub7
-rw-r--r--servers/rendering/dummy/environment/fog.h55
-rw-r--r--servers/rendering/dummy/environment/gi.h3
-rw-r--r--servers/rendering/dummy/rasterizer_dummy.h9
-rw-r--r--servers/rendering/dummy/rasterizer_scene_dummy.h4
-rw-r--r--servers/rendering/dummy/storage/SCsub5
-rw-r--r--servers/rendering/dummy/storage/material_storage.h3
-rw-r--r--servers/rendering/dummy/storage/mesh_storage.h7
-rw-r--r--servers/rendering/dummy/storage/texture_storage.cpp43
-rw-r--r--servers/rendering/dummy/storage/texture_storage.h12
-rw-r--r--servers/rendering/dummy/storage/utilities.h (renamed from servers/rendering/dummy/rasterizer_storage_dummy.h)96
-rw-r--r--servers/rendering/environment/renderer_fog.h53
-rw-r--r--servers/rendering/environment/renderer_gi.h4
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp21
-rw-r--r--servers/rendering/renderer_canvas_cull.h2
-rw-r--r--servers/rendering/renderer_canvas_render.cpp6
-rw-r--r--servers/rendering/renderer_canvas_render.h8
-rw-r--r--servers/rendering/renderer_compositor.h6
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.h8
-rw-r--r--servers/rendering/renderer_rd/effects/copy_effects.cpp116
-rw-r--r--servers/rendering/renderer_rd/effects/copy_effects.h30
-rw-r--r--servers/rendering/renderer_rd/effects/ss_effects.cpp1715
-rw-r--r--servers/rendering/renderer_rd/effects/ss_effects.h508
-rw-r--r--servers/rendering/renderer_rd/effects/vrs.cpp171
-rw-r--r--servers/rendering/renderer_rd/effects/vrs.h75
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp1245
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h384
-rw-r--r--servers/rendering/renderer_rd/environment/fog.cpp128
-rw-r--r--servers/rendering/renderer_rd/environment/fog.h83
-rw-r--r--servers/rendering/renderer_rd/environment/gi.cpp253
-rw-r--r--servers/rendering/renderer_rd/environment/gi.h51
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp206
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h22
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp3
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h5
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp91
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h16
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp3
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp9
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h6
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp15
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.h12
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp506
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h62
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp58
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.h19
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h222
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/shaders/SCsub2
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/SCsub2
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl8
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl (renamed from servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl)38
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl (renamed from servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl)20
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_inc.glsl28
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl (renamed from servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl)48
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl112
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl (renamed from servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssao.glsl (renamed from servers/rendering/renderer_rd/shaders/ssao.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl (renamed from servers/rendering/renderer_rd/shaders/ssao_blur.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl (renamed from servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl (renamed from servers/rendering/renderer_rd/shaders/ssao_interleave.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssil.glsl (renamed from servers/rendering/renderer_rd/shaders/ssil.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl (renamed from servers/rendering/renderer_rd/shaders/ssil_blur.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl (renamed from servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl (renamed from servers/rendering/renderer_rd/shaders/ssil_interleave.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/vrs.glsl72
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/SCsub2
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/gi.glsl158
-rw-r--r--servers/rendering/renderer_rd/shaders/specular_merge.glsl53
-rw-r--r--servers/rendering/renderer_rd/shaders/taa_resolve.glsl5
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl1
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.cpp38
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.h7
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.cpp14
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.h86
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp32
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.h10
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.cpp43
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.h6
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp93
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h16
-rw-r--r--servers/rendering/renderer_rd/storage_rd/utilities.cpp (renamed from servers/rendering/renderer_rd/renderer_storage_rd.cpp)430
-rw-r--r--servers/rendering/renderer_rd/storage_rd/utilities.h122
-rw-r--r--servers/rendering/renderer_scene.h4
-rw-r--r--servers/rendering/renderer_scene_cull.cpp26
-rw-r--r--servers/rendering/renderer_scene_cull.h38
-rw-r--r--servers/rendering/renderer_scene_render.h4
-rw-r--r--servers/rendering/renderer_viewport.cpp28
-rw-r--r--servers/rendering/renderer_viewport.h7
-rw-r--r--servers/rendering/rendering_device.cpp5
-rw-r--r--servers/rendering/rendering_device.h28
-rw-r--r--servers/rendering/rendering_server_default.cpp51
-rw-r--r--servers/rendering/rendering_server_default.h22
-rw-r--r--servers/rendering/rendering_server_globals.cpp3
-rw-r--r--servers/rendering/rendering_server_globals.h5
-rw-r--r--servers/rendering/storage/light_storage.h1
-rw-r--r--servers/rendering/storage/material_storage.h4
-rw-r--r--servers/rendering/storage/mesh_storage.h4
-rw-r--r--servers/rendering/storage/particles_storage.h1
-rw-r--r--servers/rendering/storage/texture_storage.h14
-rw-r--r--servers/rendering/storage/utilities.cpp (renamed from servers/rendering/renderer_storage.cpp)16
-rw-r--r--servers/rendering/storage/utilities.h (renamed from servers/rendering/renderer_storage.h)196
-rw-r--r--servers/rendering_server.cpp28
-rw-r--r--servers/rendering_server.h19
-rw-r--r--servers/text/text_server_extension.cpp46
-rw-r--r--servers/text/text_server_extension.h38
-rw-r--r--servers/text_server.cpp93
-rw-r--r--servers/text_server.h41
-rw-r--r--servers/xr/xr_interface.cpp88
-rw-r--r--servers/xr/xr_interface.h7
-rw-r--r--servers/xr/xr_interface_extension.cpp12
-rw-r--r--servers/xr/xr_interface_extension.h2
-rw-r--r--tests/core/io/test_image.h38
-rw-r--r--tests/core/math/test_plane.h172
-rw-r--r--tests/core/object/test_class_db.h12
-rw-r--r--tests/core/string/test_string.h75
-rw-r--r--tests/core/threads/test_worker_thread_pool.h158
-rw-r--r--tests/scene/test_code_edit.h2
-rw-r--r--tests/scene/test_text_edit.h20
-rw-r--r--tests/scene/test_theme.h2
-rw-r--r--tests/test_main.cpp2
-rw-r--r--thirdparty/README.md12
-rw-r--r--thirdparty/etcpak/ProcessRGB.cpp8
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS.hh165
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/Anchor.hh84
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat1.hh46
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat2.hh58
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh70
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh77
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/ChainContextPos.hh14
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/Common.hh32
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/ContextPos.hh14
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePos.hh35
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh281
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/ExtensionPos.hh17
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh113
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh35
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh217
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh35
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh244
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh36
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh227
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh52
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh38
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh420
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh314
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PosLookup.hh79
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PosLookupSubTable.hh79
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh98
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh124
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh140
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh329
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh8
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh258
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/Glyph.hh233
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh48
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh216
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh72
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/glyf-helpers.hh90
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/glyf.hh388
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/loca.hh43
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/path-builder.hh135
-rw-r--r--thirdparty/harfbuzz/src/graph/graph.hh860
-rw-r--r--thirdparty/harfbuzz/src/graph/serialize.hh249
-rw-r--r--thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh8
-rw-r--r--thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-algs.hh38
-rw-r--r--thirdparty/harfbuzz/src/hb-array.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-bimap.hh9
-rw-r--r--thirdparty/harfbuzz/src/hb-bit-set-invertible.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-bit-set.hh32
-rw-r--r--thirdparty/harfbuzz/src/hb-blob.cc4
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer-serialize.cc18
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer-verify.cc28
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.cc37
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.h34
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.hh44
-rw-r--r--thirdparty/harfbuzz/src/hb-cache.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-common.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-config.hh13
-rw-r--r--thirdparty/harfbuzz/src/hb-coretext.cc56
-rw-r--r--thirdparty/harfbuzz/src/hb-cplusplus.hh192
-rw-r--r--thirdparty/harfbuzz/src/hb-directwrite.cc7
-rw-r--r--thirdparty/harfbuzz/src/hb-draw.cc65
-rw-r--r--thirdparty/harfbuzz/src/hb-draw.hh14
-rw-r--r--thirdparty/harfbuzz/src/hb-face.cc4
-rw-r--r--thirdparty/harfbuzz/src/hb-face.h2
-rw-r--r--thirdparty/harfbuzz/src/hb-font.cc177
-rw-r--r--thirdparty/harfbuzz/src/hb-font.h6
-rw-r--r--thirdparty/harfbuzz/src/hb-font.hh81
-rw-r--r--thirdparty/harfbuzz/src/hb-ft.cc158
-rw-r--r--thirdparty/harfbuzz/src/hb-ft.h9
-rw-r--r--thirdparty/harfbuzz/src/hb-iter.hh16
-rw-r--r--thirdparty/harfbuzz/src/hb-machinery.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-map.cc38
-rw-r--r--thirdparty/harfbuzz/src/hb-map.h6
-rw-r--r--thirdparty/harfbuzz/src/hb-map.hh134
-rw-r--r--thirdparty/harfbuzz/src/hb-meta.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-null.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cff1-table.hh15
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cmap-table.hh77
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-cpal-table.hh5
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-font.cc164
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-glyf-table.hh1330
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh9
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-common.hh233
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh3090
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh7
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh421
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.cc48
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.hh3
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-name-language-static.hh12
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-name-table.hh36
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-os2-table.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh14
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh603
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc501
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.hh431
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh396
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh115
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh492
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh177
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh849
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc11
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape.cc18
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-arabic-fallback.hh (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh)80
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-joining-list.hh)6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-arabic-pua.hh118
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh)141
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-arabic-win1256.hh (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh)8
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc)27
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-arabic.hh (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.hh)8
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-default.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-default.cc)6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc)6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-hebrew.cc)6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh589
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc560
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc)356
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-indic.hh66
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh428
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc)29
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh553
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc)74
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc)31
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.hh (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.hh)13
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc)16
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh931
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh)12
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-use.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc)16
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc)4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.hh (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.hh)8
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shaper.hh (renamed from thirdparty/harfbuzz/src/hb-ot-shape-complex.hh)85
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-tag-table.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-tag.cc25
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh132
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh11
-rw-r--r--thirdparty/harfbuzz/src/hb-repacker.hh1054
-rw-r--r--thirdparty/harfbuzz/src/hb-serialize.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-set-digest.hh30
-rw-r--r--thirdparty/harfbuzz/src/hb-set.cc20
-rw-r--r--thirdparty/harfbuzz/src/hb-set.h3
-rw-r--r--thirdparty/harfbuzz/src/hb-set.hh1
-rw-r--r--thirdparty/harfbuzz/src/hb-shape-plan.cc7
-rw-r--r--thirdparty/harfbuzz/src/hb-shape.cc20
-rw-r--r--thirdparty/harfbuzz/src/hb-shaper.cc16
-rw-r--r--thirdparty/harfbuzz/src/hb-static.cc3
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-cff-common.hh3
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-input.cc15
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.cc48
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-subset.cc120
-rw-r--r--thirdparty/harfbuzz/src/hb-ucd-table.hh3
-rw-r--r--thirdparty/harfbuzz/src/hb-unicode.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-unicode.hh7
-rw-r--r--thirdparty/harfbuzz/src/hb-version.h6
-rw-r--r--thirdparty/harfbuzz/src/hb.hh5
-rw-r--r--thirdparty/mbedtls/LICENSE205
-rw-r--r--thirdparty/mbedtls/apache-2.0.txt202
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aes.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aria.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/asn1.h12
-rw-r--r--thirdparty/mbedtls/include/mbedtls/bignum.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/blowfish.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/camellia.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/chachapoly.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/check_config.h49
-rw-r--r--thirdparty/mbedtls/include/mbedtls/config.h143
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ctr_drbg.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/debug.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecjpake.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecp.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/entropy.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/hkdf.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/hmac_drbg.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/oid.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pem.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pk.h75
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform_time.h8
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform_util.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/rsa.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl.h36
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_cache.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_cookie.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_internal.h44
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_ticket.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/version.h8
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509.h9
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_crl.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_crt.h15
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_csr.h7
-rw-r--r--thirdparty/mbedtls/library/aes.c4
-rw-r--r--thirdparty/mbedtls/library/asn1write.c7
-rw-r--r--thirdparty/mbedtls/library/bignum.c4
-rw-r--r--thirdparty/mbedtls/library/cipher.c11
-rw-r--r--thirdparty/mbedtls/library/constant_time.c15
-rw-r--r--thirdparty/mbedtls/library/constant_time_internal.h7
-rw-r--r--thirdparty/mbedtls/library/ctr_drbg.c6
-rw-r--r--thirdparty/mbedtls/library/ecdh.c2
-rw-r--r--thirdparty/mbedtls/library/ecjpake.c2
-rw-r--r--thirdparty/mbedtls/library/ecp.c8
-rw-r--r--thirdparty/mbedtls/library/ecp_curves.c2
-rw-r--r--thirdparty/mbedtls/library/memory_buffer_alloc.c4
-rw-r--r--thirdparty/mbedtls/library/mps_common.h2
-rw-r--r--thirdparty/mbedtls/library/net_sockets.c2
-rw-r--r--thirdparty/mbedtls/library/pkparse.c10
-rw-r--r--thirdparty/mbedtls/library/rsa.c4
-rw-r--r--thirdparty/mbedtls/library/ssl_ciphersuites.c1
-rw-r--r--thirdparty/mbedtls/library/ssl_cli.c111
-rw-r--r--thirdparty/mbedtls/library/ssl_cookie.c3
-rw-r--r--thirdparty/mbedtls/library/ssl_msg.c131
-rw-r--r--thirdparty/mbedtls/library/ssl_srv.c99
-rw-r--r--thirdparty/mbedtls/library/ssl_ticket.c4
-rw-r--r--thirdparty/mbedtls/library/ssl_tls.c58
-rw-r--r--thirdparty/mbedtls/library/threading.c2
-rw-r--r--thirdparty/mbedtls/library/timing.c9
-rw-r--r--thirdparty/mbedtls/library/x509.c21
-rw-r--r--thirdparty/mbedtls/library/x509_crl.c2
-rw-r--r--thirdparty/mbedtls/library/x509_crt.c2
-rw-r--r--thirdparty/mbedtls/library/x509write_crt.c2
-rw-r--r--thirdparty/zstd/common/bitstream.h33
-rw-r--r--thirdparty/zstd/common/compiler.h132
-rw-r--r--thirdparty/zstd/common/entropy_common.c16
-rw-r--r--thirdparty/zstd/common/error_private.h79
-rw-r--r--thirdparty/zstd/common/fse.h3
-rw-r--r--thirdparty/zstd/common/fse_decompress.c2
-rw-r--r--thirdparty/zstd/common/huf.h46
-rw-r--r--thirdparty/zstd/common/mem.h18
-rw-r--r--thirdparty/zstd/common/pool.c17
-rw-r--r--thirdparty/zstd/common/pool.h4
-rw-r--r--thirdparty/zstd/common/portability_macros.h137
-rw-r--r--thirdparty/zstd/common/xxhash.c810
-rw-r--r--thirdparty/zstd/common/xxhash.h5733
-rw-r--r--thirdparty/zstd/common/zstd_internal.h187
-rw-r--r--thirdparty/zstd/common/zstd_trace.h15
-rw-r--r--thirdparty/zstd/compress/clevels.h134
-rw-r--r--thirdparty/zstd/compress/fse_compress.c90
-rw-r--r--thirdparty/zstd/compress/huf_compress.c641
-rw-r--r--thirdparty/zstd/compress/zstd_compress.c680
-rw-r--r--thirdparty/zstd/compress/zstd_compress_internal.h257
-rw-r--r--thirdparty/zstd/compress/zstd_compress_literals.c7
-rw-r--r--thirdparty/zstd/compress/zstd_compress_literals.h4
-rw-r--r--thirdparty/zstd/compress/zstd_compress_sequences.c29
-rw-r--r--thirdparty/zstd/compress/zstd_compress_superblock.c7
-rw-r--r--thirdparty/zstd/compress/zstd_cwksp.h68
-rw-r--r--thirdparty/zstd/compress/zstd_double_fast.c415
-rw-r--r--thirdparty/zstd/compress/zstd_fast.c439
-rw-r--r--thirdparty/zstd/compress/zstd_lazy.c1044
-rw-r--r--thirdparty/zstd/compress/zstd_ldm.c16
-rw-r--r--thirdparty/zstd/compress/zstd_ldm.h2
-rw-r--r--thirdparty/zstd/compress/zstd_ldm_geartab.h5
-rw-r--r--thirdparty/zstd/compress/zstd_opt.c397
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.c114
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.h5
-rw-r--r--thirdparty/zstd/decompress/huf_decompress.c916
-rw-r--r--thirdparty/zstd/decompress/huf_decompress_amd64.S585
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress.c107
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_block.c964
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_block.h10
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_internal.h37
-rw-r--r--thirdparty/zstd/zstd.h315
1367 files changed, 90647 insertions, 49306 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index ebbbe345fd..e7e88e95d7 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -139,10 +139,10 @@ doc_classes/* @godotengine/documentation
# Platform
/platform/android/ @godotengine/android
-/platform/iphone/ @godotengine/ios
+/platform/ios/ @godotengine/ios
/platform/javascript/ @godotengine/html5
/platform/linuxbsd/ @godotengine/linux-bsd
-/platform/osx/ @godotengine/macos
+/platform/macos/ @godotengine/macos
/platform/uwp/ @godotengine/uwp
/platform/windows/ @godotengine/windows
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 332ed2b72f..8dc712c78d 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,11 +1,7 @@
<!--
-Pull requests should always be made for the `master` branch first, as that's
-where development happens and the source of all future stable release branches.
+Please target the `master` branch in priority.
+PRs can target `3.x` if the same change was done in `master`, or is not relevant there.
-Relevant fixes are cherry-picked for stable branches as needed.
-
-Do not create a pull request for stable branches unless the change is already
-available in the `master` branch and it cannot be easily cherry-picked.
-Alternatively, if the change is only relevant for that branch (e.g. rendering
-fixes for the 3.2 branch).
+Relevant fixes are cherry-picked for stable branches as needed by maintainers.
+You can mention in the description if the change is compatible with `3.x`.
-->
diff --git a/.github/actions/godot-build/action.yml b/.github/actions/godot-build/action.yml
index 7af3516f71..75f3d9ab37 100644
--- a/.github/actions/godot-build/action.yml
+++ b/.github/actions/godot-build/action.yml
@@ -35,5 +35,5 @@ runs:
run: |
echo "Building with flags:" ${{ env.SCONSFLAGS }}
if ! ${{ inputs.tools }}; then rm -rf editor; fi # Ensure we don't include editor code.
- scons p=${{ inputs.platform }} target=${{ inputs.target }} tools=${{ inputs.tools }} tests=${{ inputs.tests }} --jobs=2 ${{ env.SCONSFLAGS }}
+ scons p=${{ inputs.platform }} target=${{ inputs.target }} tools=${{ inputs.tools }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }}
ls -l bin/
diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml
index 40f091e234..03277edc1d 100644
--- a/.github/workflows/ios_builds.yml
+++ b/.github/workflows/ios_builds.yml
@@ -30,7 +30,7 @@ jobs:
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }}
- platform: iphone
+ platform: ios
target: release
tools: false
tests: false
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml
index 3df4409041..4e4a143f88 100644
--- a/.github/workflows/linux_builds.yml
+++ b/.github/workflows/linux_builds.yml
@@ -31,12 +31,12 @@ jobs:
proj-conv: true
artifact: true
- - name: Editor with doubles and GCC sanitizers (target=debug, tools=yes, float=64, tests=yes, use_asan=yes, use_ubsan=yes)
+ - name: Editor with doubles and GCC sanitizers (target=debug, tools=yes, float=64, tests=yes, use_asan=yes, use_ubsan=yes, linker=gold)
cache-name: linux-editor-double-sanitizers
target: debug
tools: true
tests: true
- sconsflags: float=64 use_asan=yes use_ubsan=yes
+ sconsflags: float=64 use_asan=yes use_ubsan=yes linker=gold
proj-test: true
# Can be turned off for PRs that intentionally break compat with godot-cpp,
# until both the upstream PR and the matching godot-cpp changes are merged.
@@ -46,12 +46,12 @@ jobs:
# Skip 2GiB artifact speeding up action.
artifact: false
- - name: Editor with clang sanitizers (target=debug, tools=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes)
+ - name: Editor with clang sanitizers (target=debug, tools=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)
cache-name: linux-editor-llvm-sanitizers
target: debug
tools: true
tests: true
- sconsflags: use_asan=yes use_ubsan=yes use_llvm=yes
+ sconsflags: use_asan=yes use_ubsan=yes use_llvm=yes linker=lld
bin: "./bin/godot.linuxbsd.tools.64.llvm.san"
build-mono: false
# Skip 2GiB artifact speeding up action.
@@ -127,6 +127,8 @@ jobs:
- name: Unit tests
if: ${{ matrix.tests }}
run: |
+ ${{ matrix.bin }} --version
+ ${{ matrix.bin }} --help
${{ matrix.bin }} --test --headless
# Check class reference
@@ -210,7 +212,7 @@ jobs:
if: ${{ matrix.godot-cpp-test }}
run: |
cd godot-cpp/test
- scons target=${{ matrix.target }} -j2
+ scons target=${{ matrix.target }}
cd ../..
- name: Prepare artifact
diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml
index 68623f2770..0cb037bfae 100644
--- a/.github/workflows/macos_builds.yml
+++ b/.github/workflows/macos_builds.yml
@@ -5,7 +5,7 @@ on: [push, pull_request]
env:
# Only used for the cache key. Increment version to force clean build.
GODOT_BASE_BRANCH: master-v3
- SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
+ SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes use_volk=yes
concurrency:
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-macos
@@ -24,7 +24,7 @@ jobs:
target: release_debug
tools: true
tests: true
- bin: "./bin/godot.osx.opt.tools.64"
+ bin: "./bin/godot.macos.opt.tools.64"
- name: Template (target=release, tools=no)
cache-name: macos-template
@@ -49,7 +49,7 @@ jobs:
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }}
- platform: osx
+ platform: macos
target: ${{ matrix.target }}
tools: ${{ matrix.tools }}
tests: ${{ matrix.tests }}
@@ -58,6 +58,8 @@ jobs:
- name: Unit tests
if: ${{ matrix.tests }}
run: |
+ ${{ matrix.bin }} --version
+ ${{ matrix.bin }} --help
${{ matrix.bin }} --test
- name: Prepare artifact
diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml
index 4919f34cf0..e04d49adde 100644
--- a/.github/workflows/windows_builds.yml
+++ b/.github/workflows/windows_builds.yml
@@ -64,6 +64,8 @@ jobs:
- name: Unit tests
if: ${{ matrix.tests }}
run: |
+ ${{ matrix.bin }} --version
+ ${{ matrix.bin }} --help
${{ matrix.bin }} --test
- name: Prepare artifact
diff --git a/SConstruct b/SConstruct
index 28395227d2..0fd9326e1c 100644
--- a/SConstruct
+++ b/SConstruct
@@ -195,7 +195,7 @@ opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all
opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False))
opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False))
opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False))
-opts.Add("disable_classes", "Disable given classes (comma separated)", "")
+opts.Add("build_feature_profile", "Path to a file containing a feature build profile", "")
opts.Add(BoolVariable("modules_enabled_by_default", "If no, disable all modules except ones explicitly enabled", True))
opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True))
opts.Add("system_certs_path", "Use this path as SSL certificates default for editor (for package maintainers)", "")
@@ -260,7 +260,7 @@ else:
):
selected_platform = "linuxbsd"
elif sys.platform == "darwin":
- selected_platform = "osx"
+ selected_platform = "macos"
elif sys.platform == "win32":
selected_platform = "windows"
else:
@@ -272,6 +272,20 @@ else:
if selected_platform != "":
print("Automatically detected platform: " + selected_platform)
+if selected_platform in ["macos", "osx"]:
+ if selected_platform == "osx":
+ # Deprecated alias kept for compatibility.
+ print('Platform "osx" has been renamed to "macos" in Godot 4.0. Building for platform "macos".')
+ # Alias for convenience.
+ selected_platform = "macos"
+
+if selected_platform in ["ios", "iphone"]:
+ if selected_platform == "iphone":
+ # Deprecated alias kept for compatibility.
+ print('Platform "iphone" has been renamed to "ios" in Godot 4.0. Building for platform "ios".')
+ # Alias for convenience.
+ selected_platform = "ios"
+
if selected_platform in ["linux", "bsd", "x11"]:
if selected_platform == "x11":
# Deprecated alias kept for compatibility.
@@ -399,6 +413,24 @@ if selected_platform in platform_list:
env = env_base.Clone()
+ # Default num_jobs to local cpu count if not user specified.
+ # SCons has a peculiarity where user-specified options won't be overridden
+ # by SetOption, so we can rely on this to know if we should use our default.
+ initial_num_jobs = env.GetOption("num_jobs")
+ altered_num_jobs = initial_num_jobs + 1
+ env.SetOption("num_jobs", altered_num_jobs)
+ if env.GetOption("num_jobs") == altered_num_jobs:
+ cpu_count = os.cpu_count()
+ if cpu_count is None:
+ print("Couldn't auto-detect CPU count to configure build parallelism. Specify it with the -j argument.")
+ else:
+ safer_cpu_count = cpu_count if cpu_count <= 4 else cpu_count - 1
+ print(
+ "Auto-detected %d CPU cores available for build parallelism. Using %d cores by default. You can override it with the -j argument."
+ % (cpu_count, safer_cpu_count)
+ )
+ env.SetOption("num_jobs", safer_cpu_count)
+
if env["compiledb"]:
# Generating the compilation DB (`compile_commands.json`) requires SCons 4.0.0 or later.
from SCons import __version__ as scons_raw_version
@@ -536,7 +568,7 @@ if selected_platform in platform_list:
)
# Apple LLVM versions differ from upstream LLVM version \o/, compare
# in https://en.wikipedia.org/wiki/Xcode#Toolchain_versions
- elif env["platform"] == "osx" or env["platform"] == "iphone":
+ elif env["platform"] == "macos" or env["platform"] == "ios":
vanilla = methods.is_vanilla_clang(env)
if vanilla and cc_version_major < 6:
print(
@@ -720,7 +752,27 @@ if selected_platform in platform_list:
if env["tools"]:
env.Append(CPPDEFINES=["TOOLS_ENABLED"])
- methods.write_disabled_classes(env["disable_classes"].split(","))
+
+ disabled_classes = []
+
+ if env["build_feature_profile"] != "":
+ print("Using build feature profile: " + env["build_feature_profile"])
+ import json
+
+ try:
+ ft = json.load(open(env["build_feature_profile"]))
+ if "disabled_classes" in ft:
+ disabled_classes = ft["disabled_classes"]
+ if "disabled_build_options" in ft:
+ dbo = ft["disabled_build_options"]
+ for c in dbo:
+ env[c] = dbo[c]
+ except:
+ print("Error opening feature build profile: " + env["build_feature_profile"])
+ Exit(255)
+
+ methods.write_disabled_classes(disabled_classes)
+
if env["disable_3d"]:
if env["tools"]:
print(
@@ -788,7 +840,8 @@ if selected_platform in platform_list:
SConscript("core/SCsub")
SConscript("servers/SCsub")
SConscript("scene/SCsub")
- SConscript("editor/SCsub")
+ if env["tools"]:
+ SConscript("editor/SCsub")
SConscript("drivers/SCsub")
SConscript("platform/SCsub")
@@ -801,6 +854,9 @@ if selected_platform in platform_list:
# Microsoft Visual Studio Project Generation
if env["vsproj"]:
+ if os.name != "nt":
+ print("Error: The `vsproj` option is only usable on Windows with Visual Studio.")
+ Exit(255)
env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]]
methods.generate_vs_project(env, GetOption("num_jobs"))
methods.generate_cpp_hint_file("cpp.hint")
diff --git a/core/SCsub b/core/SCsub
index 1379e9df9b..97080b8710 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -129,6 +129,9 @@ if env["builtin_zstd"]:
"decompress/zstd_decompress_block.c",
"decompress/zstd_decompress.c",
]
+ if env["platform"] in ["android", "ios", "linuxbsd", "macos"]:
+ # Match platforms with ZSTD_ASM_SUPPORTED in common/portability_macros.h
+ thirdparty_zstd_sources.append("decompress/huf_decompress_amd64.S")
thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources]
env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"])
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 7145e628c1..f9bac58ffa 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -488,7 +488,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// We need to test both possibilities as extensions for Linux binaries are optional
// (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck').
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
if (!found) {
// Attempt to load PCK from macOS .app bundle resources.
found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_basename + ".pck")) || _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_filename + ".pck"));
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index fc91f83462..26ecd41353 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -83,6 +83,14 @@ Vector<String> ResourceLoader::get_recognized_extensions_for_type(const String &
return ret;
}
+void ResourceLoader::add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front) {
+ ::ResourceLoader::add_resource_format_loader(p_format_loader, p_at_front);
+}
+
+void ResourceLoader::remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader) {
+ ::ResourceLoader::remove_resource_format_loader(p_format_loader);
+}
+
void ResourceLoader::set_abort_on_missing_resources(bool p_abort) {
::ResourceLoader::set_abort_on_missing_resources(p_abort);
}
@@ -119,6 +127,8 @@ void ResourceLoader::_bind_methods() {
ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "cache_mode"), &ResourceLoader::load, DEFVAL(""), DEFVAL(CACHE_MODE_REUSE));
ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &ResourceLoader::get_recognized_extensions_for_type);
+ ClassDB::bind_method(D_METHOD("add_resource_format_loader", "format_loader", "at_front"), &ResourceLoader::add_resource_format_loader, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("remove_resource_format_loader", "format_loader"), &ResourceLoader::remove_resource_format_loader);
ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &ResourceLoader::set_abort_on_missing_resources);
ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &ResourceLoader::get_dependencies);
ClassDB::bind_method(D_METHOD("has_cached", "path"), &ResourceLoader::has_cached);
@@ -137,7 +147,7 @@ void ResourceLoader::_bind_methods() {
////// ResourceSaver //////
-Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) {
+Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, BitField<SaverFlags> p_flags) {
ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, "Can't save empty resource to path '" + String(p_path) + "'.");
return ::ResourceSaver::save(p_path, p_resource, p_flags);
}
@@ -153,20 +163,30 @@ Vector<String> ResourceSaver::get_recognized_extensions(const Ref<Resource> &p_r
return ret;
}
+void ResourceSaver::add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front) {
+ ::ResourceSaver::add_resource_format_saver(p_format_saver, p_at_front);
+}
+
+void ResourceSaver::remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver) {
+ ::ResourceSaver::remove_resource_format_saver(p_format_saver);
+}
+
ResourceSaver *ResourceSaver::singleton = nullptr;
void ResourceSaver::_bind_methods() {
ClassDB::bind_method(D_METHOD("save", "path", "resource", "flags"), &ResourceSaver::save, DEFVAL((uint32_t)FLAG_NONE));
ClassDB::bind_method(D_METHOD("get_recognized_extensions", "type"), &ResourceSaver::get_recognized_extensions);
+ ClassDB::bind_method(D_METHOD("add_resource_format_saver", "format_saver", "at_front"), &ResourceSaver::add_resource_format_saver, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("remove_resource_format_saver", "format_saver"), &ResourceSaver::remove_resource_format_saver);
- BIND_ENUM_CONSTANT(FLAG_NONE);
- BIND_ENUM_CONSTANT(FLAG_RELATIVE_PATHS);
- BIND_ENUM_CONSTANT(FLAG_BUNDLE_RESOURCES);
- BIND_ENUM_CONSTANT(FLAG_CHANGE_PATH);
- BIND_ENUM_CONSTANT(FLAG_OMIT_EDITOR_PROPERTIES);
- BIND_ENUM_CONSTANT(FLAG_SAVE_BIG_ENDIAN);
- BIND_ENUM_CONSTANT(FLAG_COMPRESS);
- BIND_ENUM_CONSTANT(FLAG_REPLACE_SUBRESOURCE_PATHS);
+ BIND_BITFIELD_FLAG(FLAG_NONE);
+ BIND_BITFIELD_FLAG(FLAG_RELATIVE_PATHS);
+ BIND_BITFIELD_FLAG(FLAG_BUNDLE_RESOURCES);
+ BIND_BITFIELD_FLAG(FLAG_CHANGE_PATH);
+ BIND_BITFIELD_FLAG(FLAG_OMIT_EDITOR_PROPERTIES);
+ BIND_BITFIELD_FLAG(FLAG_SAVE_BIG_ENDIAN);
+ BIND_BITFIELD_FLAG(FLAG_COMPRESS);
+ BIND_BITFIELD_FLAG(FLAG_REPLACE_SUBRESOURCE_PATHS);
}
////// OS //////
@@ -1820,13 +1840,14 @@ void Thread::_start_func(void *ud) {
ERR_FAIL_MSG(vformat("Could not call function '%s' on previously freed instance to start thread %s.", t->target_callable.get_method(), t->get_id()));
}
- ::Thread::set_name(t->target_callable.get_method());
+ String func_name = t->target_callable.is_custom() ? t->target_callable.get_custom()->get_as_text() : String(t->target_callable.get_method());
+ ::Thread::set_name(func_name);
Callable::CallError ce;
t->target_callable.call(nullptr, 0, t->ret, ce);
if (ce.error != Callable::CallError::CALL_OK) {
t->running.clear();
- ERR_FAIL_MSG("Could not call function '" + t->target_callable.get_method().operator String() + "' to start thread " + t->get_id() + ": " + Variant::get_callable_error_text(t->target_callable, nullptr, 0, ce) + ".");
+ ERR_FAIL_MSG("Could not call function '" + func_name + "' to start thread " + t->get_id() + ": " + Variant::get_callable_error_text(t->target_callable, nullptr, 0, ce) + ".");
}
t->running.clear();
diff --git a/core/core_bind.h b/core/core_bind.h
index ec9bcdbc02..c116ac4986 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -77,6 +77,8 @@ public:
Ref<Resource> load(const String &p_path, const String &p_type_hint = "", CacheMode p_cache_mode = CACHE_MODE_REUSE);
Vector<String> get_recognized_extensions_for_type(const String &p_type);
+ void add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front);
+ void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader);
void set_abort_on_missing_resources(bool p_abort);
PackedStringArray get_dependencies(const String &p_path);
bool has_cached(const String &p_path);
@@ -107,8 +109,10 @@ public:
static ResourceSaver *get_singleton() { return singleton; }
- Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags);
+ Error save(const String &p_path, const Ref<Resource> &p_resource, BitField<SaverFlags> p_flags);
Vector<String> get_recognized_extensions(const Ref<Resource> &p_resource);
+ void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front);
+ void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver);
ResourceSaver() { singleton = this; }
};
@@ -715,7 +719,7 @@ public:
VARIANT_ENUM_CAST(core_bind::ResourceLoader::ThreadLoadStatus);
VARIANT_ENUM_CAST(core_bind::ResourceLoader::CacheMode);
-VARIANT_ENUM_CAST(core_bind::ResourceSaver::SaverFlags);
+VARIANT_BITFIELD_CAST(core_bind::ResourceSaver::SaverFlags);
VARIANT_ENUM_CAST(core_bind::OS::VideoDriver);
VARIANT_ENUM_CAST(core_bind::OS::Weekday);
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 24d8b0af6e..1753efad60 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -570,9 +570,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM_SUGGESTION);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_EXP_EASING);
- BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LENGTH);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LINK);
- BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_KEY_ACCEL);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_FLAGS);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_RENDER);
@@ -620,15 +618,14 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NONE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_STORAGE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR);
- BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NETWORK);
- BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_HELPER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CHECKABLE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CHECKED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_GROUP);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SUBGROUP);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CLASS_IS_BITFIELD);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE);
@@ -656,11 +653,8 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_NORMAL);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_EDITOR);
- BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_NOSCRIPT);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_CONST);
- BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_REVERSE);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VIRTUAL);
- BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_FROM_SCRIPT);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VARARG);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_STATIC);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_OBJECT_CORE);
diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp
index 263c75760b..d495a8ee20 100644
--- a/core/debugger/engine_debugger.cpp
+++ b/core/debugger/engine_debugger.cpp
@@ -43,6 +43,8 @@ HashMap<StringName, EngineDebugger::Profiler> EngineDebugger::profilers;
HashMap<StringName, EngineDebugger::Capture> EngineDebugger::captures;
HashMap<String, EngineDebugger::CreatePeerFunc> EngineDebugger::protocols;
+void (*EngineDebugger::allow_focus_steal_fn)();
+
void EngineDebugger::register_profiler(const StringName &p_name, const Profiler &p_func) {
ERR_FAIL_COND_MSG(profilers.has(p_name), "Profiler already registered: " + p_name);
profilers.insert(p_name, p_func);
@@ -133,7 +135,7 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks,
singleton->poll_events(true);
}
-void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints) {
+void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints, void (*p_allow_focus_steal_fn)()) {
register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more.
if (p_uri.is_empty()) {
return;
@@ -174,6 +176,8 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp));
}
+
+ allow_focus_steal_fn = p_allow_focus_steal_fn;
}
void EngineDebugger::deinitialize() {
diff --git a/core/debugger/engine_debugger.h b/core/debugger/engine_debugger.h
index a8a791f9b0..236d5e5f63 100644
--- a/core/debugger/engine_debugger.h
+++ b/core/debugger/engine_debugger.h
@@ -100,13 +100,15 @@ protected:
static HashMap<StringName, Capture> captures;
static HashMap<String, CreatePeerFunc> protocols;
+ static void (*allow_focus_steal_fn)();
+
public:
_FORCE_INLINE_ static EngineDebugger *get_singleton() { return singleton; }
_FORCE_INLINE_ static bool is_active() { return singleton != nullptr && script_debugger != nullptr; }
_FORCE_INLINE_ static ScriptDebugger *get_script_debugger() { return script_debugger; };
- static void initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints);
+ static void initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints, void (*p_allow_focus_steal_fn)());
static void deinitialize();
static void register_profiler(const StringName &p_name, const Profiler &p_profiler);
static void unregister_profiler(const StringName &p_name);
diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp
index 06e08081e9..58d239ccb9 100644
--- a/core/debugger/local_debugger.cpp
+++ b/core/debugger/local_debugger.cpp
@@ -31,7 +31,7 @@
#include "local_debugger.h"
#include "core/debugger/script_debugger.h"
-#include "scene/main/scene_tree.h"
+#include "core/os/os.h"
struct LocalDebugger::ScriptsProfiler {
struct ProfileInfoSort {
@@ -273,7 +273,10 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
script_debugger->set_depth(-1);
script_debugger->set_lines_left(-1);
- SceneTree::get_singleton()->quit();
+ MainLoop *main_loop = OS::get_singleton()->get_main_loop();
+ if (main_loop->get_class() == "SceneTree") {
+ main_loop->call("quit");
+ }
break;
} else if (line.begins_with("delete")) {
if (line.get_slice_count(" ") <= 1) {
diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp
index 5ee4e2c368..23ee977df4 100644
--- a/core/debugger/remote_debugger.cpp
+++ b/core/debugger/remote_debugger.cpp
@@ -208,7 +208,7 @@ void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *
rd->script_debugger->send_error(String::utf8(p_func), String::utf8(p_file), p_line, String::utf8(p_err), String::utf8(p_descr), p_editor_notify, p_type, si);
}
-void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error) {
+void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error, bool p_rich) {
RemoteDebugger *rd = static_cast<RemoteDebugger *>(p_this);
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive prints during flush.
@@ -237,7 +237,13 @@ void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p
OutputString output_string;
output_string.message = s;
- output_string.type = p_error ? MESSAGE_TYPE_ERROR : MESSAGE_TYPE_LOG;
+ if (p_error) {
+ output_string.type = MESSAGE_TYPE_ERROR;
+ } else if (p_rich) {
+ output_string.type = MESSAGE_TYPE_LOG_RICH;
+ } else {
+ output_string.type = MESSAGE_TYPE_LOG;
+ }
rd->output_strings.push_back(output_string);
if (overflowed) {
@@ -291,6 +297,14 @@ void RemoteDebugger::flush_output() {
}
strings.push_back(output_string.message);
types.push_back(MESSAGE_TYPE_ERROR);
+ } else if (output_string.type == MESSAGE_TYPE_LOG_RICH) {
+ if (!joined_log_strings.is_empty()) {
+ strings.push_back(String("\n").join(joined_log_strings));
+ types.push_back(MESSAGE_TYPE_LOG_RICH);
+ joined_log_strings.clear();
+ }
+ strings.push_back(output_string.message);
+ types.push_back(MESSAGE_TYPE_LOG_RICH);
} else {
joined_log_strings.push_back(output_string.message);
}
@@ -438,6 +452,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
msg.push_back(error_str);
ERR_FAIL_COND(!script_lang);
msg.push_back(script_lang->debug_get_stack_level_count() > 0);
+ if (allow_focus_steal_fn) {
+ allow_focus_steal_fn();
+ }
send_message("debug_enter", msg);
Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode();
diff --git a/core/debugger/remote_debugger.h b/core/debugger/remote_debugger.h
index fdb312ae68..fe4bbe86ea 100644
--- a/core/debugger/remote_debugger.h
+++ b/core/debugger/remote_debugger.h
@@ -44,6 +44,7 @@ public:
enum MessageType {
MESSAGE_TYPE_LOG,
MESSAGE_TYPE_ERROR,
+ MESSAGE_TYPE_LOG_RICH,
};
private:
@@ -82,7 +83,7 @@ private:
Thread::ID flush_thread = 0;
PrintHandlerList phl;
- static void _print_handler(void *p_this, const String &p_string, bool p_error);
+ static void _print_handler(void *p_this, const String &p_string, bool p_error, bool p_rich);
ErrorHandlerList eh;
static void _err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, bool p_editor_notify, ErrorHandlerType p_type);
diff --git a/core/doc_data.cpp b/core/doc_data.cpp
index 1e72ad1090..89e7a8dc71 100644
--- a/core/doc_data.cpp
+++ b/core/doc_data.cpp
@@ -38,7 +38,7 @@ void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const Proper
} else {
p_method.return_type += "*";
}
- } else if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ } else if (p_retinfo.type == Variant::INT && p_retinfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
p_method.return_enum = p_retinfo.class_name;
if (p_method.return_enum.begins_with("_")) { //proxy class
p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length());
@@ -69,7 +69,7 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const
} else {
p_argument.type += "*";
}
- } else if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ } else if (p_arginfo.type == Variant::INT && p_arginfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
p_argument.enumeration = p_arginfo.class_name;
if (p_argument.enumeration.begins_with("_")) { //proxy class
p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length());
diff --git a/core/doc_data.h b/core/doc_data.h
index af20b717d7..1d8d2483e0 100644
--- a/core/doc_data.h
+++ b/core/doc_data.h
@@ -103,6 +103,7 @@ public:
String value;
bool is_value_valid = false;
String enumeration;
+ bool is_bitfield = false;
String description;
bool operator<(const ConstantDoc &p_const) const {
return name < p_const.name;
@@ -111,6 +112,7 @@ public:
struct EnumDoc {
String name = "@unnamed_enum";
+ bool is_bitfield = false;
String description;
Vector<DocData::ConstantDoc> values;
};
@@ -163,6 +165,7 @@ public:
Vector<ConstantDoc> constants;
HashMap<String, String> enums;
Vector<PropertyDoc> properties;
+ Vector<MethodDoc> annotations;
Vector<ThemeItemDoc> theme_properties;
bool is_script_doc = false;
String script_path;
diff --git a/core/error/error_macros.cpp b/core/error/error_macros.cpp
index 8add4b9a3a..f71a642b23 100644
--- a/core/error/error_macros.cpp
+++ b/core/error/error_macros.cpp
@@ -83,7 +83,13 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
// Main error printing function.
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify, ErrorHandlerType p_type) {
- OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, p_editor_notify, (Logger::ErrorType)p_type);
+ if (OS::get_singleton()) {
+ OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, p_editor_notify, (Logger::ErrorType)p_type);
+ } else {
+ // Fallback if errors happen before OS init or after it's destroyed.
+ const char *err_details = (p_message && *p_message) ? p_message : p_error;
+ fprintf(stderr, "ERROR: %s\n at: %s (%s:%i)\n", err_details, p_function, p_file, p_line);
+ }
_global_lock();
ErrorHandlerList *l = error_handler_list;
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 9d846f87c2..ecdb1e26dc 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -46,9 +46,12 @@ static String get_type_name(const PropertyInfo &p_info) {
return p_info.hint_string + "*";
}
}
- if (p_info.type == Variant::INT && (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM)) {
+ if (p_info.type == Variant::INT && (p_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM))) {
return String("enum::") + String(p_info.class_name);
}
+ if (p_info.type == Variant::INT && (p_info.usage & (PROPERTY_USAGE_CLASS_IS_BITFIELD))) {
+ return String("bitfield::") + String(p_info.class_name);
+ }
if (p_info.class_name != StringName()) {
return p_info.class_name;
}
@@ -665,6 +668,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
for (const StringName &F : enum_list) {
Dictionary d2;
d2["name"] = String(F);
+ d2["is_bitfield"] = ClassDB::is_enum_bitfield(class_name, F);
Array values;
List<StringName> enum_constant_list;
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h
index ccd6fb0f7e..f106b805e7 100644
--- a/core/extension/gdnative_interface.h
+++ b/core/extension/gdnative_interface.h
@@ -252,13 +252,10 @@ typedef void *GDNativeExtensionClassLibraryPtr;
typedef enum {
GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL = 1,
GDNATIVE_EXTENSION_METHOD_FLAG_EDITOR = 2,
- GDNATIVE_EXTENSION_METHOD_FLAG_NOSCRIPT = 4,
- GDNATIVE_EXTENSION_METHOD_FLAG_CONST = 8,
- GDNATIVE_EXTENSION_METHOD_FLAG_REVERSE = 16, /* used for events */
- GDNATIVE_EXTENSION_METHOD_FLAG_VIRTUAL = 32,
- GDNATIVE_EXTENSION_METHOD_FLAG_FROM_SCRIPT = 64,
- GDNATIVE_EXTENSION_METHOD_FLAG_VARARG = 128,
- GDNATIVE_EXTENSION_METHOD_FLAG_STATIC = 256,
+ GDNATIVE_EXTENSION_METHOD_FLAG_CONST = 4,
+ GDNATIVE_EXTENSION_METHOD_FLAG_VIRTUAL = 8,
+ GDNATIVE_EXTENSION_METHOD_FLAG_VARARG = 16,
+ GDNATIVE_EXTENSION_METHOD_FLAG_STATIC = 32,
GDNATIVE_EXTENSION_METHOD_FLAGS_DEFAULT = GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL,
} GDNativeExtensionClassMethodFlags;
@@ -540,7 +537,7 @@ typedef struct {
void (*classdb_register_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs);
void (*classdb_register_extension_class_method)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info);
- void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value);
+ void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield);
void (*classdb_register_extension_class_property)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter);
void (*classdb_register_extension_class_property_group)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix);
void (*classdb_register_extension_class_property_subgroup)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix);
diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp
index ebdfa20725..b69859b441 100644
--- a/core/extension/native_extension.cpp
+++ b/core/extension/native_extension.cpp
@@ -55,14 +55,7 @@ protected:
virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
GDNativePropertyInfo pinfo;
get_argument_info_func(method_userdata, p_arg, &pinfo);
- PropertyInfo ret;
- ret.type = Variant::Type(pinfo.type);
- ret.name = pinfo.name;
- ret.class_name = pinfo.class_name;
- ret.hint = PropertyHint(pinfo.hint);
- ret.usage = pinfo.usage;
- ret.class_name = pinfo.class_name;
- return ret;
+ return PropertyInfo(pinfo);
}
public:
@@ -189,7 +182,7 @@ void NativeExtension::_register_extension_class_method(const GDNativeExtensionCl
ClassDB::bind_method_custom(class_name, method);
}
-void NativeExtension::_register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value) {
+void NativeExtension::_register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield) {
NativeExtension *self = static_cast<NativeExtension *>(p_library);
StringName class_name = p_class_name;
@@ -197,23 +190,18 @@ void NativeExtension::_register_extension_class_integer_constant(const GDNativeE
//Extension *extension = &self->extension_classes[class_name];
- ClassDB::bind_integer_constant(class_name, p_enum_name, p_constant_name, p_constant_value);
+ ClassDB::bind_integer_constant(class_name, p_enum_name, p_constant_name, p_constant_value, p_is_bitfield);
}
void NativeExtension::_register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter) {
NativeExtension *self = static_cast<NativeExtension *>(p_library);
StringName class_name = p_class_name;
- ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property '" + String(p_info->name) + "' for unexisting class '" + class_name + "'.");
+ String property_name = p_info->name;
+ ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property '" + property_name + "' for unexisting class '" + class_name + "'.");
//Extension *extension = &self->extension_classes[class_name];
- PropertyInfo pinfo;
- pinfo.type = Variant::Type(p_info->type);
- pinfo.name = p_info->name;
- pinfo.class_name = p_info->class_name;
- pinfo.hint = PropertyHint(p_info->hint);
- pinfo.hint_string = p_info->hint_string;
- pinfo.usage = p_info->usage;
+ PropertyInfo pinfo(*p_info);
ClassDB::add_property(class_name, pinfo, p_setter, p_getter);
}
@@ -245,13 +233,7 @@ void NativeExtension::_register_extension_class_signal(const GDNativeExtensionCl
MethodInfo s;
s.name = p_signal_name;
for (int i = 0; i < p_argument_count; i++) {
- PropertyInfo arg;
- arg.type = Variant::Type(p_argument_info[i].type);
- arg.name = p_argument_info[i].name;
- arg.class_name = p_argument_info[i].class_name;
- arg.hint = PropertyHint(p_argument_info[i].hint);
- arg.hint_string = p_argument_info[i].hint_string;
- arg.usage = p_argument_info[i].usage;
+ PropertyInfo arg(p_argument_info[i]);
s.arguments.push_back(arg);
}
ClassDB::add_signal(class_name, s);
diff --git a/core/extension/native_extension.h b/core/extension/native_extension.h
index 8f106f753d..ca50f78621 100644
--- a/core/extension/native_extension.h
+++ b/core/extension/native_extension.h
@@ -49,7 +49,7 @@ class NativeExtension : public Resource {
static void _register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs);
static void _register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info);
- static void _register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value);
+ static void _register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield);
static void _register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter);
static void _register_extension_class_property_group(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix);
static void _register_extension_class_property_subgroup(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix);
diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt
index 5a71bcbef3..d751f6c9b8 100644
--- a/core/input/gamecontrollerdb.txt
+++ b/core/input/gamecontrollerdb.txt
@@ -2,6 +2,7 @@
# Source: https://github.com/gabomdq/SDL_GameControllerDB
# Windows
+03000000300f00000a01000000000000,3 In 1 Conversion Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,
03000000fa2d00000100000000000000,3dRudder Foot Motion Controller,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows,
03000000d0160000040d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
03000000d0160000050d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
@@ -31,6 +32,7 @@
03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000290000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows,
03000000c82d00003038000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows,
+030000003512000012ab000000000000,8BitDo NES30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Windows,
03000000c82d000012ab000000000000,8BitDo NES30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
03000000022000000090000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000203800000900000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
@@ -47,10 +49,11 @@
03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000060000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000061000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
-03000000102800000900000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
-03000000c82d000021ab000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
-03000000c82d00003028000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
-03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
+03000000102800000900000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
+03000000c82d000021ab000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
+03000000c82d00003028000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
+030000003512000020ab000000000000,8BitDo SN30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b11,x:b4,y:b3,platform:Windows,
+03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00001290000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d000020ab000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00004028000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
@@ -63,21 +66,12 @@
03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000a00500003232000000000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
-03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
+03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
-03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows,
030000008f0e00001200000000000000,Acme GA02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
03000000c01100000355000000000000,Acrux,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000fa190000f0ff000000000000,Acteck AGJ 3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-030000006d0400000bc2000000000000,Logitech WingMan Action Pad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:a5~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:a2~,start:b8,x:b3,y:b4,platform:Windows,
03000000d1180000402c000000000000,ADT1,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a3,rightx:a2,righty:a5,x:b3,y:b4,platform:Windows,
-030000006f0e00001301000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000006f0e00001302000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000006f0e00001304000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000006f0e00001413000000000000,Afterglow Xbox Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000006f0e00003901000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-03000000ab1200000103000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-03000000ad1b000000f9000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00000263000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00001101000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -85,6 +79,13 @@
030000006f0e00001402000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00001901000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00001a01000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000006f0e00001301000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000006f0e00001302000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000006f0e00001304000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000006f0e00001413000000000000,Afterglow Xbox Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000006f0e00003901000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000ab1200000103000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000ad1b000000f9000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000100000008200000000000000,Akishop Customs PS360,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000007c1800000006000000000000,Alienware Dual Compatible PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,
@@ -93,10 +94,8 @@
03000000120c0000100e000000000000,Armor 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000490b00004406000000000000,ASCII Seamic Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
03000000869800002500000000000000,Astro C40 TR PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000a30c00002700000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
+03000000a30c00002700000000000000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
-03000000ef0500000300000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,
-03000000fd0500000230000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,
03000000e4150000103f000000000000,Batarang,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000d6200000e557000000000000,Batarang PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,
@@ -121,7 +120,10 @@
030000006b1400000103000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
03000000120c0000200e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000120c0000210e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000310c000000000000,Brook Super Converter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000d81d00000b00000000000000,Buffalo BSGP1601 Series,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,
+030000005b1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
+030000005b1c00002500000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
030000006d04000042c2000000000000,ChillStream,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000457500000401000000000000,Cobra,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -135,7 +137,6 @@
03000000f806000000a3000000000000,DA Leader,a:b7,b:b6,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b8,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:b3,rightx:a2,righty:a3,start:b12,x:b4,y:b5,platform:Windows,
030000001a1c00000001000000000000,Datel Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-030000007d0400000840000000000000,Destroyer Tiltpad,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows,
03000000791d00000103000000000000,Dual Box Wii,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000c0160000e105000000000000,Dual Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
030000004f040000070f000000000000,Dual Power,a:b8,b:b9,back:b4,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,leftshoulder:b13,leftstick:b6,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b12,rightstick:b7,righttrigger:b15,start:b5,x:b10,y:b11,platform:Windows,
@@ -158,25 +159,21 @@
030000006e0500001320000000000000,Elecom U4113,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006e0500001020000000000000,Elecom U4113S,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,
030000006e0500000720000000000000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
+030000007d0400000640000000000000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Windows,
03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000430b00000300000000000000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
03000000242f000000b7000000000000,ESM 9110,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows,
03000000101c0000181c000000000000,Essential,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b4,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
03000000341a00000108000000000000,EXEQ RF Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-03000000790000003018000000000000,Mayflash F300 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-03000000242f00003900000000000000,Mayflash F300 Elite Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00008401000000000000,Faceoff Deluxe Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00008001000000000000,Faceoff Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000021000000090000000000000,FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
0300000011040000c600000000000000,FC801,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000852100000201000000000000,FF GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700002847000000000000,Xbox 360 Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000ad1b000028f0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000ad1b00002ef0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000ad1b000038f0000000000000,Fightpad TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
-03000000380700001847000000000000,Mad Catz Street Fighter 4 Xbox 360 FightStick,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
-03000000380700008031000000000000,Mad Catz FightStick Alpha PS3 ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000f806000001a3000000000000,Firestorm,a:b9,b:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b10,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b12,x:b8,y:b4,platform:Windows,
03000000b50700000399000000000000,Firestorm 2,a:b2,b:b4,back:b10,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b9,start:b11,x:b3,y:b5,platform:Windows,
03000000b50700001302000000000000,Firestorm D3,a:b0,b:b2,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,x:b1,y:b3,platform:Windows,
@@ -184,15 +181,14 @@
03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,platform:Windows,
03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Windows,
03000000b40400001224000000000000,Flydigi Vader 2 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,paddle3:b17,paddle4:b18,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
-030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows,
+030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows,
0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,
03000000260900002625000000000000,GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,
03000000341a000005f7000000000000,GameCube Controller,a:b2,b:b3,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b1,y:b0,platform:Windows,
03000000430b00000500000000000000,GameCube Controller,a:b0,b:b2,dpdown:b10,dpleft:b8,dpright:b9,dpup:b11,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a3,rightx:a5,righty:a2,start:b7,x:b1,y:b3,platform:Windows,
03000000790000004718000000000000,GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
-03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b0,x:b2,y:b3,start:b9,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,rightshoulder:b7,lefttrigger:a3,righttrigger:a4,platform:Windows,
+03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
030000008f0e00000d31000000000000,Gamepad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000280400000140000000000000,GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000ac0500003d03000000000000,GameSir G3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000ac0500005b05000000000000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
@@ -217,41 +213,40 @@
030000004f04000026b3000000000000,GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
0300000079000000d418000000000000,GPD Win,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000c6240000025b000000000000,GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000007d0400000540000000000000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-030000007d0400000340000000000000,Gravis G44011 Xterminator,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a2,start:b9,x:b3,y:b4,platform:Windows,
+030000007d0400000840000000000000,Gravis Destroyer Tilt,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows,
+030000007d0400000540000000000000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
+03000000280400000140000000000000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a3,dpup:-a4,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00000610000000000000,GreenAsia,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a5,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
03000000ac0500006b05000000000000,GT2a,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000fd0500003902000000000000,InterAct Hammerhead,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,rightshoulder:b7,rightstick:b5,righttrigger:b9,start:b10,x:b0,y:b1,platform:Windows,
-03000000fd0500002a26000000000000,InterAct Hammerhead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,
-03000000fd0500002f26000000000000,InterAct Hammerhead FX,a:b4,b:b5,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b1,y:b2,platform:Windows,
-030000000d0f00004900000000000000,Hatsune Miku Sho PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00004900000000000000,Hatsune Miku Sho PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000001008000001e1000000000000,Havit HV G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,
030000000d0f00000c00000000000000,HEXT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000d81400000862000000000000,HitBox Edition Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
03000000632500002605000000000000,HJD X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
030000000d0f00000a00000000000000,Hori DOA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000000d0f00005100000000000000,Hori Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008600000000000000,Hori Fighting Commander,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000000d0f0000ba00000000000000,Hori Fighting Commander,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f00008500000000000000,Hori Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00002500000000000000,Hori Fighting Commander 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00005f00000000000000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00005e00000000000000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00008400000000000000,Hori Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00005100000000000000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00008600000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000000d0f0000ba00000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f00001000000000000000,Hori Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000f0d00000010000000000000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00003200000000000000,Hori Fightstick 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f0000c000000000000000,Hori Fightstick 4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f00000d00000000000000,Hori Fightstick EX2,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
030000000d0f00003701000000000000,Hori Fightstick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Windows,
030000000d0f00004000000000000000,Hori Fightstick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008700000000000000,Hori Fightstick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008800000000000000,Hori Fightstick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
+030000000d0f00008700000000000000,Hori Fightstick Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00008800000000000000,Hori Fightstick Mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
030000000d0f00002100000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00002700000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f0000a000000000000000,Hori Grip TAC4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b13,x:b0,y:b3,platform:Windows,
+030000000d0f0000a500000000000000,Hori Miku Project Diva X HD PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f0000a600000000000000,Hori Miku Project Diva X HD PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00000101000000000000,Hori Mini Hatsune Miku FT,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00005400000000000000,Hori Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -289,27 +284,33 @@
030000000d0f00006600000000000000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00004200000000000000,Horipad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000ad1b000001f5000000000000,Horipad EXT2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000005b1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
030000000d0f0000ee00000000000000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows,
-03000000790000004e95000000000000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,
+03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,
+03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows,
03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000d81d00001000000000000000,iBuffalo BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
030000005c0a00000285000000000000,iDroidCon,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b6,platform:Windows,
03000000696400006964000000000000,iDroidCon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000b50700001403000000000000,Impact Black,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
030000006f0e00002401000000000000,Injustice Fightstick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-03000000830500005130000000000000,InterAct ActionPad,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
+03000000830500005130000000000000,InterAct ActionPad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
+03000000ef0500000300000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,
+03000000fd0500000230000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,
+03000000fd0500000030000000000000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,
+03000000fd0500003902000000000000,InterAct Hammerhead,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,rightshoulder:b7,rightstick:b5,righttrigger:b9,start:b10,x:b0,y:b1,platform:Windows,
+03000000fd0500002a26000000000000,InterAct Hammerhead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,
+03000000fd0500002f26000000000000,InterAct Hammerhead FX,a:b4,b:b5,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b1,y:b2,platform:Windows,
03000000fd0500005302000000000000,InterAct ProPad,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,
03000000ac0500002c02000000000000,Ipega Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000491900000204000000000000,Ipega PG9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000491900000304000000000000,Ipega PG9087,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,
030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,
030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
+03000000250900000017000000000000,Joypad Adapter,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,
03000000bd12000003c0000000000000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000250900000017000000000000,Joypad to Adapter,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,
03000000ff1100004033000000000000,JPD FFB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a2,start:b15,x:b3,y:b0,platform:Windows,
03000000242f00002d00000000000000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000242f00008a00000000000000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
@@ -331,6 +332,7 @@
030000006d0400001fc2000000000000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000006d0400001ac2000000000000,Logitech Precision,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000009c2000000000000,Logitech WingMan,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
+030000006d0400000bc2000000000000,Logitech WingMan Action Pad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:a5~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:a2~,start:b8,x:b3,y:b4,platform:Windows,
030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,
03000000380700005645000000000000,Lynx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000222200006000000000000000,Macally,a:b1,b:b2,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -340,41 +342,44 @@
03000000380700006652000000000000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000380700005032000000000000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000380700005082000000000000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000380700008031000000000000,Mad Catz FightStick Alpha PS3 ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000003807000038b7000000000000,Mad Catz Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
03000000380700008433000000000000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000380700008483000000000000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000380700008134000000000000,Mad Catz Fightstick TE2 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000380700008184000000000000,Mad Catz Fightstick TE2 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-78696e70757403000000000000000000,Mad Catz Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,
03000000380700006252000000000000,Mad Catz Micro CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000380700008232000000000000,Mad Catz PlayStation Brawlpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000380700008731000000000000,Mad Catz PlayStation Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000003807000056a8000000000000,Mad Catz PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000380700001888000000000000,Mad Catz SFIV Fightstick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000380700008081000000000000,Mad Catz SFV Arcade Fightstick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000380700001847000000000000,Mad Catz Street Fighter 4 Xbox 360 FightStick,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,
+03000000790000003018000000000000,Mayflash F300 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
+03000000242f00003900000000000000,Mayflash F300 Elite Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00001030000000000000,Mayflash Sega Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,
-0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
-03000000790000000018000000000000,Mayflash WiiU Pro Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
+03000000790000000318000000000000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
+03000000790000000018000000000000,Mayflash Wii U Pro Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000790000002418000000000000,Mega Drive Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows,
0300000079000000ae18000000000000,Mega Drive Controller,a:b0,b:b1,back:b7,dpdown:b14,dpleft:b15,dpright:b13,dpup:b2,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
-03000000c0160000990a000000000000,Mega Drive Controller,a:b0,b:b1,leftx:a0,lefty:a1,righttrigger:b2,start:b3,platform:Windows,
+03000000c0160000990a000000000000,Mega Drive Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,righttrigger:b2,start:b3,platform:Windows,
030000005e0400002800000000000000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Windows,
030000005e0400000300000000000000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
030000005e0400000700000000000000,Microsoft SideWinder,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
030000005e0400000e00000000000000,Microsoft SideWinder Freestyle Pro,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b8,x:b3,y:b4,platform:Windows,
030000005e0400002700000000000000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Windows,
03000000280d00000202000000000000,Miller Lite Cantroller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b5,x:b2,y:b3,platform:Windows,
-030000005b1c00002500000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
03000000ad1b000023f0000000000000,MLG,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a6,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
03000000ad1b00003ef0000000000000,MLG Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
03000000380700006382000000000000,MLG PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -388,6 +393,7 @@
03000000c62400001b89000000000000,Moga XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
+03000000091200004488000000000000,MUSIA PlayStation 2 Input Display,a:b0,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:b11,rightx:a2,righty:a3,start:b5,x:b1,y:b3,platform:Windows,
03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows,
030000006b140000010c000000000000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -398,9 +404,8 @@
0300000038070000efbe000000000000,NEO SE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
0300000092120000474e000000000000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Windows,
03000000921200004b46000000000000,NES 2 port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,
-03000000000f00000100000000000000,NES Controller,a:b1,b:b0,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
-03000000571d00002100000000000000,NES Controller,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
-03000000921200004346000000000000,NES Controller,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
+03000000000f00000100000000000000,NES Controller,a:b1,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,
+03000000921200004346000000000000,NES Controller,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,
03000000790000004518000000000000,NEXILUX GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows,
03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows,
@@ -434,6 +439,7 @@
03000000d9040000160f000000000000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+0300000062060000d570000000000000,PowerA PS3 Contoller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d620000013a7000000000000,PowerA Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000084ca000000000000,Precision,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
03000000d62000009557000000000000,Pro Elite PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -494,6 +500,7 @@
03000000300f00000211000000000000,Qanba 2P,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000300f00000011000000000000,Qanba Arcade Stick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,
03000000300f00001611000000000000,Qanba Arcade Stick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
+03000000222c00000025000000000000,Qanba Dragon Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000222c00000020000000000000,Qanba Drone Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00001211000000000000,Qanba Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00001210000000000000,Qanba Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
@@ -502,6 +509,7 @@
03000000222c00000023000000000000,Qanba Obsidian Arcade Stick PS4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000008a2400006682000000000000,R1 Mobile Controller,a:b3,b:b1,back:b7,leftx:a0,lefty:a1,start:b6,x:b4,y:b0,platform:Windows,
03000000086700006626000000000000,RadioShack,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,
+03000000ff1100004733000000000000,Ramox FPS Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,
030000009b2800002300000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,
030000009b2800006900000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,
030000009b2800000800000000000000,Raphnet Dreamcast Adapter,a:b2,b:b1,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,lefttrigger:a2,leftx:a0,righttrigger:a3,righty:a1,start:b3,x:b10,y:b9,platform:Windows,
@@ -509,11 +517,12 @@
030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows,
030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,
+030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows,
030000009b2800004300000000000000,Raphnet Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
-030000009b2800000500000000000000,Raphnet Saturn Adapter 2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
+030000009b2800000500000000000000,Raphnet Saturn Adapter 2.0,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
030000009b2800000300000000000000,Raphnet SNES Adapter,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
-030000009b2800005600000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,
-030000009b2800005700000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,
+030000009b2800005600000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,
+030000009b2800005700000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,
030000009b2800001e00000000000000,Raphnet Vectrex Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a1,lefty:a2,x:b2,y:b3,platform:Windows,
030000009b2800002b00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,
030000009b2800002c00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,
@@ -529,12 +538,14 @@
03000000321500000910000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000321500000011000000000000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000632500008005000000010000,Redgear,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,guide:b12,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,
+03000000921200004547000000000000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b6,x:b3,y:b4,platform:Windows,
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
03000000bd12000013d0000000000000,Retrolink Sega Saturn Classic Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,
03000000bd12000015d0000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
-0300000000f000000300000000000000,RetroUSB RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
-0300000000f00000f100000000000000,RetroUSB Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
+0300000000f000000300000000000000,RetroUSB RetroPad,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
+0300000000f00000f100000000000000,RetroUSB Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
03000000830500000960000000000000,Revenger,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b5,platform:Windows,
030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000006b140000020d000000000000,Revolution Pro Controller 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -576,25 +587,25 @@
03000000411200004550000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a1,righty:a2,start:b9,x:b1,y:b3,platform:Windows,
03000000c01100004150000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
03000000c01100004450000000000000,Sanwa Online Grip,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b14,x:b3,y:b4,platform:Windows,
-03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
+03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,
03000000830500006120000000000000,Sanwa Smart Grip II,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,x:b1,y:b3,platform:Windows,
03000000c01100000051000000000000,Satechi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
030000004f04000028b3000000000000,Score A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000952e00002577000000000000,Scuf PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000a30c00002500000000000000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Windows,
03000000a30c00002400000000000000,Sega Mega Drive Mini 6B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
-0300000000050000289b000000000000,Sega Saturn Adapter,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
-0300000000f000000800000000000000,Sega Saturn Controller,a:b1,b:b2,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b3,start:b0,x:b5,y:b6,platform:Windows,
+0300000000050000289b000000000000,Sega Saturn Adapter,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
+0300000000f000000800000000000000,Sega Saturn Controller,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b7,righttrigger:b3,start:b0,x:b5,y:b6,platform:Windows,
03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
-03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
+03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows,
+03000000f82100001900000000000000,Shogun Bros Chameleon X1,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
03000000120c00001c1e000000000000,SnakeByte 4S PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-0300000003040000c197000000000000,SNES Controller,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
-03000000571d00002000000000000000,SNES Controller,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
-0300000081170000960a000000000000,SNES Controller,a:b4,b:b0,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b5,y:b1,platform:Windows,
+0300000003040000c197000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
+0300000081170000960a000000000000,SNES Controller,a:b4,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b5,y:b1,platform:Windows,
03000000811700009d0a000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
030000008b2800000300000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
-03000000921200004653000000000000,SNES Controller,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
+03000000921200004653000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
03000000ff000000cb01000000000000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00000208000000000000,Speedlink 6555,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00000908000000000000,Speedlink 6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
@@ -608,18 +619,20 @@
03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000381000001214000000000000,SteelSeries Free,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000381000003014000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows,
03000000790000001c18000000000000,STK 7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-03000000381000003014000000000000,Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-03000000381000003114000000000000,Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000380700003847000000000000,Street Fighter Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows,
-030000001f08000001e4000000000000,Super Famicom Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
+030000001f08000001e4000000000000,Super Famicom Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000790000000418000000000000,Super Famicom Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
+03000000341200001300000000000000,Super Racer,a:b2,b:b3,back:b8,leftshoulder:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b7,x:b0,y:b1,platform:Windows,
03000000d620000011a7000000000000,Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f0000f600000000000000,Switch Hori,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
+030000000d0f0000f600000000000000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000457500002211000000000000,Szmy Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000004f0400000ab1000000000000,T16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,
030000000d0f00007b00000000000000,TAC GEAR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000e40a00000207000000000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Windows,
03000000d814000001a0000000000000,TE Kitty,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
@@ -631,12 +644,14 @@
030000004f0400000ed0000000000000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000008d0000000000000,ThrustMaster Ferrari 150 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,
-030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
+030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
030000004f04000003d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000009d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000088ca000000000000,Thunderpad,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
03000000666600000488000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
030000004f04000007d0000000000000,TMini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000571d00002100000000000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Windows,
+03000000571d00002000000000000000,Tomee SNES Controller Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000d62000006000000000000000,Tournament PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000c01100000055000000000000,Tronsmart,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -644,6 +659,7 @@
030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows,
03000000411200000450000000000000,Twin Shock,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a4,start:b11,x:b3,y:b0,platform:Windows,
03000000d90400000200000000000000,TwinShock PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
+03000000151900005678000000000000,Uniplay U6,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b10,x:b3,y:b4,platform:Windows,
03000000101c0000171c000000000000,uRage Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
030000000b0400003065000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,
03000000242f00006e00000000000000,USB Controller,a:b1,b:b4,back:b10,leftshoulder:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b3,platform:Windows,
@@ -664,7 +680,7 @@
030000006f0e00000702000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:a3,righty:a4,start:b4,x:b2,y:b3,platform:Windows,
03000000120c0000ab57000000000000,Warrior Joypad JS083,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000007e0500003003000000000000,WiiU Pro,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b6,leftstick:b11,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b12,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
+030000007e0500003003000000000000,Wii U Pro,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b6,leftstick:b11,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b12,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
0300000032150000030a000000000000,Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
0300000032150000140a000000000000,Wolverine,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000002e160000efbe000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows,
@@ -683,6 +699,7 @@
03000000ad1b00008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000c62400000053000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000c6240000fdfa000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000380700002847000000000000,Xbox 360 Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000005e040000a102000000000000,Xbox 360 Wireless Receiver,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000120c00000a88000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
@@ -716,17 +733,19 @@
03000000172700004431000000000000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000007d0400000340000000000000,Xterminator Digital Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:-a4,lefttrigger:+a4,leftx:a0,lefty:a1,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b9,righttrigger:b2,rightx:a3,righty:a5,start:b8,x:b3,y:b4,platform:Windows,
03000000790000004f18000000000000,ZDT Android Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000120c0000101e000000000000,Zeroplus P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
# Mac OS X
-030000008f0e00000300000009010000,2In1 Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
+030000008f0e00000300000009010000,2 In 1 Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000c82d00000031000001000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c82d00000531000000020000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000a30c00002400000006020000,8BitDo M30,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,guide:b9,leftshoulder:b6,lefttrigger:b5,rightshoulder:b4,righttrigger:b7,start:b8,x:b3,y:b0,platform:Mac OS X,
03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
-03000000c82d00005106000000010000,8BitDo M30,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d00005106000000010000,8BitDo M30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b2,leftshoulder:b6,lefttrigger:a5,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
030000003512000012ab000001000000,8BitDo NES30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
@@ -741,8 +760,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000231000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000331000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000431000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
-03000000102800000900000000000000,8BitDo SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
-03000000c82d00001290000001000000,8BitDo SN30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000102800000900000000000000,8BitDo SFC30 Joystick,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d00001290000001000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00004028000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,
@@ -750,14 +769,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000a00500003232000009010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
-03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
-03000000a30c00002700000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
+03000000a30c00002700000003030000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000a30c00002800000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
-03000000ef0500000300000000020000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,
03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -768,8 +786,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000a306000022f6000001030000,Cyborg V3 Rumble Pad PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000791d00000103000009010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
-030000000d0f00008400000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000000d0f00008500000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000006f0e00008401000003010000,Faceoff Premiere Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Mac OS X,
03000000790000004618000000010000,GameCube Controller Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,
@@ -777,22 +794,28 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006f0e00000102000000000000,GameStop Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-030000007d0400000540000001010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
-03000000280400000140000000020000,Gravis Gamepad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000007d0400000540000001010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
+03000000280400000140000000020000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00000300000007010000,GreenAsia Joystick,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Mac OS X,
030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005f00000000000000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005f00000000010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005e00000000000000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005e00000000010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000000d0f00008400000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000000d0f00008500000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00004d00000000000000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000000d0f00003801000008010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Mac OS X,
030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006e00000000010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006600000000010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006600000000000000,Horipad FPS Plus 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f0000ee00000000010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X,
-03000000830500006020000000000000,iBuffalo Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
+03000000790000004e95000000010000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Mac OS X,
+03000000830500006020000000000000,iBuffalo Gamepad,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
+03000000ef0500000300000000020000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,
+03000000fd0500000030000010010000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Mac OS X,
030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Mac OS X,
030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000242f00002d00000007010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
@@ -810,14 +833,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000380700005082000000010000,Mad Catz PS4 Fightpad Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000380700008483000000010000,Mad Catz PS4 Fightstick TE S+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000790000000600000007010000,Marvo GT-004,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
+03000000790000004318000000010000,Mayflash GameCube Adapter,a:b4,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,
03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,
-03000000790000004318000000010000,Mayflash GameCube Adapter,a:b4,b:b0,x:b8,y:b12,start:b36,rightshoulder:b28,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a4,rightx:a20,righty:a8,lefttrigger:a12,righttrigger:a16,platform:Mac OS X,
03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X,
0300000079000000d218000026010000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000d620000010a7000003010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,
-03000000790000000018000000010000,Mayflash Wii U Pro Controller Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
-03000000790000000018000000000000,Mayflash WiiU Pro Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
+0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,
+03000000790000000318000000010000,Mayflash Wii DolphinBar,a:b8,b:b12,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b44,leftshoulder:b16,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b4,platform:Mac OS X,
+03000000790000000018000000000000,Mayflash Wii U Pro Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
+03000000790000000018000000010000,Mayflash Wii U Pro Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
030000005e0400002800000002010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Mac OS X,
030000005e0400002700000001010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,
03000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
@@ -835,18 +859,20 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,
030000006f0e00000901000002010000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
-030000004c050000da0c000000010000,PlayStation Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
+030000004c050000da0c000000010000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
030000004c0500003713000000010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000100800000300000006010000,PS2 Adapter,a:b2,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
-030000004c0500006802000072050000,PS3 Controller,a:b14,b:b13,x:b15,y:b12,back:b0,guide:b16,start:b3,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpdown:b6,dpleft:b7,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Mac OS X,
+030000004c0500006802000072050000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
030000004c050000a00b000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
+03000000222c00000225000000010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000222c00000020000000010000,Qanba Drone Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000321500000204000000010000,Razer Panthera PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -857,6 +883,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
+030000000d0f0000c100000072050000,Retro Bit Sega Genesis 6B Controller,a:b2,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b8,rightshoulder:b6,righttrigger:b7,start:b9,x:b3,y:b0,platform:Mac OS X,
+03000000921200004547000000020000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b2,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,lefttrigger:b14,rightshoulder:b10,righttrigger:b4,start:b12,x:b6,y:b8,platform:Mac OS X,
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000790000001100000005010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,
@@ -864,31 +892,37 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006b140000130d000000010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000c6240000fefa000000000000,Rock Candy PS3,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Mac OS X,
+03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Mac OS X,
+03000000a30c00002500000006020000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Mac OS X,
03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,
-03000000b40400000a01000000000000,Sega Saturn,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,
-030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000b40400000a01000000000000,Sega Saturn,a:b0,b:b1,back:b5,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b2,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,
+030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,
-030000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000a00b000000000000,Sony DualShock 4 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,
+03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
05000000484944204465766963650000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
050000004e696d6275732b008b000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
05000000556e6b6e6f776e2048494400,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
+03000000381000003014000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
+03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
+030000000d0f0000f600000000010000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
030000004f0400000ed0000000020000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
+03000000571d00002100000021000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Mac OS X,
03000000bd12000015d0000000010000,Tomee Retro Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000bd12000015d0000000000000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
+03000000571d00002000000021000000,Tomee SNES Controller Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,
+030000005f140000c501000000020000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
030000006f0e00000302000025040000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006f0e00000702000003060000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -912,6 +946,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
030000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
+030000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000120c0000100e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000120c0000101e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -926,7 +961,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux,
03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
-03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
+03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
03000000022000000090000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
@@ -943,9 +978,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
030000003512000012ab000010010000,8BitDo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,
030000003512000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
-03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
-05000000102800000900000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
-05000000c82d00003028000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
+03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
+05000000102800000900000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
+05000000c82d00003028000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,
@@ -955,9 +990,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
-05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
+05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
05000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
-03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
+03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
050000005e040000e002000030110000,8BitDo Zero 2,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000c01100000355000011010000,Acrux Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -971,7 +1006,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux,
05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
+03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
05000000050b00000045000031000000,Asus Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
05000000050b00000045000040000000,Asus Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
@@ -986,8 +1021,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000503200000210000045010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
05000000503200000210000046010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
05000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:-a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux,
-03000000120c00000500000010010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,
-03000000ef0500000300000000010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,
03000000c62400001b89000011010000,BDA MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000c21100000791000011010000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
@@ -1005,12 +1038,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-030000004f04000004b3000010010000,Dual Power 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000242f00009100000000010000,EasySMX ESM-9101,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
030000006e0500000720000010010000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,
+030000007d0400000640000010010000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Linux,
03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
@@ -1025,23 +1058,23 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000007d0400000540000000010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-03000000280400000140000000010000,Gravis Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
+030000007d0400000540000000010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
+03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,
030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
06000000adde0000efbe000002010000,Hidromancer Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
+03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000632500002605000010010000,HJDX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,
030000000d0f00006d00000020010000,Hori EDGE 301,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:+a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000000d0f00008500000010010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f00008600000002010000,Hori Fighting Commander,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00001000000011010000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000ad1b000003f5000033050000,Hori Fightstick VX,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b8,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00004d00000011010000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1049,6 +1082,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux,
030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f0000aa00000011010000,Hori Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+030000000d0f00001100000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1062,10 +1096,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,
03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,
-03000000fd0500000030000000010000,InterAct GoPad I73000,a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,
+03000000120c00000500000010010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,
+03000000ef0500000300000000010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,
+03000000fd0500000030000000010000,InterAct GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Linux,
03000000fd0500002a26000000010000,InterAct HammerHead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
0500000049190000020400001b010000,Ipega PG 9069,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000632500007505000011010000,Ipega PG 9099,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
@@ -1109,28 +1146,29 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
-03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
+03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,
0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000242f0000f700000001010000,Mayflash Magic S Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-0300000025090000e803000001010000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
-03000000b50700001203000010010000,Mega World Logic 3 Controller,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,platform:Linux,
+0300000025090000e803000001010000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
+03000000790000000318000011010000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,
+03000000b50700001203000010010000,Mega World Logic 3 Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000780000000600000010010000,Microntek Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
030000005e0400002800000000010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Linux,
030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
-030000005e0400000700000000010000,Microsoft SideWinder Gamepad,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux,
+030000005e0400000700000000010000,Microsoft SideWinder Gamepad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux,
030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux,
030000005e0400008502000000010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e0400008e02000001000000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.1,dpleft:h0.2,dpright:h0.8,dpup:h0.4,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000004010000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000056210000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000062230000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e040000120b00000b050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000d102000001010000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000d102000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000120b00000b050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000dd02000003020000,Microsoft Xbox One 2015,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -1147,14 +1185,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000c62400001a89000000010000,MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
-030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
+030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
+03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux,
03000000790000004518000010010000,Nexilux GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux,
-050000004e696d6275732b0000000000,Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux,
060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux,
@@ -1189,6 +1228,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e0000b802000001010000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000b802000013020000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00008001000011010000,PDP Faceoff Nintendo Switch Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -1203,12 +1243,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
03000000c62400001a53000000010000,PowerA Mini Pro Ex,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000c62400001a58000001010000,PowerA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000000220000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1240,9 +1282,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
+030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
+050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,
+03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux,
+03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,
030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
@@ -1286,16 +1334,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux,
03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux,
03000000790000002201000011010000,Sega Saturn,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
-03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux,
-030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
+03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux,
+030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000632500007505000010010000,Shanwan PS3 PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000bc2000000055000010010000,Shanwan PS3 PC ,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
-030000005f140000c501000010010000,Shanwan Trust,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
-050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
@@ -1303,23 +1348,25 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
+03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
-03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
+03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux,
03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000ad1b000038f0000090040000,Street Fighter IV Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000003b07000004a1000000010000,Suncom SFX Plus,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,
+030000003b07000004a1000000010000,Suncom SFX Plus,a:b0,b:b2,back:b7,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,
03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
-0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
+0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
030000008f0e00000d31000010010000,SZMY Power 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000457500002211000010010000,SZMY Power Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1332,17 +1379,19 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux,
030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux,
030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,
+030000004f04000004b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000026b3000002040000,Thrustmaster GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c6240000025b000002020000,Thrustmaster GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000004f04000008d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000004f04000009d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000004f04000007d0000000010000,Thrustmaster T Mini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000004f04000012b3000010010000,Thrustmaster vibrating,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
+030000004f04000012b3000010010000,Thrustmaster Vibrating Gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
03000000571d00002000000010010000,Tomee SNES Adapter,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
03000000bd12000015d0000010010000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000d814000007cd000011010000,Toodles 2008 Chimp PC PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,
030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
@@ -1396,13 +1445,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
# Android
38653964633230666463343334313533,8BitDo Adapter,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
36666264316630653965636634386234,8BitDo Adapter 2,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b19,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
-38426974446f20417263616465205374,8BitDo Arcade Stick,a:b0,b:b1,back:b15,guide:b5,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+38426974446f20417263616465205374,8BitDo Arcade Stick,a:b0,b:b1,back:b15,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b5,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
61393962646434393836356631636132,8BitDo Arcade Stick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b19,y:b2,platform:Android,
64323139346131306233636562663738,8BitDo Arcade Stick,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android,
64643565386136613265663236636564,8BitDo Arcade Stick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b19,y:b2,platform:Android,
34343439373236623466343934376233,8BitDo FC30 Pro,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b28,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b29,righttrigger:b7,start:b5,x:b30,y:b2,platform:Android,
-05000000c82d000006500000ffff3f00,8BitDo M30,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android,
-05000000c82d000051060000ffff3f00,8BitDo M30,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000006500000ffff3f00,8BitDo M30,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b17,leftshoulder:b9,lefttrigger:a5,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000051060000ffff3f00,8BitDo M30,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b17,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b3,y:b2,platform:Android,
33656266353630643966653238646264,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:a5,start:b10,x:b19,y:b2,platform:Android,
39366630663062373237616566353437,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,start:b6,x:b2,y:b3,platform:Android,
64653533313537373934323436343563,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b10,start:b6,x:b2,y:b3,platform:Android,
@@ -1422,9 +1471,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000c82d000000600000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
05000000c82d000000610000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
38426974646f20534633302050726f00,8BitDo SF30 Pro,a:b1,b:b0,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b17,platform:Android,
-61623334636338643233383735326439,8BitDo SFC30,a:b0,b:b1,back:b4,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b31,start:b5,x:b30,y:b2,platform:Android,
-05000000c82d000012900000ffff3f00,8BitDo SN30,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
-05000000c82d000062280000ffff3f00,8BitDo SN30,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+61623334636338643233383735326439,8BitDo SFC30,a:b0,b:b1,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b3,rightshoulder:b31,start:b5,x:b30,y:b2,platform:Android,
+05000000c82d000012900000ffff3f00,8BitDo SN30,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000062280000ffff3f00,8BitDo SN30,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
35383531346263653330306238353131,8BitDo SN30 PP,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
05000000c82d000001600000ffff3f00,8BitDo SN30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
36653638656632326235346264663661,8BitDo SN30 Pro Plus,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android,
@@ -1436,16 +1485,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000c82d000002600000ffff0f00,8BitDo SN30 Pro+,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
050000002028000009000000ffff3f00,8BitDo SNES30,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
050000003512000020ab000000780f00,8BitDo SNES30,a:b21,b:b20,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b24,y:b23,platform:Android,
-33666663316164653937326237613331,8BitDo Zero,a:b0,b:b1,back:b15,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,platform:Android,
-38426974646f205a65726f2047616d65,8BitDo Zero,a:b0,b:b1,back:b15,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,platform:Android,
-05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
-05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+33666663316164653937326237613331,8BitDo Zero,a:b0,b:b1,back:b15,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b2,y:b3,platform:Android,
+38426974646f205a65726f2047616d65,8BitDo Zero,a:b0,b:b1,back:b15,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b2,y:b3,platform:Android,
+05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
33663434393362303033616630346337,8BitDo Zero 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,start:b18,x:b19,y:b2,platform:Android,
34656330626361666438323266633963,8BitDo Zero 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b20,start:b10,x:b19,y:b2,platform:Android,
63396666386564393334393236386630,8BitDo Zero 2,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
63633435623263373466343461646430,8BitDo Zero 2,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,platform:Android,
32333634613735616163326165323731,Amazon Luna Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
-417374726f2063697479206d696e6920,Astro City Mini,a:b23,b:b22,back:b29,leftx:a0,lefty:a1,rightshoulder:b25,righttrigger:b26,start:b30,x:b24,y:b21,platform:Android,
+417374726f2063697479206d696e6920,Astro City Mini,a:b23,b:b22,back:b29,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b25,righttrigger:b26,start:b30,x:b24,y:b21,platform:Android,
+32303165626138343962363666346165,Brook Mars PS4 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
38383337343564366131323064613561,Brook Mars PS4 Controller,a:b1,b:b19,back:b17,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
30363230653635633863366338623265,Evo VR,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,x:b2,y:b3,platform:Android,
05000000b404000011240000dfff3f00,Flydigi Vader 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
@@ -1464,12 +1514,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b2,y:b3,platform:Android,
64306137363261396266353433303531,InterAct GoPad,a:b24,b:b25,leftshoulder:b23,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,x:b21,y:b22,platform:Android,
532e542e442e20496e74657261637420,InterAct HammerHead FX,a:b23,b:b24,back:b30,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b22,lefttrigger:b28,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b25,righttrigger:b29,rightx:a2,righty:a3,start:b31,x:b20,y:b21,platform:Android,
-65346535636333663931613264643164,Joy Con,a:b21,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b23,y:b24,platform:Android,
-33346566643039343630376565326335,Joy Con (L),a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b17,x:b19,y:b2,platform:Android,
-35313531613435623366313835326238,Joy Con (L),a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b17,x:b19,y:b2,platform:Android,
-38383665633039363066383334653465,Joy Con (R),a:b0,b:b1,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b18,x:b19,y:b2,platform:Android,
-39363561613936303237333537383931,Joy Con (R),a:b0,b:b1,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b18,x:b19,y:b2,platform:Android,
+65346535636333663931613264643164,Joy-Con,a:b21,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b23,y:b24,platform:Android,
+33346566643039343630376565326335,Joy-Con (L),a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b17,x:b19,y:b2,platform:Android,
+35313531613435623366313835326238,Joy-Con (L),a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b17,x:b19,y:b2,platform:Android,
4a6f792d436f6e20284c290000000000,Joy-Con (L),a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,rightshoulder:b20,start:b17,x:b19,y:b2,platform:Android,
+38383665633039363066383334653465,Joy-Con (R),a:b0,b:b1,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b18,x:b19,y:b2,platform:Android,
+39363561613936303237333537383931,Joy-Con (R),a:b0,b:b1,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b18,x:b19,y:b2,platform:Android,
4a6f792d436f6e202852290000000000,Joy-Con (R),a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,rightshoulder:b20,start:b18,x:b19,y:b2,platform:Android,
39656136363638323036303865326464,JYS Aapter,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
63316564383539663166353034616434,JYS Adapter,a:b1,b:b3,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b0,y:b2,platform:Android,
@@ -1482,22 +1532,21 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
30363066623539323534363639323363,Magic NS,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
31353762393935386662336365626334,Magic NS,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
39623565346366623931666633323530,Magic NS,a:b1,b:b3,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b0,y:b2,platform:Android,
-32303165626138343962363666346165,Brook Mars PS4 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
-6d6179666c617368206c696d69746564,Mayflash GameCube Adapter,a:b22,b:b21,x:b23,y:b24,start:b30,rightshoulder:b28,lefttrigger:b25,righttrigger:b26,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Android,
-65666330633838383061313633326461,Mayflash N64 Adapter,a:b1,b:b19,leftshoulder:b3,rightshoulder:b20,lefttrigger:b9,start:b18,guide:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,platform:Android,
-436f6e74726f6c6c6572000000000000,Mayflash N64 Adapter,a:b1,b:b19,leftshoulder:b3,rightshoulder:b20,lefttrigger:b9,start:b18,guide:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,platform:Android,
-31323564663862633234646330373138,Mega Drive,a:b23,b:b22,leftx:a0,lefty:a1,rightshoulder:b25,righttrigger:b26,start:b30,x:b24,y:b21,platform:Android,
+6d6179666c617368206c696d69746564,Mayflash GameCube Adapter,a:b22,b:b21,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a5,righty:a2,start:b30,x:b23,y:b24,platform:Android,
+436f6e74726f6c6c6572000000000000,Mayflash N64 Adapter,a:b1,b:b19,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a2,righty:a3,start:b18,platform:Android,
+65666330633838383061313633326461,Mayflash N64 Adapter,a:b1,b:b19,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a2,righty:a3,start:b18,platform:Android,
+31323564663862633234646330373138,Mega Drive,a:b23,b:b22,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b25,righttrigger:b26,start:b30,x:b24,y:b21,platform:Android,
37333564393261653735306132613061,Mega Drive,a:b21,b:b22,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,lefttrigger:b28,rightshoulder:b27,righttrigger:b23,start:b30,x:b24,y:b25,platform:Android,
64363363336633363736393038313464,Mega Drive,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Android,
33323763323132376537376266393366,Microsoft Dual Strike,a:b24,b:b23,back:b25,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b29,rightshoulder:b78,rightx:a0,righty:a1~,start:b26,x:b22,y:b21,platform:Android,
-30306461613834333439303734316539,Microsoft SideWinder Pro,a:b0,b:b1,leftshoulder:b20,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b19,righttrigger:b10,start:b17,x:b2,y:b3,platform:Android,
+30306461613834333439303734316539,Microsoft SideWinder Pro,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b20,lefttrigger:b9,rightshoulder:b19,righttrigger:b10,start:b17,x:b2,y:b3,platform:Android,
32386235353630393033393135613831,Microsoft Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
4d4f435554452d303533582d4d35312d,Mocute 053X,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
33343361376163623438613466616531,Mocute M053,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
39306635663061636563316166303966,Mocute M053,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
7573622067616d657061642020202020,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Android,
050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b17,y:b2,platform:Android,
-34323437396534643531326161633738,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,misc1:b5,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+34323437396534643531326161633738,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,misc1:b5,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
50726f20436f6e74726f6c6c65720000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b2,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b10,rightx:a2,righty:a3,start:b18,y:b3,platform:Android,
36326533353166323965623661303933,NSO N64 Controller,+rightx:b17,+righty:b10,-rightx:b2,-righty:b19,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,misc1:b7,rightshoulder:b20,righttrigger:b15,start:b18,platform:Android,
4e363420436f6e74726f6c6c65720000,NSO N64 Controller,+rightx:b17,+righty:b10,-rightx:b2,-righty:b19,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,misc1:b7,rightshoulder:b20,righttrigger:b15,start:b18,platform:Android,
@@ -1512,7 +1561,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
39383335313438623439373538343266,OUYA Controller,a:b0,b:b2,dpdown:b18,dpleft:b15,dpright:b16,dpup:b17,leftshoulder:b3,leftstick:b9,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,x:b1,y:b19,platform:Android,
4f5559412047616d6520436f6e74726f,OUYA Controller,a:b0,b:b2,dpdown:b18,dpleft:b15,dpright:b6,dpup:b17,leftshoulder:b3,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b19,platform:Android,
506572666f726d616e63652044657369,PDP PS3 Rock Candy Controller,a:b1,b:b17,back:h0.2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b0,y:b2,platform:Android,
-62653335326261303663356263626339,PlayStation Classic Controller,a:b19,b:b1,back:b17,leftshoulder:b9,lefttrigger:b3,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b20,start:b18,x:b2,y:b0,platform:Android,
+62653335326261303663356263626339,PlayStation Classic Controller,a:b19,b:b1,back:b17,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,lefttrigger:b3,rightshoulder:b10,righttrigger:b20,start:b18,x:b2,y:b0,platform:Android,
61653962353232366130326530363061,Pokken,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:b9,rightshoulder:b20,righttrigger:b10,start:b18,x:b0,y:b2,platform:Android,
32666633663735353234363064386132,PS2,a:b23,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a3,righty:a2,start:b30,x:b24,y:b21,platform:Android,
050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
@@ -1540,6 +1589,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
65366465656364636137653363376531,PS4 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
66613532303965383534396638613230,PS4 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
050000004c050000e60c0000fffe3f00,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
+32633532643734376632656664383733,PS5 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
+37363764353731323963323639666565,PS5 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
+61303162353165316365336436343139,PS5 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
+32346465346533616263386539323932,PS5 Controller,a:b0,b:b1,x:b2,y:b3,leftshoulder:b9,rightshoulder:b10,lefttrigger:a4,righttrigger:a5,guide:b5,start:b6,leftstick:b7,rightstick:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,back:b15,platform:Android,
64336263393933626535303339616332,Qanba 4RAF,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b20,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b9,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android,
36626666353861663864336130363137,Razer Junglecat,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
62653861643333663663383332396665,Razer Kishi,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
@@ -1554,22 +1607,20 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
38653130373365613538333235303036,Retroid Pocket 2,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
64363363336633363736393038313463,Retrolink,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b6,platform:Android,
33373336396634316434323337666361,RumblePad 2,a:b22,b:b23,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b21,y:b24,platform:Android,
-66386565396238363534313863353065,Sanwa Mobile,a:b21,b:b22,leftshoulder:b23,leftx:a0,lefty:a1,rightshoulder:b24,platform:Android,
+66386565396238363534313863353065,Sanwa PlayOnline Mobile,a:b21,b:b22,back:b23,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b24,platform:Android,
32383165316333383766336338373261,Saturn,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:a4,righttrigger:a5,x:b2,y:b3,platform:Android,
37316565396364386635383230353365,Saturn,a:b21,b:b22,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,lefttrigger:b28,rightshoulder:b27,righttrigger:b23,start:b30,x:b24,y:b25,platform:Android,
-38613865396530353338373763623431,Saturn,a:b0,b:b1,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b19,start:b17,x:b2,y:b3,platform:Android,
+38613865396530353338373763623431,Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,lefttrigger:b10,rightshoulder:b20,righttrigger:b19,start:b17,x:b2,y:b3,platform:Android,
61316232336262373631343137633631,Saturn,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:a4,righttrigger:a5,x:b2,y:b3,platform:Android,
30353835333338613130373363646337,SG H510,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b17,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b18,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b19,y:b2,platform:Android,
66386262366536653765333235343634,SG H510,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
66633132393363353531373465633064,SG H510,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b17,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b18,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b19,y:b2,platform:Android,
62653761636366393366613135366338,SN30 PP,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
-38376662666661636265313264613039,SNES,a:b0,b:b1,back:b9,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,start:b10,x:b19,y:b2,platform:Android,
-5346432f555342205061640000000000,SNES Adapter,a:b0,b:b1,back:b9,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,start:b10,x:b19,y:b2,platform:Android,
+38376662666661636265313264613039,SNES,a:b0,b:b1,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b3,rightshoulder:b20,start:b10,x:b19,y:b2,platform:Android,
+5346432f555342205061640000000000,SNES Adapter,a:b0,b:b1,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b3,rightshoulder:b20,start:b10,x:b19,y:b2,platform:Android,
5553422047616d657061642000000000,SNES Controller,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
-32633532643734376632656664383733,PS5 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
-61303162353165316365336436343139,PS5 Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
63303964303462366136616266653561,Sony PSP,a:b21,b:b22,back:b27,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b25,leftx:a0,lefty:a1,rightshoulder:b26,start:b28,x:b23,y:b24,platform:Android,
-63376637643462343766333462383235,Sony Vita,a:b1,b:b19,back:b17,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a3,righty:a4,start:b18,x:b0,y:b2,platform:Android,
+63376637643462343766333462383235,Sony Vita,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a3,righty:a4,start:b18,x:b0,y:b2,platform:Android,
476f6f676c65204c4c43205374616469,Stadia Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
@@ -1579,8 +1630,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
5477696e20555342204a6f7973746963,Twin Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android,
30623739343039643830333266346439,Valve Steam Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,paddle1:b24,paddle2:b23,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
31643365666432386133346639383937,Valve Steam Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,paddle1:b24,paddle2:b23,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
-30386438313564306161393537333663,Wii Classic Controller,a:b23,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a2,righty:a3,start:b30,x:b24,y:b21,platform:Android,
-33333034646336346339646538643633,Wii Classic Controller,a:b23,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a2,righty:a3,start:b30,x:b24,y:b21,platform:Android,
+30386438313564306161393537333663,Wii Classic Adapter,a:b23,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a2,righty:a3,start:b30,x:b24,y:b21,platform:Android,
+33333034646336346339646538643633,Wii Classic Adapter,a:b23,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a2,righty:a3,start:b30,x:b24,y:b21,platform:Android,
050000005e0400008e02000000783f00,Xbox 360 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
30396232393162346330326334636566,Xbox 360 Controller,a:b0,b:b1,back:b4,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
38313038323730383864666463383533,Xbox 360 Controller,a:b0,b:b1,back:b4,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
diff --git a/core/input/input.cpp b/core/input/input.cpp
index b3a68bb98c..da0c6cb62a 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -325,6 +325,7 @@ float Input::get_action_strength(const StringName &p_action, bool p_exact) const
}
float Input::get_action_raw_strength(const StringName &p_action, bool p_exact) const {
+ ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), 0.0, InputMap::get_singleton()->suggest_actions(p_action));
HashMap<StringName, Action>::ConstIterator E = action_state.find(p_action);
if (!E) {
return 0.0f;
diff --git a/core/input/input.h b/core/input/input.h
index f02f2abae5..3ad8c91ddf 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -110,7 +110,7 @@ private:
bool emulate_touch_from_mouse = false;
bool emulate_mouse_from_touch = false;
bool use_input_buffering = false;
- bool use_accumulated_input = false;
+ bool use_accumulated_input = true;
int mouse_from_touch_index = -1;
diff --git a/core/input/input_builders.py b/core/input/input_builders.py
index 748ec06133..c0dac26f02 100644
--- a/core/input/input_builders.py
+++ b/core/input/input_builders.py
@@ -47,9 +47,9 @@ def make_default_controller_mappings(target, source, env):
platform_variables = {
"Linux": "#if X11_ENABLED",
"Windows": "#ifdef WINDOWS_ENABLED",
- "Mac OS X": "#ifdef OSX_ENABLED",
+ "Mac OS X": "#ifdef MACOS_ENABLED",
"Android": "#if defined(__ANDROID__)",
- "iOS": "#ifdef IPHONE_ENABLED",
+ "iOS": "#ifdef IOS_ENABLED",
"Javascript": "#ifdef JAVASCRIPT_ENABLED",
"UWP": "#ifdef UWP_ENABLED",
}
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 32e025417e..3c104c2c86 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -741,6 +741,14 @@ float InputEventMouseMotion::get_pressure() const {
return pressure;
}
+void InputEventMouseMotion::set_pen_inverted(bool p_inverted) {
+ pen_inverted = p_inverted;
+}
+
+bool InputEventMouseMotion::get_pen_inverted() const {
+ return pen_inverted;
+}
+
void InputEventMouseMotion::set_relative(const Vector2 &p_relative) {
relative = p_relative;
}
@@ -768,6 +776,7 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co
mm->set_position(p_xform.xform(get_position() + p_local_ofs));
mm->set_pressure(get_pressure());
+ mm->set_pen_inverted(get_pen_inverted());
mm->set_tilt(get_tilt());
mm->set_global_position(get_global_position());
@@ -805,9 +814,9 @@ String InputEventMouseMotion::to_string() {
break;
}
- // Work around the fact vformat can only take 5 substitutions but 6 need to be passed.
- String mask_and_position = vformat("button_mask=%s, position=(%s)", button_mask_string, String(get_position()));
- return vformat("InputEventMouseMotion: %s, relative=(%s), velocity=(%s), pressure=%.2f, tilt=(%s)", mask_and_position, String(get_relative()), String(get_velocity()), get_pressure(), String(get_tilt()));
+ // Work around the fact vformat can only take 5 substitutions but 7 need to be passed.
+ String mask_and_position_and_relative = vformat("button_mask=%s, position=(%s), relative=(%s)", button_mask_string, String(get_position()), String(get_relative()));
+ return vformat("InputEventMouseMotion: %s, velocity=(%s), pressure=%.2f, tilt=(%s), pen_inverted=(%d)", mask_and_position_and_relative, String(get_velocity()), get_pressure(), String(get_tilt()), get_pen_inverted());
}
bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
@@ -859,6 +868,9 @@ void InputEventMouseMotion::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventMouseMotion::set_pressure);
ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventMouseMotion::get_pressure);
+ ClassDB::bind_method(D_METHOD("set_pen_inverted", "pen_inverted"), &InputEventMouseMotion::set_pen_inverted);
+ ClassDB::bind_method(D_METHOD("get_pen_inverted"), &InputEventMouseMotion::get_pen_inverted);
+
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative);
@@ -867,6 +879,7 @@ void InputEventMouseMotion::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pen_inverted"), "set_pen_inverted", "get_pen_inverted");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative", PROPERTY_HINT_NONE, "suffix:px"), "set_relative", "get_relative");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity", PROPERTY_HINT_NONE, "suffix:px/s"), "set_velocity", "get_velocity");
}
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 114db46623..59a2df497c 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -272,6 +272,7 @@ class InputEventMouseMotion : public InputEventMouse {
float pressure = 0;
Vector2 relative;
Vector2 velocity;
+ bool pen_inverted = false;
protected:
static void _bind_methods();
@@ -283,6 +284,9 @@ public:
void set_pressure(float p_pressure);
float get_pressure() const;
+ void set_pen_inverted(bool p_inverted);
+ bool get_pen_inverted() const;
+
void set_relative(const Vector2 &p_relative);
Vector2 get_relative() const;
diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp
index 433a7efb21..f82d6f077f 100644
--- a/core/io/dir_access.cpp
+++ b/core/io/dir_access.cpp
@@ -34,6 +34,7 @@
#include "core/io/file_access.h"
#include "core/os/memory.h"
#include "core/os/os.h"
+#include "core/templates/local_vector.h"
String DirAccess::_get_root_path() const {
switch (_access_type) {
@@ -181,6 +182,10 @@ Error DirAccess::make_dir_recursive(String p_dir) {
return OK;
}
+DirAccess::AccessType DirAccess::get_access_type() const {
+ return _access_type;
+}
+
String DirAccess::fix_path(String p_path) const {
switch (_access_type) {
case ACCESS_RESOURCES: {
@@ -282,11 +287,16 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {
Ref<FileAccess> fdst = FileAccess::open(p_to, FileAccess::WRITE, &err);
ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to open " + p_to);
+ const size_t copy_buffer_limit = 65536; // 64 KB
+
fsrc->seek_end(0);
int size = fsrc->get_position();
fsrc->seek(0);
err = OK;
- while (size--) {
+ size_t buffer_size = MIN(size * sizeof(uint8_t), copy_buffer_limit);
+ LocalVector<uint8_t> buffer;
+ buffer.resize(buffer_size);
+ while (size > 0) {
if (fsrc->get_error() != OK) {
err = fsrc->get_error();
break;
@@ -296,7 +306,14 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {
break;
}
- fdst->store_8(fsrc->get_8());
+ int bytes_read = fsrc->get_buffer(buffer.ptr(), buffer_size);
+ if (bytes_read <= 0) {
+ err = FAILED;
+ break;
+ }
+ fdst->store_buffer(buffer.ptr(), bytes_read);
+
+ size -= bytes_read;
}
}
diff --git a/core/io/dir_access.h b/core/io/dir_access.h
index 0125f011b5..22017efaa3 100644
--- a/core/io/dir_access.h
+++ b/core/io/dir_access.h
@@ -57,6 +57,7 @@ protected:
String _get_root_path() const;
String _get_root_string() const;
+ AccessType get_access_type() const;
String fix_path(String p_path) const;
template <class T>
diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp
index 7d8da1b11c..da25f23917 100644
--- a/core/io/file_access.cpp
+++ b/core/io/file_access.cpp
@@ -388,9 +388,7 @@ String FileAccess::get_as_utf8_string() const {
w[len] = 0;
String s;
- if (s.parse_utf8((const char *)w)) {
- return String();
- }
+ s.parse_utf8((const char *)w);
return s;
}
@@ -516,7 +514,6 @@ String FileAccess::get_pascal_string() {
String ret;
ret.parse_utf8(cs.ptr());
-
return ret;
}
diff --git a/core/io/image.cpp b/core/io/image.cpp
index f065dac212..0f20aabd7e 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -1339,6 +1339,108 @@ void Image::crop(int p_width, int p_height) {
crop_from_point(0, 0, p_width, p_height);
}
+void Image::rotate_90(ClockDirection p_direction) {
+ ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats.");
+ ERR_FAIL_COND_MSG(width <= 1, "The Image width specified (" + itos(width) + " pixels) must be greater than 1 pixels.");
+ ERR_FAIL_COND_MSG(height <= 1, "The Image height specified (" + itos(height) + " pixels) must be greater than 1 pixels.");
+
+ int saved_width = height;
+ int saved_height = width;
+
+ if (width != height) {
+ int n = MAX(width, height);
+ resize(n, n, INTERPOLATE_NEAREST);
+ }
+
+ bool used_mipmaps = has_mipmaps();
+ if (used_mipmaps) {
+ clear_mipmaps();
+ }
+
+ {
+ uint8_t *w = data.ptrw();
+ uint8_t src[16];
+ uint8_t dst[16];
+ uint32_t pixel_size = get_format_pixel_size(format);
+
+ // Flip.
+
+ if (p_direction == CLOCKWISE) {
+ for (int y = 0; y < height / 2; y++) {
+ for (int x = 0; x < width; x++) {
+ _get_pixelb(x, y, pixel_size, w, src);
+ _get_pixelb(x, height - y - 1, pixel_size, w, dst);
+
+ _put_pixelb(x, height - y - 1, pixel_size, w, src);
+ _put_pixelb(x, y, pixel_size, w, dst);
+ }
+ }
+ } else {
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width / 2; x++) {
+ _get_pixelb(x, y, pixel_size, w, src);
+ _get_pixelb(width - x - 1, y, pixel_size, w, dst);
+
+ _put_pixelb(width - x - 1, y, pixel_size, w, src);
+ _put_pixelb(x, y, pixel_size, w, dst);
+ }
+ }
+ }
+
+ // Transpose.
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ if (x < y) {
+ _get_pixelb(x, y, pixel_size, w, src);
+ _get_pixelb(y, x, pixel_size, w, dst);
+
+ _put_pixelb(y, x, pixel_size, w, src);
+ _put_pixelb(x, y, pixel_size, w, dst);
+ }
+ }
+ }
+ }
+
+ if (saved_width != saved_height) {
+ resize(saved_width, saved_height, INTERPOLATE_NEAREST);
+ } else if (used_mipmaps) {
+ generate_mipmaps();
+ }
+}
+
+void Image::rotate_180() {
+ ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats.");
+ ERR_FAIL_COND_MSG(width <= 1, "The Image width specified (" + itos(width) + " pixels) must be greater than 1 pixels.");
+ ERR_FAIL_COND_MSG(height <= 1, "The Image height specified (" + itos(height) + " pixels) must be greater than 1 pixels.");
+
+ bool used_mipmaps = has_mipmaps();
+ if (used_mipmaps) {
+ clear_mipmaps();
+ }
+
+ {
+ uint8_t *w = data.ptrw();
+ uint8_t src[16];
+ uint8_t dst[16];
+ uint32_t pixel_size = get_format_pixel_size(format);
+
+ for (int y = 0; y < height / 2; y++) {
+ for (int x = 0; x < width; x++) {
+ _get_pixelb(x, y, pixel_size, w, src);
+ _get_pixelb(width - x - 1, height - y - 1, pixel_size, w, dst);
+
+ _put_pixelb(width - x - 1, height - y - 1, pixel_size, w, src);
+ _put_pixelb(x, y, pixel_size, w, dst);
+ }
+ }
+ }
+
+ if (used_mipmaps) {
+ generate_mipmaps();
+ }
+}
+
void Image::flip_y() {
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_y in compressed or custom image formats.");
@@ -2284,6 +2386,21 @@ Error Image::load(const String &p_path) {
return ImageLoader::load_image(p_path, this);
}
+Ref<Image> Image::load_from_file(const String &p_path) {
+#ifdef DEBUG_ENABLED
+ if (p_path.begins_with("res://") && ResourceLoader::exists(p_path)) {
+ WARN_PRINT("Loaded resource as image file, this will not work on export: '" + p_path + "'. Instead, import the image file as an Image resource and load it normally as a resource.");
+ }
+#endif
+ Ref<Image> image;
+ image.instantiate();
+ Error err = ImageLoader::load_image(p_path, image);
+ if (err != OK) {
+ ERR_FAIL_V_MSG(Ref<Image>(), vformat("Failed to load image. Error %d", err));
+ }
+ return image;
+}
+
Error Image::save_png(const String &p_path) const {
if (save_png_func == nullptr) {
return ERR_UNAVAILABLE;
@@ -2463,15 +2580,15 @@ Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const V
create(p_width, p_height, p_mipmaps, p_format, p_data);
}
-Rect2 Image::get_used_rect() const {
+Rect2i Image::get_used_rect() const {
if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGB565) {
- return Rect2(Point2(), Size2(width, height));
+ return Rect2i(0, 0, width, height);
}
int len = data.size();
if (len == 0) {
- return Rect2();
+ return Rect2i();
}
int minx = 0xFFFFFF, miny = 0xFFFFFFF;
@@ -2497,15 +2614,15 @@ Rect2 Image::get_used_rect() const {
}
if (maxx == -1) {
- return Rect2();
+ return Rect2i();
} else {
- return Rect2(minx, miny, maxx - minx + 1, maxy - miny + 1);
+ return Rect2i(minx, miny, maxx - minx + 1, maxy - miny + 1);
}
}
-Ref<Image> Image::get_rect(const Rect2 &p_area) const {
+Ref<Image> Image::get_rect(const Rect2i &p_area) const {
Ref<Image> img = memnew(Image(p_area.size.x, p_area.size.y, mipmaps, format));
- img->blit_rect(Ref<Image>((Image *)this), p_area, Point2(0, 0));
+ img->blit_rect(Ref<Image>((Image *)this), p_area, Point2i(0, 0));
return img;
}
@@ -2542,7 +2659,7 @@ void Image::_get_clipped_src_and_dest_rects(const Ref<Image> &p_src, const Rect2
r_clipped_dest_rect.size.y = r_clipped_src_rect.size.y;
}
-void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
+void Image::blit_rect(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest) {
ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
int dsize = data.size();
int srcdsize = p_src->data.size();
@@ -2584,7 +2701,7 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
}
}
-void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
+void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2i &p_src_rect, const Point2i &p_dest) {
ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
ERR_FAIL_COND_MSG(p_mask.is_null(), "It's not a reference to a valid Image object.");
int dsize = data.size();
@@ -2634,7 +2751,7 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
}
}
-void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
+void Image::blend_rect(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest) {
ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
int dsize = data.size();
int srcdsize = p_src->data.size();
@@ -2669,7 +2786,7 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
}
}
-void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
+void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2i &p_src_rect, const Point2i &p_dest) {
ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
ERR_FAIL_COND_MSG(p_mask.is_null(), "It's not a reference to a valid Image object.");
int dsize = data.size();
@@ -2741,7 +2858,7 @@ void Image::fill(const Color &p_color) {
_repeat_pixel_over_subsequent_memory(dst_data_ptr, pixel_size, width * height);
}
-void Image::fill_rect(const Rect2 &p_rect, const Color &p_color) {
+void Image::fill_rect(const Rect2i &p_rect, const Color &p_color) {
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill rect in compressed or custom image formats.");
Rect2i r = Rect2i(0, 0, width, height).intersection(p_rect.abs());
@@ -3183,6 +3300,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_empty"), &Image::is_empty);
ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
+ ClassDB::bind_static_method("Image", D_METHOD("load_from_file", "path"), &Image::load_from_file);
ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
ClassDB::bind_method(D_METHOD("save_png_to_buffer"), &Image::save_png_to_buffer);
ClassDB::bind_method(D_METHOD("save_jpg", "path", "quality"), &Image::save_jpg, DEFVAL(0.75));
@@ -3201,6 +3319,9 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("decompress"), &Image::decompress);
ClassDB::bind_method(D_METHOD("is_compressed"), &Image::is_compressed);
+ ClassDB::bind_method(D_METHOD("rotate_90", "direction"), &Image::rotate_90);
+ ClassDB::bind_method(D_METHOD("rotate_180"), &Image::rotate_180);
+
ClassDB::bind_method(D_METHOD("fix_alpha_edges"), &Image::fix_alpha_edges);
ClassDB::bind_method(D_METHOD("premultiply_alpha"), &Image::premultiply_alpha);
ClassDB::bind_method(D_METHOD("srgb_to_linear"), &Image::srgb_to_linear);
diff --git a/core/io/image.h b/core/io/image.h
index 2cad26f3e9..46820a4c08 100644
--- a/core/io/image.h
+++ b/core/io/image.h
@@ -254,6 +254,9 @@ public:
void crop_from_point(int p_x, int p_y, int p_width, int p_height);
void crop(int p_width, int p_height);
+ void rotate_90(ClockDirection p_direction);
+ void rotate_180();
+
void flip_x();
void flip_y();
@@ -290,6 +293,7 @@ public:
Vector<uint8_t> get_data() const;
Error load(const String &p_path);
+ static Ref<Image> load_from_file(const String &p_path);
Error save_png(const String &p_path) const;
Error save_jpg(const String &p_path, float p_quality = 0.75) const;
Vector<uint8_t> save_png_to_buffer() const;
@@ -369,15 +373,15 @@ public:
Ref<Image> get_image_from_mipmap(int p_mipamp) const;
void bump_map_to_normal_map(float bump_scale = 1.0);
- void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
- void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
- void blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
- void blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
+ void blit_rect(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest);
+ void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2i &p_src_rect, const Point2i &p_dest);
+ void blend_rect(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest);
+ void blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2i &p_src_rect, const Point2i &p_dest);
void fill(const Color &p_color);
- void fill_rect(const Rect2 &p_rect, const Color &p_color);
+ void fill_rect(const Rect2i &p_rect, const Color &p_color);
- Rect2 get_used_rect() const;
- Ref<Image> get_rect(const Rect2 &p_area) const;
+ Rect2i get_used_rect() const;
+ Ref<Image> get_rect(const Rect2i &p_area) const;
static void set_compress_bc_func(void (*p_compress_func)(Image *, float, UsedChannels));
static void set_compress_bptc_func(void (*p_compress_func)(Image *, float, UsedChannels));
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index bb9606c94b..8ee19f274e 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -78,7 +78,7 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r
ERR_FAIL_COND_V(strlen < 0 || strlen + pad > len, ERR_FILE_EOF);
String str;
- ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen), ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA);
r_string = str;
// Add padding
@@ -532,7 +532,13 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::RID: {
- r_variant = RID();
+ ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
+ uint64_t id = decode_uint64(buf);
+ if (r_len) {
+ (*r_len) += 8;
+ }
+
+ r_variant = RID::from_uint64(id);
} break;
case Variant::OBJECT: {
if (type & ENCODE_FLAG_OBJECT_AS_ID) {
@@ -614,9 +620,20 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = Callable();
} break;
case Variant::SIGNAL: {
- r_variant = Signal();
- } break;
+ String name;
+ Error err = _decode_string(buf, len, r_len, name);
+ if (err) {
+ return err;
+ }
+ ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
+ ObjectID id = ObjectID(decode_uint64(buf));
+ if (r_len) {
+ (*r_len) += 8;
+ }
+
+ r_variant = Signal(id, StringName(name));
+ } break;
case Variant::DICTIONARY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
@@ -1352,10 +1369,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::RID: {
- } break;
- case Variant::CALLABLE: {
- } break;
- case Variant::SIGNAL: {
+ RID rid = p_variant;
+
+ if (buf) {
+ encode_uint64(rid.get_id(), buf);
+ }
+ r_len += 8;
} break;
case Variant::OBJECT: {
if (p_full_objects) {
@@ -1419,6 +1438,18 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
}
} break;
+ case Variant::CALLABLE: {
+ } break;
+ case Variant::SIGNAL: {
+ Signal signal = p_variant;
+
+ _encode_string(signal.get_name(), buf, r_len);
+
+ if (buf) {
+ encode_uint64(signal.get_object_id(), buf);
+ }
+ r_len += 8;
+ } break;
case Variant::DICTIONARY: {
Dictionary d = p_variant;
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index b1c50e829c..0f4bc1e19c 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -865,6 +865,22 @@ String ResourceLoaderBinary::get_unicode_string() {
return s;
}
+void ResourceLoaderBinary::get_classes_used(Ref<FileAccess> p_f, HashSet<StringName> *p_classes) {
+ open(p_f, false, true);
+ if (error) {
+ return;
+ }
+
+ for (int i = 0; i < internal_resources.size(); i++) {
+ p_f->seek(internal_resources[i].offset);
+ String t = get_unicode_string();
+ ERR_FAIL_COND(p_f->get_error() != OK);
+ if (t != String()) {
+ p_classes->insert(t);
+ }
+ }
+}
+
void ResourceLoaderBinary::get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types) {
open(p_f, false, true);
if (error) {
@@ -1337,6 +1353,16 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
return OK;
}
+void ResourceFormatLoaderBinary::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) {
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_MSG(f.is_null(), "Cannot open file '" + p_path + "'.");
+
+ ResourceLoaderBinary loader;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ loader.res_path = loader.local_path;
+ loader.get_classes_used(f, r_classes);
+}
+
String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
if (f.is_null()) {
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index 5da880ddb8..2b043302fd 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -101,6 +101,7 @@ public:
void open(Ref<FileAccess> p_f, bool p_no_resources = false, bool p_keep_uuid_paths = false);
String recognize(Ref<FileAccess> p_f);
void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types);
+ void get_classes_used(Ref<FileAccess> p_f, HashSet<StringName> *p_classes);
ResourceLoaderBinary() {}
};
@@ -112,6 +113,7 @@ public:
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
+ virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
virtual ResourceUID::ID get_resource_uid(const String &p_path) const;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map);
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index 934cb780e6..e059fc842b 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -352,6 +352,16 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons
return pat.metadata;
}
+void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) {
+ PathAndType pat;
+ Error err = _get_path_and_type(p_path, pat);
+
+ if (err != OK) {
+ return;
+ }
+
+ ResourceLoader::get_classes_used(pat.path, r_classes);
+}
void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
PathAndType pat;
diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h
index 0c7909df06..d0ea98b598 100644
--- a/core/io/resource_importer.h
+++ b/core/io/resource_importer.h
@@ -65,12 +65,12 @@ public:
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
virtual ResourceUID::ID get_resource_uid(const String &p_path) const;
-
virtual Variant get_resource_metadata(const String &p_path) const;
virtual bool is_import_valid(const String &p_path) const;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual bool is_imported(const String &p_path) const { return recognize_path(p_path); }
virtual String get_import_group_file(const String &p_path) const;
+ virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
virtual bool exists(const String &p_path) const;
virtual int get_import_order(const String &p_path) const;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 2cd455475c..fc4177004b 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -76,6 +76,21 @@ bool ResourceFormatLoader::handles_type(const String &p_type) const {
return false;
}
+void ResourceFormatLoader::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) {
+ Vector<String> ret;
+ if (GDVIRTUAL_CALL(_get_classes_used, p_path, ret)) {
+ for (int i = 0; i < ret.size(); i++) {
+ r_classes->insert(ret[i]);
+ }
+ return;
+ }
+
+ String res = get_resource_type(p_path);
+ if (!res.is_empty()) {
+ r_classes->insert(res);
+ }
+}
+
String ResourceFormatLoader::get_resource_type(const String &p_path) const {
String ret;
@@ -180,6 +195,7 @@ void ResourceFormatLoader::_bind_methods() {
GDVIRTUAL_BIND(_get_dependencies, "path", "add_types");
GDVIRTUAL_BIND(_rename_dependencies, "path", "renames");
GDVIRTUAL_BIND(_exists, "path");
+ GDVIRTUAL_BIND(_get_classes_used, "path");
GDVIRTUAL_BIND(_load, "path", "original_path", "use_sub_threads", "cache_mode");
}
@@ -730,6 +746,18 @@ Error ResourceLoader::rename_dependencies(const String &p_path, const HashMap<St
return OK; // ??
}
+void ResourceLoader::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) {
+ String local_path = _validate_local_path(p_path);
+
+ for (int i = 0; i < loader_count; i++) {
+ if (!loader[i]->recognize_path(local_path)) {
+ continue;
+ }
+
+ return loader[i]->get_classes_used(p_path, r_classes);
+ }
+}
+
String ResourceLoader::get_resource_type(const String &p_path) {
String local_path = _validate_local_path(p_path);
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 815dd1dd72..91ba930176 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -55,6 +55,7 @@ protected:
GDVIRTUAL1RC(String, _get_resource_type, String)
GDVIRTUAL1RC(ResourceUID::ID, _get_resource_uid, String)
GDVIRTUAL2RC(Vector<String>, _get_dependencies, String, bool)
+ GDVIRTUAL1RC(Vector<String>, _get_classes_used, String)
GDVIRTUAL2RC(int64_t, _rename_dependencies, String, Dictionary)
GDVIRTUAL1RC(bool, _exists, String)
@@ -67,6 +68,7 @@ public:
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const;
virtual bool handles_type(const String &p_type) const;
+ virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
virtual String get_resource_type(const String &p_path) const;
virtual ResourceUID::ID get_resource_uid(const String &p_path) const;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
@@ -170,6 +172,7 @@ public:
static void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions);
static void add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front = false);
static void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader);
+ static void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
static String get_resource_type(const String &p_path);
static ResourceUID::ID get_resource_uid(const String &p_path);
static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index 7b43193f47..154b55f5e7 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -72,11 +72,11 @@ void XMLParser::_parse_closing_xml_element() {
node_empty = false;
attributes.clear();
- ++P;
+ next_char();
const char *pBeginClose = P;
while (*P && *P != '>') {
- ++P;
+ next_char();
}
node_name = String::utf8(pBeginClose, (int)(P - pBeginClose));
@@ -85,7 +85,7 @@ void XMLParser::_parse_closing_xml_element() {
#endif
if (*P) {
- ++P;
+ next_char();
}
}
@@ -95,12 +95,12 @@ void XMLParser::_ignore_definition() {
char *F = P;
// move until end marked with '>' reached
while (*P && *P != '>') {
- ++P;
+ next_char();
}
node_name.parse_utf8(F, P - F);
if (*P) {
- ++P;
+ next_char();
}
}
@@ -114,7 +114,7 @@ bool XMLParser::_parse_cdata() {
// skip '<![CDATA['
int count = 0;
while (*P && count < 8) {
- ++P;
+ next_char();
++count;
}
@@ -134,7 +134,7 @@ bool XMLParser::_parse_cdata() {
cDataEnd = P - 2;
}
- ++P;
+ next_char();
}
if (cDataEnd) {
@@ -180,7 +180,7 @@ void XMLParser::_parse_comment() {
} else if (*P == '<') {
++count;
}
- ++P;
+ next_char();
}
if (count) {
@@ -206,7 +206,7 @@ void XMLParser::_parse_opening_xml_element() {
// find end of element
while (*P && *P != '>' && !_is_white_space(*P)) {
- ++P;
+ next_char();
}
const char *endName = P;
@@ -214,7 +214,7 @@ void XMLParser::_parse_opening_xml_element() {
// find attributes
while (*P && *P != '>') {
if (_is_white_space(*P)) {
- ++P;
+ next_char();
} else {
if (*P != '/') {
// we've got an attribute
@@ -223,7 +223,7 @@ void XMLParser::_parse_opening_xml_element() {
const char *attributeNameBegin = P;
while (*P && !_is_white_space(*P) && *P != '=') {
- ++P;
+ next_char();
}
if (!*P) {
@@ -231,12 +231,12 @@ void XMLParser::_parse_opening_xml_element() {
}
const char *attributeNameEnd = P;
- ++P;
+ next_char();
// read the attribute value
// check for quotes and single quotes, thx to murphy
while ((*P != '\"') && (*P != '\'') && *P) {
- ++P;
+ next_char();
}
if (!*P) { // malformatted xml file
@@ -245,16 +245,16 @@ void XMLParser::_parse_opening_xml_element() {
const char attributeQuoteChar = *P;
- ++P;
+ next_char();
const char *attributeValueBegin = P;
while (*P != attributeQuoteChar && *P) {
- ++P;
+ next_char();
}
const char *attributeValueEnd = P;
if (*P) {
- ++P;
+ next_char();
}
Attribute attr;
@@ -268,7 +268,7 @@ void XMLParser::_parse_opening_xml_element() {
attributes.push_back(attr);
} else {
// tag is closed directly
- ++P;
+ next_char();
node_empty = true;
break;
}
@@ -288,7 +288,7 @@ void XMLParser::_parse_opening_xml_element() {
#endif
if (*P) {
- ++P;
+ next_char();
}
}
@@ -298,7 +298,7 @@ void XMLParser::_parse_current_node() {
// more forward until '<' found
while (*P != '<' && *P) {
- ++P;
+ next_char();
}
if (P - start > 0) {
@@ -312,7 +312,7 @@ void XMLParser::_parse_current_node() {
return;
}
- ++P;
+ next_char();
// based on current token, parse and report next element
switch (*P) {
@@ -487,6 +487,7 @@ Error XMLParser::open(const String &p_path) {
file->get_buffer((uint8_t *)data, length);
data[length] = 0;
P = data;
+ current_line = 0;
return OK;
}
@@ -523,10 +524,7 @@ void XMLParser::close() {
}
int XMLParser::get_current_line() const {
- return 0;
-}
-
-XMLParser::XMLParser() {
+ return current_line;
}
XMLParser::~XMLParser() {
diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h
index da14ee8eae..aea252ddc7 100644
--- a/core/io/xml_parser.h
+++ b/core/io/xml_parser.h
@@ -68,6 +68,7 @@ private:
char *data = nullptr;
char *P = nullptr;
uint64_t length = 0;
+ uint64_t current_line = 0;
String node_name;
bool node_empty = false;
NodeType node_type = NODE_NONE;
@@ -88,6 +89,13 @@ private:
void _parse_opening_xml_element();
void _parse_current_node();
+ _FORCE_INLINE_ void next_char() {
+ if (*P == '\n') {
+ current_line++;
+ }
+ P++;
+ }
+
static void _bind_methods();
public:
@@ -113,7 +121,6 @@ public:
void close();
- XMLParser();
~XMLParser();
};
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index ce5e9aa9b3..f8e7c47107 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -817,14 +817,13 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
#endif
*/
real_t angle, x, y, z; // variables for result
- real_t epsilon = 0.01; // margin to allow for rounding errors
- real_t epsilon2 = 0.1; // margin to distinguish between 0 and 180 degrees
+ real_t angle_epsilon = 0.1; // margin to distinguish between 0 and 180 degrees
- if ((Math::abs(rows[1][0] - rows[0][1]) < epsilon) && (Math::abs(rows[2][0] - rows[0][2]) < epsilon) && (Math::abs(rows[2][1] - rows[1][2]) < epsilon)) {
+ if ((Math::abs(rows[1][0] - rows[0][1]) < CMP_EPSILON) && (Math::abs(rows[2][0] - rows[0][2]) < CMP_EPSILON) && (Math::abs(rows[2][1] - rows[1][2]) < CMP_EPSILON)) {
// singularity found
// first check for identity matrix which must have +1 for all terms
// in leading diagonal and zero in other terms
- if ((Math::abs(rows[1][0] + rows[0][1]) < epsilon2) && (Math::abs(rows[2][0] + rows[0][2]) < epsilon2) && (Math::abs(rows[2][1] + rows[1][2]) < epsilon2) && (Math::abs(rows[0][0] + rows[1][1] + rows[2][2] - 3) < epsilon2)) {
+ if ((Math::abs(rows[1][0] + rows[0][1]) < angle_epsilon) && (Math::abs(rows[2][0] + rows[0][2]) < angle_epsilon) && (Math::abs(rows[2][1] + rows[1][2]) < angle_epsilon) && (Math::abs(rows[0][0] + rows[1][1] + rows[2][2] - 3) < angle_epsilon)) {
// this singularity is identity matrix so angle = 0
r_axis = Vector3(0, 1, 0);
r_angle = 0;
@@ -839,7 +838,7 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
real_t xz = (rows[2][0] + rows[0][2]) / 4;
real_t yz = (rows[2][1] + rows[1][2]) / 4;
if ((xx > yy) && (xx > zz)) { // rows[0][0] is the largest diagonal term
- if (xx < epsilon) {
+ if (xx < CMP_EPSILON) {
x = 0;
y = Math_SQRT12;
z = Math_SQRT12;
@@ -849,7 +848,7 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
z = xz / x;
}
} else if (yy > zz) { // rows[1][1] is the largest diagonal term
- if (yy < epsilon) {
+ if (yy < CMP_EPSILON) {
x = Math_SQRT12;
y = 0;
z = Math_SQRT12;
@@ -859,7 +858,7 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
z = yz / y;
}
} else { // rows[2][2] is the largest diagonal term so base result on this
- if (zz < epsilon) {
+ if (zz < CMP_EPSILON) {
x = Math_SQRT12;
y = Math_SQRT12;
z = 0;
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 419056d7d6..e230b69dc9 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -891,7 +891,7 @@ Expression::ENode *Expression::_parse_expression() {
case TK_PERIOD: {
//named indexing or function call
_get_token(tk);
- if (tk.type != TK_IDENTIFIER) {
+ if (tk.type != TK_IDENTIFIER && tk.type != TK_BUILTIN_FUNC) {
_set_error("Expected identifier after '.'");
return nullptr;
}
diff --git a/core/math/octree.h b/core/math/octree.h
deleted file mode 100644
index 8dd103f109..0000000000
--- a/core/math/octree.h
+++ /dev/null
@@ -1,1271 +0,0 @@
-/*************************************************************************/
-/* octree.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef OCTREE_H
-#define OCTREE_H
-
-#include "core/math/aabb.h"
-#include "core/math/geometry_3d.h"
-#include "core/math/vector3.h"
-#include "core/string/print_string.h"
-#include "core/templates/list.h"
-#include "core/templates/rb_map.h"
-#include "core/variant/variant.h"
-
-typedef uint32_t OctreeElementID;
-
-#define OCTREE_ELEMENT_INVALID_ID 0
-#define OCTREE_SIZE_LIMIT 1e15
-
-template <class T, bool use_pairs = false, class AL = DefaultAllocator>
-class Octree {
-public:
- typedef void *(*PairCallback)(void *, OctreeElementID, T *, int, OctreeElementID, T *, int);
- typedef void (*UnpairCallback)(void *, OctreeElementID, T *, int, OctreeElementID, T *, int, void *);
-
-private:
- enum {
- NEG = 0,
- POS = 1,
- };
-
- enum {
- OCTANT_NX_NY_NZ,
- OCTANT_PX_NY_NZ,
- OCTANT_NX_PY_NZ,
- OCTANT_PX_PY_NZ,
- OCTANT_NX_NY_PZ,
- OCTANT_PX_NY_PZ,
- OCTANT_NX_PY_PZ,
- OCTANT_PX_PY_PZ
- };
-
- struct PairKey {
- union {
- struct {
- OctreeElementID A;
- OctreeElementID B;
- };
- uint64_t key;
- };
-
- _FORCE_INLINE_ bool operator<(const PairKey &p_pair) const {
- return key < p_pair.key;
- }
-
- _FORCE_INLINE_ PairKey(OctreeElementID p_A, OctreeElementID p_B) {
- if (p_A < p_B) {
- A = p_A;
- B = p_B;
- } else {
- B = p_A;
- A = p_B;
- }
- }
-
- _FORCE_INLINE_ PairKey() {}
- };
-
- struct Element;
-
- struct Octant {
- // cached for FAST plane check
- AABB aabb;
-
- uint64_t last_pass = 0;
- Octant *parent = nullptr;
- Octant *children[8] = { nullptr };
-
- int children_count = 0; // cache for amount of children (fast check for removal)
- int parent_index = -1; // cache for parent index (fast check for removal)
-
- List<Element *, AL> pairable_elements;
- List<Element *, AL> elements;
-
- Octant() {}
- ~Octant() {}
- };
-
- struct PairData;
-
- struct Element {
- Octree *octree = nullptr;
-
- T *userdata = nullptr;
- int subindex = 0;
- bool pairable = false;
- uint32_t pairable_mask = 0;
- uint32_t pairable_type = 0;
-
- uint64_t last_pass = 0;
- OctreeElementID _id = 0;
- Octant *common_parent = nullptr;
-
- AABB aabb;
- AABB container_aabb;
-
- List<PairData *, AL> pair_list;
-
- struct OctantOwner {
- Octant *octant = nullptr;
- typename List<Element *, AL>::Element *E;
- }; // an element can be in max 8 octants
-
- List<OctantOwner, AL> octant_owners;
-
- Element() {}
- };
-
- struct PairData {
- int refcount;
- bool intersect;
- Element *A, *B;
- void *ud = nullptr;
- typename List<PairData *, AL>::Element *eA, *eB;
- };
-
- typedef HashMap<OctreeElementID, Element, Comparator<OctreeElementID>, AL> ElementMap;
- typedef HashMap<PairKey, PairData, Comparator<PairKey>, AL> PairMap;
- ElementMap element_map;
- PairMap pair_map;
-
- PairCallback pair_callback = nullptr;
- UnpairCallback unpair_callback = nullptr;
- void *pair_callback_userdata = nullptr;
- void *unpair_callback_userdata = nullptr;
-
- OctreeElementID last_element_id = 1;
- uint64_t pass = 1;
-
- real_t unit_size = 1.0;
- Octant *root = nullptr;
- int octant_count = 0;
- int pair_count = 0;
-
- _FORCE_INLINE_ void _pair_check(PairData *p_pair) {
- bool intersect = p_pair->A->aabb.intersects_inclusive(p_pair->B->aabb);
-
- if (intersect != p_pair->intersect) {
- if (intersect) {
- if (pair_callback) {
- p_pair->ud = pair_callback(pair_callback_userdata, p_pair->A->_id, p_pair->A->userdata, p_pair->A->subindex, p_pair->B->_id, p_pair->B->userdata, p_pair->B->subindex);
- }
- pair_count++;
- } else {
- if (unpair_callback) {
- unpair_callback(pair_callback_userdata, p_pair->A->_id, p_pair->A->userdata, p_pair->A->subindex, p_pair->B->_id, p_pair->B->userdata, p_pair->B->subindex, p_pair->ud);
- }
- pair_count--;
- }
-
- p_pair->intersect = intersect;
- }
- }
-
- _FORCE_INLINE_ void _pair_reference(Element *p_A, Element *p_B) {
- if (p_A == p_B || (p_A->userdata == p_B->userdata && p_A->userdata)) {
- return;
- }
-
- if (!(p_A->pairable_type & p_B->pairable_mask) &&
- !(p_B->pairable_type & p_A->pairable_mask)) {
- return; // none can pair with none
- }
-
- PairKey key(p_A->_id, p_B->_id);
- typename PairMap::Element *E = pair_map.find(key);
-
- if (!E) {
- PairData pdata;
- pdata.refcount = 1;
- pdata.A = p_A;
- pdata.B = p_B;
- pdata.intersect = false;
- E = pair_map.insert(key, pdata);
- E->get().eA = p_A->pair_list.push_back(&E->get());
- E->get().eB = p_B->pair_list.push_back(&E->get());
- } else {
- E->get().refcount++;
- }
- }
-
- _FORCE_INLINE_ void _pair_unreference(Element *p_A, Element *p_B) {
- if (p_A == p_B) {
- return;
- }
-
- PairKey key(p_A->_id, p_B->_id);
- typename PairMap::Element *E = pair_map.find(key);
- if (!E) {
- return; // no pair
- }
-
- E->get().refcount--;
-
- if (E->get().refcount == 0) {
- // bye pair
-
- if (E->get().intersect) {
- if (unpair_callback) {
- unpair_callback(pair_callback_userdata, p_A->_id, p_A->userdata, p_A->subindex, p_B->_id, p_B->userdata, p_B->subindex, E->get().ud);
- }
-
- pair_count--;
- }
-
- if (p_A == E->get().B) {
- //may be reaching inverted
- SWAP(p_A, p_B);
- }
-
- p_A->pair_list.erase(E->get().eA);
- p_B->pair_list.erase(E->get().eB);
- pair_map.erase(E);
- }
- }
-
- _FORCE_INLINE_ void _element_check_pairs(Element *p_element) {
- typename List<PairData *, AL>::Element *E = p_element->pair_list.front();
- while (E) {
- _pair_check(E->get());
- E = E->next();
- }
- }
-
- _FORCE_INLINE_ void _optimize() {
- while (root && root->children_count < 2 && !root->elements.size() && !(use_pairs && root->pairable_elements.size())) {
- Octant *new_root = nullptr;
- if (root->children_count == 1) {
- for (int i = 0; i < 8; i++) {
- if (root->children[i]) {
- new_root = root->children[i];
- root->children[i] = nullptr;
- break;
- }
- }
- ERR_FAIL_COND(!new_root);
- new_root->parent = nullptr;
- new_root->parent_index = -1;
- }
-
- memdelete_allocator<Octant, AL>(root);
- octant_count--;
- root = new_root;
- }
- }
-
- void _insert_element(Element *p_element, Octant *p_octant);
- void _ensure_valid_root(const AABB &p_aabb);
- bool _remove_element_from_octant(Element *p_element, Octant *p_octant, Octant *p_limit = nullptr);
- void _remove_element(Element *p_element);
- void _pair_element(Element *p_element, Octant *p_octant);
- void _unpair_element(Element *p_element, Octant *p_octant);
-
- struct _CullConvexData {
- const Plane *planes;
- int plane_count;
- const Vector3 *points;
- int point_count;
- T **result_array;
- int *result_idx = nullptr;
- int result_max;
- uint32_t mask;
- };
-
- void _cull_convex(Octant *p_octant, _CullConvexData *p_cull);
- void _cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask);
- void _cull_segment(Octant *p_octant, const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask);
- void _cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask);
-
- void _remove_tree(Octant *p_octant) {
- if (!p_octant) {
- return;
- }
-
- for (int i = 0; i < 8; i++) {
- if (p_octant->children[i]) {
- _remove_tree(p_octant->children[i]);
- }
- }
-
- memdelete_allocator<Octant, AL>(p_octant);
- }
-
-public:
- OctreeElementID create(T *p_userdata, const AABB &p_aabb = AABB(), int p_subindex = 0, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1);
- void move(OctreeElementID p_id, const AABB &p_aabb);
- void set_pairable(OctreeElementID p_id, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1);
- void erase(OctreeElementID p_id);
-
- bool is_pairable(OctreeElementID p_id) const;
- T *get(OctreeElementID p_id) const;
- int get_subindex(OctreeElementID p_id) const;
-
- int cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF);
- int cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
- int cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
-
- int cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
-
- void set_pair_callback(PairCallback p_callback, void *p_userdata);
- void set_unpair_callback(UnpairCallback p_callback, void *p_userdata);
-
- int get_octant_count() const { return octant_count; }
- int get_pair_count() const { return pair_count; }
- Octree(real_t p_unit_size = 1.0);
- ~Octree() { _remove_tree(root); }
-};
-
-/* PRIVATE FUNCTIONS */
-
-template <class T, bool use_pairs, class AL>
-T *Octree<T, use_pairs, AL>::get(OctreeElementID p_id) const {
- const typename ElementMap::Element *E = element_map.find(p_id);
- ERR_FAIL_COND_V(!E, nullptr);
- return E->get().userdata;
-}
-
-template <class T, bool use_pairs, class AL>
-bool Octree<T, use_pairs, AL>::is_pairable(OctreeElementID p_id) const {
- const typename ElementMap::Element *E = element_map.find(p_id);
- ERR_FAIL_COND_V(!E, false);
- return E->get().pairable;
-}
-
-template <class T, bool use_pairs, class AL>
-int Octree<T, use_pairs, AL>::get_subindex(OctreeElementID p_id) const {
- const typename ElementMap::Element *E = element_map.find(p_id);
- ERR_FAIL_COND_V(!E, -1);
- return E->get().subindex;
-}
-
-#define OCTREE_DIVISOR 4
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_octant) {
- real_t element_size = p_element->aabb.get_longest_axis_size() * 1.01; // avoid precision issues
-
- if (p_octant->aabb.size.x / OCTREE_DIVISOR < element_size) {
- //if (p_octant->aabb.size.x*0.5 < element_size) {
- /* at smallest possible size for the element */
- typename Element::OctantOwner owner;
- owner.octant = p_octant;
-
- if (use_pairs && p_element->pairable) {
- p_octant->pairable_elements.push_back(p_element);
- owner.E = p_octant->pairable_elements.back();
- } else {
- p_octant->elements.push_back(p_element);
- owner.E = p_octant->elements.back();
- }
-
- p_element->octant_owners.push_back(owner);
-
- if (p_element->common_parent == nullptr) {
- p_element->common_parent = p_octant;
- p_element->container_aabb = p_octant->aabb;
- } else {
- p_element->container_aabb.merge_with(p_octant->aabb);
- }
-
- if (use_pairs && p_octant->children_count > 0) {
- pass++; //elements below this only get ONE reference added
-
- for (int i = 0; i < 8; i++) {
- if (p_octant->children[i]) {
- _pair_element(p_element, p_octant->children[i]);
- }
- }
- }
- } else {
- /* not big enough, send it to subitems */
- int splits = 0;
- bool candidate = p_element->common_parent == nullptr;
-
- for (int i = 0; i < 8; i++) {
- if (p_octant->children[i]) {
- /* element exists, go straight to it */
- if (p_octant->children[i]->aabb.intersects_inclusive(p_element->aabb)) {
- _insert_element(p_element, p_octant->children[i]);
- splits++;
- }
- } else {
- /* check against AABB where child should be */
-
- AABB aabb = p_octant->aabb;
- aabb.size *= 0.5;
-
- if (i & 1) {
- aabb.position.x += aabb.size.x;
- }
- if (i & 2) {
- aabb.position.y += aabb.size.y;
- }
- if (i & 4) {
- aabb.position.z += aabb.size.z;
- }
-
- if (aabb.intersects_inclusive(p_element->aabb)) {
- /* if actually intersects, create the child */
-
- Octant *child = memnew_allocator(Octant, AL);
- p_octant->children[i] = child;
- child->parent = p_octant;
- child->parent_index = i;
-
- child->aabb = aabb;
-
- p_octant->children_count++;
-
- _insert_element(p_element, child);
- octant_count++;
- splits++;
- }
- }
- }
-
- if (candidate && splits > 1) {
- p_element->common_parent = p_octant;
- }
- }
-
- if (use_pairs) {
- typename List<Element *, AL>::Element *E = p_octant->pairable_elements.front();
-
- while (E) {
- _pair_reference(p_element, E->get());
- E = E->next();
- }
-
- if (p_element->pairable) {
- // and always test non-pairable if element is pairable
- E = p_octant->elements.front();
- while (E) {
- _pair_reference(p_element, E->get());
- E = E->next();
- }
- }
- }
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_ensure_valid_root(const AABB &p_aabb) {
- if (!root) {
- // octre is empty
-
- AABB base(Vector3(), Vector3(1.0, 1.0, 1.0) * unit_size);
-
- while (!base.encloses(p_aabb)) {
- if (ABS(base.position.x + base.size.x) <= ABS(base.position.x)) {
- /* grow towards positive */
- base.size *= 2.0;
- } else {
- base.position -= base.size;
- base.size *= 2.0;
- }
- }
-
- root = memnew_allocator(Octant, AL);
-
- root->parent = nullptr;
- root->parent_index = -1;
- root->aabb = base;
-
- octant_count++;
-
- } else {
- AABB base = root->aabb;
-
- while (!base.encloses(p_aabb)) {
- ERR_FAIL_COND_MSG(base.size.x > OCTREE_SIZE_LIMIT, "Octree upper size limit reached, does the AABB supplied contain NAN?");
-
- Octant *gp = memnew_allocator(Octant, AL);
- octant_count++;
- root->parent = gp;
-
- if (ABS(base.position.x + base.size.x) <= ABS(base.position.x)) {
- /* grow towards positive */
- base.size *= 2.0;
- gp->aabb = base;
- gp->children[0] = root;
- root->parent_index = 0;
- } else {
- base.position -= base.size;
- base.size *= 2.0;
- gp->aabb = base;
- gp->children[(1 << 0) | (1 << 1) | (1 << 2)] = root; // add at all-positive
- root->parent_index = (1 << 0) | (1 << 1) | (1 << 2);
- }
-
- gp->children_count = 1;
- root = gp;
- }
- }
-}
-
-template <class T, bool use_pairs, class AL>
-bool Octree<T, use_pairs, AL>::_remove_element_from_octant(Element *p_element, Octant *p_octant, Octant *p_limit) {
- bool octant_removed = false;
-
- while (true) {
- // check all exit conditions
-
- if (p_octant == p_limit) { // reached limit, nothing to erase, exit
- return octant_removed;
- }
-
- bool unpaired = false;
-
- if (use_pairs && p_octant->last_pass != pass) {
- // check whether we should unpair stuff
- // always test pairable
- typename List<Element *, AL>::Element *E = p_octant->pairable_elements.front();
- while (E) {
- _pair_unreference(p_element, E->get());
- E = E->next();
- }
- if (p_element->pairable) {
- // and always test non-pairable if element is pairable
- E = p_octant->elements.front();
- while (E) {
- _pair_unreference(p_element, E->get());
- E = E->next();
- }
- }
- p_octant->last_pass = pass;
- unpaired = true;
- }
-
- bool removed = false;
-
- Octant *parent = p_octant->parent;
-
- if (p_octant->children_count == 0 && p_octant->elements.is_empty() && p_octant->pairable_elements.is_empty()) {
- // erase octant
-
- if (p_octant == root) { // won't have a parent, just erase
-
- root = nullptr;
- } else {
- ERR_FAIL_INDEX_V(p_octant->parent_index, 8, octant_removed);
-
- parent->children[p_octant->parent_index] = nullptr;
- parent->children_count--;
- }
-
- memdelete_allocator<Octant, AL>(p_octant);
- octant_count--;
- removed = true;
- octant_removed = true;
- }
-
- if (!removed && !unpaired) {
- return octant_removed; // no reason to keep going up anymore! was already visited and was not removed
- }
-
- p_octant = parent;
- }
-
- return octant_removed;
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_unpair_element(Element *p_element, Octant *p_octant) {
- // always test pairable
- typename List<Element *, AL>::Element *E = p_octant->pairable_elements.front();
- while (E) {
- if (E->get()->last_pass != pass) { // only remove ONE reference
- _pair_unreference(p_element, E->get());
- E->get()->last_pass = pass;
- }
- E = E->next();
- }
-
- if (p_element->pairable) {
- // and always test non-pairable if element is pairable
- E = p_octant->elements.front();
- while (E) {
- if (E->get()->last_pass != pass) { // only remove ONE reference
- _pair_unreference(p_element, E->get());
- E->get()->last_pass = pass;
- }
- E = E->next();
- }
- }
-
- p_octant->last_pass = pass;
-
- if (p_octant->children_count == 0) {
- return; // small optimization for leafs
- }
-
- for (int i = 0; i < 8; i++) {
- if (p_octant->children[i]) {
- _unpair_element(p_element, p_octant->children[i]);
- }
- }
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_pair_element(Element *p_element, Octant *p_octant) {
- // always test pairable
-
- typename List<Element *, AL>::Element *E = p_octant->pairable_elements.front();
-
- while (E) {
- if (E->get()->last_pass != pass) { // only get ONE reference
- _pair_reference(p_element, E->get());
- E->get()->last_pass = pass;
- }
- E = E->next();
- }
-
- if (p_element->pairable) {
- // and always test non-pairable if element is pairable
- E = p_octant->elements.front();
- while (E) {
- if (E->get()->last_pass != pass) { // only get ONE reference
- _pair_reference(p_element, E->get());
- E->get()->last_pass = pass;
- }
- E = E->next();
- }
- }
- p_octant->last_pass = pass;
-
- if (p_octant->children_count == 0) {
- return; // small optimization for leafs
- }
-
- for (int i = 0; i < 8; i++) {
- if (p_octant->children[i]) {
- _pair_element(p_element, p_octant->children[i]);
- }
- }
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_remove_element(Element *p_element) {
- pass++; // will do a new pass for this
-
- typename List<typename Element::OctantOwner, AL>::Element *I = p_element->octant_owners.front();
-
- /* FIRST remove going up normally */
- for (; I; I = I->next()) {
- Octant *o = I->get().octant;
-
- if (!use_pairs) { // small speedup
- o->elements.erase(I->get().E);
- }
-
- _remove_element_from_octant(p_element, o);
- }
-
- /* THEN remove going down */
-
- I = p_element->octant_owners.front();
-
- if (use_pairs) {
- for (; I; I = I->next()) {
- Octant *o = I->get().octant;
-
- // erase children pairs, they are erased ONCE even if repeated
- pass++;
- for (int i = 0; i < 8; i++) {
- if (o->children[i]) {
- _unpair_element(p_element, o->children[i]);
- }
- }
-
- if (p_element->pairable) {
- o->pairable_elements.erase(I->get().E);
- } else {
- o->elements.erase(I->get().E);
- }
- }
- }
-
- p_element->octant_owners.clear();
-
- if (use_pairs) {
- int remaining = p_element->pair_list.size();
- //p_element->pair_list.clear();
- ERR_FAIL_COND(remaining);
- }
-}
-
-template <class T, bool use_pairs, class AL>
-OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
-// check for AABB validity
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V(p_aabb.position.x > 1e15 || p_aabb.position.x < -1e15, 0);
- ERR_FAIL_COND_V(p_aabb.position.y > 1e15 || p_aabb.position.y < -1e15, 0);
- ERR_FAIL_COND_V(p_aabb.position.z > 1e15 || p_aabb.position.z < -1e15, 0);
- ERR_FAIL_COND_V(p_aabb.size.x > 1e15 || p_aabb.size.x < 0.0, 0);
- ERR_FAIL_COND_V(p_aabb.size.y > 1e15 || p_aabb.size.y < 0.0, 0);
- ERR_FAIL_COND_V(p_aabb.size.z > 1e15 || p_aabb.size.z < 0.0, 0);
- ERR_FAIL_COND_V(Math::is_nan(p_aabb.size.x), 0);
- ERR_FAIL_COND_V(Math::is_nan(p_aabb.size.y), 0);
- ERR_FAIL_COND_V(Math::is_nan(p_aabb.size.z), 0);
-
-#endif
- typename ElementMap::Element *E = element_map.insert(last_element_id++,
- Element());
- Element &e = E->get();
-
- e.aabb = p_aabb;
- e.userdata = p_userdata;
- e.subindex = p_subindex;
- e.last_pass = 0;
- e.octree = this;
- e.pairable = p_pairable;
- e.pairable_type = p_pairable_type;
- e.pairable_mask = p_pairable_mask;
- e._id = last_element_id - 1;
-
- if (!e.aabb.has_no_surface()) {
- _ensure_valid_root(p_aabb);
- _insert_element(&e, root);
- if (use_pairs) {
- _element_check_pairs(&e);
- }
- }
-
- return last_element_id - 1;
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
-#ifdef DEBUG_ENABLED
- // check for AABB validity
- ERR_FAIL_COND(p_aabb.position.x > 1e15 || p_aabb.position.x < -1e15);
- ERR_FAIL_COND(p_aabb.position.y > 1e15 || p_aabb.position.y < -1e15);
- ERR_FAIL_COND(p_aabb.position.z > 1e15 || p_aabb.position.z < -1e15);
- ERR_FAIL_COND(p_aabb.size.x > 1e15 || p_aabb.size.x < 0.0);
- ERR_FAIL_COND(p_aabb.size.y > 1e15 || p_aabb.size.y < 0.0);
- ERR_FAIL_COND(p_aabb.size.z > 1e15 || p_aabb.size.z < 0.0);
- ERR_FAIL_COND(Math::is_nan(p_aabb.size.x));
- ERR_FAIL_COND(Math::is_nan(p_aabb.size.y));
- ERR_FAIL_COND(Math::is_nan(p_aabb.size.z));
-#endif
- typename ElementMap::Element *E = element_map.find(p_id);
- ERR_FAIL_COND(!E);
- Element &e = E->get();
-
- bool old_has_surf = !e.aabb.has_no_surface();
- bool new_has_surf = !p_aabb.has_no_surface();
-
- if (old_has_surf != new_has_surf) {
- if (old_has_surf) {
- _remove_element(&e); // removing
- e.common_parent = nullptr;
- e.aabb = AABB();
- _optimize();
- } else {
- _ensure_valid_root(p_aabb); // inserting
- e.common_parent = nullptr;
- e.aabb = p_aabb;
- _insert_element(&e, root);
- if (use_pairs) {
- _element_check_pairs(&e);
- }
- }
-
- return;
- }
-
- if (!old_has_surf) { // doing nothing
- return;
- }
-
- // it still is enclosed in the same AABB it was assigned to
- if (e.container_aabb.encloses(p_aabb)) {
- e.aabb = p_aabb;
- if (use_pairs) {
- _element_check_pairs(&e); // must check pairs anyway
- }
-
- return;
- }
-
- AABB combined = e.aabb;
- combined.merge_with(p_aabb);
- _ensure_valid_root(combined);
-
- ERR_FAIL_COND(e.octant_owners.front() == nullptr);
-
- /* FIND COMMON PARENT */
-
- List<typename Element::OctantOwner, AL> owners = e.octant_owners; // save the octant owners
- Octant *common_parent = e.common_parent;
- ERR_FAIL_COND(!common_parent);
-
- //src is now the place towards where insertion is going to happen
- pass++;
-
- while (common_parent && !common_parent->aabb.encloses(p_aabb)) {
- common_parent = common_parent->parent;
- }
-
- ERR_FAIL_COND(!common_parent);
-
- //prepare for reinsert
- e.octant_owners.clear();
- e.common_parent = nullptr;
- e.aabb = p_aabb;
-
- _insert_element(&e, common_parent); // reinsert from this point
-
- pass++;
-
- for (typename List<typename Element::OctantOwner, AL>::Element *F = owners.front(); F;) {
- Octant *o = F->get().octant;
- typename List<typename Element::OctantOwner, AL>::Element *N = F->next();
-
- if (use_pairs && e.pairable) {
- o->pairable_elements.erase(F->get().E);
- } else {
- o->elements.erase(F->get().E);
- }
-
- if (_remove_element_from_octant(&e, o, common_parent->parent)) {
- owners.erase(F);
- }
-
- F = N;
- }
-
- if (use_pairs) {
- //unpair child elements in anything that survived
- for (typename List<typename Element::OctantOwner, AL>::Element *F = owners.front(); F; F = F->next()) {
- Octant *o = F->get().octant;
-
- // erase children pairs, unref ONCE
- pass++;
- for (int i = 0; i < 8; i++) {
- if (o->children[i]) {
- _unpair_element(&e, o->children[i]);
- }
- }
- }
-
- _element_check_pairs(&e);
- }
-
- _optimize();
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::set_pairable(OctreeElementID p_id, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
- typename ElementMap::Element *E = element_map.find(p_id);
- ERR_FAIL_COND(!E);
-
- Element &e = E->get();
-
- if (p_pairable == e.pairable && e.pairable_type == p_pairable_type && e.pairable_mask == p_pairable_mask) {
- return; // no changes, return
- }
-
- if (!e.aabb.has_no_surface()) {
- _remove_element(&e);
- }
-
- e.pairable = p_pairable;
- e.pairable_type = p_pairable_type;
- e.pairable_mask = p_pairable_mask;
- e.common_parent = nullptr;
-
- if (!e.aabb.has_no_surface()) {
- _ensure_valid_root(e.aabb);
- _insert_element(&e, root);
- if (use_pairs) {
- _element_check_pairs(&e);
- }
- }
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::erase(OctreeElementID p_id) {
- typename ElementMap::Element *E = element_map.find(p_id);
- ERR_FAIL_COND(!E);
-
- Element &e = E->get();
-
- if (!e.aabb.has_no_surface()) {
- _remove_element(&e);
- }
-
- element_map.erase(p_id);
- _optimize();
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) {
- if (*p_cull->result_idx == p_cull->result_max) {
- return; //pointless
- }
-
- if (!p_octant->elements.is_empty()) {
- typename List<Element *, AL>::Element *I;
- I = p_octant->elements.front();
-
- for (; I; I = I->next()) {
- Element *e = I->get();
-
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask))) {
- continue;
- }
- e->last_pass = pass;
-
- if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
- if (*p_cull->result_idx < p_cull->result_max) {
- p_cull->result_array[*p_cull->result_idx] = e->userdata;
- (*p_cull->result_idx)++;
- } else {
- return; // pointless to continue
- }
- }
- }
- }
-
- if (use_pairs && !p_octant->pairable_elements.is_empty()) {
- typename List<Element *, AL>::Element *I;
- I = p_octant->pairable_elements.front();
-
- for (; I; I = I->next()) {
- Element *e = I->get();
-
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask))) {
- continue;
- }
- e->last_pass = pass;
-
- if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
- if (*p_cull->result_idx < p_cull->result_max) {
- p_cull->result_array[*p_cull->result_idx] = e->userdata;
- (*p_cull->result_idx)++;
- } else {
- return; // pointless to continue
- }
- }
- }
- }
-
- for (int i = 0; i < 8; i++) {
- if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
- _cull_convex(p_octant->children[i], p_cull);
- }
- }
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
- if (*p_result_idx == p_result_max) {
- return; //pointless
- }
-
- if (!p_octant->elements.is_empty()) {
- typename List<Element *, AL>::Element *I;
- I = p_octant->elements.front();
- for (; I; I = I->next()) {
- Element *e = I->get();
-
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
- continue;
- }
- e->last_pass = pass;
-
- if (p_aabb.intersects_inclusive(e->aabb)) {
- if (*p_result_idx < p_result_max) {
- p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array) {
- p_subindex_array[*p_result_idx] = e->subindex;
- }
-
- (*p_result_idx)++;
- } else {
- return; // pointless to continue
- }
- }
- }
- }
-
- if (use_pairs && !p_octant->pairable_elements.is_empty()) {
- typename List<Element *, AL>::Element *I;
- I = p_octant->pairable_elements.front();
- for (; I; I = I->next()) {
- Element *e = I->get();
-
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
- continue;
- }
- e->last_pass = pass;
-
- if (p_aabb.intersects_inclusive(e->aabb)) {
- if (*p_result_idx < p_result_max) {
- p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array) {
- p_subindex_array[*p_result_idx] = e->subindex;
- }
- (*p_result_idx)++;
- } else {
- return; // pointless to continue
- }
- }
- }
- }
-
- for (int i = 0; i < 8; i++) {
- if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) {
- _cull_aabb(p_octant->children[i], p_aabb, p_result_array, p_result_idx, p_result_max, p_subindex_array, p_mask);
- }
- }
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
- if (*p_result_idx == p_result_max) {
- return; //pointless
- }
-
- if (!p_octant->elements.is_empty()) {
- typename List<Element *, AL>::Element *I;
- I = p_octant->elements.front();
- for (; I; I = I->next()) {
- Element *e = I->get();
-
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
- continue;
- }
- e->last_pass = pass;
-
- if (e->aabb.intersects_segment(p_from, p_to)) {
- if (*p_result_idx < p_result_max) {
- p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array) {
- p_subindex_array[*p_result_idx] = e->subindex;
- }
- (*p_result_idx)++;
-
- } else {
- return; // pointless to continue
- }
- }
- }
- }
-
- if (use_pairs && !p_octant->pairable_elements.is_empty()) {
- typename List<Element *, AL>::Element *I;
- I = p_octant->pairable_elements.front();
- for (; I; I = I->next()) {
- Element *e = I->get();
-
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
- continue;
- }
-
- e->last_pass = pass;
-
- if (e->aabb.intersects_segment(p_from, p_to)) {
- if (*p_result_idx < p_result_max) {
- p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array) {
- p_subindex_array[*p_result_idx] = e->subindex;
- }
-
- (*p_result_idx)++;
-
- } else {
- return; // pointless to continue
- }
- }
- }
- }
-
- for (int i = 0; i < 8; i++) {
- if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_segment(p_from, p_to)) {
- _cull_segment(p_octant->children[i], p_from, p_to, p_result_array, p_result_idx, p_result_max, p_subindex_array, p_mask);
- }
- }
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
- if (*p_result_idx == p_result_max) {
- return; //pointless
- }
-
- if (!p_octant->elements.is_empty()) {
- typename List<Element *, AL>::Element *I;
- I = p_octant->elements.front();
- for (; I; I = I->next()) {
- Element *e = I->get();
-
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
- continue;
- }
- e->last_pass = pass;
-
- if (e->aabb.has_point(p_point)) {
- if (*p_result_idx < p_result_max) {
- p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array) {
- p_subindex_array[*p_result_idx] = e->subindex;
- }
- (*p_result_idx)++;
-
- } else {
- return; // pointless to continue
- }
- }
- }
- }
-
- if (use_pairs && !p_octant->pairable_elements.is_empty()) {
- typename List<Element *, AL>::Element *I;
- I = p_octant->pairable_elements.front();
- for (; I; I = I->next()) {
- Element *e = I->get();
-
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
- continue;
- }
-
- e->last_pass = pass;
-
- if (e->aabb.has_point(p_point)) {
- if (*p_result_idx < p_result_max) {
- p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array) {
- p_subindex_array[*p_result_idx] = e->subindex;
- }
-
- (*p_result_idx)++;
-
- } else {
- return; // pointless to continue
- }
- }
- }
- }
-
- for (int i = 0; i < 8; i++) {
- //could be optimized..
- if (p_octant->children[i] && p_octant->children[i]->aabb.has_point(p_point)) {
- _cull_point(p_octant->children[i], p_point, p_result_array, p_result_idx, p_result_max, p_subindex_array, p_mask);
- }
- }
-}
-
-template <class T, bool use_pairs, class AL>
-int Octree<T, use_pairs, AL>::cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask) {
- if (!root || p_convex.size() == 0) {
- return 0;
- }
-
- Vector<Vector3> convex_points = Geometry3D::compute_convex_mesh_points(&p_convex[0], p_convex.size());
- if (convex_points.size() == 0) {
- return 0;
- }
-
- int result_count = 0;
- pass++;
- _CullConvexData cdata;
- cdata.planes = &p_convex[0];
- cdata.plane_count = p_convex.size();
- cdata.points = &convex_points[0];
- cdata.point_count = convex_points.size();
- cdata.result_array = p_result_array;
- cdata.result_max = p_result_max;
- cdata.result_idx = &result_count;
- cdata.mask = p_mask;
-
- _cull_convex(root, &cdata);
-
- return result_count;
-}
-
-template <class T, bool use_pairs, class AL>
-int Octree<T, use_pairs, AL>::cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
- if (!root) {
- return 0;
- }
-
- int result_count = 0;
- pass++;
- _cull_aabb(root, p_aabb, p_result_array, &result_count, p_result_max, p_subindex_array, p_mask);
-
- return result_count;
-}
-
-template <class T, bool use_pairs, class AL>
-int Octree<T, use_pairs, AL>::cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
- if (!root) {
- return 0;
- }
-
- int result_count = 0;
- pass++;
- _cull_segment(root, p_from, p_to, p_result_array, &result_count, p_result_max, p_subindex_array, p_mask);
-
- return result_count;
-}
-
-template <class T, bool use_pairs, class AL>
-int Octree<T, use_pairs, AL>::cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
- if (!root) {
- return 0;
- }
-
- int result_count = 0;
- pass++;
- _cull_point(root, p_point, p_result_array, &result_count, p_result_max, p_subindex_array, p_mask);
-
- return result_count;
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::set_pair_callback(PairCallback p_callback, void *p_userdata) {
- pair_callback = p_callback;
- pair_callback_userdata = p_userdata;
-}
-
-template <class T, bool use_pairs, class AL>
-void Octree<T, use_pairs, AL>::set_unpair_callback(UnpairCallback p_callback, void *p_userdata) {
- unpair_callback = p_callback;
- unpair_callback_userdata = p_userdata;
-}
-
-template <class T, bool use_pairs, class AL>
-Octree<T, use_pairs, AL>::Octree(real_t p_unit_size) {
- unit_size = p_unit_size;
-}
-
-#endif // OCTREE_H
diff --git a/core/math/plane.h b/core/math/plane.h
index 66c1741662..73babfa496 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -52,7 +52,7 @@ struct _NO_DISCARD_ Plane {
_FORCE_INLINE_ bool is_point_over(const Vector3 &p_point) const; ///< Point is over plane
_FORCE_INLINE_ real_t distance_to(const Vector3 &p_point) const;
- _FORCE_INLINE_ bool has_point(const Vector3 &p_point, real_t _epsilon = CMP_EPSILON) const;
+ _FORCE_INLINE_ bool has_point(const Vector3 &p_point, real_t p_tolerance = CMP_EPSILON) const;
/* intersections */
@@ -97,10 +97,10 @@ real_t Plane::distance_to(const Vector3 &p_point) const {
return (normal.dot(p_point) - d);
}
-bool Plane::has_point(const Vector3 &p_point, real_t _epsilon) const {
+bool Plane::has_point(const Vector3 &p_point, real_t p_tolerance) const {
real_t dist = normal.dot(p_point) - d;
dist = ABS(dist);
- return (dist <= _epsilon);
+ return (dist <= p_tolerance);
}
Plane::Plane(const Vector3 &p_normal, real_t p_d) :
diff --git a/core/multiplayer/multiplayer_api.cpp b/core/multiplayer/multiplayer_api.cpp
index 9605647b3f..6cce31e0d1 100644
--- a/core/multiplayer/multiplayer_api.cpp
+++ b/core/multiplayer/multiplayer_api.cpp
@@ -463,8 +463,12 @@ bool MultiplayerAPI::is_cache_confirmed(NodePath p_path, int p_peer) {
return cache->is_cache_confirmed(p_path, p_peer);
}
-bool MultiplayerAPI::send_object_cache(Object *p_obj, NodePath p_path, int p_peer_id, int &r_id) {
- return cache->send_object_cache(p_obj, p_path, p_peer_id, r_id);
+bool MultiplayerAPI::send_object_cache(Object *p_obj, int p_peer_id, int &r_id) {
+ return cache->send_object_cache(p_obj, p_peer_id, r_id);
+}
+
+int MultiplayerAPI::make_object_cache(Object *p_obj) {
+ return cache->make_object_cache(p_obj);
}
Object *MultiplayerAPI::get_cached_object(int p_from, uint32_t p_cache_id) {
diff --git a/core/multiplayer/multiplayer_api.h b/core/multiplayer/multiplayer_api.h
index cc7743ccf8..35452acb1f 100644
--- a/core/multiplayer/multiplayer_api.h
+++ b/core/multiplayer/multiplayer_api.h
@@ -77,7 +77,8 @@ public:
virtual void process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {}
// Returns true if all peers have cached path.
- virtual bool send_object_cache(Object *p_obj, NodePath p_path, int p_target, int &p_id) { return false; }
+ virtual bool send_object_cache(Object *p_obj, int p_target, int &r_id) { return false; }
+ virtual int make_object_cache(Object *p_obj) { return false; }
virtual Object *get_cached_object(int p_from, uint32_t p_cache_id) { return nullptr; }
virtual bool is_cache_confirmed(NodePath p_path, int p_peer) { return false; }
@@ -160,7 +161,8 @@ public:
Error replication_start(Object *p_object, Variant p_config);
Error replication_stop(Object *p_object, Variant p_config);
// Cache API
- bool send_object_cache(Object *p_obj, NodePath p_path, int p_target, int &p_id);
+ bool send_object_cache(Object *p_obj, int p_target, int &r_id);
+ int make_object_cache(Object *p_obj);
Object *get_cached_object(int p_from, uint32_t p_cache_id);
bool is_cache_confirmed(NodePath p_path, int p_peer);
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 3c9f373d12..d67315f20d 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -305,6 +305,13 @@ void ClassDB::add_compatibility_class(const StringName &p_class, const StringNam
compat_classes[p_class] = p_fallback;
}
+StringName ClassDB::get_compatibility_class(const StringName &p_class) {
+ if (compat_classes.has(p_class)) {
+ return compat_classes[p_class];
+ }
+ return StringName();
+}
+
Object *ClassDB::instantiate(const StringName &p_class) {
ClassInfo *ti;
{
@@ -536,7 +543,7 @@ MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_n
return nullptr;
}
-void ClassDB::bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant) {
+void ClassDB::bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield) {
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -555,13 +562,15 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
enum_name = enum_name.get_slicec('.', 1);
}
- List<StringName> *constants_list = type->enum_map.getptr(enum_name);
+ ClassInfo::EnumInfo *constants_list = type->enum_map.getptr(enum_name);
if (constants_list) {
- constants_list->push_back(p_name);
+ constants_list->constants.push_back(p_name);
+ constants_list->is_bitfield = p_is_bitfield;
} else {
- List<StringName> new_list;
- new_list.push_back(p_name);
+ ClassInfo::EnumInfo new_list;
+ new_list.is_bitfield = p_is_bitfield;
+ new_list.constants.push_back(p_name);
type->enum_map[enum_name] = new_list;
}
}
@@ -645,8 +654,8 @@ StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const S
ClassInfo *type = classes.getptr(p_class);
while (type) {
- for (KeyValue<StringName, List<StringName>> &E : type->enum_map) {
- List<StringName> &constants_list = E.value;
+ for (KeyValue<StringName, ClassInfo::EnumInfo> &E : type->enum_map) {
+ List<StringName> &constants_list = E.value.constants;
const List<StringName>::Element *found = constants_list.find(p_name);
if (found) {
return E.key;
@@ -669,7 +678,7 @@ void ClassDB::get_enum_list(const StringName &p_class, List<StringName> *p_enums
ClassInfo *type = classes.getptr(p_class);
while (type) {
- for (KeyValue<StringName, List<StringName>> &E : type->enum_map) {
+ for (KeyValue<StringName, ClassInfo::EnumInfo> &E : type->enum_map) {
p_enums->push_back(E.key);
}
@@ -687,10 +696,10 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_
ClassInfo *type = classes.getptr(p_class);
while (type) {
- const List<StringName> *constants = type->enum_map.getptr(p_enum);
+ const ClassInfo::EnumInfo *constants = type->enum_map.getptr(p_enum);
if (constants) {
- for (const List<StringName>::Element *E = constants->front(); E; E = E->next()) {
+ for (const List<StringName>::Element *E = constants->constants.front(); E; E = E->next()) {
p_constants->push_back(E->get());
}
}
@@ -748,6 +757,25 @@ bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool
return false;
}
+bool ClassDB::is_enum_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
+ OBJTYPE_RLOCK;
+
+ ClassInfo *type = classes.getptr(p_class);
+
+ while (type) {
+ if (type->enum_map.has(p_name) && type->enum_map[p_name].is_bitfield) {
+ return true;
+ }
+ if (p_no_inheritance) {
+ return false;
+ }
+
+ type = type->inherits_ptr;
+ }
+
+ return false;
+}
+
void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
OBJTYPE_WLOCK;
diff --git a/core/object/class_db.h b/core/object/class_db.h
index f2f73dc674..8b6a260d86 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -104,7 +104,12 @@ public:
HashMap<StringName, MethodBind *> method_map;
HashMap<StringName, int64_t> constant_map;
- HashMap<StringName, List<StringName>> enum_map;
+ struct EnumInfo {
+ List<StringName> constants;
+ bool is_bitfield = false;
+ };
+
+ HashMap<StringName, EnumInfo> enum_map;
HashMap<StringName, MethodInfo> signal_map;
List<PropertyInfo> property_list;
HashMap<StringName, PropertyInfo> property_map;
@@ -325,15 +330,17 @@ public:
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true, const Vector<String> &p_arg_names = Vector<String>(), bool p_object_core = false);
static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false);
- static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant);
+ static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield = false);
static void get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance = false);
static int64_t get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success = nullptr);
static bool has_integer_constant(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
static StringName get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
+ static StringName get_integer_constant_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false);
static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false);
static bool has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
+ static bool is_enum_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
static void set_method_error_return_values(const StringName &p_class, const StringName &p_method, const Vector<Error> &p_values);
static Vector<Error> get_method_error_return_values(const StringName &p_class, const StringName &p_method);
@@ -350,6 +357,7 @@ public:
static bool is_resource_extension(const StringName &p_extension);
static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback);
+ static StringName get_compatibility_class(const StringName &p_class);
static void set_current_api(APIType p_api);
static APIType get_current_api();
@@ -370,6 +378,9 @@ public:
#define BIND_ENUM_CONSTANT(m_constant) \
::ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
+#define BIND_BITFIELD_FLAG(m_constant) \
+ ::ClassDB::bind_integer_constant(get_class_static(), __constant_get_bitfield_name(m_constant, #m_constant), #m_constant, m_constant, true);
+
_FORCE_INLINE_ void errarray_add_str(Vector<Error> &arr) {
}
@@ -401,20 +412,23 @@ _FORCE_INLINE_ Vector<Error> errarray(P... p_args) {
#define BIND_ENUM_CONSTANT(m_constant) \
::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
+#define BIND_BITFIELD_FLAG(m_constant) \
+ ::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant, true);
+
#define BIND_METHOD_ERR_RETURN_DOC(m_method, ...)
#endif
-#define GDREGISTER_CLASS(m_class) \
- if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
- ::ClassDB::register_class<m_class>(); \
+#define GDREGISTER_CLASS(m_class) \
+ if (m_class::_class_is_enabled) { \
+ ::ClassDB::register_class<m_class>(); \
}
-#define GDREGISTER_VIRTUAL_CLASS(m_class) \
- if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
- ::ClassDB::register_class<m_class>(true); \
+#define GDREGISTER_VIRTUAL_CLASS(m_class) \
+ if (m_class::_class_is_enabled) { \
+ ::ClassDB::register_class<m_class>(true); \
}
#define GDREGISTER_ABSTRACT_CLASS(m_class) \
- if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
+ if (m_class::_class_is_enabled) { \
::ClassDB::register_abstract_class<m_class>(); \
}
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 440da00c17..5f2287c9d3 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -493,7 +493,7 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
uint32_t pcount;
const GDNativePropertyInfo *pinfo = _extension->get_property_list(_extension_instance, &pcount);
for (uint32_t i = 0; i < pcount; i++) {
- p_list->push_back(PropertyInfo(Variant::Type(pinfo[i].type), pinfo[i].class_name, PropertyHint(pinfo[i].hint), pinfo[i].hint_string, pinfo[i].usage, pinfo[i].class_name));
+ p_list->push_back(PropertyInfo(pinfo[i]));
}
if (_extension->free_property_list) {
_extension->free_property_list(_extension_instance, pinfo);
diff --git a/core/object/object.h b/core/object/object.h
index e065634000..17f75a4e1d 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -51,9 +51,7 @@ enum PropertyHint {
PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc"
PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout")
- PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
PROPERTY_HINT_LINK,
- PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
PROPERTY_HINT_LAYERS_2D_RENDER,
PROPERTY_HINT_LAYERS_2D_PHYSICS,
@@ -99,40 +97,39 @@ enum PropertyHint {
enum PropertyUsageFlags {
PROPERTY_USAGE_NONE = 0,
- PROPERTY_USAGE_STORAGE = 1,
- PROPERTY_USAGE_EDITOR = 2,
- PROPERTY_USAGE_NETWORK = 4,
- PROPERTY_USAGE_EDITOR_HELPER = 8,
- PROPERTY_USAGE_CHECKABLE = 16, //used for editing global variables
- PROPERTY_USAGE_CHECKED = 32, //used for editing global variables
- PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
- PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
- PROPERTY_USAGE_CATEGORY = 256,
- PROPERTY_USAGE_SUBGROUP = 512,
- PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
- PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
- PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
- PROPERTY_USAGE_STORE_IF_NULL = 16384,
- PROPERTY_USAGE_ANIMATE_AS_TRIGGER = 32768,
- PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED = 65536,
- PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE = 1 << 17,
- PROPERTY_USAGE_CLASS_IS_ENUM = 1 << 18,
- PROPERTY_USAGE_NIL_IS_VARIANT = 1 << 19,
- PROPERTY_USAGE_INTERNAL = 1 << 20,
- PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 21, // If the object is duplicated also this property will be duplicated
- PROPERTY_USAGE_HIGH_END_GFX = 1 << 22,
- PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 23,
- PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 24,
- PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 25, // Used in inspector to increment property when keyed in animation player
- PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 26, // when loading, the resource for this property can be set at the end of loading
- PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 27, // For Object properties, instantiate them when creating in editor.
- PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 28, //for project or editor settings, show when basic settings are selected
- PROPERTY_USAGE_READ_ONLY = 1 << 29, // Mark a property as read-only in the inspector.
- PROPERTY_USAGE_ARRAY = 1 << 30, // Used in the inspector to group properties as elements of an array.
-
- PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
- PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
- PROPERTY_USAGE_NO_EDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK,
+ PROPERTY_USAGE_STORAGE = 1 << 1,
+ PROPERTY_USAGE_EDITOR = 1 << 2,
+ PROPERTY_USAGE_CHECKABLE = 1 << 3, // Used for editing global variables.
+ PROPERTY_USAGE_CHECKED = 1 << 4, // Used for editing global variables.
+ PROPERTY_USAGE_INTERNATIONALIZED = 1 << 5, // Hint for internationalized strings.
+ PROPERTY_USAGE_GROUP = 1 << 6, // Used for grouping props in the editor.
+ PROPERTY_USAGE_CATEGORY = 1 << 7,
+ PROPERTY_USAGE_SUBGROUP = 1 << 8,
+ PROPERTY_USAGE_CLASS_IS_BITFIELD = 1 << 9,
+ PROPERTY_USAGE_NO_INSTANCE_STATE = 1 << 10,
+ PROPERTY_USAGE_RESTART_IF_CHANGED = 1 << 11,
+ PROPERTY_USAGE_SCRIPT_VARIABLE = 1 << 12,
+ PROPERTY_USAGE_STORE_IF_NULL = 1 << 13,
+ PROPERTY_USAGE_ANIMATE_AS_TRIGGER = 1 << 14,
+ PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED = 1 << 15,
+ PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE = 1 << 16,
+ PROPERTY_USAGE_CLASS_IS_ENUM = 1 << 17,
+ PROPERTY_USAGE_NIL_IS_VARIANT = 1 << 18,
+ PROPERTY_USAGE_INTERNAL = 1 << 19,
+ PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 20, // If the object is duplicated also this property will be duplicated.
+ PROPERTY_USAGE_HIGH_END_GFX = 1 << 21,
+ PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 22,
+ PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 23,
+ PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 24, // Used in inspector to increment property when keyed in animation player.
+ PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 25, // when loading, the resource for this property can be set at the end of loading.
+ PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 26, // For Object properties, instantiate them when creating in editor.
+ PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 27, //for project or editor settings, show when basic settings are selected.
+ PROPERTY_USAGE_READ_ONLY = 1 << 28, // Mark a property as read-only in the inspector.
+ PROPERTY_USAGE_ARRAY = 1 << 29, // Used in the inspector to group properties as elements of an array.
+
+ PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR,
+ PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNATIONALIZED,
+ PROPERTY_USAGE_NO_EDITOR = PROPERTY_USAGE_STORAGE,
};
#define ADD_SIGNAL(m_signal) ::ClassDB::add_signal(get_class_static(), m_signal)
@@ -190,6 +187,14 @@ struct PropertyInfo {
type(Variant::OBJECT),
class_name(p_class_name) {}
+ explicit PropertyInfo(const GDNativePropertyInfo &pinfo) :
+ type((Variant::Type)pinfo.type),
+ name(pinfo.name),
+ class_name(pinfo.class_name), // can be null
+ hint((PropertyHint)pinfo.hint),
+ hint_string(pinfo.hint_string), // can be null
+ usage(pinfo.usage) {}
+
bool operator==(const PropertyInfo &p_info) const {
return ((type == p_info.type) &&
(name == p_info.name) &&
@@ -209,14 +214,11 @@ Array convert_property_list(const List<PropertyInfo> *p_list);
enum MethodFlags {
METHOD_FLAG_NORMAL = 1,
METHOD_FLAG_EDITOR = 2,
- METHOD_FLAG_NOSCRIPT = 4,
- METHOD_FLAG_CONST = 8,
- METHOD_FLAG_REVERSE = 16, // used for events
- METHOD_FLAG_VIRTUAL = 32,
- METHOD_FLAG_FROM_SCRIPT = 64,
- METHOD_FLAG_VARARG = 128,
- METHOD_FLAG_STATIC = 256,
- METHOD_FLAG_OBJECT_CORE = 512,
+ METHOD_FLAG_CONST = 4,
+ METHOD_FLAG_VIRTUAL = 8,
+ METHOD_FLAG_VARARG = 16,
+ METHOD_FLAG_STATIC = 32,
+ METHOD_FLAG_OBJECT_CORE = 64,
METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL,
};
@@ -356,6 +358,7 @@ private:
friend class ::ClassDB; \
\
public: \
+ static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \
virtual String get_class() const override { \
if (_get_extension()) { \
return _get_extension()->class_name.operator String(); \
@@ -665,6 +668,8 @@ public: // Should be protected, but bug in clang++.
_FORCE_INLINE_ static void register_custom_data_to_otdb() {}
public:
+ static constexpr bool _class_is_enabled = true;
+
void notify_property_list_changed();
static void *get_class_ptr_static() {
diff --git a/core/object/script_language.h b/core/object/script_language.h
index 776a9bfaab..686ab5b8d3 100644
--- a/core/object/script_language.h
+++ b/core/object/script_language.h
@@ -350,6 +350,7 @@ public:
LOOKUP_RESULT_CLASS_SIGNAL,
LOOKUP_RESULT_CLASS_ENUM,
LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE,
+ LOOKUP_RESULT_CLASS_ANNOTATION,
LOOKUP_RESULT_MAX
};
@@ -402,6 +403,7 @@ public:
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
virtual void get_public_functions(List<MethodInfo> *p_functions) const = 0;
virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const = 0;
+ virtual void get_public_annotations(List<MethodInfo> *p_annotations) const = 0;
struct ProfilingInfo {
StringName signature;
diff --git a/core/object/script_language_extension.cpp b/core/object/script_language_extension.cpp
index 5af79bbea3..ab8dd6d1ee 100644
--- a/core/object/script_language_extension.cpp
+++ b/core/object/script_language_extension.cpp
@@ -134,6 +134,7 @@ void ScriptLanguageExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_recognized_extensions);
GDVIRTUAL_BIND(_get_public_functions);
GDVIRTUAL_BIND(_get_public_constants);
+ GDVIRTUAL_BIND(_get_public_annotations);
GDVIRTUAL_BIND(_profiling_start);
GDVIRTUAL_BIND(_profiling_stop);
@@ -160,6 +161,7 @@ void ScriptLanguageExtension::_bind_methods() {
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_SIGNAL);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_ENUM);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE);
+ BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_ANNOTATION);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_MAX);
BIND_ENUM_CONSTANT(LOCATION_LOCAL);
diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h
index 406a431a11..2c53139ec2 100644
--- a/core/object/script_language_extension.h
+++ b/core/object/script_language_extension.h
@@ -580,6 +580,15 @@ public:
p_constants->push_back(Pair<String, Variant>(d["name"], d["value"]));
}
}
+ GDVIRTUAL0RC(TypedArray<Dictionary>, _get_public_annotations)
+ virtual void get_public_annotations(List<MethodInfo> *p_annotations) const override {
+ TypedArray<Dictionary> ret;
+ GDVIRTUAL_REQUIRED_CALL(_get_public_annotations, ret);
+ for (int i = 0; i < ret.size(); i++) {
+ MethodInfo mi = MethodInfo::from_dict(ret[i]);
+ p_annotations->push_back(mi);
+ }
+ }
EXBIND0(profiling_start)
EXBIND0(profiling_stop)
@@ -671,7 +680,7 @@ public:
uint32_t pcount;
const GDNativePropertyInfo *pinfo = native_info->get_property_list_func(instance, &pcount);
for (uint32_t i = 0; i < pcount; i++) {
- p_list->push_back(PropertyInfo(Variant::Type(pinfo[i].type), pinfo[i].class_name, PropertyHint(pinfo[i].hint), pinfo[i].hint_string, pinfo[i].usage, pinfo[i].class_name));
+ p_list->push_back(PropertyInfo(pinfo[i]));
}
if (native_info->free_property_list_func) {
native_info->free_property_list_func(instance, pinfo);
@@ -716,9 +725,9 @@ public:
m.name = minfo[i].name;
m.flags = minfo[i].flags;
m.id = minfo[i].id;
- m.return_val = PropertyInfo(Variant::Type(minfo[i].return_value.type), minfo[i].return_value.class_name, PropertyHint(minfo[i].return_value.hint), minfo[i].return_value.hint_string, minfo[i].return_value.usage, minfo[i].return_value.class_name);
+ m.return_val = PropertyInfo(minfo[i].return_value);
for (uint32_t j = 0; j < minfo[i].argument_count; j++) {
- m.arguments.push_back(PropertyInfo(Variant::Type(minfo[i].arguments[j].type), minfo[i].arguments[j].class_name, PropertyHint(minfo[i].arguments[j].hint), minfo[i].arguments[j].hint_string, minfo[i].arguments[j].usage, minfo[i].arguments[j].class_name));
+ m.arguments.push_back(PropertyInfo(minfo[i].arguments[j]));
}
const Variant *def_values = (const Variant *)minfo[i].default_arguments;
for (uint32_t j = 0; j < minfo[i].default_argument_count; j++) {
diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp
new file mode 100644
index 0000000000..c276802f99
--- /dev/null
+++ b/core/object/worker_thread_pool.cpp
@@ -0,0 +1,463 @@
+/*************************************************************************/
+/* worker_thread_pool.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "worker_thread_pool.h"
+
+#include "core/os/os.h"
+
+WorkerThreadPool *WorkerThreadPool::singleton = nullptr;
+
+void WorkerThreadPool::_process_task_queue() {
+ task_mutex.lock();
+ Task *task = task_queue.first()->self();
+ task_queue.remove(task_queue.first());
+ task_mutex.unlock();
+ _process_task(task);
+}
+
+void WorkerThreadPool::_process_task(Task *p_task) {
+ bool low_priority = p_task->low_priority;
+
+ if (p_task->group) {
+ // Handling a group
+ bool do_post = false;
+ if (p_task->native_group_func) {
+ while (true) {
+ uint32_t work_index = p_task->group->index.postincrement();
+ if (work_index >= p_task->group->max) {
+ do_post = work_index == p_task->group->max; // First one reaching max handles semaphore and clean-up.
+ break;
+ }
+ p_task->native_group_func(p_task->native_func_userdata, work_index);
+ }
+
+ } else {
+ Callable::CallError ce;
+ Variant ret;
+ Variant arg;
+ Variant *argptr = &arg;
+ while (true) {
+ uint32_t work_index = p_task->group->index.postincrement();
+ if (work_index >= p_task->group->max) {
+ do_post = work_index == p_task->group->max; // First one reaching max handles semaphore and clean-up.
+ break;
+ }
+ arg = work_index;
+ p_task->callable.call((const Variant **)&argptr, 1, ret, ce);
+ }
+ }
+
+ if (low_priority && use_native_low_priority_threads) {
+ p_task->completed = true;
+ p_task->done_semaphore.post();
+ if (do_post) {
+ p_task->group->completed.set_to(true);
+ }
+ } else {
+ if (do_post) {
+ p_task->group->done_semaphore.post();
+ p_task->group->completed.set_to(true);
+ }
+ uint32_t max_users = p_task->group->tasks_used + 1; // Add 1 because the thread waiting for it is also user. Read before to avoid another thread freeing task after increment.
+ uint32_t finished_users = p_task->group->finished.increment();
+
+ if (finished_users == max_users) {
+ // Get rid of the group, because nobody else is using it.
+ task_mutex.lock();
+ group_allocator.free(p_task->group);
+ task_mutex.unlock();
+ }
+
+ // For groups, tasks get rid of themselves.
+
+ task_mutex.lock();
+ task_allocator.free(p_task);
+ task_mutex.unlock();
+ }
+ } else {
+ if (p_task->native_func) {
+ p_task->native_func(p_task->native_func_userdata);
+ } else {
+ Callable::CallError ce;
+ Variant ret;
+ p_task->callable.call(nullptr, 0, ret, ce);
+ }
+
+ p_task->completed = true;
+ p_task->done_semaphore.post();
+ }
+
+ if (!use_native_low_priority_threads && low_priority) {
+ // A low prioriry task was freed, so see if we can move a pending one to the high priority queue.
+ bool post = false;
+ task_mutex.lock();
+ if (low_priority_task_queue.first()) {
+ Task *low_prio_task = low_priority_task_queue.first()->self();
+ low_priority_task_queue.remove(low_priority_task_queue.first());
+ task_queue.add_last(&low_prio_task->task_elem);
+ post = true;
+ } else {
+ low_priority_threads_used.decrement();
+ }
+ task_mutex.lock();
+ if (post) {
+ task_available_semaphore.post();
+ }
+ }
+}
+
+void WorkerThreadPool::_thread_function(void *p_user) {
+ while (true) {
+ singleton->task_available_semaphore.wait();
+ if (singleton->exit_threads.is_set()) {
+ break;
+ }
+ singleton->_process_task_queue();
+ }
+}
+
+void WorkerThreadPool::_native_low_priority_thread_function(void *p_user) {
+ Task *task = (Task *)p_user;
+ singleton->_process_task(task);
+}
+
+void WorkerThreadPool::_post_task(Task *p_task, bool p_high_priority) {
+ task_mutex.lock();
+ p_task->low_priority = !p_high_priority;
+ if (!p_high_priority && use_native_low_priority_threads) {
+ task_mutex.unlock();
+ p_task->low_priority_thread = native_thread_allocator.alloc();
+ p_task->low_priority_thread->start(_native_low_priority_thread_function, p_task); // Pask task directly to thread.
+
+ } else if (p_high_priority || low_priority_threads_used.get() < max_low_priority_threads) {
+ task_queue.add_last(&p_task->task_elem);
+ if (!p_high_priority) {
+ low_priority_threads_used.increment();
+ }
+ task_mutex.unlock();
+ task_available_semaphore.post();
+ } else {
+ // Too many threads using low priority, must go to queue.
+ low_priority_task_queue.add_last(&p_task->task_elem);
+ task_mutex.unlock();
+ }
+}
+
+WorkerThreadPool::TaskID WorkerThreadPool::add_native_task(void (*p_func)(void *), void *p_userdata, bool p_high_priority, const String &p_description) {
+ task_mutex.lock();
+ // Get a free task
+ Task *task = task_allocator.alloc();
+ TaskID id = last_task++;
+ task->native_func = p_func;
+ task->native_func_userdata = p_userdata;
+ task->description = p_description;
+ tasks.insert(id, task);
+ task_mutex.unlock();
+
+ _post_task(task, p_high_priority);
+
+ return id;
+}
+
+WorkerThreadPool::TaskID WorkerThreadPool::add_task(const Callable &p_action, bool p_high_priority, const String &p_description) {
+ task_mutex.lock();
+ // Get a free task
+ Task *task = task_allocator.alloc();
+ TaskID id = last_task++;
+ task->callable = p_action;
+ task->description = p_description;
+ tasks.insert(id, task);
+ task_mutex.unlock();
+
+ _post_task(task, p_high_priority);
+
+ return id;
+}
+
+bool WorkerThreadPool::is_task_completed(TaskID p_task_id) const {
+ task_mutex.lock();
+ const Task *const *taskp = tasks.getptr(p_task_id);
+ if (!taskp) {
+ task_mutex.unlock();
+ ERR_FAIL_V_MSG(false, "Invalid Task ID"); // Invalid task
+ }
+
+ bool completed = (*taskp)->completed;
+ task_mutex.unlock();
+
+ return completed;
+}
+
+void WorkerThreadPool::wait_for_task_completion(TaskID p_task_id) {
+ task_mutex.lock();
+ Task **taskp = tasks.getptr(p_task_id);
+ if (!taskp) {
+ task_mutex.unlock();
+ ERR_FAIL_MSG("Invalid Task ID"); // Invalid task
+ }
+ Task *task = *taskp;
+
+ if (task->waiting) {
+ String description = task->description;
+ task_mutex.unlock();
+ if (description.is_empty()) {
+ ERR_FAIL_MSG("Another thread is waiting on this task: " + itos(p_task_id)); // Invalid task
+ } else {
+ ERR_FAIL_MSG("Another thread is waiting on this task: " + description + " (" + itos(p_task_id) + ")"); // Invalid task
+ }
+ }
+
+ task->waiting = true;
+
+ task_mutex.unlock();
+
+ if (use_native_low_priority_threads && task->low_priority) {
+ task->low_priority_thread->wait_to_finish();
+ native_thread_allocator.free(task->low_priority_thread);
+ } else {
+ int *index = thread_ids.getptr(Thread::get_caller_id());
+
+ if (index) {
+ // We are an actual process thread, we must not be blocked so continue processing stuff if available.
+ while (true) {
+ if (task->done_semaphore.try_wait()) {
+ // If done, exit
+ break;
+ }
+ if (task_available_semaphore.try_wait()) {
+ // Solve tasks while they are around.
+ _process_task_queue();
+ continue;
+ }
+ OS::get_singleton()->delay_usec(1); // Microsleep, this could be converted to waiting for multiple objects in supported platforms for a bit more performance.
+ }
+ } else {
+ task->done_semaphore.wait();
+ }
+ }
+
+ task_mutex.lock();
+ tasks.erase(p_task_id);
+ task_allocator.free(task);
+ task_mutex.unlock();
+}
+
+WorkerThreadPool::GroupID WorkerThreadPool::add_native_group_task(void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) {
+ ERR_FAIL_COND_V(p_elements <= 0, INVALID_TASK_ID);
+ if (p_tasks < 0) {
+ p_tasks = threads.size();
+ }
+
+ task_mutex.lock();
+ Group *group = group_allocator.alloc();
+ GroupID id = last_task++;
+ group->max = p_elements;
+ group->self = id;
+ group->tasks_used = p_tasks;
+ Task **tasks_posted = (Task **)alloca(sizeof(Task *) * p_tasks);
+ for (int i = 0; i < p_tasks; i++) {
+ Task *task = task_allocator.alloc();
+ task->native_group_func = p_func;
+ task->native_func_userdata = p_userdata;
+ task->description = p_description;
+ task->group = group;
+ tasks_posted[i] = task;
+ // No task ID is used.
+ }
+ groups[id] = group;
+ task_mutex.unlock();
+
+ if (!p_high_priority && use_native_low_priority_threads) {
+ group->low_priority_native_tasks.resize(p_tasks);
+ }
+
+ for (int i = 0; i < p_tasks; i++) {
+ _post_task(tasks_posted[i], p_high_priority);
+ if (!p_high_priority && use_native_low_priority_threads) {
+ group->low_priority_native_tasks[i] = tasks_posted[i];
+ }
+ }
+
+ return id;
+}
+
+WorkerThreadPool::GroupID WorkerThreadPool::add_group_task(const Callable &p_action, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) {
+ ERR_FAIL_COND_V(p_elements <= 0, INVALID_TASK_ID);
+ if (p_tasks < 0) {
+ p_tasks = threads.size();
+ }
+
+ task_mutex.lock();
+ Group *group = group_allocator.alloc();
+ GroupID id = last_task++;
+ group->max = p_elements;
+ group->self = id;
+ group->tasks_used = p_tasks;
+ Task **tasks_posted = (Task **)alloca(sizeof(Task *) * p_tasks);
+ for (int i = 0; i < p_tasks; i++) {
+ Task *task = task_allocator.alloc();
+ task->callable = p_action;
+ task->description = p_description;
+ task->group = group;
+ tasks_posted[i] = task;
+ // No task ID is used.
+ }
+ groups[id] = group;
+ task_mutex.unlock();
+
+ if (!p_high_priority && use_native_low_priority_threads) {
+ group->low_priority_native_tasks.resize(p_tasks);
+ }
+
+ for (int i = 0; i < p_tasks; i++) {
+ _post_task(tasks_posted[i], p_high_priority);
+ if (!p_high_priority && use_native_low_priority_threads) {
+ group->low_priority_native_tasks[i] = tasks_posted[i];
+ }
+ }
+ return id;
+}
+
+bool WorkerThreadPool::is_group_task_completed(GroupID p_group) const {
+ task_mutex.lock();
+ const Group *const *groupp = groups.getptr(p_group);
+ if (!groupp) {
+ task_mutex.unlock();
+ ERR_FAIL_V_MSG(false, "Invalid Group ID");
+ }
+ bool completed = (*groupp)->completed.is_set();
+ task_mutex.unlock();
+ return completed;
+}
+
+void WorkerThreadPool::wait_for_group_task_completion(GroupID p_group) {
+ task_mutex.lock();
+ Group **groupp = groups.getptr(p_group);
+ task_mutex.unlock();
+ if (!groupp) {
+ ERR_FAIL_MSG("Invalid Group ID");
+ }
+ Group *group = *groupp;
+
+ if (group->low_priority_native_tasks.size() > 0) {
+ for (uint32_t i = 0; i < group->low_priority_native_tasks.size(); i++) {
+ group->low_priority_native_tasks[i]->low_priority_thread->wait_to_finish();
+ native_thread_allocator.free(group->low_priority_native_tasks[i]->low_priority_thread);
+ task_mutex.lock();
+ task_allocator.free(group->low_priority_native_tasks[i]);
+ task_mutex.unlock();
+ }
+
+ task_mutex.lock();
+ group_allocator.free(group);
+ task_mutex.unlock();
+ } else {
+ group->done_semaphore.wait();
+
+ uint32_t max_users = group->tasks_used + 1; // Add 1 because the thread waiting for it is also user. Read before to avoid another thread freeing task after increment.
+ uint32_t finished_users = group->finished.increment(); // fetch happens before inc, so increment later.
+
+ if (finished_users == max_users) {
+ // All tasks using this group are gone (finished before the group), so clear the gorup too.
+ task_mutex.lock();
+ group_allocator.free(group);
+ task_mutex.unlock();
+ }
+ }
+
+ groups.erase(p_group); // Threads do not access this, so safe to erase here.
+}
+
+void WorkerThreadPool::init(int p_thread_count, bool p_use_native_threads_low_priority, float p_low_priority_task_ratio) {
+ ERR_FAIL_COND(threads.size() > 0);
+ if (p_thread_count < 0) {
+ p_thread_count = OS::get_singleton()->get_default_thread_pool_size();
+ }
+
+ if (p_use_native_threads_low_priority) {
+ max_low_priority_threads = 0;
+ } else {
+ max_low_priority_threads = CLAMP(p_thread_count * p_low_priority_task_ratio, 1, p_thread_count);
+ }
+
+ use_native_low_priority_threads = p_use_native_threads_low_priority;
+
+ threads.resize(p_thread_count);
+
+ for (uint32_t i = 0; i < threads.size(); i++) {
+ threads[i].index = i;
+ threads[i].thread.start(&WorkerThreadPool::_thread_function, &threads[i]);
+ thread_ids.insert(threads[i].thread.get_id(), i);
+ }
+}
+
+void WorkerThreadPool::finish() {
+ if (threads.size() == 0) {
+ return;
+ }
+
+ task_mutex.lock();
+ SelfList<Task> *E = low_priority_task_queue.first();
+ while (E) {
+ print_error("Task waiting was never re-claimed: " + E->self()->description);
+ E = E->next();
+ }
+ task_mutex.unlock();
+
+ exit_threads.set_to(true);
+
+ for (uint32_t i = 0; i < threads.size(); i++) {
+ task_available_semaphore.post();
+ }
+
+ for (uint32_t i = 0; i < threads.size(); i++) {
+ threads[i].thread.wait_to_finish();
+ }
+
+ threads.clear();
+}
+
+void WorkerThreadPool::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("add_task", "action", "high_priority", "description"), &WorkerThreadPool::add_task, DEFVAL(false), DEFVAL(String()));
+ ClassDB::bind_method(D_METHOD("is_task_completed", "task_id"), &WorkerThreadPool::is_task_completed);
+ ClassDB::bind_method(D_METHOD("wait_for_task_completion", "task_id"), &WorkerThreadPool::wait_for_task_completion);
+
+ ClassDB::bind_method(D_METHOD("add_group_task", "action", "elements", "tasks_needed", "high_priority", "description"), &WorkerThreadPool::add_group_task, DEFVAL(-1), DEFVAL(false), DEFVAL(String()));
+ ClassDB::bind_method(D_METHOD("is_group_task_completed", "group_id"), &WorkerThreadPool::is_group_task_completed);
+ ClassDB::bind_method(D_METHOD("wait_for_group_task_completion", "group_id"), &WorkerThreadPool::wait_for_group_task_completion);
+}
+
+WorkerThreadPool::WorkerThreadPool() {
+ singleton = this;
+}
+
+WorkerThreadPool::~WorkerThreadPool() {
+ finish();
+}
diff --git a/core/object/worker_thread_pool.h b/core/object/worker_thread_pool.h
new file mode 100644
index 0000000000..dfb0050605
--- /dev/null
+++ b/core/object/worker_thread_pool.h
@@ -0,0 +1,146 @@
+/*************************************************************************/
+/* worker_thread_pool.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef WORKER_THREAD_POOL_H
+#define WORKER_THREAD_POOL_H
+
+#include "core/os/memory.h"
+#include "core/os/os.h"
+#include "core/os/semaphore.h"
+#include "core/os/thread.h"
+#include "core/templates/local_vector.h"
+#include "core/templates/paged_allocator.h"
+#include "core/templates/rid.h"
+#include "core/templates/safe_refcount.h"
+
+class WorkerThreadPool : public Object {
+ GDCLASS(WorkerThreadPool, Object)
+public:
+ enum {
+ INVALID_TASK_ID = -1
+ };
+
+ typedef int64_t TaskID;
+ typedef int64_t GroupID;
+
+private:
+ struct Task;
+
+ struct Group {
+ GroupID self;
+ SafeNumeric<uint32_t> index;
+ uint32_t max = 0;
+ Semaphore done_semaphore;
+ SafeFlag completed;
+ SafeNumeric<uint32_t> finished;
+ uint32_t tasks_used = 0;
+ TightLocalVector<Task *> low_priority_native_tasks;
+ };
+
+ struct Task {
+ Callable callable;
+ void (*native_func)(void *) = nullptr;
+ void (*native_group_func)(void *, uint32_t) = nullptr;
+ void *native_func_userdata = nullptr;
+ String description;
+ Semaphore done_semaphore;
+ bool completed = false;
+ Group *group = nullptr;
+ SelfList<Task> task_elem;
+ bool waiting = false; // Waiting for completion
+ bool low_priority = false;
+ Thread *low_priority_thread = nullptr;
+ Task() :
+ task_elem(this) {}
+ };
+
+ PagedAllocator<Task> task_allocator;
+ PagedAllocator<Group> group_allocator;
+ PagedAllocator<Thread> native_thread_allocator;
+
+ SelfList<Task>::List low_priority_task_queue;
+ SelfList<Task>::List task_queue;
+
+ Mutex task_mutex;
+ Semaphore task_available_semaphore;
+
+ struct ThreadData {
+ uint32_t index;
+ Thread thread;
+ };
+
+ TightLocalVector<ThreadData> threads;
+ SafeFlag exit_threads;
+
+ HashMap<Thread::ID, int> thread_ids;
+ HashMap<TaskID, Task *> tasks;
+ HashMap<GroupID, Group *> groups;
+
+ bool use_native_low_priority_threads = false;
+ uint32_t max_low_priority_threads = 0;
+ SafeNumeric<uint32_t> low_priority_threads_used;
+
+ uint64_t last_task = 1;
+
+ static void _thread_function(void *p_user);
+ static void _native_low_priority_thread_function(void *p_user);
+
+ void _process_task_queue();
+ void _process_task(Task *task);
+
+ void _post_task(Task *p_task, bool p_high_priority);
+
+ static WorkerThreadPool *singleton;
+
+protected:
+ static void _bind_methods();
+
+public:
+ TaskID add_native_task(void (*p_func)(void *), void *p_userdata, bool p_high_priority = false, const String &p_description = String());
+ TaskID add_task(const Callable &p_action, bool p_high_priority = false, const String &p_description = String());
+
+ bool is_task_completed(TaskID p_task_id) const;
+ void wait_for_task_completion(TaskID p_task_id);
+
+ GroupID add_native_group_task(void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks = -1, bool p_high_priority = false, const String &p_description = String());
+ GroupID add_group_task(const Callable &p_action, int p_elements, int p_tasks = -1, bool p_high_priority = false, const String &p_description = String());
+ bool is_group_task_completed(GroupID p_group) const;
+ void wait_for_group_task_completion(GroupID p_group);
+
+ _FORCE_INLINE_ int get_thread_count() const { return threads.size(); }
+
+ static WorkerThreadPool *get_singleton() { return singleton; }
+ void init(int p_thread_count = -1, bool p_use_native_threads_low_priority = true, float p_low_priority_task_ratio = 0.3);
+ void finish();
+ WorkerThreadPool();
+ ~WorkerThreadPool();
+};
+
+#endif // WORKER_THREAD_POOL_H
diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp
index 3e690991d9..a592791d06 100644
--- a/core/os/keyboard.cpp
+++ b/core/os/keyboard.cpp
@@ -61,7 +61,7 @@ static const _KeyCodeText _keycodes[] = {
{Key::PAGEDOWN ,"PageDown"},
{Key::SHIFT ,"Shift"},
{Key::CTRL ,"Ctrl"},
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
{Key::META ,"Command"},
#else
{Key::META ,"Meta"},
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 93477f4288..b9daf6fa53 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -100,6 +100,21 @@ void OS::print(const char *p_format, ...) {
va_end(argp);
}
+void OS::print_rich(const char *p_format, ...) {
+ if (!_stdout_enabled) {
+ return;
+ }
+
+ va_list argp;
+ va_start(argp, p_format);
+
+ if (_logger) {
+ _logger->logv(p_format, argp, false);
+ }
+
+ va_end(argp);
+}
+
void OS::printerr(const char *p_format, ...) {
if (!_stderr_enabled) {
return;
diff --git a/core/os/os.h b/core/os/os.h
index c6ea9d869a..0428f6df2a 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -120,6 +120,7 @@ public:
void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, Logger::ErrorType p_type = Logger::ERR_ERROR);
void print(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
+ void print_rich(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
virtual String get_stdin_string(bool p_block = true) = 0;
@@ -159,6 +160,7 @@ public:
virtual String get_name() const = 0;
virtual List<String> get_cmdline_args() const { return _cmdline; }
+ virtual List<String> get_cmdline_platform_args() const { return List<String>(); }
virtual String get_model_name() const;
bool is_layered_allowed() const { return _allow_layered; }
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index e60d325f74..aab4b9a580 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -74,6 +74,7 @@
#include "core/object/class_db.h"
#include "core/object/script_language_extension.h"
#include "core/object/undo_redo.h"
+#include "core/object/worker_thread_pool.h"
#include "core/os/main_loop.h"
#include "core/os/time.h"
#include "core/string/optimized_translation.h"
@@ -101,6 +102,8 @@ static IP *ip = nullptr;
static core_bind::Geometry2D *_geometry_2d = nullptr;
static core_bind::Geometry3D *_geometry_3d = nullptr;
+static WorkerThreadPool *worker_thread_pool = nullptr;
+
extern Mutex _global_mutex;
static NativeExtensionManager *native_extension_manager = nullptr;
@@ -189,6 +192,8 @@ void register_core_types() {
GDREGISTER_CLASS(PacketPeerUDP);
GDREGISTER_CLASS(UDPServer);
+ GDREGISTER_ABSTRACT_CLASS(WorkerThreadPool);
+
ClassDB::register_custom_instance_class<HTTPClient>();
// Crypto
@@ -271,6 +276,8 @@ void register_core_types() {
GDREGISTER_NATIVE_STRUCT(AudioFrame, "float left;float right");
GDREGISTER_NATIVE_STRUCT(ScriptLanguageExtensionProfilingInfo, "StringName signature;uint64_t call_count;uint64_t total_time;uint64_t self_time");
+
+ worker_thread_pool = memnew(WorkerThreadPool);
}
void register_core_settings() {
@@ -279,9 +286,18 @@ void register_core_settings() {
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/tcp/connect_timeout_seconds", PropertyInfo(Variant::INT, "network/limits/tcp/connect_timeout_seconds", PROPERTY_HINT_RANGE, "1,1800,1"));
GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16));
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/packet_peer_stream/max_buffer_po2", PropertyInfo(Variant::INT, "network/limits/packet_peer_stream/max_buffer_po2", PROPERTY_HINT_RANGE, "0,64,1,or_greater"));
-
GLOBAL_DEF("network/ssl/certificate_bundle_override", "");
ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificate_bundle_override", PropertyInfo(Variant::STRING, "network/ssl/certificate_bundle_override", PROPERTY_HINT_FILE, "*.crt"));
+
+ int worker_threads = GLOBAL_DEF("threading/worker_pool/max_threads", -1);
+ bool low_priority_use_system_threads = GLOBAL_DEF("threading/worker_pool/use_system_threads_for_low_priority_tasks", true);
+ float low_property_ratio = GLOBAL_DEF("threading/worker_pool/low_priority_thread_ratio", 0.3);
+
+ if (Engine::get_singleton()->is_editor_hint() || Engine::get_singleton()->is_project_manager_hint()) {
+ worker_thread_pool->init();
+ } else {
+ worker_thread_pool->init(worker_threads, low_priority_use_system_threads, low_property_ratio);
+ }
}
void register_core_singletons() {
@@ -319,6 +335,7 @@ void register_core_singletons() {
Engine::get_singleton()->add_singleton(Engine::Singleton("Time", Time::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("NativeExtensionManager", NativeExtensionManager::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceUID", ResourceUID::get_singleton()));
+ Engine::get_singleton()->add_singleton(Engine::Singleton("WorkerThreadPool", worker_thread_pool));
}
void register_core_extensions() {
@@ -350,6 +367,8 @@ void unregister_core_types() {
memdelete(_geometry_2d);
memdelete(_geometry_3d);
+ memdelete(worker_thread_pool);
+
ResourceLoader::remove_resource_format_loader(resource_format_image);
resource_format_image.unref();
diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp
index 238897c2b1..30fa434fad 100644
--- a/core/string/node_path.cpp
+++ b/core/string/node_path.cpp
@@ -199,6 +199,21 @@ Vector<StringName> NodePath::get_subnames() const {
return Vector<StringName>();
}
+StringName NodePath::get_concatenated_names() const {
+ ERR_FAIL_COND_V(!data, StringName());
+
+ if (!data->concatenated_path) {
+ int pc = data->path.size();
+ String concatenated;
+ const StringName *sn = data->path.ptr();
+ for (int i = 0; i < pc; i++) {
+ concatenated += i == 0 ? sn[i].operator String() : "/" + sn[i];
+ }
+ data->concatenated_path = concatenated;
+ }
+ return data->concatenated_path;
+}
+
StringName NodePath::get_concatenated_subnames() const {
ERR_FAIL_COND_V(!data, StringName());
diff --git a/core/string/node_path.h b/core/string/node_path.h
index 53976bd524..2bce33e21e 100644
--- a/core/string/node_path.h
+++ b/core/string/node_path.h
@@ -39,6 +39,7 @@ class NodePath {
SafeRefCount refcount;
Vector<StringName> path;
Vector<StringName> subpath;
+ StringName concatenated_path;
StringName concatenated_subpath;
bool absolute;
bool has_slashes;
@@ -59,6 +60,7 @@ public:
StringName get_subname(int p_idx) const;
Vector<StringName> get_names() const;
Vector<StringName> get_subnames() const;
+ StringName get_concatenated_names() const;
StringName get_concatenated_subnames() const;
NodePath rel_path_to(const NodePath &p_np) const;
diff --git a/core/string/print_string.cpp b/core/string/print_string.cpp
index 919c9e08e3..f58486e0a5 100644
--- a/core/string/print_string.cpp
+++ b/core/string/print_string.cpp
@@ -79,7 +79,98 @@ void __print_line(String p_string) {
_global_lock();
PrintHandlerList *l = print_handler_list;
while (l) {
- l->printfunc(l->userdata, p_string, false);
+ l->printfunc(l->userdata, p_string, false, false);
+ l = l->next;
+ }
+
+ _global_unlock();
+}
+
+void __print_line_rich(String p_string) {
+ if (!_print_line_enabled) {
+ return;
+ }
+
+ // Convert a subset of BBCode tags to ANSI escape codes for correct display in the terminal.
+ // Support of those ANSI escape codes varies across terminal emulators,
+ // especially for italic and strikethrough.
+ String p_string_ansi = p_string;
+
+ p_string_ansi = p_string_ansi.replace("[b]", "\u001b[1m");
+ p_string_ansi = p_string_ansi.replace("[/b]", "\u001b[22m");
+ p_string_ansi = p_string_ansi.replace("[i]", "\u001b[3m");
+ p_string_ansi = p_string_ansi.replace("[/i]", "\u001b[23m");
+ p_string_ansi = p_string_ansi.replace("[u]", "\u001b[4m");
+ p_string_ansi = p_string_ansi.replace("[/u]", "\u001b[24m");
+ p_string_ansi = p_string_ansi.replace("[s]", "\u001b[9m");
+ p_string_ansi = p_string_ansi.replace("[/s]", "\u001b[29m");
+
+ p_string_ansi = p_string_ansi.replace("[indent]", " ");
+ p_string_ansi = p_string_ansi.replace("[/indent]", "");
+ p_string_ansi = p_string_ansi.replace("[code]", "\u001b[2m");
+ p_string_ansi = p_string_ansi.replace("[/code]", "\u001b[22m");
+ p_string_ansi = p_string_ansi.replace("[url]", "");
+ p_string_ansi = p_string_ansi.replace("[/url]", "");
+ p_string_ansi = p_string_ansi.replace("[center]", "\n\t\t\t");
+ p_string_ansi = p_string_ansi.replace("[/center]", "");
+ p_string_ansi = p_string_ansi.replace("[right]", "\n\t\t\t\t\t\t");
+ p_string_ansi = p_string_ansi.replace("[/right]", "");
+
+ if (p_string_ansi.contains("[color")) {
+ p_string_ansi = p_string_ansi.replace("[color=black]", "\u001b[30m");
+ p_string_ansi = p_string_ansi.replace("[color=red]", "\u001b[91m");
+ p_string_ansi = p_string_ansi.replace("[color=green]", "\u001b[92m");
+ p_string_ansi = p_string_ansi.replace("[color=lime]", "\u001b[92m");
+ p_string_ansi = p_string_ansi.replace("[color=yellow]", "\u001b[93m");
+ p_string_ansi = p_string_ansi.replace("[color=blue]", "\u001b[94m");
+ p_string_ansi = p_string_ansi.replace("[color=magenta]", "\u001b[95m");
+ p_string_ansi = p_string_ansi.replace("[color=pink]", "\u001b[38;5;218m");
+ p_string_ansi = p_string_ansi.replace("[color=purple]", "\u001b[38;5;98m");
+ p_string_ansi = p_string_ansi.replace("[color=cyan]", "\u001b[96m");
+ p_string_ansi = p_string_ansi.replace("[color=white]", "\u001b[97m");
+ p_string_ansi = p_string_ansi.replace("[color=orange]", "\u001b[38;5;208m");
+ p_string_ansi = p_string_ansi.replace("[color=gray]", "\u001b[90m");
+ p_string_ansi = p_string_ansi.replace("[/color]", "\u001b[39m");
+ }
+ if (p_string_ansi.contains("[bgcolor")) {
+ p_string_ansi = p_string_ansi.replace("[bgcolor=black]", "\u001b[40m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=red]", "\u001b[101m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=green]", "\u001b[102m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=lime]", "\u001b[102m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=yellow]", "\u001b[103m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=blue]", "\u001b[104m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=magenta]", "\u001b[105m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=pink]", "\u001b[48;5;218m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=purple]", "\u001b[48;5;98m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=cyan]", "\u001b[106m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=white]", "\u001b[107m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=orange]", "\u001b[48;5;208m");
+ p_string_ansi = p_string_ansi.replace("[bgcolor=gray]", "\u001b[100m");
+ p_string_ansi = p_string_ansi.replace("[/bgcolor]", "\u001b[49m");
+ }
+ if (p_string_ansi.contains("[fgcolor")) {
+ p_string_ansi = p_string_ansi.replace("[fgcolor=black]", "\u001b[30;40m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=red]", "\u001b[91;101m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=green]", "\u001b[92;102m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=lime]", "\u001b[92;102m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=yellow]", "\u001b[93;103m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=blue]", "\u001b[94;104m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=magenta]", "\u001b[95;105m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=pink]", "\u001b[38;5;218;48;5;218m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=purple]", "\u001b[38;5;98;48;5;98m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=cyan]", "\u001b[96;106m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=white]", "\u001b[97;107m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=orange]", "\u001b[38;5;208;48;5;208m");
+ p_string_ansi = p_string_ansi.replace("[fgcolor=gray]", "\u001b[90;100m");
+ p_string_ansi = p_string_ansi.replace("[/fgcolor]", "\u001b[39;49m");
+ }
+
+ OS::get_singleton()->print_rich("%s\n", p_string_ansi.utf8().get_data());
+
+ _global_lock();
+ PrintHandlerList *l = print_handler_list;
+ while (l) {
+ l->printfunc(l->userdata, p_string, false, true);
l = l->next;
}
@@ -96,7 +187,7 @@ void print_error(String p_string) {
_global_lock();
PrintHandlerList *l = print_handler_list;
while (l) {
- l->printfunc(l->userdata, p_string, true);
+ l->printfunc(l->userdata, p_string, true, false);
l = l->next;
}
diff --git a/core/string/print_string.h b/core/string/print_string.h
index f7d0f25030..823e2c29e8 100644
--- a/core/string/print_string.h
+++ b/core/string/print_string.h
@@ -35,7 +35,7 @@
extern void (*_print_func)(String);
-typedef void (*PrintHandlerFunc)(void *, const String &p_string, bool p_error);
+typedef void (*PrintHandlerFunc)(void *, const String &p_string, bool p_error, bool p_rich);
struct PrintHandlerList {
PrintHandlerFunc printfunc = nullptr;
@@ -59,6 +59,7 @@ void remove_print_handler(const PrintHandlerList *p_handler);
extern bool _print_line_enabled;
extern bool _print_error_enabled;
extern void __print_line(String p_string);
+extern void __print_line_rich(String p_string);
extern void print_error(String p_string);
extern void print_verbose(String p_string);
@@ -66,9 +67,18 @@ inline void print_line(Variant v) {
__print_line(stringify_variants(v));
}
+inline void print_line_rich(Variant v) {
+ __print_line_rich(stringify_variants(v));
+}
+
template <typename... Args>
void print_line(Variant p_var, Args... p_args) {
__print_line(stringify_variants(p_var, p_args...));
}
+template <typename... Args>
+void print_line_rich(Variant p_var, Args... p_args) {
+ __print_line_rich(stringify_variants(p_var, p_args...));
+}
+
#endif // PRINT_STRING_H
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index df1aae5370..beefe54faf 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -323,7 +323,13 @@ void String::copy_from(const char *p_cstr) {
char32_t *dst = this->ptrw();
for (size_t i = 0; i <= len; i++) {
- dst[i] = p_cstr[i];
+ uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
+ if (c == 0 && i < len) {
+ print_unicode_error("NUL character", true);
+ dst[i] = 0x20;
+ } else {
+ dst[i] = c;
+ }
}
}
@@ -350,7 +356,13 @@ void String::copy_from(const char *p_cstr, const int p_clip_to) {
char32_t *dst = this->ptrw();
for (int i = 0; i < len; i++) {
- dst[i] = p_cstr[i];
+ uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
+ if (c == 0) {
+ print_unicode_error("NUL character", true);
+ dst[i] = 0x20;
+ } else {
+ dst[i] = c;
+ }
}
dst[len] = 0;
}
@@ -376,14 +388,21 @@ void String::copy_from(const wchar_t *p_cstr, const int p_clip_to) {
}
void String::copy_from(const char32_t &p_char) {
+ if (p_char == 0) {
+ print_unicode_error("NUL character", true);
+ return;
+ }
+ if ((p_char & 0xfffff800) == 0xd800) {
+ print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)p_char));
+ }
+ if (p_char > 0x10ffff) {
+ print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)p_char));
+ }
+
resize(2);
+
char32_t *dst = ptrw();
- if ((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff)) {
- print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(p_char, 16) + ".");
- dst[0] = 0xfffd;
- } else {
- dst[0] = p_char;
- }
+ dst[0] = p_char;
dst[1] = 0;
}
@@ -437,12 +456,18 @@ void String::copy_from_unchecked(const char32_t *p_char, const int p_length) {
dst[p_length] = 0;
for (int i = 0; i < p_length; i++) {
- if ((p_char[i] >= 0xd800 && p_char[i] <= 0xdfff) || (p_char[i] > 0x10ffff)) {
- print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(p_char[i], 16) + ".");
- dst[i] = 0xfffd;
- } else {
- dst[i] = p_char[i];
+ if (p_char[i] == 0) {
+ print_unicode_error("NUL character", true);
+ dst[i] = 0x20;
+ continue;
+ }
+ if ((p_char[i] & 0xfffff800) == 0xd800) {
+ print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)p_char[i]));
}
+ if (p_char[i] > 0x10ffff) {
+ print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)p_char[i]));
+ }
+ dst[i] = p_char[i];
}
}
@@ -481,7 +506,7 @@ String operator+(const wchar_t *p_chr, const String &p_str) {
// wchar_t is 16-bit
String tmp = String::utf16((const char16_t *)p_chr);
#else
- // wchar_t is 32-bi
+ // wchar_t is 32-bit
String tmp = (const char32_t *)p_chr;
#endif
tmp += p_str;
@@ -527,7 +552,13 @@ String &String::operator+=(const char *p_str) {
char32_t *dst = ptrw() + lhs_len;
for (size_t i = 0; i <= rhs_len; i++) {
- dst[i] = p_str[i];
+ uint8_t c = p_str[i] >= 0 ? p_str[i] : uint8_t(256 + p_str[i]);
+ if (c == 0 && i < rhs_len) {
+ print_unicode_error("NUL character", true);
+ dst[i] = 0x20;
+ } else {
+ dst[i] = c;
+ }
}
return *this;
@@ -550,15 +581,21 @@ String &String::operator+=(const char32_t *p_str) {
}
String &String::operator+=(char32_t p_char) {
+ if (p_char == 0) {
+ print_unicode_error("NUL character", true);
+ return *this;
+ }
+ if ((p_char & 0xfffff800) == 0xd800) {
+ print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)p_char));
+ }
+ if (p_char > 0x10ffff) {
+ print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)p_char));
+ }
+
const int lhs_len = length();
resize(lhs_len + 2);
char32_t *dst = ptrw();
- if ((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff)) {
- print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(p_char, 16) + ".");
- dst[lhs_len] = 0xfffd;
- } else {
- dst[lhs_len] = p_char;
- }
+ dst[lhs_len] = p_char;
dst[lhs_len + 1] = 0;
return *this;
@@ -1583,6 +1620,14 @@ String String::hex_encode_buffer(const uint8_t *p_buffer, int p_len) {
return ret;
}
+void String::print_unicode_error(const String &p_message, bool p_critical) const {
+ if (p_critical) {
+ print_error(vformat("Unicode parsing error, some characters were replaced with spaces: %s", p_message));
+ } else {
+ print_error(vformat("Unicode parsing error: %s", p_message));
+ }
+}
+
CharString String::ascii(bool p_allow_extended) const {
if (!length()) {
return CharString();
@@ -1596,7 +1641,7 @@ CharString String::ascii(bool p_allow_extended) const {
if ((c <= 0x7f) || (c <= 0xff && p_allow_extended)) {
cs[i] = c;
} else {
- print_error("Unicode parsing error: Cannot represent " + num_int64(c, 16) + " as ASCII/Latin-1 character.");
+ print_unicode_error(vformat("Invalid unicode codepoint (%x), cannot represent as ASCII/Latin-1", (uint32_t)c));
cs[i] = 0x20;
}
}
@@ -1611,11 +1656,9 @@ String String::utf8(const char *p_utf8, int p_len) {
return ret;
}
-bool String::parse_utf8(const char *p_utf8, int p_len) {
-#define UNICERROR(m_err) print_error("Unicode parsing error: " + String(m_err) + ". Is the string valid UTF-8?");
-
+Error String::parse_utf8(const char *p_utf8, int p_len) {
if (!p_utf8) {
- return true;
+ return ERR_INVALID_DATA;
}
String aux;
@@ -1635,14 +1678,17 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
}
}
+ bool decode_error = false;
+ bool decode_failed = false;
{
const char *ptrtmp = p_utf8;
const char *ptrtmp_limit = &p_utf8[p_len];
int skip = 0;
+ uint8_t c_start = 0;
while (ptrtmp != ptrtmp_limit && *ptrtmp) {
- if (skip == 0) {
- uint8_t c = *ptrtmp >= 0 ? *ptrtmp : uint8_t(256 + *ptrtmp);
+ uint8_t c = *ptrtmp >= 0 ? *ptrtmp : uint8_t(256 + *ptrtmp);
+ if (skip == 0) {
/* Determine the number of characters in sequence */
if ((c & 0x80) == 0) {
skip = 0;
@@ -1652,20 +1698,34 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
skip = 2;
} else if ((c & 0xf8) == 0xf0) {
skip = 3;
+ } else if ((c & 0xfc) == 0xf8) {
+ skip = 4;
+ } else if ((c & 0xfe) == 0xfc) {
+ skip = 5;
} else {
- UNICERROR("invalid skip at " + num_int64(cstr_size));
- return true; //invalid utf8
+ skip = 0;
+ print_unicode_error(vformat("Invalid UTF-8 leading byte (%x)", c), true);
+ decode_failed = true;
}
+ c_start = c;
if (skip == 1 && (c & 0x1e) == 0) {
- UNICERROR("overlong rejected at " + num_int64(cstr_size));
- return true; //reject overlong
+ print_unicode_error(vformat("Overlong encoding (%x ...)", c));
+ decode_error = true;
}
-
str_size++;
-
} else {
- --skip;
+ if ((c_start == 0xe0 && skip == 2 && c < 0xa0) || (c_start == 0xf0 && skip == 3 && c < 0x90) || (c_start == 0xf8 && skip == 4 && c < 0x88) || (c_start == 0xfc && skip == 5 && c < 0x84)) {
+ print_unicode_error(vformat("Overlong encoding (%x %x ...)", c_start, c));
+ decode_error = true;
+ }
+ if (c < 0x80 || c > 0xbf) {
+ print_unicode_error(vformat("Invalid UTF-8 continuation byte (%x ... %x ...)", c_start, c), true);
+ decode_failed = true;
+ skip = 0;
+ } else {
+ --skip;
+ }
}
cstr_size++;
@@ -1673,80 +1733,91 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
}
if (skip) {
- UNICERROR("no space left");
- return true; //not enough space
+ print_unicode_error(vformat("Missing %d UTF-8 continuation byte(s)", skip), true);
+ decode_failed = true;
}
}
if (str_size == 0) {
clear();
- return false;
+ return OK; // empty string
}
resize(str_size + 1);
char32_t *dst = ptrw();
dst[str_size] = 0;
+ int skip = 0;
+ uint32_t unichar = 0;
while (cstr_size) {
- int len = 0;
-
- /* Determine the number of characters in sequence */
- if ((*p_utf8 & 0x80) == 0) {
- len = 1;
- } else if ((*p_utf8 & 0xe0) == 0xc0) {
- len = 2;
- } else if ((*p_utf8 & 0xf0) == 0xe0) {
- len = 3;
- } else if ((*p_utf8 & 0xf8) == 0xf0) {
- len = 4;
- } else {
- UNICERROR("invalid len");
- return true; //invalid UTF8
- }
-
- if (len > cstr_size) {
- UNICERROR("no space left");
- return true; //not enough space
- }
-
- if (len == 2 && (*p_utf8 & 0x1E) == 0) {
- UNICERROR("no space left");
- return true; //reject overlong
- }
-
- /* Convert the first character */
-
- uint32_t unichar = 0;
-
- if (len == 1) {
- unichar = *p_utf8;
+ uint8_t c = *p_utf8 >= 0 ? *p_utf8 : uint8_t(256 + *p_utf8);
+
+ if (skip == 0) {
+ /* Determine the number of characters in sequence */
+ if ((c & 0x80) == 0) {
+ *(dst++) = c;
+ unichar = 0;
+ skip = 0;
+ } else if ((c & 0xe0) == 0xc0) {
+ unichar = (0xff >> 3) & c;
+ skip = 1;
+ } else if ((c & 0xf0) == 0xe0) {
+ unichar = (0xff >> 4) & c;
+ skip = 2;
+ } else if ((c & 0xf8) == 0xf0) {
+ unichar = (0xff >> 5) & c;
+ skip = 3;
+ } else if ((c & 0xfc) == 0xf8) {
+ unichar = (0xff >> 6) & c;
+ skip = 4;
+ } else if ((c & 0xfe) == 0xfc) {
+ unichar = (0xff >> 7) & c;
+ skip = 5;
+ } else {
+ *(dst++) = 0x20;
+ unichar = 0;
+ skip = 0;
+ }
} else {
- unichar = (0xff >> (len + 1)) & *p_utf8;
-
- for (int i = 1; i < len; i++) {
- if ((p_utf8[i] & 0xc0) != 0x80) {
- UNICERROR("invalid utf8");
- return true; //invalid utf8
- }
- if (unichar == 0 && i == 2 && ((p_utf8[i] & 0x7f) >> (7 - len)) == 0) {
- UNICERROR("invalid utf8 overlong");
- return true; //no overlong
+ if (c < 0x80 || c > 0xbf) {
+ *(dst++) = 0x20;
+ skip = 0;
+ } else {
+ unichar = (unichar << 6) | (c & 0x3f);
+ --skip;
+ if (skip == 0) {
+ if (unichar == 0) {
+ print_unicode_error("NUL character", true);
+ decode_failed = true;
+ unichar = 0x20;
+ }
+ if ((unichar & 0xfffff800) == 0xd800) {
+ print_unicode_error(vformat("Unpaired surrogate (%x)", unichar));
+ decode_error = true;
+ }
+ if (unichar > 0x10ffff) {
+ print_unicode_error(vformat("Invalid unicode codepoint (%x)", unichar));
+ decode_error = true;
+ }
+ *(dst++) = unichar;
}
- unichar = (unichar << 6) | (p_utf8[i] & 0x3f);
}
}
- if (unichar >= 0xd800 && unichar <= 0xdfff) {
- UNICERROR("invalid code point");
- return CharString();
- }
- *(dst++) = unichar;
- cstr_size -= len;
- p_utf8 += len;
+ cstr_size--;
+ p_utf8++;
+ }
+ if (skip) {
+ *(dst++) = 0x20;
}
- return false;
-#undef UNICERROR
+ if (decode_failed) {
+ return ERR_INVALID_DATA;
+ } else if (decode_error) {
+ return ERR_PARSE_ERROR;
+ } else {
+ return OK;
+ }
}
CharString String::utf8() const {
@@ -1765,15 +1836,17 @@ CharString String::utf8() const {
fl += 2;
} else if (c <= 0xffff) { // 16 bits
fl += 3;
- } else if (c <= 0x0010ffff) { // 21 bits
+ } else if (c <= 0x001fffff) { // 21 bits
fl += 4;
+ } else if (c <= 0x03ffffff) { // 26 bits
+ fl += 5;
+ print_unicode_error(vformat("Invalid unicode codepoint (%x)", c));
+ } else if (c <= 0x7fffffff) { // 31 bits
+ fl += 6;
+ print_unicode_error(vformat("Invalid unicode codepoint (%x)", c));
} else {
- print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(c, 16) + ".");
- return CharString();
- }
- if (c >= 0xd800 && c <= 0xdfff) {
- print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(c, 16) + ".");
- return CharString();
+ fl += 1;
+ print_unicode_error(vformat("Invalid unicode codepoint (%x), cannot represent as UTF-8", c), true);
}
}
@@ -1799,11 +1872,26 @@ CharString String::utf8() const {
APPEND_CHAR(uint32_t(0xe0 | ((c >> 12) & 0x0f))); // Top 4 bits.
APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Middle 6 bits.
APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
- } else { // 21 bits
+ } else if (c <= 0x001fffff) { // 21 bits
APPEND_CHAR(uint32_t(0xf0 | ((c >> 18) & 0x07))); // Top 3 bits.
APPEND_CHAR(uint32_t(0x80 | ((c >> 12) & 0x3f))); // Upper middle 6 bits.
APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower middle 6 bits.
APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
+ } else if (c <= 0x03ffffff) { // 26 bits
+ APPEND_CHAR(uint32_t(0xf8 | ((c >> 24) & 0x03))); // Top 2 bits.
+ APPEND_CHAR(uint32_t(0x80 | ((c >> 18) & 0x3f))); // Upper middle 6 bits.
+ APPEND_CHAR(uint32_t(0x80 | ((c >> 12) & 0x3f))); // middle 6 bits.
+ APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower middle 6 bits.
+ APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
+ } else if (c <= 0x7fffffff) { // 31 bits
+ APPEND_CHAR(uint32_t(0xfc | ((c >> 30) & 0x01))); // Top 1 bit.
+ APPEND_CHAR(uint32_t(0x80 | ((c >> 24) & 0x3f))); // Upper upper middle 6 bits.
+ APPEND_CHAR(uint32_t(0x80 | ((c >> 18) & 0x3f))); // Lower upper middle 6 bits.
+ APPEND_CHAR(uint32_t(0x80 | ((c >> 12) & 0x3f))); // Upper lower middle 6 bits.
+ APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower lower middle 6 bits.
+ APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
+ } else {
+ APPEND_CHAR(0x20);
}
}
#undef APPEND_CHAR
@@ -1819,11 +1907,9 @@ String String::utf16(const char16_t *p_utf16, int p_len) {
return ret;
}
-bool String::parse_utf16(const char16_t *p_utf16, int p_len) {
-#define UNICERROR(m_err) print_error("Unicode parsing error: " + String(m_err) + ". Is the string valid UTF-16?");
-
+Error String::parse_utf16(const char16_t *p_utf16, int p_len) {
if (!p_utf16) {
- return true;
+ return ERR_INVALID_DATA;
}
String aux;
@@ -1850,80 +1936,90 @@ bool String::parse_utf16(const char16_t *p_utf16, int p_len) {
}
}
+ bool decode_error = false;
{
const char16_t *ptrtmp = p_utf16;
const char16_t *ptrtmp_limit = &p_utf16[p_len];
- int skip = 0;
+ uint32_t c_prev = 0;
+ bool skip = false;
while (ptrtmp != ptrtmp_limit && *ptrtmp) {
uint32_t c = (byteswap) ? BSWAP16(*ptrtmp) : *ptrtmp;
- if (skip == 0) {
- if ((c & 0xfffffc00) == 0xd800) {
- skip = 1; // lead surrogate
- } else if ((c & 0xfffffc00) == 0xdc00) {
- UNICERROR("invalid utf16 surrogate at " + num_int64(cstr_size));
- return true; // invalid UTF16
- } else {
- skip = 0;
+
+ if ((c & 0xfffffc00) == 0xd800) { // lead surrogate
+ if (skip) {
+ print_unicode_error(vformat("Unpaired lead surrogate (%x [trail?] %x)", c_prev, c));
+ decode_error = true;
}
- str_size++;
- } else {
- if ((c & 0xfffffc00) == 0xdc00) { // trail surrogate
- --skip;
+ skip = true;
+ } else if ((c & 0xfffffc00) == 0xdc00) { // trail surrogate
+ if (skip) {
+ str_size--;
} else {
- UNICERROR("invalid utf16 surrogate at " + num_int64(cstr_size));
- return true; // invalid UTF16
+ print_unicode_error(vformat("Unpaired trail surrogate (%x [lead?] %x)", c_prev, c));
+ decode_error = true;
}
+ skip = false;
+ } else {
+ skip = false;
}
+ c_prev = c;
+ str_size++;
cstr_size++;
ptrtmp++;
}
if (skip) {
- UNICERROR("no space left");
- return true; // not enough space
+ print_unicode_error(vformat("Unpaired lead surrogate (%x [eol])", c_prev));
+ decode_error = true;
}
}
if (str_size == 0) {
clear();
- return false;
+ return OK; // empty string
}
resize(str_size + 1);
char32_t *dst = ptrw();
dst[str_size] = 0;
+ bool skip = false;
+ uint32_t c_prev = 0;
while (cstr_size) {
- int len = 0;
uint32_t c = (byteswap) ? BSWAP16(*p_utf16) : *p_utf16;
- if ((c & 0xfffffc00) == 0xd800) {
- len = 2;
+ if ((c & 0xfffffc00) == 0xd800) { // lead surrogate
+ if (skip) {
+ *(dst++) = c_prev; // unpaired, store as is
+ }
+ skip = true;
+ } else if ((c & 0xfffffc00) == 0xdc00) { // trail surrogate
+ if (skip) {
+ *(dst++) = (c_prev << 10UL) + c - ((0xd800 << 10UL) + 0xdc00 - 0x10000); // decode pair
+ } else {
+ *(dst++) = c; // unpaired, store as is
+ }
+ skip = false;
} else {
- len = 1;
+ *(dst++) = c;
+ skip = false;
}
- if (len > cstr_size) {
- UNICERROR("no space left");
- return true; //not enough space
- }
-
- uint32_t unichar = 0;
- if (len == 1) {
- unichar = c;
- } else {
- uint32_t c2 = (byteswap) ? BSWAP16(p_utf16[1]) : p_utf16[1];
- unichar = (c << 10UL) + c2 - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
- }
+ cstr_size--;
+ p_utf16++;
+ c_prev = c;
+ }
- *(dst++) = unichar;
- cstr_size -= len;
- p_utf16 += len;
+ if (skip) {
+ *(dst++) = c_prev;
}
- return false;
-#undef UNICERROR
+ if (decode_error) {
+ return ERR_PARSE_ERROR;
+ } else {
+ return OK;
+ }
}
Char16String String::utf16() const {
@@ -1938,15 +2034,14 @@ Char16String String::utf16() const {
uint32_t c = d[i];
if (c <= 0xffff) { // 16 bits.
fl += 1;
+ if ((c & 0xfffff800) == 0xd800) {
+ print_unicode_error(vformat("Unpaired surrogate (%x)", c));
+ }
} else if (c <= 0x10ffff) { // 32 bits.
fl += 2;
} else {
- print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(c, 16) + ".");
- return Char16String();
- }
- if (c >= 0xd800 && c <= 0xdfff) {
- print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(c, 16) + ".");
- return Char16String();
+ print_unicode_error(vformat("Invalid unicode codepoint (%x), cannot represent as UTF-16", c), true);
+ fl += 1;
}
}
@@ -1965,9 +2060,11 @@ Char16String String::utf16() const {
if (c <= 0xffff) { // 16 bits.
APPEND_CHAR(c);
- } else { // 32 bits.
+ } else if (c <= 0x10ffff) { // 32 bits.
APPEND_CHAR(uint32_t((c >> 10) + 0xd7c0)); // lead surrogate.
APPEND_CHAR(uint32_t((c & 0x3ff) | 0xdc00)); // trail surrogate.
+ } else {
+ APPEND_CHAR(0x20);
}
}
#undef APPEND_CHAR
diff --git a/core/string/ustring.h b/core/string/ustring.h
index 11d0974381..1b8bf3d234 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -271,6 +271,9 @@ public:
bool is_valid_string() const;
+ /* debug, error messages */
+ void print_unicode_error(const String &p_message, bool p_critical = false) const;
+
/* complex helpers */
String substr(int p_from, int p_chars = -1) const;
int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed
@@ -373,11 +376,11 @@ public:
CharString ascii(bool p_allow_extended = false) const;
CharString utf8() const;
- bool parse_utf8(const char *p_utf8, int p_len = -1); //return true on error
+ Error parse_utf8(const char *p_utf8, int p_len = -1);
static String utf8(const char *p_utf8, int p_len = -1);
Char16String utf16() const;
- bool parse_utf16(const char16_t *p_utf16, int p_len = -1); //return true on error
+ Error parse_utf16(const char16_t *p_utf16, int p_len = -1);
static String utf16(const char16_t *p_utf16, int p_len = -1);
static uint32_t hash(const char32_t *p_cstr, int p_len); /* hash the string */
diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h
index f4e0748c27..8d687effcf 100644
--- a/core/templates/local_vector.h
+++ b/core/templates/local_vector.h
@@ -38,7 +38,9 @@
#include <initializer_list>
-template <class T, class U = uint32_t, bool force_trivial = false>
+// If tight, it grows strictly as much as needed.
+// Otherwise, it grows exponentially (the default and what you want in most cases).
+template <class T, class U = uint32_t, bool force_trivial = false, bool tight = false>
class LocalVector {
private:
U count = 0;
@@ -121,7 +123,7 @@ public:
_FORCE_INLINE_ bool is_empty() const { return count == 0; }
_FORCE_INLINE_ U get_capacity() const { return capacity; }
_FORCE_INLINE_ void reserve(U p_size) {
- p_size = nearest_power_of_2_templated(p_size);
+ p_size = tight ? p_size : nearest_power_of_2_templated(p_size);
if (p_size > capacity) {
capacity = p_size;
data = (T *)memrealloc(data, capacity * sizeof(T));
@@ -262,4 +264,7 @@ public:
}
};
+template <class T, class U = uint32_t, bool force_trivial = false>
+using TightLocalVector = LocalVector<T, U, force_trivial, true>;
+
#endif // LOCAL_VECTOR_H
diff --git a/core/templates/lru.h b/core/templates/lru.h
index 48ba318b12..b08b6455b6 100644
--- a/core/templates/lru.h
+++ b/core/templates/lru.h
@@ -35,7 +35,7 @@
#include "hash_map.h"
#include "list.h"
-template <class TKey, class TData>
+template <class TKey, class TData, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<TKey>>
class LRUCache {
private:
struct Pair {
@@ -52,7 +52,7 @@ private:
typedef typename List<Pair>::Element *Element;
List<Pair> _list;
- HashMap<TKey, Element> _map;
+ HashMap<TKey, Element, Hasher, Comparator> _map;
size_t capacity;
public:
@@ -102,6 +102,7 @@ public:
}
_FORCE_INLINE_ size_t get_capacity() const { return capacity; }
+ _FORCE_INLINE_ size_t get_size() const { return _map.size(); }
void set_capacity(size_t p_capacity) {
if (capacity > 0) {
diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h
index 76f76be96a..1f6551762e 100644
--- a/core/templates/safe_refcount.h
+++ b/core/templates/safe_refcount.h
@@ -111,7 +111,8 @@ public:
if (tmp >= p_value) {
return tmp; // already greater, or equal
}
- if (value.compare_exchange_weak(tmp, p_value, std::memory_order_release)) {
+
+ if (value.compare_exchange_weak(tmp, p_value, std::memory_order_acq_rel)) {
return p_value;
}
}
@@ -123,7 +124,7 @@ public:
if (c == 0) {
return 0;
}
- if (value.compare_exchange_weak(c, c + 1, std::memory_order_release)) {
+ if (value.compare_exchange_weak(c, c + 1, std::memory_order_acq_rel)) {
return c + 1;
}
}
diff --git a/core/templates/vector.h b/core/templates/vector.h
index 2ac7c7630a..f3f5ed76a7 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -145,6 +145,9 @@ public:
Vector<uint8_t> to_byte_array() const {
Vector<uint8_t> ret;
+ if (is_empty()) {
+ return ret;
+ }
ret.resize(size() * sizeof(T));
memcpy(ret.ptrw(), ptr(), sizeof(T) * size());
return ret;
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 22a13b0fab..84f894dcbf 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -106,6 +106,29 @@ struct VariantCaster<const T &> {
static void initialize(m_enum &value) { value = (m_enum)0; } \
};
+#define VARIANT_BITFIELD_CAST(m_enum) \
+ MAKE_BITFIELD_TYPE_INFO(m_enum) \
+ template <> \
+ struct VariantCaster<BitField<m_enum>> { \
+ static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
+ return BitField<m_enum>(p_variant.operator int64_t()); \
+ } \
+ }; \
+ template <> \
+ struct PtrToArg<BitField<m_enum>> { \
+ _FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
+ return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
+ } \
+ typedef int64_t EncodeT; \
+ _FORCE_INLINE_ static void encode(BitField<m_enum> p_val, const void *p_ptr) { \
+ *(int64_t *)p_ptr = p_val; \
+ } \
+ }; \
+ template <> \
+ struct ZeroInitializer<BitField<m_enum>> { \
+ static void initialize(BitField<m_enum> &value) { value = 0; } \
+ };
+
// Object enum casts must go here
VARIANT_ENUM_CAST(Object::ConnectFlags);
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index 5453f0d5c6..f20ec4037a 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -437,6 +437,6 @@ bool CallableComparator::operator()(const Variant &p_l, const Variant &p_r) cons
Variant res;
func.call(args, 2, res, err);
ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false,
- "Error calling compare method: " + Variant::get_callable_error_text(func, args, 1, err));
+ "Error calling compare method: " + Variant::get_callable_error_text(func, args, 2, err));
return res;
}
diff --git a/core/variant/type_info.h b/core/variant/type_info.h
index bacd0d19ce..1bd3a74289 100644
--- a/core/variant/type_info.h
+++ b/core/variant/type_info.h
@@ -279,6 +279,52 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
return GetTypeInfo<T>::get_class_info().class_name;
}
+template <class T>
+class BitField {
+ uint32_t value = 0;
+
+public:
+ _FORCE_INLINE_ void set_flag(T p_flag) { value |= p_flag; }
+ _FORCE_INLINE_ bool has_flag(T p_flag) const { return value & p_flag; }
+ _FORCE_INLINE_ void clear_flag(T p_flag) { return value &= ~p_flag; }
+ _FORCE_INLINE_ BitField(uint32_t p_value) { value = p_value; }
+ _FORCE_INLINE_ operator uint32_t() const { return value; }
+ _FORCE_INLINE_ operator Variant() const { return value; }
+};
+
+#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \
+ template <> \
+ struct GetTypeInfo<m_impl> { \
+ static const Variant::Type VARIANT_TYPE = Variant::INT; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
+ godot::details::enum_qualified_name_to_class_info_name(String(#m_enum))); \
+ } \
+ }; \
+ template <> \
+ struct GetTypeInfo<BitField<m_impl>> { \
+ static const Variant::Type VARIANT_TYPE = Variant::INT; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
+ godot::details::enum_qualified_name_to_class_info_name(String(#m_enum))); \
+ } \
+ };
+
+#define MAKE_BITFIELD_TYPE_INFO(m_enum) \
+ TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum) \
+ TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum const) \
+ TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum &) \
+ TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, const m_enum &)
+
+template <typename T>
+inline StringName __constant_get_bitfield_name(T param, const String &p_constant) {
+ if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
+ ERR_PRINT("Missing VARIANT_ENUM_CAST for constant's bitfield: " + p_constant);
+ }
+ return GetTypeInfo<BitField<T>>::get_class_info().class_name;
+}
#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
template <typename T>
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index a4bb7630d6..47943a563f 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -753,40 +753,56 @@ struct _VariantCall {
static PackedInt32Array func_PackedByteArray_decode_s32_array(PackedByteArray *p_instance) {
uint64_t size = p_instance->size();
PackedInt32Array dest;
- ERR_FAIL_COND_V_MSG(size < sizeof(int32_t), dest, "Size didn't match array of size int32_t, maybe you are trying to convert to the wrong type?");
+ if (size == 0) {
+ return dest;
+ }
+ ERR_FAIL_COND_V_MSG(size % sizeof(int32_t), dest, "PackedByteArray size must be a multiple of 4 (size of 32-bit integer) to convert to PackedInt32Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(int32_t));
- memcpy(dest.ptrw(), r, size);
+ ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ memcpy(dest.ptrw(), r, dest.size() * sizeof(int32_t));
return dest;
}
static PackedInt64Array func_PackedByteArray_decode_s64_array(PackedByteArray *p_instance) {
uint64_t size = p_instance->size();
PackedInt64Array dest;
- ERR_FAIL_COND_V_MSG(size < sizeof(int64_t), dest, "Size didn't match array of size int64_t, maybe you are trying to convert to the wrong type?");
+ if (size == 0) {
+ return dest;
+ }
+ ERR_FAIL_COND_V_MSG(size % sizeof(int64_t), dest, "PackedByteArray size must be a multiple of 8 (size of 64-bit integer) to convert to PackedInt64Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(int64_t));
- memcpy(dest.ptrw(), r, size);
+ ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ memcpy(dest.ptrw(), r, dest.size() * sizeof(int64_t));
return dest;
}
static PackedFloat32Array func_PackedByteArray_decode_float_array(PackedByteArray *p_instance) {
uint64_t size = p_instance->size();
PackedFloat32Array dest;
- ERR_FAIL_COND_V_MSG(size < sizeof(float), dest, "Size didn't match array of size float, maybe you are trying to convert to the wrong type?");
+ if (size == 0) {
+ return dest;
+ }
+ ERR_FAIL_COND_V_MSG(size % sizeof(float), dest, "PackedByteArray size must be a multiple of 4 (size of 32-bit float) to convert to PackedFloat32Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(float));
- memcpy(dest.ptrw(), r, size);
+ ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ memcpy(dest.ptrw(), r, dest.size() * sizeof(float));
return dest;
}
static PackedFloat64Array func_PackedByteArray_decode_double_array(PackedByteArray *p_instance) {
uint64_t size = p_instance->size();
PackedFloat64Array dest;
- ERR_FAIL_COND_V_MSG(size < sizeof(double), dest, "Size didn't match array of size double, maybe you are trying to convert to the wrong type?");
+ if (size == 0) {
+ return dest;
+ }
+ ERR_FAIL_COND_V_MSG(size % sizeof(double), dest, "PackedByteArray size must be a multiple of 8 (size of 64-bit double) to convert to PackedFloat64Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(double));
- memcpy(dest.ptrw(), r, size);
+ ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ memcpy(dest.ptrw(), r, dest.size() * sizeof(double));
return dest;
}
@@ -1716,7 +1732,7 @@ static void _register_variant_builtin_methods() {
bind_method(Plane, is_equal_approx, sarray("to_plane"), varray());
bind_method(Plane, is_point_over, sarray("plane"), varray());
bind_method(Plane, distance_to, sarray("point"), varray());
- bind_method(Plane, has_point, sarray("point", "epsilon"), varray(CMP_EPSILON));
+ bind_method(Plane, has_point, sarray("point", "tolerance"), varray(CMP_EPSILON));
bind_method(Plane, project, sarray("point"), varray());
bind_methodv(Plane, intersect_3, &Plane::intersect_3_bind, sarray("b", "c"), varray());
bind_methodv(Plane, intersects_ray, &Plane::intersects_ray_bind, sarray("from", "dir"), varray());
@@ -1790,6 +1806,7 @@ static void _register_variant_builtin_methods() {
bind_method(NodePath, get_subname_count, sarray(), varray());
bind_method(NodePath, hash, sarray(), varray());
bind_method(NodePath, get_subname, sarray("idx"), varray());
+ bind_method(NodePath, get_concatenated_names, sarray(), varray());
bind_method(NodePath, get_concatenated_subnames, sarray(), varray());
bind_method(NodePath, get_as_property_path, sarray(), varray());
bind_method(NodePath, is_empty, sarray(), varray());
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 3696ffae60..e0cfb42e1e 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -304,6 +304,13 @@ public:
v->_get_obj().id = ObjectID();
}
+ static void update_object_id(Variant *v) {
+ const Object *o = v->_get_obj().obj;
+ if (o) {
+ v->_get_obj().id = o->get_instance_id();
+ }
+ }
+
_FORCE_INLINE_ static void *get_opaque_pointer(Variant *v) {
switch (v->type) {
case Variant::NIL:
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index d1b5e285d2..2bca5f8284 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -560,6 +560,22 @@ struct VariantUtilityFunctions {
r_error.error = Callable::CallError::CALL_OK;
}
+ static inline void print_rich(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+ String s;
+ for (int i = 0; i < p_arg_count; i++) {
+ String os = p_args[i]->operator String();
+
+ if (i == 0) {
+ s = os;
+ } else {
+ s += os;
+ }
+ }
+
+ print_line_rich(s);
+ r_error.error = Callable::CallError::CALL_OK;
+ }
+
static inline void print_verbose(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
if (OS::get_singleton()->is_stdout_verbose()) {
String s;
@@ -1306,6 +1322,7 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDVARARGS(str, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDR(error_string, sarray("error"), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDVARARGV(print, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
+ FUNCBINDVARARGV(print_rich, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDVARARGV(printerr, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDVARARGV(printt, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDVARARGV(prints, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
diff --git a/doc/class.xsd b/doc/class.xsd
index 498c930d6f..70c0323464 100644
--- a/doc/class.xsd
+++ b/doc/class.xsd
@@ -155,6 +155,7 @@
<xs:attribute type="xs:string" name="name" />
<xs:attribute type="xs:string" name="value" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
@@ -162,6 +163,42 @@
</xs:sequence>
</xs:complexType>
</xs:element>
+ <xs:element name="annotations" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="annotation" maxOccurs="unbounded" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="return" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:sequence />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="type" />
+ <xs:attribute type="xs:string" name="enum" use="optional" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="argument" maxOccurs="unbounded" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:sequence />
+ </xs:sequence>
+ <xs:attribute type="xs:byte" name="index" />
+ <xs:attribute type="xs:string" name="name" />
+ <xs:attribute type="xs:string" name="type" />
+ <xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:string" name="default" use="optional" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element type="xs:string" name="description" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="name" use="optional" />
+ <xs:attribute type="xs:string" name="qualifiers" use="optional" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
<xs:element name="theme_items" minOccurs="0">
<xs:complexType>
<xs:sequence>
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 1a0253a28b..fbeda641ad 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -657,6 +657,16 @@
[b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed.
</description>
</method>
+ <method name="print_rich" qualifiers="vararg">
+ <description>
+ Converts one or more arguments of any type to string in the best way possible and prints them to the console. The following BBCode tags are supported: b, i, u, s, indent, code, url, center, right, color, bgcolor, fgcolor. Color tags only support named colors such as [code]red[/code], [i]not[/i] hexadecimal color codes. Unsupported tags will be left as-is in standard output.
+ When printing to standard output, the supported subset of BBCode is converted to ANSI escape codes for the terminal emulator to display. Displaying ANSI escape codes is currently only supported on Linux and macOS. Support for ANSI escape codes may vary across terminal emulators, especially for italic and strikethrough.
+ [codeblock]
+ print_rich("[code][b]Hello world![/b][/code]") # Prints out: [b]Hello world![/b]
+ [/codeblock]
+ [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print] or [method print_rich]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed.
+ </description>
+ </method>
<method name="print_verbose" qualifiers="vararg">
<description>
If verbose mode is enabled ([method OS.is_stdout_verbose] returning [code]true[/code]), converts one or more arguments of any type to string in the best way possible and prints them to the console.
@@ -1212,6 +1222,8 @@
<member name="VisualScriptCustomNodes" type="VisualScriptCustomNodes" setter="" getter="">
The [VisualScriptCustomNodes] singleton.
</member>
+ <member name="WorkerThreadPool" type="WorkerThreadPool" setter="" getter="">
+ </member>
<member name="XRServer" type="XRServer" setter="" getter="">
The [XRServer] singleton.
</member>
@@ -2505,72 +2517,66 @@
<constant name="PROPERTY_HINT_EXP_EASING" value="4" enum="PropertyHint">
Hints that a float property should be edited via an exponential easing function. The hint string can include [code]"attenuation"[/code] to flip the curve horizontally and/or [code]"inout"[/code] to also include in/out easing.
</constant>
- <constant name="PROPERTY_HINT_LENGTH" value="5" enum="PropertyHint">
- Deprecated hint, unused.
- </constant>
- <constant name="PROPERTY_HINT_LINK" value="6" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LINK" value="5" enum="PropertyHint">
Hints that a vector property should allow linking values (e.g. to edit both [code]x[/code] and [code]y[/code] together).
</constant>
- <constant name="PROPERTY_HINT_KEY_ACCEL" value="7" enum="PropertyHint">
- Deprecated hint, unused.
- </constant>
- <constant name="PROPERTY_HINT_FLAGS" value="8" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_FLAGS" value="6" enum="PropertyHint">
Hints that an integer property is a bitmask with named bit flags. For example, to allow toggling bits 0, 1, 2 and 4, the hint could be something like [code]"Bit0,Bit1,Bit2,,Bit4"[/code].
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="9" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="7" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D render layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="10" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="8" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D physics layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_NAVIGATION" value="11" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_NAVIGATION" value="9" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D navigation layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="12" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="10" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D render layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="13" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="11" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D physics layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_NAVIGATION" value="14" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_NAVIGATION" value="12" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D navigation layers.
</constant>
- <constant name="PROPERTY_HINT_FILE" value="15" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_FILE" value="13" enum="PropertyHint">
Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_DIR" value="16" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_DIR" value="14" enum="PropertyHint">
Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_FILE" value="17" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_FILE" value="15" enum="PropertyHint">
Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_DIR" value="18" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_DIR" value="16" enum="PropertyHint">
Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="19" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="17" enum="PropertyHint">
Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate.
</constant>
- <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="20" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="18" enum="PropertyHint">
Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed.
</constant>
- <constant name="PROPERTY_HINT_EXPRESSION" value="21" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_EXPRESSION" value="19" enum="PropertyHint">
Hints that a string property is an [Expression].
</constant>
- <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="22" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="20" enum="PropertyHint">
Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use.
</constant>
- <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="23" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="21" enum="PropertyHint">
Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="24" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="22" enum="PropertyHint">
Hints that an image is compressed using lossy compression.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="25" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="23" enum="PropertyHint">
Hints that an image is compressed using lossless compression.
</constant>
- <constant name="PROPERTY_HINT_OBJECT_ID" value="26" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_OBJECT_ID" value="24" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_TYPE_STRING" value="27" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_TYPE_STRING" value="25" enum="PropertyHint">
Hint that a property represents a particular type. If a property is [constant TYPE_STRING], allows to set a type from the create dialog. If you need to create an [Array] to contain elements of a specific type, the [code]hint_string[/code] must encode nested types using [code]":"[/code] and [code]"/"[/code] for specifying [Resource] types. For instance:
[codeblock]
hint_string = "%s:" % [TYPE_INT] # Array of inteters.
@@ -2580,128 +2586,124 @@
[/codeblock]
[b]Note:[/b] The final colon is required to specify for properly detecting built-in types.
</constant>
- <constant name="PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE" value="28" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE" value="26" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_METHOD_OF_VARIANT_TYPE" value="29" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_METHOD_OF_VARIANT_TYPE" value="27" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_METHOD_OF_BASE_TYPE" value="30" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_METHOD_OF_BASE_TYPE" value="28" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_METHOD_OF_INSTANCE" value="31" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_METHOD_OF_INSTANCE" value="29" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_METHOD_OF_SCRIPT" value="32" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_METHOD_OF_SCRIPT" value="30" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE" value="33" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE" value="31" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_PROPERTY_OF_BASE_TYPE" value="34" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_PROPERTY_OF_BASE_TYPE" value="32" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_PROPERTY_OF_INSTANCE" value="35" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_PROPERTY_OF_INSTANCE" value="33" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_PROPERTY_OF_SCRIPT" value="36" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_PROPERTY_OF_SCRIPT" value="34" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_OBJECT_TOO_BIG" value="37" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_OBJECT_TOO_BIG" value="35" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_NODE_PATH_VALID_TYPES" value="38" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_NODE_PATH_VALID_TYPES" value="36" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_SAVE_FILE" value="39" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_SAVE_FILE" value="37" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_SAVE_FILE" value="40" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_SAVE_FILE" value="38" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_INT_IS_OBJECTID" value="41" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_INT_IS_OBJECTID" value="39" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_INT_IS_POINTER" value="43" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_INT_IS_POINTER" value="41" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_ARRAY_TYPE" value="42" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_ARRAY_TYPE" value="40" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_LOCALE_ID" value="44" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LOCALE_ID" value="42" enum="PropertyHint">
Hints that a string property is a locale code. Editing it will show a locale dialog for picking language and country.
</constant>
- <constant name="PROPERTY_HINT_LOCALIZABLE_STRING" value="45" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LOCALIZABLE_STRING" value="43" enum="PropertyHint">
Hints that a dictionary property is string translation map. Dictionary keys are locale codes and, values are translated strings.
</constant>
- <constant name="PROPERTY_HINT_NODE_TYPE" value="46" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_NODE_TYPE" value="44" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_MAX" value="47" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_MAX" value="45" enum="PropertyHint">
</constant>
<constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_STORAGE" value="1" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_STORAGE" value="2" enum="PropertyUsageFlags">
The property is serialized and saved in the scene file (default).
</constant>
- <constant name="PROPERTY_USAGE_EDITOR" value="2" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_EDITOR" value="4" enum="PropertyUsageFlags">
The property is shown in the editor inspector (default).
</constant>
- <constant name="PROPERTY_USAGE_NETWORK" value="4" enum="PropertyUsageFlags">
- Deprecated usage flag, unused.
- </constant>
- <constant name="PROPERTY_USAGE_EDITOR_HELPER" value="8" enum="PropertyUsageFlags">
- Deprecated usage flag, unused.
- </constant>
- <constant name="PROPERTY_USAGE_CHECKABLE" value="16" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_CHECKABLE" value="8" enum="PropertyUsageFlags">
The property can be checked in the editor inspector.
</constant>
- <constant name="PROPERTY_USAGE_CHECKED" value="32" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_CHECKED" value="16" enum="PropertyUsageFlags">
The property is checked in the editor inspector.
</constant>
- <constant name="PROPERTY_USAGE_INTERNATIONALIZED" value="64" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_INTERNATIONALIZED" value="32" enum="PropertyUsageFlags">
The property is a translatable string.
</constant>
- <constant name="PROPERTY_USAGE_GROUP" value="128" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_GROUP" value="64" enum="PropertyUsageFlags">
Used to group properties together in the editor. See [EditorInspector].
</constant>
- <constant name="PROPERTY_USAGE_CATEGORY" value="256" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_CATEGORY" value="128" enum="PropertyUsageFlags">
Used to categorize properties together in the editor.
</constant>
- <constant name="PROPERTY_USAGE_SUBGROUP" value="512" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_SUBGROUP" value="256" enum="PropertyUsageFlags">
Used to group properties together in the editor in a subgroup (under a group). See [EditorInspector].
</constant>
- <constant name="PROPERTY_USAGE_NO_INSTANCE_STATE" value="2048" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_CLASS_IS_BITFIELD" value="512" enum="PropertyUsageFlags">
+ </constant>
+ <constant name="PROPERTY_USAGE_NO_INSTANCE_STATE" value="1024" enum="PropertyUsageFlags">
The property does not save its state in [PackedScene].
</constant>
- <constant name="PROPERTY_USAGE_RESTART_IF_CHANGED" value="4096" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_RESTART_IF_CHANGED" value="2048" enum="PropertyUsageFlags">
Editing the property prompts the user for restarting the editor.
</constant>
- <constant name="PROPERTY_USAGE_SCRIPT_VARIABLE" value="8192" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_SCRIPT_VARIABLE" value="4096" enum="PropertyUsageFlags">
The property is a script variable which should be serialized and saved in the scene file.
</constant>
- <constant name="PROPERTY_USAGE_STORE_IF_NULL" value="16384" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_STORE_IF_NULL" value="8192" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_ANIMATE_AS_TRIGGER" value="32768" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_ANIMATE_AS_TRIGGER" value="16384" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED" value="65536" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED" value="32768" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE" value="131072" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE" value="65536" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_CLASS_IS_ENUM" value="262144" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_CLASS_IS_ENUM" value="131072" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_NIL_IS_VARIANT" value="524288" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_NIL_IS_VARIANT" value="262144" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_INTERNAL" value="1048576" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_INTERNAL" value="524288" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE" value="2097152" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE" value="1048576" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_HIGH_END_GFX" value="4194304" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_HIGH_END_GFX" value="2097152" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT" value="8388608" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT" value="4194304" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT" value="16777216" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT" value="8388608" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_KEYING_INCREMENTS" value="33554432" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_KEYING_INCREMENTS" value="16777216" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_DEFERRED_SET_RESOURCE" value="67108864" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_DEFERRED_SET_RESOURCE" value="33554432" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT" value="134217728" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT" value="67108864" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_EDITOR_BASIC_SETTING" value="268435456" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_EDITOR_BASIC_SETTING" value="134217728" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_ARRAY" value="1073741824" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_ARRAY" value="536870912" enum="PropertyUsageFlags">
</constant>
- <constant name="PROPERTY_USAGE_DEFAULT" value="7" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_DEFAULT" value="6" enum="PropertyUsageFlags">
Default usage (storage, editor and network).
</constant>
- <constant name="PROPERTY_USAGE_DEFAULT_INTL" value="71" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_DEFAULT_INTL" value="38" enum="PropertyUsageFlags">
Default usage for translatable strings (storage, editor, network and internationalized).
</constant>
- <constant name="PROPERTY_USAGE_NO_EDITOR" value="5" enum="PropertyUsageFlags">
+ <constant name="PROPERTY_USAGE_NO_EDITOR" value="2" enum="PropertyUsageFlags">
Default usage but without showing the property in the editor (storage, network).
</constant>
<constant name="METHOD_FLAG_NORMAL" value="1" enum="MethodFlags">
@@ -2710,26 +2712,17 @@
<constant name="METHOD_FLAG_EDITOR" value="2" enum="MethodFlags">
Flag for an editor method.
</constant>
- <constant name="METHOD_FLAG_NOSCRIPT" value="4" enum="MethodFlags">
- Deprecated method flag, unused.
- </constant>
- <constant name="METHOD_FLAG_CONST" value="8" enum="MethodFlags">
+ <constant name="METHOD_FLAG_CONST" value="4" enum="MethodFlags">
Flag for a constant method.
</constant>
- <constant name="METHOD_FLAG_REVERSE" value="16" enum="MethodFlags">
- Deprecated method flag, unused.
- </constant>
- <constant name="METHOD_FLAG_VIRTUAL" value="32" enum="MethodFlags">
+ <constant name="METHOD_FLAG_VIRTUAL" value="8" enum="MethodFlags">
Flag for a virtual method.
</constant>
- <constant name="METHOD_FLAG_FROM_SCRIPT" value="64" enum="MethodFlags">
- Deprecated method flag, unused.
- </constant>
- <constant name="METHOD_FLAG_VARARG" value="128" enum="MethodFlags">
+ <constant name="METHOD_FLAG_VARARG" value="16" enum="MethodFlags">
</constant>
- <constant name="METHOD_FLAG_STATIC" value="256" enum="MethodFlags">
+ <constant name="METHOD_FLAG_STATIC" value="32" enum="MethodFlags">
</constant>
- <constant name="METHOD_FLAG_OBJECT_CORE" value="512" enum="MethodFlags">
+ <constant name="METHOD_FLAG_OBJECT_CORE" value="64" enum="MethodFlags">
Used internally. Allows to not dump core virtuals such as [code]_notification[/code] to the JSON API.
</constant>
<constant name="METHOD_FLAGS_DEFAULT" value="1" enum="MethodFlags">
diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml
index c1e28ffba3..0009c82548 100644
--- a/doc/classes/AcceptDialog.xml
+++ b/doc/classes/AcceptDialog.xml
@@ -62,6 +62,7 @@
Sets autowrapping for the text in the dialog.
</member>
<member name="dialog_close_on_escape" type="bool" setter="set_close_on_escape" getter="get_close_on_escape" default="true">
+ If [code]true[/code], the dialog will be hidden when the escape key ([constant @GlobalScope.KEY_ESCAPE]) is pressed.
</member>
<member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" default="true">
If [code]true[/code], the dialog is hidden when the OK button is pressed. You can set it to [code]false[/code] if you want to do e.g. input validation when receiving the [signal confirmed] signal, and handle hiding the dialog in your own logic.
@@ -71,6 +72,9 @@
The text displayed by the dialog.
</member>
<member name="exclusive" type="bool" setter="set_exclusive" getter="is_exclusive" overrides="Window" default="true" />
+ <member name="ok_button_text" type="String" setter="set_ok_button_text" getter="get_ok_button_text" default="&quot;OK&quot;">
+ The text displayed by the OK button (see [method get_ok_button]).
+ </member>
<member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Alert!&quot;" />
<member name="transient" type="bool" setter="set_transient" getter="is_transient" overrides="Window" default="true" />
<member name="visible" type="bool" setter="set_visible" getter="is_visible" overrides="Window" default="false" />
diff --git a/doc/classes/AnimationNode.xml b/doc/classes/AnimationNode.xml
index 9026aa6a34..189e30b5f2 100644
--- a/doc/classes/AnimationNode.xml
+++ b/doc/classes/AnimationNode.xml
@@ -88,7 +88,7 @@
<argument index="3" name="seek_root" type="bool" />
<argument index="4" name="blend" type="float" />
<argument index="5" name="filter" type="int" enum="AnimationNode.FilterAction" default="0" />
- <argument index="6" name="optimize" type="bool" default="true" />
+ <argument index="6" name="sync" type="bool" default="true" />
<description>
Blend an input. This is only useful for nodes created for an [AnimationNodeBlendTree]. The [code]time[/code] parameter is a relative delta, unless [code]seek[/code] is [code]true[/code], in which case it is absolute. A filter mode may be optionally passed (see [enum FilterAction] for options).
</description>
@@ -102,7 +102,7 @@
<argument index="4" name="seek_root" type="bool" />
<argument index="5" name="blend" type="float" />
<argument index="6" name="filter" type="int" enum="AnimationNode.FilterAction" default="0" />
- <argument index="7" name="optimize" type="bool" default="true" />
+ <argument index="7" name="sync" type="bool" default="true" />
<description>
Blend another animation node (in case this node contains children animation nodes). This function is only useful if you inherit from [AnimationRootNode] instead, else editors will not display your node for addition.
</description>
diff --git a/doc/classes/AnimationNodeAdd2.xml b/doc/classes/AnimationNodeAdd2.xml
index ca117e3ecd..e6ac1dd963 100644
--- a/doc/classes/AnimationNodeAdd2.xml
+++ b/doc/classes/AnimationNodeAdd2.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="AnimationNodeAdd2" inherits="AnimationNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+<class name="AnimationNodeAdd2" inherits="AnimationNodeSync" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Blends two animations additively inside of an [AnimationNodeBlendTree].
</brief_description>
@@ -9,9 +9,4 @@
<tutorials>
<link title="AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
</tutorials>
- <members>
- <member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
- If [code]true[/code], sets the [code]optimization[/code] to [code]false[/code] when calling [method AnimationNode.blend_input], forcing the blended animations to update every frame.
- </member>
- </members>
</class>
diff --git a/doc/classes/AnimationNodeAdd3.xml b/doc/classes/AnimationNodeAdd3.xml
index 91e030a6ae..f290032e11 100644
--- a/doc/classes/AnimationNodeAdd3.xml
+++ b/doc/classes/AnimationNodeAdd3.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="AnimationNodeAdd3" inherits="AnimationNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+<class name="AnimationNodeAdd3" inherits="AnimationNodeSync" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Blends two of three animations additively inside of an [AnimationNodeBlendTree].
</brief_description>
@@ -14,9 +14,4 @@
<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>
- <members>
- <member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
- If [code]true[/code], sets the [code]optimization[/code] to [code]false[/code] when calling [method AnimationNode.blend_input], forcing the blended animations to update every frame.
- </member>
- </members>
</class>
diff --git a/doc/classes/AnimationNodeBlend2.xml b/doc/classes/AnimationNodeBlend2.xml
index f17163e155..5001e3ba24 100644
--- a/doc/classes/AnimationNodeBlend2.xml
+++ b/doc/classes/AnimationNodeBlend2.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="AnimationNodeBlend2" inherits="AnimationNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+<class name="AnimationNodeBlend2" inherits="AnimationNodeSync" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Blends two animations linearly inside of an [AnimationNodeBlendTree].
</brief_description>
@@ -11,9 +11,4 @@
<link title="3D Platformer Demo">https://godotengine.org/asset-library/asset/125</link>
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
</tutorials>
- <members>
- <member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
- If [code]true[/code], sets the [code]optimization[/code] to [code]false[/code] when calling [method AnimationNode.blend_input], forcing the blended animations to update every frame.
- </member>
- </members>
</class>
diff --git a/doc/classes/AnimationNodeBlend3.xml b/doc/classes/AnimationNodeBlend3.xml
index 6bc7a20823..93947c2462 100644
--- a/doc/classes/AnimationNodeBlend3.xml
+++ b/doc/classes/AnimationNodeBlend3.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="AnimationNodeBlend3" inherits="AnimationNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+<class name="AnimationNodeBlend3" inherits="AnimationNodeSync" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Blends two of three animations linearly inside of an [AnimationNodeBlendTree].
</brief_description>
@@ -13,9 +13,4 @@
<tutorials>
<link title="AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
</tutorials>
- <members>
- <member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
- If [code]true[/code], sets the [code]optimization[/code] to [code]false[/code] when calling [method AnimationNode.blend_input], forcing the blended animations to update every frame.
- </member>
- </members>
</class>
diff --git a/doc/classes/AnimationNodeBlendSpace1D.xml b/doc/classes/AnimationNodeBlendSpace1D.xml
index 6ded3a7ff9..7bb136308d 100644
--- a/doc/classes/AnimationNodeBlendSpace1D.xml
+++ b/doc/classes/AnimationNodeBlendSpace1D.xml
@@ -76,6 +76,10 @@
<member name="snap" type="float" setter="set_snap" getter="get_snap" default="0.1">
Position increment to snap to when moving a point on the axis.
</member>
+ <member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
+ If [code]false[/code], the blended animations' frame are stopped when the blend value is [code]0[/code].
+ If [code]true[/code], forcing the blended animations to advance frame.
+ </member>
<member name="value_label" type="String" setter="set_value_label" getter="get_value_label" default="&quot;value&quot;">
Label of the virtual axis of the blend space.
</member>
diff --git a/doc/classes/AnimationNodeBlendSpace2D.xml b/doc/classes/AnimationNodeBlendSpace2D.xml
index 9e0e408ac5..eb2249d2d2 100644
--- a/doc/classes/AnimationNodeBlendSpace2D.xml
+++ b/doc/classes/AnimationNodeBlendSpace2D.xml
@@ -113,6 +113,10 @@
<member name="snap" type="Vector2" setter="set_snap" getter="get_snap" default="Vector2(0.1, 0.1)">
Position increment to snap to when moving a point.
</member>
+ <member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
+ If [code]false[/code], the blended animations' frame are stopped when the blend value is [code]0[/code].
+ If [code]true[/code], forcing the blended animations to advance frame.
+ </member>
<member name="x_label" type="String" setter="set_x_label" getter="get_x_label" default="&quot;x&quot;">
Name of the blend space's X axis.
</member>
diff --git a/doc/classes/AnimationNodeOneShot.xml b/doc/classes/AnimationNodeOneShot.xml
index de2414cd43..14abc34992 100644
--- a/doc/classes/AnimationNodeOneShot.xml
+++ b/doc/classes/AnimationNodeOneShot.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="AnimationNodeOneShot" inherits="AnimationNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+<class name="AnimationNodeOneShot" inherits="AnimationNodeSync" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Plays an animation once in [AnimationNodeBlendTree].
</brief_description>
@@ -26,8 +26,6 @@
</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>
<constants>
<constant name="MIX_MODE_BLEND" value="0" enum="MixMode">
diff --git a/doc/classes/AnimationNodeStateMachineTransition.xml b/doc/classes/AnimationNodeStateMachineTransition.xml
index 94e6a2f23d..0badb831de 100644
--- a/doc/classes/AnimationNodeStateMachineTransition.xml
+++ b/doc/classes/AnimationNodeStateMachineTransition.xml
@@ -19,6 +19,12 @@
[/csharp]
[/codeblocks]
</member>
+ <member name="advance_expression" type="String" setter="set_advance_expression" getter="get_advance_expression" default="&quot;&quot;">
+ Use an expression as a condition for state machine transitions. It is possible to create complex animation advance conditions for switching between states and gives much greater flexibility for creating complex state machines by directly interfacing with the script code.
+ </member>
+ <member name="advance_expression_base_node" type="NodePath" setter="set_advance_expression_base_node" getter="get_advance_expression_base_node" default="NodePath(&quot;&quot;)">
+ The path to the [Node] used to evaluate an [Expression] if one is not explicitly specified internally.
+ </member>
<member name="auto_advance" type="bool" setter="set_auto_advance" getter="has_auto_advance" default="false">
Turn on the transition automatically when this state is reached. This works best with [constant SWITCH_MODE_AT_END].
</member>
diff --git a/doc/classes/AnimationNodeSync.xml b/doc/classes/AnimationNodeSync.xml
new file mode 100644
index 0000000000..21cac11d50
--- /dev/null
+++ b/doc/classes/AnimationNodeSync.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="AnimationNodeSync" inherits="AnimationNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <members>
+ <member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
+ If [code]false[/code], the blended animations' frame are stopped when the blend value is [code]0[/code].
+ If [code]true[/code], forcing the blended animations to advance frame.
+ </member>
+ </members>
+</class>
diff --git a/doc/classes/AnimationNodeTransition.xml b/doc/classes/AnimationNodeTransition.xml
index 70c874d251..7e757d4640 100644
--- a/doc/classes/AnimationNodeTransition.xml
+++ b/doc/classes/AnimationNodeTransition.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="AnimationNodeTransition" inherits="AnimationNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+<class name="AnimationNodeTransition" inherits="AnimationNodeSync" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A generic animation transition node for [AnimationTree].
</brief_description>
@@ -40,6 +40,9 @@
</method>
</methods>
<members>
+ <member name="from_start" type="bool" setter="set_from_start" getter="is_from_start" default="true">
+ If [code]true[/code], the destination animation is played back from the beginning when switched.
+ </member>
<member name="input_count" type="int" setter="set_enabled_inputs" getter="get_enabled_inputs" default="0">
The number of available input ports for this node.
</member>
diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml
index 67e64c6bee..45d9152564 100644
--- a/doc/classes/AnimationTree.xml
+++ b/doc/classes/AnimationTree.xml
@@ -37,6 +37,9 @@
<member name="active" type="bool" setter="set_active" getter="is_active" default="false">
If [code]true[/code], the [AnimationTree] will be processing.
</member>
+ <member name="advance_expression_base_node" type="NodePath" setter="set_advance_expression_base_node" getter="get_advance_expression_base_node" default="NodePath(&quot;.&quot;)">
+ The path to the [Node] used to evaluate the AnimationNode [Expression] if one is not explicitly specified internally.
+ </member>
<member name="anim_player" type="NodePath" setter="set_animation_player" getter="get_animation_player" default="NodePath(&quot;&quot;)">
The path to the [AnimationPlayer] used for animating.
</member>
diff --git a/doc/classes/AudioStreamPlayer.xml b/doc/classes/AudioStreamPlayer.xml
index 26fe1278f7..e0bc98e208 100644
--- a/doc/classes/AudioStreamPlayer.xml
+++ b/doc/classes/AudioStreamPlayer.xml
@@ -55,6 +55,7 @@
</member>
<member name="bus" type="StringName" setter="set_bus" getter="get_bus" default="&amp;&quot;Master&quot;">
Bus on which this audio is playing.
+ [b]Note:[/b] When setting this property, keep in mind that no validation is performed to see if the given name matches an existing bus. This is because audio bus layouts might be loaded after this property is set. If this given name can't be resolved at runtime, it will fall back to [code]"Master"[/code].
</member>
<member name="max_polyphony" type="int" setter="set_max_polyphony" getter="get_max_polyphony" default="1">
The maximum number of sounds this node can play at the same time. Playing additional sounds after this value is reached will cut off the oldest sounds.
diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml
index 76666b1f27..f04f95bd72 100644
--- a/doc/classes/AudioStreamPlayer2D.xml
+++ b/doc/classes/AudioStreamPlayer2D.xml
@@ -57,6 +57,7 @@
</member>
<member name="bus" type="StringName" setter="set_bus" getter="get_bus" default="&amp;&quot;Master&quot;">
Bus on which this audio is playing.
+ [b]Note:[/b] When setting this property, keep in mind that no validation is performed to see if the given name matches an existing bus. This is because audio bus layouts might be loaded after this property is set. If this given name can't be resolved at runtime, it will fall back to [code]"Master"[/code].
</member>
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="2000.0">
Maximum distance from which audio is still hearable.
diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml
index a49b1e2291..72febf7006 100644
--- a/doc/classes/AudioStreamPlayer3D.xml
+++ b/doc/classes/AudioStreamPlayer3D.xml
@@ -64,6 +64,7 @@
</member>
<member name="bus" type="StringName" setter="set_bus" getter="get_bus" default="&amp;&quot;Master&quot;">
The bus on which this audio is playing.
+ [b]Note:[/b] When setting this property, keep in mind that no validation is performed to see if the given name matches an existing bus. This is because audio bus layouts might be loaded after this property is set. If this given name can't be resolved at runtime, it will fall back to [code]"Master"[/code].
</member>
<member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" enum="AudioStreamPlayer3D.DopplerTracking" default="0">
Decides in which step the Doppler effect should be calculated.
diff --git a/doc/classes/BoneMap.xml b/doc/classes/BoneMap.xml
new file mode 100644
index 0000000000..371cb4fa93
--- /dev/null
+++ b/doc/classes/BoneMap.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="BoneMap" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ Bone map for retargeting.
+ </brief_description>
+ <description>
+ This class contains a hashmap that uses a list of bone names in [SkeletonProfile] as key names.
+ By assigning the actual [Skeleton3D] bone name as the key value, it maps the [Skeleton3D] to the [SkeletonProfile].
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="find_profile_bone_name" qualifiers="const">
+ <return type="StringName" />
+ <argument index="0" name="skeleton_bone_name" type="StringName" />
+ <description>
+ Returns a profile bone name having [code]skeleton_bone_name[/code]. If not found, an empty [StringName] will be returned.
+ In the retargeting process, the returned bone name is the bone name of the target skeleton.
+ </description>
+ </method>
+ <method name="get_skeleton_bone_name" qualifiers="const">
+ <return type="StringName" />
+ <argument index="0" name="profile_bone_name" type="StringName" />
+ <description>
+ Returns a skeleton bone name is mapped to [code]profile_bone_name[/code].
+ In the retargeting process, the returned bone name is the bone name of the source skeleton.
+ </description>
+ </method>
+ <method name="set_skeleton_bone_name">
+ <return type="void" />
+ <argument index="0" name="profile_bone_name" type="StringName" />
+ <argument index="1" name="skeleton_bone_name" type="StringName" />
+ <description>
+ Maps a skeleton bone name to [code]profile_bone_name[/code].
+ In the retargeting process, the setting bone name is the bone name of the source skeleton.
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="profile" type="SkeletonProfile" setter="set_profile" getter="get_profile">
+ A [SkeletonProfile] of the mapping target. Key names in the [BoneMap] are synchronized with it.
+ </member>
+ </members>
+ <signals>
+ <signal name="bone_map_updated">
+ <description>
+ This signal is emitted when change the key value in the [BoneMap]. This is used to validate mapping and to update [BoneMap] editor.
+ </description>
+ </signal>
+ <signal name="profile_updated">
+ <description>
+ This signal is emitted when change the value in profile or change the reference of profile. This is used to update key names in the [BoneMap] and to redraw the [BoneMap] editor.
+ </description>
+ </signal>
+ </signals>
+</class>
diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml
index 1e0b685795..1cd9ca0afb 100644
--- a/doc/classes/Button.xml
+++ b/doc/classes/Button.xml
@@ -40,29 +40,6 @@
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link>
<link title="OS Test Demo">https://godotengine.org/asset-library/asset/677</link>
</tutorials>
- <methods>
- <method name="clear_opentype_features">
- <return type="void" />
- <description>
- Removes all OpenType features.
- </description>
- </method>
- <method name="get_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code].
- </description>
- </method>
- <method name="set_opentype_feature">
- <return type="void" />
- <argument index="0" name="tag" type="String" />
- <argument index="1" name="value" type="int" />
- <description>
- Sets OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
- </methods>
<members>
<member name="alignment" type="int" setter="set_text_alignment" getter="get_text_alignment" enum="HorizontalAlignment" default="1">
Text alignment policy for the button's text, use one of the [enum @GlobalScope.HorizontalAlignment] constants.
diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml
index 56e5ce1522..468fddcfc1 100644
--- a/doc/classes/Camera3D.xml
+++ b/doc/classes/Camera3D.xml
@@ -155,6 +155,7 @@
</member>
<member name="current" type="bool" setter="set_current" getter="is_current" default="false">
If [code]true[/code], the ancestor [Viewport] is currently using this camera.
+ If multiple cameras are in the scene, one will always be made current. For example, if two [Camera3D] nodes are present in the scene and only one is current, setting one camera's [member current] to [code]false[/code] will cause the other camera to be made current.
</member>
<member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" enum="Camera3D.DopplerTracking" default="0">
If not [constant DOPPLER_TRACKING_DISABLED], this camera will simulate the [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] for objects changed in particular [code]_process[/code] methods. See [enum DopplerTracking] for possible values.
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index 98a498d719..2d68ae6902 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -48,17 +48,26 @@
</description>
</method>
<method name="draw_char" qualifiers="const">
- <return type="float" />
+ <return type="void" />
+ <argument index="0" name="font" type="Font" />
+ <argument index="1" name="pos" type="Vector2" />
+ <argument index="2" name="char" type="String" />
+ <argument index="3" name="font_size" type="int" default="16" />
+ <argument index="4" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
+ <description>
+ Draws a string first character using a custom font.
+ </description>
+ </method>
+ <method name="draw_char_outline" qualifiers="const">
+ <return type="void" />
<argument index="0" name="font" type="Font" />
<argument index="1" name="pos" type="Vector2" />
<argument index="2" name="char" type="String" />
- <argument index="3" name="next" type="String" default="&quot;&quot;" />
- <argument index="4" name="size" type="int" default="16" />
+ <argument index="3" name="font_size" type="int" default="16" />
+ <argument index="4" name="size" type="int" default="-1" />
<argument index="5" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <argument index="6" name="outline_size" type="int" default="0" />
- <argument index="7" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" />
<description>
- Draws a string character using a custom font. Returns the advance, depending on the character width and kerning with an optional next character.
+ Draws a string first character outline using a custom font.
</description>
</method>
<method name="draw_circle">
@@ -127,7 +136,7 @@
<argument index="4" name="outline" type="float" default="0.0" />
<argument index="5" name="pixel_range" type="float" default="4.0" />
<description>
- Draws a textured rectangle region of the multi-channel signed distance field texture at a given position, optionally modulated by a color. See [member FontData.multichannel_signed_distance_field] for more information and caveats about MSDF font rendering.
+ Draws a textured rectangle region of the multi-channel signed distance field texture at a given position, optionally modulated by a color. See [member FontFile.multichannel_signed_distance_field] for more information and caveats about MSDF font rendering.
If [code]outline[/code] is positive, each alpha channel value of pixel in region is set to maximum value of true distance in the [code]outline[/code] radius.
Value of the [code]pixel_range[/code] should the same that was used during distance field texture generation.
</description>
@@ -157,16 +166,36 @@
<argument index="2" name="text" type="String" />
<argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<argument index="4" name="width" type="float" default="-1" />
- <argument index="5" name="max_lines" type="int" default="-1" />
- <argument index="6" name="size" type="int" default="16" />
+ <argument index="5" name="font_size" type="int" default="16" />
+ <argument index="6" name="max_lines" type="int" default="-1" />
<argument index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <argument index="8" name="outline_size" type="int" default="0" />
- <argument index="9" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" />
- <argument index="10" name="flags" type="int" default="99" />
+ <argument index="8" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
+ <argument index="9" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="10" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="11" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
Breaks [code]text[/code] to the lines and draws it using the specified [code]font[/code] at the [code]position[/code] (top-left corner). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
</description>
</method>
+ <method name="draw_multiline_string_outline" qualifiers="const">
+ <return type="void" />
+ <argument index="0" name="font" type="Font" />
+ <argument index="1" name="pos" type="Vector2" />
+ <argument index="2" name="text" type="String" />
+ <argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
+ <argument index="4" name="width" type="float" default="-1" />
+ <argument index="5" name="font_size" type="int" default="16" />
+ <argument index="6" name="max_lines" type="int" default="-1" />
+ <argument index="7" name="size" type="int" default="1" />
+ <argument index="8" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
+ <argument index="9" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
+ <argument index="10" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="11" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="12" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
+ <description>
+ Breaks [code]text[/code] to the lines and draws text outline using the specified [code]font[/code] at the [code]position[/code] (top-left corner). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
+ </description>
+ </method>
<method name="draw_multimesh">
<return type="void" />
<argument index="0" name="multimesh" type="MultiMesh" />
@@ -250,11 +279,11 @@
<argument index="2" name="text" type="String" />
<argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<argument index="4" name="width" type="float" default="-1" />
- <argument index="5" name="size" type="int" default="16" />
+ <argument index="5" name="font_size" type="int" default="16" />
<argument index="6" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <argument index="7" name="outline_size" type="int" default="0" />
- <argument index="8" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" />
- <argument index="9" name="flags" type="int" default="3" />
+ <argument index="7" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="8" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="9" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
Draws [code]text[/code] using the specified [code]font[/code] at the [code]position[/code] (bottom-left corner using the baseline of the font). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
[b]Example using the default project font:[/b]
@@ -279,6 +308,23 @@
See also [method Font.draw_string].
</description>
</method>
+ <method name="draw_string_outline" qualifiers="const">
+ <return type="void" />
+ <argument index="0" name="font" type="Font" />
+ <argument index="1" name="pos" type="Vector2" />
+ <argument index="2" name="text" type="String" />
+ <argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
+ <argument index="4" name="width" type="float" default="-1" />
+ <argument index="5" name="font_size" type="int" default="16" />
+ <argument index="6" name="size" type="int" default="1" />
+ <argument index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
+ <argument index="8" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="9" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="10" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
+ <description>
+ Draws [code]text[/code] outline using the specified [code]font[/code] at the [code]position[/code] (bottom-left corner using the baseline of the font). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
+ </description>
+ </method>
<method name="draw_style_box">
<return type="void" />
<argument index="0" name="style_box" type="StyleBox" />
diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml
index 7ca27a35fe..4994ef352e 100644
--- a/doc/classes/CodeEdit.xml
+++ b/doc/classes/CodeEdit.xml
@@ -592,6 +592,9 @@
<theme_item name="completion_scroll_color" data_type="color" type="Color" default="Color(1, 1, 1, 0.29)">
[Color] of the scrollbar in the code completion popup.
</theme_item>
+ <theme_item name="completion_scroll_hovered_color" data_type="color" type="Color" default="Color(1, 1, 1, 0.4)">
+ [Color] of the scrollbar in the code completion popup when hovered.
+ </theme_item>
<theme_item name="completion_selected_color" data_type="color" type="Color" default="Color(0.26, 0.26, 0.27, 1)">
Background highlight [Color] for the current selected option item in the code completion popup.
</theme_item>
diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml
index 7c9c4ed4d6..cc9c5877c5 100644
--- a/doc/classes/ColorPicker.xml
+++ b/doc/classes/ColorPicker.xml
@@ -37,16 +37,15 @@
<member name="color" type="Color" setter="set_pick_color" getter="get_pick_color" default="Color(1, 1, 1, 1)">
The currently selected color.
</member>
+ <member name="color_mode" type="int" setter="set_color_mode" getter="get_color_mode" enum="ColorPicker.ColorModeType" default="0">
+ The currently selected color mode. See [enum ColorModeType].
+ </member>
<member name="deferred_mode" type="bool" setter="set_deferred_mode" getter="is_deferred_mode" default="false">
If [code]true[/code], the color will apply only after the user releases the mouse button, otherwise it will apply immediately even in mouse motion event (which can cause performance issues).
</member>
<member name="edit_alpha" type="bool" setter="set_edit_alpha" getter="is_editing_alpha" default="true">
If [code]true[/code], shows an alpha channel slider (opacity).
</member>
- <member name="hsv_mode" type="bool" setter="set_hsv_mode" getter="is_hsv_mode" default="false">
- If [code]true[/code], allows editing the color with Hue/Saturation/Value sliders.
- [b]Note:[/b] Cannot be enabled if raw mode is on.
- </member>
<member name="picker_shape" type="int" setter="set_picker_shape" getter="get_picker_shape" enum="ColorPicker.PickerShapeType" default="0">
The shape of the color space view. See [enum PickerShapeType].
</member>
@@ -56,10 +55,6 @@
<member name="presets_visible" type="bool" setter="set_presets_visible" getter="are_presets_visible" default="true">
If [code]true[/code], saved color presets are visible.
</member>
- <member name="raw_mode" type="bool" setter="set_raw_mode" getter="is_raw_mode" default="false">
- If [code]true[/code], allows the color R, G, B component values to go beyond 1.0, which can be used for certain special operations that require it (like tinting without darkening or rendering sprites in HDR).
- [b]Note:[/b] Cannot be enabled if HSV mode is on.
- </member>
</members>
<signals>
<signal name="color_changed">
@@ -82,6 +77,20 @@
</signal>
</signals>
<constants>
+ <constant name="MODE_RGB" value="0" enum="ColorModeType">
+ Allows editing the color with Red/Green/Blue sliders.
+ </constant>
+ <constant name="MODE_HSV" value="1" enum="ColorModeType">
+ Allows editing the color with Hue/Saturation/Value sliders.
+ </constant>
+ <constant name="MODE_RAW" value="2" enum="ColorModeType">
+ Allows the color R, G, B component values to go beyond 1.0, which can be used for certain special operations that require it (like tinting without darkening or rendering sprites in HDR).
+ </constant>
+ <constant name="MODE_OKHSL" value="3" enum="ColorModeType">
+ Allows editing the color with Hue/Saturation/Lightness sliders.
+ OKHSL is a new color space similar to HSL but that better match perception by leveraging the Oklab color space which is designed to be simple to use, while doing a good job at predicting perceived lightness, chroma and hue.
+ [url=https://bottosson.github.io/posts/colorpicker/]Okhsv and Okhsl color spaces[/url]
+ </constant>
<constant name="SHAPE_HSV_RECTANGLE" value="0" enum="PickerShapeType">
HSV Color Model rectangle color space.
</constant>
diff --git a/doc/classes/ConfirmationDialog.xml b/doc/classes/ConfirmationDialog.xml
index 2316e32b5d..d4c503857d 100644
--- a/doc/classes/ConfirmationDialog.xml
+++ b/doc/classes/ConfirmationDialog.xml
@@ -27,6 +27,9 @@
</method>
</methods>
<members>
+ <member name="cancel_button_text" type="String" setter="set_cancel_button_text" getter="get_cancel_button_text" default="&quot;Cancel&quot;">
+ The text displayed by the cancel button (see [method get_cancel_button]).
+ </member>
<member name="min_size" type="Vector2i" setter="set_min_size" getter="get_min_size" overrides="Window" default="Vector2i(200, 70)" />
<member name="size" type="Vector2i" setter="set_size" getter="get_size" overrides="Window" default="Vector2i(200, 100)" />
<member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Please Confirm...&quot;" />
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 2846b564b4..9fc80e1aab 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -1281,8 +1281,8 @@
<constant name="PRESET_HCENTER_WIDE" value="14" enum="LayoutPreset">
Snap all 4 anchors to a horizontal line that cuts the parent control in half. Use with [method set_anchors_preset].
</constant>
- <constant name="PRESET_WIDE" value="15" enum="LayoutPreset">
- Snap all 4 anchors to the respective corners of the parent control. Set all 4 offsets to 0 after you applied this preset and the [Control] will fit its parent control. This is equivalent to the "Full Rect" layout option in the editor. Use with [method set_anchors_preset].
+ <constant name="PRESET_FULL_RECT" value="15" enum="LayoutPreset">
+ Snap all 4 anchors to the respective corners of the parent control. Set all 4 offsets to 0 after you applied this preset and the [Control] will fit its parent control. Use with [method set_anchors_preset].
</constant>
<constant name="PRESET_MODE_MINSIZE" value="0" enum="LayoutPresetMode">
The control will be resized to its minimum size.
diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml
index c0ad61b77e..861b4b480c 100644
--- a/doc/classes/Decal.xml
+++ b/doc/classes/Decal.xml
@@ -79,7 +79,7 @@
Sets the size of the [AABB] used by the decal. The AABB goes from [code]-extents[/code] to [code]extents[/code].
</member>
<member name="lower_fade" type="float" setter="set_lower_fade" getter="get_lower_fade" default="0.3">
- Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB].
+ Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB]. Only positive values are valid (negative values will be clamped to [code]0.0[/code]).
</member>
<member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" default="Color(1, 1, 1, 1)">
Changes the [Color] of the Decal by multiplying it with this value.
@@ -89,18 +89,22 @@
</member>
<member name="texture_albedo" type="Texture2D" setter="set_texture" getter="get_texture">
[Texture2D] with the base [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object.
+ [b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for [Decal] textures is set globally with [member ProjectSettings.rendering/textures/decals/filter].
</member>
<member name="texture_emission" type="Texture2D" setter="set_texture" getter="get_texture">
[Texture2D] with the emission [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object.
+ [b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for [Decal] textures is set globally with [member ProjectSettings.rendering/textures/decals/filter].
</member>
<member name="texture_normal" type="Texture2D" setter="set_texture" getter="get_texture">
[Texture2D] with the per-pixel normal map for the decal. Use this to add extra detail to decals.
+ [b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for [Decal] textures is set globally with [member ProjectSettings.rendering/textures/decals/filter].
</member>
<member name="texture_orm" type="Texture2D" setter="set_texture" getter="get_texture">
[Texture2D] storing ambient occlusion, roughness, and metallic for the decal. Use this to add extra detail to decals.
+ [b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for [Decal] textures is set globally with [member ProjectSettings.rendering/textures/decals/filter].
</member>
<member name="upper_fade" type="float" setter="set_upper_fade" getter="get_upper_fade" default="0.3">
- Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB].
+ Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB]. Only positive values are valid (negative values will be clamped to [code]0.0[/code]).
</member>
</members>
<constants>
diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml
index 8aa2db2cf8..f217fbaf48 100644
--- a/doc/classes/EditorExportPlugin.xml
+++ b/doc/classes/EditorExportPlugin.xml
@@ -96,7 +96,7 @@
Adds a static lib from the given [code]path[/code] to the iOS project.
</description>
</method>
- <method name="add_osx_plugin_file">
+ <method name="add_macos_plugin_file">
<return type="void" />
<argument index="0" name="path" type="String" />
<description>
diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml
index b1fd7b4e76..6fd5abe369 100644
--- a/doc/classes/EditorFileDialog.xml
+++ b/doc/classes/EditorFileDialog.xml
@@ -11,9 +11,11 @@
<method name="add_filter">
<return type="void" />
<argument index="0" name="filter" type="String" />
+ <argument index="1" name="description" type="String" default="&quot;&quot;" />
<description>
- Adds a comma-delimited file extension filter option to the [EditorFileDialog] with an optional semi-colon-delimited label.
- For example, [code]"*.tscn, *.scn; Scenes"[/code] results in filter text "Scenes (*.tscn, *.scn)".
+ Adds a comma-delimited file name [code]filter[/code] option to the [EditorFileDialog] with an optional [code]description[/code], which restricts what files can be picked.
+ A [code]filter[/code] should be of the form [code]"filename.extension"[/code], where filename and extension can be [code]*[/code] to match any string. Filters starting with [code].[/code] (i.e. empty filenames) are not allowed.
+ For example, a [code]filter[/code] of [code]"*.tscn, *.scn"[/code] and a [code]description[/code] of [code]"Scenes"[/code] results in filter text "Scenes (*.tscn, *.scn)".
</description>
</method>
<method name="clear_filters">
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index 1514b82ff8..2930c2ec22 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -296,6 +296,28 @@
<return type="bool" />
<description>
Returns [code]true[/code] if this is a main screen editor plugin (it goes in the workspace selector together with [b]2D[/b], [b]3D[/b], [b]Script[/b] and [b]AssetLib[/b]).
+ When the plugin's workspace is selected, other main screen plugins will be hidden, but your plugin will not appear automatically. It needs to be added as a child of [method EditorInterface.get_base_control] and made visible inside [method _make_visible].
+ Use [method _get_plugin_name] and [method _get_plugin_icon] to customize the plugin button's appearance.
+ [codeblock]
+ var plugin_control
+
+ func _enter_tree():
+ plugin_control = preload("my_plugin_control.tscn").instantiate()
+ get_editor_interface().get_editor_main_control().add_child(plugin_control)
+ plugin_control.hide()
+
+ func _has_main_screen():
+ return true
+
+ func _make_visible(visible):
+ plugin_control.visible = visible
+
+ func _get_plugin_name():
+ return "My Super Cool Plugin 3000"
+
+ func _get_plugin_icon():
+ return get_editor_interface().get_base_control().get_theme_icon("Node", "EditorIcons")
+ [/codeblock]
</description>
</method>
<method name="_make_visible" qualifiers="virtual">
diff --git a/doc/classes/EditorScenePostImportPlugin.xml b/doc/classes/EditorScenePostImportPlugin.xml
index 0fdbd5db1e..44d644411d 100644
--- a/doc/classes/EditorScenePostImportPlugin.xml
+++ b/doc/classes/EditorScenePostImportPlugin.xml
@@ -88,7 +88,7 @@
<argument index="2" name="default_value" type="Variant" />
<argument index="3" name="hint" type="int" enum="PropertyHint" default="0" />
<argument index="4" name="hint_string" type="String" default="&quot;&quot;" />
- <argument index="5" name="usage_flags" type="int" default="7" />
+ <argument index="5" name="usage_flags" type="int" default="6" />
<description>
Add a specific import option. This function can only be called from [method _get_import_options] and [method _get_internal_import_options].
</description>
@@ -114,7 +114,9 @@
</constant>
<constant name="INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE" value="5" enum="InternalImportCategory">
</constant>
- <constant name="INTERNAL_IMPORT_CATEGORY_MAX" value="6" enum="InternalImportCategory">
+ <constant name="INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE" value="6" enum="InternalImportCategory">
+ </constant>
+ <constant name="INTERNAL_IMPORT_CATEGORY_MAX" value="7" enum="InternalImportCategory">
</constant>
</constants>
</class>
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index 9d55704604..f45031cea8 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -12,10 +12,11 @@
<method name="add_filter">
<return type="void" />
<argument index="0" name="filter" type="String" />
+ <argument index="1" name="description" type="String" default="&quot;&quot;" />
<description>
- Adds [code]filter[/code] to the list of filters, which restricts what files can be picked.
- A [code]filter[/code] should be of the form [code]"filename.extension ; Description"[/code], where filename and extension can be [code]*[/code] to match any string. Filters starting with [code].[/code] (i.e. empty filenames) are not allowed.
- Example filters: [code]"*.png ; PNG Images"[/code], [code]"project.godot ; Godot Project"[/code].
+ Adds a comma-delimited file name [code]filter[/code] option to the [FileDialog] with an optional [code]description[/code], which restricts what files can be picked.
+ A [code]filter[/code] should be of the form [code]"filename.extension"[/code], where filename and extension can be [code]*[/code] to match any string. Filters starting with [code].[/code] (i.e. empty filenames) are not allowed.
+ For example, a [code]filter[/code] of [code]"*.png, *.jpg"[/code] and a [code]description[/code] of [code]"Images"[/code] results in filter text "Images (*.png, *.jpg)".
</description>
</method>
<method name="clear_filters">
@@ -75,6 +76,9 @@
<member name="mode_overrides_title" type="bool" setter="set_mode_overrides_title" getter="is_mode_overriding_title" default="true">
If [code]true[/code], changing the [code]Mode[/code] property will set the window title accordingly (e.g. setting mode to [constant FILE_MODE_OPEN_FILE] will change the window title to "Open a File").
</member>
+ <member name="root_subfolder" type="String" setter="set_root_subfolder" getter="get_root_subfolder" default="&quot;&quot;">
+ If non-empty, the given sub-folder will be "root" of this [FileDialog], i.e. user won't be able to go to its parent directory.
+ </member>
<member name="show_hidden_files" type="bool" setter="set_show_hidden_files" getter="is_showing_hidden_files" default="false">
If [code]true[/code], the dialog will show hidden files.
</member>
diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml
index dae42ddf34..6377c829e1 100644
--- a/doc/classes/Font.xml
+++ b/doc/classes/Font.xml
@@ -1,93 +1,36 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Font" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Font class is set of font data sources used to draw text.
+ Base class for fonts and font variations.
</brief_description>
<description>
- Font contains a set of glyphs to represent Unicode characters, as well as the ability to draw it with variable width, ascent, descent and kerning.
- [b]Note:[/b] A character is a symbol that represents an item (letter, digit etc.) in an abstract way.
- [b]Note:[/b] A glyph is a bitmap or shape used to draw a one or more characters in a context-dependent manner. Glyph indices are bound to the specific font data source.
- [b]Note:[/b] If a non of the font data sources contain glyphs for a character used in a string, the character in question will be replaced with a box displaying its hexadecimal code.
- [codeblocks]
- [gdscript]
- var font = Font.new()
- font.add_data(load("res://BarlowCondensed-Bold.ttf"))
- $"Label".set("custom_fonts/font", font)
- $"Label".set("custom_fonts/font_size", 64)
- [/gdscript]
- [csharp]
- var font = new Font();
- font.AddData(ResourceLoader.Load&lt;FontData&gt;("res://BarlowCondensed-Bold.ttf"));
- GetNode("Label").Set("custom_fonts/font", font);
- GetNode("Label").Set("custom_font_sizes/font_size", 64);
- [/csharp]
- [/codeblocks]
- To control font substitution priority use [FontData] language and script support.
- Use language overrides to use same [Font] stack for multiple languages:
- [codeblocks]
- [gdscript]
- # Use Naskh font for Persian and Nastaʼlīq font for Urdu text.
- var font_data_fa = load("res://NotoNaskhArabicUI_Regular.ttf");
- font_data_fa.set_language_support_override("fa", true);
- font_data_fa.set_language_support_override("ur", false);
-
- var font_data_ur = load("res://NotoNastaliqUrdu_Regular.ttf");
- font_data_ur.set_language_support_override("fa", false);
- font_data_ur.set_language_support_override("ur", true);
- [/gdscript]
- [csharp]
- // Use Naskh font for Persian and Nastaʼlīq font for Urdu text.
- var fontDataFA = ResourceLoader.Load&lt;FontData&gt;("res://NotoNaskhArabicUI_Regular.ttf");
- fontDataFA.SetLanguageSupportOverride("fa", true);
- fontDataFA.SetLanguageSupportOverride("ur", false);
-
- var fontDataUR = ResourceLoader.Load&lt;FontData&gt;("res://NotoNastaliqUrdu_Regular.ttf");
- fontDataUR.SetLanguageSupportOverride("fa", false);
- fontDataUR.SetLanguageSupportOverride("ur", true);
- [/csharp]
- [/codeblocks]
- Use script overrides to specify supported scripts for bitmap font or for less common scripts not directly supported by TrueType format:
- [codeblocks]
- [gdscript]
- # Use specified font for Egyptian hieroglyphs.
- var font_data = load("res://unifont.ttf");
- font_data.set_script_support_override("Egyp", true);
- [/gdscript]
- [csharp]
- // Use specified font for Egyptian hieroglyphs.
- var fontData = ResourceLoader.Load&lt;FontData&gt;("res://unifont.ttf");
- fontData.SetScriptSupportOverride("Egyp", true);
- [/csharp]
- [/codeblocks]
+ Font is the abstract base class for font, so it shouldn't be used directly. Other types of fonts inherit from it.
</description>
<tutorials>
</tutorials>
<methods>
- <method name="add_data">
- <return type="void" />
- <argument index="0" name="data" type="FontData" />
- <description>
- Add font data source to the set.
- </description>
- </method>
- <method name="clear_data">
- <return type="void" />
+ <method name="draw_char" qualifiers="const">
+ <return type="float" />
+ <argument index="0" name="canvas_item" type="RID" />
+ <argument index="1" name="pos" type="Vector2" />
+ <argument index="2" name="char" type="int" />
+ <argument index="3" name="modulate" type="int" />
+ <argument index="4" name="arg4" type="Color" default="Color(1, 1, 1, 1)" />
<description>
- Removes all font data sourcers for the set.
+ Draw a single Unicode character [code]char[/code] into a canvas item using the font, at a given position, with [code]modulate[/code] color. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
+ [b]Note:[/b] Do not use this function to draw strings character by character, use [method draw_string] or [TextLine] instead.
</description>
</method>
- <method name="draw_char" qualifiers="const">
+ <method name="draw_char_outline" qualifiers="const">
<return type="float" />
<argument index="0" name="canvas_item" type="RID" />
<argument index="1" name="pos" type="Vector2" />
<argument index="2" name="char" type="int" />
- <argument index="3" name="next" type="int" default="0" />
- <argument index="4" name="size" type="int" default="16" />
- <argument index="5" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <argument index="6" name="outline_size" type="int" default="0" />
- <argument index="7" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" />
+ <argument index="3" name="size" type="int" />
+ <argument index="4" name="modulate" type="int" default="-1" />
+ <argument index="5" name="arg5" type="Color" default="Color(1, 1, 1, 1)" />
<description>
- Draw a single Unicode character [code]char[/code] into a canvas item using the font, at a given position, with [code]modulate[/code] color, and optionally kerning if [code]next[/code] is passed. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
+ Draw a single Unicode character [code]char[/code] outline into a canvas item using the font, at a given position, with [code]modulate[/code] color and [code]size[/code] outline size. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
[b]Note:[/b] Do not use this function to draw strings character by character, use [method draw_string] or [TextLine] instead.
</description>
</method>
@@ -98,17 +41,38 @@
<argument index="2" name="text" type="String" />
<argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<argument index="4" name="width" type="float" default="-1" />
- <argument index="5" name="max_lines" type="int" default="-1" />
- <argument index="6" name="size" type="int" default="16" />
+ <argument index="5" name="font_size" type="int" default="16" />
+ <argument index="6" name="max_lines" type="int" default="-1" />
<argument index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <argument index="8" name="outline_size" type="int" default="0" />
- <argument index="9" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" />
- <argument index="10" name="flags" type="int" default="99" />
+ <argument index="8" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
+ <argument index="9" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="10" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="11" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
Breaks [code]text[/code] to the lines using rules specified by [code]flags[/code] and draws it into a canvas item using the font, at a given position, with [code]modulate[/code] color, optionally clipping the width and aligning horizontally. [code]position[/code] specifies the baseline of the first line, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
See also [method CanvasItem.draw_multiline_string].
</description>
</method>
+ <method name="draw_multiline_string_outline" qualifiers="const">
+ <return type="void" />
+ <argument index="0" name="canvas_item" type="RID" />
+ <argument index="1" name="pos" type="Vector2" />
+ <argument index="2" name="text" type="String" />
+ <argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
+ <argument index="4" name="width" type="float" default="-1" />
+ <argument index="5" name="font_size" type="int" default="16" />
+ <argument index="6" name="max_lines" type="int" default="-1" />
+ <argument index="7" name="size" type="int" default="1" />
+ <argument index="8" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
+ <argument index="9" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
+ <argument index="10" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="11" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="12" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
+ <description>
+ Breaks [code]text[/code] to the lines using rules specified by [code]flags[/code] and draws text outline into a canvas item using the font, at a given position, with [code]modulate[/code] color and [code]size[/code] outline size, optionally clipping the width and aligning horizontally. [code]position[/code] specifies the baseline of the first line, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
+ See also [method CanvasItem.draw_multiline_string_outline].
+ </description>
+ </method>
<method name="draw_string" qualifiers="const">
<return type="void" />
<argument index="0" name="canvas_item" type="RID" />
@@ -116,19 +80,47 @@
<argument index="2" name="text" type="String" />
<argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<argument index="4" name="width" type="float" default="-1" />
- <argument index="5" name="size" type="int" default="16" />
+ <argument index="5" name="font_size" type="int" default="16" />
<argument index="6" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <argument index="7" name="outline_size" type="int" default="0" />
- <argument index="8" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" />
- <argument index="9" name="flags" type="int" default="3" />
+ <argument index="7" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="8" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="9" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
Draw [code]text[/code] into a canvas item using the font, at a given position, with [code]modulate[/code] color, optionally clipping the width and aligning horizontally. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
See also [method CanvasItem.draw_string].
</description>
</method>
+ <method name="draw_string_outline" qualifiers="const">
+ <return type="void" />
+ <argument index="0" name="canvas_item" type="RID" />
+ <argument index="1" name="pos" type="Vector2" />
+ <argument index="2" name="text" type="String" />
+ <argument index="3" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
+ <argument index="4" name="width" type="float" default="-1" />
+ <argument index="5" name="font_size" type="int" default="16" />
+ <argument index="6" name="size" type="int" default="1" />
+ <argument index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
+ <argument index="8" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="9" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="10" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
+ <description>
+ Draw [code]text[/code] outline into a canvas item using the font, at a given position, with [code]modulate[/code] color and [code]size[/code] outline size, optionally clipping the width and aligning horizontally. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
+ See also [method CanvasItem.draw_string_outline].
+ </description>
+ </method>
+ <method name="find_variation" qualifiers="const">
+ <return type="RID" />
+ <argument index="0" name="variation_coordinates" type="Dictionary" />
+ <argument index="1" name="face_index" type="int" default="0" />
+ <argument index="2" name="strength" type="float" default="0.0" />
+ <argument index="3" name="transform" type="Transform2D" default="Transform2D(1, 0, 0, 1, 0, 0)" />
+ <description>
+ Returns [TextServer] RID of the font cache for specific variation.
+ </description>
+ </method>
<method name="get_ascent" qualifiers="const">
<return type="float" />
- <argument index="0" name="size" type="int" default="16" />
+ <argument index="0" name="font_size" type="int" default="16" />
<description>
Returns the average font ascent (number of pixels above the baseline).
[b]Note:[/b] Real ascent of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the ascent of empty line).
@@ -137,44 +129,53 @@
<method name="get_char_size" qualifiers="const">
<return type="Vector2" />
<argument index="0" name="char" type="int" />
- <argument index="1" name="next" type="int" default="0" />
- <argument index="2" name="size" type="int" default="16" />
+ <argument index="1" name="arg1" type="int" />
<description>
Returns the size of a character, optionally taking kerning into account if the next character is provided.
[b]Note:[/b] Do not use this function to calculate width of the string character by character, use [method get_string_size] or [TextLine] instead. The height returned is the font height (see also [method get_height]) and has no relation to the glyph height.
</description>
</method>
- <method name="get_data" qualifiers="const">
- <return type="FontData" />
- <argument index="0" name="idx" type="int" />
+ <method name="get_descent" qualifiers="const">
+ <return type="float" />
+ <argument index="0" name="font_size" type="int" default="16" />
<description>
- Returns the font data source at index [code]idx[/code]. If the index does not exist, returns [code]null[/code].
+ Returns the average font descent (number of pixels below the baseline).
+ [b]Note:[/b] Real descent of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the descent of empty line).
</description>
</method>
- <method name="get_data_count" qualifiers="const">
+ <method name="get_face_count" qualifiers="const">
<return type="int" />
<description>
- Returns the number of font data sources.
+ Returns number of faces in the TrueType / OpenType collection.
</description>
</method>
- <method name="get_data_rid" qualifiers="const">
- <return type="RID" />
- <argument index="0" name="idx" type="int" />
+ <method name="get_fallbacks" qualifiers="const">
+ <return type="Font[]" />
<description>
- Returns TextServer RID of the font data resources.
+ Returns array of fallback [Font]s.
</description>
</method>
- <method name="get_descent" qualifiers="const">
- <return type="float" />
- <argument index="0" name="size" type="int" default="16" />
+ <method name="get_font_name" qualifiers="const">
+ <return type="String" />
<description>
- Returns the average font descent (number of pixels below the baseline).
- [b]Note:[/b] Real descent of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the descent of empty line).
+ Returns font family name.
+ </description>
+ </method>
+ <method name="get_font_style" qualifiers="const">
+ <return type="int" enum="TextServer.FontStyle" />
+ <description>
+ Returns font style flags, see [enum TextServer.FontStyle].
+ </description>
+ </method>
+ <method name="get_font_style_name" qualifiers="const">
+ <return type="String" />
+ <description>
+ Returns font style name.
</description>
</method>
<method name="get_height" qualifiers="const">
<return type="float" />
- <argument index="0" name="size" type="int" default="16" />
+ <argument index="0" name="font_size" type="int" default="16" />
<description>
Returns the total average font height (ascent plus descent) in pixels.
[b]Note:[/b] Real height of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate (e.g. as the height of empty line).
@@ -183,18 +184,29 @@
<method name="get_multiline_string_size" qualifiers="const">
<return type="Vector2" />
<argument index="0" name="text" type="String" />
- <argument index="1" name="width" type="float" default="-1" />
- <argument index="2" name="size" type="int" default="16" />
- <argument index="3" name="flags" type="int" default="96" />
+ <argument index="1" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
+ <argument index="2" name="width" type="float" default="-1" />
+ <argument index="3" name="font_size" type="int" default="16" />
+ <argument index="4" name="max_lines" type="int" default="-1" />
+ <argument index="5" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
+ <argument index="6" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="7" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="8" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
Returns the size of a bounding box of a string broken into the lines, taking kerning and advance into account.
See also [method draw_multiline_string].
</description>
</method>
+ <method name="get_opentype_features" qualifiers="const">
+ <return type="Dictionary" />
+ <description>
+ Returns a set of OpenType feature tags. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
+ </description>
+ </method>
<method name="get_rids" qualifiers="const">
- <return type="Array" />
+ <return type="RID[]" />
<description>
- Returns [Array] of valid [FontData] [RID]s, which can be passed to the [TextServer] methods.
+ Returns [Array] of valid [Font] [RID]s, which can be passed to the [TextServer] methods.
</description>
</method>
<method name="get_spacing" qualifiers="const">
@@ -207,14 +219,19 @@
<method name="get_string_size" qualifiers="const">
<return type="Vector2" />
<argument index="0" name="text" type="String" />
- <argument index="1" name="size" type="int" default="16" />
- <argument index="2" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
- <argument index="3" name="width" type="float" default="-1" />
- <argument index="4" name="flags" type="int" default="3" />
+ <argument index="1" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
+ <argument index="2" name="width" type="float" default="-1" />
+ <argument index="3" name="font_size" type="int" default="16" />
+ <argument index="4" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <argument index="5" name="direction" type="int" enum="TextServer.Direction" default="0" />
+ <argument index="6" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
- Returns the size of a bounding box of a string, taking kerning and advance into account.
+ Returns the size of a bounding box of a single-line string, taking kerning and advance into account. See also [method get_multiline_string_size] and [method draw_string].
+ For example, to get the string size as displayed by a single-line Label, use:
+ [codeblock]
+ var string_size = $Label.get_theme_font("font").get_string_size($Label.text, HORIZONTAL_ALIGNMENT_LEFT, -1, $Label.get_theme_font_size("font_size"))
+ [/codeblock]
[b]Note:[/b] Real height of the string is context-dependent and can be significantly different from the value returned by [method get_height].
- See also [method draw_string].
</description>
</method>
<method name="get_supported_chars" qualifiers="const">
@@ -224,9 +241,22 @@
If a given character is included in more than one font data source, it appears only once in the returned string.
</description>
</method>
+ <method name="get_supported_feature_list" qualifiers="const">
+ <return type="Dictionary" />
+ <description>
+ Returns list of OpenType features supported by font.
+ </description>
+ </method>
+ <method name="get_supported_variation_list" qualifiers="const">
+ <return type="Dictionary" />
+ <description>
+ Returns list of supported [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]variation coordinates[/url], each coordinate is returned as [code]tag: Vector3i(min_value,max_value,default_value)[/code].
+ Font variations allow for continuous change of glyph characteristics along some given design axis, such as weight, width or slant.
+ </description>
+ </method>
<method name="get_underline_position" qualifiers="const">
<return type="float" />
- <argument index="0" name="size" type="int" default="16" />
+ <argument index="0" name="font_size" type="int" default="16" />
<description>
Returns average pixel offset of the underline below the baseline.
[b]Note:[/b] Real underline position of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate.
@@ -234,7 +264,7 @@
</method>
<method name="get_underline_thickness" qualifiers="const">
<return type="float" />
- <argument index="0" name="size" type="int" default="16" />
+ <argument index="0" name="font_size" type="int" default="16" />
<description>
Returns average thickness of the underline.
[b]Note:[/b] Real underline thickness of the string is context-dependent and can be significantly different from the value returned by this function. Use it only as rough estimate.
@@ -247,45 +277,34 @@
Returns [code]true[/code] if a Unicode [code]char[/code] is available in the font.
</description>
</method>
- <method name="remove_data">
- <return type="void" />
- <argument index="0" name="idx" type="int" />
+ <method name="is_language_supported" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="language" type="String" />
<description>
- Removes the font data source at index [code]idx[/code]. If the index does not exist, nothing happens.
+ Returns [code]true[/code], if font supports given language ([url=https://en.wikipedia.org/wiki/ISO_639-1]ISO 639[/url] code).
</description>
</method>
- <method name="set_data">
- <return type="void" />
- <argument index="0" name="idx" type="int" />
- <argument index="1" name="data" type="FontData" />
+ <method name="is_script_supported" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="script" type="String" />
<description>
- Sets the font data source at index [code]idx[/code]. If the index does not exist, nothing happens.
+ Returns [code]true[/code], if font supports given script ([url=https://en.wikipedia.org/wiki/ISO_15924]ISO 15924[/url] code).
</description>
</method>
- <method name="set_spacing">
+ <method name="set_cache_capacity">
<return type="void" />
- <argument index="0" name="spacing" type="int" enum="TextServer.SpacingType" />
- <argument index="1" name="value" type="int" />
+ <argument index="0" name="single_line" type="int" />
+ <argument index="1" name="multi_line" type="int" />
<description>
- Sets the spacing for [code]type[/code] (see [enum TextServer.SpacingType]) to [code]value[/code] in pixels (not relative to the font size).
+ Sets LRU cache capacity for [code]draw_*[/code] methods.
</description>
</method>
- <method name="update_changes">
+ <method name="set_fallbacks">
<return type="void" />
+ <argument index="0" name="fallbacks" type="Font[]" />
<description>
- After editing a font (changing data sources, etc.). Call this function to propagate changes to controls that might use it.
+ Sets array of fallback [Font]s.
</description>
</method>
</methods>
- <members>
- <member name="spacing_bottom" type="int" setter="set_spacing" getter="get_spacing" default="0">
- Extra spacing at the bottom of the line in pixels.
- </member>
- <member name="spacing_top" type="int" setter="set_spacing" getter="get_spacing" default="0">
- Extra spacing at the top of the line in pixels.
- </member>
- <member name="variation_coordinates" type="Dictionary" setter="set_variation_coordinates" getter="get_variation_coordinates" default="{}">
- Default font [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]variation coordinates[/url].
- </member>
- </members>
</class>
diff --git a/doc/classes/FontData.xml b/doc/classes/FontFile.xml
index d32e7b3a94..aaf871d55a 100644
--- a/doc/classes/FontData.xml
+++ b/doc/classes/FontFile.xml
@@ -1,13 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="FontData" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+<class name="FontFile" inherits="Font" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
- Font source data and prerendered glyph cache, imported from dynamic or bitmap font.
+ FontFile source data and prerendered glyph cache, imported from dynamic or bitmap font.
+ </brief_description>
+ <description>
+ [FontFile] contains a set of glyphs to represent Unicode characters imported from a font file, as well as a cache of rasterized glyphs, and a set of fallback [Font]s to use.
+ Use [FontVariation] to access specific OpenType variation of the font, create simulated bold / slanted version, and draw lines of text.
+ For more complex text processing, use [FontVariation] in conjunction with [TextLine] or [TextParagraph].
Supported font formats:
- Dynamic font importer: TrueType (.ttf), TrueType collection (.ttc), OpenType (.otf), OpenType collection (.otc), WOFF (.woff), WOFF2 (.woff2), Type 1 (.pfb, .pfm).
- Bitmap font importer: AngelCode BMFont (.fnt, .font), text and binary (version 3) format variants.
- Monospace image font importer: All supported image formats.
- </brief_description>
- <description>
+ [b]Note:[/b] A character is a symbol that represents an item (letter, digit etc.) in an abstract way.
+ [b]Note:[/b] A glyph is a bitmap or shape used to draw a one or more characters in a context-dependent manner. Glyph indices are bound to the specific font data source.
+ [b]Note:[/b] If a none of the font data sources contain glyphs for a character used in a string, the character in question will be replaced with a box displaying its hexadecimal code.
+
+ [codeblocks]
+ [gdscript]
+ var f = load("res://BarlowCondensed-Bold.ttf")
+ $"Label".set("custom_fonts/font", f)
+ $"Label".set("custom_fonts/font_size", 64)
+ [/gdscript]
+ [csharp]
+ var f = ResourceLoader.Load&lt;FontFile&gt;("res://BarlowCondensed-Bold.ttf");
+ GetNode("Label").Set("custom_fonts/font", f);
+ GetNode("Label").Set("custom_font_sizes/font_size", 64);
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
</tutorials>
@@ -51,14 +70,7 @@
[b]Note:[/b] This function will not remove glyphs associated with the texture, use [method remove_glyph] to remove them manually.
</description>
</method>
- <method name="find_cache" qualifiers="const">
- <return type="RID" />
- <argument index="0" name="variation_coordinates" type="Dictionary" />
- <description>
- Returns existing or creates a new font cache entry for the specified variation coordinates.
- </description>
- </method>
- <method name="get_ascent" qualifiers="const">
+ <method name="get_cache_ascent" qualifiers="const">
<return type="float" />
<argument index="0" name="cache_index" type="int" />
<argument index="1" name="size" type="int" />
@@ -72,25 +84,46 @@
Returns number of the font cache entries.
</description>
</method>
- <method name="get_cache_rid" qualifiers="const">
- <return type="RID" />
+ <method name="get_cache_descent" qualifiers="const">
+ <return type="float" />
+ <argument index="0" name="cache_index" type="int" />
+ <argument index="1" name="size" type="int" />
+ <description>
+ </description>
+ </method>
+ <method name="get_cache_scale" qualifiers="const">
+ <return type="float" />
+ <argument index="0" name="cache_index" type="int" />
+ <argument index="1" name="size" type="int" />
+ <description>
+ </description>
+ </method>
+ <method name="get_cache_underline_position" qualifiers="const">
+ <return type="float" />
<argument index="0" name="cache_index" type="int" />
+ <argument index="1" name="size" type="int" />
<description>
- Returns text server font cache entry resource id.
</description>
</method>
- <method name="get_descent" qualifiers="const">
+ <method name="get_cache_underline_thickness" qualifiers="const">
<return type="float" />
<argument index="0" name="cache_index" type="int" />
<argument index="1" name="size" type="int" />
<description>
- Returns font descent (number of pixels below the baseline).
</description>
</method>
- <method name="get_face_count" qualifiers="const">
+ <method name="get_embolden" qualifiers="const">
+ <return type="float" />
+ <argument index="0" name="cache_index" type="int" />
+ <description>
+ Returns embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness.
+ </description>
+ </method>
+ <method name="get_face_index" qualifiers="const">
<return type="int" />
+ <argument index="0" name="cache_index" type="int" />
<description>
- Returns number of faces in the TrueType / OpenType collection.
+ Recturns an active face index in the TrueType / OpenType collection.
</description>
</method>
<method name="get_glyph_advance" qualifiers="const">
@@ -186,14 +219,6 @@
Returns list of language support overrides.
</description>
</method>
- <method name="get_scale" qualifiers="const">
- <return type="float" />
- <argument index="0" name="cache_index" type="int" />
- <argument index="1" name="size" type="int" />
- <description>
- Returns scaling factor of the color bitmap font.
- </description>
- </method>
<method name="get_script_support_override" qualifiers="const">
<return type="bool" />
<argument index="0" name="script" type="String" />
@@ -214,34 +239,6 @@
Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size.
</description>
</method>
- <method name="get_spacing" qualifiers="const">
- <return type="int" />
- <argument index="0" name="cache_index" type="int" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="spacing_type" type="int" enum="TextServer.SpacingType" />
- <description>
- Returns extra spacing added between glyphs in pixels.
- </description>
- </method>
- <method name="get_supported_chars" qualifiers="const">
- <return type="String" />
- <description>
- Returns a string containing all the characters available in the font.
- </description>
- </method>
- <method name="get_supported_feature_list" qualifiers="const">
- <return type="Dictionary" />
- <description>
- Returns list of OpenType features supported by font.
- </description>
- </method>
- <method name="get_supported_variation_list" qualifiers="const">
- <return type="Dictionary" />
- <description>
- Returns list of supported [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]variation coordinates[/url], each coordinate is returned as [code]tag: Vector3i(min_value,max_value,default_value)[/code].
- Font variations allow for continuous change of glyph characteristics along some given design axis, such as weight, width or slant.
- </description>
- </method>
<method name="get_texture_count" qualifiers="const">
<return type="int" />
<argument index="0" name="cache_index" type="int" />
@@ -268,48 +265,18 @@
Returns a copy of the array containing the first free pixel in the each column of texture. Should be the same size as texture width or empty.
</description>
</method>
- <method name="get_underline_position" qualifiers="const">
- <return type="float" />
- <argument index="0" name="cache_index" type="int" />
- <argument index="1" name="size" type="int" />
- <description>
- Returns pixel offset of the underline below the baseline.
- </description>
- </method>
- <method name="get_underline_thickness" qualifiers="const">
- <return type="float" />
+ <method name="get_transform" qualifiers="const">
+ <return type="Transform2D" />
<argument index="0" name="cache_index" type="int" />
- <argument index="1" name="size" type="int" />
<description>
- Returns thickness of the underline in pixels.
+ Returns 2D transform, applied to the font outlines, can be used for slanting, flipping and rotating glyphs.
</description>
</method>
<method name="get_variation_coordinates" qualifiers="const">
<return type="Dictionary" />
<argument index="0" name="cache_index" type="int" />
<description>
- Returns variation coordinates for the specified font cache entry. See [method get_supported_variation_list] for more info.
- </description>
- </method>
- <method name="has_char" qualifiers="const">
- <return type="bool" />
- <argument index="0" name="char" type="int" />
- <description>
- Returns [code]true[/code] if a Unicode [code]char[/code] is available in the font.
- </description>
- </method>
- <method name="is_language_supported" qualifiers="const">
- <return type="bool" />
- <argument index="0" name="language" type="String" />
- <description>
- Returns [code]true[/code], if font supports given language ([url=https://en.wikipedia.org/wiki/ISO_639-1]ISO 639[/url] code).
- </description>
- </method>
- <method name="is_script_supported" qualifiers="const">
- <return type="bool" />
- <argument index="0" name="script" type="String" />
- <description>
- Returns [code]true[/code], if font supports given script ([url=https://en.wikipedia.org/wiki/ISO_15924]ISO 15924[/url] code).
+ Returns variation coordinates for the specified font cache entry. See [method Font.get_supported_variation_list] for more info.
</description>
</method>
<method name="load_bitmap_font">
@@ -324,8 +291,7 @@
<return type="int" enum="Error" />
<argument index="0" name="path" type="String" />
<description>
- Loads a TrueType (.ttf), TrueType collection (.ttc), OpenType (.otf), OpenType collection (.otc), WOFF (.woff), WOFF2 (.woff2) or Type 1 (.pfb, .pfm) dynamic font from file [code]path[/code].
- [b]Note:[/b] Use [member face_index] to select specific face from the collection file.
+ Loads a TrueType (.ttf), OpenType (.otf), WOFF (.woff), WOFF2 (.woff2) or Type 1 (.pfb, .pfm) dynamic font from file [code]path[/code].
[b]Warning:[/b] This method should only be used in the editor or in cases when you need to load external fonts at run-time, such as fonts located at the [code]user://[/code] directory.
</description>
</method>
@@ -383,8 +349,8 @@
<argument index="1" name="size" type="Vector2i" />
<argument index="2" name="texture_index" type="int" />
<description>
- Removes specified texture from font cache entry.
- [b]Note:[/b] This function will not remove glyphs associated with the texture, remove them manually, using [method remove_glyph].
+ Removes specified texture from the cache entry.
+ [b]Note:[/b] This function will not remove glyphs associated with the texture. Remove them manually using [method remove_glyph].
</description>
</method>
<method name="render_glyph">
@@ -393,7 +359,7 @@
<argument index="1" name="size" type="Vector2i" />
<argument index="2" name="index" type="int" />
<description>
- Renders specified glyph the the font cache texture.
+ Renders specified glyph to the font cache texture.
</description>
</method>
<method name="render_range">
@@ -406,22 +372,60 @@
Renders the range of characters to the font cache texture.
</description>
</method>
- <method name="set_ascent">
+ <method name="set_cache_ascent">
<return type="void" />
<argument index="0" name="cache_index" type="int" />
<argument index="1" name="size" type="int" />
<argument index="2" name="ascent" type="float" />
<description>
- Sets the font ascent (number of pixels above the baseline).
</description>
</method>
- <method name="set_descent">
+ <method name="set_cache_descent">
<return type="void" />
<argument index="0" name="cache_index" type="int" />
<argument index="1" name="size" type="int" />
<argument index="2" name="descent" type="float" />
<description>
- Sets the font descent (number of pixels below the baseline).
+ </description>
+ </method>
+ <method name="set_cache_scale">
+ <return type="void" />
+ <argument index="0" name="cache_index" type="int" />
+ <argument index="1" name="size" type="int" />
+ <argument index="2" name="scale" type="float" />
+ <description>
+ </description>
+ </method>
+ <method name="set_cache_underline_position">
+ <return type="void" />
+ <argument index="0" name="cache_index" type="int" />
+ <argument index="1" name="size" type="int" />
+ <argument index="2" name="underline_position" type="float" />
+ <description>
+ </description>
+ </method>
+ <method name="set_cache_underline_thickness">
+ <return type="void" />
+ <argument index="0" name="cache_index" type="int" />
+ <argument index="1" name="size" type="int" />
+ <argument index="2" name="underline_thickness" type="float" />
+ <description>
+ </description>
+ </method>
+ <method name="set_embolden">
+ <return type="void" />
+ <argument index="0" name="cache_index" type="int" />
+ <argument index="1" name="strength" type="float" />
+ <description>
+ Sets embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness.
+ </description>
+ </method>
+ <method name="set_face_index">
+ <return type="void" />
+ <argument index="0" name="cache_index" type="int" />
+ <argument index="1" name="face_index" type="int" />
+ <description>
+ Sets an active face index in the TrueType / OpenType collection.
</description>
</method>
<method name="set_glyph_advance">
@@ -490,16 +494,7 @@
<argument index="0" name="language" type="String" />
<argument index="1" name="supported" type="bool" />
<description>
- Adds override for [method is_language_supported].
- </description>
- </method>
- <method name="set_scale">
- <return type="void" />
- <argument index="0" name="cache_index" type="int" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="scale" type="float" />
- <description>
- Sets scaling factor of the color bitmap font.
+ Adds override for [method Font.is_language_supported].
</description>
</method>
<method name="set_script_support_override">
@@ -507,17 +502,7 @@
<argument index="0" name="script" type="String" />
<argument index="1" name="supported" type="bool" />
<description>
- Adds override for [method is_script_supported].
- </description>
- </method>
- <method name="set_spacing">
- <return type="void" />
- <argument index="0" name="cache_index" type="int" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="spacing_type" type="int" enum="TextServer.SpacingType" />
- <argument index="3" name="value" type="int" />
- <description>
- Sets extra spacing added between glyphs in pixels.
+ Adds override for [method Font.is_script_supported].
</description>
</method>
<method name="set_texture_image">
@@ -540,22 +525,12 @@
Sets array containing the first free pixel in the each column of texture. Should be the same size as texture width or empty (for the fonts without dynamic glyph generation support).
</description>
</method>
- <method name="set_underline_position">
+ <method name="set_transform">
<return type="void" />
<argument index="0" name="cache_index" type="int" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="underline_position" type="float" />
+ <argument index="1" name="transform" type="Transform2D" />
<description>
- Sets pixel offset of the underline below the baseline.
- </description>
- </method>
- <method name="set_underline_thickness">
- <return type="void" />
- <argument index="0" name="cache_index" type="int" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="underline_thickness" type="float" />
- <description>
- Sets thickness of the underline in pixels.
+ Sets 2D transform, applied to the font outlines, can be used for slanting, flipping and rotating glyphs.
</description>
</method>
<method name="set_variation_coordinates">
@@ -563,7 +538,7 @@
<argument index="0" name="cache_index" type="int" />
<argument index="1" name="variation_coordinates" type="Dictionary" />
<description>
- Sets variation coordinates for the specified font cache entry. See [method get_supported_variation_list] for more info.
+ Sets variation coordinates for the specified font cache entry. See [method Font.get_supported_variation_list] for more info.
</description>
</method>
</methods>
@@ -574,11 +549,8 @@
<member name="data" type="PackedByteArray" setter="set_data" getter="get_data" default="PackedByteArray()">
Contents of the dynamic font source file.
</member>
- <member name="embolden" type="float" setter="set_embolden" getter="get_embolden" default="0.0">
- If is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness.
- </member>
- <member name="face_index" type="int" setter="set_face_index" getter="get_face_index" default="0">
- Active face index in the TrueType / OpenType collection file.
+ <member name="fallbacks" type="Font[]" setter="set_fallbacks" getter="get_fallbacks" default="[]">
+ Array of fallback [Font]s.
</member>
<member name="fixed_size" type="int" setter="set_fixed_size" getter="get_fixed_size" default="0">
Font size, used only for the bitmap fonts.
@@ -586,7 +558,7 @@
<member name="font_name" type="String" setter="set_font_name" getter="get_font_name" default="&quot;&quot;">
Font family name.
</member>
- <member name="font_style" type="int" setter="set_font_style" getter="get_font_style" default="0">
+ <member name="font_style" type="int" setter="set_font_style" getter="get_font_style" enum="TextServer.FontStyle" default="0">
Font style flags, see [enum TextServer.FontStyle].
</member>
<member name="force_autohinter" type="bool" setter="set_force_autohinter" getter="is_force_autohinter" default="false">
@@ -619,9 +591,5 @@
<member name="subpixel_positioning" type="int" setter="set_subpixel_positioning" getter="get_subpixel_positioning" enum="TextServer.SubpixelPositioning" default="1">
Font glyph sub-pixel positioning mode. Subpixel positioning provides shaper text and better kerning for smaller font sizes, at the cost of memory usage and font rasterization speed. Use [constant TextServer.SUBPIXEL_POSITIONING_AUTO] to automatically enable it based on the font size.
</member>
- <member name="transform" type="Transform2D" setter="set_transform" getter="get_transform" default="Transform2D(1, 0, 0, 1, 0, 0)">
- 2D transform, applied to the font outlines, can be used for slanting, flipping and rotating glyphs.
- For example, to simulate italic typeface by slanting, apply the following transform [code]Transform2D(1.0, slant, 0.0, 1.0, 0.0, 0.0)[/code].
- </member>
</members>
</class>
diff --git a/doc/classes/FontVariation.xml b/doc/classes/FontVariation.xml
new file mode 100644
index 0000000000..a1b96fb137
--- /dev/null
+++ b/doc/classes/FontVariation.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="FontVariation" inherits="Font" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ Variation of the [Font].
+ </brief_description>
+ <description>
+ OpenType variations, simulated bold / slant, and additional font settings like OpenType features and extra spacing.
+
+ To use simulated bold font variant:
+ [codeblocks]
+ [gdscript]
+ var fv = FontVariation.new()
+ fv.set_base_font(load("res://BarlowCondensed-Regular.ttf"))
+ fv.set_variation_embolden(1.2);
+ $"Label".set("custom_fonts/font", fv)
+ $"Label".set("custom_fonts/font_size", 64)
+ [/gdscript]
+ [csharp]
+ var fv = new FontVariation();
+ fv.SetBaseFont(ResourceLoader.Load&lt;FontFile&gt;("res://BarlowCondensed-Regular.ttf"));
+ fv.SetVariationEmbolden(1.2);
+ GetNode("Label").Set("custom_fonts/font", fv);
+ GetNode("Label").Set("custom_font_sizes/font_size", 64);
+ [/csharp]
+ [/codeblocks]
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="set_spacing">
+ <return type="void" />
+ <argument index="0" name="spacing" type="int" enum="TextServer.SpacingType" />
+ <argument index="1" name="value" type="int" />
+ <description>
+ Sets the spacing for [code]type[/code] (see [enum TextServer.SpacingType]) to [code]value[/code] in pixels (not relative to the font size).
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="base_font" type="Font" setter="set_base_font" getter="get_base_font">
+ Base font used to create a variation. If not set, default [Theme] font is used.
+ </member>
+ <member name="fallbacks" type="Font[]" setter="set_fallbacks" getter="get_fallbacks" default="[]">
+ Array of fallback [Font]s. If not set [member base_font] fallback are ussed.
+ </member>
+ <member name="opentype_features" type="Dictionary" setter="set_opentype_features" getter="get_opentype_features" default="{}">
+ A set of OpenType feature tags. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
+ </member>
+ <member name="spacing_bottom" type="int" setter="set_spacing" getter="get_spacing" default="0">
+ Extra spacing at the bottom of the line in pixels.
+ </member>
+ <member name="spacing_glyph" type="int" setter="set_spacing" getter="get_spacing" default="0">
+ Extra spacing between graphical glyphs
+ </member>
+ <member name="spacing_space" type="int" setter="set_spacing" getter="get_spacing" default="0">
+ Extra width of the space glyphs.
+ </member>
+ <member name="spacing_top" type="int" setter="set_spacing" getter="get_spacing" default="0">
+ Extra spacing at the top of the line in pixels.
+ </member>
+ <member name="variation_embolden" type="float" setter="set_variation_embolden" getter="get_variation_embolden" default="0.0">
+ If is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness.
+ [b]Note:[/b] Emboldened fonts might have self-intersecting outlines, which will prevent MSDF fonts and [TextMesh] from working correctly.
+ </member>
+ <member name="variation_face_index" type="int" setter="set_variation_face_index" getter="get_variation_face_index" default="0">
+ Active face index in the TrueType / OpenType collection file.
+ </member>
+ <member name="variation_opentype" type="Dictionary" setter="set_variation_opentype" getter="get_variation_opentype" default="{}">
+ Font OpenType variation coordinates. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg]OpenType variation tags[/url].
+ </member>
+ <member name="variation_transform" type="Transform2D" setter="set_variation_transform" getter="get_variation_transform" default="Transform2D(1, 0, 0, 1, 0, 0)">
+ 2D transform, applied to the font outlines, can be used for slanting, flipping and rotating glyphs.
+ For example, to simulate italic typeface by slanting, apply the following transform [code]Transform2D(1.0, slant, 0.0, 1.0, 0.0, 0.0)[/code].
+ </member>
+ </members>
+</class>
diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml
index f261da8413..36dbae1d74 100644
--- a/doc/classes/GraphNode.xml
+++ b/doc/classes/GraphNode.xml
@@ -17,12 +17,6 @@
Disables all input and output slots of the GraphNode.
</description>
</method>
- <method name="clear_opentype_features">
- <return type="void" />
- <description>
- Removes all OpenType features.
- </description>
- </method>
<method name="clear_slot">
<return type="void" />
<argument index="0" name="idx" type="int" />
@@ -98,13 +92,6 @@
Returns the type of the output connection [code]idx[/code].
</description>
</method>
- <method name="get_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code].
- </description>
- </method>
<method name="get_slot_color_left" qualifiers="const">
<return type="Color" />
<argument index="0" name="idx" type="int" />
@@ -154,14 +141,6 @@
Returns [code]true[/code] if right (output) side of the slot [code]idx[/code] is enabled.
</description>
</method>
- <method name="set_opentype_feature">
- <return type="void" />
- <argument index="0" name="tag" type="String" />
- <argument index="1" name="value" type="int" />
- <description>
- Sets OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
<method name="set_slot">
<return type="void" />
<argument index="0" name="idx" type="int" />
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index 166923314f..3d2e9449e2 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -106,8 +106,7 @@
if error != OK:
push_error("Couldn't load the image.")
- var texture = ImageTexture.new()
- texture.create_from_image(image)
+ var texture = ImageTexture.create_from_image(image)
# Display the image in a TextureRect node.
var texture_rect = TextureRect.new()
@@ -252,6 +251,7 @@
Maximum number of allowed redirects.
</member>
<member name="timeout" type="float" setter="set_timeout" getter="get_timeout" default="0.0">
+ If set to a value greater than [code]0.0[/code] before the request starts, the HTTP request will time out after [code]timeout[/code] seconds have passed and the request is not [i]completed[/i] yet. For small HTTP requests such as REST API usage, set [member timeout] to a value between [code]10.0[/code] and [code]30.0[/code] to prevent the application from getting stuck if the request fails to get a response in a timely manner. For file downloads, leave this to [code]0.0[/code] to prevent the download from failing if it takes too much time.
</member>
<member name="use_threads" type="bool" setter="set_use_threads" getter="is_using_threads" default="false">
If [code]true[/code], multithreading is used to improve performance.
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index 43b03ce65e..a927345e79 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -23,8 +23,8 @@
<method name="blend_rect">
<return type="void" />
<argument index="0" name="src" type="Image" />
- <argument index="1" name="src_rect" type="Rect2" />
- <argument index="2" name="dst" type="Vector2" />
+ <argument index="1" name="src_rect" type="Rect2i" />
+ <argument index="2" name="dst" type="Vector2i" />
<description>
Alpha-blends [code]src_rect[/code] from [code]src[/code] image to this image at coordinates [code]dest[/code], clipped accordingly to both image bounds. This image and [code]src[/code] image [b]must[/b] have the same format. [code]src_rect[/code] with not positive size is treated as empty.
</description>
@@ -33,8 +33,8 @@
<return type="void" />
<argument index="0" name="src" type="Image" />
<argument index="1" name="mask" type="Image" />
- <argument index="2" name="src_rect" type="Rect2" />
- <argument index="3" name="dst" type="Vector2" />
+ <argument index="2" name="src_rect" type="Rect2i" />
+ <argument index="3" name="dst" type="Vector2i" />
<description>
Alpha-blends [code]src_rect[/code] from [code]src[/code] image to this image using [code]mask[/code] image at coordinates [code]dst[/code], clipped accordingly to both image bounds. Alpha channels are required for both [code]src[/code] and [code]mask[/code]. [code]dst[/code] pixels and [code]src[/code] pixels will blend if the corresponding mask pixel's alpha value is not 0. This image and [code]src[/code] image [b]must[/b] have the same format. [code]src[/code] image and [code]mask[/code] image [b]must[/b] have the same size (width and height) but they can have different formats. [code]src_rect[/code] with not positive size is treated as empty.
</description>
@@ -42,8 +42,8 @@
<method name="blit_rect">
<return type="void" />
<argument index="0" name="src" type="Image" />
- <argument index="1" name="src_rect" type="Rect2" />
- <argument index="2" name="dst" type="Vector2" />
+ <argument index="1" name="src_rect" type="Rect2i" />
+ <argument index="2" name="dst" type="Vector2i" />
<description>
Copies [code]src_rect[/code] from [code]src[/code] image to this image at coordinates [code]dst[/code], clipped accordingly to both image bounds. This image and [code]src[/code] image [b]must[/b] have the same format. [code]src_rect[/code] with not positive size is treated as empty.
</description>
@@ -52,8 +52,8 @@
<return type="void" />
<argument index="0" name="src" type="Image" />
<argument index="1" name="mask" type="Image" />
- <argument index="2" name="src_rect" type="Rect2" />
- <argument index="3" name="dst" type="Vector2" />
+ <argument index="2" name="src_rect" type="Rect2i" />
+ <argument index="3" name="dst" type="Vector2i" />
<description>
Blits [code]src_rect[/code] area from [code]src[/code] image to this image at the coordinates given by [code]dst[/code], clipped accordingly to both image bounds. [code]src[/code] pixel is copied onto [code]dst[/code] if the corresponding [code]mask[/code] pixel's alpha value is not 0. This image and [code]src[/code] image [b]must[/b] have the same format. [code]src[/code] image and [code]mask[/code] image [b]must[/b] have the same size (width and height) but they can have different formats. [code]src_rect[/code] with not positive size is treated as empty.
</description>
@@ -168,7 +168,7 @@
</method>
<method name="fill_rect">
<return type="void" />
- <argument index="0" name="rect" type="Rect2" />
+ <argument index="0" name="rect" type="Rect2i" />
<argument index="1" name="color" type="Color" />
<description>
Fills [code]rect[/code] with [code]color[/code].
@@ -244,7 +244,7 @@
</method>
<method name="get_rect" qualifiers="const">
<return type="Image" />
- <argument index="0" name="rect" type="Rect2" />
+ <argument index="0" name="rect" type="Rect2i" />
<description>
Returns a new image that is a copy of the image's area specified with [code]rect[/code].
</description>
@@ -256,9 +256,9 @@
</description>
</method>
<method name="get_used_rect" qualifiers="const">
- <return type="Rect2" />
+ <return type="Rect2i" />
<description>
- Returns a [Rect2] enclosing the visible portion of the image, considering each pixel with a non-zero alpha channel as visible.
+ Returns a [Rect2i] enclosing the visible portion of the image, considering each pixel with a non-zero alpha channel as visible.
</description>
</method>
<method name="get_width" qualifiers="const">
@@ -308,6 +308,13 @@
[b]Note:[/b] Godot's BMP module doesn't support 16-bit per pixel images. Only 1-bit, 4-bit, 8-bit, 24-bit, and 32-bit per pixel images are supported.
</description>
</method>
+ <method name="load_from_file" qualifiers="static">
+ <return type="Image" />
+ <argument index="0" name="path" type="String" />
+ <description>
+ Creates a new [Image] and loads data from the specified file.
+ </description>
+ </method>
<method name="load_jpg_from_buffer">
<return type="int" enum="Error" />
<argument index="0" name="buffer" type="PackedByteArray" />
@@ -371,6 +378,19 @@
Converts a standard RGBE (Red Green Blue Exponent) image to an sRGB image.
</description>
</method>
+ <method name="rotate_180">
+ <return type="void" />
+ <description>
+ Rotates the image by [code]180[/code] degrees. The width and height of the image must be greater than [code]1[/code].
+ </description>
+ </method>
+ <method name="rotate_90">
+ <return type="void" />
+ <argument index="0" name="direction" type="int" enum="ClockDirection" />
+ <description>
+ Rotates the image in the specified [code]direction[/code] by [code]90[/code] degrees. The width and height of the image must be greater than [code]1[/code]. If the width and height are not equal, the image will be resized.
+ </description>
+ </method>
<method name="save_exr" qualifiers="const">
<return type="int" enum="Error" />
<argument index="0" name="path" type="String" />
diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml
index aecb4fc4b6..084bf7e809 100644
--- a/doc/classes/ImageTexture.xml
+++ b/doc/classes/ImageTexture.xml
@@ -6,10 +6,8 @@
<description>
A [Texture2D] based on an [Image]. For an image to be displayed, an [ImageTexture] has to be created from it using the [method create_from_image] method:
[codeblock]
- var texture = ImageTexture.new()
- var image = Image.new()
- image.load("res://icon.png")
- texture.create_from_image(image)
+ var image = Image.load_from_file("res://icon.png")
+ var texture = ImageTexture.create_from_image(image)
$Sprite2D.texture = texture
[/codeblock]
This way, textures can be created at run-time by loading images both from within the editor and externally.
@@ -31,11 +29,11 @@
<link title="Importing images">$DOCS_URL/tutorials/assets_pipeline/importing_images.html</link>
</tutorials>
<methods>
- <method name="create_from_image">
- <return type="void" />
+ <method name="create_from_image" qualifiers="static">
+ <return type="ImageTexture" />
<argument index="0" name="image" type="Image" />
<description>
- Initializes the texture by allocating and setting the data from an [Image].
+ Creates a new [ImageTexture] and initializes it by allocating and setting the data from an [Image].
</description>
</method>
<method name="get_format" qualifiers="const">
@@ -44,9 +42,17 @@
Returns the format of the texture, one of [enum Image.Format].
</description>
</method>
+ <method name="set_image">
+ <return type="void" />
+ <argument index="0" name="image" type="Image" />
+ <description>
+ Replaces the texture's data with a new [Image]. This will re-allocate new memory for the texture.
+ If you want to update the image, but don't need to change its parameters (format, size), use [method update] instead for better performance.
+ </description>
+ </method>
<method name="set_size_override">
<return type="void" />
- <argument index="0" name="size" type="Vector2" />
+ <argument index="0" name="size" type="Vector2i" />
<description>
Resizes the texture to the specified dimensions.
</description>
@@ -56,8 +62,8 @@
<argument index="0" name="image" type="Image" />
<description>
Replaces the texture's data with a new [Image].
- [b]Note:[/b] The texture has to be initialized first with the [method create_from_image] method before it can be updated. The new image dimensions, format, and mipmaps configuration should match the existing texture's image configuration, otherwise it has to be re-created with the [method create_from_image] method.
- Use this method over [method create_from_image] if you need to update the texture frequently, which is faster than allocating additional memory for a new texture each time.
+ [b]Note:[/b] The texture has to be created using [method create_from_image] or initialized first with the [method set_image] method before it can be updated. The new image dimensions, format, and mipmaps configuration should match the existing texture's image configuration.
+ Use this method over [method set_image] if you need to update the texture frequently, which is faster than allocating additional memory for a new texture each time.
</description>
</method>
</methods>
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index 66683fa0ee..e73021ead4 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -375,6 +375,7 @@
<member name="use_accumulated_input" type="bool" setter="set_use_accumulated_input" getter="is_using_accumulated_input">
If [code]true[/code], similar input events sent by the operating system are accumulated. When input accumulation is enabled, all input events generated during a frame will be merged and emitted when the frame is done rendering. Therefore, this limits the number of input method calls per second to the rendering FPS.
Input accumulation can be disabled to get slightly more precise/reactive input at the cost of increased CPU usage. In applications where drawing freehand lines is required, input accumulation should generally be disabled while the user is drawing the line to get results that closely follow the actual input.
+ [b]Note:[/b] Input accumulation is [i]enabled[/i] by default.
</member>
</members>
<signals>
diff --git a/doc/classes/InputEventMouseMotion.xml b/doc/classes/InputEventMouseMotion.xml
index ad74204d82..83aad587a5 100644
--- a/doc/classes/InputEventMouseMotion.xml
+++ b/doc/classes/InputEventMouseMotion.xml
@@ -12,6 +12,10 @@
<link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link>
</tutorials>
<members>
+ <member name="pen_inverted" type="bool" setter="set_pen_inverted" getter="get_pen_inverted" default="false">
+ Returns [code]true[/code] when using the eraser end of a stylus pen.
+ [b]Note:[/b] This property is implemented on Linux, macOS and Windows.
+ </member>
<member name="pressure" type="float" setter="set_pressure" getter="get_pressure" default="0.0">
Represents the pressure the user puts on the pen. Ranges from [code]0.0[/code] to [code]1.0[/code].
</member>
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index d52234e9ac..15c97b0838 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -38,13 +38,6 @@
Removes all items from the list.
</description>
</method>
- <method name="clear_item_opentype_features">
- <return type="void" />
- <argument index="0" name="idx" type="int" />
- <description>
- Removes all OpenType features from the item's text.
- </description>
- </method>
<method name="deselect">
<return type="void" />
<argument index="0" name="idx" type="int" />
@@ -122,14 +115,6 @@
Returns the metadata value of the specified index.
</description>
</method>
- <method name="get_item_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="idx" type="int" />
- <argument index="1" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code] of the item's text.
- </description>
- </method>
<method name="get_item_text" qualifiers="const">
<return type="String" />
<argument index="0" name="idx" type="int" />
@@ -302,15 +287,6 @@
Sets a value (of any type) to be stored with the item associated with the specified index.
</description>
</method>
- <method name="set_item_opentype_feature">
- <return type="void" />
- <argument index="0" name="idx" type="int" />
- <argument index="1" name="tag" type="String" />
- <argument index="2" name="value" type="int" />
- <description>
- Sets OpenType feature [code]tag[/code] for the item's text. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
<method name="set_item_selectable">
<return type="void" />
<argument index="0" name="idx" type="int" />
diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml
index b5f045621b..8448109f02 100644
--- a/doc/classes/Label.xml
+++ b/doc/classes/Label.xml
@@ -11,12 +11,6 @@
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link>
</tutorials>
<methods>
- <method name="clear_opentype_features">
- <return type="void" />
- <description>
- Removes all OpenType features.
- </description>
- </method>
<method name="get_line_count" qualifiers="const">
<return type="int" />
<description>
@@ -32,13 +26,6 @@
If there're no lines returns font size in pixels.
</description>
</method>
- <method name="get_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code].
- </description>
- </method>
<method name="get_total_character_count" qualifiers="const">
<return type="int" />
<description>
@@ -51,14 +38,6 @@
Returns the number of lines shown. Useful if the [Label]'s height cannot currently display all lines.
</description>
</method>
- <method name="set_opentype_feature">
- <return type="void" />
- <argument index="0" name="tag" type="String" />
- <argument index="1" name="value" type="int" />
- <description>
- Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
</methods>
<members>
<member name="autowrap_mode" type="int" setter="set_autowrap_mode" getter="get_autowrap_mode" enum="TextServer.AutowrapMode" default="0">
@@ -70,6 +49,9 @@
<member name="horizontal_alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants.
</member>
+ <member name="label_settings" type="LabelSettings" setter="set_label_settings" getter="get_label_settings">
+ Resource to override [Theme] font, outline and shadow properties.
+ </member>
<member name="language" type="String" setter="set_language" getter="get_language" default="&quot;&quot;">
Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
</member>
@@ -119,7 +101,7 @@
Default text [Color] of the [Label].
</theme_item>
<theme_item name="font_outline_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
- The tint of [Font]'s outline.
+ The tint of text outline.
</theme_item>
<theme_item name="font_shadow_color" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
[Color] of the text's shadow effect.
diff --git a/doc/classes/Label3D.xml b/doc/classes/Label3D.xml
index 47126575f7..2c3c27079a 100644
--- a/doc/classes/Label3D.xml
+++ b/doc/classes/Label3D.xml
@@ -9,12 +9,6 @@
<tutorials>
</tutorials>
<methods>
- <method name="clear_opentype_features">
- <return type="void" />
- <description>
- Removes all OpenType features.
- </description>
- </method>
<method name="generate_triangle_mesh" qualifiers="const">
<return type="TriangleMesh" />
<description>
@@ -28,13 +22,6 @@
Returns the value of the specified flag.
</description>
</method>
- <method name="get_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code].
- </description>
- </method>
<method name="set_draw_flag">
<return type="void" />
<argument index="0" name="flag" type="int" enum="Label3D.DrawFlags" />
@@ -43,14 +30,6 @@
If [code]true[/code], the specified flag will be enabled. See [enum Label3D.DrawFlags] for a list of flags.
</description>
</method>
- <method name="set_opentype_feature">
- <return type="void" />
- <argument index="0" name="tag" type="String" />
- <argument index="1" name="value" type="int" />
- <description>
- Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
</methods>
<members>
<member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" enum="Label3D.AlphaCutMode" default="0">
@@ -72,7 +51,7 @@
If [code]true[/code], the label is rendered at the same size regardless of distance.
</member>
<member name="font" type="Font" setter="set_font" getter="get_font">
- [Font] used for the [Label3D]'s text.
+ Font configuration used to display text.
</member>
<member name="font_size" type="int" setter="set_font_size" getter="get_font_size" default="16">
Font size of the [Label3D]'s text.
@@ -96,7 +75,7 @@
The text drawing offset (in pixels).
</member>
<member name="outline_modulate" type="Color" setter="set_outline_modulate" getter="get_outline_modulate" default="Color(0, 0, 0, 1)">
- The tint of [Font]'s outline.
+ The tint of text outline.
</member>
<member name="outline_render_priority" type="int" setter="set_outline_render_priority" getter="get_outline_render_priority" default="-1">
Sets the render priority for the text outline. Higher priority objects will be sorted in front of lower priority objects.
diff --git a/doc/classes/LabelSettings.xml b/doc/classes/LabelSettings.xml
new file mode 100644
index 0000000000..5f7427f4aa
--- /dev/null
+++ b/doc/classes/LabelSettings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="LabelSettings" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ Resource to override [Theme] font, outline and shadow properties of the [Label].
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <members>
+ <member name="font" type="Font" setter="set_font" getter="get_font">
+ [Font] of the [Label]'s text.
+ </member>
+ <member name="font_color" type="Color" setter="set_font_color" getter="get_font_color" default="Color(0.875, 0.875, 0.875, 1)">
+ Default text [Color] of the [Label].
+ </member>
+ <member name="font_size" type="int" setter="set_font_size" getter="get_font_size" default="16">
+ Font size of the [Label]'s text.
+ </member>
+ <member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="0.0">
+ Vertical space between lines in multiline text.
+ </member>
+ <member name="outline_color" type="Color" setter="set_outline_color" getter="get_outline_color" default="Color(1, 1, 1, 1)">
+ The tint of text outline.
+ </member>
+ <member name="outline_size" type="int" setter="set_outline_size" getter="get_outline_size" default="0">
+ Text outline size.
+ </member>
+ <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color(1, 1, 1, 1)">
+ The tint of text shadow.
+ </member>
+ <member name="shadow_offset" type="Vector2" setter="set_shadow_offset" getter="get_shadow_offset" default="Vector2(1, 1)">
+ The offset of the text's shadow.
+ </member>
+ <member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" default="0">
+ The size of the text's shadow.
+ </member>
+ </members>
+</class>
diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml
index 4d8fd63257..0ebd83c882 100644
--- a/doc/classes/Light3D.xml
+++ b/doc/classes/Light3D.xml
@@ -73,6 +73,7 @@
</member>
<member name="light_projector" type="Texture2D" setter="set_projector" getter="get_projector">
[Texture2D] projected by light. [member shadow_enabled] must be on for the projector to work. Light projectors make the light appear as if it is shining through a colored but transparent object, almost like light shining through stained-glass.
+ [b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for light projector textures is set globally with [member ProjectSettings.rendering/textures/light_projectors/filter].
</member>
<member name="light_size" type="float" setter="set_param" getter="get_param" default="0.0">
The size of the light in Godot units. Only available for [OmniLight3D]s and [SpotLight3D]s. Increasing this value will make the light fade out slower and shadows appear blurrier. This can be used to simulate area lights to an extent.
diff --git a/doc/classes/LightmapGI.xml b/doc/classes/LightmapGI.xml
index ffde0d95ce..c0766cd1ec 100644
--- a/doc/classes/LightmapGI.xml
+++ b/doc/classes/LightmapGI.xml
@@ -21,7 +21,7 @@
Number of light bounces that are taken into account during baking. Higher values result in brighter, more realistic lighting, at the cost of longer bake times. If set to [code]0[/code], only environment lighting, direct light and emissive lighting is baked.
</member>
<member name="directional" type="bool" setter="set_directional" getter="is_directional" default="false">
- If [code]true[/code], bakes lightmaps to contain directional information as spherical harmonics. This results in more realistic lighting appearance, especially with normal mapped materials and for lights that their have direct light baked ([member Light3D.light_bake_mode] set to [constant Light3D.BAKE_STATIC]). The directional information is also used to provide rough reflections for static and dynamic objects. This has a small run-time performance cost as the shader has to perform more work to interpret the direction information from the lightmap. Directional lightmaps also take longer to bake and result in larger file sizes.
+ If [code]true[/code], bakes lightmaps to contain directional information as spherical harmonics. This results in more realistic lighting appearance, especially with normal mapped materials and for lights that have their direct light baked ([member Light3D.light_bake_mode] set to [constant Light3D.BAKE_STATIC]). The directional information is also used to provide rough reflections for static and dynamic objects. This has a small run-time performance cost as the shader has to perform more work to interpret the direction information from the lightmap. Directional lightmaps also take longer to bake and result in larger file sizes.
[b]Note:[/b] The property's name has no relationship with [DirectionalLight3D]. [member directional] works with all light types.
</member>
<member name="environment_custom_color" type="Color" setter="set_environment_custom_color" getter="get_environment_custom_color">
diff --git a/doc/classes/LightmapGIData.xml b/doc/classes/LightmapGIData.xml
index 20113ac309..13f44150d7 100644
--- a/doc/classes/LightmapGIData.xml
+++ b/doc/classes/LightmapGIData.xml
@@ -22,7 +22,7 @@
<method name="clear_users">
<return type="void" />
<description>
- Clear all objects that are considred baked within this [LightmapGIData].
+ Clear all objects that are considered baked within this [LightmapGIData].
</description>
</method>
<method name="get_user_count" qualifiers="const">
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index 55e012ee0c..84471bafc0 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -37,12 +37,6 @@
Erases the [LineEdit]'s [member text].
</description>
</method>
- <method name="clear_opentype_features">
- <return type="void" />
- <description>
- Removes all OpenType features.
- </description>
- </method>
<method name="delete_char_at_caret">
<return type="void" />
<description>
@@ -70,13 +64,6 @@
[b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to hide it or any of its children, use their [member Window.visible] property.
</description>
</method>
- <method name="get_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code].
- </description>
- </method>
<method name="get_scroll_offset" qualifiers="const">
<return type="int" />
<description>
@@ -149,14 +136,6 @@
Selects the whole [String].
</description>
</method>
- <method name="set_opentype_feature">
- <return type="void" />
- <argument index="0" name="tag" type="String" />
- <argument index="1" name="value" type="int" />
- <description>
- Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
</methods>
<members>
<member name="alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml
index ba80504caf..7c6ff2d4e1 100644
--- a/doc/classes/LinkButton.xml
+++ b/doc/classes/LinkButton.xml
@@ -9,29 +9,6 @@
</description>
<tutorials>
</tutorials>
- <methods>
- <method name="clear_opentype_features">
- <return type="void" />
- <description>
- Removes all OpenType features.
- </description>
- </method>
- <method name="get_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code].
- </description>
- </method>
- <method name="set_opentype_feature">
- <return type="void" />
- <argument index="0" name="tag" type="String" />
- <argument index="1" name="value" type="int" />
- <description>
- Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
- </methods>
<members>
<member name="language" type="String" setter="set_language" getter="get_language" default="&quot;&quot;">
Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
diff --git a/doc/classes/MovieWriter.xml b/doc/classes/MovieWriter.xml
index bc702adde6..d47e52d7c0 100644
--- a/doc/classes/MovieWriter.xml
+++ b/doc/classes/MovieWriter.xml
@@ -68,7 +68,7 @@
<return type="void" />
<argument index="0" name="writer" type="MovieWriter" />
<description>
- Adds a writer to be usable by the engine. The supported file extensions can be set by overridding [method _handles_file].
+ Adds a writer to be usable by the engine. The supported file extensions can be set by overriding [method _handles_file].
[b]Note:[/b] [method add_writer] must be called early enough in the engine initialization to work, as movie writing is designed to start at the same time as the rest of the engine.
</description>
</method>
diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml
index 631b2ea050..9d8f1e1e5d 100644
--- a/doc/classes/MultiMesh.xml
+++ b/doc/classes/MultiMesh.xml
@@ -91,7 +91,8 @@
<member name="custom_data_array" type="PackedColorArray" setter="_set_custom_data_array" getter="_get_custom_data_array">
</member>
<member name="instance_count" type="int" setter="set_instance_count" getter="get_instance_count" default="0">
- Number of instances that will get drawn. This clears and (re)sizes the buffers. By default, all instances are drawn but you can limit this with [member visible_instance_count].
+ Number of instances that will get drawn. This clears and (re)sizes the buffers. Setting data format or flags afterwards will have no effect.
+ By default, all instances are drawn but you can limit this with [member visible_instance_count].
</member>
<member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh">
Mesh to be drawn.
diff --git a/doc/classes/MultiplayerSpawner.xml b/doc/classes/MultiplayerSpawner.xml
index 4ca92728ff..9de67068eb 100644
--- a/doc/classes/MultiplayerSpawner.xml
+++ b/doc/classes/MultiplayerSpawner.xml
@@ -43,8 +43,6 @@
</method>
</methods>
<members>
- <member name="auto_spawn" type="bool" setter="set_auto_spawning" getter="is_auto_spawning" default="false">
- </member>
<member name="spawn_limit" type="int" setter="set_spawn_limit" getter="get_spawn_limit" default="0">
</member>
<member name="spawn_path" type="NodePath" setter="set_spawn_path" getter="get_spawn_path" default="NodePath(&quot;&quot;)">
diff --git a/doc/classes/MultiplayerSynchronizer.xml b/doc/classes/MultiplayerSynchronizer.xml
index ac067791e6..3766491a6c 100644
--- a/doc/classes/MultiplayerSynchronizer.xml
+++ b/doc/classes/MultiplayerSynchronizer.xml
@@ -6,12 +6,64 @@
</description>
<tutorials>
</tutorials>
+ <methods>
+ <method name="add_visibility_filter">
+ <return type="void" />
+ <argument index="0" name="filter" type="Callable" />
+ <description>
+ </description>
+ </method>
+ <method name="get_visibility_for" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="peer" type="int" />
+ <description>
+ </description>
+ </method>
+ <method name="remove_visibility_filter">
+ <return type="void" />
+ <argument index="0" name="filter" type="Callable" />
+ <description>
+ </description>
+ </method>
+ <method name="set_visibility_for">
+ <return type="void" />
+ <argument index="0" name="peer" type="int" />
+ <argument index="1" name="visible" type="bool" />
+ <description>
+ </description>
+ </method>
+ <method name="update_visibility">
+ <return type="void" />
+ <argument index="0" name="for_peer" type="int" default="0" />
+ <description>
+ </description>
+ </method>
+ </methods>
<members>
+ <member name="public_visibility" type="bool" setter="set_visibility_public" getter="is_visibility_public" default="true">
+ </member>
<member name="replication_config" type="SceneReplicationConfig" setter="set_replication_config" getter="get_replication_config">
</member>
<member name="replication_interval" type="float" setter="set_replication_interval" getter="get_replication_interval" default="0.0">
</member>
<member name="root_path" type="NodePath" setter="set_root_path" getter="get_root_path" default="NodePath(&quot;..&quot;)">
</member>
+ <member name="visibility_update_mode" type="int" setter="set_visibility_update_mode" getter="get_visibility_update_mode" enum="MultiplayerSynchronizer.VisibilityUpdateMode" default="0">
+ </member>
</members>
+ <signals>
+ <signal name="visibility_changed">
+ <argument index="0" name="for_peer" type="int" />
+ <description>
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ <constant name="VISIBILITY_PROCESS_IDLE" value="0" enum="VisibilityUpdateMode">
+ </constant>
+ <constant name="VISIBILITY_PROCESS_PHYSICS" value="1" enum="VisibilityUpdateMode">
+ </constant>
+ <constant name="VISIBILITY_PROCESS_NONE" value="2" enum="VisibilityUpdateMode">
+ </constant>
+ </constants>
</class>
diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml
index ac434af4fa..ff2afd595a 100644
--- a/doc/classes/Node3D.xml
+++ b/doc/classes/Node3D.xml
@@ -281,6 +281,13 @@
<member name="basis" type="Basis" setter="set_basis" getter="get_basis">
Direct access to the 3x3 basis of the [Transform3D] property.
</member>
+ <member name="global_position" type="Vector3" setter="set_global_position" getter="get_global_position">
+ Global position of this node. This is equivalent to [code]global_transform.origin[/code].
+ </member>
+ <member name="global_rotation" type="Vector3" setter="set_global_rotation" getter="get_global_rotation">
+ Rotation part of the global transformation in radians, specified in terms of YXZ-Euler angles in the format (X angle, Y angle, Z angle).
+ [b]Note:[/b] In the mathematical sense, rotation is a matrix and not a vector. The three Euler angles, which are the three independent parameters of the Euler-angle parametrization of the rotation matrix, are stored in a [Vector3] data structure not because the rotation is a vector, but only because [Vector3] exists as a convenient data-structure to store 3 floating-point numbers. Therefore, applying affine operations on the rotation "vector" is not meaningful.
+ </member>
<member name="global_transform" type="Transform3D" setter="set_global_transform" getter="get_global_transform">
World3D space (global) [Transform3D] of this node.
</member>
diff --git a/doc/classes/NodePath.xml b/doc/classes/NodePath.xml
index 00c5dcaa3d..d9e0680a38 100644
--- a/doc/classes/NodePath.xml
+++ b/doc/classes/NodePath.xml
@@ -87,6 +87,12 @@
[/codeblocks]
</description>
</method>
+ <method name="get_concatenated_names" qualifiers="const">
+ <return type="StringName" />
+ <description>
+ Returns all paths concatenated with a slash character ([code]/[/code]) as separator without subnames.
+ </description>
+ </method>
<method name="get_concatenated_subnames" qualifiers="const">
<return type="StringName" />
<description>
diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml
index 5d0861bcf3..3af3bb8697 100644
--- a/doc/classes/PackedByteArray.xml
+++ b/doc/classes/PackedByteArray.xml
@@ -409,7 +409,7 @@
<return type="PackedFloat32Array" />
<description>
Returns a copy of the data converted to a [PackedFloat32Array], where each block of 4 bytes has been converted to a 32-bit float (C++ [code]float[/code]).
- The size of the new array will be [code]byte_array.size() / 4[/code].
+ The size of the input array must be a multiple of 4 (size of 32-bit float). The size of the new array will be [code]byte_array.size() / 4[/code].
If the original data can't be converted to 32-bit floats, the resulting data is undefined.
</description>
</method>
@@ -417,7 +417,7 @@
<return type="PackedFloat64Array" />
<description>
Returns a copy of the data converted to a [PackedFloat64Array], where each block of 8 bytes has been converted to a 64-bit float (C++ [code]double[/code], Godot [float]).
- The size of the new array will be [code]byte_array.size() / 8[/code].
+ The size of the input array must be a multiple of 8 (size of 64-bit double). The size of the new array will be [code]byte_array.size() / 8[/code].
If the original data can't be converted to 64-bit floats, the resulting data is undefined.
</description>
</method>
@@ -425,15 +425,15 @@
<return type="PackedInt32Array" />
<description>
Returns a copy of the data converted to a [PackedInt32Array], where each block of 4 bytes has been converted to a signed 32-bit integer (C++ [code]int32_t[/code]).
- The size of the new array will be [code]byte_array.size() / 4[/code].
+ The size of the input array must be a multiple of 4 (size of 32-bit integer). The size of the new array will be [code]byte_array.size() / 4[/code].
If the original data can't be converted to signed 32-bit integers, the resulting data is undefined.
</description>
</method>
<method name="to_int64_array" qualifiers="const">
<return type="PackedInt64Array" />
<description>
- Returns a copy of the data converted to a [PackedInt64Array], where each block of 4 bytes has been converted to a signed 64-bit integer (C++ [code]int64_t[/code], Godot [int]).
- The size of the new array will be [code]byte_array.size() / 8[/code].
+ Returns a copy of the data converted to a [PackedInt64Array], where each block of 8 bytes has been converted to a signed 64-bit integer (C++ [code]int64_t[/code], Godot [int]).
+ The size of the input array must be a multiple of 8 (size of 64-bit integer). The size of the new array will be [code]byte_array.size() / 8[/code].
If the original data can't be converted to signed 64-bit integers, the resulting data is undefined.
</description>
</method>
diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml
index 885bedbc04..354fbd462c 100644
--- a/doc/classes/ParticlesMaterial.xml
+++ b/doc/classes/ParticlesMaterial.xml
@@ -77,28 +77,30 @@
Each particle's rotation will be animated along this [CurveTexture].
</member>
<member name="angle_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
- Maximum angle.
+ Maximum initial rotation applied to each particle, in degrees.
+ Only applied when [member particle_flag_disable_z] or [member particle_flag_rotate_y] are [code]true[/code] or the [BaseMaterial3D] being used to draw the particle is using [constant BaseMaterial3D.BILLBOARD_PARTICLES].
</member>
<member name="angle_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
- Minimum angle.
+ Minimum equivalent of [member angle_max].
</member>
<member name="angular_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's angular velocity (rotation speed) will vary along this [CurveTexture] over its lifetime.
</member>
<member name="angular_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
Maximum initial angular velocity (rotation speed) applied to each particle in [i]degrees[/i] per second.
+ Only applied when [member particle_flag_disable_z] or [member particle_flag_rotate_y] are [code]true[/code] or the [BaseMaterial3D] being used to draw the particle is using [constant BaseMaterial3D.BILLBOARD_PARTICLES].
</member>
<member name="angular_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
- Minimum initial angular velocity (rotation speed) applied to each particle in [i]degrees[/i] per second.
+ Minimum equivalent of [member angular_velocity_max].
</member>
<member name="anim_offset_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's animation offset will vary along this [CurveTexture].
</member>
<member name="anim_offset_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
- Maximum animation offset.
+ Maximum animation offset that corresponds to frame index in the texture. [code]0[/code] is the first frame, [code]1[/code] is the last one. See [member CanvasItemMaterial.particles_animation].
</member>
<member name="anim_offset_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
- Minimum animation offset.
+ Minimum equivalent of [member anim_offset_max].
</member>
<member name="anim_speed_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's animation speed will vary along this [CurveTexture].
@@ -108,7 +110,7 @@
With animation speed greater than [code]1[/code], remember to enable [member CanvasItemMaterial.particles_anim_loop] property if you want the animation to repeat.
</member>
<member name="anim_speed_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
- Minimum particle animation speed.
+ Minimum equivalent of [member anim_speed_max].
</member>
<member name="attractor_interaction_enabled" type="bool" setter="set_attractor_interaction_enabled" getter="is_attractor_interaction_enabled" default="true">
True if the interaction with particle attractors is enabled.
@@ -138,8 +140,10 @@
Damping will vary along this [CurveTexture].
</member>
<member name="damping_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ The maximum rate at which particles lose velocity. For example value of [code]100[/code] means that the particle will go from [code]100[/code] velocity to [code]0[/code] in [code]1[/code] second.
</member>
<member name="damping_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum equivalent of [member damping_max].
</member>
<member name="direction" type="Vector3" setter="set_direction" getter="get_direction" default="Vector3(1, 0, 0)">
Unit vector specifying the particles' emission direction.
@@ -187,16 +191,16 @@
Each particle's hue will vary along this [CurveTexture].
</member>
<member name="hue_variation_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
- Maximum hue variation.
+ Maximum initial hue variation applied to each particle. It will shift the particle color's hue.
</member>
<member name="hue_variation_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
- Minimum hue variation.
+ Minimum equivalent of [member hue_variation_max].
</member>
<member name="initial_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
- Maximum initial velocity.
+ Maximum initial velocity magnitude for each particle. Direction comes from [member direction] and [member spread].
</member>
<member name="initial_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
- Minimum initial velocity.
+ Minimum equivalent of [member initial_velocity_max].
</member>
<member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0">
Particle lifetime randomness ratio. The lifetime will be multiplied by a value interpolated between [code]1.0[/code] and a random number less than one. For example a random ratio of [code]0.4[/code] would scale the original lifetime between [code]0.4-1.0[/code] of its original value.
@@ -205,19 +209,20 @@
Each particle's linear acceleration will vary along this [CurveTexture].
</member>
<member name="linear_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
- Maximum linear acceleration.
+ Maximum linear acceleration applied to each particle in the direction of motion.
</member>
<member name="linear_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
- Minimum linear acceleration.
+ Minimum equivalent of [member linear_accel_min].
</member>
<member name="orbit_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's orbital velocity will vary along this [CurveTexture].
</member>
<member name="orbit_velocity_max" type="float" setter="set_param_max" getter="get_param_max">
- Maximum orbit velocity.
+ Maximum orbital velocity applied to each particle. Makes the particles circle around origin. Specified in number of full rotations around origin per second.
+ Only available when [member particle_flag_disable_z] is [code]true[/code].
</member>
<member name="orbit_velocity_min" type="float" setter="set_param_min" getter="get_param_min">
- Minimum orbit velocity.
+ Minimum equivalent of [member orbit_velocity_max].
</member>
<member name="particle_flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false">
Align Y axis of particle with the direction of its velocity.
@@ -232,19 +237,19 @@
Each particle's radial acceleration will vary along this [CurveTexture].
</member>
<member name="radial_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
- Maximum radial acceleration.
+ Maximum radial acceleration applied to each particle. Makes particle accelerate away from the origin or towards it if negative.
</member>
<member name="radial_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
- Minimum radial acceleration.
+ Minimum equivalent of [member radial_accel_max].
</member>
<member name="scale_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's scale will vary along this [CurveTexture]. If a [CurveXYZTexture] is supplied instead, the scale will be separated per-axis.
</member>
<member name="scale_max" type="float" setter="set_param_max" getter="get_param_max" default="1.0">
- Maximum scale.
+ Maximum initial scale applied to each particle.
</member>
<member name="scale_min" type="float" setter="set_param_min" getter="get_param_min" default="1.0">
- Minimum scale.
+ Minimum equivalent of [member scale_max].
</member>
<member name="spread" type="float" setter="set_spread" getter="get_spread" default="45.0">
Each particle's initial direction range from [code]+spread[/code] to [code]-spread[/code] degrees.
@@ -261,10 +266,10 @@
Each particle's tangential acceleration will vary along this [CurveTexture].
</member>
<member name="tangential_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
- Maximum tangential acceleration.
+ Maximum tangential acceleration applied to each particle. Tangential acceleration is perpendicular to the particle's velocity giving the particles a swirling motion.
</member>
<member name="tangential_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
- Minimum tangential acceleration.
+ Minimum equivalent of [member tangential_accel_max].
</member>
</members>
<constants>
diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml
index a42ceba777..33e9e0c92d 100644
--- a/doc/classes/Plane.xml
+++ b/doc/classes/Plane.xml
@@ -77,15 +77,15 @@
<return type="float" />
<argument index="0" name="point" type="Vector3" />
<description>
- Returns the shortest distance from the plane to the position [code]point[/code].
+ Returns the shortest distance from the plane to the position [code]point[/code]. If the point is above the plane, the distance will be positive. If below, the distance will be negative.
</description>
</method>
<method name="has_point" qualifiers="const">
<return type="bool" />
<argument index="0" name="point" type="Vector3" />
- <argument index="1" name="epsilon" type="float" default="1e-05" />
+ <argument index="1" name="tolerance" type="float" default="1e-05" />
<description>
- Returns [code]true[/code] if [code]point[/code] is inside the plane. Comparison uses a custom minimum [code]epsilon[/code] threshold.
+ Returns [code]true[/code] if [code]point[/code] is inside the plane. Comparison uses a custom minimum [code]tolerance[/code] threshold.
</description>
</method>
<method name="intersect_3" qualifiers="const">
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 73413b379e..5da2196f29 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -182,13 +182,6 @@
Removes all items from the [PopupMenu].
</description>
</method>
- <method name="clear_item_opentype_features">
- <return type="void" />
- <argument index="0" name="index" type="int" />
- <description>
- Removes all OpenType features form the item's text.
- </description>
- </method>
<method name="get_current_index" qualifiers="const">
<return type="int" />
<description>
@@ -244,14 +237,6 @@
Returns the metadata of the specified item, which might be of any type. You can set it with [method set_item_metadata], which provides a simple way of assigning context data to items.
</description>
</method>
- <method name="get_item_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="index" type="int" />
- <argument index="1" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code] of the item's text.
- </description>
- </method>
<method name="get_item_shortcut" qualifiers="const">
<return type="Shortcut" />
<argument index="0" name="index" type="int" />
@@ -452,15 +437,6 @@
Sets the state of a multistate item. See [method add_multistate_item] for details.
</description>
</method>
- <method name="set_item_opentype_feature">
- <return type="void" />
- <argument index="0" name="index" type="int" />
- <argument index="1" name="tag" type="String" />
- <argument index="2" name="value" type="int" />
- <description>
- Sets OpenType feature [code]tag[/code] for the item's text. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
<method name="set_item_shortcut">
<return type="void" />
<argument index="0" name="index" type="int" />
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 2391cb892c..f7567133cd 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -203,6 +203,9 @@
Path to an image used as the boot splash. If left empty, the default Godot Engine splash will be displayed instead.
[b]Note:[/b] Only effective if [member application/boot_splash/show_image] is [code]true[/code].
</member>
+ <member name="application/boot_splash/minimum_display_time" type="int" setter="" getter="" default="0">
+ Minimum boot splash display time (in milliseconds). It is not recommended to set too high values for this setting.
+ </member>
<member name="application/boot_splash/show_image" type="bool" setter="" getter="" default="true">
If [code]true[/code], displays the image specified in [member application/boot_splash/image] when the engine starts. If [code]false[/code], only displays the plain color specified in [member application/boot_splash/bg_color].
</member>
@@ -494,6 +497,12 @@
<member name="debug/shapes/navigation/geometry_color" type="Color" setter="" getter="" default="Color(0.1, 1, 0.7, 0.4)">
Color of the navigation geometry, visible when "Visible Navigation" is enabled in the Debug menu.
</member>
+ <member name="debug/shapes/paths/geometry_color" type="Color" setter="" getter="" default="Color(0.1, 1, 0.7, 0.4)">
+ Color of the curve path geometry, visible when "Visible Paths" is enabled in the Debug menu.
+ </member>
+ <member name="debug/shapes/paths/geometry_width" type="float" setter="" getter="" default="2.0">
+ Line width of the curve path geometry, visible when "Visible Paths" is enabled in the Debug menu.
+ </member>
<member name="display/mouse_cursor/custom_image" type="String" setter="" getter="" default="&quot;&quot;">
Custom image for the mouse cursor (limited to 256×256).
</member>
@@ -622,7 +631,7 @@
Path to a custom [Font] resource to use as default for all GUI elements of the project.
</member>
<member name="gui/theme/default_font_antialiased" type="bool" setter="" getter="" default="true">
- If set to [code]true[/code], default font uses 8-bit anitialiased glyph rendering. See [member FontData.antialiased].
+ If set to [code]true[/code], default font uses 8-bit anitialiased glyph rendering. See [member FontFile.antialiased].
</member>
<member name="gui/theme/default_font_generate_mipmaps" type="bool" setter="" getter="" default="false">
If set to [code]true[/code], the default font will have mipmaps generated. This prevents text from looking grainy when a [Control] is scaled down, or when a [Label3D] is viewed from a long distance (if [member Label3D.texture_filter] is set to a mode that displays mipmaps).
@@ -630,7 +639,7 @@
[b]Note:[/b] This setting does not affect custom [Font]s used within the project.
</member>
<member name="gui/theme/default_font_hinting" type="int" setter="" getter="" default="1">
- Default font hinting mode. See [member FontData.hinting].
+ Default font hinting mode. See [member FontFile.hinting].
</member>
<member name="gui/theme/default_font_multichannel_signed_distance_field" type="bool" setter="" getter="" default="false">
If set to [code]true[/code], the default font will use multichannel signed distance field (MSDF) for crisp rendering at any size. Since this approach does not rely on rasterizing the font every time its size changes, this allows for resizing the font in real-time without any performance penalty. Text will also not look grainy for [Control]s that are scaled down (or for [Label3D]s viewed from a long distance).
@@ -638,7 +647,7 @@
[b]Note:[/b] This setting does not affect custom [Font]s used within the project.
</member>
<member name="gui/theme/default_font_subpixel_positioning" type="int" setter="" getter="" default="1">
- Default font glyph sub-pixel positioning mode. See [member FontData.subpixel_positioning].
+ Default font glyph sub-pixel positioning mode. See [member FontFile.subpixel_positioning].
</member>
<member name="gui/theme/default_theme_scale" type="float" setter="" getter="" default="1.0">
</member>
@@ -1889,41 +1898,41 @@
<member name="rendering/shadows/directional_shadow/size.mobile" type="int" setter="" getter="" default="2048">
Lower-end override for [member rendering/shadows/directional_shadow/size] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/shadows/directional_shadow/soft_shadow_quality" type="int" setter="" getter="" default="2">
+ <member name="rendering/shadows/directional_shadow/soft_shadow_filter_quality" type="int" setter="" getter="" default="2">
Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
[b]Note:[/b] The Soft Very Low setting will automatically multiply [i]constant[/i] shadow blur by 0.75x to reduce the amount of noise visible. This automatic blur change only affects the constant blur factor defined in [member Light3D.shadow_blur], not the variable blur performed by [DirectionalLight3D]s' [member Light3D.light_angular_distance].
[b]Note:[/b] The Soft High and Soft Ultra settings will automatically multiply [i]constant[/i] shadow blur by 1.5× and 2× respectively to make better use of the increased sample count. This increased blur also improves stability of dynamic object shadows.
</member>
- <member name="rendering/shadows/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
- Lower-end override for [member rendering/shadows/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/shadows/directional_shadow/soft_shadow_filter_quality.mobile" type="int" setter="" getter="" default="0">
+ Lower-end override for [member rendering/shadows/directional_shadow/soft_shadow_filter_quality] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/shadows/shadow_atlas/16_bits" type="bool" setter="" getter="" default="true">
+ <member name="rendering/shadows/positional_shadow/atlas_16_bits" type="bool" setter="" getter="" default="true">
</member>
- <member name="rendering/shadows/shadow_atlas/quadrant_0_subdiv" type="int" setter="" getter="" default="2">
+ <member name="rendering/shadows/positional_shadow/atlas_quadrant_0_subdiv" type="int" setter="" getter="" default="2">
Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
</member>
- <member name="rendering/shadows/shadow_atlas/quadrant_1_subdiv" type="int" setter="" getter="" default="2">
+ <member name="rendering/shadows/positional_shadow/atlas_quadrant_1_subdiv" type="int" setter="" getter="" default="2">
Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
</member>
- <member name="rendering/shadows/shadow_atlas/quadrant_2_subdiv" type="int" setter="" getter="" default="3">
+ <member name="rendering/shadows/positional_shadow/atlas_quadrant_2_subdiv" type="int" setter="" getter="" default="3">
Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
</member>
- <member name="rendering/shadows/shadow_atlas/quadrant_3_subdiv" type="int" setter="" getter="" default="4">
+ <member name="rendering/shadows/positional_shadow/atlas_quadrant_3_subdiv" type="int" setter="" getter="" default="4">
Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
</member>
- <member name="rendering/shadows/shadow_atlas/size" type="int" setter="" getter="" default="4096">
+ <member name="rendering/shadows/positional_shadow/atlas_size" type="int" setter="" getter="" default="4096">
Size for shadow atlas (used for OmniLights and SpotLights). See documentation.
</member>
- <member name="rendering/shadows/shadow_atlas/size.mobile" type="int" setter="" getter="" default="2048">
- Lower-end override for [member rendering/shadows/shadow_atlas/size] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/shadows/positional_shadow/atlas_size.mobile" type="int" setter="" getter="" default="2048">
+ Lower-end override for [member rendering/shadows/positional_shadow/atlas_size] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/shadows/shadows/soft_shadow_quality" type="int" setter="" getter="" default="2">
+ <member name="rendering/shadows/positional_shadow/soft_shadow_filter_quality" type="int" setter="" getter="" default="2">
Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
[b]Note:[/b] The Soft Very Low setting will automatically multiply [i]constant[/i] shadow blur by 0.75x to reduce the amount of noise visible. This automatic blur change only affects the constant blur factor defined in [member Light3D.shadow_blur], not the variable blur performed by [DirectionalLight3D]s' [member Light3D.light_angular_distance].
[b]Note:[/b] The Soft High and Soft Ultra settings will automatically multiply shadow blur by 1.5× and 2× respectively to make better use of the increased sample count. This increased blur also improves stability of dynamic object shadows.
</member>
- <member name="rendering/shadows/shadows/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
- Lower-end override for [member rendering/shadows/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/shadows/positional_shadow/soft_shadow_filter_quality.mobile" type="int" setter="" getter="" default="0">
+ Lower-end override for [member rendering/shadows/positional_shadow/soft_shadow_filter_quality] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/textures/decals/filter" type="int" setter="" getter="" default="3">
</member>
@@ -1959,6 +1968,12 @@
If [code]true[/code], the texture importer will import VRAM-compressed textures using the S3 Texture Compression algorithm. This algorithm is only supported on desktop platforms and consoles.
[b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]).
</member>
+ <member name="rendering/vrs/mode" type="int" setter="" getter="" default="0">
+ Set the default Variable Rate Shading (VRS) mode for the main viewport. See [member Viewport.vrs_mode] to change this at runtime, and [enum Viewport.VRSMode] for possible values.
+ </member>
+ <member name="rendering/vrs/texture" type="String" setter="" getter="" default="&quot;&quot;">
+ If [member rendering/vrs/mode] is set to texture, this is the path to default texture loaded as the VRS image.
+ </member>
<member name="rendering/vulkan/descriptor_pools/max_descriptors_per_pool" type="int" setter="" getter="" default="64">
</member>
<member name="rendering/vulkan/rendering/back_end" type="int" setter="" getter="" default="0">
@@ -1971,6 +1986,12 @@
</member>
<member name="rendering/vulkan/staging_buffer/texture_upload_region_size_px" type="int" setter="" getter="" default="64">
</member>
+ <member name="threading/worker_pool/low_priority_thread_ratio" type="float" setter="" getter="" default="0.3">
+ </member>
+ <member name="threading/worker_pool/max_threads" type="int" setter="" getter="" default="-1">
+ </member>
+ <member name="threading/worker_pool/use_system_threads_for_low_priority_tasks" type="bool" setter="" getter="" default="true">
+ </member>
<member name="xr/openxr/default_action_map" type="String" setter="" getter="" default="&quot;res://openxr_action_map.tres&quot;">
Action map configuration to load by default.
</member>
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index 0d121a29d2..6248394b1a 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -395,7 +395,7 @@
<description>
</description>
</method>
- <method name="limit_get">
+ <method name="limit_get" qualifiers="const">
<return type="int" />
<argument index="0" name="limit" type="int" enum="RenderingDevice.Limit" />
<description>
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index d92121a950..6199c7b4e6 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -890,7 +890,7 @@
<description>
</description>
</method>
- <method name="directional_shadow_quality_set">
+ <method name="directional_soft_shadow_filter_set_quality">
<return type="void" />
<argument index="0" name="quality" type="int" enum="RenderingServer.ShadowQuality" />
<description>
@@ -2519,6 +2519,12 @@
If [code]true[/code], particles use local coordinates. If [code]false[/code] they use global coordinates. Equivalent to [member GPUParticles3D.local_coords].
</description>
</method>
+ <method name="positional_soft_shadow_filter_set_quality">
+ <return type="void" />
+ <argument index="0" name="quality" type="int" enum="RenderingServer.ShadowQuality" />
+ <description>
+ </description>
+ </method>
<method name="reflection_probe_create">
<return type="RID" />
<description>
@@ -2753,12 +2759,6 @@
[b]Note:[/b] If the sampler array is used use [code]index[/code] to access the specified texture.
</description>
</method>
- <method name="shadows_quality_set">
- <return type="void" />
- <argument index="0" name="quality" type="int" enum="RenderingServer.ShadowQuality" />
- <description>
- </description>
- </method>
<method name="skeleton_allocate_data">
<return type="void" />
<argument index="0" name="skeleton" type="RID" />
@@ -3220,6 +3220,25 @@
Sets the viewport's parent to another viewport.
</description>
</method>
+ <method name="viewport_set_positional_shadow_atlas_quadrant_subdivision">
+ <return type="void" />
+ <argument index="0" name="viewport" type="RID" />
+ <argument index="1" name="quadrant" type="int" />
+ <argument index="2" name="subdivision" type="int" />
+ <description>
+ Sets the shadow atlas quadrant's subdivision.
+ </description>
+ </method>
+ <method name="viewport_set_positional_shadow_atlas_size">
+ <return type="void" />
+ <argument index="0" name="viewport" type="RID" />
+ <argument index="1" name="size" type="int" />
+ <argument index="2" name="use_16_bits" type="bool" default="false" />
+ <description>
+ Sets the size of the shadow atlas's images (used for omni and spot lights). The value will be rounded up to the nearest power of 2.
+ [b]Note:[/b] If this is set to [code]0[/code], no shadows will be visible at all (including directional shadows).
+ </description>
+ </method>
<method name="viewport_set_render_direct_to_screen">
<return type="void" />
<argument index="0" name="viewport" type="RID" />
@@ -3269,24 +3288,6 @@
<description>
</description>
</method>
- <method name="viewport_set_shadow_atlas_quadrant_subdivision">
- <return type="void" />
- <argument index="0" name="viewport" type="RID" />
- <argument index="1" name="quadrant" type="int" />
- <argument index="2" name="subdivision" type="int" />
- <description>
- Sets the shadow atlas quadrant's subdivision.
- </description>
- </method>
- <method name="viewport_set_shadow_atlas_size">
- <return type="void" />
- <argument index="0" name="viewport" type="RID" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="use_16_bits" type="bool" default="false" />
- <description>
- Sets the size of the shadow atlas's images (used for omni and spot lights). The value will be rounded up to the nearest power of 2.
- </description>
- </method>
<method name="viewport_set_size">
<return type="void" />
<argument index="0" name="viewport" type="RID" />
@@ -3356,6 +3357,22 @@
If [code]true[/code], the viewport uses augmented or virtual reality technologies. See [XRInterface].
</description>
</method>
+ <method name="viewport_set_vrs_mode">
+ <return type="void" />
+ <argument index="0" name="viewport" type="RID" />
+ <argument index="1" name="mode" type="int" enum="RenderingServer.ViewportVRSMode" />
+ <description>
+ Sets the Variable Rate Shading (VRS) mode for the viewport. Note, if hardware does not support VRS this property is ignored.
+ </description>
+ </method>
+ <method name="viewport_set_vrs_texture">
+ <return type="void" />
+ <argument index="0" name="viewport" type="RID" />
+ <argument index="1" name="texture" type="RID" />
+ <description>
+ Texture to use when the VRS mode is set to [constant RenderingServer.VIEWPORT_VRS_TEXTURE].
+ </description>
+ </method>
<method name="visibility_notifier_create">
<return type="RID" />
<description>
@@ -4115,6 +4132,18 @@
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_MOTION_VECTORS" value="25" enum="ViewportDebugDraw">
</constant>
+ <constant name="VIEWPORT_VRS_DISABLED" value="0" enum="ViewportVRSMode">
+ VRS is disabled.
+ </constant>
+ <constant name="VIEWPORT_VRS_TEXTURE" value="1" enum="ViewportVRSMode">
+ VRS uses a texture. Note, for stereoscopic use a texture atlas with a texture for each view.
+ </constant>
+ <constant name="VIEWPORT_VRS_XR" value="2" enum="ViewportVRSMode">
+ VRS texture is supplied by the primary [XRInterface].
+ </constant>
+ <constant name="VIEWPORT_VRS_MAX" value="3" enum="ViewportVRSMode">
+ Represents the size of the [enum ViewportVRSMode] enum.
+ </constant>
<constant name="SKY_MODE_AUTOMATIC" value="0" enum="SkyMode">
</constant>
<constant name="SKY_MODE_QUALITY" value="1" enum="SkyMode">
diff --git a/doc/classes/ResourceFormatLoader.xml b/doc/classes/ResourceFormatLoader.xml
index 36b64f5a86..fef94b5f3b 100644
--- a/doc/classes/ResourceFormatLoader.xml
+++ b/doc/classes/ResourceFormatLoader.xml
@@ -17,6 +17,12 @@
<description>
</description>
</method>
+ <method name="_get_classes_used" qualifiers="virtual const">
+ <return type="PackedStringArray" />
+ <argument index="0" name="path" type="String" />
+ <description>
+ </description>
+ </method>
<method name="_get_dependencies" qualifiers="virtual const">
<return type="PackedStringArray" />
<argument index="0" name="path" type="String" />
diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml
index 1ffb0dba5c..dd52d09750 100644
--- a/doc/classes/ResourceLoader.xml
+++ b/doc/classes/ResourceLoader.xml
@@ -6,11 +6,21 @@
<description>
Singleton used to load resource files from the filesystem.
It uses the many [ResourceFormatLoader] classes registered in the engine (either built-in or from a plugin) to load files into memory and convert them to a format that can be used by the engine.
+ [b]Note:[/b] You have to import the files into the engine first to load them using [method load]. If you want to load [Image]s at run-time, you may use [method Image.load]. If you want to import audio files, you can use the snippet described in [member AudioStreamMP3.data].
</description>
<tutorials>
<link title="OS Test Demo">https://godotengine.org/asset-library/asset/677</link>
</tutorials>
<methods>
+ <method name="add_resource_format_loader">
+ <return type="void" />
+ <argument index="0" name="format_loader" type="ResourceFormatLoader" />
+ <argument index="1" name="at_front" type="bool" default="false" />
+ <description>
+ Registers a new [ResourceFormatLoader]. The ResourceLoader will use the ResourceFormatLoader as described in [method load].
+ This method is performed implicitly for ResourceFormatLoaders written in GDScript (see [ResourceFormatLoader] for more information).
+ </description>
+ </method>
<method name="exists">
<return type="bool" />
<argument index="0" name="path" type="String" />
@@ -89,6 +99,13 @@
Loads the resource using threads. If [code]use_sub_threads[/code] is [code]true[/code], multiple threads will be used to load the resource, which makes loading faster, but may affect the main thread (and thus cause game slowdowns).
</description>
</method>
+ <method name="remove_resource_format_loader">
+ <return type="void" />
+ <argument index="0" name="format_loader" type="ResourceFormatLoader" />
+ <description>
+ Unregisters the given [ResourceFormatLoader].
+ </description>
+ </method>
<method name="set_abort_on_missing_resources">
<return type="void" />
<argument index="0" name="abort" type="bool" />
diff --git a/doc/classes/ResourceSaver.xml b/doc/classes/ResourceSaver.xml
index a029fb9acf..240c72a131 100644
--- a/doc/classes/ResourceSaver.xml
+++ b/doc/classes/ResourceSaver.xml
@@ -10,6 +10,15 @@
<tutorials>
</tutorials>
<methods>
+ <method name="add_resource_format_saver">
+ <return type="void" />
+ <argument index="0" name="format_saver" type="ResourceFormatSaver" />
+ <argument index="1" name="at_front" type="bool" default="false" />
+ <description>
+ Registers a new [ResourceFormatSaver]. The ResourceSaver will use the ResourceFormatSaver as described in [method save].
+ This method is performed implicitly for ResourceFormatSavers written in GDScript (see [ResourceFormatSaver] for more information).
+ </description>
+ </method>
<method name="get_recognized_extensions">
<return type="PackedStringArray" />
<argument index="0" name="type" type="Resource" />
@@ -17,11 +26,18 @@
Returns the list of extensions available for saving a resource of a given type.
</description>
</method>
+ <method name="remove_resource_format_saver">
+ <return type="void" />
+ <argument index="0" name="format_saver" type="ResourceFormatSaver" />
+ <description>
+ Unregisters the given [ResourceFormatSaver].
+ </description>
+ </method>
<method name="save">
<return type="int" enum="Error" />
<argument index="0" name="path" type="String" />
<argument index="1" name="resource" type="Resource" />
- <argument index="2" name="flags" type="int" default="0" />
+ <argument index="2" name="flags" type="int" enum="ResourceSaver.SaverFlags" default="0" />
<description>
Saves a resource to disk to the given path, using a [ResourceFormatSaver] that recognizes the resource object.
The [code]flags[/code] bitmask can be specified to customize the save behavior using [enum SaverFlags] flags.
@@ -30,28 +46,28 @@
</method>
</methods>
<constants>
- <constant name="FLAG_NONE" value="0" enum="SaverFlags">
+ <constant name="FLAG_NONE" value="0" enum="SaverFlags" is_bitfield="true">
No resource saving option.
</constant>
- <constant name="FLAG_RELATIVE_PATHS" value="1" enum="SaverFlags">
+ <constant name="FLAG_RELATIVE_PATHS" value="1" enum="SaverFlags" is_bitfield="true">
Save the resource with a path relative to the scene which uses it.
</constant>
- <constant name="FLAG_BUNDLE_RESOURCES" value="2" enum="SaverFlags">
+ <constant name="FLAG_BUNDLE_RESOURCES" value="2" enum="SaverFlags" is_bitfield="true">
Bundles external resources.
</constant>
- <constant name="FLAG_CHANGE_PATH" value="4" enum="SaverFlags">
+ <constant name="FLAG_CHANGE_PATH" value="4" enum="SaverFlags" is_bitfield="true">
Changes the [member Resource.resource_path] of the saved resource to match its new location.
</constant>
- <constant name="FLAG_OMIT_EDITOR_PROPERTIES" value="8" enum="SaverFlags">
+ <constant name="FLAG_OMIT_EDITOR_PROPERTIES" value="8" enum="SaverFlags" is_bitfield="true">
Do not save editor-specific metadata (identified by their [code]__editor[/code] prefix).
</constant>
- <constant name="FLAG_SAVE_BIG_ENDIAN" value="16" enum="SaverFlags">
+ <constant name="FLAG_SAVE_BIG_ENDIAN" value="16" enum="SaverFlags" is_bitfield="true">
Save as big endian (see [member File.big_endian]).
</constant>
- <constant name="FLAG_COMPRESS" value="32" enum="SaverFlags">
+ <constant name="FLAG_COMPRESS" value="32" enum="SaverFlags" is_bitfield="true">
Compress the resource on save using [constant File.COMPRESSION_ZSTD]. Only available for binary resource types.
</constant>
- <constant name="FLAG_REPLACE_SUBRESOURCE_PATHS" value="64" enum="SaverFlags">
+ <constant name="FLAG_REPLACE_SUBRESOURCE_PATHS" value="64" enum="SaverFlags" is_bitfield="true">
Take over the paths of the saved subresources (see [method Resource.take_over_path]).
</constant>
</constants>
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index 1294e5b58a..3c9e9b1bfc 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -276,18 +276,10 @@
Adds a [code][font][/code] tag to the tag stack. Overrides default fonts for its duration.
</description>
</method>
- <method name="push_font_features">
- <return type="void" />
- <argument index="0" name="opentype_features" type="Dictionary" />
- <description>
- Adds a [code][ot_feature][/code] tag to the tag stack. Overrides default OpenType font feature for its duration.
- </description>
- </method>
<method name="push_font_size">
<return type="void" />
<argument index="0" name="font_size" type="int" />
<description>
- Adds a [code][font_size][/code] tag to the tag stack. Overrides default font size for its duration.
</description>
</method>
<method name="push_hint">
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index c6b80f171a..cf6ab977db 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -221,6 +221,9 @@
<member name="debug_navigation_hint" type="bool" setter="set_debug_navigation_hint" getter="is_debugging_navigation_hint" default="false">
If [code]true[/code], navigation polygons will be visible when running the game from the editor for debugging purposes.
</member>
+ <member name="debug_paths_hint" type="bool" setter="set_debug_paths_hint" getter="is_debugging_paths_hint" default="false">
+ If [code]true[/code], curves from [Path2D] and [Path3D] nodes will be visible when running the game from the editor for debugging purposes.
+ </member>
<member name="edited_scene_root" type="Node" setter="set_edited_scene_root" getter="get_edited_scene_root">
The root of the edited scene.
</member>
diff --git a/doc/classes/ScriptCreateDialog.xml b/doc/classes/ScriptCreateDialog.xml
index e21fac2d32..79ee95719d 100644
--- a/doc/classes/ScriptCreateDialog.xml
+++ b/doc/classes/ScriptCreateDialog.xml
@@ -40,6 +40,7 @@
</methods>
<members>
<member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" overrides="AcceptDialog" default="false" />
+ <member name="ok_button_text" type="String" setter="set_ok_button_text" getter="get_ok_button_text" overrides="AcceptDialog" default="&quot;Create&quot;" />
<member name="title" type="String" setter="set_title" getter="get_title" overrides="Window" default="&quot;Attach Node Script&quot;" />
</members>
<signals>
diff --git a/doc/classes/ScriptLanguageExtension.xml b/doc/classes/ScriptLanguageExtension.xml
index 0f757cf806..45d4cf44fa 100644
--- a/doc/classes/ScriptLanguageExtension.xml
+++ b/doc/classes/ScriptLanguageExtension.xml
@@ -174,6 +174,11 @@
<description>
</description>
</method>
+ <method name="_get_public_annotations" qualifiers="virtual const">
+ <return type="Dictionary[]" />
+ <description>
+ </description>
+ </method>
<method name="_get_public_constants" qualifiers="virtual const">
<return type="Dictionary" />
<description>
@@ -378,7 +383,9 @@
</constant>
<constant name="LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE" value="7" enum="LookupResultType">
</constant>
- <constant name="LOOKUP_RESULT_MAX" value="8" enum="LookupResultType">
+ <constant name="LOOKUP_RESULT_CLASS_ANNOTATION" value="8" enum="LookupResultType">
+ </constant>
+ <constant name="LOOKUP_RESULT_MAX" value="9" enum="LookupResultType">
</constant>
<constant name="LOCATION_LOCAL" value="0" enum="CodeCompletionLocation">
The option is local to the location of the code completion query - e.g. a local variable.
diff --git a/doc/classes/SkeletonProfile.xml b/doc/classes/SkeletonProfile.xml
new file mode 100644
index 0000000000..a7f5f7a0a6
--- /dev/null
+++ b/doc/classes/SkeletonProfile.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="SkeletonProfile" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ Profile of a virtual skeleton used as a target for retargeting.
+ </brief_description>
+ <description>
+ This resource is used in [EditorScenePostImport]. Some parameters are referring to bones in [Skeleton3D], [Skin], [Animation], and some other nodes are rewritten based on the parameters of [SkeletonProfile].
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="find_bone" qualifiers="const">
+ <return type="int" />
+ <argument index="0" name="bone_name" type="StringName" />
+ <description>
+ Returns the bone index that matches [code]bone_name[/code] as its name.
+ </description>
+ </method>
+ <method name="get_bone_name" qualifiers="const">
+ <return type="StringName" />
+ <argument index="0" name="bone_idx" type="int" />
+ <description>
+ Returns the name of the bone at [code]bone_idx[/code] that will be the key name in the [BoneMap].
+ In the retargeting process, the returned bone name is the bone name of the target skeleton.
+ </description>
+ </method>
+ <method name="get_bone_parent" qualifiers="const">
+ <return type="StringName" />
+ <argument index="0" name="bone_idx" type="int" />
+ <description>
+ Returns the name of the bone which is the parent to the bone at [code]bone_idx[/code]. The result is empty if the bone has no parent.
+ </description>
+ </method>
+ <method name="get_bone_tail" qualifiers="const">
+ <return type="StringName" />
+ <argument index="0" name="bone_idx" type="int" />
+ <description>
+ Returns the name of the bone which is the tail of the bone at [code]bone_idx[/code].
+ </description>
+ </method>
+ <method name="get_group" qualifiers="const">
+ <return type="StringName" />
+ <argument index="0" name="bone_idx" type="int" />
+ <description>
+ Returns the group of the bone at [code]bone_idx[/code].
+ </description>
+ </method>
+ <method name="get_group_name" qualifiers="const">
+ <return type="StringName" />
+ <argument index="0" name="group_idx" type="int" />
+ <description>
+ Returns the name of the group at [code]group_idx[/code] that will be the drawing group in the [BoneMap] editor.
+ </description>
+ </method>
+ <method name="get_handle_offset" qualifiers="const">
+ <return type="Vector2" />
+ <argument index="0" name="bone_idx" type="int" />
+ <description>
+ Returns the offset of the bone at [code]bone_idx[/code] that will be the button position in the [BoneMap] editor.
+ This is the offset with origin at the top left corner of the square.
+ </description>
+ </method>
+ <method name="get_reference_pose" qualifiers="const">
+ <return type="Transform3D" />
+ <argument index="0" name="bone_idx" type="int" />
+ <description>
+ Returns the reference pose transform for bone [code]bone_idx[/code].
+ </description>
+ </method>
+ <method name="get_tail_direction" qualifiers="const">
+ <return type="int" enum="SkeletonProfile.TailDirection" />
+ <argument index="0" name="bone_idx" type="int" />
+ <description>
+ Returns the tail direction of the bone at [code]bone_idx[/code].
+ </description>
+ </method>
+ <method name="get_texture" qualifiers="const">
+ <return type="Texture2D" />
+ <argument index="0" name="group_idx" type="int" />
+ <description>
+ Returns the texture of the group at [code]group_idx[/code] that will be the drawing group background image in the [BoneMap] editor.
+ </description>
+ </method>
+ <method name="set_bone_name">
+ <return type="void" />
+ <argument index="0" name="bone_idx" type="int" />
+ <argument index="1" name="bone_name" type="StringName" />
+ <description>
+ Sets the name of the bone at [code]bone_idx[/code] that will be the key name in the [BoneMap].
+ In the retargeting process, the setting bone name is the bone name of the target skeleton.
+ </description>
+ </method>
+ <method name="set_bone_parent">
+ <return type="void" />
+ <argument index="0" name="bone_idx" type="int" />
+ <argument index="1" name="bone_parent" type="StringName" />
+ <description>
+ Sets the bone with name [code]bone_parent[/code] as the parent of the bone at [code]bone_idx[/code]. If an empty string is passed, then the bone has no parent.
+ </description>
+ </method>
+ <method name="set_bone_tail">
+ <return type="void" />
+ <argument index="0" name="bone_idx" type="int" />
+ <argument index="1" name="bone_tail" type="StringName" />
+ <description>
+ Sets the bone with name [code]bone_tail[/code] as the tail of the bone at [code]bone_idx[/code].
+ </description>
+ </method>
+ <method name="set_group">
+ <return type="void" />
+ <argument index="0" name="bone_idx" type="int" />
+ <argument index="1" name="group" type="StringName" />
+ <description>
+ Sets the group of the bone at [code]bone_idx[/code].
+ </description>
+ </method>
+ <method name="set_group_name">
+ <return type="void" />
+ <argument index="0" name="group_idx" type="int" />
+ <argument index="1" name="group_name" type="StringName" />
+ <description>
+ Sets the name of the group at [code]group_idx[/code] that will be the drawing group in the [BoneMap] editor.
+ </description>
+ </method>
+ <method name="set_handle_offset">
+ <return type="void" />
+ <argument index="0" name="bone_idx" type="int" />
+ <argument index="1" name="handle_offset" type="Vector2" />
+ <description>
+ Sets the offset of the bone at [code]bone_idx[/code] that will be the button position in the [BoneMap] editor.
+ This is the offset with origin at the top left corner of the square.
+ </description>
+ </method>
+ <method name="set_reference_pose">
+ <return type="void" />
+ <argument index="0" name="bone_idx" type="int" />
+ <argument index="1" name="bone_name" type="Transform3D" />
+ <description>
+ Sets the reference pose transform for bone [code]bone_idx[/code].
+ </description>
+ </method>
+ <method name="set_tail_direction">
+ <return type="void" />
+ <argument index="0" name="bone_idx" type="int" />
+ <argument index="1" name="tail_direction" type="int" enum="SkeletonProfile.TailDirection" />
+ <description>
+ Sets the tail direction of the bone at [code]bone_idx[/code].
+ [b]Note:[/b] This only specifies the method of calculation. The actual coordinates required should be stored in an external skeleton, so the calculation itself needs to be done externally.
+ </description>
+ </method>
+ <method name="set_texture">
+ <return type="void" />
+ <argument index="0" name="group_idx" type="int" />
+ <argument index="1" name="texture" type="Texture2D" />
+ <description>
+ Sets the texture of the group at [code]group_idx[/code] that will be the drawing group background image in the [BoneMap] editor.
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="bone_size" type="int" setter="set_bone_size" getter="get_bone_size" default="0">
+ </member>
+ <member name="group_size" type="int" setter="set_group_size" getter="get_group_size" default="0">
+ </member>
+ </members>
+ <signals>
+ <signal name="profile_updated">
+ <description>
+ This signal is emitted when change the value in profile. This is used to update key name in the [BoneMap] and to redraw the [BoneMap] editor.
+ [b]Note[/b]: This signal is not connected directly to editor to simplify the reference, instead it is passed on to editor through the [BoneMap].
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ <constant name="TAIL_DIRECTION_AVERAGE_CHILDREN" value="0" enum="TailDirection">
+ Direction to the average coordinates of bone children.
+ </constant>
+ <constant name="TAIL_DIRECTION_SPECIFIC_CHILD" value="1" enum="TailDirection">
+ Direction to the coordinates of specified bone child.
+ </constant>
+ <constant name="TAIL_DIRECTION_END" value="2" enum="TailDirection">
+ Direction is not calculated.
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/SkeletonProfileHumanoid.xml b/doc/classes/SkeletonProfileHumanoid.xml
new file mode 100644
index 0000000000..065184244e
--- /dev/null
+++ b/doc/classes/SkeletonProfileHumanoid.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="SkeletonProfileHumanoid" inherits="SkeletonProfile" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ </brief_description>
+ <description>
+ A [SkeletonProfile] as a preset that is optimized for the human form. This exists for standardization, so all parameters are read-only.
+ </description>
+ <tutorials>
+ </tutorials>
+ <members>
+ <member name="bone_size" type="int" setter="set_bone_size" getter="get_bone_size" overrides="SkeletonProfile" default="56" />
+ <member name="group_size" type="int" setter="set_group_size" getter="get_group_size" overrides="SkeletonProfile" default="4" />
+ </members>
+</class>
diff --git a/doc/classes/SpriteFrames.xml b/doc/classes/SpriteFrames.xml
index b0d1e1efcf..0d423630d4 100644
--- a/doc/classes/SpriteFrames.xml
+++ b/doc/classes/SpriteFrames.xml
@@ -130,9 +130,4 @@
</description>
</method>
</methods>
- <members>
- <member name="frames" type="Array" setter="_set_frames" getter="_get_frames">
- Compatibility property, always equals to an empty array.
- </member>
- </members>
</class>
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index f4d453700c..9f197dae02 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -180,7 +180,22 @@
<argument index="0" name="values" type="Variant" />
<argument index="1" name="placeholder" type="String" default="&quot;{_}&quot;" />
<description>
- Formats the string by replacing all occurrences of [code]placeholder[/code] with [code]values[/code].
+ Formats the string by replacing all occurrences of [code]placeholder[/code] with the elements of [code]values[/code].
+ [code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in [code]placeholder[/code] will be replaced with the corresponding keys in advance. Array elements use their index as keys.
+ [codeblock]
+ # Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is named after it.
+ var use_array_values = "Waiting for {0} is a play by {1}, and {0} Engine is named after it."
+ print(use_array_values.format(["Godot", "Samuel Beckett"]))
+
+ # Prints: User 42 is Godot.
+ print("User {id} is {name}.".format({"id": 42, "name": "Godot"}))
+ [/codeblock]
+ Some additional handling is performed when [code]values[/code] is an array. If [code]placeholder[/code] does not contain an underscore, the elements of the array will be used to replace one occurrence of the placeholder in turn; If an array element is another 2-element array, it'll be interpreted as a key-value pair.
+ [codeblock]
+ # Prints: User 42 is Godot.
+ print("User {} is {}.".format([42, "Godot"], "{}"))
+ print("User {id} is {name}.".format([["id", 42], ["name", "Godot"]]))
+ [/codeblock]
</description>
</method>
<method name="get_base_dir" qualifiers="const">
diff --git a/doc/classes/StyleBox.xml b/doc/classes/StyleBox.xml
index 74d02a84fd..d863e3c652 100644
--- a/doc/classes/StyleBox.xml
+++ b/doc/classes/StyleBox.xml
@@ -46,8 +46,8 @@
<argument index="0" name="canvas_item" type="RID" />
<argument index="1" name="rect" type="Rect2" />
<description>
- Draws this stylebox using a [CanvasItem] with given [RID].
- You can get a [RID] value using [method Object.get_instance_id] on a [CanvasItem]-derived node.
+ Draws this stylebox using a canvas item identified by the given [RID].
+ The [RID] value can either be the result of [method CanvasItem.get_canvas_item] called on an existing [CanvasItem]-derived node, or directly from creating a canvas item in the [RenderingServer] with [method RenderingServer.canvas_item_create].
</description>
</method>
<method name="get_center_size" qualifiers="const">
diff --git a/doc/classes/TabBar.xml b/doc/classes/TabBar.xml
index a8ed0d4286..79d52b70fb 100644
--- a/doc/classes/TabBar.xml
+++ b/doc/classes/TabBar.xml
@@ -17,13 +17,6 @@
Adds a new tab.
</description>
</method>
- <method name="clear_tab_opentype_features">
- <return type="void" />
- <argument index="0" name="tab_idx" type="int" />
- <description>
- Removes all OpenType features from the tab title.
- </description>
- </method>
<method name="ensure_tab_visible">
<return type="void" />
<argument index="0" name="idx" type="int" />
@@ -77,14 +70,6 @@
Returns the number of hidden tabs offsetted to the left.
</description>
</method>
- <method name="get_tab_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="tab_idx" type="int" />
- <argument index="1" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code] of the tab title.
- </description>
- </method>
<method name="get_tab_rect" qualifiers="const">
<return type="Rect2" />
<argument index="0" name="tab_idx" type="int" />
@@ -175,15 +160,6 @@
Sets language code of tab title used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
</description>
</method>
- <method name="set_tab_opentype_feature">
- <return type="void" />
- <argument index="0" name="tab_idx" type="int" />
- <argument index="1" name="tag" type="String" />
- <argument index="2" name="values" type="int" />
- <description>
- Sets OpenType feature [code]tag[/code] for the tab title. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
<method name="set_tab_text_direction">
<return type="void" />
<argument index="0" name="tab_idx" type="int" />
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 2de185903d..18a4893f03 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -85,12 +85,6 @@
Performs a full reset of [TextEdit], including undo history.
</description>
</method>
- <method name="clear_opentype_features">
- <return type="void" />
- <description>
- Removes all OpenType features.
- </description>
- </method>
<method name="clear_undo_history">
<return type="void" />
<description>
@@ -355,13 +349,6 @@
Returns the count to the next visible line from [code]line[/code] to [code]line + visible_amount[/code]. Can also count backwards. For example if a [TextEdit] has 5 lines with lines 2 and 3 hidden, calling this with [code]line = 1, visible_amount = 1[/code] would return 3.
</description>
</method>
- <method name="get_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code].
- </description>
- </method>
<method name="get_pos_at_line_column" qualifiers="const">
<return type="Vector2i" />
<argument index="0" name="line" type="int" />
@@ -859,14 +846,6 @@
Sets the text for [code]gutter[/code] on [code]line[/code].
</description>
</method>
- <method name="set_opentype_feature">
- <return type="void" />
- <argument index="0" name="tag" type="String" />
- <argument index="1" name="value" type="int" />
- <description>
- Sets OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
<method name="set_overtype_mode_enabled">
<return type="void" />
<argument index="0" name="enabled" type="bool" />
@@ -998,13 +977,16 @@
<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>
+ <member name="scroll_fit_content_height" type="bool" setter="set_fit_content_height_enabled" getter="is_fit_content_height_enabled" default="false">
+ If [code]true[/code], [TextEdit] will disable vertical scroll and fit minimum height to the number of visible lines.
+ </member>
<member name="scroll_horizontal" type="int" setter="set_h_scroll" getter="get_h_scroll" default="0">
If there is a horizontal scrollbar, this determines the current horizontal scroll value in pixels.
</member>
<member name="scroll_past_end_of_file" type="bool" setter="set_scroll_past_end_of_file_enabled" getter="is_scroll_past_end_of_file_enabled" default="false">
Allow scrolling past the last line into "virtual" space.
</member>
- <member name="scroll_smooth" type="bool" setter="set_smooth_scroll_enable" getter="is_smooth_scroll_enabled" default="false">
+ <member name="scroll_smooth" type="bool" setter="set_smooth_scroll_enabled" getter="is_smooth_scroll_enabled" default="false">
Scroll smoothly over the text rather then jumping to the next location.
</member>
<member name="scroll_v_scroll_speed" type="float" setter="set_v_scroll_speed" getter="get_v_scroll_speed" default="80.0">
diff --git a/doc/classes/TextLine.xml b/doc/classes/TextLine.xml
index f154cbbe9a..601650db2e 100644
--- a/doc/classes/TextLine.xml
+++ b/doc/classes/TextLine.xml
@@ -22,11 +22,10 @@
<method name="add_string">
<return type="bool" />
<argument index="0" name="text" type="String" />
- <argument index="1" name="fonts" type="Font" />
- <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" />
+ <argument index="1" name="font" type="Font" />
+ <argument index="2" name="font_size" type="int" />
+ <argument index="3" name="language" type="String" default="&quot;&quot;" />
+ <argument index="4" name="meta" type="Variant" default="null" />
<description>
Adds text span and font to draw it.
</description>
@@ -149,8 +148,8 @@
<member name="direction" type="int" setter="set_direction" getter="get_direction" enum="TextServer.Direction" default="0">
Text writing direction.
</member>
- <member name="flags" type="int" setter="set_flags" getter="get_flags" default="3">
- Line Alignment rules. For more info see [TextServer].
+ <member name="flags" type="int" setter="set_flags" getter="get_flags" enum="TextServer.JustificationFlag" default="3">
+ Line alignment rules. For more info see [TextServer].
</member>
<member name="orientation" type="int" setter="set_orientation" getter="get_orientation" enum="TextServer.Orientation" default="0">
Text orientation.
diff --git a/doc/classes/TextMesh.xml b/doc/classes/TextMesh.xml
index 5a1501d2ca..17a0ca32e4 100644
--- a/doc/classes/TextMesh.xml
+++ b/doc/classes/TextMesh.xml
@@ -10,29 +10,6 @@
</description>
<tutorials>
</tutorials>
- <methods>
- <method name="clear_opentype_features">
- <return type="void" />
- <description>
- Removes all OpenType features.
- </description>
- </method>
- <method name="get_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code].
- </description>
- </method>
- <method name="set_opentype_feature">
- <return type="void" />
- <argument index="0" name="tag" type="String" />
- <argument index="1" name="value" type="int" />
- <description>
- Returns OpenType feature [code]tag[/code]. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url].
- </description>
- </method>
- </methods>
<members>
<member name="curve_step" type="float" setter="set_curve_step" getter="get_curve_step" default="0.5">
Step (in pixels) used to approximate Bézier curves.
@@ -41,7 +18,7 @@
Depths of the mesh, if set to [code]0.0[/code] only front surface, is generated, and UV layout is changed to use full texture for the front face only.
</member>
<member name="font" type="Font" setter="set_font" getter="get_font">
- [Font] used for the [TextMesh]'s text.
+ Font configuration used to display text.
</member>
<member name="font_size" type="int" setter="set_font_size" getter="get_font_size" default="16">
Font size of the [TextMesh]'s text.
diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml
index aaaacfe3ac..c733d8fcee 100644
--- a/doc/classes/TextParagraph.xml
+++ b/doc/classes/TextParagraph.xml
@@ -22,11 +22,10 @@
<method name="add_string">
<return type="bool" />
<argument index="0" name="text" type="String" />
- <argument index="1" name="fonts" type="Font" />
- <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" />
+ <argument index="1" name="font" type="Font" />
+ <argument index="2" name="font_size" type="int" />
+ <argument index="3" name="language" type="String" default="&quot;&quot;" />
+ <argument index="4" name="meta" type="Variant" default="null" />
<description>
Adds text span and font to draw it.
</description>
@@ -217,18 +216,6 @@
Returns the size of the bounding box of the paragraph.
</description>
</method>
- <method name="get_spacing_bottom" qualifiers="const">
- <return type="int" />
- <description>
- Returns extra spacing at the bottom of the line. See [member Font.spacing_bottom].
- </description>
- </method>
- <method name="get_spacing_top" qualifiers="const">
- <return type="int" />
- <description>
- Returns extra spacing at the top of the line. See [member Font.spacing_top].
- </description>
- </method>
<method name="hit_test" qualifiers="const">
<return type="int" />
<argument index="0" name="coords" type="Vector2" />
@@ -256,11 +243,10 @@
<method name="set_dropcap">
<return type="bool" />
<argument index="0" name="text" type="String" />
- <argument index="1" name="fonts" type="Font" />
- <argument index="2" name="size" type="int" />
+ <argument index="1" name="font" type="Font" />
+ <argument index="2" name="font_size" type="int" />
<argument index="3" name="dropcap_margins" type="Rect2" default="Rect2(0, 0, 0, 0)" />
- <argument index="4" name="opentype_features" type="Dictionary" default="{}" />
- <argument index="5" name="language" type="String" default="&quot;&quot;" />
+ <argument index="4" name="language" type="String" default="&quot;&quot;" />
<description>
Sets drop cap, overrides previously set drop cap. Drop cap (dropped capital) is a decorative element at the beginning of a paragraph that is larger than the rest of the text.
</description>
@@ -277,14 +263,17 @@
<member name="alignment" type="int" setter="set_alignment" getter="get_alignment" enum="HorizontalAlignment" default="0">
Paragraph horizontal alignment.
</member>
+ <member name="break_flags" type="int" setter="set_break_flags" getter="get_break_flags" enum="TextServer.LineBreakFlag" default="3">
+ Line breaking rules. For more info see [TextServer].
+ </member>
<member name="custom_punctuation" type="String" setter="set_custom_punctuation" getter="get_custom_punctuation" default="&quot;&quot;">
Custom punctuation character list, used for word breaking. If set to empty string, server defaults are used.
</member>
<member name="direction" type="int" setter="set_direction" getter="get_direction" enum="TextServer.Direction" default="0">
Text writing direction.
</member>
- <member name="flags" type="int" setter="set_flags" getter="get_flags" default="99">
- Line breaking and alignment rules. For more info see [TextServer].
+ <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" default="3">
+ Line alignment rules. For more info see [TextServer].
</member>
<member name="max_lines_visible" type="int" setter="set_max_lines_visible" getter="get_max_lines_visible" default="-1">
Limits the lines of text shown.
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index ca1aec19ea..e1b676427b 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -355,17 +355,8 @@
Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size.
</description>
</method>
- <method name="font_get_spacing" qualifiers="const">
- <return type="int" />
- <argument index="0" name="font_rid" type="RID" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="spacing" type="int" enum="TextServer.SpacingType" />
- <description>
- Returns extra spacing added between glyphs in pixels.
- </description>
- </method>
<method name="font_get_style" qualifiers="const">
- <return type="int" />
+ <return type="int" enum="TextServer.FontStyle" />
<argument index="0" name="font_rid" type="RID" />
<description>
Returns font style flags, see [enum FontStyle].
@@ -542,7 +533,7 @@
<argument index="1" name="size" type="Vector2i" />
<argument index="2" name="texture_index" type="int" />
<description>
- Removes specified texture from font cache entry.
+ Removes specified texture from the cache entry.
[b]Note:[/b] This function will not remove glyphs associated with the texture, remove them manually, using [method font_remove_glyph].
</description>
</method>
@@ -792,20 +783,10 @@
Adds override for [method font_is_script_supported].
</description>
</method>
- <method name="font_set_spacing">
- <return type="void" />
- <argument index="0" name="font_rid" type="RID" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="spacing" type="int" enum="TextServer.SpacingType" />
- <argument index="3" name="value" type="int" />
- <description>
- Sets extra spacing added between glyphs in pixels.
- </description>
- </method>
<method name="font_set_style">
<return type="void" />
<argument index="0" name="font_rid" type="RID" />
- <argument index="1" name="style" type="int" />
+ <argument index="1" name="style" type="int" enum="TextServer.FontStyle" />
<description>
Sets the font style flags, see [enum FontStyle].
</description>
@@ -1096,7 +1077,7 @@
<return type="float" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="width" type="float" />
- <argument index="2" name="jst_flags" type="int" default="3" />
+ <argument index="2" name="jst_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
<description>
Adjusts text with to fit to specified width, returns new text width.
</description>
@@ -1203,7 +1184,7 @@
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="width" type="float" />
<argument index="2" name="start" type="int" default="0" />
- <argument index="3" name="break_flags" type="int" default="96" />
+ <argument index="3" name="break_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
<description>
Breaks text to the lines and returns character ranges for each line.
</description>
@@ -1214,7 +1195,7 @@
<argument index="1" name="width" type="PackedFloat32Array" />
<argument index="2" name="start" type="int" default="0" />
<argument index="3" name="once" type="bool" default="true" />
- <argument index="4" name="break_flags" type="int" default="96" />
+ <argument index="4" name="break_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
<description>
Breaks text to the lines and columns. Returns character ranges for each segment.
</description>
@@ -1286,6 +1267,14 @@
Returns size of the text.
</description>
</method>
+ <method name="shaped_text_get_spacing" qualifiers="const">
+ <return type="int" />
+ <argument index="0" name="shaped" type="RID" />
+ <argument index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
+ <description>
+ Returns extra spacing added between glyphs or lines in pixels.
+ </description>
+ </method>
<method name="shaped_text_get_trim_pos" qualifiers="const">
<return type="int" />
<argument index="0" name="shaped" type="RID" />
@@ -1317,7 +1306,7 @@
<method name="shaped_text_get_word_breaks" qualifiers="const">
<return type="PackedInt32Array" />
<argument index="0" name="shaped" type="RID" />
- <argument index="1" name="grapheme_flags" type="int" default="264" />
+ <argument index="1" name="grapheme_flags" type="int" enum="TextServer.GraphemeFlag" default="264" />
<description>
Breaks text into words and returns array of character ranges. Use [code]grapheme_flags[/code] to set what characters are used for breaking (see [enum GraphemeFlag]).
</description>
@@ -1357,7 +1346,7 @@
<return type="void" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="width" type="float" default="0" />
- <argument index="2" name="overrun_trim_flags" type="int" default="0" />
+ <argument index="2" name="overrun_trim_flags" type="int" enum="TextServer.TextOverrunFlag" default="0" />
<description>
Trims text if it exceeds the given width.
</description>
@@ -1431,6 +1420,15 @@
If set to [code]true[/code] text buffer will display invalid characters as hexadecimal codes, otherwise nothing is displayed.
</description>
</method>
+ <method name="shaped_text_set_spacing">
+ <return type="void" />
+ <argument index="0" name="shaped" type="RID" />
+ <argument index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
+ <argument index="2" name="value" type="int" />
+ <description>
+ Sets extra spacing added between glyphs or lines in pixels.
+ </description>
+ </method>
<method name="shaped_text_shape">
<return type="bool" />
<argument index="0" name="shaped" type="RID" />
@@ -1524,22 +1522,22 @@
Left to right text is written vertically from top to bottom.
Right to left text is written vertically from bottom to top.
</constant>
- <constant name="JUSTIFICATION_NONE" value="0" enum="JustificationFlag">
+ <constant name="JUSTIFICATION_NONE" value="0" enum="JustificationFlag" is_bitfield="true">
Do not justify text.
</constant>
- <constant name="JUSTIFICATION_KASHIDA" value="1" enum="JustificationFlag">
+ <constant name="JUSTIFICATION_KASHIDA" value="1" enum="JustificationFlag" is_bitfield="true">
Justify text by adding and removing kashidas.
</constant>
- <constant name="JUSTIFICATION_WORD_BOUND" value="2" enum="JustificationFlag">
+ <constant name="JUSTIFICATION_WORD_BOUND" value="2" enum="JustificationFlag" is_bitfield="true">
Justify text by changing width of the spaces between the words.
</constant>
- <constant name="JUSTIFICATION_TRIM_EDGE_SPACES" value="4" enum="JustificationFlag">
+ <constant name="JUSTIFICATION_TRIM_EDGE_SPACES" value="4" enum="JustificationFlag" is_bitfield="true">
Remove trailing and leading spaces from the justified text.
</constant>
- <constant name="JUSTIFICATION_AFTER_LAST_TAB" value="8" enum="JustificationFlag">
+ <constant name="JUSTIFICATION_AFTER_LAST_TAB" value="8" enum="JustificationFlag" is_bitfield="true">
Only apply justification to the part of the text after the last tab.
</constant>
- <constant name="JUSTIFICATION_CONSTRAIN_ELLIPSIS" value="16" enum="JustificationFlag">
+ <constant name="JUSTIFICATION_CONSTRAIN_ELLIPSIS" value="16" enum="JustificationFlag" is_bitfield="true">
Apply justification to the trimmed line with ellipsis.
</constant>
<constant name="AUTOWRAP_OFF" value="0" enum="AutowrapMode">
@@ -1554,20 +1552,19 @@
<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="BREAK_NONE" value="0" enum="LineBreakFlag">
+ <constant name="BREAK_NONE" value="0" enum="LineBreakFlag" is_bitfield="true">
Do not break the line.
</constant>
- <constant name="BREAK_MANDATORY" value="32" enum="LineBreakFlag">
+ <constant name="BREAK_MANDATORY" value="1" enum="LineBreakFlag" is_bitfield="true">
Break the line at the line mandatory break characters (e.g. [code]"\n"[/code]).
</constant>
- <constant name="BREAK_WORD_BOUND" value="64" enum="LineBreakFlag">
+ <constant name="BREAK_WORD_BOUND" value="2" enum="LineBreakFlag" is_bitfield="true">
Break the line between the words.
</constant>
- <constant name="BREAK_GRAPHEME_BOUND" value="128" enum="LineBreakFlag">
+ <constant name="BREAK_GRAPHEME_BOUND" value="4" enum="LineBreakFlag" is_bitfield="true">
Break the line between any unconnected graphemes.
</constant>
- <constant name="BREAK_WORD_BOUND_ADAPTIVE" value="320" enum="LineBreakFlag">
- Break the line between the words, or any unconnected graphemes if line is too short to fit the whole word.
+ <constant name="BREAK_ADAPTIVE" value="8" enum="LineBreakFlag" is_bitfield="true">
</constant>
<constant name="VC_CHARS_BEFORE_SHAPING" value="0" enum="VisibleCharactersBehavior">
Trims text before the shaping. e.g, increasing [member Label.visible_characters] or [member RichTextLabel.visible_characters] value is visually identical to typing the text.
@@ -1599,54 +1596,54 @@
<constant name="OVERRUN_TRIM_WORD_ELLIPSIS" value="4" enum="OverrunBehavior">
Trims the text per word and adds an ellipsis to indicate that parts are hidden.
</constant>
- <constant name="OVERRUN_NO_TRIM" value="0" enum="TextOverrunFlag">
+ <constant name="OVERRUN_NO_TRIM" value="0" enum="TextOverrunFlag" is_bitfield="true">
No trimming is performed.
</constant>
- <constant name="OVERRUN_TRIM" value="1" enum="TextOverrunFlag">
+ <constant name="OVERRUN_TRIM" value="1" enum="TextOverrunFlag" is_bitfield="true">
Trims the text when it exceeds the given width.
</constant>
- <constant name="OVERRUN_TRIM_WORD_ONLY" value="2" enum="TextOverrunFlag">
+ <constant name="OVERRUN_TRIM_WORD_ONLY" value="2" enum="TextOverrunFlag" is_bitfield="true">
Trims the text per word instead of per grapheme.
</constant>
- <constant name="OVERRUN_ADD_ELLIPSIS" value="4" enum="TextOverrunFlag">
+ <constant name="OVERRUN_ADD_ELLIPSIS" value="4" enum="TextOverrunFlag" is_bitfield="true">
Determines whether an ellipsis should be added at the end of the text.
</constant>
- <constant name="OVERRUN_ENFORCE_ELLIPSIS" value="8" enum="TextOverrunFlag">
+ <constant name="OVERRUN_ENFORCE_ELLIPSIS" value="8" enum="TextOverrunFlag" is_bitfield="true">
Determines whether the ellipsis at the end of the text is enforced and may not be hidden.
</constant>
- <constant name="OVERRUN_JUSTIFICATION_AWARE" value="16" enum="TextOverrunFlag">
+ <constant name="OVERRUN_JUSTIFICATION_AWARE" value="16" enum="TextOverrunFlag" is_bitfield="true">
</constant>
- <constant name="GRAPHEME_IS_VALID" value="1" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_VALID" value="1" enum="GraphemeFlag" is_bitfield="true">
Grapheme is supported by the font, and can be drawn.
</constant>
- <constant name="GRAPHEME_IS_RTL" value="2" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_RTL" value="2" enum="GraphemeFlag" is_bitfield="true">
Grapheme is part of right-to-left or bottom-to-top run.
</constant>
- <constant name="GRAPHEME_IS_VIRTUAL" value="4" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_VIRTUAL" value="4" enum="GraphemeFlag" is_bitfield="true">
Grapheme is not part of source text, it was added by justification process.
</constant>
- <constant name="GRAPHEME_IS_SPACE" value="8" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_SPACE" value="8" enum="GraphemeFlag" is_bitfield="true">
Grapheme is whitespace.
</constant>
- <constant name="GRAPHEME_IS_BREAK_HARD" value="16" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_BREAK_HARD" value="16" enum="GraphemeFlag" is_bitfield="true">
Grapheme is mandatory break point (e.g. [code]"\n"[/code]).
</constant>
- <constant name="GRAPHEME_IS_BREAK_SOFT" value="32" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_BREAK_SOFT" value="32" enum="GraphemeFlag" is_bitfield="true">
Grapheme is optional break point (e.g. space).
</constant>
- <constant name="GRAPHEME_IS_TAB" value="64" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_TAB" value="64" enum="GraphemeFlag" is_bitfield="true">
Grapheme is the tabulation character.
</constant>
- <constant name="GRAPHEME_IS_ELONGATION" value="128" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_ELONGATION" value="128" enum="GraphemeFlag" is_bitfield="true">
Grapheme is kashida.
</constant>
- <constant name="GRAPHEME_IS_PUNCTUATION" value="256" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_PUNCTUATION" value="256" enum="GraphemeFlag" is_bitfield="true">
Grapheme is punctuation character.
</constant>
- <constant name="GRAPHEME_IS_UNDERSCORE" value="512" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_UNDERSCORE" value="512" enum="GraphemeFlag" is_bitfield="true">
Grapheme is underscore character.
</constant>
- <constant name="GRAPHEME_IS_CONNECTED" value="1024" enum="GraphemeFlag">
+ <constant name="GRAPHEME_IS_CONNECTED" value="1024" enum="GraphemeFlag" is_bitfield="true">
Grapheme is connected to the previous grapheme. Breaking line before this grapheme is not safe.
</constant>
<constant name="HINTING_NONE" value="0" enum="Hinting">
@@ -1739,13 +1736,15 @@
<constant name="SPACING_BOTTOM" value="3" enum="SpacingType">
Spacing at the bottom of the line.
</constant>
- <constant name="FONT_BOLD" value="1" enum="FontStyle">
+ <constant name="SPACING_MAX" value="4" enum="SpacingType">
+ </constant>
+ <constant name="FONT_BOLD" value="1" enum="FontStyle" is_bitfield="true">
Font is bold.
</constant>
- <constant name="FONT_ITALIC" value="2" enum="FontStyle">
+ <constant name="FONT_ITALIC" value="2" enum="FontStyle" is_bitfield="true">
Font is italic or oblique.
</constant>
- <constant name="FONT_FIXED_WIDTH" value="4" enum="FontStyle">
+ <constant name="FONT_FIXED_WIDTH" value="4" enum="FontStyle" is_bitfield="true">
Font have fixed-width characters.
</constant>
<constant name="STRUCTURED_TEXT_DEFAULT" value="0" enum="StructuredTextParser">
diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml
index b3be858ca1..4501ec744a 100644
--- a/doc/classes/TextServerExtension.xml
+++ b/doc/classes/TextServerExtension.xml
@@ -345,17 +345,8 @@
Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size.
</description>
</method>
- <method name="font_get_spacing" qualifiers="virtual const">
- <return type="int" />
- <argument index="0" name="font_rid" type="RID" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="spacing" type="int" enum="TextServer.SpacingType" />
- <description>
- Returns extra spacing added between glyphs in pixels.
- </description>
- </method>
<method name="font_get_style" qualifiers="virtual const">
- <return type="int" />
+ <return type="int" enum="TextServer.FontStyle" />
<argument index="0" name="font_rid" type="RID" />
<description>
Returns font style flags, see [enum TextServer.FontStyle].
@@ -531,7 +522,7 @@
<argument index="1" name="size" type="Vector2i" />
<argument index="2" name="texture_index" type="int" />
<description>
- Removes specified texture from font cache entry.
+ Removes specified texture from the cache entry.
</description>
</method>
<method name="font_render_glyph" qualifiers="virtual">
@@ -788,20 +779,10 @@
Adds override for [method font_is_script_supported].
</description>
</method>
- <method name="font_set_spacing" qualifiers="virtual">
- <return type="void" />
- <argument index="0" name="font_rid" type="RID" />
- <argument index="1" name="size" type="int" />
- <argument index="2" name="spacing" type="int" enum="TextServer.SpacingType" />
- <argument index="3" name="value" type="int" />
- <description>
- Sets extra spacing added between glyphs in pixels.
- </description>
- </method>
<method name="font_set_style" qualifiers="virtual">
<return type="void" />
<argument index="0" name="font_rid" type="RID" />
- <argument index="1" name="style" type="int" />
+ <argument index="1" name="style" type="int" enum="TextServer.FontStyle" />
<description>
Sets the font style flags, see [enum TextServer.FontStyle].
</description>
@@ -1093,7 +1074,7 @@
<return type="float" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="width" type="float" />
- <argument index="2" name="jst_flags" type="int" />
+ <argument index="2" name="jst_flags" type="int" enum="TextServer.JustificationFlag" />
<description>
Adjusts text with to fit to specified width, returns new text width.
</description>
@@ -1202,7 +1183,7 @@
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="width" type="float" />
<argument index="2" name="start" type="int" />
- <argument index="3" name="break_flags" type="int" />
+ <argument index="3" name="break_flags" type="int" enum="TextServer.LineBreakFlag" />
<description>
Breaks text to the lines and returns character ranges for each line.
[b]Note:[/b] If this method is not implemented in the plugin, the default implementation will be used.
@@ -1214,7 +1195,7 @@
<argument index="1" name="width" type="PackedFloat32Array" />
<argument index="2" name="start" type="int" />
<argument index="3" name="once" type="bool" />
- <argument index="4" name="break_flags" type="int" />
+ <argument index="4" name="break_flags" type="int" enum="TextServer.LineBreakFlag" />
<description>
Breaks text to the lines and columns. Returns character ranges for each segment.
[b]Note:[/b] If this method is not implemented in the plugin, the default implementation will be used.
@@ -1288,6 +1269,14 @@
Returns size of the text.
</description>
</method>
+ <method name="shaped_text_get_spacing" qualifiers="virtual const">
+ <return type="int" />
+ <argument index="0" name="shaped" type="RID" />
+ <argument index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
+ <description>
+ Returns extra spacing added between glyphs or lines in pixels.
+ </description>
+ </method>
<method name="shaped_text_get_trim_pos" qualifiers="virtual const">
<return type="int" />
<argument index="0" name="shaped" type="RID" />
@@ -1319,7 +1308,7 @@
<method name="shaped_text_get_word_breaks" qualifiers="virtual const">
<return type="PackedInt32Array" />
<argument index="0" name="shaped" type="RID" />
- <argument index="1" name="grapheme_flags" type="int" />
+ <argument index="1" name="grapheme_flags" type="int" enum="TextServer.GraphemeFlag" />
<description>
Breaks text into words and returns array of character ranges.
[b]Note:[/b] If this method is not implemented in the plugin, the default implementation will be used.
@@ -1363,7 +1352,7 @@
<return type="void" />
<argument index="0" name="shaped" type="RID" />
<argument index="1" name="width" type="float" />
- <argument index="2" name="trim_flags" type="int" />
+ <argument index="2" name="trim_flags" type="int" enum="TextServer.TextOverrunFlag" />
<description>
Trims text if it exceeds the given width.
</description>
@@ -1436,6 +1425,15 @@
If set to [code]true[/code] text buffer will display invalid characters as hexadecimal codes, otherwise nothing is displayed.
</description>
</method>
+ <method name="shaped_text_set_spacing" qualifiers="virtual">
+ <return type="void" />
+ <argument index="0" name="shaped" type="RID" />
+ <argument index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
+ <argument index="2" name="value" type="int" />
+ <description>
+ Sets extra spacing added between glyphs or lines in pixels.
+ </description>
+ </method>
<method name="shaped_text_shape" qualifiers="virtual">
<return type="bool" />
<argument index="0" name="shaped" type="RID" />
diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml
index 5270da9588..7f4e0645c8 100644
--- a/doc/classes/Theme.xml
+++ b/doc/classes/Theme.xml
@@ -334,8 +334,8 @@
<argument index="0" name="name" type="StringName" />
<argument index="1" name="theme_type" type="StringName" />
<description>
- Returns [code]true[/code] if the font size property defined by [code]name[/code] and [code]theme_type[/code] exists, or if the default theme font size is set up (see [method has_default_font_size]).
- Returns [code]false[/code] if neither exist. Use [method set_font_size] to define the property.
+ Returns [code]true[/code] if [member default_font_size] has a valid value.
+ Returns [code]false[/code] if it doesn't. The value must be greater than [code]0[/code] to be considered valid.
</description>
</method>
<method name="has_icon" qualifiers="const">
@@ -426,8 +426,8 @@
<argument index="1" name="name" type="StringName" />
<argument index="2" name="theme_type" type="StringName" />
<description>
- Renames the font size property defined by [code]old_name[/code] and [code]theme_type[/code] to [code]name[/code], if it exists.
- Fails if it doesn't exist, or if a similar property with the new name already exists. Use [method has_font_size] to check for existence, and [method clear_font_size] to remove the existing property.
+ Returns [code]true[/code] if the font size property defined by [code]name[/code] and [code]theme_type[/code] exists, or if the default theme font size is set up (see [method has_default_font_size]).
+ Returns [code]false[/code] if neither exist. Use [method set_font_size] to define the property.
</description>
</method>
<method name="rename_icon">
@@ -495,7 +495,8 @@
<argument index="1" name="theme_type" type="StringName" />
<argument index="2" name="font_size" type="int" />
<description>
- Creates or changes the value of the font size property defined by [code]name[/code] and [code]theme_type[/code]. Use [method clear_font_size] to remove the property.
+ Renames the font size property defined by [code]old_name[/code] and [code]theme_type[/code] to [code]name[/code], if it exists.
+ Fails if it doesn't exist, or if a similar property with the new name already exists. Use [method has_font_size] to check for existence, and [method clear_font_size] to remove the existing property.
</description>
</method>
<method name="set_icon">
diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml
index 10ccad973f..ad52b2f2f1 100644
--- a/doc/classes/TileSet.xml
+++ b/doc/classes/TileSet.xml
@@ -591,7 +591,7 @@
Tile coordinates layout where both axis stay consistent with their respective local horizontal and vertical axis.
</constant>
<constant name="TILE_LAYOUT_STACKED_OFFSET" value="1" enum="TileLayout">
- Same as [code]TILE_LAYOUT_STAKED[/code], but the first half-offset is negative instead of positive.
+ Same as [constant TILE_LAYOUT_STACKED], but the first half-offset is negative instead of positive.
</constant>
<constant name="TILE_LAYOUT_STAIRS_RIGHT" value="2" enum="TileLayout">
Tile coordinates layout where the horizontal axis stay horizontal, and the vertical one goes down-right.
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index 8a30364ebe..b06be0cf99 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -42,13 +42,6 @@
Clears the tree. This removes all items.
</description>
</method>
- <method name="clear_column_title_opentype_features">
- <return type="void" />
- <argument index="0" name="column" type="int" />
- <description>
- Removes all OpenType features from the item's text.
- </description>
- </method>
<method name="create_item">
<return type="TreeItem" />
<argument index="0" name="parent" type="TreeItem" default="null" />
@@ -114,14 +107,6 @@
Returns column title language code.
</description>
</method>
- <method name="get_column_title_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="column" type="int" />
- <argument index="1" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code] of the column title.
- </description>
- </method>
<method name="get_column_width" qualifiers="const">
<return type="int" />
<argument index="0" name="column" type="int" />
@@ -308,15 +293,6 @@
Sets language code of column title used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
</description>
</method>
- <method name="set_column_title_opentype_feature">
- <return type="void" />
- <argument index="0" name="column" type="int" />
- <argument index="1" name="tag" type="String" />
- <argument index="2" name="value" type="int" />
- <description>
- Sets OpenType feature [code]tag[/code] for the column title.
- </description>
- </method>
</methods>
<members>
<member name="allow_reselect" type="bool" setter="set_allow_reselect" getter="get_allow_reselect" default="false">
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index 0a680b9627..fbba1147a2 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -42,13 +42,6 @@
Resets the color for the given column to default.
</description>
</method>
- <method name="clear_opentype_features">
- <return type="void" />
- <argument index="0" name="column" type="int" />
- <description>
- Removes all OpenType features.
- </description>
- </method>
<method name="create_child">
<return type="TreeItem" />
<argument index="0" name="idx" type="int" default="-1" />
@@ -230,25 +223,17 @@
<method name="get_next" qualifiers="const">
<return type="TreeItem" />
<description>
- Returns the next TreeItem in the tree or a null object if there is none.
+ Returns the next sibling TreeItem in the tree or a null object if there is none.
</description>
</method>
<method name="get_next_visible">
<return type="TreeItem" />
<argument index="0" name="wrap" type="bool" default="false" />
<description>
- Returns the next visible TreeItem in the tree or a null object if there is none.
+ Returns the next visible sibling TreeItem in the tree or a null object if there is none.
If [code]wrap[/code] is enabled, the method will wrap around to the first visible element in the tree when called on the last visible element, otherwise it returns [code]null[/code].
</description>
</method>
- <method name="get_opentype_feature" qualifiers="const">
- <return type="int" />
- <argument index="0" name="column" type="int" />
- <argument index="1" name="tag" type="String" />
- <description>
- Returns OpenType feature [code]tag[/code] of the item's text.
- </description>
- </method>
<method name="get_parent" qualifiers="const">
<return type="TreeItem" />
<description>
@@ -258,14 +243,14 @@
<method name="get_prev">
<return type="TreeItem" />
<description>
- Returns the previous TreeItem in the tree or a null object if there is none.
+ Returns the previous sibling TreeItem in the tree or a null object if there is none.
</description>
</method>
<method name="get_prev_visible">
<return type="TreeItem" />
<argument index="0" name="wrap" type="bool" default="false" />
<description>
- Returns the previous visible TreeItem in the tree or a null object if there is none.
+ Returns the previous visible sibling TreeItem in the tree or a null object if there is none.
If [code]wrap[/code] is enabled, the method will wrap around to the last visible element in the tree when called on the first visible element, otherwise it returns [code]null[/code].
</description>
</method>
@@ -580,15 +565,6 @@
Sets the metadata value for the given column, which can be retrieved later using [method get_metadata]. This can be used, for example, to store a reference to the original data.
</description>
</method>
- <method name="set_opentype_feature">
- <return type="void" />
- <argument index="0" name="column" type="int" />
- <argument index="1" name="tag" type="String" />
- <argument index="2" name="value" type="int" />
- <description>
- Sets OpenType feature [code]tag[/code] for the item's text.
- </description>
- </method>
<method name="set_range">
<return type="void" />
<argument index="0" name="column" type="int" />
diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml
index f9ec0d115d..b18232f5c3 100644
--- a/doc/classes/Tween.xml
+++ b/doc/classes/Tween.xml
@@ -4,41 +4,41 @@
Lightweight object used for general-purpose animation via script, using [Tweener]s.
</brief_description>
<description>
- Tweens are mostly useful for animations requiring a numerical property to be interpolated over a range of values. The name [i]tween[/i] comes from [i]in-betweening[/i], an animation technique where you specify [i]keyframes[/i] and the computer interpolates the frames that appear between them.
+ Tweens are mostly useful for animations requiring a numerical property to be interpolated over a range of values. The name [i]tween[/i] comes from [i]in-betweening[/i], an animation technique where you specify [i]keyframes[/i] and the computer interpolates the frames that appear between them. Animating something with a [Tween] is called tweening.
[Tween] is more suited than [AnimationPlayer] for animations where you don't know the final values in advance. For example, interpolating a dynamically-chosen camera zoom value is best done with a [Tween]; it would be difficult to do the same thing with an [AnimationPlayer] node. Tweens are also more light-weight than [AnimationPlayer], so they are very much suited for simple animations or general tasks that don't require visual tweaking provided by the editor. They can be used in a fire-and-forget manner for some logic that normally would be done by code. You can e.g. make something shoot periodically by using a looped [CallbackTweener] with a delay.
A [Tween] can be created by using either [method SceneTree.create_tween] or [method Node.create_tween]. [Tween]s created manually (i.e. by using [code]Tween.new()[/code]) are invalid and can't be used for tweening values.
- A [Tween] animation is composed of a sequence of [Tweener]s, which by default are executed one after another. You can create a sequence by appending [Tweener]s to the [Tween]. Animating something with a [Tweener] is called tweening. Example tweening sequence looks like this:
+ A tween animation is created by adding [Tweener]s to the [Tween] object, using [method tween_property], [method tween_interval], [method tween_callback] or [method tween_method]:
[codeblock]
var tween = get_tree().create_tween()
tween.tween_property($Sprite, "modulate", Color.red, 1)
tween.tween_property($Sprite, "scale", Vector2(), 1)
tween.tween_callback($Sprite.queue_free)
[/codeblock]
- This sequence will make the [code]$Sprite[/code] node turn red, then shrink and finally the [method Node.queue_free] is called to remove the sprite. See methods [method tween_property], [method tween_interval], [method tween_callback] and [method tween_method] for more usage information.
- When a [Tweener] is created with one of the [code]tween_*[/code] methods, a chained method call can be used to tweak the properties of this [Tweener]. For example, if you want to set different transition type in the above example, you can do:
+ This sequence will make the [code]$Sprite[/code] node turn red, then shrink, before finally calling [method Node.queue_free] to free the sprite. [Tweener]s are executed one after another by default. This behavior can be changed using [method parallel] and [method set_parallel].
+ When a [Tweener] is created with one of the [code]tween_*[/code] methods, a chained method call can be used to tweak the properties of this [Tweener]. For example, if you want to set a different transition type in the above example, you can use [method set_trans]:
[codeblock]
var tween = get_tree().create_tween()
tween.tween_property($Sprite, "modulate", Color.red, 1).set_trans(Tween.TRANS_SINE)
tween.tween_property($Sprite, "scale", Vector2(), 1).set_trans(Tween.TRANS_BOUNCE)
tween.tween_callback($Sprite.queue_free)
[/codeblock]
- Most of the [Tween] methods can be chained this way too. In this example the [Tween] is bound and have set a default transition:
+ Most of the [Tween] methods can be chained this way too. In the following example the [Tween] is bound to the running script's node and a default transition is set for its [Tweener]s:
[codeblock]
var tween = get_tree().create_tween().bind_node(self).set_trans(Tween.TRANS_ELASTIC)
tween.tween_property($Sprite, "modulate", Color.red, 1)
tween.tween_property($Sprite, "scale", Vector2(), 1)
tween.tween_callback($Sprite.queue_free)
[/codeblock]
- Another interesting use for [Tween]s is animating arbitrary set of objects:
+ Another interesting use for [Tween]s is animating arbitrary sets of objects:
[codeblock]
var tween = create_tween()
for sprite in get_children():
- tween.tween_property(sprite, "position", Vector2(), 1)
+ tween.tween_property(sprite, "position", Vector2(0, 0), 1)
[/codeblock]
In the example above, all children of a node are moved one after another to position (0, 0).
- Some [Tweener]s use transitions and eases. The first accepts an [enum TransitionType] constant, and refers to the way the timing of the animation is handled (see [url=https://easings.net/]easings.net[/url] for some examples). The second accepts an [enum EaseType] constant, and controls where the [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different [enum TransitionType] constants with [constant EASE_IN_OUT], and use the one that looks best.
+ Some [Tweener]s use transitions and eases. The first accepts a [enum TransitionType] constant, and refers to the way the timing of the animation is handled (see [url=https://easings.net/]easings.net[/url] for some examples). The second accepts an [enum EaseType] constant, and controls where the [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different [enum TransitionType] constants with [constant EASE_IN_OUT], and use the one that looks best.
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]
- [b]Note:[/b] All [Tween]s will automatically start by default. To prevent a [Tween] from autostarting, you can call [method stop] immediately after it was created.
+ [b]Note:[/b] All [Tween]s will automatically start by default. To prevent a [Tween] from autostarting, you can call [method stop] immediately after it is created.
</description>
<tutorials>
</tutorials>
@@ -67,15 +67,15 @@
<return type="bool" />
<argument index="0" name="delta" type="float" />
<description>
- Processes the [Tween] by given [code]delta[/code] value, in seconds. Mostly useful when the [Tween] is paused, for controlling it manually. Can also be used to end the [Tween] animation immediately, by using [code]delta[/code] longer than the whole duration.
+ Processes the [Tween] by the given [code]delta[/code] value, in seconds. This is mostly useful for manual control when the [Tween] is paused. It can also be used to end the [Tween] animation immediately, by setting [code]delta[/code] longer than the whole duration of the [Tween] animation.
Returns [code]true[/code] if the [Tween] still has [Tweener]s that haven't finished.
- [b]Note:[/b] The [Tween] will become invalid after finished, but you can call [method stop] after the step, to keep it and reset.
+ [b]Note:[/b] The [Tween] will become invalid in the next processing frame after its animation finishes. Calling [method stop] after performing [method custom_step] instead keeps and resets the [Tween].
</description>
</method>
<method name="get_total_elapsed_time" qualifiers="const">
<return type="float" />
<description>
- Returns the total time in seconds the [Tween] has been animating (i.e. time since it started, not counting pauses etc.). The time is affected by [method set_speed_scale] and [method stop] will reset it to [code]0[/code].
+ Returns the total time in seconds the [Tween] has been animating (i.e. the time since it started, not counting pauses etc.). The time is affected by [method set_speed_scale], and [method stop] will reset it to [code]0[/code].
[b]Note:[/b] As it results from accumulating frame deltas, the time returned after the [Tween] has finished animating will be slightly greater than the actual [Tween] duration.
</description>
</method>
@@ -105,7 +105,7 @@
<method name="is_valid">
<return type="bool" />
<description>
- Returns whether the [Tween] is valid. A valid [Tween] is a [Tween] contained by the scene tree (i.e. the array from [method SceneTree.get_processed_tweens] will contain this [Tween]). [Tween] might become invalid when it has finished tweening or was killed, also when created with [code]Tween.new()[/code]. Invalid [Tween] can't have [Tweener]s appended, because it can't animate them.
+ Returns whether the [Tween] is valid. A valid [Tween] is a [Tween] contained by the scene tree (i.e. the array from [method SceneTree.get_processed_tweens] will contain this [Tween]). A [Tween] might become invalid when it has finished tweening, is killed, or when created with [code]Tween.new()[/code]. Invalid [Tween]s can't have [Tweener]s appended.
</description>
</method>
<method name="kill">
@@ -152,8 +152,8 @@
<argument index="0" name="loops" type="int" default="0" />
<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 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].
+ Calling this method without arguments will make the [Tween] run infinitely, until either it is killed with [method kill], the [Tween]'s bound node is freed, 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. To prevent the game freezing, 0-duration looped animations (e.g. a single [CallbackTweener] with no delay) are stopped after a small number of loops, which may produce unexpected results. If a [Tween]'s lifetime depends on some node, always use [method bind_node].
</description>
</method>
<method name="set_parallel">
@@ -221,7 +221,7 @@
<return type="IntervalTweener" />
<argument index="0" name="time" type="float" />
<description>
- Creates and appends an [IntervalTweener]. This method can be used to create delays in the tween animation, as an alternative for using the delay in other [Tweener]s or when there's no animation (in which case the [Tween] acts as a timer). [code]time[/code] is the length of the interval, in seconds.
+ Creates and appends an [IntervalTweener]. This method can be used to create delays in the tween animation, as an alternative to using the delay in other [Tweener]s, or when there's no animation (in which case the [Tween] acts as a timer). [code]time[/code] is the length of the interval, in seconds.
Example: creating an interval in code execution.
[codeblock]
# ... some code
@@ -271,7 +271,7 @@
<argument index="2" name="final_val" type="Variant" />
<argument index="3" name="duration" type="float" />
<description>
- Creates and appends a [PropertyTweener]. This method tweens a [code]property[/code] of an [code]object[/code] between an initial value and [code]final_val[/code] in a span of time equal to [code]duration[/code], in seconds. The initial value by default is a value at the time the tweening of the [PropertyTweener] start. For example:
+ Creates and appends a [PropertyTweener]. This method tweens a [code]property[/code] of an [code]object[/code] between an initial value and [code]final_val[/code] in a span of time equal to [code]duration[/code], in seconds. The initial value by default is the property's value at the time the tweening of the [PropertyTweener] starts. For example:
[codeblock]
var tween = create_tween()
tween.tween_property($Sprite, "position", Vector2(100, 200), 1)
@@ -292,19 +292,19 @@
<signal name="finished">
<description>
Emitted when the [Tween] has finished all tweening. Never emitted when the [Tween] is set to infinite looping (see [method set_loops]).
- [b]Note:[/b] The [Tween] is removed (invalidated) after this signal is emitted, but it doesn't happen immediately, but on the next processing frame. Calling [method stop] inside the signal callback will preserve the [Tween].
+ [b]Note:[/b] The [Tween] is removed (invalidated) in the next processing frame after this signal is emitted. Calling [method stop] inside the signal callback will prevent the [Tween] from being removed.
</description>
</signal>
<signal name="loop_finished">
<argument index="0" name="loop_count" type="int" />
<description>
- Emitted when a full loop is complete (see [method set_loops]), providing the loop index. This signal is not emitted after final loop, use [signal finished] instead for this case.
+ Emitted when a full loop is complete (see [method set_loops]), providing the loop index. This signal is not emitted after the final loop, use [signal finished] instead for this case.
</description>
</signal>
<signal name="step_finished">
<argument index="0" name="idx" type="int" />
<description>
- Emitted when one step of the [Tween] is complete, providing the step index. One step is either a single [Tweener] or a group of [Tweener]s running parallelly.
+ Emitted when one step of the [Tween] is complete, providing the step index. One step is either a single [Tweener] or a group of [Tweener]s running in parallel.
</description>
</signal>
</signals>
diff --git a/doc/classes/VehicleBody3D.xml b/doc/classes/VehicleBody3D.xml
index 330a405d5f..08309a8ecc 100644
--- a/doc/classes/VehicleBody3D.xml
+++ b/doc/classes/VehicleBody3D.xml
@@ -16,7 +16,7 @@
Slows down the vehicle by applying a braking force. The vehicle is only slowed down if the wheels are in contact with a surface. The force you need to apply to adequately slow down your vehicle depends on the [member RigidDynamicBody3D.mass] of the vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 30 range for hard braking.
</member>
<member name="engine_force" type="float" setter="set_engine_force" getter="get_engine_force" default="0.0">
- Accelerates the vehicle by applying an engine force. The vehicle is only speed up if the wheels that have [member VehicleWheel3D.use_as_traction] set to [code]true[/code] and are in contact with a surface. The [member RigidDynamicBody3D.mass] of the vehicle has an effect on the acceleration of the vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 range for acceleration.
+ Accelerates the vehicle by applying an engine force. The vehicle is only sped up if the wheels that have [member VehicleWheel3D.use_as_traction] set to [code]true[/code] and are in contact with a surface. The [member RigidDynamicBody3D.mass] of the vehicle has an effect on the acceleration of the vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 range for acceleration.
[b]Note:[/b] The simulation does not take the effect of gears into account, you will need to add logic for this if you wish to simulate gears.
A negative value will result in the vehicle reversing.
</member>
diff --git a/doc/classes/VehicleWheel3D.xml b/doc/classes/VehicleWheel3D.xml
index 1c164d7c9a..ac126f824e 100644
--- a/doc/classes/VehicleWheel3D.xml
+++ b/doc/classes/VehicleWheel3D.xml
@@ -48,7 +48,7 @@
The damping applied to the spring when relaxing. This value should be between 0.0 (no damping) and 1.0. This value should always be slightly higher than the [member damping_compression] property. For a [member damping_compression] value of 0.3, try a relaxation value of 0.5.
</member>
<member name="engine_force" type="float" setter="set_engine_force" getter="get_engine_force" default="0.0">
- Accelerates the wheel by applying an engine force. The wheel is only speed up if it is in contact with a surface. The [member RigidDynamicBody3D.mass] of the vehicle has an effect on the acceleration of the vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 range for acceleration.
+ Accelerates the wheel by applying an engine force. The wheel is only sped up if it is in contact with a surface. The [member RigidDynamicBody3D.mass] of the vehicle has an effect on the acceleration of the vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 range for acceleration.
[b]Note:[/b] The simulation does not take the effect of gears into account, you will need to add logic for this if you wish to simulate gears.
A negative value will result in the wheel reversing.
</member>
diff --git a/doc/classes/VideoStreamPlayer.xml b/doc/classes/VideoStreamPlayer.xml
index 092a754a39..f6594ff9e7 100644
--- a/doc/classes/VideoStreamPlayer.xml
+++ b/doc/classes/VideoStreamPlayer.xml
@@ -58,7 +58,7 @@
<member name="bus" type="StringName" setter="set_bus" getter="get_bus" default="&amp;&quot;Master&quot;">
Audio bus to use for sound playback.
</member>
- <member name="expand" type="bool" setter="set_expand" getter="has_expand" default="true">
+ <member name="expand" type="bool" setter="set_expand" getter="has_expand" default="false">
If [code]true[/code], the video scales to the control size. Otherwise, the control minimum size will be automatically adjusted to match the video stream's dimensions.
</member>
<member name="paused" type="bool" setter="set_paused" getter="is_paused" default="false">
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 4727bc389e..53603b5356 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -57,6 +57,13 @@
Returns the mouse's position in this [Viewport] using the coordinate system of this [Viewport].
</description>
</method>
+ <method name="get_positional_shadow_atlas_quadrant_subdiv" qualifiers="const">
+ <return type="int" enum="Viewport.PositionalShadowAtlasQuadrantSubdiv" />
+ <argument index="0" name="quadrant" type="int" />
+ <description>
+ Returns the [enum PositionalShadowAtlasQuadrantSubdiv] of the specified quadrant.
+ </description>
+ </method>
<method name="get_render_info">
<return type="int" />
<argument index="0" name="type" type="int" enum="Viewport.RenderInfoType" />
@@ -64,13 +71,6 @@
<description>
</description>
</method>
- <method name="get_shadow_atlas_quadrant_subdiv" qualifiers="const">
- <return type="int" enum="Viewport.ShadowAtlasQuadrantSubdiv" />
- <argument index="0" name="quadrant" type="int" />
- <description>
- Returns the [enum ShadowAtlasQuadrantSubdiv] of the specified quadrant.
- </description>
- </method>
<method name="get_texture" qualifiers="const">
<return type="ViewportTexture" />
<description>
@@ -158,10 +158,10 @@
Stops the input from propagating further down the [SceneTree].
</description>
</method>
- <method name="set_shadow_atlas_quadrant_subdiv">
+ <method name="set_positional_shadow_atlas_quadrant_subdiv">
<return type="void" />
<argument index="0" name="quadrant" type="int" />
- <argument index="1" name="subdiv" type="int" enum="Viewport.ShadowAtlasQuadrantSubdiv" />
+ <argument index="1" name="subdiv" type="int" enum="Viewport.PositionalShadowAtlasQuadrantSubdiv" />
<description>
Sets the number of subdivisions to use in the specified quadrant. A higher number of subdivisions allows you to have more shadows in the scene at once, but reduces the quality of the shadows. A good practice is to have quadrants with a varying number of subdivisions and to have as few subdivisions as possible.
</description>
@@ -232,6 +232,24 @@
<member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking" default="false">
If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process.
</member>
+ <member name="positional_shadow_atlas_16_bits" type="bool" setter="set_positional_shadow_atlas_16_bits" getter="get_positional_shadow_atlas_16_bits" default="true">
+ </member>
+ <member name="positional_shadow_atlas_quad_0" type="int" setter="set_positional_shadow_atlas_quadrant_subdiv" getter="get_positional_shadow_atlas_quadrant_subdiv" enum="Viewport.PositionalShadowAtlasQuadrantSubdiv" default="2">
+ The subdivision amount of the first quadrant on the shadow atlas.
+ </member>
+ <member name="positional_shadow_atlas_quad_1" type="int" setter="set_positional_shadow_atlas_quadrant_subdiv" getter="get_positional_shadow_atlas_quadrant_subdiv" enum="Viewport.PositionalShadowAtlasQuadrantSubdiv" default="2">
+ The subdivision amount of the second quadrant on the shadow atlas.
+ </member>
+ <member name="positional_shadow_atlas_quad_2" type="int" setter="set_positional_shadow_atlas_quadrant_subdiv" getter="get_positional_shadow_atlas_quadrant_subdiv" enum="Viewport.PositionalShadowAtlasQuadrantSubdiv" default="3">
+ The subdivision amount of the third quadrant on the shadow atlas.
+ </member>
+ <member name="positional_shadow_atlas_quad_3" type="int" setter="set_positional_shadow_atlas_quadrant_subdiv" getter="get_positional_shadow_atlas_quadrant_subdiv" enum="Viewport.PositionalShadowAtlasQuadrantSubdiv" default="4">
+ The subdivision amount of the fourth quadrant on the shadow atlas.
+ </member>
+ <member name="positional_shadow_atlas_size" type="int" setter="set_positional_shadow_atlas_size" getter="get_positional_shadow_atlas_size" default="2048">
+ The shadow atlas' resolution (used for omni and spot lights). The value will be rounded up to the nearest power of 2.
+ [b]Note:[/b] If this is set to [code]0[/code], no shadows will be visible at all (including directional shadows).
+ </member>
<member name="scaling_3d_mode" type="int" setter="set_scaling_3d_mode" getter="get_scaling_3d_mode" enum="Viewport.Scaling3DMode" default="0">
Sets scaling 3d mode. Bilinear scaling renders at different resolution to either undersample or supersample the viewport. FidelityFX Super Resolution 1.0, abbreviated to FSR, is an upscaling technology that produces high quality images at fast framerates by using a spatially aware upscaling algorithm. FSR is slightly more expensive than bilinear, but it produces significantly higher image quality. FSR should be used where possible.
To control this property on the root viewport, set the [member ProjectSettings.rendering/scaling_3d/mode] project setting.
@@ -248,24 +266,6 @@
</member>
<member name="sdf_scale" type="int" setter="set_sdf_scale" getter="get_sdf_scale" enum="Viewport.SDFScale" default="1">
</member>
- <member name="shadow_atlas_16_bits" type="bool" setter="set_shadow_atlas_16_bits" getter="get_shadow_atlas_16_bits" default="true">
- </member>
- <member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="2">
- The subdivision amount of the first quadrant on the shadow atlas.
- </member>
- <member name="shadow_atlas_quad_1" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="2">
- The subdivision amount of the second quadrant on the shadow atlas.
- </member>
- <member name="shadow_atlas_quad_2" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="3">
- The subdivision amount of the third quadrant on the shadow atlas.
- </member>
- <member name="shadow_atlas_quad_3" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="4">
- The subdivision amount of the fourth quadrant on the shadow atlas.
- </member>
- <member name="shadow_atlas_size" type="int" setter="set_shadow_atlas_size" getter="get_shadow_atlas_size" default="2048">
- The shadow atlas' resolution (used for omni and spot lights). The value will be rounded up to the nearest power of 2.
- [b]Note:[/b] If this is set to 0, shadows won't be visible.
- </member>
<member name="snap_2d_transforms_to_pixel" type="bool" setter="set_snap_2d_transforms_to_pixel" getter="is_snap_2d_transforms_to_pixel_enabled" default="false">
</member>
<member name="snap_2d_vertices_to_pixel" type="bool" setter="set_snap_2d_vertices_to_pixel" getter="is_snap_2d_vertices_to_pixel_enabled" default="false">
@@ -286,6 +286,12 @@
<member name="use_xr" type="bool" setter="set_use_xr" getter="is_using_xr" default="false">
If [code]true[/code], the viewport will use the primary XR interface to render XR output. When applicable this can result in a stereoscopic image and the resulting render being output to a headset.
</member>
+ <member name="vrs_mode" type="int" setter="set_vrs_mode" getter="get_vrs_mode" enum="Viewport.VRSMode" default="0">
+ The Variable Rate Shading (VRS) mode that is used for this viewport. Note, if hardware does not support VRS this property is ignored.
+ </member>
+ <member name="vrs_texture" type="Texture2D" setter="set_vrs_texture" getter="get_vrs_texture">
+ Texture to use when [member vrs_mode] is set to [constant Viewport.VRS_TEXTURE].
+ </member>
<member name="world_2d" type="World2D" setter="set_world_2d" getter="get_world_2d">
The custom [World2D] which can be used as 2D environment source.
</member>
@@ -307,29 +313,29 @@
</signal>
</signals>
<constants>
- <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED" value="0" enum="ShadowAtlasQuadrantSubdiv">
+ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED" value="0" enum="PositionalShadowAtlasQuadrantSubdiv">
This quadrant will not be used.
</constant>
- <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_1" value="1" enum="ShadowAtlasQuadrantSubdiv">
+ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_1" value="1" enum="PositionalShadowAtlasQuadrantSubdiv">
This quadrant will only be used by one shadow map.
</constant>
- <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_4" value="2" enum="ShadowAtlasQuadrantSubdiv">
+ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_4" value="2" enum="PositionalShadowAtlasQuadrantSubdiv">
This quadrant will be split in 4 and used by up to 4 shadow maps.
</constant>
- <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_16" value="3" enum="ShadowAtlasQuadrantSubdiv">
+ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_16" value="3" enum="PositionalShadowAtlasQuadrantSubdiv">
This quadrant will be split 16 ways and used by up to 16 shadow maps.
</constant>
- <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_64" value="4" enum="ShadowAtlasQuadrantSubdiv">
+ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_64" value="4" enum="PositionalShadowAtlasQuadrantSubdiv">
This quadrant will be split 64 ways and used by up to 64 shadow maps.
</constant>
- <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_256" value="5" enum="ShadowAtlasQuadrantSubdiv">
- This quadrant will be split 256 ways and used by up to 256 shadow maps. Unless the [member shadow_atlas_size] is very high, the shadows in this quadrant will be very low resolution.
+ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_256" value="5" enum="PositionalShadowAtlasQuadrantSubdiv">
+ This quadrant will be split 256 ways and used by up to 256 shadow maps. Unless the [member positional_shadow_atlas_size] is very high, the shadows in this quadrant will be very low resolution.
</constant>
- <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_1024" value="6" enum="ShadowAtlasQuadrantSubdiv">
- This quadrant will be split 1024 ways and used by up to 1024 shadow maps. Unless the [member shadow_atlas_size] is very high, the shadows in this quadrant will be very low resolution.
+ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_1024" value="6" enum="PositionalShadowAtlasQuadrantSubdiv">
+ This quadrant will be split 1024 ways and used by up to 1024 shadow maps. Unless the [member positional_shadow_atlas_size] is very high, the shadows in this quadrant will be very low resolution.
</constant>
- <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_MAX" value="7" enum="ShadowAtlasQuadrantSubdiv">
- Represents the size of the [enum ShadowAtlasQuadrantSubdiv] enum.
+ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_MAX" value="7" enum="PositionalShadowAtlasQuadrantSubdiv">
+ Represents the size of the [enum PositionalShadowAtlasQuadrantSubdiv] enum.
</constant>
<constant name="SCALING_3D_MODE_BILINEAR" value="0" enum="Scaling3DMode">
Use bilinear scaling for the viewport's 3D buffer. The amount of scaling can be set using [member scaling_3d_scale]. Values less then [code]1.0[/code] will result in undersampling while values greater than [code]1.0[/code] will result in supersampling. A value of [code]1.0[/code] disables scaling.
@@ -492,5 +498,17 @@
</constant>
<constant name="SDF_SCALE_MAX" value="3" enum="SDFScale">
</constant>
+ <constant name="VRS_DISABLED" value="0" enum="VRSMode">
+ VRS is disabled.
+ </constant>
+ <constant name="VRS_TEXTURE" value="1" enum="VRSMode">
+ VRS uses a texture. Note, for stereoscopic use a texture atlas with a texture for each view.
+ </constant>
+ <constant name="VRS_XR" value="2" enum="VRSMode">
+ VRS texture is supplied by the primary [XRInterface].
+ </constant>
+ <constant name="VRS_MAX" value="3" enum="VRSMode">
+ Represents the size of the [enum VRSMode] enum.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/VoxelGI.xml b/doc/classes/VoxelGI.xml
index 55ba1c4934..d941185d33 100644
--- a/doc/classes/VoxelGI.xml
+++ b/doc/classes/VoxelGI.xml
@@ -37,6 +37,7 @@
</member>
<member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3(10, 10, 10)">
The size of the area covered by the [VoxelGI]. If you make the extents larger without increasing the subdivisions with [member subdiv], the size of each cell will increase and result in lower detailed lighting.
+ [b]Note:[/b] Extents are clamped to 1.0 unit or more on each axis.
</member>
<member name="subdiv" type="int" setter="set_subdiv" getter="get_subdiv" enum="VoxelGI.Subdiv" default="1">
Number of times to subdivide the grid that the [VoxelGI] operates on. A higher number results in finer detail and thus higher visual quality, while lower numbers result in better performance.
diff --git a/doc/classes/WorkerThreadPool.xml b/doc/classes/WorkerThreadPool.xml
new file mode 100644
index 0000000000..22eabf9012
--- /dev/null
+++ b/doc/classes/WorkerThreadPool.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="WorkerThreadPool" inherits="Object" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_group_task">
+ <return type="int" />
+ <argument index="0" name="action" type="Callable" />
+ <argument index="1" name="elements" type="int" />
+ <argument index="2" name="tasks_needed" type="int" default="-1" />
+ <argument index="3" name="high_priority" type="bool" default="false" />
+ <argument index="4" name="description" type="String" default="&quot;&quot;" />
+ <description>
+ </description>
+ </method>
+ <method name="add_task">
+ <return type="int" />
+ <argument index="0" name="action" type="Callable" />
+ <argument index="1" name="high_priority" type="bool" default="false" />
+ <argument index="2" name="description" type="String" default="&quot;&quot;" />
+ <description>
+ </description>
+ </method>
+ <method name="is_group_task_completed" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="group_id" type="int" />
+ <description>
+ </description>
+ </method>
+ <method name="is_task_completed" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="task_id" type="int" />
+ <description>
+ </description>
+ </method>
+ <method name="wait_for_group_task_completion">
+ <return type="void" />
+ <argument index="0" name="group_id" type="int" />
+ <description>
+ </description>
+ </method>
+ <method name="wait_for_task_completion">
+ <return type="void" />
+ <argument index="0" name="task_id" type="int" />
+ <description>
+ </description>
+ </method>
+ </methods>
+</class>
diff --git a/doc/classes/XMLParser.xml b/doc/classes/XMLParser.xml
index c40a07c40a..79ab33045f 100644
--- a/doc/classes/XMLParser.xml
+++ b/doc/classes/XMLParser.xml
@@ -32,7 +32,7 @@
<method name="get_current_line" qualifiers="const">
<return type="int" />
<description>
- Gets the current line in the parsed file (currently not implemented).
+ Gets the current line in the parsed file, counting from 0.
</description>
</method>
<method name="get_named_attribute_value" qualifiers="const">
diff --git a/doc/classes/XRCamera3D.xml b/doc/classes/XRCamera3D.xml
index e0fc016a7d..4d6baa327b 100644
--- a/doc/classes/XRCamera3D.xml
+++ b/doc/classes/XRCamera3D.xml
@@ -8,6 +8,6 @@
The position and orientation of this node is automatically updated by the XR Server to represent the location of the HMD if such tracking is available and can thus be used by game logic. Note that, in contrast to the XR Controller, the render thread has access to the most up-to-date tracking data of the HMD and the location of the XRCamera3D can lag a few milliseconds behind what is used for rendering as a result.
</description>
<tutorials>
- <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link>
+ <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link>
</tutorials>
</class>
diff --git a/doc/classes/XRController3D.xml b/doc/classes/XRController3D.xml
index deea888b8f..ff4aec46e1 100644
--- a/doc/classes/XRController3D.xml
+++ b/doc/classes/XRController3D.xml
@@ -10,7 +10,7 @@
As many XR runtimes now use a configurable action map all inputs are named.
</description>
<tutorials>
- <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link>
+ <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link>
</tutorials>
<methods>
<method name="get_axis" qualifiers="const">
diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml
index 0f4159cbbf..26b7699af2 100644
--- a/doc/classes/XRInterface.xml
+++ b/doc/classes/XRInterface.xml
@@ -8,7 +8,7 @@
Interfaces should be written in such a way that simply enabling them will give us a working setup. You can query the available interfaces through [XRServer].
</description>
<tutorials>
- <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link>
+ <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link>
</tutorials>
<methods>
<method name="get_camera_feed_id">
diff --git a/doc/classes/XRInterfaceExtension.xml b/doc/classes/XRInterfaceExtension.xml
index 71f6a44724..1642ae61f7 100644
--- a/doc/classes/XRInterfaceExtension.xml
+++ b/doc/classes/XRInterfaceExtension.xml
@@ -106,6 +106,11 @@
Returns the number of views this interface requires, 1 for mono, 2 for stereoscopic.
</description>
</method>
+ <method name="_get_vrs_texture" qualifiers="virtual">
+ <return type="RID" />
+ <description>
+ </description>
+ </method>
<method name="_initialize" qualifiers="virtual">
<return type="bool" />
<description>
diff --git a/doc/classes/XROrigin3D.xml b/doc/classes/XROrigin3D.xml
index b7811f4d53..7acee097e7 100644
--- a/doc/classes/XROrigin3D.xml
+++ b/doc/classes/XROrigin3D.xml
@@ -10,7 +10,7 @@
For example, if your character is driving a car, the XROrigin3D node should be a child node of this car. Or, if you're implementing a teleport system to move your character, you should change the position of this node.
</description>
<tutorials>
- <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link>
+ <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link>
</tutorials>
<members>
<member name="world_scale" type="float" setter="set_world_scale" getter="get_world_scale" default="1.0">
diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml
index d15558c9e8..c146b27fcb 100644
--- a/doc/classes/XRPositionalTracker.xml
+++ b/doc/classes/XRPositionalTracker.xml
@@ -9,7 +9,7 @@
The [XRController3D] and [XRAnchor3D] both consume objects of this type and should be used in your project. The positional trackers are just under-the-hood objects that make this all work. These are mostly exposed so that GDExtension-based interfaces can interact with them.
</description>
<tutorials>
- <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link>
+ <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link>
</tutorials>
<methods>
<method name="get_input" qualifiers="const">
diff --git a/doc/classes/XRServer.xml b/doc/classes/XRServer.xml
index a322a3c5c9..d3cb958cbc 100644
--- a/doc/classes/XRServer.xml
+++ b/doc/classes/XRServer.xml
@@ -7,7 +7,7 @@
The AR/VR server is the heart of our Advanced and Virtual Reality solution and handles all the processing.
</description>
<tutorials>
- <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link>
+ <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link>
</tutorials>
<methods>
<method name="add_interface">
diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py
index ce09361dfa..312dffc7ee 100755
--- a/doc/tools/make_rst.py
+++ b/doc/tools/make_rst.py
@@ -36,6 +36,7 @@ BASE_STRINGS = [
"Signals",
"Enumerations",
"Constants",
+ "Annotations",
"Property Descriptions",
"Constructor Descriptions",
"Method Descriptions",
@@ -122,16 +123,18 @@ class MethodDef:
class ConstantDef:
- def __init__(self, name, value, text): # type: (str, str, Optional[str]) -> None
+ def __init__(self, name, value, text, bitfield): # type: (str, str, Optional[str], Optional[bool]) -> None
self.name = name
self.value = value
self.text = text
+ self.is_bitfield = bitfield
class EnumDef:
- def __init__(self, name): # type: (str) -> None
+ def __init__(self, name, bitfield): # type: (str, Optional[bool]) -> None
self.name = name
self.values = OrderedDict() # type: OrderedDict[str, ConstantDef]
+ self.is_bitfield = bitfield
class ThemeItemDef:
@@ -155,6 +158,7 @@ class ClassDef:
self.methods = OrderedDict() # type: OrderedDict[str, List[MethodDef]]
self.operators = OrderedDict() # type: OrderedDict[str, List[MethodDef]]
self.signals = OrderedDict() # type: OrderedDict[str, SignalDef]
+ self.annotations = OrderedDict() # type: OrderedDict[str, List[MethodDef]]
self.theme_items = OrderedDict() # type: OrderedDict[str, ThemeItemDef]
self.inherits = None # type: Optional[str]
self.brief_description = None # type: Optional[str]
@@ -305,7 +309,8 @@ class State:
constant_name = constant.attrib["name"]
value = constant.attrib["value"]
enum = constant.get("enum")
- constant_def = ConstantDef(constant_name, value, constant.text)
+ is_bitfield = constant.get("is_bitfield") or False
+ constant_def = ConstantDef(constant_name, value, constant.text, is_bitfield)
if enum is None:
if constant_name in class_def.constants:
print_error('{}.xml: Duplicate constant "{}".'.format(class_name, constant_name), self)
@@ -318,11 +323,32 @@ class State:
enum_def = class_def.enums[enum]
else:
- enum_def = EnumDef(enum)
+ enum_def = EnumDef(enum, is_bitfield)
class_def.enums[enum] = enum_def
enum_def.values[constant_name] = constant_def
+ annotations = class_root.find("annotations")
+ if annotations is not None:
+ for annotation in annotations:
+ assert annotation.tag == "annotation"
+
+ annotation_name = annotation.attrib["name"]
+ qualifiers = annotation.get("qualifiers")
+
+ params = parse_arguments(annotation)
+
+ desc_element = annotation.find("description")
+ annotation_desc = None
+ if desc_element is not None:
+ annotation_desc = desc_element.text
+
+ annotation_def = MethodDef(annotation_name, return_type, params, annotation_desc, qualifiers)
+ if annotation_name not in class_def.annotations:
+ class_def.annotations[annotation_name] = []
+
+ class_def.annotations[annotation_name].append(annotation_def)
+
signals = class_root.find("signals")
if signals is not None:
for signal in signals:
@@ -706,7 +732,11 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
for value in e.values.values():
f.write(".. _class_{}_constant_{}:\n\n".format(class_name, value.name))
- f.write("enum **{}**:\n\n".format(e.name))
+ if e.is_bitfield:
+ f.write("flags **{}**:\n\n".format(e.name))
+ else:
+ f.write("enum **{}**:\n\n".format(e.name))
+
for value in e.values.values():
f.write("- **{}** = **{}**".format(value.name, value.value))
if value.text is not None and value.text.strip() != "":
@@ -732,6 +762,26 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
f.write("\n\n")
+ if len(class_def.annotations) > 0:
+ f.write(make_heading("Annotations", "-"))
+ index = 0
+
+ for method_list in class_def.annotations.values():
+ for i, m in enumerate(method_list):
+ if index != 0:
+ f.write("----\n\n")
+
+ if i == 0:
+ f.write(".. _class_{}_annotation_{}:\n\n".format(class_name, m.name.strip("@")))
+
+ ret_type, signature = make_method_signature(class_def, m, "", state)
+ f.write("- {} {}\n\n".format(ret_type, signature))
+
+ if m.description is not None and m.description.strip() != "":
+ f.write(rstize_text(m.description.strip(), state) + "\n\n")
+
+ index += 1
+
# Property descriptions
if any(not p.overrides for p in class_def.properties.values()) > 0:
f.write(make_heading("Property Descriptions", "-"))
@@ -1065,6 +1115,11 @@ def rstize_text(text, state): # type: (str, State) -> str
print_error('{}.xml: Unresolved signal "{}".'.format(state.current_class, param), state)
ref_type = "_signal"
+ elif cmd.startswith("annotation"):
+ if method_param not in class_def.annotations:
+ print_error('{}.xml: Unresolved annotation "{}".'.format(state.current_class, param), state)
+ ref_type = "_annotation"
+
elif cmd.startswith("constant"):
found = False
diff --git a/doc/translations/ar.po b/doc/translations/ar.po
index 8354193353..a4488f3339 100644
--- a/doc/translations/ar.po
+++ b/doc/translations/ar.po
@@ -545,7 +545,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1258,7 +1258,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10132,7 +10132,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10297,7 +10303,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12308,10 +12320,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19607,13 +19621,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19623,7 +19641,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19640,23 +19662,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28458,7 +28480,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28597,13 +28619,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30018,7 +30041,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30592,10 +30618,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30607,6 +30637,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30919,6 +30955,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31083,7 +31124,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34834,12 +34886,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "ÙŠÙØ±Ø¬Ø¹ باقي قسمة كل من Ø§Ù„Ù…ÙØªØ¬Ù‡ÙŠÙ† (الشعاعين)."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -34875,7 +34933,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35674,6 +35735,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35720,6 +35784,9 @@ msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35763,6 +35830,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35782,6 +35852,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35917,11 +35990,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36037,6 +36146,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
@@ -36249,20 +36375,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36358,6 +36504,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36479,6 +36633,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36649,7 +36813,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38531,13 +38703,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38549,7 +38727,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38559,15 +38740,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40279,6 +40466,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45389,6 +45580,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45801,7 +45999,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49377,20 +49586,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49398,19 +49615,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49442,14 +49668,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49903,8 +50137,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54140,24 +54374,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54166,8 +54399,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54175,16 +54409,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54196,7 +54430,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54226,21 +54460,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54276,11 +54513,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54321,13 +54558,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54391,10 +54628,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54448,8 +54685,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54480,16 +54717,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54497,7 +54733,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55806,11 +56042,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58277,7 +58532,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58467,11 +58746,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58874,9 +59153,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60421,6 +60702,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب التمام \"cosine \" لقيمة المَعلم."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63353,7 +63639,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65806,11 +66103,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65890,8 +66187,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66498,9 +66795,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66529,7 +66827,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/ca.po b/doc/translations/ca.po
index 234b5cd60c..bd84c415cc 100644
--- a/doc/translations/ca.po
+++ b/doc/translations/ca.po
@@ -507,7 +507,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1214,7 +1214,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10078,7 +10078,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10243,7 +10249,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12252,10 +12264,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19537,13 +19551,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19553,7 +19571,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19570,23 +19592,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28377,7 +28399,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28516,13 +28538,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29935,7 +29958,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30509,10 +30535,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30524,6 +30554,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30835,6 +30871,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30999,7 +31040,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34746,11 +34798,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34787,7 +34844,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35579,6 +35639,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35624,6 +35687,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35667,6 +35733,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35686,6 +35755,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35815,11 +35887,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35929,6 +36037,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36135,20 +36260,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36242,6 +36387,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36362,6 +36515,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36531,7 +36694,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38406,13 +38577,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38424,7 +38601,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38434,15 +38614,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40149,6 +40335,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45237,6 +45427,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45649,7 +45846,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49222,20 +49430,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49243,19 +49459,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49287,14 +49512,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49748,8 +49981,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53983,24 +54216,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54009,8 +54241,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54018,16 +54251,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54039,7 +54272,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54069,21 +54302,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54119,11 +54355,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54164,13 +54400,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54234,10 +54470,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54291,8 +54527,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54323,16 +54559,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54340,7 +54575,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55649,11 +55884,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58118,7 +58372,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58308,11 +58586,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58715,9 +58993,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60254,6 +60534,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63183,7 +63467,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65629,11 +65924,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65713,8 +66008,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66317,9 +66612,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66348,7 +66644,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/classes.pot b/doc/translations/classes.pot
index 72d9388f80..90ebdbf9f3 100644
--- a/doc/translations/classes.pot
+++ b/doc/translations/classes.pot
@@ -387,7 +387,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1094,7 +1094,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9958,7 +9958,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10123,7 +10129,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12132,10 +12144,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19417,13 +19431,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19433,7 +19451,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19450,23 +19472,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28254,7 +28276,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28393,13 +28415,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29812,7 +29835,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30386,10 +30412,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30401,6 +30431,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30712,6 +30748,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30876,7 +30917,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34623,11 +34675,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34664,7 +34721,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35456,6 +35516,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35501,6 +35564,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35544,6 +35610,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35563,6 +35632,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35692,11 +35764,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35806,6 +35914,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36012,20 +36137,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36119,6 +36264,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36239,6 +36392,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36408,7 +36571,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38283,13 +38454,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38301,7 +38478,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38311,15 +38491,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40026,6 +40212,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45114,6 +45304,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45526,7 +45723,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49099,20 +49307,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49120,19 +49336,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49164,14 +49389,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49625,8 +49858,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53860,24 +54093,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53886,8 +54118,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53895,16 +54128,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53916,7 +54149,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53946,21 +54179,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -53996,11 +54232,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54041,13 +54277,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54111,10 +54347,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54168,8 +54404,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54200,16 +54436,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54217,7 +54452,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55526,11 +55761,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -57995,7 +58249,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58185,11 +58463,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58592,9 +58870,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60131,6 +60411,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63060,7 +63344,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65506,7 +65801,7 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set "
"to [code]true[/code] and are in contact with a surface. The [member "
"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
@@ -65590,7 +65885,7 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
+"Accelerates the wheel by applying an engine force. The wheel is only sped "
"up if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
@@ -66194,9 +66489,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66225,7 +66521,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/cs.po b/doc/translations/cs.po
index 4b60e4d7c4..48a79d9ec3 100644
--- a/doc/translations/cs.po
+++ b/doc/translations/cs.po
@@ -542,7 +542,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1574,7 +1574,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10475,7 +10475,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10640,7 +10646,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12653,10 +12665,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19985,13 +19999,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20001,7 +20019,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20018,23 +20040,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28847,7 +28869,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28986,13 +29008,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30408,7 +30431,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30982,10 +31008,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30996,6 +31026,15 @@ msgid "Mouse and input coordinates"
msgstr ""
#: doc/classes/InputEventMouseMotion.xml
+#, fuzzy
+msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+"Vrací [code]true[/code] pokud si jsou [code]a[/code] a [code]b[/code] "
+"přiblížně rovny."
+
+#: doc/classes/InputEventMouseMotion.xml
msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
@@ -31309,6 +31348,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31473,7 +31517,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -35229,12 +35284,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Vrátí zbytek po dělení dvou vektorů."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -35270,7 +35331,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -36070,6 +36134,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -36116,6 +36183,9 @@ msgstr "Vrátí sinus parametru."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -36159,6 +36229,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -36178,6 +36251,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36314,11 +36390,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36434,6 +36546,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Vrací [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "Vrací [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula."
@@ -36648,20 +36777,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36757,6 +36906,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36881,6 +37038,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -37051,7 +37218,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38933,13 +39108,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38951,7 +39132,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38961,15 +39145,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40685,6 +40875,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45805,6 +45999,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -46218,7 +46419,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49795,20 +50007,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49816,19 +50036,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49860,14 +50089,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50321,8 +50558,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54566,24 +54803,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54592,8 +54828,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54601,16 +54838,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54622,7 +54859,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54652,21 +54889,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54702,11 +54942,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54747,13 +54987,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54817,10 +55057,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54874,8 +55114,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54906,16 +55146,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54923,7 +55162,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56233,11 +56472,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58711,7 +58969,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58901,11 +59183,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -59308,9 +59590,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60865,6 +61149,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "Vrátí [code] true [/code], pokud je vektor normalizován, jinak false."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63819,7 +64108,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -66279,11 +66579,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -66363,8 +66663,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66975,9 +67275,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -67006,7 +67307,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/de.po b/doc/translations/de.po
index 640725bd9a..ba4e24c02b 100644
--- a/doc/translations/de.po
+++ b/doc/translations/de.po
@@ -47,12 +47,13 @@
# Andreas <self@andreasbresser.de>, 2022.
# Christian Packenius <christian@packenius.com>, 2022.
# Hannes Petersen <01zustrom.baklava@icloud.com>, 2022.
+# Hans Peter <figefi6308@runqx.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-05-13 19:27+0000\n"
-"Last-Translator: Hannes Petersen <01zustrom.baklava@icloud.com>\n"
+"PO-Revision-Date: 2022-06-22 23:17+0000\n"
+"Last-Translator: Hans Peter <figefi6308@runqx.com>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/de/>\n"
"Language: de\n"
@@ -60,7 +61,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -606,7 +607,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1774,7 +1775,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -12025,7 +12026,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -12191,7 +12198,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -14221,10 +14234,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -21702,13 +21717,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -21718,7 +21737,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -21735,23 +21758,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -30628,7 +30651,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -30767,13 +30790,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -32198,7 +32222,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -32772,10 +32799,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -32786,6 +32817,14 @@ msgid "Mouse and input coordinates"
msgstr ""
#: doc/classes/InputEventMouseMotion.xml
+#, fuzzy
+msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+"Liefert [code]true[/code] wenn die Länge der Zeichenkette [code]0[/code] ist."
+
+#: doc/classes/InputEventMouseMotion.xml
msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
@@ -33103,6 +33142,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -33267,7 +33311,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34560,6 +34615,8 @@ msgid ""
"Displays plain text in a line or wrapped inside a rectangle. For formatted "
"text, use [RichTextLabel]."
msgstr ""
+"Zeigt einfachen Text in einer Zeile oder in einem Rechteck an. Verwenden Sie "
+"für formatierten Text [RichTextLabel]."
#: doc/classes/Label.xml
msgid ""
@@ -34576,6 +34633,19 @@ msgid ""
"emoji) are [i]not[/i] supported on Windows. They will display as unknown "
"characters instead. This will be resolved in Godot 4.0."
msgstr ""
+"Label zeigt einfachen Text auf dem Bildschirm an. Sie können die horizontale "
+"und vertikale Ausrichtung steuern und den Text innerhalb des "
+"Begrenzungsrahmens des Nodes umbrechen. Fett, kursiv oder andere "
+"Formatierungen werden nicht unterstützt. Verwenden Sie stattdessen "
+"[RichTextLabel] für diesen Zweck.\n"
+"[b]Hinweis:[/b] Im Gegensatz zu den meisten anderen [Steuerelementen] ist "
+"Labels [member Control.mouse_filter] standardmäßig auf [constant Control."
+"MOUSE_FILTER_IGNORE] eingestellt (d.h. es reagiert nicht auf Mauseingaben). "
+"Das bedeutet, dass ein Label keinen konfigurierten [member Control."
+"hint_tooltip] anzeigt, solange Sie seinen Mausfilter nicht ändern.\n"
+"[b]Hinweis:[/b] Unicode-Zeichen nach [code]0xffff[/code] (wie die meisten "
+"Emoji) werden [i]nicht[/i] von Windows unterstützt. Sie werden stattdessen "
+"als unbekannte Zeichen angezeigt. Dies wird in Godot 4.0 behoben."
#: doc/classes/Label.xml
msgid "Returns the amount of lines of text the Label has."
@@ -34602,6 +34672,9 @@ msgid ""
"Controls the text's horizontal align. Supports left, center, right, and "
"fill, or justify. Set it to one of the [enum Align] constants."
msgstr ""
+"Steuert die horizontale Ausrichtung des Textes. Unterstützt links, "
+"zentriert, rechts und füllen oder ausrichten. Setzen Sie ihn auf eine der "
+"[enum Align] Konstanten."
#: doc/classes/Label.xml
msgid ""
@@ -34609,12 +34682,19 @@ msgid ""
"If you resize the node, it will change its height automatically to show all "
"the text."
msgstr ""
+"Wenn [code]An[/code], wird der Text innerhalb des Begrenzungsrechtecks des "
+"Nodes angepasst (Es wird automatisch eine neue Zeile angefangen, wenn der "
+"Text nicht in eine Zeile passt). Sollte der Text nicht in das "
+"Begrenzungsrechtecks des Nodes passen, wird das Begrenzungsrechteck "
+"automatisch in der Höhe angepasst."
#: doc/classes/Label.xml
msgid ""
"If [code]true[/code], the Label only shows the text that fits inside its "
"bounding rectangle and will clip text horizontally."
msgstr ""
+"Wenn [code]An[/code], zeigt das Label nur den Text, der in sein "
+"Begrenzungsrechteck passt an und schneidet den restlichen Text ab."
#: doc/classes/Label.xml
msgid ""
@@ -34624,7 +34704,7 @@ msgstr ""
#: doc/classes/Label.xml
msgid "Limits the lines of text the node shows on screen."
-msgstr ""
+msgstr "Begrenzt die Textzeilen, die das Node auf dem Bildschirm anzeigt."
#: doc/classes/Label.xml
msgid ""
@@ -34632,24 +34712,32 @@ msgid ""
"code] to 0.5, only up to half of the text's characters will display on "
"screen. Useful to animate the text in a dialog box."
msgstr ""
+"Begrenzt die Anzahl der sichtbaren Zeichen. Wenn Sie [code]percent_visible[/"
+"code] auf 0,5 setzen, wird nur der halbe Text auf dem Bildschirm angezeigt. "
+"Nützlich, um den Text in einem Dialogfeld zu animieren."
#: doc/classes/Label.xml doc/classes/Label3D.xml
msgid "The text to display on screen."
-msgstr ""
+msgstr "Der Text, der auf dem Bildschirm angezeigt werden soll."
#: doc/classes/Label.xml doc/classes/Label3D.xml doc/classes/TextMesh.xml
msgid "If [code]true[/code], all the text displays as UPPERCASE."
msgstr ""
+"Wenn [code]An[/code] , wird der gesamte Text in GROSSBUCHSTABEN angezeigt."
#: doc/classes/Label.xml
msgid ""
"Controls the text's vertical align. Supports top, center, bottom, and fill. "
"Set it to one of the [enum VAlign] constants."
msgstr ""
+"Steuert die vertikale Ausrichtung des Textes. Unterstützt oben, mitte, unten "
+"und füllen. Setzen Sie ihn auf eine der [enum VAlign] Konstanten."
#: doc/classes/Label.xml
msgid "Restricts the number of characters to display. Set to -1 to disable."
msgstr ""
+"Begrenzt die Anzahl der anzuzeigenden Zeichen. Zum Deaktivieren auf -1 "
+"setzen."
#: doc/classes/Label.xml doc/classes/Label3D.xml doc/classes/TextMesh.xml
msgid "Align rows to the left (default)."
@@ -37043,12 +37131,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Gibt die Anzahl der Punkte auf der Blend-Achse zurück."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -37084,7 +37178,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -37884,6 +37981,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -37930,6 +38030,9 @@ msgstr "Gibt die Anzahl der Spuren in der Animation zurück."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -37974,6 +38077,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -37993,6 +38099,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -38137,11 +38246,47 @@ msgid "Destroys the given RID."
msgstr "Gibt den gegebenen Übergang zurück."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -38264,6 +38409,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Logischer ODER-Operator ([code]oder[/code] oder [code]||[/code])."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "Logischer ODER-Operator ([code]oder[/code] oder [code]||[/code])."
@@ -38484,21 +38646,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
-msgid "The radius of the agent."
-msgstr "Der Name des Audiobusses des Bereichs."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
+msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -38596,6 +38777,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -38719,6 +38908,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr "Wenn [code]true[/code], ist die Filterung aktiviert."
@@ -38895,7 +39094,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -40787,13 +40994,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -40805,7 +41018,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -40815,15 +41031,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -42542,6 +42764,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -47700,6 +47926,14 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+#, fuzzy
+msgid "Sorts the elements of the array in ascending order."
+msgstr "Entfernt das Element der Arrays dessen Position übergeben wurde."
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -48152,7 +48386,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -51747,20 +51992,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -51768,19 +52021,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -51812,14 +52074,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -52273,8 +52543,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -56573,24 +56843,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -56599,8 +56868,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -56608,16 +56878,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -56629,7 +56899,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56659,21 +56929,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -56709,11 +56982,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56754,13 +57027,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -56824,10 +57097,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -56881,8 +57154,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -56913,16 +57186,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -56930,7 +57202,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -58251,11 +58523,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -60770,7 +61061,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -60960,11 +61275,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -61371,9 +61686,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -62947,6 +63264,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "Wenn [code]true[/code], wird die Textur zentriert."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -65929,7 +66251,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -68548,11 +68881,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -68632,8 +68965,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -69249,9 +69582,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -69283,7 +69617,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/el.po b/doc/translations/el.po
index e19557ebb4..c7236b41df 100644
--- a/doc/translations/el.po
+++ b/doc/translations/el.po
@@ -402,7 +402,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1109,7 +1109,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9976,7 +9976,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10141,7 +10147,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12152,10 +12164,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19452,13 +19466,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19468,7 +19486,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19485,23 +19507,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28303,7 +28325,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28442,13 +28464,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29863,7 +29886,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30437,10 +30463,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30452,6 +30482,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30764,6 +30800,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30928,7 +30969,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34679,12 +34731,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "ΕπιστÏέφει το υπόλοιπο των 2 διανυσμάτων."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -34720,7 +34778,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35513,6 +35574,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35559,6 +35623,9 @@ msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35602,6 +35669,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35621,6 +35691,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35756,11 +35829,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35876,6 +35985,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
@@ -36088,20 +36214,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36197,6 +36343,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36318,6 +36472,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36488,7 +36652,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38370,13 +38542,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38388,7 +38566,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38398,15 +38579,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40118,6 +40305,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45215,6 +45406,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45627,7 +45825,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49203,20 +49412,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49224,19 +49441,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49268,14 +49494,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49729,8 +49963,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53966,24 +54200,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53992,8 +54225,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54001,16 +54235,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54022,7 +54256,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54052,21 +54286,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54102,11 +54339,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54147,13 +54384,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54217,10 +54454,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54274,8 +54511,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54306,16 +54543,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54323,7 +54559,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55632,11 +55868,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58103,7 +58358,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58293,11 +58572,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58700,9 +58979,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60247,6 +60528,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "ΕπιστÏέφει το συνημίτονο της παÏαμέτÏου."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63179,7 +63465,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65632,11 +65929,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65716,8 +66013,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66324,9 +66621,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66355,7 +66653,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/es.po b/doc/translations/es.po
index 4c4982ad59..50425a97d9 100644
--- a/doc/translations/es.po
+++ b/doc/translations/es.po
@@ -599,7 +599,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1749,7 +1749,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -13142,8 +13142,14 @@ msgstr ""
"escena."
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
-msgstr "El bus en el que se está reproduciendo este audio."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
+msgstr ""
#: doc/classes/AudioStreamPlayer.xml
msgid ""
@@ -13329,9 +13335,14 @@ msgstr ""
"escena."
#: doc/classes/AudioStreamPlayer3D.xml
-#, fuzzy
-msgid "The bus on which this audio is playing."
-msgstr "El bus en el que se está reproduciendo este audio."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
+msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
@@ -15915,10 +15926,12 @@ msgstr ""
"horizontales y el tamaño de la pantalla."
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr "La cámara se actualiza con la llamada [code]_physics_process[/code]."
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr "La cámara se actualiza con la llamada de [code]_process[/code]."
@@ -25571,16 +25584,18 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
-"Si [code]true[/code], el detalle de la sombra se sacrifica a cambio de "
-"transiciones más suaves entre las divisiones."
#: doc/classes/DirectionalLight.xml
msgid ""
@@ -25591,8 +25606,12 @@ msgstr ""
"movimiento. Ver [enum ShadowDepthRange]."
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
-msgstr "La distancia máxima para las divisiones de la sombra."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
+msgstr ""
#: doc/classes/DirectionalLight.xml
msgid "The light's shadow rendering algorithm. See [enum ShadowMode]."
@@ -25606,11 +25625,12 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
+#, fuzzy
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
"La distancia de la cámara a la sombra se divide en 1. Relativo a [member "
"directional_shadow_max_distance]. Sólo se utiliza cuando [member "
@@ -25618,11 +25638,12 @@ msgstr ""
"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
#: doc/classes/DirectionalLight.xml
+#, fuzzy
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
"La distancia de la sombra se divide en dos. Relativo a [member "
"directional_shadow_max_distance]. Sólo se utiliza cuando [member "
@@ -25630,10 +25651,11 @@ msgstr ""
"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
#: doc/classes/DirectionalLight.xml
+#, fuzzy
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
"La distancia de la sombra se divide en dos y tres. Relativo a [member "
"directional_shadow_max_distance]. Sólo se usa cuando [member "
@@ -37418,7 +37440,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -37667,13 +37689,14 @@ msgstr "Número máximo de redirecciones permitidas."
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -39542,7 +39565,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
"Habilita o deshabilita la acumulación de eventos de entrada similares "
"enviados por el sistema operativo. Cuando la acumulación de entrada está "
@@ -40301,10 +40327,14 @@ msgstr "Tipo de evento de entrada para los eventos de movimiento del ratón."
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -40327,6 +40357,15 @@ msgid "Mouse and input coordinates"
msgstr "Medio desplazamiento en la coordenada X."
#: doc/classes/InputEventMouseMotion.xml
+#, fuzzy
+msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+"Devuelve el número de disposiciones del teclado.\n"
+"[b]Nota:[/b] Este método está implementado en Linux, macOS y Windows."
+
+#: doc/classes/InputEventMouseMotion.xml
msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
@@ -40745,6 +40784,12 @@ msgstr ""
"automáticamente el nuevo contenido."
#: doc/classes/InterpolatedCamera.xml
+#, fuzzy
+msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr "La llamada al proceso de la cámara. Ver [enum Camera2DProcessMode]."
+
+#: doc/classes/InterpolatedCamera.xml
msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
@@ -40959,7 +41004,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
"Este control proporciona una lista seleccionable de elementos que pueden "
"estar en una sola (o varias columnas) con opción de texto, iconos o ambos. "
@@ -45877,14 +45933,17 @@ msgstr ""
"material de anulación."
#: doc/classes/MeshInstance.xml
-#, fuzzy
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
-"Devuelve el [Material] sobreescrito para la superficie especificada del "
-"recurso [Mesh]."
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+#, fuzzy
+msgid "Returns the number of surface override materials."
msgstr "Devuelve el número de materiales de la superficie."
#: doc/classes/MeshInstance.xml
@@ -45921,11 +45980,11 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-#, fuzzy
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
-"Devuelve el [Material] sobreescrito para la superficie especificada del "
-"recurso [Mesh]."
#: doc/classes/MeshInstance.xml
msgid "The [Mesh] resource for the instance."
@@ -46972,6 +47031,9 @@ msgstr "Nodo de navegación y busqueda de caminos basado en una malla."
#: doc/classes/Navigation.xml
#, fuzzy
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -47030,6 +47092,9 @@ msgstr "Devuelve el [RID] de la forma enésima de un área."
#: doc/classes/Navigation.xml
#, fuzzy
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -47082,6 +47147,9 @@ msgstr "Navegación 2D y nodo de búsqueda de caminos."
#: doc/classes/Navigation2D.xml
#, fuzzy
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -47105,6 +47173,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
#, fuzzy
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -47252,12 +47323,48 @@ msgid "Destroys the given RID."
msgstr "Quita la identificación del tile dado."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Create a new map."
msgstr "Crea un [Area2D]."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -47387,6 +47494,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Devuelve [code]true[/code] si existe la [code]signal[/code] dada."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -47611,21 +47735,40 @@ msgstr "La instancia no tiene un tipo."
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
-msgid "The radius of the agent."
-msgstr "El radio del cilindro."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
+msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -47723,6 +47866,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -47862,6 +48013,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr "Si [code]true[/code], se activan las pulsaciones de paso."
@@ -48045,7 +48206,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -50740,13 +50909,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -50758,28 +50933,39 @@ msgid "Emitted when the node is renamed."
msgstr "Emitido cuando el nodo es renombrado."
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
-msgstr "Emitido cuando el nodo entra en el árbol."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
+msgstr ""
#: doc/classes/Node.xml
msgid "Emitted after the node exits the tree and is no longer active."
msgstr "Emitido después de que el nodo sale del árbol y ya no está activo."
#: doc/classes/Node.xml
+#, fuzzy
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
"Emitido cuando el nodo está todavía activo pero a punto de salir del árbol. "
"Este es el lugar adecuado para la des-inicialización (o un \"destructor\", "
"si se quiere)."
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
-msgstr "Notificación recibida cuando el nodo entra en un [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
+msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+#, fuzzy
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
"Notificación recibida cuando el nodo está a punto de salir de un [SceneTree]."
@@ -53118,6 +53304,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
"Devuelve los argumentos de la línea de mando pasados al motor.\n"
@@ -59911,6 +60101,14 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr "Cambia el byte en el índice dado."
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+#, fuzzy
+msgid "Sorts the elements of the array in ascending order."
+msgstr "Elimina un elemento del array por indice."
+
#: doc/classes/PoolByteArray.xml
#, fuzzy
msgid ""
@@ -60447,10 +60645,19 @@ msgstr "El PopupMenu muestra una lista de opciones."
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
-"[PopupMenu] es un [Control] que muestra una lista de opciones. Son populares "
-"en las barras de herramientas o en los menús contextuales."
#: doc/classes/PopupMenu.xml
msgid ""
@@ -64918,20 +65125,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -64939,19 +65154,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -64983,14 +65207,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -65547,12 +65779,13 @@ msgstr ""
"documentación del mapeo de sombras."
#: doc/classes/ProjectSettings.xml
+#, fuzzy
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
-"Tamaño para el atlas de sombras (usado para OmniLights y SpotLights). Vea la "
-"documentación."
+"Establece el tamaño de las imágenes del atlas de sombras (usado para omni y "
+"focos). El valor se redondeará a la potencia más cercana de 2."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -71099,24 +71332,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -71125,8 +71357,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -71134,16 +71367,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -71155,7 +71388,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -71185,21 +71418,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -71235,11 +71471,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -71280,13 +71516,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -71350,10 +71586,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -71407,8 +71643,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -71439,16 +71675,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -71456,7 +71691,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -73105,11 +73340,41 @@ msgstr ""
#: doc/classes/Spatial.xml
#, fuzzy
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+"Parte de la rotación de la transformación local en radianes, especificada en "
+"términos de ángulos YXZ-Euler en el formato (ángulo X, ángulo Y, ángulo Z).\n"
+"[b]Nota:[/b] En el sentido matemático, la rotación es una matriz y no un "
+"vector. Los tres ángulos de Euler, que son los tres parámetros "
+"independientes de la parametrización del ángulo de Euler de la matriz de "
+"rotación, se almacenan en una estructura de datos [Vector3] no porque la "
+"rotación sea un vector, sino sólo porque el [Vector3] existe como una "
+"estructura de datos conveniente para almacenar 3 números reales. Por lo "
+"tanto, la aplicación de operaciones afines en el \"vector\" de rotación no "
+"es significativa."
+
+#: doc/classes/Spatial.xml
+#, fuzzy
msgid "World space (global) [Transform] of this node."
msgstr "World3D espacio (global) [Transform] de este nodo."
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -76242,10 +76507,32 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
-"Formatea la string reemplazando todas las ocurrencias de [code]placeholder[/"
-"code] por [code]values[/code]."
#: doc/classes/String.xml
msgid "If the string is a valid file path, returns the base directory name."
@@ -76497,11 +76784,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
"Devuelve [code]true[/code] si esta string es un identificador válido. Un "
@@ -77015,13 +77302,12 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
-"Dibuja este cuadro de estilo usando un [CanvasItem] con un [RID] dado.\n"
-"Puedes obtener un valor [RID] usando el [method Object.get_instance_id] en "
-"un nodo derivado de [CanvasItem]."
#: doc/classes/StyleBox.xml
msgid "Returns the size of this [StyleBox] without the margins."
@@ -79002,6 +79288,11 @@ msgstr ""
"contextual."
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "Si [code]true[/code], el cuerpo puede ser detectado por los rayos."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -82666,6 +82957,7 @@ msgid "Control to show a tree of items."
msgstr "Control para mostrar un árbol de objetos."
#: doc/classes/Tree.xml
+#, fuzzy
msgid ""
"This shows a tree of items that can be selected, expanded and collapsed. The "
"tree can have multiple columns with custom controls like text editing, "
@@ -82687,7 +82979,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
"Esto muestra un árbol de objetos que pueden ser seleccionados, expandidos y "
"colapsados. El árbol puede tener múltiples columnas con controles "
@@ -86063,11 +86366,11 @@ msgstr ""
#, fuzzy
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -86191,8 +86494,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
#, fuzzy
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -86972,12 +87275,14 @@ msgstr ""
"La cantidad de subdivisión del cuarto cuadrante en el atlas de las sombras."
#: doc/classes/Viewport.xml
+#, fuzzy
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
"La resolución del atlas de las sombras (usado para luces omni y spot). El "
"valor se redondeará a la potencia más cercana de 2.\n"
@@ -87014,9 +87319,12 @@ msgid ""
msgstr "Si [code]true[/code], el viewport debería hacer su fondo transparente."
#: doc/classes/Viewport.xml
-#, fuzzy
-msgid "The rendering mode of viewport."
-msgstr "El modo de selección a utilizar."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
+msgstr ""
#: doc/classes/Viewport.xml
msgid ""
diff --git a/doc/translations/fa.po b/doc/translations/fa.po
index ee4b608fbd..5f170b2b28 100644
--- a/doc/translations/fa.po
+++ b/doc/translations/fa.po
@@ -15,12 +15,13 @@
# ahmad maftoon <ahmadmaftoon.1387@gmail.com>, 2021.
# Seyed Fazel Alavi <fazel8195@gmail.com>, 2022.
# Giga hertz <gigahertzyt@gmail.com>, 2022.
+# ilia khormali <iliakhormaly1384@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-04-03 08:11+0000\n"
-"Last-Translator: Giga hertz <gigahertzyt@gmail.com>\n"
+"PO-Revision-Date: 2022-06-21 15:55+0000\n"
+"Last-Translator: ilia khormali <iliakhormaly1384@gmail.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/fa/>\n"
"Language: fa\n"
@@ -28,7 +29,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.12-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -106,6 +107,7 @@ msgstr ""
msgid ""
"This method should typically be overridden by the user to have any effect."
msgstr ""
+"این روش معمولا نیازمند است توسط خود ÙØ±Ø¯ نوشته شود تا بتواند تاثییری بگذارد."
#: doc/tools/make_rst.py
msgid ""
@@ -548,7 +550,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1527,7 +1529,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10397,7 +10399,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10562,7 +10570,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12571,10 +12585,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19856,13 +19872,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19872,7 +19892,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19889,23 +19913,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28696,7 +28720,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28835,13 +28859,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30254,7 +30279,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30828,10 +30856,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30843,6 +30875,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -31154,6 +31192,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31318,7 +31361,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -35065,11 +35119,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35106,7 +35165,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35904,6 +35966,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35949,6 +36014,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35992,6 +36060,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -36011,6 +36082,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36140,11 +36214,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36254,6 +36364,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36460,20 +36587,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36567,6 +36714,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36687,6 +36842,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36856,7 +37021,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38731,13 +38904,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38749,7 +38928,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38759,15 +38941,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40474,6 +40662,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45574,6 +45766,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45986,7 +46185,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49559,20 +49769,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49580,19 +49798,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49624,14 +49851,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50085,8 +50320,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54324,24 +54559,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54350,8 +54584,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54359,16 +54594,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54380,7 +54615,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54410,21 +54645,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54460,11 +54698,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54505,13 +54743,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54575,10 +54813,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54632,8 +54870,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54664,16 +54902,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54681,7 +54918,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55990,11 +56227,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58459,7 +58715,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58649,11 +58929,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -59056,9 +59336,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60595,6 +60877,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63524,7 +63810,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65970,11 +66267,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -66054,8 +66351,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66658,9 +66955,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66689,7 +66987,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/fi.po b/doc/translations/fi.po
index 108f9f7780..0ab098fd33 100644
--- a/doc/translations/fi.po
+++ b/doc/translations/fi.po
@@ -469,7 +469,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1176,7 +1176,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10049,7 +10049,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10214,7 +10220,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12226,10 +12238,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19528,13 +19542,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19544,7 +19562,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19561,23 +19583,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28386,7 +28408,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28525,13 +28547,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29946,7 +29969,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30520,10 +30546,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30535,6 +30565,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30847,6 +30883,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31011,7 +31052,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34763,12 +34815,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Palauttaa kahden vektorin jäännöksen."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -34804,7 +34862,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35597,6 +35658,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35643,6 +35707,9 @@ msgstr "Palauttaa parametrin sinin."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35686,6 +35753,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35705,6 +35775,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35840,11 +35913,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35960,6 +36069,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Laskee kahden vektorin ristitulon."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "Laskee kahden vektorin ristitulon."
@@ -36173,20 +36299,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36282,6 +36428,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36403,6 +36557,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36573,7 +36737,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38455,13 +38627,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38473,7 +38651,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38483,15 +38664,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40203,6 +40390,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45300,6 +45491,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45712,7 +45910,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49288,20 +49497,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49309,19 +49526,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49353,14 +49579,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49814,8 +50048,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54051,24 +54285,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54077,8 +54310,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54086,16 +54320,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54107,7 +54341,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54137,21 +54371,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54187,11 +54424,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54232,13 +54469,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54302,10 +54539,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54359,8 +54596,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54391,16 +54628,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54408,7 +54644,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55718,11 +55954,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58190,7 +58445,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58380,11 +58659,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58787,9 +59066,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60335,6 +60616,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "Palauttaa parametrin kosinin."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63269,7 +63555,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65725,11 +66022,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65809,8 +66106,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66417,9 +66714,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66448,7 +66746,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/fil.po b/doc/translations/fil.po
index d34766797c..2dabe612e9 100644
--- a/doc/translations/fil.po
+++ b/doc/translations/fil.po
@@ -403,7 +403,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1110,7 +1110,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9974,7 +9974,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10139,7 +10145,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12148,10 +12160,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19433,13 +19447,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19449,7 +19467,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19466,23 +19488,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28273,7 +28295,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28412,13 +28434,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29831,7 +29854,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30405,10 +30431,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30420,6 +30450,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30731,6 +30767,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30895,7 +30936,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34642,11 +34694,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34683,7 +34740,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35475,6 +35535,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35520,6 +35583,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35563,6 +35629,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35582,6 +35651,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35711,11 +35783,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35825,6 +35933,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36031,20 +36156,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36138,6 +36283,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36258,6 +36411,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36427,7 +36590,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38302,13 +38473,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38320,7 +38497,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38330,15 +38510,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40045,6 +40231,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45133,6 +45323,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45545,7 +45742,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49118,20 +49326,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49139,19 +49355,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49183,14 +49408,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49644,8 +49877,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53879,24 +54112,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53905,8 +54137,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53914,16 +54147,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53935,7 +54168,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53965,21 +54198,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54015,11 +54251,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54060,13 +54296,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54130,10 +54366,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54187,8 +54423,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54219,16 +54455,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54236,7 +54471,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55545,11 +55780,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58014,7 +58268,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58204,11 +58482,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58611,9 +58889,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60150,6 +60430,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63079,7 +63363,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65525,11 +65820,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65609,8 +65904,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66213,9 +66508,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66244,7 +66540,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/fr.po b/doc/translations/fr.po
index 98f4921109..9d5c5f4a01 100644
--- a/doc/translations/fr.po
+++ b/doc/translations/fr.po
@@ -61,7 +61,7 @@ msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-19 11:54+0000\n"
+"PO-Revision-Date: 2022-07-18 08:12+0000\n"
"Last-Translator: Maxime Leroy <lisacintosh@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/fr/>\n"
@@ -70,7 +70,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.13.1-dev\n"
+"X-Generator: Weblate 4.14-dev\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -608,6 +608,7 @@ msgstr ""
"nouveau en une instance. Utile pour la désérialisation."
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns an \"eased\" value of [code]x[/code] based on an easing function "
"defined with [code]curve[/code]. This easing function is based on an "
@@ -622,7 +623,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1003,13 +1004,16 @@ msgid ""
"To perform eased interpolation with [method lerp], combine it with [method "
"ease] or [method smoothstep]."
msgstr ""
-"Interpolation linéaire entre deux valeurs par une valeur normalisée. C'est "
-"l'inverse de [method inverse_lerp].\n"
+"L'interpolation linéaire entre deux valeurs avec un facteur défini par "
+"[code]weight[/code]. Pour faire une interpolation, [code]weight[/code] doit "
+"être entre [code]0.0[/code] et [code]1.0[/code] (inclus). Pour autant, des "
+"valeurs en dehors de cet intervalle sont autorisés pour faire une "
+"[i]extrapolation[/i].\n"
"Si les arguments [code]from[/code] et [code]to[/code] sont de type [int] ou "
-"[float], la valeur de retour est un [float].\n"
+"[float], la valeur retournée est un [float].\n"
"Si les deux sont du même type de vecteur ([Vector2], [Vector3] ou [Color]), "
-"la valeur de retour sera du même type ([code]lerp[/code] appelle alors la "
-"méthode du type de vecteur [code]linear_interpolate[/code]).\n"
+"la valeur de retour sera du même type (puisque [code]lerp[/code] appelle "
+"alors la méthode [code]linear_interpolate[/code] du même type).\n"
"[codeblock]\n"
"lerp(0, 4, 0.75) # Retourne 3.0\n"
"lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Retourne Vector2(2, 3.5)\n"
@@ -1807,6 +1811,7 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns the result of smoothly interpolating the value of [code]s[/code] "
"between [code]0[/code] and [code]1[/code], based on the where [code]s[/code] "
@@ -1827,7 +1832,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -2079,9 +2084,9 @@ msgid ""
"[code]true[/code] encoding objects is allowed (and can potentially include "
"code)."
msgstr ""
-"Encode la valeur d'une variable en un tableau d'octets ([i]byte array[/i]). "
-"Lorsque [code]full_objects[/code] a la valeur [code]true[/code], l'encodage "
-"d'objets est autorisé (et peut potentiellement inclure du code)."
+"Encode la valeur d'une variable en un tableau d'octets. Lorsque "
+"[code]full_objects[/code] a la valeur [code]true[/code], l'encodage d'objets "
+"est autorisé (et peut potentiellement inclure du code)."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -3986,9 +3991,8 @@ msgid "Gamepad right analog trigger."
msgstr "Gâchette analogique droite de la manette."
#: doc/classes/@GlobalScope.xml
-#, fuzzy
msgid "VR Controller analog trigger."
-msgstr "Axe du déclencheur gauche du contrôleur de jeu."
+msgstr "Gâchette analogique de la manette VR."
#: doc/classes/@GlobalScope.xml
#, fuzzy
@@ -4016,7 +4020,7 @@ msgid ""
"MIDI note OFF message. See the documentation of [InputEventMIDI] for "
"information of how to use MIDI inputs."
msgstr ""
-"Le message MIDI pour la note OFF. Référez vous à la documentation de "
+"Le message OFF pour la note MIDI. Référez vous à la documentation de "
"[InputEventMIDI] pour avoir des informations concernant les entrées MIDI."
#: doc/classes/@GlobalScope.xml
@@ -4040,18 +4044,17 @@ msgid ""
"MIDI control change message. This message is sent when a controller value "
"changes. Controllers include devices such as pedals and levers."
msgstr ""
-"Le message MIDI de changement de contrôle. Ce message est envoyé lorsqu'un "
+"Le message de changement de contrôle MIDI. Ce message est envoyé lorsqu'un "
"contrôleur change de valeur. Les contrôleurs comprennent des dispositifs "
"comme des pédales, des leviers."
#: doc/classes/@GlobalScope.xml
-#, fuzzy
msgid ""
"MIDI program change message. This message sent when the program patch number "
"changes."
msgstr ""
-"Le message de changement de programme MIDI. Ce message est envoyé lorsque "
-"l'on reçoit une consigne de changement de programme."
+"Le message de changement de programme MIDI. Ce message est envoyé lorsque le "
+"nombre du patch du programme est changée."
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -4059,18 +4062,27 @@ msgid ""
"down on the key after it \"bottoms out\". This message is different from "
"polyphonic after-touch as it indicates the highest pressure across all keys."
msgstr ""
+"Le message de pression de canal MIDI. Ce message est le plus souvent envoyé "
+"en appuyant sur la touche après qu'il « se retire » . Ce message est "
+"différent de l'après-touche polyphonique car il indique la plus haute "
+"pression sur toutes les clés."
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI pitch bend message. This message is sent to indicate a change in the "
"pitch bender (wheel or lever, typically)."
msgstr ""
+"Le message de la hauteur MIDI. Ce message est envoyé pour indiquer un "
+"changement dans le plieur de hauteur (généralement une roue ou un levier)."
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI system exclusive message. This has behavior exclusive to the device "
"you're receiving input from. Getting this data is not implemented in Godot."
msgstr ""
+"Le message exclusif du système MIDI. Cela a un comportement exclusif à "
+"l'appareil dont vous recevez l'entrée. Obtenir cette donnée n'est pas "
+"implémenté dans Godot."
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -4083,30 +4095,43 @@ msgid ""
"MIDI song position pointer message. Gives the number of 16th notes since the "
"start of the song. Getting this data is not implemented in Godot."
msgstr ""
+"Le message de position de chanson MIDI. Donne le nombre de seizième de note "
+"depuis le début de la chanson. Obtenir cette donnée n'est pas implémenté "
+"dans Godot."
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI song select message. Specifies which sequence or song is to be played. "
"Getting this data is not implemented in Godot."
msgstr ""
+"Le message de sélectionne de la chanson. Spécifie quelle séquence ou quelle "
+"chanson doit être jouée. Obtenir cette donnée n'est pas implémenté dans "
+"Godot."
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI tune request message. Upon receiving a tune request, all analog "
"synthesizers should tune their oscillators."
msgstr ""
+"Le message de requête d'accordage MIDI. À la réception d'une requête "
+"d'accordage, tous les synthétiseurs analogiques devraient accorder leurs "
+"oscillateurs."
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI timing clock message. Sent 24 times per quarter note when "
"synchronization is required."
msgstr ""
+"Le message d'horloge MIDI. Envoyé 24 fois par quart de note lorsque la "
+"synchronisation est requise."
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI start message. Start the current sequence playing. This message will be "
"followed with Timing Clocks."
msgstr ""
+"Le message de démarrage MIDI. Commence la séquence actuelle. Ce message sera "
+"suivi avec un message d'horloge."
#: doc/classes/@GlobalScope.xml
msgid "MIDI continue message. Continue at the point the sequence was stopped."
@@ -5210,9 +5235,11 @@ msgid ""
"the [code]button[/code] will no longer emit this dialog's [signal "
"custom_action] signal or cancel this dialog."
msgstr ""
-"Enlever le [code]bouton[/code] de la boite de la boîte de dialogue. Ne "
-"libère pas le bouton. Le bouton dois être un [Button] ajouté avec la méthode "
-"[method add_button] ou [method add_cancel] ."
+"Retire le [code]button[/code] de la boite de dialogue. Ne libère PAS le "
+"[code]button[/code]. Le [code]button[/code] doit être un [Button] ajouté "
+"avec la méthode [method add_button] ou [method add_cancel]. Après être "
+"retiré, appuyer sur [code]button[/code] n'émettra plus le signal [signal "
+"custom_action] du dialogue ni ne l'annulera."
#: doc/classes/AcceptDialog.xml
msgid "Sets autowrapping for the text in the dialog."
@@ -6580,7 +6607,7 @@ msgstr ""
"- L'animation à mélanger quand la valeur est dans la plage [code][-1.0, 0.0]"
"[/code].\n"
"- L'animation à mélanger quand la valeur est dans la plage [code][0.0, 1.0][/"
-"code]."
+"code]"
#: doc/classes/AnimationNodeAdd3.xml doc/classes/AnimationNodeAnimation.xml
#: doc/classes/AnimationNodeBlend2.xml
@@ -7950,15 +7977,15 @@ msgid ""
"_physics_process])."
msgstr ""
"Les animations progresseront pendant les trames physiques (dans [méthode "
-"Node._physics_process)]"
+"Node._physics_process)]."
#: doc/classes/AnimationTree.xml
msgid ""
"The animations will progress during the idle frame (i.e. [method Node."
"_process])."
msgstr ""
-"Les animations progresseront pendant les trames d'inactivité (dans [méthode "
-"Node._process)]"
+"Les animations progresseront pendant les trames d'inactivité (dans [method "
+"Node._process])."
#: doc/classes/AnimationTree.xml
msgid "The animations will only progress manually (see [method advance])."
@@ -8337,6 +8364,9 @@ msgid ""
"Returns the number of inputs for the transition node with name [code]id[/"
"code]. You can add inputs by right-clicking on the transition node."
msgstr ""
+"Retourne le nombre d'entrées pour le nœud de transition nommé [code]id[/"
+"code]. Vous pouvez ajouter des entrées en faisant un clic droit sur le nœud "
+"de transition."
#: doc/classes/AnimationTreePlayer.xml
#, fuzzy
@@ -8351,6 +8381,9 @@ msgid ""
"transition node with name [code]id[/code] is set to automatically advance to "
"the next input upon completion."
msgstr ""
+"Retourne [code]true[/code] si l'entrée [code]input_idx[/code] du nœud de "
+"transition nommé [code]id[/code] est définie pour avancer automatiquement "
+"vers la prochaine entrée dès que la transition se termine."
#: doc/classes/AnimationTreePlayer.xml
#, fuzzy
@@ -8366,6 +8399,8 @@ msgid ""
"The transition node with name [code]id[/code] advances to its next input "
"automatically when the input at [code]input_idx[/code] completes."
msgstr ""
+"Le nœud de transition nommé [code]id[/code] avance à sa prochaine entrée "
+"automatiquement lorsque l'entrée [code]input_idx[/code] se termine."
#: doc/classes/AnimationTreePlayer.xml
msgid ""
@@ -8404,6 +8439,10 @@ msgid ""
"binds animations to animation nodes.\n"
"Once set, [Animation] nodes can be added to the [AnimationTreePlayer]."
msgstr ""
+"Le chemin vers le [AnimationPlayer] d'où cette [AnimationTreePlayer] "
+"connecte les animations aux nœuds d'animation.\n"
+"Une fois défini, les nœuds [Animation] peuvent être ajoutés au "
+"[AnimationTreePlayer]."
#: doc/classes/AnimationTreePlayer.xml
msgid "The thread in which to update animations."
@@ -8459,6 +8498,10 @@ msgid ""
"exiting. Can also alter or override local physics parameters (gravity, "
"damping) and route audio to custom audio buses."
msgstr ""
+"La zone 3D qui détecte nœuds [CollisionObject] qui se chevauchent, entrent "
+"ou sortent. Peut également modifier ou surcharger les paramètres de physique "
+"locale (gravité, amortissement) et passer l'audio à des bus audio "
+"personnalisés."
#: doc/classes/Area.xml doc/classes/QuadMesh.xml doc/classes/Viewport.xml
#: doc/classes/ViewportTexture.xml
@@ -8539,6 +8582,10 @@ msgid ""
"See [member ProjectSettings.physics/3d/default_angular_damp] for more "
"details about damping."
msgstr ""
+"La vitesse à laquelle les objets s'arrêtent de tourner dans cette zone. "
+"Représente la vitesse angulaire perdue par seconde.\n"
+"Voir [member ProjectSettings.physics/3d/default_angular_damp] pour plus de "
+"détails sur l'amortissement."
#: doc/classes/Area.xml doc/classes/Area2D.xml
msgid "The name of the area's audio bus."
@@ -8588,6 +8635,10 @@ msgid ""
"See [member ProjectSettings.physics/3d/default_linear_damp] for more details "
"about damping."
msgstr ""
+"La vitesse à laquelle les objets arrêtent de se déplacer dans cette zone. "
+"Représente la vitesse linéaire perdue par seconde.\n"
+"Voir [member ProjectSettings.physics/3d/default_linear_damp] pour plus de "
+"détails sur l'amortissement."
#: doc/classes/Area.xml doc/classes/Area2D.xml
msgid "If [code]true[/code], other monitoring areas can detect this area."
@@ -8646,6 +8697,9 @@ msgid ""
"be set to [code]true[/code].\n"
"[code]area[/code] the other Area."
msgstr ""
+"Émis quand une autre Area entre dans cette zone. Nécessite [member "
+"monitoring] d'être défini à [code]true[/code].\n"
+"[code]area[/code] l'autre Area."
#: doc/classes/Area.xml
msgid ""
@@ -8653,6 +8707,9 @@ msgid ""
"be set to [code]true[/code].\n"
"[code]area[/code] the other Area."
msgstr ""
+"Émis quand une autre Area quitte cette Area. Nécessite [member monitoring] "
+"d'être défini à [code]true[/code].\n"
+"[code]area[/code] l'autre Area."
#: doc/classes/Area.xml
msgid ""
@@ -8724,6 +8781,20 @@ msgid ""
"the [PhysicsServer]. Get the [CollisionShape] node with [code]self."
"shape_owner_get_owner(local_shape_index)[/code]."
msgstr ""
+"Émis quand une des [Shape] d'un [PhysicsBody] ou [GridMap] entre dans une "
+"des [Shape] de cette Area. Nécessite [member monitoring] d'être à "
+"[code]true[/code]. Les [GridMap] sont détectées si le [MeshLibrary] à une "
+"[Shape] de Collision.\n"
+"[code]body_rid[/code] le [RID] du [CollisionObject] du [PhysicsBody] ou du "
+"[MeshLibrary] utilisé par le [PhysicsServer].\n"
+"[code]body[/code] le [Node], s'il existe dans l'arborescence, du "
+"[PhysicsBody] ou [GridMap].\n"
+"[code]body_shape_index[/code] l'index de la [Shape] du [PhysicsBody] ou "
+"[GridMap] utilisé par le [PhysicsServer]. Obtenez le nœud [CollisionShape] "
+"avec [code]body.shape_owner_get_owner(body_shape_index)[/code].\n"
+"[code]local_shape_index[/code] l'index de la [Shape] de cette Area utilisée "
+"par le [PhysicsServer]. Obtenez le nœud [CollisionShape] nœud avec "
+"[code]self.shape_owner_get_owner(local_shape_index)[/code]."
#: doc/classes/Area.xml doc/classes/Area2D.xml
msgid "This area does not affect gravity/damping."
@@ -8806,6 +8877,14 @@ msgid ""
"list is modified once during the physics step, not immediately after objects "
"are moved. Consider using signals instead."
msgstr ""
+"Retourne la liste des intersections entre les [PhysiqueBody2D]. Le calque "
+"[member CollisionObject2D.collision_layer] du corps entrant en intersection "
+"doit être dans le masque [member CollisionObject2D.collision_mask] de ce "
+"corps pour être détecté.\n"
+"Pour des raisons de performance (les collisions sont toutes traitées en même "
+"temps) cette liste est modifiée une fois pendant l'étape physique, pas "
+"immédiatement après le déplacement des objets. Considérez plutôt "
+"l'utilisation des signaux."
#: doc/classes/Area2D.xml
msgid ""
@@ -8814,6 +8893,11 @@ msgid ""
"For performance, the list of overlaps is updated once per frame and before "
"the physics step. Consider using signals instead."
msgstr ""
+"Si [code]true[/code], la zone donnée recouvre la Area2D.\n"
+"[b]Note :[/b] Le résultat de ce test n'est pas immédiat après le déplacement "
+"des objets. Pour des raisons de performance, la liste des collisions est "
+"mise à jour une fois par trame et avant l'étape physique. Considérez plutôt "
+"l'utilisation des signaux."
#: doc/classes/Area2D.xml
msgid ""
@@ -8864,6 +8948,10 @@ msgid ""
"See [member ProjectSettings.physics/2d/default_linear_damp] for more details "
"about damping."
msgstr ""
+"La vitesse à laquelle les objets arrêtent de se déplacer dans cette zone. "
+"Représente la vitesse linéaire perdue par seconde.\n"
+"Voir [member ProjectSettings.physics/2d/default_linear_damp] pour plus de "
+"détails sur l'amortissement."
#: doc/classes/Area2D.xml
msgid ""
@@ -8871,6 +8959,9 @@ msgid ""
"to be set to [code]true[/code].\n"
"[code]area[/code] the other Area2D."
msgstr ""
+"Émis quand une autre Area2D entre dans cette Area2D. Nécessite [member "
+"monitoring] d'être défini à [code]true[/code].\n"
+"[code]area[/code] l'autre Area2D."
#: doc/classes/Area2D.xml
msgid ""
@@ -8878,6 +8969,9 @@ msgid ""
"to be set to [code]true[/code].\n"
"[code]area[/code] the other Area2D."
msgstr ""
+"Émis quand une autre Area2D quitte cette Area2D. Nécessite [member "
+"monitoring] d'être défini à [code]true[/code].\n"
+"[code]area[/code] l'autre Area2D."
#: doc/classes/Area2D.xml
msgid ""
@@ -8941,6 +9035,11 @@ msgid ""
"[code]body[/code] the [Node], if it exists in the tree, of the other "
"[PhysicsBody2D] or [TileMap]."
msgstr ""
+"Émis quand un [PhysicsBody2D] ou [TileMap] entre dans cette Area2D. "
+"Nécessite [member monitoring] d'être [code]true[/code]. Les [TileMap] sont "
+"détectés si le [TileSet] a une [Shape2D] de Collision.\n"
+"[code]body[/code] le [Node], s'il existe dans l'arborescence, de l'autre "
+"[PhysicsBody2D] ou [TileMap]."
#: doc/classes/Area2D.xml
msgid ""
@@ -8950,6 +9049,11 @@ msgid ""
"[code]body[/code] the [Node], if it exists in the tree, of the other "
"[PhysicsBody2D] or [TileMap]."
msgstr ""
+"Émis quand un [PhysicsBody2D] ou [TileMap] quitte dans cette Area2D. "
+"Nécessite [member monitoring] d'être [code]true[/code]. Les [TileMap] sont "
+"détectés si le [TileSet] a une [Shape2D] de Collision.\n"
+"[code]body[/code] le [Node], s'il existe dans l'arborescence, de l'autre "
+"[PhysicsBody2D] ou [TileMap]."
#: doc/classes/Area2D.xml
msgid ""
@@ -9799,7 +9903,7 @@ msgstr ""
#: doc/classes/ArrayMesh.xml
msgid "Will regenerate normal maps for the [ArrayMesh]."
-msgstr ""
+msgstr "Régénérera les cartes normales pour le [ArrayMesh]."
#: doc/classes/ArrayMesh.xml
msgid ""
@@ -9814,12 +9918,16 @@ msgid ""
"Returns the length in indices of the index array in the requested surface "
"(see [method add_surface_from_arrays])."
msgstr ""
+"Retourne la longueur des indices du tableau d'indices pour la surface "
+"spécifiée (voir [method add_surface_from_arrays].)"
#: doc/classes/ArrayMesh.xml
msgid ""
"Returns the length in vertices of the vertex array in the requested surface "
"(see [method add_surface_from_arrays])."
msgstr ""
+"Retourne la longueur des sommets du tableau des sommets dans la surface "
+"spécifiée (voir [method add_surface_from_arrays].)"
#: doc/classes/ArrayMesh.xml
msgid ""
@@ -9867,7 +9975,7 @@ msgstr ""
#: doc/classes/ArrayMesh.xml
msgid "Sets the blend shape mode to one of [enum Mesh.BlendShapeMode]."
-msgstr ""
+msgstr "Définit le mode de forme de mélange avec [enum Mesh.BlendShapeMode]"
#: doc/classes/ArrayMesh.xml doc/classes/PrimitiveMesh.xml
msgid ""
@@ -10804,6 +10912,9 @@ msgid ""
"the AR/VR eyes to [VisualServer]. The value comes from an internal call to "
"[method OS.get_ticks_usec]."
msgstr ""
+"Retourne l'horodatage absolu (en μs) de la dernière mise à jour des yeux AR/"
+"VR du [ARVRServer] envoyée au [VisualServer]. La valeur est récupérée via un "
+"appel interne à [method OS.get_ticks_usec]."
#: doc/classes/ARVRServer.xml
msgid ""
@@ -10811,6 +10922,9 @@ msgid ""
"difference between [method get_last_commit_usec] and [method "
"get_last_process_usec] when committing."
msgstr ""
+"Retourne la durée (en μs) de la dernière trame. Ceci est calculé comme la "
+"différence entre [method get_last_commit_usec] et [method "
+"get_last_process_usec] lorsque vous commettez."
#: doc/classes/ARVRServer.xml
msgid ""
@@ -10818,6 +10932,9 @@ msgid ""
"callback. The value comes from an internal call to [method OS."
"get_ticks_usec]."
msgstr ""
+"Retourne l'horodatage absolu (en μs) du dernier appel de mise à jour du "
+"[ARVRServer]. La valeur vient est récupérée via un appel interne à [method "
+"OS.get_ticks_usec]."
#: doc/classes/ARVRServer.xml
msgid ""
@@ -11122,7 +11239,7 @@ msgstr ""
" return min(0, abs(u - v) - 1)\n"
"[/codeblock]\n"
"[method estimate_cost] doit retourne la valeur minimale de la distance, soit "
-"[code]_estimate_cost(u, v) <= compute_cost(u, v)[ /code]. Cela sert d'indice "
+"[code]_estimate_cost(u, v) <= compute_cost(u, v)[/code]. Cela sert d'indice "
"pour l'algorithme la méthode [code]_compute_cost[/code] peut être longue à "
"calculer. Si ce n'est pas le cas, utilisez [method estimate_cost] pour "
"retourner la même valeur que [method compute_cost] pour fournir à "
@@ -11132,7 +11249,7 @@ msgstr ""
"limite inférieure du coût du chemin, les chemins retournés par A* seront les "
"chemins les moins coûteux. Ici, le coût d'un chemin correspond à la somme "
"des résultats [méthode compute_cost] de tous les segments dans le chemin "
-"multiplié par le [code]weight_scale[/code]s des paramètres de fin des "
+"multiplié par le [code]weight_scale[/code] des paramètres de fin des "
"segments respectifs. Si les méthodes par défaut sont utilisées et que le "
"[code]weight_scale[/code] de tous les points est [code]1.0[/code], ça "
"correspond à la somme des distances euclidiennes de tous les segments du "
@@ -11338,6 +11455,8 @@ msgid ""
"Returns the capacity of the structure backing the points, useful in "
"conjunction with [code]reserve_space[/code]."
msgstr ""
+"Retourne la capacité de la structure qui garde les points en cache, utile "
+"avec [code]reserve_space[/code]."
#: doc/classes/AStar.xml
msgid ""
@@ -11400,6 +11519,8 @@ msgid ""
"Returns the weight scale of the point associated with the given [code]id[/"
"code]."
msgstr ""
+"Retourne l'échelle de poids du point associé pour le [code]id[/code] "
+"spécifié."
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid "Returns an array of all points."
@@ -11416,6 +11537,8 @@ msgid ""
"Returns whether a point is disabled or not for pathfinding. By default, all "
"points are enabled."
msgstr ""
+"Retourne si un point est désactivé ou non pour le calcul du chemin. Par "
+"défaut, tous les points sont activés."
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
@@ -11431,6 +11554,9 @@ msgid ""
"you're adding a known large number of points at once, for a grid for "
"instance. New capacity must be greater or equals to old capacity."
msgstr ""
+"Réserve l'espace interne pour [code]num_nodes[/code] points, utile si vous "
+"voulez ajouter un grand nombre de points à la fois, pour une grille par "
+"exemple. La nouvelle capacité doit être supérieure ou égale à l'ancienne."
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
@@ -11791,6 +11917,9 @@ msgid ""
"Limits the frequencies in a range around the [member AudioEffectFilter."
"cutoff_hz] and allows frequencies outside of this range to pass."
msgstr ""
+"Limite l'intensité des fréquences dans la gamme autour de [member "
+"AudioEffectFilter.cutoff_hz], et permet aux fréquences en dehors de cette "
+"gamme de passer."
#: doc/classes/AudioEffectBandPassFilter.xml
msgid "Adds a band pass filter to the audio bus."
@@ -11801,6 +11930,9 @@ msgid ""
"Attenuates the frequencies inside of a range around the [member "
"AudioEffectFilter.cutoff_hz] and cuts frequencies outside of this band."
msgstr ""
+"Atténue les fréquences à l'intérieur de la gamme autour de [member "
+"AudioEffectFilter.cutoff_hz] et coupe les fréquences en dehors de cette "
+"gamme."
#: doc/classes/AudioEffectCapture.xml
msgid "Captures audio from an audio bus in real-time."
@@ -11838,6 +11970,11 @@ msgid ""
"samples if available, or an empty [PoolVector2Array] if insufficient data "
"was available."
msgstr ""
+"Retourne les prochains [code]frames[/code] d'échantillonnage audio de la "
+"mémoire interne en anneau.\n"
+"Retourne un [PoolVector2Array] contenant exactement [code]frames[/code] "
+"échantillons audio si disponible, ou un [PoolVector2Array] vide s'il n'y a "
+"pas assez de données disponibles."
#: doc/classes/AudioEffectCapture.xml
#, fuzzy
@@ -11985,6 +12122,9 @@ msgid ""
"Compressor's delay time to stop reducing the signal after the signal level "
"falls below the threshold, in milliseconds. Value can range from 20 to 2000."
msgstr ""
+"Le retard du compresseur avant d'arrêter de réduire le signal après que le "
+"niveau de signal sous le seuil, en millisecondes. La valeur peut aller de 20 "
+"à 2000."
#: doc/classes/AudioEffectCompressor.xml
msgid "Reduce the sound level using another audio bus for threshold detection."
@@ -12017,6 +12157,10 @@ msgid ""
"echo. Delay effects range from a subtle echo effect to a pronounced blending "
"of previous sounds with new sounds."
msgstr ""
+"Joue le signal d'entrée après une période de temps. Le signal retardé peut "
+"être joué plusieurs fois pour créer un écho qui s'amortit dans le temps. Les "
+"effets de retard vont d'un subtil écho à un mélange prononcé de sons "
+"précédents avec les nouveaux sons."
#: doc/classes/AudioEffectDelay.xml
msgid ""
@@ -12055,6 +12199,8 @@ msgid ""
"Pan position for [code]tap1[/code]. Value can range from -1 (fully left) to "
"1 (fully right)."
msgstr ""
+"La position gauche-droite pour [code]tap1[/code]. La valeur peut aller de -1 "
+"(complètement à gauche) à 1 (complètement à droite)."
#: doc/classes/AudioEffectDelay.xml
msgid "If [code]true[/code], [code]tap2[/code] will be enabled."
@@ -12073,6 +12219,8 @@ msgid ""
"Pan position for [code]tap2[/code]. Value can range from -1 (fully left) to "
"1 (fully right)."
msgstr ""
+"La position gauche-droite pour [code]tap2[/code]. La valeur peut aller de -1 "
+"(complètement à gauche) à 1 (complètement à droite)."
#: doc/classes/AudioEffectDistortion.xml
msgid ""
@@ -12104,6 +12252,8 @@ msgid ""
"High-pass filter, in Hz. Frequencies higher than this value will not be "
"affected by the distortion. Value can range from 1 to 20000."
msgstr ""
+"Le filtre passe-haut, en Hz. Les fréquences supérieures à cette valeur ne "
+"seront pas affectées par la distorsion. La valeur peut aller de 1 à 20000 Hz."
#: doc/classes/AudioEffectDistortion.xml
msgid "Distortion type."
@@ -12114,12 +12264,16 @@ msgid ""
"Increases or decreases the volume after the effect. Value can range from -80 "
"to 24."
msgstr ""
+"Augmente ou diminue le volume sonore après l'application de l'effet. La "
+"valeur peut aller de -80 à 24 dB."
#: doc/classes/AudioEffectDistortion.xml
msgid ""
"Increases or decreases the volume before the effect. Value can range from "
"-60 to 60."
msgstr ""
+"Augmente ou diminue le volume sonore avant l'application de l'effet. La "
+"valeur peut aller de -60 à 60 dB."
#: doc/classes/AudioEffectDistortion.xml
msgid ""
@@ -12132,6 +12286,8 @@ msgid ""
"Low-resolution digital distortion effect. You can use it to emulate the "
"sound of early digital audio devices."
msgstr ""
+"Effet de distorsion numérique à basse résolution. Vous pouvez l'utiliser "
+"pour émuler le son des tous premiers périphériques audio numériques."
#: doc/classes/AudioEffectDistortion.xml
msgid ""
@@ -12179,6 +12335,9 @@ msgid ""
"over frequencies from 31 Hz to 16000 Hz.\n"
"Each frequency can be modulated between -60/+24 dB."
msgstr ""
+"Ajoute un effet audio d'égaliseur de 10 bandes à un bus audio. Vous donne le "
+"contrôle des fréquences de 31 Hz à 16000 Hz.\n"
+"Chaque fréquence peut être modulée entre -60/+24 dB."
#: doc/classes/AudioEffectEQ10.xml
msgid ""
@@ -12214,6 +12373,9 @@ msgid ""
"over frequencies from 22 Hz to 22000 Hz.\n"
"Each frequency can be modulated between -60/+24 dB."
msgstr ""
+"Ajoute un effet audio d'égaliseur de 21 bandes à un bus audio. Vous donne le "
+"contrôle des fréquences de 22 Hz à 22000 Hz.\n"
+"Chaque fréquence peut être modulée entre -60/+24 dB."
#: doc/classes/AudioEffectEQ21.xml
msgid ""
@@ -12271,6 +12433,9 @@ msgid ""
"frequencies from 32 Hz to 10000 Hz.\n"
"Each frequency can be modulated between -60/+24 dB."
msgstr ""
+"Ajoute un effet audio d'égaliseur de 6 bandes à un bus audio. Vous donne le "
+"contrôle des fréquences de 32 Hz à 10000 Hz.\n"
+"Chaque fréquence peut être modulée entre -60/+24 dB."
#: doc/classes/AudioEffectEQ6.xml
msgid ""
@@ -12398,15 +12563,22 @@ msgid ""
"Attenuates frequencies in a narrow band around the [member AudioEffectFilter."
"cutoff_hz] and cuts frequencies outside of this range."
msgstr ""
+"Atténue les fréquences dans une bande étroite autour du [member "
+"AudioEffectFilter.cutoff_hz] et coupe les fréquences en dehors de cette "
+"gamme."
#: doc/classes/AudioEffectPanner.xml
msgid "Adds a panner audio effect to an Audio bus. Pans sound left or right."
msgstr ""
+"Ajoute un effet audio de balance à un bus audio. Balance les sons à gauche "
+"ou à droite."
#: doc/classes/AudioEffectPanner.xml
msgid ""
"Determines how much of an audio signal is sent to the left and right buses."
msgstr ""
+"Détermine quelle quantité d'un signal audio est envoyé aux bus de gauche et "
+"de droite."
#: doc/classes/AudioEffectPanner.xml
msgid "Pan position. Value can range from -1 (fully left) to 1 (fully right)."
@@ -12420,6 +12592,9 @@ msgid ""
"Combines the original signal with a copy that is slightly out of phase with "
"the original."
msgstr ""
+"Ajoute un effet audio de phaseur à un bus audio.\n"
+"Combine le signal original avec une copie de l'original légèrement hors "
+"phase."
#: doc/classes/AudioEffectPhaser.xml
msgid ""
@@ -12488,6 +12663,10 @@ msgid ""
"are more demanding on the CPU and may cause audio cracking if the CPU can't "
"keep up."
msgstr ""
+"Le facteur de suréchantillonnage à utiliser. Des valeurs plus élevées "
+"entraînent une meilleure qualité, mais nécessitent plus de puissance du CPU "
+"et peuvent provoquer des craquements audibles si le CPU n'est pas assez "
+"puissant."
#: doc/classes/AudioEffectPitchShift.xml
msgid ""
@@ -12776,6 +12955,8 @@ msgid ""
"Returns the [AudioEffectInstance] assigned to the given bus and effect "
"indices (and optionally channel)."
msgstr ""
+"Retourne le [AudioEffectInstance] assigné au bus et aux indices de l'effet "
+"donnés (et le canal en option)."
#: doc/classes/AudioServer.xml
msgid "Returns the index of the bus with the name [code]bus_name[/code]."
@@ -12790,26 +12971,32 @@ msgid ""
"Returns the peak volume of the left speaker at bus index [code]bus_idx[/"
"code] and channel index [code]channel[/code]."
msgstr ""
+"Retourne le volume de crête du haut-parleur gauche à l'index du bus "
+"[code]bus_idx[/code] et l'index du canal [code]canal[/code]."
#: doc/classes/AudioServer.xml
msgid ""
"Returns the peak volume of the right speaker at bus index [code]bus_idx[/"
"code] and channel index [code]channel[/code]."
msgstr ""
+"Retourne le volume de crête du haut-parleur droit à l'index de bus "
+"[code]bus_idx[/code] et l'index de canal [code]canal[/code]."
#: doc/classes/AudioServer.xml
msgid ""
"Returns the name of the bus that the bus at index [code]bus_idx[/code] sends "
"to."
msgstr ""
+"Retourne le nom du bus vers lequel le bus à l'index [code]bus_idx[/code] "
+"envoie l'audio."
#: doc/classes/AudioServer.xml
msgid "Returns the volume of the bus at index [code]bus_idx[/code] in dB."
-msgstr ""
+msgstr "Retourne le volume du bus à l'index [code]bus_idx[/code] en dB."
#: doc/classes/AudioServer.xml
msgid "Returns the names of all audio devices detected on the system."
-msgstr ""
+msgstr "Retourne les noms de tous les appareils audio détectés sur le système."
#: doc/classes/AudioServer.xml
#, fuzzy
@@ -12845,6 +13032,8 @@ msgid ""
"If [code]true[/code], the effect at index [code]effect_idx[/code] on the bus "
"at index [code]bus_idx[/code] is enabled."
msgstr ""
+"Si [code]true[/code], l'effet à l'index [code]effect_idx[/code] sur le bus à "
+"l'index [code]bus_idx[/code] est activé."
#: doc/classes/AudioServer.xml
msgid "If [code]true[/code], the bus at index [code]bus_idx[/code] is muted."
@@ -12855,12 +13044,15 @@ msgstr ""
msgid ""
"If [code]true[/code], the bus at index [code]bus_idx[/code] is in solo mode."
msgstr ""
+"Si [code]true[/code], le bus à l'index [code]bus_idx[/code] est en mode solo."
#: doc/classes/AudioServer.xml
msgid ""
"Locks the audio driver's main loop.\n"
"[b]Note:[/b] Remember to unlock it afterwards."
msgstr ""
+"Verrouille la boucle principale du pilote audio.\n"
+"[b]Note :[/b] Il est important de la déverrouiller après utilisation."
#: doc/classes/AudioServer.xml
msgid ""
@@ -12888,6 +13080,7 @@ msgstr "Remplace le [AudioBusLayout] actuellement utilisé."
msgid ""
"Sets the name of the bus at index [code]bus_idx[/code] to [code]name[/code]."
msgstr ""
+"Définit le nom du bus à l'index [code]bus_idx[/code] avec [code]name[/code]."
#: doc/classes/AudioServer.xml
msgid ""
@@ -12902,6 +13095,8 @@ msgid ""
"Sets the volume of the bus at index [code]bus_idx[/code] to [code]volume_db[/"
"code]."
msgstr ""
+"Définit le volume du bus à l'index [code]bus_idx[/code] à [code]volume_db[/"
+"code]."
#: doc/classes/AudioServer.xml
msgid "Swaps the position of two effects in bus [code]bus_idx[/code]."
@@ -12912,6 +13107,8 @@ msgid ""
"Unlocks the audio driver's main loop. (After locking it, you should always "
"unlock it.)"
msgstr ""
+"Déverrouille la boucle principale du pilote audio. (Après le verrouillage, "
+"vous devriez toujours le déverrouiller.)"
#: doc/classes/AudioServer.xml
msgid "Number of available audio buses."
@@ -12956,6 +13153,8 @@ msgid ""
"Scales the rate at which audio is played (i.e. setting it to [code]0.5[/"
"code] will make the audio be played twice as fast)."
msgstr ""
+"Mets à l'échelle la fréquence à laquelle l'audio est joué (c'est-à-dire que "
+"la valeur [code]0.5[/code] jouera l'audio deux fois plus vite)."
#: doc/classes/AudioServer.xml
msgid "Emitted when the [AudioBusLayout] changes."
@@ -12987,6 +13186,9 @@ msgid ""
"music playback, and support WAV (via [AudioStreamSample]) and OGG (via "
"[AudioStreamOGGVorbis]) file formats."
msgstr ""
+"La classe de base pour les flux audio. Les flux audio sont utilisés pour les "
+"effets sonores et la lecture de musique, et supportent les formats de "
+"fichiers WAV (via [AudioStreamSample)] et OGG (via [AudioStreamOGGVorbis)]."
#: doc/classes/AudioStream.xml doc/classes/AudioStreamPlayer.xml
msgid "Audio streams"
@@ -13018,6 +13220,15 @@ msgid ""
"class from GDScript, consider using a lower [member mix_rate] such as 11,025 "
"Hz or 22,050 Hz."
msgstr ""
+"Ce flux audio ne joue pas de sons par défaut, les données audio doivent être "
+"générées à partir d'un script. Voir aussi [AudioStreamGeneratorPlayback].\n"
+"Voir aussi [AudioEffectSpectrumAnalyzer] pour l'analyse spectrale de l'audio "
+"en temps réel.\n"
+"[b]Note :[/b] En raison des contraintes de performance, il est préférable "
+"d'utiliser cette classe à partir de code C# ou d'un langage compilée via "
+"GDNative. Si vous souhaitez tout de même utiliser cette classe avec "
+"GDScript, envisagez d'utiliser une fréquence [member mix_rate] plus faible "
+"comme 11025 Hz ou 22050 Hz."
#: doc/classes/AudioStreamGenerator.xml
msgid ""
@@ -13026,6 +13237,11 @@ msgid ""
"resulting in increased CPU usage and more risk for audio cracking if the CPU "
"can't keep up."
msgstr ""
+"La longueur de la mémoire tampon à générer (en secondes). Les valeurs "
+"inférieures entraînent moins de latence, mais exigent que le script génère "
+"les données audio plus rapidement, ce qui entraîne une utilisation plus "
+"important du CPU et plus de risques de craquements audio si le CPU n'est pas "
+"assez puissant."
#: doc/classes/AudioStreamGenerator.xml
msgid ""
@@ -13088,6 +13304,11 @@ msgid ""
"added again. Therefore, make sure your script can always generate and push "
"new audio frames fast enough to avoid audio cracking."
msgstr ""
+"Retourne le nombre de frames de données audio restantes à jouer. Si ce "
+"nombre atteint [code]0[/code], l'audio cessera de jouer jusqu'à ce que de "
+"nouvelles frames soient ajoutés. Par conséquent, assurez-vous que votre "
+"script peut toujours générer et pousser de nouveaux frames audio assez "
+"rapidement pour éviter les craquements audio."
#: doc/classes/AudioStreamGeneratorPlayback.xml
msgid ""
@@ -13095,6 +13316,10 @@ msgid ""
"efficient than [method push_frame] in C# and compiled languages via "
"GDNative, but [method push_buffer] may be [i]less[/i] efficient in GDScript."
msgstr ""
+"Ajoute plusieurs frames de données audio dans la mémoire tampon. Ceci est "
+"généralement plus efficace que [method push_frame] pour le C# et les "
+"langages compilés avec GDNative, mais [method push_buffer] peut être "
+"[i]moins[/i] efficace avec GDScript."
#: doc/classes/AudioStreamGeneratorPlayback.xml
msgid ""
@@ -13102,6 +13327,10 @@ msgid ""
"efficient than [method push_buffer] in C# and compiled languages via "
"GDNative, but [method push_frame] may be [i]more[/i] efficient in GDScript."
msgstr ""
+"Ajouter une seule frame de données audio dans la mémoire tampon. Ceci est "
+"généralement moins efficace que [method push_buffer] pour le C# et les "
+"langages compilés avec GDNative, mais [method push_frame] peut être "
+"[i]moins[/i] efficace avec GDScript."
#: modules/minimp3/doc_classes/AudioStreamMP3.xml
#, fuzzy
@@ -13125,7 +13354,7 @@ msgstr ""
#: modules/minimp3/doc_classes/AudioStreamMP3.xml
#: modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml
msgid "Time in seconds at which the stream starts after being looped."
-msgstr ""
+msgstr "Le temps en secondes où le flux commence après avoir bouclé."
#: modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml
msgid "OGG Vorbis audio stream driver."
@@ -13140,6 +13369,8 @@ msgid ""
"Can play, loop, pause a scroll through audio. See [AudioStream] and "
"[AudioStreamOGGVorbis] for usage."
msgstr ""
+"Peut jouer, boucler, faire pause dans l'audio. Voir [AudioStream] et "
+"[AudioStreamOGGVorbis] pour l'utilisation."
#: doc/classes/AudioStreamPlayer.xml
msgid "Plays back audio non-positionally."
@@ -13151,6 +13382,9 @@ msgid ""
"To play audio positionally, use [AudioStreamPlayer2D] or "
"[AudioStreamPlayer3D] instead of [AudioStreamPlayer]."
msgstr ""
+"Joue un flux audio indépendamment de la position.\n"
+"Pour jouer audio en fonction de la position, utilisez [AudioStreamPlayer2D] "
+"ou [AudioStreamPlayer3D] au lieu de [AudioStreamPlayer]."
#: doc/classes/AudioStreamPlayer.xml
msgid "Returns the position in the [AudioStream] in seconds."
@@ -13185,8 +13419,14 @@ msgstr ""
"scènes."
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
-msgstr "Bus sur lequel cet audio joue."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
+msgstr ""
#: doc/classes/AudioStreamPlayer.xml
msgid ""
@@ -13239,6 +13479,7 @@ msgstr "L'audio sera joué sur tous les canaux surround."
msgid ""
"The audio will be played on the second channel, which is usually the center."
msgstr ""
+"L'audio sera joué sur le deuxième canal, qui est généralement le centre."
#: doc/classes/AudioStreamPlayer2D.xml
msgid "Plays positional sound in 2D space."
@@ -13253,6 +13494,13 @@ msgid ""
"[member volume_db] to a very low value like [code]-100[/code] (which isn't "
"audible to human hearing)."
msgstr ""
+"Joue l'audio étant amortit suivan la distance du centre d'écran.\n"
+"Voir aussi [AudioStreamPlayer] pour jouer un son indépendemment de la "
+"position.\n"
+"[b]Note :[/b] Masquer un nœud [AudioStreamPlayer2D] ne désactive pas sa "
+"sortie audio. Pour désactiver temporairement la sortie audio d'un "
+"[AudioStreamPlayer2D], choisissez une valeur très basse pour [member "
+"volume_db] comme [code]-100[/code] (qui n'est pas audible humainement)."
#: doc/classes/AudioStreamPlayer2D.xml doc/classes/AudioStreamPlayer3D.xml
msgid "Returns the position in the [AudioStream]."
@@ -13282,6 +13530,12 @@ msgid ""
"\"water\" area so that sounds played in the water are redirected through an "
"audio bus to make them sound like they are being played underwater."
msgstr ""
+"Détermine quelles calques du [Area2D] affectent le son pour les effets de "
+"réverbération et du bus audio. Les zones peuvent être utilisées pour "
+"rediriger le [AudioStream] afin qu'ils soient joués dans un certain bus "
+"audio. Un exemple de la façon dont vous pouvez utiliser ceci est de faire "
+"une zone \"eau\" de sorte que les sons joués dans l'eau sont redirigés par "
+"un bus audio pour les faire sonner comme ils étaient joués sous l'eau."
#: doc/classes/AudioStreamPlayer2D.xml
msgid "Dampens audio over distance with this as an exponent."
@@ -13357,6 +13611,10 @@ msgid ""
"disable the dampening effect entirely, set this to [code]20500[/code] as "
"this frequency is above the human hearing limit."
msgstr ""
+"Amortit l'audio en utilisant un filtre passe-bas au-dessus de la fréquence "
+"spécifiée, en Hz. Pour désactiver entièrement l'effet d'amortissement, "
+"définissez la fréquence à [code]20500[/code] car cette fréquence est "
+"supérieure à la limite de l'audition humaine."
#: doc/classes/AudioStreamPlayer3D.xml
msgid "Amount how much the filter affects the loudness, in decibels."
@@ -13381,8 +13639,14 @@ msgstr ""
"ajouté à la scène."
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
-msgstr "Le bus sur lequel cet audio est joué."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
+msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
@@ -13394,9 +13658,9 @@ msgid ""
msgstr ""
"Décide dans quelle mesure [url=https://fr.wikipedia.org/wiki/"
"Effet_Doppler]L'effet Doppler[/url] doit être calculé.\n"
-"[b]Note :[/b] Ce n'est efficace que si la propriété actuelle [Camera] "
-"enregistrée [member Camera.doppler_tracking] est définie à une valeur autre "
-"que [constant Camera. DOPPLER_TRACKING_DISABLED]"
+"[b]Note :[/b] Ce n'est actif que si la propriété [member Camera."
+"doppler_tracking] de la [Camera] actuelle est définie à une valeur autre que "
+"[constant Camera.DOPPLER_TRACKING_DISABLED]."
#: doc/classes/AudioStreamPlayer3D.xml
msgid "The angle in which the audio reaches cameras undampened."
@@ -13418,7 +13682,7 @@ msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
msgid "Sets the absolute maximum of the soundlevel, in decibels."
-msgstr ""
+msgstr "Définit le maximum absolu du niveau sonore, en décibels."
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
@@ -13450,13 +13714,15 @@ msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
msgid "The base sound level unaffected by dampening, in decibels."
-msgstr ""
+msgstr "Le niveau sonore de base non affecté par l'amortissement, en décibels."
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
"The factor for the attenuation effect. Higher values make the sound audible "
"over a larger distance."
msgstr ""
+"Le facteur pour l'effet d'atténuation. Des valeurs plus élevées rendent le "
+"son audible sur une distance plus grande."
#: doc/classes/AudioStreamPlayer3D.xml
msgid "Linear dampening of loudness according to distance."
@@ -13487,6 +13753,10 @@ msgid ""
"but keeps the sound playing at the correct position if the camera leaves and "
"enters the [AudioStreamPlayer3D]'s [member max_distance] radius."
msgstr ""
+"Mélanger ce son, même lorsqu'il est hors de portée. Cela augmente "
+"l'utilisation de CPU, mais garde le son à la bonne position de lecture si la "
+"caméra quitte puis entre à nouveau dans le rayon [member max_distance] du "
+"[AudioStreamPlayer3D]."
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
@@ -13494,6 +13764,9 @@ msgid ""
"will cause the sound to restart if the camera leaves and enters the "
"[AudioStreamPlayer3D]'s [member max_distance] radius."
msgstr ""
+"Pause ce son quand il hors de portée. Cela diminue l'utilisation du CPU, "
+"mais cela fera redémarrer le son si la caméra quitte puis entre dans le "
+"rayon [member max_distance] du [AudioStreamPlayer3D]."
#: doc/classes/AudioStreamPlayer3D.xml
msgid "Disables doppler tracking."
@@ -13537,6 +13810,13 @@ msgid ""
"This class can also be used to store dynamically-generated PCM audio data. "
"See also [AudioStreamGenerator] for procedural audio generation."
msgstr ""
+"AudioStreamSample stocke des échantillons sonores chargés depuis des "
+"fichiers WAV. Pour jouer le son enregistré, utilisez un [AudioStreamPlayer] "
+"(pour l'audio indépendamment de la position) ou AudioStreamPlayer2D]/"
+"[AudioStreamPlayer3D (en fonction de la position). Le son peut être bouclé.\n"
+"Cette classe peut également être utilisée pour stocker des données audio "
+"dynamiques au format PCM. Voir aussi [AudioStreamGenerator] pour la "
+"génération audio procédurale."
#: doc/classes/AudioStreamSample.xml
msgid ""
@@ -13545,6 +13825,11 @@ msgid ""
"[b]Note:[/b] A [code].wav[/code] extension is automatically appended to "
"[code]path[/code] if it is missing."
msgstr ""
+"Enregistre le AudioStreamSample dans un fichier WAV à l'emplacement "
+"[code]path[/code]. Les échantillons au format IMA ADPCM peuvent être "
+"enregistrés.\n"
+"[b]Note :[/b] L'extension [code].wav[/code] est automatiquement ajoutée au "
+"[code]path[/code] si elle manque."
#: doc/classes/AudioStreamSample.xml
msgid ""
@@ -13552,6 +13837,10 @@ msgid ""
"[b]Note:[/b] This property expects signed PCM8 data. To convert unsigned "
"PCM8 to signed PCM8, subtract 128 from each byte."
msgstr ""
+"Contient les données audio en octets.\n"
+"[b]Note :[/b] Cette propriété s'attend à des données PCM8 signées. Pour "
+"convertir des PCM8 non signés en PCM8, il faut soustraire 128 de chaque "
+"octet."
#: doc/classes/AudioStreamSample.xml
msgid "Audio format. See [enum Format] constants for values."
@@ -13565,6 +13854,9 @@ msgid ""
"sample). This information will be imported automatically from the WAV file "
"if present."
msgstr ""
+"Le point de départ de la boucle (en nombre de frames depuis le début de "
+"l'échantillon). Ces informations seront automatiquement importées depuis le "
+"fichier WAV si elles y sont présentes."
#: doc/classes/AudioStreamSample.xml
msgid ""
@@ -13572,12 +13864,18 @@ msgid ""
"sample). This information will be imported automatically from the WAV file "
"if present."
msgstr ""
+"Le point de fin de la boucle (en nombre de frames depuis le début de "
+"l'échantillon). Ces informations seront automatiquement importées depuis le "
+"fichier WAV si elles y sont présentes."
#: doc/classes/AudioStreamSample.xml
msgid ""
"The loop mode. This information will be imported automatically from the WAV "
"file if present. See [enum LoopMode] constants for values."
msgstr ""
+"Le mode de boucle. Ces informations seront automatiquement importées depuis "
+"fichier WAV si elles y sont présentes. Voir les constantes [enum LoopMode] "
+"pour les valeurs possibles."
#: doc/classes/AudioStreamSample.xml
msgid ""
@@ -13594,6 +13892,19 @@ msgid ""
"[code]32000[/code] or [code]22050[/code] may be usable with no loss in "
"quality."
msgstr ""
+"Le taux d'échantillonnage pour mélanger ce son. Les valeurs plus élevées "
+"nécessitent plus d'espace de stockage, mais proposent une meilleure "
+"qualité.\n"
+"Dans les jeux, les taux d'échantillonnage courants sont [code]11025[/code], "
+"[code]16000[/code], [code]22050[/code], [code]32000[/code], [code]44100[/"
+"code], et [code]48000[/code].\n"
+"D'après le [url=https://fr.wikipedia.org/wiki/"
+"Th%C3%A9or%C3%A8me_d'%C3%A9chantillonnage]Théorème d'échantillonnage[/url], "
+"il n'y a aucune différence de qualité pour l'audition humaine au-delà de 40 "
+"000 Hz (puisque la plupart des humains ne peuvent entendre que jusqu'à 20 "
+"000 Hz, et souvent bien moins). Si vous générez des sons inférieurs tels que "
+"les voix, des taux d'échantillonnage inférieurs tels que [code]32000[/code] "
+"ou [code]22050[/code] peuvent être utilisables sans perte de qualité audible."
#: doc/classes/AudioStreamSample.xml
msgid "If [code]true[/code], audio is stereo."
@@ -13628,6 +13939,8 @@ msgid ""
"Audio loops the data between [member loop_begin] and [member loop_end], "
"playing back and forth."
msgstr ""
+"Les données audio bouclent entre [member loop_begin] et [member loop_end], "
+"jouant en arrière puis en avant."
#: doc/classes/AudioStreamSample.xml
msgid ""
@@ -13643,6 +13956,9 @@ msgid ""
"accessed in your shader scripts through the "
"[code]texture(SCREEN_TEXTURE, ...)[/code] function."
msgstr ""
+"Copie une région de l'écran (ou l'écran entier) vers une mémoire tampon afin "
+"qu'il puisse être accédé dans vos shaders avec la fonction "
+"[code]texture(SCREEN_TEXTURE, ...)[/code]."
#: doc/classes/BackBufferCopy.xml
msgid ""
@@ -13746,6 +14062,17 @@ msgid ""
"[b]Note:[/b] [member bounce_indirect_energy] only has an effect if [member "
"bounces] is set to a value greater than or equal to [code]1[/code]."
msgstr ""
+"Le multiplicateur d'énergie à chaque rebond. Des valeurs plus élevées "
+"rendront l'éclairage indirect plus lumineux. Une valeur de [code]1.0[/code] "
+"représente un comportement physiquement réaliste, mais des valeurs plus "
+"élevées peuvent être utilisées pour rendre l'éclairage indirect plus visible "
+"avec un faible nombre de rebonds. Cela peut être utilisé pour accélérer les "
+"temps de calcul des lumières en réduisant le nombre de [member bounces] puis "
+"en augmentant [member bounce_indirect_energy]. Contrairement à [member "
+"BakedLightmapData.energy], cette propriété n'affecte pas l'éclairage direct "
+"émis par les lumières, les matériaux avec émission et l'environnement.\n"
+"[b]Note :[/b] [member bounce_indirect_energy] a seulement un effet si "
+"[member bounces] est à une valeur supérieure ou égale à [code]1[/code]."
#: doc/classes/BakedLightmap.xml
msgid ""
@@ -13795,6 +14122,9 @@ msgid ""
"[constant ENVIRONMENT_MODE_CUSTOM_COLOR] or [constant "
"ENVIRONMENT_MODE_CUSTOM_SKY]."
msgstr ""
+"Le facteur d'énergie lorsque [member environment_mode] est défini à "
+"[constant ENVIRONMENT_MODE_CUSTOM_COLOR] ou [constant "
+"ENVIRONMENT_MODE_CUSTOM_SKY]."
#: doc/classes/BakedLightmap.xml
msgid ""
@@ -13833,6 +14163,8 @@ msgid ""
"Deprecated, in previous versions it determined the location where lightmaps "
"were be saved."
msgstr ""
+"Obsolète, dans les versions précédentes ça déterminait l'emplacement où les "
+"textures de lumière étaient enregistrées."
#: doc/classes/BakedLightmap.xml
msgid "The calculated light data."
@@ -13870,6 +14202,15 @@ msgid ""
"lightmap banding even when using the GLES2 backend or if [member "
"ProjectSettings.rendering/quality/depth/hdr] is [code]false[/code]."
msgstr ""
+"Si [code]true[/code], enregistre les textures de lumière dans un format de "
+"plage dynamique élevée (type EXR). Si [code]false[/code], enregistre les "
+"textures de lumière dans une image PNG de plage dynamique faible. Ceci peut "
+"être défini à [code]false[/code] pour réduire l'usage du disque, mais les "
+"valeurs lumineuses supérieures à 1.0 seront limitées et vous pouvez voir un "
+"effet de bandes qui apparaissent à cause de cette précision réduite.\n"
+"[b]Note :[/b] Définir [member use_hdr] à [code]true[/code] réduira l'effet "
+"de bandes même sous GLES2 ou quand [member ProjectSettings.rendering/quality/"
+"depth/hdr] est [code]false[/code]."
#: doc/classes/BakedLightmap.xml
msgid "The lowest bake quality mode. Fastest to calculate."
@@ -13896,6 +14237,9 @@ msgid ""
"Returns if no viable save path is found. This can happen where an [member "
"image_path] is not specified or when the save location is invalid."
msgstr ""
+"Retourne si aucun chemin d'enregistrement invalid n'est trouvé. Cela peut se "
+"produire lorsqu'un [member image_path] n'est pas spécifié ou lorsque "
+"l'emplacement de sauvegarde est invalide."
#: doc/classes/BakedLightmap.xml doc/classes/SpatialMaterial.xml
msgid "Currently unused."
@@ -13972,17 +14316,25 @@ msgid ""
"directly (it doesn't display anything). Other types of buttons inherit from "
"it."
msgstr ""
+"BaseButton est la classe de base abstraite pour les boutons, elle ne doit "
+"donc pas être utilisée directement (elle ne montre rien du tout). D'autres "
+"types de boutons héritent de cette classe."
#: doc/classes/BaseButton.xml
msgid ""
"Called when the button is pressed. If you need to know the button's pressed "
"state (and [member toggle_mode] is active), use [method _toggled] instead."
msgstr ""
+"Appelé quand le bouton est pressé. Si vous avez besoin de connaître l'état "
+"du bouton activé (et que [member toggle_mode] est actif), utilisez plutôt "
+"[méthode _toggled]."
#: doc/classes/BaseButton.xml
msgid ""
"Called when the button is toggled (only if [member toggle_mode] is active)."
msgstr ""
+"Appelé quand un bouton est basculé (seulement si [member toggle_mode] est "
+"actif)."
#: doc/classes/BaseButton.xml
msgid ""
@@ -13991,6 +14343,10 @@ msgid ""
"to \"draw\" signal. The visual state of the button is defined by the [enum "
"DrawMode] enum."
msgstr ""
+"Retourne l'état visuel utilisé pour dessiner le bouton. Ceci est utile "
+"surtout pour implémenter votre propre code d'affichage en surchargeant "
+"_draw() ou en se connectant au signal \"draw\". L'état visuel du bouton est "
+"défini par l'enumération [enum DrawMode]."
#: doc/classes/BaseButton.xml
#, fuzzy
@@ -14010,6 +14366,13 @@ msgid ""
"[b]Note:[/b] This method doesn't unpress other buttons in its button [member "
"group]."
msgstr ""
+"Change l'état [member pressed] du bouton, sans émettre le signal [signal "
+"toggled]. Utilisez lorsque vous voulez simplement changer l'état du bouton "
+"sans envoyer l'événement quand il est manuellement pressé (par exemple au "
+"moment de l'initialisation de la scène). Fonctionne seulement si [member "
+"toggle_mode] est [code]true[/code].\n"
+"[b]Note :[/b] Cette méthode ne déselectionne pas les autres boutons dans son "
+"[member group]."
#: doc/classes/BaseButton.xml
msgid ""
@@ -14025,12 +14388,18 @@ msgid ""
"To allow both left-click and right-click, use [code]BUTTON_MASK_LEFT | "
"BUTTON_MASK_RIGHT[/code]."
msgstr ""
+"La masque binaire pour choisir quels boutons de clic de la souris permet "
+"d'appuyer sur ce bouton.\n"
+"Pour permettre à la fois le clic gauche et le clic droit, utilisez "
+"[code]BUTTON_MASK_LEFT | BUTTON_MASK_RIGHT[/code]."
#: doc/classes/BaseButton.xml
msgid ""
"If [code]true[/code], the button is in disabled state and can't be clicked "
"or toggled."
msgstr ""
+"Si [code]true[/code], le bouton est désactivé et il ne peut donc pas être "
+"appuyé ou basculé."
#: doc/classes/BaseButton.xml
msgid ""
@@ -14038,6 +14407,9 @@ msgid ""
"will be removed in Godot 4.0. This property no longer has any effect when "
"set. Please use [member Control.focus_mode] instead."
msgstr ""
+"[i]Obsolète.[/i] Cette propriété est obsolète en raison de sa redondance et "
+"sera enlevée dans Godot 4.0. Cette propriété n'a plus d'effet quand elle est "
+"définie. Veuillez plutôt utiliser [member Control.focus_mode]."
#: doc/classes/BaseButton.xml
msgid "[ButtonGroup] associated to the button."
@@ -14051,6 +14423,11 @@ msgid ""
"Signals will be emitted at the same moment regardless of this property's "
"value."
msgstr ""
+"Si [code]true[/code], le bouton reste pressé quand le clic est maintenu mais "
+"que le curseur est déplacé en dehors du bouton.\n"
+"[b]Note :[/b] Cette propriété n'affecte que l'aspect visuel du bouton. Les "
+"signaux seront toujours émis au même moment, peu importe la valeur de cette "
+"propriété."
#: doc/classes/BaseButton.xml
msgid ""
@@ -14061,6 +14438,12 @@ msgid ""
"emitted. If you want to change the pressed state without emitting that "
"signal, use [method set_pressed_no_signal]."
msgstr ""
+"Si [code]true[/code], l'état du bouton est appuyé. Ce qui signifie que le "
+"bouton est soit appuyé ou basculé (si [member toggle_mode] est actif). Ne "
+"fonctionne que si [member toggle_mode] est [code]true[/code].\n"
+"[b]Note :[/b] Activer [member pressed] émettra le signal [signal toggled]. "
+"Si vous voulez changer l'état pressé sans émettre ce signal, utilisez plutôt "
+"[method set_pressed_no_signal]."
#: doc/classes/BaseButton.xml
msgid "[ShortCut] associated to the button."
@@ -14079,6 +14462,8 @@ msgid ""
"If [code]true[/code], the button is in toggle mode. Makes the button flip "
"state between pressed and unpressed each time its area is clicked."
msgstr ""
+"Si [code]true[/code], le bouton est en mode basculement. Fait basculer le "
+"bouton entre les états pressé et non-pressé chaque fois qu'il est cliqué."
#: doc/classes/BaseButton.xml
msgid "Emitted when the button starts being held down."
@@ -14096,6 +14481,11 @@ msgid ""
"If you need to know the button's pressed state (and [member toggle_mode] is "
"active), use [signal toggled] instead."
msgstr ""
+"Émis quand le bouton est basculé ou pressé. Émis lors de [signal "
+"button_down] si [member action_mode] est [constant ACTION_MODE_BUTTON_PRESS] "
+"et lors de [signal button_up] sinon.\n"
+"Si vous avez besoin de connaître l'état du bouton (et que [member "
+"toggle_mode] est actif), utilisez plutôt [signal toggled]."
#: doc/classes/BaseButton.xml
msgid ""
@@ -14103,12 +14493,17 @@ msgid ""
"(only if [member toggle_mode] is active). The new state is contained in the "
"[code]button_pressed[/code] argument."
msgstr ""
+"Émis lorsque le bouton a été juste basculé entre les états pressé et normal "
+"(seulement si [member toggle_mode] est actif). Le nouvel état est passé dans "
+"l'argument [code]button_pressed[/code]."
#: doc/classes/BaseButton.xml
msgid ""
"The normal state (i.e. not pressed, not hovered, not toggled and enabled) of "
"buttons."
msgstr ""
+"L'état normal (c'est-à-dire non pressé, non survolé, non basculé ni activé) "
+"des boutons."
#: doc/classes/BaseButton.xml
msgid "The state of buttons are pressed."
@@ -14155,6 +14550,17 @@ msgid ""
"For more information, read the \"Matrices and transforms\" documentation "
"article."
msgstr ""
+"Une matrice 3×3 utilisée pour la rotation et la mise à l'échelle en 3D. "
+"Presque toujours utilisé comme base orthogonale pour une Transform.\n"
+"Contient 3 champs vectoriels X, Y et Z qui composent ses colonnes, qui sont "
+"généralement interprétées comme les vecteurs de base locaux d'une "
+"transformation. Pour une telle utilisation, c'est composé d'une mise à "
+"l'échelle et d'une matrice de rotation, dans cet ordre (M = R.S)\n"
+"Peut également être accessible comme un tableau de vecteurs 3D. Ces vecteurs "
+"sont normalement orthogonaux l'un avec l'autre, mais ne sont pas "
+"nécessairement normalisés (en raison de la mise à l'échelle).\n"
+"Pour plus d'informations, lisez l'article de documentation « Matrices et "
+"transformations »."
#: doc/classes/Basis.xml doc/classes/Transform.xml doc/classes/Transform2D.xml
msgid "Matrices and transforms"
@@ -14166,7 +14572,6 @@ msgstr "Utiliser les transformations 3D"
#: doc/classes/Basis.xml doc/classes/Line2D.xml doc/classes/Transform.xml
#: doc/classes/Transform2D.xml doc/classes/Vector2.xml doc/classes/Vector3.xml
-#, fuzzy
msgid "Matrix Transform Demo"
msgstr "Démo de transformation matricielle"
@@ -14201,16 +14606,21 @@ msgid ""
"Consider using the [Quat] constructor instead, which uses a quaternion "
"instead of Euler angles."
msgstr ""
+"Construit une matrice de base de rotation pure à partir des angles d'Euler "
+"spécifiés (suivant la convention YXZ : lors de la *composition*, d'abord Y, "
+"puis X, et enfin Z), qui sont donnés dans un vecteur comme (angle X, angle "
+"Y, angle Z).\n"
+"Vous pouvez considérer l'utilisation du constructeur [Quat], qui utilise un "
+"quaternion au lieu des angles d'Euler."
#: doc/classes/Basis.xml
-#, fuzzy
msgid ""
"Constructs a pure rotation basis matrix, rotated around the given "
"[code]axis[/code] by [code]angle[/code] (in radians). The axis must be a "
"normalized vector."
msgstr ""
-"Construit un quaternion qui tournera autour de l'axe donné selon l'angle "
-"spécifié. L'axe doit être un vecteur normalisé."
+"Construit un quaternion qui tournera autour de l'axe [code]axis[/code] par "
+"[code]angle[/code] (en radians). L'axe doit être un vecteur normalisé."
#: doc/classes/Basis.xml
msgid "Constructs a basis matrix from 3 axis vectors (matrix columns)."
@@ -14269,8 +14679,8 @@ msgid ""
"discarded. Don't use the epsilon argument, it does nothing."
msgstr ""
"Retourne [code]true[/code] si cette base et [code]b[/code] sont "
-"approximativement égales, en appelant [method @GDScript.is_equal_approx] sur "
-"chaque composantes.\n"
+"approximativement égales, en appelant [code]is_equal_approx[/code] sur "
+"chaque composant.\n"
"[b]Note :[/b] Pour des raisons compliquées, l'argument epsilon est toujours "
"ignoré. Ne l'utilisez pas, il ne sert à rien."
@@ -14326,24 +14736,34 @@ msgid ""
"[b]Note:[/b] This results in a multiplication by the inverse of the matrix "
"only if it represents a rotation-reflection."
msgstr ""
+"Retourne un vecteur transformé (multiplié) par la matrice de base "
+"transposée.\n"
+"[b]Note :[/b] Cela entraîne une multiplication par l'inverse de la matrice "
+"seulement si elle représente une rotation-réflexion."
#: doc/classes/Basis.xml doc/classes/Transform2D.xml
msgid ""
"The basis matrix's X vector (column 0). Equivalent to array index [code]0[/"
"code]."
msgstr ""
+"Le vecteur X (la colonne 0) de la matrice de la base. Équivalent à l'index "
+"de tableau [code]0[/code]."
#: doc/classes/Basis.xml doc/classes/Transform2D.xml
msgid ""
"The basis matrix's Y vector (column 1). Equivalent to array index [code]1[/"
"code]."
msgstr ""
+"Le vecteur Y (la colonne 1) de la matrice de la base. Équivalent à l'index "
+"de tableau [code]1[/code]."
#: doc/classes/Basis.xml
msgid ""
"The basis matrix's Z vector (column 2). Equivalent to array index [code]2[/"
"code]."
msgstr ""
+"Le vecteur Z (la colonne 2) de la matrice de la base. Équivalent à l'index "
+"de tableau [code]2[/code]."
#: doc/classes/Basis.xml
msgid ""
@@ -14352,24 +14772,34 @@ msgid ""
"This constant can be used to make your code clearer, and for consistency "
"with C#."
msgstr ""
+"La base d'identité, sans rotation ni mise à l'échelle.\n"
+"Ceci est identique à [code]Basis()[/code] sans aucun paramètre. Cette "
+"constante peut être utilisée pour que votre code soit plus clair, et pour la "
+"cohérence avec C#."
#: doc/classes/Basis.xml
msgid ""
"The basis that will flip something along the X axis when used in a "
"transformation."
msgstr ""
+"La base qui appliquera un effet miroir suivant l'axe X lorsqu'elle est "
+"utilisée dans une transformation."
#: doc/classes/Basis.xml
msgid ""
"The basis that will flip something along the Y axis when used in a "
"transformation."
msgstr ""
+"La base qui appliquera un effet miroir suivant l'axe Y lorsqu'elle est "
+"utilisée dans une transformation."
#: doc/classes/Basis.xml
msgid ""
"The basis that will flip something along the Z axis when used in a "
"transformation."
msgstr ""
+"La base qui appliquera un effet miroir suivant l'axe Z lorsqu'elle est "
+"utilisée dans une transformation."
#: doc/classes/BitMap.xml
msgid "Boolean matrix."
@@ -14381,6 +14811,10 @@ msgid ""
"a binary matrix (every matrix element takes only one bit) and query the "
"values using natural cartesian coordinates."
msgstr ""
+"Un tableau bidimensionnel de valeurs booléennes, peut être utilisé pour "
+"stocker efficacement une matrice binaire (chaque élément matrice ne contient "
+"qu'un bit) et faire des requêtes sur ces valeurs à l'aide de coordonnées "
+"naturelles cartésiennes."
#: doc/classes/BitMap.xml
msgid ""
@@ -14389,6 +14823,10 @@ msgid ""
"are being converted into white pixels, and [code]false[/code] bits into "
"black."
msgstr ""
+"Retourne une image de la même taille que la bitmap au format [enum.Format] "
+"du type [code]FORMAT_L8[/code]. Les valeurs [code]true[/code] de l'image "
+"seront converties en pixels blancs, et les valeurs [code]false[/code] en "
+"noir."
#: doc/classes/BitMap.xml
msgid ""
@@ -14404,6 +14842,10 @@ msgid ""
"that position is equal to [code]threshold[/code] or less, and [code]true[/"
"code] in other case."
msgstr ""
+"Crée un bitmap qui correspond aux dimensions de l'image donnée, chaque "
+"élément du bitmap sera remplacé par [code]false[/code] si l'opacité de ce "
+"pixel est inférieur ou égal à [code]threshold[/code], et [code]true[/code] "
+"sinon."
#: doc/classes/BitMap.xml
msgid "Returns bitmap's value at the specified position."
@@ -14426,6 +14868,12 @@ msgid ""
"area where the morphological operation is applied. Pixels located outside "
"the [code]rect[/code] are unaffected by [method grow_mask]."
msgstr ""
+"Applique une dilatation ou une érosion morphologique du bitmap. Si "
+"[code]pixels[/code] est positif, une dilatation est appliquée au bitmap. Si "
+"[code]pixels[/code] est négatif, une érosion est appliquée. [code]rect[/"
+"code] définit la zone où l'opération morphologique est appliquée. Les pixels "
+"situés à l'extérieur du [code]rect[/code] ne sont pas affectés par [method "
+"grow_mask]."
#: doc/classes/BitMap.xml
msgid "Resizes the image to [code]new_size[/code]."
@@ -14458,6 +14906,10 @@ msgid ""
"Supports distance fields. For using vector font files like TTF directly, see "
"[DynamicFont]."
msgstr ""
+"Rend le texte en utilisant les atlas des texture contenues dans le fichier "
+"[code]*.fnt[/code]. Supporte les champs de distance. Pour utiliser "
+"directement des fichiers de police vectorielles, comme le TTF, voir "
+"[DynamicFont]."
#: doc/classes/BitmapFont.xml
msgid ""
@@ -14467,6 +14919,11 @@ msgid ""
"alignment for the character and [code]advance[/code] is the (optional) "
"advance."
msgstr ""
+"Ajoute un caractère à la police, où [code]character[/code] est la valeur "
+"Unicode, [code]texture[/code] est l'index de la texture, [code]rect[/code] "
+"est la région de la texture (en pixels !), [code]align[/code] est "
+"l'alignement (optionnel) du caractère et [code]advance[/code] est "
+"l'avancement (optionnel)."
#: doc/classes/BitmapFont.xml
msgid ""
@@ -14537,6 +14994,17 @@ msgid ""
"menu option, from the code, you need to iterate over the bones to set their "
"individual rest poses."
msgstr ""
+"Utilise une hiérarchie [code]Bone2D[/code] liée à un [Skeleton2D] pour "
+"contrôler et animer d'autres nœuds [Node2D].\n"
+"Vous pouvez utiliser les nœuds [code]Bone2D[/code] et [code]Skeleton2D[/"
+"code] pour animer les maillages 2D créées avec l'éditeur d'UV de Polygon "
+"2D.\n"
+"Chaque os a une transformation de repos [member rest] que vous pouvez "
+"réinitialiser avec [method apply_rest]. Ces poses de repos sont par rapport "
+"au parent de l'os.\n"
+"Si dans l'éditeur vous pouvez définir la pose de repos d'un squelette entier "
+"en utilisant une option de menu, à partir du code, vous devez itérer sur les "
+"os pour définir leurs poses de repos individuelles."
#: doc/classes/Bone2D.xml
msgid "Stores the node's current transforms in [member rest]."
@@ -14552,6 +15020,9 @@ msgid ""
"Returns the node's [member rest] [code]Transform2D[/code] if it doesn't have "
"a parent, or its rest pose relative to its parent."
msgstr ""
+"Retourne la [code]Transform2D[/code] du nœud pour la position de repos "
+"[member rest] s'il n'a pas de parent, ou si sa position de repos est "
+"relative à son parent."
#: doc/classes/Bone2D.xml
msgid ""
@@ -14578,6 +15049,9 @@ msgid ""
"for this node to attach to. The BoneAttachment node will copy the transform "
"of the selected bone."
msgstr ""
+"Ce nœud doit être l'enfant d'un nœud [Skeleton]. Vous pouvez alors "
+"sélectionner un os pour que ce nœud soit attaché. Le nœud BoneAttachment "
+"copiera la transformation de l'os sélectionné."
#: doc/classes/BoneAttachment.xml
msgid "The name of the attached bone."
@@ -14712,6 +15186,11 @@ msgid ""
"Examples: [code]bool(\"False\")[/code] returns [code]true[/code], "
"[code]bool(\"\")[/code] returns [code]false[/code]."
msgstr ""
+"Convertit une valeur [String] en valeur booléenne, cette méthode retournera "
+"[code]false[/code] si [code]\"\"[/code] est donné, et [code]true[/code] pour "
+"toute chaîne non vide.\n"
+"Exemples : [code]bool(\"False\")[/code] retourne [code]true[/code], "
+"[code]bool(\"\")[/code] retourne [code]false[/code]."
#: doc/classes/BoxContainer.xml
msgid "Base class for box containers."
@@ -14722,12 +15201,16 @@ msgid ""
"Arranges child controls vertically or horizontally, and rearranges the "
"controls automatically when their minimum size changes."
msgstr ""
+"Arrange les contrôles enfants verticalement ou horizontalement, et "
+"réorganise les contrôles automatiquement lorsque leur taille minimale change."
#: doc/classes/BoxContainer.xml
msgid ""
"Adds a control to the box as a spacer. If [code]true[/code], [code]begin[/"
"code] will insert the spacer control in front of other children."
msgstr ""
+"Ajoute un contrôle à la boîte comme espace. Si [code]true[/code], "
+"[code]begin[/code] insérera le contrôle d'espace devant les autres enfants."
#: doc/classes/BoxContainer.xml
msgid ""
@@ -14764,20 +15247,22 @@ msgstr ""
#: doc/classes/RigidBody.xml doc/classes/SphereShape.xml
#: doc/classes/StaticBody.xml
msgid "3D Physics Tests Demo"
-msgstr ""
+msgstr "Démo des tests de physique 3D"
#: doc/classes/BoxShape.xml doc/classes/CollisionShape.xml
#: modules/gridmap/doc_classes/GridMap.xml doc/classes/KinematicBody.xml
#: doc/classes/Mesh.xml doc/classes/MeshInstance.xml
#: doc/classes/MeshLibrary.xml
msgid "3D Kinematic Character Demo"
-msgstr ""
+msgstr "Démo de caractère cinématique 3D"
#: doc/classes/BoxShape.xml
msgid ""
"The box's half extents. The width, height and depth of this shape is twice "
"the half extents."
msgstr ""
+"La demi-étendue de la boîte. La largeur, la hauteur et la profondeur de "
+"cette forme sont deux fois plus larges."
#: doc/classes/Button.xml
msgid "Standard themed Button."
@@ -14838,7 +15323,7 @@ msgstr ""
#: doc/classes/PoolStringArray.xml doc/classes/ProjectSettings.xml
#: doc/classes/ResourceLoader.xml doc/classes/RichTextLabel.xml
msgid "OS Test Demo"
-msgstr ""
+msgstr "Démo de test de système d'exploitation"
#: doc/classes/Button.xml
msgid ""
@@ -14854,12 +15339,17 @@ msgid ""
"clipped, when disabled the Button will always be wide enough to hold the "
"text."
msgstr ""
+"Lorsque cette propriété est activée, un texte trop grand pour ce bouton sera "
+"tronqué, et lorsque le bouton est désactivé, il sera toujours assez grand "
+"pour contenir tout le texte."
#: doc/classes/Button.xml
msgid ""
"When enabled, the button's icon will expand/shrink to fit the button's size "
"while keeping its aspect."
msgstr ""
+"Lorsque actif, l'icône du bouton s'étendra/se réduira selon la taille du "
+"bouton et gardera son aspect."
#: doc/classes/Button.xml
msgid "Flat buttons don't display decoration."
@@ -14872,6 +15362,11 @@ msgid ""
"property of [Button] and [code]content_margin_*[/code] properties of the "
"used [StyleBox]es."
msgstr ""
+"L'icône du bouton, si le texte est présent, l'icône sera placée avant le "
+"texte.\n"
+"Pour modifier la marge et l'espacement de l'icône, utilisez la propriété "
+"[code]hseparation[/code] du thème pour le [Button] et les propriétés "
+"[code]content_margin_*[/code] de la [StyleBox] utilisée."
#: doc/classes/Button.xml
msgid ""
@@ -14879,6 +15374,10 @@ msgid ""
"button. Uses the same [enum TextAlign] constants as the text alignment. If "
"centered, text will draw on top of the icon."
msgstr ""
+"Spécifie si l'icône doit être alignée sur la gauche, la droite ou au centre "
+"d'un bouton. Utilisez les mêmes constantes [enum TextAlign] que pour "
+"l'alignement du texte. Si l'icône est centrée, elle sera affichée sous le "
+"texte."
#: doc/classes/Button.xml doc/classes/LinkButton.xml
msgid "The button's text that will be displayed inside the button's area."
@@ -14910,6 +15409,9 @@ msgid ""
"text color of the button. Disabled, hovered, and pressed states take "
"precedence over this color."
msgstr ""
+"La [Color] du texte utilisée lorsque le [Button] a le focus. Ne fait que "
+"remplacer la couleur normale du texte du bouton. Les couleurs définies pour "
+"les états désactivé, survolé et pressé sont prioritaires sur cette couleur."
#: doc/classes/Button.xml
msgid "Text [Color] used when the [Button] is being hovered."
@@ -14937,6 +15439,9 @@ msgid ""
"current [StyleBox], so using [StyleBoxEmpty] will just disable the focus "
"visual effect."
msgstr ""
+"La [StyleBox] utilisée lorsque le [Button] a le focus. Elle est affichée par "
+"dessus la [StyleBox] actuelle, donc en utilisant [StyleBoxEmpty], ne fera "
+"que désactiver l'effet visuel quand le bouton a le focus."
#: doc/classes/Button.xml
msgid "[StyleBox] used when the [Button] is being hovered."
@@ -14960,6 +15465,10 @@ msgid ""
"Only one allows being pressed.\n"
"[member BaseButton.toggle_mode] should be [code]true[/code]."
msgstr ""
+"Un groupe de [Button]. Tous les boutons enfants directs et indirects "
+"deviennent des boutons radios. Un seul de ces boutons peut être pressé à la "
+"fois.\n"
+"[member BaseButton.toggle_mode] devrait être [code]true[/code]."
#: doc/classes/ButtonGroup.xml
msgid ""
@@ -15043,6 +15552,9 @@ msgid ""
"[code]enable_next[/code] is [code]true[/code], request to make the next "
"camera current, if any."
msgstr ""
+"Si c'est la caméra actuelle, elle ne sera plus l'actuelle. Si "
+"[code]enable_next[/code] est [code]true[/code], passe à la caméra suivante "
+"pour la rendre actuelle, s'il y en a une."
#: doc/classes/Camera.xml
msgid "Returns the camera's RID from the [VisualServer]."
@@ -15055,6 +15567,10 @@ msgid ""
"to the position and orientation of the camera by subclassed cameras such as "
"[ClippedCamera], [InterpolatedCamera] and [ARVRCamera]."
msgstr ""
+"Retourne la transformation de la caméra avec les décalages vertical ([member "
+"v_offset]) et horizontal ([member h_offset]) ; et tout autre ajustement "
+"apporté à la position et à l'orientation de la caméra par les sous-classes "
+"de caméra comme [ClippedCamera], [InterpolatedCamera] et [ARVRCamera]."
#: doc/classes/Camera.xml
msgid ""
@@ -15077,6 +15593,9 @@ msgid ""
"[b]Note:[/b] A position which returns [code]false[/code] may still be "
"outside the camera's field of view."
msgstr ""
+"Retourne [code]true[/code] si la position donnée est derrière la caméra.\n"
+"[b]Note :[/b] Une position qui retourne [code]false[/code] peut quand même "
+"être en dehors du champ de vision de la caméra."
#: doc/classes/Camera.xml
msgid ""
@@ -15084,6 +15603,10 @@ msgid ""
"description). If the camera node is outside the scene tree, it will attempt "
"to become current once it's added."
msgstr ""
+"Fait que cette caméra devient l'actuelle pour le [Viewport] (voir la "
+"description de la classe). Si le nœud de la caméra est en dehors de "
+"l'arborescence de la scène, il tentera de devenir l'actuel dès qu'il sera "
+"ajouté."
#: doc/classes/Camera.xml
msgid ""
@@ -15098,6 +15621,9 @@ msgid ""
"the [Viewport] rectangle on a plane that is the given [code]z_depth[/code] "
"distance into the scene away from the camera."
msgstr ""
+"Retourne le point 3D dans l'espace global qui correspond à la coordonnées 2D "
+"donnée dans le rectangle du [Viewport] sur un plan qui est à la distance "
+"[code]z_depth[/code] donnée dans la scène par rapport à la caméra."
#: doc/classes/Camera.xml
msgid ""
@@ -15106,6 +15632,10 @@ msgid ""
"useful for casting rays in the form of (origin, normal) for object "
"intersection or picking."
msgstr ""
+"Retourne la normale dans l'espace global, qui est le résultat de la "
+"projection d'un point sur le rectangle [Viewport] par la projection inverse "
+"de la caméra. Ceci est utile pour lancer des rayons sous la forme (origine, "
+"normale) pour l'intersection ou la sélection d'objets."
#: doc/classes/Camera.xml
msgid ""
@@ -15114,6 +15644,10 @@ msgid ""
"useful for casting rays in the form of (origin, normal) for object "
"intersection or picking."
msgstr ""
+"Retourne la position 3D dans l'espace global, qui est le résultat de "
+"projeter un point sur le rectangle [Viewport] par la projection inverse de "
+"la caméra. Ceci est utile pour lancer des rayons sous la forme (origine, "
+"normale) pour l'intersection ou la sélection d'objets."
#: doc/classes/Camera.xml
msgid ""
@@ -15258,6 +15792,8 @@ msgid ""
"The axis to lock during [member fov]/[member size] adjustments. Can be "
"either [constant KEEP_WIDTH] or [constant KEEP_HEIGHT]."
msgstr ""
+"L'axe à verrouiller pendant les réglages [member fov] ou [member size]. Peut "
+"être soit [constant KEEP_WIDTH] ou [constant KEEP_HEIGHT]."
#: doc/classes/Camera.xml
msgid ""
@@ -15271,6 +15807,9 @@ msgid ""
"objects' Z distance from the camera's local space scales their perceived "
"size."
msgstr ""
+"Le mode de projection de la caméra. Dans le mode [constant "
+"PROJECTION_PERSPECTIVE], la distance des objets dans l'espace local de la "
+"caméra détermine la taille apparante de ces objets."
#: doc/classes/Camera.xml
msgid ""
@@ -15278,6 +15817,10 @@ msgid ""
"orthogonal and frustum modes. Since [member keep_aspect] locks on axis, "
"[code]size[/code] sets the other axis' size length."
msgstr ""
+"La taille de la caméra mesurée comme la moitié de la largeur ou de la "
+"hauteur. N'est applicable qu'en modes orthogonal et frustum. Comme [member "
+"keep_aspect] verrouille l'axe, [code]size[/code] fixe la longueur de la "
+"taille sur l'autre axe."
#: doc/classes/Camera.xml
msgid "The vertical (Y) offset of the camera viewport."
@@ -15296,6 +15839,9 @@ msgid ""
"Orthogonal projection, also known as orthographic projection. Objects remain "
"the same size on the screen no matter how far away they are."
msgstr ""
+"La projection orthogonale, également connue sous le nom de projection "
+"orthographique. Les objets gardent la même taille à l'écran, indépendamment "
+"de leur distance."
#: doc/classes/Camera.xml
msgid ""
@@ -15316,6 +15862,10 @@ msgid ""
"usually the best option for projects running in landscape mode, as wider "
"aspect ratios will automatically benefit from a wider horizontal FOV."
msgstr ""
+"Préserve le rapport d'aspect vertical ; également connu sous le nom "
+"d'échelle Hor+. C'est généralement la meilleure option pour les projets en "
+"mode paysage, car les ratios d'aspect plus larges bénéficieront "
+"automatiquement d'un champ de vision horizontal plus large."
#: doc/classes/Camera.xml
msgid ""
@@ -15333,6 +15883,11 @@ msgid ""
"objects affect how audio is perceived (changing the audio's [member "
"AudioStreamPlayer3D.pitch_scale])."
msgstr ""
+"Simulate [url=https://fr.wikipedia.org/wiki/Effet_Doppler]l'effet Doppler[/"
+"url] en suivant la position des objets qui ont changé lors de "
+"[code]_process[/code]. Les changements dans la vitesse relative de cette "
+"caméra par rapport à ces objets affectent la façon dont l'audio est perçu "
+"(changement de la hauteur [member AudioStreamPlayer3D.pitch_scale])."
#: doc/classes/Camera.xml
msgid ""
@@ -15363,6 +15918,21 @@ msgid ""
"limits. You can use [method get_camera_screen_center] to get the real "
"position."
msgstr ""
+"Le nœud de la caméra pour les scènes 2D. Il force l'écran (le calque actuel) "
+"à défiler en suivant ce nœud. Cela rend plus facile (et plus rapide) de "
+"programmer des scènes qui défilent que de changer manuellement la position "
+"des nœuds basés sur [CanvasItem].\n"
+"Ce nœud est destiné à être une simple aide pour obtenir les objets qui vont "
+"rapidement, mais plus de fonctionnalités peuvent être désirées pour changer "
+"la façon dont la caméra se comporte. Pour faire votre propre nœud de caméra "
+"personnalisé, héritez de [Node2D] et modifiez la transformation du canevas "
+"en paramétrant [member Viewport.canvas_transform] dans [Viewport] (vous "
+"pouvez obtenir le [Viewport] actuel en utilisant [method Node."
+"get_viewport])\n"
+"Notez que la [code]position[/code] de la [Camera2D] ne représente pas la "
+"position réelle de l'écran, qui peut différer en raison de lissage ou de "
+"limites appliqués. Vous pouvez utiliser [method get_camera_screen_center] "
+"pour obtenir la position réelle."
#: doc/classes/Camera2D.xml doc/classes/TileMap.xml doc/classes/TileSet.xml
msgid "2D Isometric Demo"
@@ -15382,6 +15952,7 @@ msgid ""
"Removes any [Camera2D] from the ancestor [Viewport]'s internal currently-"
"assigned camera."
msgstr ""
+"Enlève toute caméra [Camera2D] du [Viewport] parent assigné en interne."
#: doc/classes/Camera2D.xml
msgid "Forces the camera to update scroll immediately."
@@ -15395,6 +15966,11 @@ msgid ""
"or [member Node2D.global_position], as it is affected by the [code]drag[/"
"code] properties."
msgstr ""
+"Retourne la [code]position[/code] de la caméra (le point suivi que la caméra "
+"essaye de suivre), par rapport à l'origine.\n"
+"[b]Note :[/b] La valeur retournée n'est pas la même que [member Node2D."
+"position] ou [member Node2D.global_position], car elle est aussi affectée "
+"par les propriétés [code]drag[/code]."
#: doc/classes/Camera2D.xml
msgid ""
@@ -15403,12 +15979,18 @@ msgid ""
"[b]Note:[/b] The real [code]position[/code] of the camera may be different, "
"see [method get_camera_position]."
msgstr ""
+"Retourne l'emplacement du centre de l'écran de la [Camera2D], par rapport à "
+"l'origine.\n"
+"[b]Note :[/b] La véritable [code]position[/code] de la caméra peut être "
+"différente, voir [method get_camera_position]."
#: doc/classes/Camera2D.xml
msgid ""
"Returns the specified margin. See also [member drag_margin_bottom], [member "
"drag_margin_top], [member drag_margin_left], and [member drag_margin_right]."
msgstr ""
+"Retourne la marge spécifiée. Voir aussi [member drag_margin_bottom], [member "
+"drag_margin_top], [member drag_margin_left], et [member drag_margin_right]."
#: doc/classes/Camera2D.xml
msgid ""
@@ -15463,6 +16045,9 @@ msgid ""
"The custom [Viewport] node attached to the [Camera2D]. If [code]null[/code] "
"or not a [Viewport], uses the default viewport instead."
msgstr ""
+"Le nœud [Viewport] personnalisé attaché à la [Camera2D]. Si [code]null[/"
+"code] ou que ça n'est pas un [Viewport], ça utilise la fenêtre d'affichage "
+"par défaut à la place."
#: doc/classes/Camera2D.xml
msgid ""
@@ -15476,24 +16061,36 @@ msgid ""
"drag margins. If [code]false[/code], the camera moves horizontally "
"regardless of margins."
msgstr ""
+"Si [code]true[/code], la caméra ne bouge que lorsqu'elle atteint les marges "
+"horizontales de glissage. Si [code]false[/code], la caméra se déplace "
+"horizontalement indépendamment des marges."
#: doc/classes/Camera2D.xml
msgid ""
"Left margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
+"La marge gauche nécessaire pour pour glisser la caméra. Une valeur de "
+"[code]1[/code] ne déplace la caméra que lorsqu'elle atteint le bord de "
+"l'écran."
#: doc/classes/Camera2D.xml
msgid ""
"Right margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
+"La marge droite nécessaire pour pour glisser la caméra. Une valeur de "
+"[code]1[/code] ne déplace la caméra que lorsqu'elle atteint le bord de "
+"l'écran."
#: doc/classes/Camera2D.xml
msgid ""
"Top margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
+"La marge supérieure nécessaire pour pour glisser la caméra. Une valeur de "
+"[code]1[/code] ne déplacer la caméra que lorsqu'elle atteint le bord de "
+"l'écran."
#: doc/classes/Camera2D.xml
msgid ""
@@ -15501,16 +16098,23 @@ msgid ""
"margins. If [code]false[/code], the camera moves vertically regardless of "
"margins."
msgstr ""
+"Si [code]true[/code], la caméra ne bouge que lorsqu'elle atteint les marges "
+"verticales de glissage. Si [code]false[/code], la caméra se déplace "
+"verticalement indépendamment des marges."
#: doc/classes/Camera2D.xml
msgid ""
"If [code]true[/code], draws the camera's drag margin rectangle in the editor."
msgstr ""
+"Si [code]true[/code], dessine le rectangle de la marge de glissage de la "
+"caméra activée dans l'éditeur."
#: doc/classes/Camera2D.xml
msgid ""
"If [code]true[/code], draws the camera's limits rectangle in the editor."
msgstr ""
+"Si [code]true[/code], dessine le rectangle des limites de la caméra activée "
+"dans l'éditeur."
#: doc/classes/Camera2D.xml
msgid ""
@@ -15551,6 +16155,13 @@ msgid ""
"without smoothing, even with this setting enabled, invoke [method "
"reset_smoothing]."
msgstr ""
+"Si [code]true[/code], la caméra s'arrête en douceur quand elle atteint ses "
+"limites.\n"
+"Cette propriété n'a aucun effet si [member smoothing_enabled] est "
+"[code]false[/code].\n"
+"[b]Note :[/b] Pour mettre immédiatement à jour la position de la caméra "
+"activée sans ralenti, même avec ce réglage activé, appelez [method "
+"reset_smoothing]."
#: doc/classes/Camera2D.xml
msgid ""
@@ -15573,12 +16184,19 @@ msgid ""
"not updated in any way if drag margins are enabled and can be used to set "
"initial offset."
msgstr ""
+"Le décalage horizontal de la caméra, par rapport aux marges de glissage.\n"
+"[b]Note :[/b] Le décalage H est utilisé uniquement pour forcer le décalage "
+"par rapport aux marges. Elle n'est pas mise à jour même si les marges de "
+"glissage sont activées et peuvent être utilisées pour régler le décalage "
+"initial."
#: doc/classes/Camera2D.xml
msgid ""
"The vertical offset of the camera, relative to the drag margins.\n"
"[b]Note:[/b] Used the same as [member offset_h]."
msgstr ""
+"Le décalage vertical de la caméra, par rapport aux marges de glissage.\n"
+"[b]Note :[/b] Utilisé de la même manière que [member offset_h]."
#: doc/classes/Camera2D.xml
msgid "The camera's process callback. See [enum Camera2DProcessMode]."
@@ -15603,6 +16221,8 @@ msgid ""
"Speed in pixels per second of the camera's smoothing effect when [member "
"smoothing_enabled] is [code]true[/code]."
msgstr ""
+"La vitesse en pixels par seconde de l'effet de ralenti de la caméra quand "
+"[member smoothing_enabled] est [code]true[/code]."
#: doc/classes/Camera2D.xml
msgid ""
@@ -15611,6 +16231,10 @@ msgid ""
"example, use [code]Vector2(0.5, 0.5)[/code] for a 2× zoom-in, and "
"[code]Vector2(4, 4)[/code] for a 4× zoom-out."
msgstr ""
+"Le zoom de l'appareil photo relatif à la fenêtre d'affichage. Les valeurs "
+"supérieures à [code]Vector2(1, 1)[/code] font un zoom arrière et les valeurs "
+"plus petites un zoom avant. Par exemple, utilisez [code]Vector2(0.5, 0.5)[/"
+"code] pour un zoom à 50%, et [code]Vector2(4, 4)[/code] pour un zoom 4×."
#: doc/classes/Camera2D.xml
msgid ""
@@ -15629,10 +16253,12 @@ msgstr ""
"et la taille de l'écran."
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr "La caméra se met à jour avec le rappel [code]_physics_process[/code]."
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr "La caméra se met à jour durant l'appel de [code]_process[/code]."
@@ -15801,6 +16427,10 @@ msgid ""
"[b]Note:[/b] Many cameras supply YCbCr images which need to be converted in "
"a shader."
msgstr ""
+"Cette texture donne accès à la texture de la caméra fournie par "
+"[CameraFeed].\n"
+"[b]Note :[/b] Beaucoup de caméras fournissent des images au format YCbCr qui "
+"doivent être converties dans un shader."
#: doc/classes/CameraTexture.xml
msgid "The ID of the [CameraFeed] for which we want to display the image."
@@ -15811,13 +16441,15 @@ msgstr ""
msgid ""
"Convenience property that gives access to the active property of the "
"[CameraFeed]."
-msgstr ""
+msgstr "Propriété utile qui donne accès à la propriété active du [CameraFeed]."
#: doc/classes/CameraTexture.xml
msgid ""
"Which image within the [CameraFeed] we want access to, important if the "
"camera image is split in a Y and CbCr component."
msgstr ""
+"L'image du [CameraFeed] pour laquelle nous voulons accéder, important si "
+"l'image de la caméra est divisée en composants Y et CbCr."
#: doc/classes/CanvasItem.xml
msgid "Base class of anything 2D."
@@ -15875,7 +16507,7 @@ msgstr ""
"parente a changé.\n"
"[b]Note :[/b] Sauf exception, toutes les paramètres d'angle doivent être des "
"spécifiés en [i]radians[/i]. Pour convertir des degrés en radians, utilisez "
-"[méthod @GDScript.deg2rad]"
+"[méthod @GDScript.deg2rad]."
#: doc/classes/CanvasItem.xml doc/classes/CanvasLayer.xml
#: doc/classes/InputEvent.xml doc/classes/Viewport.xml
@@ -16006,6 +16638,8 @@ msgid ""
"Draws a [Mesh] in 2D, using the provided texture. See [MeshInstance2D] for "
"related documentation."
msgstr ""
+"Dessine un [Mesh] en 2D, en utilisant la texture spécifiée. Voir "
+"[MeshInstance2D] pour la documentation en rapport."
#: doc/classes/CanvasItem.xml
msgid ""
@@ -16034,6 +16668,7 @@ msgstr ""
"avec anti-crénelage."
#: doc/classes/CanvasItem.xml
+#, fuzzy
msgid ""
"Draws multiple disconnected lines with a uniform [code]width[/code] and "
"segment-by-segment coloring. Colors assigned to line segments match by index "
@@ -16066,6 +16701,8 @@ msgid ""
"Draws a [MultiMesh] in 2D with the provided texture. See "
"[MultiMeshInstance2D] for related documentation."
msgstr ""
+"Dessine un [MultiMesh] en 2D avec la texture spécifiée. Voir "
+"[MultiMeshInstance2D] pour la documentation en rapport."
#: doc/classes/CanvasItem.xml
msgid ""
@@ -16304,6 +16941,8 @@ msgid ""
"Returns the mouse's position in the [CanvasLayer] that this [CanvasItem] is "
"in using the coordinate system of the [CanvasLayer]."
msgstr ""
+"Retourne la position de la souris dans le [CanvasLayer] que ce [CanvasItem] "
+"utilise suivant le système de coordonnées du [CanvasLayer]."
#: doc/classes/CanvasItem.xml
msgid "Returns the global transform matrix of this item."
@@ -16321,6 +16960,8 @@ msgid ""
"Returns the mouse's position in this [CanvasItem] using the local coordinate "
"system of this [CanvasItem]."
msgstr ""
+"Retourne la position de la souris dans le [CanvasItem] en utilisant le "
+"système de coordonnées local au [CanvasItem]."
#: doc/classes/CanvasItem.xml
msgid "Returns the transform matrix of this item."
@@ -16345,6 +16986,8 @@ msgid ""
"Hide the [CanvasItem] if it's currently visible. This is equivalent to "
"setting [member visible] to [code]false[/code]."
msgstr ""
+"Cacher les [CanvasItem] s'ils sont actuellement visibles. C'est équivalent à "
+"[member visible] à [code]false[/code]."
#: doc/classes/CanvasItem.xml
msgid ""
@@ -16359,6 +17002,8 @@ msgid ""
"Returns [code]true[/code] if the node is set as top-level. See [method "
"set_as_toplevel]."
msgstr ""
+"Retourne [code]true[/code] si le nœud est défini comme de niveau supérieur. "
+"Voir [méthode set_as_toplevel]."
#: doc/classes/CanvasItem.xml
msgid ""
@@ -16375,16 +17020,24 @@ msgid ""
"also visible. If any antecedent is hidden, this node will not be visible in "
"the scene tree."
msgstr ""
+"Retourne [code]true[/code] si le nœud est présent dans le [SceneTree], que "
+"sa propriété [member visible] est [code]true[/code] et que tous ses parents "
+"sont également visibles. Si un parent est caché, ce nœud ne sera pas visible "
+"dans l'arborescence de la scène."
#: doc/classes/CanvasItem.xml
msgid "Assigns [code]screen_point[/code] as this node's new local transform."
msgstr ""
+"Assigne [code]screen_point[/code] comme la nouvelle position locale de ce "
+"nœud."
#: doc/classes/CanvasItem.xml
msgid ""
"Transformations issued by [code]event[/code]'s inputs are applied in local "
"space instead of global space."
msgstr ""
+"Les transformations émises par les entrées de [code]event[/code] sont "
+"appliquées dans l'espace local au lieu de l'espace global."
#: doc/classes/CanvasItem.xml
msgid ""
@@ -16394,6 +17047,12 @@ msgid ""
"top-level. The [CanvasItem] will effectively act as if it was placed as a "
"child of a bare [Node]. See also [method is_set_as_toplevel]."
msgstr ""
+"Si [code]enable[/code] est [code]true[/code], ce [CanvasItem] n'héritera "
+"[i]pas[/i] de sa transformation de son [CanvasItem] parent. Son ordre "
+"d'affichage sera également modifié pour dessiner sur les autres [CanvasItem] "
+"qui ne sont pas prioritaires. Le [CanvasItem] se comportera efficacement "
+"comme s'il était placé comme un enfant d'un [Node] vide. Voir aussi [method "
+"is_set_as_toplevel]."
#: doc/classes/CanvasItem.xml
msgid ""
@@ -16401,12 +17060,17 @@ msgid ""
"[constant NOTIFICATION_LOCAL_TRANSFORM_CHANGED] when its local transform "
"changes."
msgstr ""
+"Si [code]enable[/code] est [code]true[/code], ce nœud recevra [constant "
+"NOTIFICATION_LOCAL_TRANSFORM_CHANGED] lorsque sa transformation locale "
+"changera."
#: doc/classes/CanvasItem.xml
msgid ""
"If [code]enable[/code] is [code]true[/code], this node will receive "
"[constant NOTIFICATION_TRANSFORM_CHANGED] when its global transform changes."
msgstr ""
+"Si [code]enable[/code] est [code]true[/code], ce nœud recevra [constant "
+"NOTIFICATION_TRANSFORM_CHANGED] lorsque sa transformation globale changera."
#: doc/classes/CanvasItem.xml
msgid ""
@@ -16415,18 +17079,24 @@ msgid ""
"[Popup], the correct way to make them visible is to call one of the multiple "
"[code]popup*()[/code] functions instead."
msgstr ""
+"Affiche le [CanvasItem] s'il est actuellement caché. Ceci est équivalent à "
+"[member visible] à [code]true[/code]. Pour les contrôles hérités de [Popup], "
+"appelez plutôt l'une des fonctions [code]popup*()[/code] pour le rendre "
+"visible."
#: doc/classes/CanvasItem.xml
msgid ""
"Queue the [CanvasItem] for update. [constant NOTIFICATION_DRAW] will be "
"called on idle time to request redraw."
msgstr ""
+"Ajoute le [CanvasItem] pour être mis à jour. [constant NOTIFICATION_DRAW] "
+"sera émise sur le temps inoccupé pour demander la mise à jour."
#: doc/classes/CanvasItem.xml
msgid ""
"The rendering layers in which this [CanvasItem] responds to [Light2D] nodes."
msgstr ""
-"Les claques de rendu où le [CanvasItem] est affecté par les nœuds [Light2D]."
+"Les calques de rendu où le [CanvasItem] est affecté par les nœuds [Light2D]."
#: doc/classes/CanvasItem.xml
msgid "The material applied to textures on this [CanvasItem]."
@@ -16441,6 +17111,8 @@ msgid ""
"The color applied to textures on this [CanvasItem]. This is not inherited by "
"children [CanvasItem]s."
msgstr ""
+"La couleur appliquée aux textures sur ce [CanvasItem]. Cela n'est pas hérité "
+"pour les [CanvasItem] enfants."
#: doc/classes/CanvasItem.xml
msgid "If [code]true[/code], the object draws behind its parent."
@@ -16455,6 +17127,8 @@ msgid ""
"If [code]true[/code], the parent [CanvasItem]'s [member material] property "
"is used as this one's material."
msgstr ""
+"Si [code]true[/code], la propriété [member material] du [CanvasItem] parent "
+"est utilisée comme matériau de celui-ci."
#: doc/classes/CanvasItem.xml
msgid ""
@@ -16465,12 +17139,21 @@ msgid ""
"visible is to call one of the multiple [code]popup*()[/code] functions "
"instead."
msgstr ""
+"Si [code]true[/code], ce [CanvasItem] est affiché. Le nœud n'est visible que "
+"si tous ses parents le sont également (en d'autres termes, [méthode "
+"is_visible_in_tree] doit retourner [code]true[/code]).\n"
+"[b]Note :[/b] Pour les contrôles qui héritent de [Popup], la bonne manière "
+"de les rendre visible est plutôt d'appeler l'une des fonctions [code]popup*()"
+"[/code]."
#: doc/classes/CanvasItem.xml
msgid ""
"Emitted when the [CanvasItem] must redraw. This can only be connected "
"realtime, as deferred will not allow drawing."
msgstr ""
+"Émis lorsque le [CanvasItem] doit être redessiné. Ça ne peut être que "
+"connecté qu'en temps réel, puisque le différer peut ne pas permettre le "
+"dessin."
#: doc/classes/CanvasItem.xml
msgid "Emitted when becoming hidden."
@@ -16482,6 +17165,9 @@ msgid ""
"or when an action is taking place that may have impacted these boundaries (e."
"g. changing [member Sprite.texture])."
msgstr ""
+"Émis quand la position ou la taille du [Rect2] a changé, ou lorsqu'une "
+"action a changé ces valeurs là (par exemple en changeant [member Sprite."
+"texture])."
#: doc/classes/CanvasItem.xml
msgid "Emitted when the visibility (hidden/visible) changes."
@@ -16492,6 +17178,8 @@ msgid ""
"Mix blending mode. Colors are assumed to be independent of the alpha "
"(opacity) value."
msgstr ""
+"Le mode de mélange. Les couleurs sont supposées être indépendantes de "
+"l'opacité."
#: doc/classes/CanvasItem.xml doc/classes/CanvasItemMaterial.xml
msgid "Additive blending mode."
@@ -16510,6 +17198,8 @@ msgid ""
"Mix blending mode. Colors are assumed to be premultiplied by the alpha "
"(opacity) value."
msgstr ""
+"Le mode de mélange. Les couleurs sont supposées être prémultipliées par leur "
+"opacité."
#: doc/classes/CanvasItem.xml
msgid ""
@@ -16523,12 +17213,16 @@ msgid ""
"The [CanvasItem]'s global transform has changed. This notification is only "
"received if enabled by [method set_notify_transform]."
msgstr ""
+"La transformation globale du [CanvasItem] a changé. Cette notification n'est "
+"reçue que si elle est activée par [method set_notify_transform]."
#: doc/classes/CanvasItem.xml
msgid ""
"The [CanvasItem]'s local transform has changed. This notification is only "
"received if enabled by [method set_notify_local_transform]."
msgstr ""
+"La transformation locale [CanvasItem] a changé. Cette notification n'est "
+"reçue que si elle est activée par [method set_notify_local_transform]."
#: doc/classes/CanvasItem.xml
msgid "The [CanvasItem] is requested to draw."
@@ -16620,6 +17314,7 @@ msgid ""
"Render the material using both light and non-light sensitive material "
"properties."
msgstr ""
+"Fait le rendu du matériau avec et sans lumière des propriétés matérielles."
#: doc/classes/CanvasItemMaterial.xml
msgid "Render the material as if there were no light."
@@ -16652,7 +17347,7 @@ msgstr ""
#: doc/classes/CanvasLayer.xml
msgid "Canvas layers"
-msgstr "Claques du canevas"
+msgstr "Calques du canevas"
#: doc/classes/CanvasLayer.xml
msgid "Returns the RID of the canvas used by this layer."
@@ -16663,18 +17358,24 @@ msgid ""
"Hides any [CanvasItem] under this [CanvasLayer]. This is equivalent to "
"setting [member visible] to [code]false[/code]."
msgstr ""
+"Masque tous les [CanvasItem] dans ce [CanvasLayer]. Ceci est équivalent à "
+"définir [member visible] à [code]false[/code]."
#: doc/classes/CanvasLayer.xml
msgid ""
"Shows any [CanvasItem] under this [CanvasLayer]. This is equivalent to "
"setting [member visible] to [code]true[/code]."
msgstr ""
+"Affiche tous les [CanvasItem] dans ce [CanvasLayer]. Ceci est équivalent à "
+"définir [member visible] à [code]true[/code]."
#: doc/classes/CanvasLayer.xml
msgid ""
"The custom [Viewport] node assigned to the [CanvasLayer]. If [code]null[/"
"code], uses the default viewport instead."
msgstr ""
+"Le nœud [Viewport] personnalisé assigné au [CanvasLayer]. Si [code]null[/"
+"code], ça utilise la fenêtre d'affichage par défaut à la place."
#: doc/classes/CanvasLayer.xml
msgid ""
@@ -16688,6 +17389,10 @@ msgid ""
"into the foreground should have increasing scales, while layers moving into "
"the background should have decreasing scales."
msgstr ""
+"Change la mise à l'échelle du calque en utilisant [member "
+"follow_viewport_enable]. Les calques se déplaçant au premier plan devraient "
+"avoir des mises à l'échelle croissantes, tandis que les calques se déplaçant "
+"dans le fond devraient avoir des mises à l'échelle décroissantes."
#: doc/classes/CanvasLayer.xml
msgid "Layer index for draw order. Lower values are drawn first."
@@ -16722,6 +17427,10 @@ msgid ""
"Unlike [member CanvasItem.visible], visibility of a [CanvasLayer] isn't "
"propagated to underlying layers."
msgstr ""
+"Si [code]false[/code], tous les [CanvasItem] dans ce [CanvasLayer] sont "
+"cachés.\n"
+"Contrairement à [member CanvasItem.visible], la visibilité d'un "
+"[CanvasLayer] n'est pas propagée aux calques enfants."
#: doc/classes/CanvasLayer.xml
#, fuzzy
@@ -16754,6 +17463,10 @@ msgid ""
"[b]Note:[/b] The capsule's total height is equal to [member mid_height] + 2 "
"* [member radius]."
msgstr ""
+"La hauteur de la partie du cylindrique au milieu de la capsule (donc sans "
+"les bouts hémisphériques).\n"
+"[b]Note :[/b] La hauteur totale de la capsule est égale à [member "
+"mid_height] + 2 * [member radius]."
#: doc/classes/CapsuleMesh.xml
msgid "Number of radial segments on the capsule mesh."
@@ -16792,12 +17505,16 @@ msgid ""
"CenterContainer keeps children controls centered. This container keeps all "
"children to their minimum size, in the center."
msgstr ""
+"CenterContainer garde centrés les contrôles enfants. Ce conteneur garde tous "
+"les enfants à leur taille minimale, dans son centre."
#: doc/classes/CenterContainer.xml
msgid ""
"If [code]true[/code], centers children relative to the [CenterContainer]'s "
"top left corner."
msgstr ""
+"Si [code]true[/code], centre les enfants par rapport au coin supérieur "
+"gauche du [CenterContainer])."
#: doc/classes/CharFXTransform.xml
msgid ""
@@ -16934,6 +17651,15 @@ msgid ""
"See also [BaseButton] which contains common properties and methods "
"associated with this node."
msgstr ""
+"Une case à cocher qui permet à l'utilisateur de faire un choix binaire "
+"(pouvoir seulement choisir une des deux options). C'est similaire à un "
+"[CheckButton] dans ses fonctionnalités, mais avec une apparence différente. "
+"Pour suivre les recommendations d'interface établies, il est recommandé "
+"d'utiliser une CheckBox lorsqu'il n'a [b]pas[/b] d'effet immédiat sur "
+"quelque chose. Par exemple, quand le basculement sera effectif qu'une fois "
+"un bouton de confirmation pressé.\n"
+"Voir aussi [BaseButton] qui contient des propriétés et des méthodes communes "
+"associées à ce nœud."
#: doc/classes/CheckBox.xml
msgid "The [CheckBox] text's font color."
@@ -16950,6 +17676,9 @@ msgid ""
"text color of the checkbox. Disabled, hovered, and pressed states take "
"precedence over this color."
msgstr ""
+"La couleur de la police du texte de la [CheckBox] quand elle a le focus. Ne "
+"remplace que la couleur normale du texte de la case à cocher. Les états "
+"désactivé, survolé et pressé sont prioritaires sur cette couleur."
#: doc/classes/CheckBox.xml
msgid "The [CheckBox] text's font color when it's hovered."
@@ -17090,6 +17819,9 @@ msgid ""
"normal text color of the button. Disabled, hovered, and pressed states take "
"precedence over this color."
msgstr ""
+"La couleur du texte du [CheckButton] quand il a le focus. Ne remplace que la "
+"couleur de texte normale du bouton. Les états désactivés, survolé et pressés "
+"sont prioritaire sur cette couleur."
#: doc/classes/CheckButton.xml
msgid "The [CheckButton] text's font color when it's hovered."
@@ -17109,10 +17841,12 @@ msgstr "La couleur de la police du texte du [CheckButton] quand il est appuyé."
#: doc/classes/CheckButton.xml
msgid "The vertical offset used when rendering the toggle icons (in pixels)."
msgstr ""
+"Le décalage vertical utilisé lors du rendu des icônes de basculement (en "
+"pixels)."
#: doc/classes/CheckButton.xml
msgid "The separation between the toggle icon and the text (in pixels)."
-msgstr ""
+msgstr "La séparation entre l'icône de basculement et le texte (en pixels)."
#: doc/classes/CheckButton.xml
msgid "The [Font] to use for the [CheckButton] text."
@@ -17158,6 +17892,8 @@ msgid ""
"The [StyleBox] to display as a background when the [CheckButton] is hovered "
"and pressed."
msgstr ""
+"La [StyleBox] à afficher en fond lorsque le [CheckButton] est survolé et "
+"appuyé."
#: doc/classes/CheckButton.xml
msgid ""
@@ -17176,6 +17912,9 @@ msgid ""
"small characters and its collision detection with everything else is very "
"fast."
msgstr ""
+"Forme circulaire pour les collisions 2D. Cette forme est utile pour "
+"modéliser les boules ou les petits caractères et sa détection des collisions "
+"avec les autres éléments est très rapide."
#: doc/classes/CircleShape2D.xml
msgid "The circle's radius."
@@ -17195,6 +17934,8 @@ msgid ""
"Returns [code]true[/code] if you can instance objects from the specified "
"[code]class[/code], [code]false[/code] in other case."
msgstr ""
+"Retourne [code]true[/code] si vous pouvez instancer des objets à partir de "
+"[code]class[/code], [code]false[/code] dans un autre cas."
#: doc/classes/ClassDB.xml
msgid "Returns whether the specified [code]class[/code] is available or not."
@@ -17205,12 +17946,17 @@ msgid ""
"Returns a category associated with the class for use in documentation and "
"the Asset Library. Debug mode required."
msgstr ""
+"Retourne une catégorie associée à la classe à utiliser dans la documentation "
+"et la bibliothèque de ressources. Le mode débogage est nécessaire pour "
+"récupérer cette information."
#: doc/classes/ClassDB.xml
msgid ""
"Returns an array with all the keys in [code]enum[/code] of [code]class[/"
"code] or its ancestry."
msgstr ""
+"Retourne un tableau avec toutes les clés dans l'énumeration [code]enum[/"
+"code] de la [code]class[/code] ou de ses parents."
#: doc/classes/ClassDB.xml
#, fuzzy
@@ -17223,18 +17969,25 @@ msgid ""
"Returns the value of the integer constant [code]name[/code] of [code]class[/"
"code] or its ancestry. Always returns 0 when the constant could not be found."
msgstr ""
+"Retourne la valeur de la constante entière nommée [code]name[/code] dans "
+"[code]class[/code] ou un de ses parents. Retourne toujours 0 si la constante "
+"n'a pas été trouvée."
#: doc/classes/ClassDB.xml
msgid ""
"Returns which enum the integer constant [code]name[/code] of [code]class[/"
"code] or its ancestry belongs to."
msgstr ""
+"Retourne à quelle énumération la constante entière nommée [code]name[/code] "
+"dans [code]class[/code] ou un de ses parents."
#: doc/classes/ClassDB.xml
msgid ""
"Returns an array with the names all the integer constants of [code]class[/"
"code] or its ancestry."
msgstr ""
+"Retourne un tableau avec le nom de toutes les constantes entières de "
+"[code]class[/code] ou de son parent."
#: doc/classes/ClassDB.xml
msgid ""
@@ -17247,6 +18000,15 @@ msgid ""
"[b]Note:[/b] In exported release builds the debug info is not available, so "
"the returned dictionaries will contain only method names."
msgstr ""
+"Retourne un tableau avec toutes les méthodes de [code]class[/code] ou son "
+"parent si [code]no_inheritance[/code] est [code]false[/code]. Chaque élément "
+"du tableau est un [Dictionary] avec les clés suivantes : [code]args[/code], "
+"[code]default_args[/code], [code]flags[/code], [code]id[/code], [code]name[/"
+"code] et [code]return: (class_name, hint, hint_string, name, type, usage)[/"
+"code].\n"
+"[b]Note :[/b] Dans la version exportée, les informations de débogage ne sont "
+"pas disponibles, les dictionnaires retournés ne contiendront donc que le nom "
+"des méthodes."
#: doc/classes/ClassDB.xml
msgid ""
@@ -17261,6 +18023,8 @@ msgid ""
"Returns an array with all the properties of [code]class[/code] or its "
"ancestry if [code]no_inheritance[/code] is [code]false[/code]."
msgstr ""
+"Retourne un tableau avec toutes les propriétés de [code]class[/code] ou de "
+"son parent si [code]no_inheritance[/code] est [code]false[/code]."
#: doc/classes/ClassDB.xml
msgid ""
@@ -17270,6 +18034,11 @@ msgid ""
"[code]name[/code], [code]return: (class_name, hint, hint_string, name, type, "
"usage)[/code]."
msgstr ""
+"Retourne les données [code]signal[/code] de [code]class[/code] ou de son "
+"parent. La valeur retournée est un [Dictionary] avec les clés suivantes : "
+"[code]args[/code], [code]default_args[/code], [code]flags[/code], [code]id[/"
+"code], [code]name[/code] et [code]return: (class_name, hint, hint_string, "
+"name, type, usage)[/code]."
#: doc/classes/ClassDB.xml
msgid ""
@@ -17277,6 +18046,9 @@ msgid ""
"if [code]no_inheritance[/code] is [code]false[/code]. Every element of the "
"array is a [Dictionary] as described in [method class_get_signal]."
msgstr ""
+"Retourne un tableau avec tous les signaux de [code]class[/code] ou son "
+"parent si [code]no_inheritance[/code] est [code]false[/code]. Chaque élément "
+"du tableau est un [Dictionary] comme détaillé dans [method class_get_signal]."
#: doc/classes/ClassDB.xml
msgid ""
@@ -17291,12 +18063,17 @@ msgid ""
"Returns whether [code]class[/code] or its ancestry has an integer constant "
"called [code]name[/code] or not."
msgstr ""
+"Retourne si [code]class[/code] ou son parent a une constante entière appelée "
+"[code]name[/code] ou non."
#: doc/classes/ClassDB.xml
msgid ""
"Returns whether [code]class[/code] (or its ancestry if [code]no_inheritance[/"
"code] is [code]false[/code]) has a method called [code]method[/code] or not."
msgstr ""
+"Retourne si [code]class[/code] (ou un de ses parents si "
+"[code]no_inheritance[/code] est [code]false[/code]) a une méthode nommée "
+"[code]method[/code] ou non."
#: doc/classes/ClassDB.xml
msgid ""
@@ -17322,6 +18099,8 @@ msgid ""
"Returns the names of all the classes that directly or indirectly inherit "
"from [code]class[/code]."
msgstr ""
+"Retourne le nom de toutes les classes qui héritent directement ou "
+"indirectement de [code]class[/code]."
#: doc/classes/ClassDB.xml
msgid "Returns the parent class of [code]class[/code]."
@@ -17352,6 +18131,9 @@ msgid ""
"This node extends [Camera] to add collisions with [Area] and/or "
"[PhysicsBody] nodes. The camera cannot move through colliding objects."
msgstr ""
+"Ce nœud étend [Camera] pour ajouter des collisions avec des nœuds [Area] et/"
+"ou [PhysicsBody]. La caméra ne peut pas passer à travers les objets avec "
+"lesquels elle rentre en collision."
#: doc/classes/ClippedCamera.xml
msgid ""
@@ -17383,6 +18165,8 @@ msgid ""
"Returns [code]true[/code] if the specified bit index is on.\n"
"[b]Note:[/b] Bit indices range from 0-19."
msgstr ""
+"Retourne [code]true[/code] si l'index de bit spécifié est actif.\n"
+"[b]Note :[/b] Les indices de bit vont de 0 à 19."
#: doc/classes/ClippedCamera.xml
msgid "Removes a collision exception with the specified node."
@@ -17397,6 +18181,8 @@ msgid ""
"Sets the specified bit index to the [code]value[/code].\n"
"[b]Note:[/b] Bit indices range from 0-19."
msgstr ""
+"Définit l'index de bit spécifié à [code]valeur[/code].\n"
+"[b]Note :[/b] Les indices des bit vont de 0 à 19."
#: doc/classes/ClippedCamera.xml
msgid "If [code]true[/code], the camera stops on contact with [Area]s."
@@ -17416,12 +18202,19 @@ msgid ""
"physics_introduction.html#collision-layers-and-masks]Collision layers and "
"masks[/url] in the documentation for more information."
msgstr ""
+"Le masque de collision de la caméra. Seuls les objets dans au moins une "
+"calque de collision correspondant au masque seront détectés. Voir "
+"[url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-"
+"and-masks]Calques et masques de collision[/url] dans la documentation pour "
+"plus d'informations."
#: doc/classes/ClippedCamera.xml
msgid ""
"The camera's collision margin. The camera can't get closer than this "
"distance to a colliding object."
msgstr ""
+"La marge de collision de la caméra. La caméra ne peut pas se rapprocher plus "
+"d'un objet de collision que cette distance."
#: doc/classes/ClippedCamera.xml
msgid "The camera's process callback. See [enum ProcessMode]."
@@ -17439,6 +18232,13 @@ msgid ""
"owners are not nodes and do not appear in the editor, but are accessible "
"through code using the [code]shape_owner_*[/code] methods."
msgstr ""
+"CollisionObject est la classe de base pour les objets physiques. Il peut "
+"contenir n'importe quel nombre de formes [Shape] de collision. Chaque forme "
+"doit être assignée à un [i]propriétaire de forme[ /i]. Le CollisionObject "
+"peut avoir n'importe quel nombre de propriétaires de forme. Les "
+"propriétaires de forme ne sont pas des nœuds et ne apparaissent pas dans "
+"l'éditeur, mais sont accessibles par le code en utilisant les méthodes "
+"[code]shape_owner_*[/code]."
#: doc/classes/CollisionObject.xml
msgid ""
@@ -17448,12 +18248,19 @@ msgid ""
"surface at that point. Connect to the [signal input_event] signal to easily "
"pick up these events."
msgstr ""
+"Reçoie les [InputEvent] non traités. [code]position[/code] est la position "
+"dans l'espace global du curseur de la souris sur la surface de la forme avec "
+"index [code]shape_idx[/code] et [code]normal[/code] est le vecteur de "
+"normale de la surface à ce point. Connectez-vous au signal [signal "
+"input_event] pour récupérer facilement ces événements."
#: doc/classes/CollisionObject.xml doc/classes/CollisionObject2D.xml
msgid ""
"Creates a new shape owner for the given object. Returns [code]owner_id[/"
"code] of the new owner for future reference."
msgstr ""
+"Crée un nouveau propriétaire de forme pour l'objet donné. Retourne "
+"[code]owner_id[/code] du nouveau propriétaire pour une prochaine référence."
#: doc/classes/CollisionObject.xml doc/classes/CollisionObject2D.xml
msgid ""
@@ -17619,6 +18426,10 @@ msgid ""
"the mouse pointer entering/leaving, and if the mouse is inside it, report "
"input events. Requires at least one [member collision_layer] bit to be set."
msgstr ""
+"Si [code]true[/code], cet objet peut être sélectionné. Ces objets peuvent "
+"détecter l'entrée/la sortie du pointeur de la souris sur eux, et si la "
+"souris pointe sur l'objet, signaler par des événements d'entrée. Nécessite "
+"au moins un bit de [member collision_layer] d'être réglé."
#: doc/classes/CollisionObject.xml
msgid ""
@@ -17662,7 +18473,7 @@ msgstr ""
"CollisionObject2D peut avoir autant de propriétaires de forme qui "
"nécessaire. Les propriétaires de forme ne sont pas des nœuds et ne "
"apparaissent pas dans l'éditeur, mais sont accessibles par le code en "
-"utilisant les méthodes [code]shape_owner[* /code].\n"
+"utilisant les méthodes [code]shape_owner_*[/code].\n"
"[b]Note :[/b] Seules les collisions entre des objets dans le même canevas "
"(dans une même [Viewport] ou [CanvasLayer]) sont supportées. Le comportement "
"des collisions entre des objets dans différents canevas est indéfini."
@@ -17674,6 +18485,10 @@ msgid ""
"[Shape2D]. Connect to the [code]input_event[/code] signal to easily pick up "
"these events."
msgstr ""
+"Accepte les [InputEvent] non traités. Nécessite [member input_pickable] "
+"d'être à [code]true[/code]. [code]shape_idx[/code] est l'index de la "
+"[Shape2D] enfant. Connectez-vous au signal [code]input_event[/code] pour "
+"récupérer facilement ces événements."
#: doc/classes/CollisionObject2D.xml
msgid ""
@@ -17689,6 +18504,9 @@ msgid ""
"this [CollisionObject2D] will not be reported to collided with "
"[CollisionObject2D]s."
msgstr ""
+"Retourne [code]true[/code] si les collisions pour le propriétaire de forme "
+"venant de ce [CollisionObject2D] ne seront pas signalées aux "
+"[CollisionObject2D] entrants en collision."
#: doc/classes/CollisionObject2D.xml
msgid "Adds a [Shape2D] to the shape owner."
@@ -17697,12 +18515,16 @@ msgstr "Ajoute un [Shape2D] au propriétaire de la forme."
#: doc/classes/CollisionObject2D.xml
msgid "Returns the [Shape2D] with the given id from the given shape owner."
msgstr ""
+"Retourne la [Shape2D] avec l'identifiant donné du propriétaire donné de la "
+"forme."
#: doc/classes/CollisionObject2D.xml
msgid ""
"Returns the child index of the [Shape2D] with the given id from the given "
"shape owner."
msgstr ""
+"Retourne l'indice de enfant du [Shape2D] avec l'identifiant donné du "
+"propriétaire donné de forme."
#: doc/classes/CollisionObject2D.xml
msgid "Returns the shape owner's [Transform2D]."
@@ -17714,12 +18536,17 @@ msgid ""
"originating from this [CollisionObject2D] will not be reported to collided "
"with [CollisionObject2D]s."
msgstr ""
+"Si [code]enable[/code] est [code]true[/code], les collisions pour le "
+"propriétaire de forme original de ce [CollisionObject2D] ne seront pas "
+"rapportées aux [CollisionObject2D] entrant en collision."
#: doc/classes/CollisionObject2D.xml
msgid ""
"Sets the [code]one_way_collision_margin[/code] of the shape owner identified "
"by given [code]owner_id[/code] to [code]margin[/code] pixels."
msgstr ""
+"Définit la marge [code]one_way_collision_margin[/code] du propriétaire de la "
+"forme identifié par [code]owner_id[/code] à [code]margin[/code] pixels."
#: doc/classes/CollisionObject2D.xml
msgid "Sets the [Transform2D] of the given shape owner."
@@ -17735,6 +18562,14 @@ msgid ""
"and-masks]Collision layers and masks[/url] in the documentation for more "
"information."
msgstr ""
+"Le calque physique où est ce CollisionObject2D. Les objets de collision "
+"peuvent exister dans un ou plusieurs des 32 calques différents. Voir aussi "
+"[member collision_mask].\n"
+"[b]Note :[/b] Un contact est détecté si l'objet A est dans l'un des calques "
+"que l'objet B scanne, ou si l'objet B est dans tous les calques que l'objet "
+"A scanne. Voir [url=$DOCS_URL/tutorials/physics/physics_introduction."
+"html#collision-layers-and-masks]Calques et masques de Collision[/url] dans "
+"la documentation pour plus d'informations."
#: doc/classes/CollisionObject2D.xml
msgid ""
@@ -17746,6 +18581,14 @@ msgid ""
"and-masks]Collision layers and masks[/url] in the documentation for more "
"information."
msgstr ""
+"Le calque physique que ce CollisionObject2D scanne. Les objets de collision "
+"peuvent exister dans un ou plusieurs des 32 calques différents. Voir aussi "
+"[member collision_mask].\n"
+"[b]Note :[/b] Un contact est détecté si l'objet A est dans l'une des calques "
+"que l'objet B scanne, ou l'objet B est dans toutes les calques que l'objet A "
+"scanne. Voir [url=$DOCS_URL/tutorials/physics/physics_introduction."
+"html#collision-layers-and-masks]Collision calques et masques[/url] dans la "
+"documentation pour plus d'informations."
#: doc/classes/CollisionObject2D.xml
msgid ""
@@ -17753,6 +18596,10 @@ msgid ""
"[code]true[/code] and at least one [code]collision_layer[/code] bit to be "
"set. See [method _input_event] for details."
msgstr ""
+"Émis lorsqu'un événement d'entrée se produit. Nécessite [member "
+"input_pickable] d'être à [code]true[/code] et au moins un des bits de "
+"[code]collision_layer[/code] d'être définit. Voir [method input_event] pour "
+"plus de détails."
#: doc/classes/CollisionObject2D.xml
msgid ""
@@ -17760,6 +18607,9 @@ msgid ""
"[member input_pickable] to be [code]true[/code] and at least one "
"[code]collision_layer[/code] bit to be set."
msgstr ""
+"Émis lorsque le curseur de la souris entre dans l'une de ces formes. "
+"Nécessite [member input_pickable] d'être à [code]true[/code] et au moins un "
+"des bits de [code]collision_layer[/code] d'être définit."
#: doc/classes/CollisionObject2D.xml
msgid ""
@@ -17767,6 +18617,9 @@ msgid ""
"[member input_pickable] to be [code]true[/code] and at least one "
"[code]collision_layer[/code] bit to be set."
msgstr ""
+"Émis lorsque le curseur de la souris sort de toutes les formes. Nécessite "
+"[member input_pickable] d'être à [code]true[/code] et au moins un des bits "
+"de [code]collision_layer[/code] d'être définit."
#: doc/classes/CollisionPolygon.xml
msgid "Editor-only class for defining a collision polygon in 3D space."
@@ -17780,12 +18633,20 @@ msgid ""
"editor. It will not appear in the scene tree at run-time. Creates a [Shape] "
"for gameplay. Properties modified during gameplay will have no effect."
msgstr ""
+"Permet d'éditer des sommets de collision sur un plan sélectionné. Peut "
+"également définir une profondeur perpendiculaire à ce plan. Cette classe "
+"n'est disponible que dans l'éditeur. Elle n'apparaîtra pas dans "
+"l'arborescence de la scène quand le jeu est lancé. Crée une [Shape] pour les "
+"mécaniques de jeu. Les propriétés modifiées une fois le jeu lancé n'auront "
+"aucun effet."
#: doc/classes/CollisionPolygon.xml
msgid ""
"Length that the resulting collision extends in either direction "
"perpendicular to its polygon."
msgstr ""
+"La longueur que la collision résultante s'étend dans la direction "
+"perpendiculaire à son polygone."
#: doc/classes/CollisionPolygon.xml
msgid "If [code]true[/code], no collision will be produced."
@@ -17796,6 +18657,8 @@ msgid ""
"The collision margin for the generated [Shape]. See [member Shape.margin] "
"for more details."
msgstr ""
+"La marge de collision pour la [Shape] générée. Voir [member Shape.margin] "
+"pour plus d'informations."
#: doc/classes/CollisionPolygon.xml
msgid ""
@@ -17806,6 +18669,12 @@ msgid ""
"temporary variable and make changes before reassigning the [code]polygon[/"
"code] member."
msgstr ""
+"Un tableau de sommets qui définissent le polygone.\n"
+"[b]Note :[/b] La valeur retournée est une copie de l'original. Les méthodes "
+"qui modifie la taille ou les propriétés de la valeur de retour n'affecteront "
+"pas le polygone d'origine. Pour modifier les propriétés du polygone, "
+"assignez-le à une variable temporaire et faites des changements avant de le "
+"réassigner au membre [code]polygon[/code]."
#: doc/classes/CollisionPolygon2D.xml
msgid "Defines a 2D collision polygon."
@@ -17816,10 +18685,14 @@ msgid ""
"Provides a 2D collision polygon to a [CollisionObject2D] parent. Polygons "
"can be drawn in the editor or specified by a list of vertices."
msgstr ""
+"Fournit un polygone de collision 2D à un parent [CollisionObject2D]. Les "
+"polygones peuvent être dessinés manuellement dans l'éditeur ou spécifiés par "
+"une liste de sommets."
#: doc/classes/CollisionPolygon2D.xml
msgid "Collision build mode. Use one of the [enum BuildMode] constants."
msgstr ""
+"Le mode d'assemblage. Utilisez l'une des constantes de [enum BuildMode]."
#: doc/classes/CollisionPolygon2D.xml
msgid "If [code]true[/code], no collisions will be detected."
@@ -17832,6 +18705,11 @@ msgid ""
"[b]Note:[/b] This property has no effect if this [CollisionPolygon2D] is a "
"child of an [Area2D] node."
msgstr ""
+"Si [code]true[/code], seuls les bords qui font face, par rapport à la "
+"rotation du [CollisionPolygon2D], entreront en collision avec d'autres "
+"objets.\n"
+"[b]Note :[/b] Cette propriété n'a aucun effet si cette [CollisionPolygon2D] "
+"est un enfant d'un nœud [Area2D]."
#: doc/classes/CollisionPolygon2D.xml
msgid ""
@@ -17839,6 +18717,9 @@ msgid ""
"the shape thicker, and work better for colliders that enter the polygon at a "
"high velocity."
msgstr ""
+"La marge (en pixels) utilisée pour une collision à sens unique. Des valeurs "
+"plus élevées rendront la forme plus épaisse, et fonctionneront mieux pour "
+"les objets entrant en collision quand ils vont à une vitesse élevée."
#: doc/classes/CollisionPolygon2D.xml
msgid ""
@@ -17846,10 +18727,12 @@ msgid ""
"first. The returned value is a clone of the [PoolVector2Array], not a "
"reference."
msgstr ""
+"La liste des sommets du polygone. Le dernier point sera relié au premier. La "
+"valeur retournée est un copie du [PoolVector2Array], et non une référence."
#: doc/classes/CollisionPolygon2D.xml
msgid "Collisions will include the polygon and its contained area."
-msgstr ""
+msgstr "Les collisions comprendront ce polygone et sa zone englobante."
#: doc/classes/CollisionPolygon2D.xml
msgid "Collisions will only include the polygon edges."
@@ -17869,6 +18752,13 @@ msgid ""
"only helper to create shapes, use [method CollisionObject."
"shape_owner_get_shape] to get the actual shape."
msgstr ""
+"Un élément d'aide de l'éditeur pour créer et modifier des formes de "
+"collision dans l'espace 3D. Vous pouvez utiliser ce nœud pour représenter "
+"toutes sortes de formes de collision, par exemple, ajoutez-le à un [Area] "
+"pour lui donner une forme de détection, ou l'ajoutez-le à un [PhysicsBody] "
+"pour créer un objet solide. [b]IMPORTANT[/b] : c'est une aide de l'éditeur "
+"qui ne sert qu'à créer des formes, utiliser [method CollisionObject."
+"shape_owner_get_shape] pour obtenir la forme réelle."
#: doc/classes/CollisionShape.xml doc/classes/CollisionShape2D.xml
#: doc/classes/Physics2DDirectBodyState.xml
@@ -17905,6 +18795,7 @@ msgstr "La forme réelle appartenant à cette forme de collision."
#: doc/classes/CollisionShape2D.xml
msgid "Node that represents collision shape data in 2D space."
msgstr ""
+"Le nœud qui représente les données de forme de collision dans l'espace 2D."
#: doc/classes/CollisionShape2D.xml
msgid ""
@@ -17915,6 +18806,13 @@ msgid ""
"Editor-only helper to create shapes, use [method CollisionObject2D."
"shape_owner_get_shape] to get the actual shape."
msgstr ""
+"Un élément d'aide de l'éditeur pour créer et modifier des formes de "
+"collision dans l'espace 2D. Vous pouvez utiliser ce nœud pour représenter "
+"toutes sortes de formes de collision, par exemple, ajoutez-le à un [Area] "
+"pour lui donner une forme de détection, ou l'ajoutez-le à un [PhysicsBody] "
+"pour créer un objet solide. [b]IMPORTANT[/b] : c'est une aide de l'éditeur "
+"qui ne sert qu'à créer des formes, utiliser [method CollisionObject."
+"shape_owner_get_shape] pour obtenir la forme réelle."
#: doc/classes/CollisionShape2D.xml doc/classes/KinematicBody2D.xml
#: doc/classes/RectangleShape2D.xml doc/classes/TileMap.xml
@@ -18112,6 +19010,12 @@ msgid ""
"var darkgreen = green.darkened(0.2) # 20% darker than regular green\n"
"[/codeblock]"
msgstr ""
+"Retourne une nouvelle couleur à partir de cette couleur en plus foncée par "
+"le pourcentage donné (de 0 à 1).\n"
+"[codeblock]\n"
+"var green = Couleur(0.0, 1.0, 0.0) # Vert vif\n"
+"var darkgreen = vert.darkened(0.2) # 20% plus foncé que le vert vif\n"
+"/[codeblock]"
#: doc/classes/Color.xml
msgid ""
@@ -18135,6 +19039,11 @@ msgid ""
"This is useful when determining light or dark color. Colors with a luminance "
"smaller than 0.5 can be generally considered dark."
msgstr ""
+"Retourne la luminosité de la couleur dans l'intervalle [code][0.0, 1.0][/"
+"code].\n"
+"Ceci est utile pour déterminer si c'est une couleur claire ou foncée. Les "
+"couleurs avec une luminosité inférieure à 0,5 peuvent généralement être "
+"considérées comme sombres."
#: doc/classes/Color.xml
msgid ""
@@ -18295,14 +19204,14 @@ msgid ""
"[/codeblock]"
msgstr ""
"Retourne la chaîne de caractères avec le code hexadécimal façon HTML au "
-"format ARGB (par exemple [code]ff34f822[/code)].\n"
+"format ARGB (par exemple [code]ff34f822[/code]).\n"
"Définir [code]with_alpha[/code] à [code]false[/code] ne retourne pas la "
"valeur alpha dans le code hexadécimal retourné.\n"
"[codeblock]\n"
"var color = Color(1, 1, 1, 0.5)\n"
"var s1 = color.to_html() # Retourne \"7fffffff\"\n"
"var s2 = color.to_html(false) # Retourne \"ffffff\"\n"
-"/[codeblock]"
+"[/codeblock]"
#: doc/classes/Color.xml
msgid ""
@@ -18729,7 +19638,7 @@ msgstr "Couleur marron."
#: doc/classes/Color.xml
#, fuzzy
msgid "Medium aquamarine color."
-msgstr "Couleur bleu-marin moyenne."
+msgstr "Couleur bleu-marine moyenne."
#: doc/classes/Color.xml
msgid "Medium blue color."
@@ -18956,22 +19865,18 @@ msgid "Violet color."
msgstr "Couleur violette."
#: doc/classes/Color.xml
-#, fuzzy
msgid "Web gray color."
msgstr "Couleur gris Web."
#: doc/classes/Color.xml
-#, fuzzy
msgid "Web green color."
-msgstr "Couleur verte web."
+msgstr "Couleur vert Web."
#: doc/classes/Color.xml
-#, fuzzy
msgid "Web maroon color."
msgstr "Couleur marron Web."
#: doc/classes/Color.xml
-#, fuzzy
msgid "Web purple color."
msgstr "Couleur violet Web."
@@ -19007,6 +19912,11 @@ msgid ""
"[ColorPickerButton] instead if you need a button that brings up a "
"[ColorPicker] in a pop-up."
msgstr ""
+"Affiche un widget de sélection de couleurs. Utile pour sélectionner une "
+"couleur dans un espace de couleur RGB/RGBA.\n"
+"[b]Note :[/b] Ce contrôle est lui-même le widget de sélection de couleur. "
+"Vous pouvez utiliser un [ColorPickerButton] en remplacement si vous avez "
+"souhaitez un bouton qui affiche un [ColorPicker] dans une pop-up."
#: doc/classes/ColorPicker.xml
msgid ""
@@ -19014,11 +19924,18 @@ msgid ""
"in the color picker and the user will be able to select them.\n"
"[b]Note:[/b] The presets list is only for [i]this[/i] color picker."
msgstr ""
+"Ajoute la couleur donnée à une liste de pré-réglages de couleur. Les pré-"
+"réglages sont affichés dans le sélectionneur de couleurs que l'utilisateur "
+"pourra sélectionner.\n"
+"[b]Note :[/b] La liste des pré-réglages est seulement pour [i]ce[/i] "
+"sélectionneur de couleur."
#: doc/classes/ColorPicker.xml
msgid ""
"Removes the given color from the list of color presets of this color picker."
msgstr ""
+"Retire la couleur donnée de la liste des pré-réglages de couleur de ce "
+"sélectionneur de couleur."
#: doc/classes/ColorPicker.xml
msgid "Returns the list of colors in the presets of the color picker."
@@ -19035,6 +19952,10 @@ msgid ""
"mouse button, otherwise it will apply immediately even in mouse motion event "
"(which can cause performance issues)."
msgstr ""
+"Si [code]true[/code], la couleur ne s'appliquera que quand l'utilisateur "
+"relâche le bouton de la souris, sinon elle s'appliquera immédiatement en "
+"suivant le déplacement de la souris (ce qui peut causer des problèmes de "
+"performance)."
#: doc/classes/ColorPicker.xml
#, fuzzy
@@ -19047,6 +19968,9 @@ msgid ""
"sliders.\n"
"[b]Note:[/b] Cannot be enabled if raw mode is on."
msgstr ""
+"Si [code]true[/code], permet de modifier la couleur avec des curseurs teinte/"
+"saturation/valeur.\n"
+"[b]Note :[/b] Ne peut être activé si le mode brut est activé."
#: doc/classes/ColorPicker.xml
msgid "If [code]true[/code], the \"add preset\" button is enabled."
@@ -19114,10 +20038,12 @@ msgid ""
"The indicator used to signalize that the color value is outside the 0-1 "
"range."
msgstr ""
+"L'indicateur utilisé pour signaler que la valeur de couleur est en dehors de "
+"l'intervalle 0-1."
#: doc/classes/ColorPicker.xml
msgid "The icon for the screen color picker button."
-msgstr ""
+msgstr "L'icône pour le bouton de sélecteur de couleurs."
#: doc/classes/ColorPickerButton.xml
msgid "Button that pops out a [ColorPicker]."
@@ -19133,6 +20059,13 @@ msgid ""
"preview swatch to be visible. Make sure to set [member Control."
"rect_min_size] to a big enough value to give the button enough space."
msgstr ""
+"Encapsule un [ColorPicker] le rendant accessible en appuyant sur un bouton. "
+"En appuyant sur le bouton, le [ColorPicker] deviendra visible.\n"
+"Voir aussi [BaseButton] qui contient des propriétés et des méthodes communes "
+"associées à ce nœud.\n"
+"[b]Note :[/b] Par défaut, le bouton peut ne pas être assez large pour que "
+"les palettes de couleur soit visibles. Assurez-vous de configurer [member "
+"Control.rect_min_size] avec une taille suffisante grande pour le bouton."
#: doc/classes/ColorPickerButton.xml
msgid ""
@@ -19141,6 +20074,10 @@ msgid ""
"may cause a crash. If you wish to hide it or any of its children, use their "
"[member CanvasItem.visible] property."
msgstr ""
+"Retourne le [ColorPicker] que ce nœud bascule.\n"
+"[b]Avertissement :[/b] Il s'agit d'un nœud interne requis, le retirer et le "
+"supprimer peut causer un plantage. Si vous voulez le cacher ou l'un de ses "
+"enfants, utilisez la propriété [member CanvasItem.visible]."
#: doc/classes/ColorPickerButton.xml
msgid ""
@@ -19151,6 +20088,12 @@ msgid ""
"may cause a crash. If you wish to hide it or any of its children, use their "
"[member CanvasItem.visible] property."
msgstr ""
+"Retourne la commande suivante [PopupPanel] qui vous permet de vous connecter "
+"aux signaux de la fenêtre surgissante. Cela vous permet de gérer les "
+"événements lorsque le ColorPicker est affiché ou caché.\n"
+"[b]Avertissement :[/b] Il s'agit d'un nœud interne requis, le retirer et le "
+"supprimer peut causer un plantage. Si vous voulez le cacher ou l'un de ses "
+"enfants, utilisez la propriété [member CanvasItem.visible]."
#: doc/classes/ColorPickerButton.xml
msgid ""
@@ -19168,6 +20111,8 @@ msgid ""
"Emitted when the [ColorPicker] is created (the button is pressed for the "
"first time)."
msgstr ""
+"Émis lorsque le [ColorPicker] est créé (le bouton est pressé pour la "
+"première fois)."
#: doc/classes/ColorPickerButton.xml
msgid "Emitted when the [ColorPicker] is closed."
@@ -19188,6 +20133,9 @@ msgid ""
"normal text color of the button. Disabled, hovered, and pressed states take "
"precedence over this color."
msgstr ""
+"La [Color] du texte utilisée lorsque le [ColorPickerButton] a le focus. Il "
+"suffit de remplacer la couleur de texte normale du bouton. Les états "
+"désactivé, survolé et pressé sont prioritaires par rapport à cette couleur."
#: doc/classes/ColorPickerButton.xml
msgid "Text [Color] used when the [ColorPickerButton] is being hovered."
@@ -19220,6 +20168,9 @@ msgid ""
"over the current [StyleBox], so using [StyleBoxEmpty] will just disable the "
"focus visual effect."
msgstr ""
+"La [StyleBox] utilisée lorsque le [ColorPickerButton] a le focus. Il est "
+"affiché par dessus la [StyleBox] actuelle, donc utiliser [StyleBoxEmpty] ne "
+"fera que désactiver l'effet visuel de focus."
#: doc/classes/ColorPickerButton.xml
msgid "[StyleBox] used when the [ColorPickerButton] is being hovered."
@@ -19242,6 +20193,8 @@ msgid ""
"Displays a rectangle filled with a solid [member color]. If you need to "
"display the border alone, consider using [ReferenceRect] instead."
msgstr ""
+"Affiche un rectangle rempli de la couleur [member color]. Si vous devez "
+"seulement afficher la bordure, utilisez plutôt un [ReferenceRect]."
#: doc/classes/ColorRect.xml
msgid ""
@@ -19250,6 +20203,11 @@ msgid ""
"$ColorRect.color = Color(1, 0, 0, 1) # Set ColorRect's color to red.\n"
"[/codeblock]"
msgstr ""
+"La couleur de remplissage.\n"
+"[codeblock]\n"
+"$ColorRect.color = Color(1, 0, 0, 1) # Définit la couleur du ColorRect à "
+"rouge.\n"
+"[/codeblock]"
#: doc/classes/ConcavePolygonShape.xml
msgid "Concave polygon shape."
@@ -19263,6 +20221,13 @@ msgid ""
"work with static [PhysicsBody] nodes like [StaticBody] and will not work "
"with [KinematicBody] or [RigidBody] with a mode other than Static."
msgstr ""
+"Une ressource en forme de polygone concave, qui peut être utilisée dans un "
+"[PhysicsBody] ou une aire. Cette forme est créée à partir d'une liste de "
+"triangles.\n"
+"[b]Note :[/b] Lorsque qu'elle est utilisée pour les collisions, "
+"[ConcavePolygonShape] ne fonctionnera qu'avec les nœuds statiques "
+"[PhysicsBody] comme les [StaticBody] et non pas avec [KinematicBody] ou "
+"[RigidBody] quand ils ne sont pas en mode Static."
#: doc/classes/ConcavePolygonShape.xml
msgid "Returns the faces (an array of triangles)."
@@ -19289,6 +20254,18 @@ msgid ""
"uses a more complex method of collision detection, and a convex one forces "
"itself to be convex in order to speed up collision detection."
msgstr ""
+"Une ressource en forme de polygone concave pour la physique 2D. Elle est "
+"composée de segments et est optimal pour les collisions complexes de "
+"concaves polygonales. Cependant, il n'est pas conseillé de l'utiliser pour "
+"les nœuds [RigidBody2D]. Un CollisionPolygon2D décomposé en convexes "
+"(solides) ou plusieurs objets convexes sont conseillés dans ce cas. Sinon, "
+"une forme en polygone concave 2D est préférable pour les collisions "
+"statiques.\n"
+"La principale différence entre un [ConvexPolygonShape2D] et un "
+"[ConcavePolygonShape2D] est qu'un polygone concave suppose qu'il contient "
+"des zones creusées à l'intérieur et doit utiliser une méthode plus complexe "
+"pour détecter les collisions, alors qu'un polygone convexe n'admet aucune "
+"zone creusée pour pouvoir accélérer la détection des collisions."
#: doc/classes/ConcavePolygonShape2D.xml
msgid ""
@@ -19502,18 +20479,25 @@ msgid ""
"Deletes the specified section along with all the key-value pairs inside. "
"Raises an error if the section does not exist."
msgstr ""
+"Supprime la section spécifiée ainsi que toutes ses paires valeur-clé avec. "
+"Affiche une erreur si la section n'existe pas."
#: doc/classes/ConfigFile.xml
msgid ""
"Deletes the specified key in a section. Raises an error if either the "
"section or the key do not exist."
msgstr ""
+"Supprime la clé spécifiée dans une section. Affiche une erreur si la section "
+"ou la clé n'existe pas."
#: doc/classes/ConfigFile.xml
msgid ""
"Returns an array of all defined key identifiers in the specified section. "
"Raises an error and returns an empty array if the section does not exist."
msgstr ""
+"Retourne un tableau de tous les identifiants des clés définis dans la "
+"section spécifiée. Affiche une erreur et retourne un tableau vide si la "
+"section n'existe pas."
#: doc/classes/ConfigFile.xml
msgid "Returns an array of all defined section identifiers."
@@ -19526,6 +20510,10 @@ msgid ""
"[code]default[/code] value. If [code]default[/code] is not specified or set "
"to [code]null[/code], an error is also raised."
msgstr ""
+"Retourne l'actuelle valeur pour la section et la clé spécifiées. Si la "
+"section ou la clé n'existent pas, la méthode retourne la valeur du paramètre "
+"[code]default[/code]. Si [code]default[/code] n'est pas spécifié ou défini à "
+"[code]null[/code], une erreur est affichée."
#: doc/classes/ConfigFile.xml
msgid "Returns [code]true[/code] if the specified section exists."
@@ -19543,6 +20531,10 @@ msgid ""
"on.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
+"Charge le fichier de configuration spécifié en paramètre. Le contenu du "
+"fichier est interprété et chargé dans l'objet [ConfigFile] sur lequel la "
+"méthode a été appelée.\n"
+"Retourne un des codes [enum Error] ([code]OK[/code] en cas de succès)."
#: doc/classes/ConfigFile.xml
msgid ""
@@ -19551,6 +20543,11 @@ msgid ""
"the [ConfigFile] object which the method was called on.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
+"Charge le fichier de configuration crypté spécifié en paramètre, en "
+"utilisant la clé [code]key[/code] fournie pour le décrypter. Le contenu du "
+"fichier est interprété et chargé dans l'objet [ConfigFile] sur lequel la "
+"méthode a été appelée.\n"
+"Retourne un des codes [enum Error] ([code]OK[/code] en cas de succès)."
#: doc/classes/ConfigFile.xml
msgid ""
@@ -19559,6 +20556,11 @@ msgid ""
"loaded in the [ConfigFile] object which the method was called on.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
+"Charge le fichier de configuration crypté spécifié comme paramètre, en "
+"utilisant le mode de passe [code]password[/code] donné pour le décrypter. Le "
+"contenu du fichier est interprété puis chargé dans l'objet [ConfigFile] sur "
+"lequel la méthode a été appelée.\n"
+"Retourne un des codes [enum Error] ([code]OK[/code] si c'est un succès)."
#: doc/classes/ConfigFile.xml
msgid ""
@@ -19566,6 +20568,10 @@ msgid ""
"parsed and loaded in the ConfigFile object which the method was called on.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
+"Interprète la chaîne passée comme étant le contenu d'un fichier de "
+"configuration. La chaîne est interprétée puis chargée dans l'objet "
+"ConfigFile sur lequel la méthode a été appelée.\n"
+"Retourne un des codes [enum Error] ([code]OK[/code] si c'est un succès)."
#: doc/classes/ConfigFile.xml
msgid ""
@@ -19573,6 +20579,9 @@ msgid ""
"parameter. The output file uses an INI-style structure.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
+"Enregistre le contenu de l'objet [ConfigFile] au fichier spécifié en "
+"paramètre. Le fichier de sortie utilise une structure de type INI.\n"
+"Retourne un des codes [enum Error] ([code]OK[/code] si c'est un succès)."
#: doc/classes/ConfigFile.xml
msgid ""
@@ -19581,6 +20590,11 @@ msgid ""
"The output file uses an INI-style structure.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
+"Enregistre le contenu de l'objet [ConfigFile] crypté par le fichier AES-256 "
+"donné en paramètre, en utilisant le [code]key[/code] fourni pour le crypté. "
+"Le fichier de sortie utilise une structure de type INI.\n"
+"Retourne une des constantes de code [enum Error] ([code]OK[/code] sur le "
+"succès)."
#: doc/classes/ConfigFile.xml
msgid ""
@@ -19589,6 +20603,12 @@ msgid ""
"encrypt it. The output file uses an INI-style structure.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
+"Enregistre le contenu de l'objet [ConfigFile] crypté avec la clé AES-256 "
+"donnée en paramètre, en utilisant le mot de passe [code]password[/code] "
+"fourni pour le crypté. Le fichier de sortie utilise une structure de type "
+"INI.\n"
+"Retourne une des constantes de code [enum Error] ([code]OK[/code] sur le "
+"succès)."
#: doc/classes/ConfigFile.xml
msgid ""
@@ -19597,6 +20617,10 @@ msgid ""
"code] value deletes the specified key if it exists, and deletes the section "
"if it ends up empty once the key has been removed."
msgstr ""
+"Attribue une valeur à la clé spécifiée de la section spécifiée. Si la "
+"section ou la clé n'existe pas, elles sont créées. Passer une valeur "
+"[code]null[/code] supprime la clé spécifiée si elle existe, et supprime la "
+"section si elle est vide une fois que la clé a été supprimée."
#: doc/classes/ConfirmationDialog.xml
msgid "Dialog for confirmation of actions."
@@ -19612,6 +20636,13 @@ msgid ""
"get_cancel().connect(\"pressed\", self, \"cancelled\")\n"
"[/codeblock]."
msgstr ""
+"Le dialogue pour la confirmation des actions. Ce dialogue hérite de "
+"[AcceptDialog], mais a par défaut un bouton OK et Annuler (dans l'ordre "
+"définit par le système d'exploitation hôte).\n"
+"Pour annuler l'action, vous pouvez utiliser:\n"
+"[codeblock]\n"
+"get_cancel().connect(\"pressed\", self, \"cancelled\")\n"
+"[/codeblock]."
#: doc/classes/ConfirmationDialog.xml
msgid ""
@@ -19620,6 +20651,10 @@ msgid ""
"may cause a crash. If you wish to hide it or any of its children, use their "
"[member CanvasItem.visible] property."
msgstr ""
+"Retourne le bouton annuler.\n"
+"[b]Avertissement :[/b] Il s'agit d'un nœud interne requis, le retirer et le "
+"libérer peut causer un plantage. Si vous voulez le cacher lui ou un de ses "
+"enfants, utilisez la propriété [member CanvasItem.visible]."
#: doc/classes/Container.xml
msgid "Base node for containers."
@@ -19631,18 +20666,26 @@ msgid ""
"automatically arranges them in a certain way.\n"
"A Control can inherit this to create custom container classes."
msgstr ""
+"Le nœud de base pour les conteneurs. Un [Container] contient d'autres "
+"contrôles et les arrange automatiquement d'une certaine manière.\n"
+"Un Control peut en hériter pour créer des classes de conteneur qui arrange "
+"les contrôles enfants de manière personnalisée."
#: doc/classes/Container.xml
msgid ""
"Fit a child control in a given rect. This is mainly a helper for creating "
"custom container classes."
msgstr ""
+"Ajuste un contrôle enfant dans un rectangle donné. Il s'agit principalement "
+"d'une aide pour créer des classes de conteneurs personnalisées."
#: doc/classes/Container.xml
msgid ""
"Queue resort of the contained children. This is called automatically anyway, "
"but can be called upon request."
msgstr ""
+"Ajoute un commande de tri pour les contrôles enfants. Ceci est appelé "
+"automatiquement de tous les cas, mais peut être appelé sur demande."
#: doc/classes/Container.xml
msgid "Emitted when sorting the children is needed."
@@ -19652,12 +20695,17 @@ msgstr "Émis quand le tri des enfants est nécessaire."
msgid ""
"Notification for when sorting the children, it must be obeyed immediately."
msgstr ""
+"La notification pour le tri des enfants, à laquelle faut l'obéir "
+"immédiatement."
#: doc/classes/Control.xml
msgid ""
"All user interface nodes inherit from Control. A control's anchors and "
"margins adapt its position and size relative to its parent."
msgstr ""
+"Tous les nœuds d'interface utilisateur héritent de Control. Les ancres et "
+"les marges des contrôles adaptent leur position et leur taille par rapport à "
+"son parent."
#: doc/classes/Control.xml
msgid ""
@@ -19744,7 +20792,7 @@ msgstr "Galerie des nœuds de contrôle"
#: doc/classes/Control.xml
msgid "All GUI Demos"
-msgstr ""
+msgstr "Toutes les démos d'interface"
#: doc/classes/Control.xml
msgid ""
@@ -19754,6 +20802,13 @@ msgid ""
"Similar to [member rect_clip_content], but doesn't affect visibility.\n"
"If not overridden, defaults to [code]false[/code]."
msgstr ""
+"Méthode virtuelle à surcharger par l'utilisateur. Retourne si [méthode "
+"gui_input] ne doit pas être appelé pour les contrôles enfants en dehors du "
+"rectangle englobant du contrôle. L'entrée sera limitée au Rect de ce "
+"[Control]. Similaire à [member rect_clip_content], mais n'affecte pas la "
+"visibilité.\n"
+"Si la méthode n'est pas surchargée, la valeur par défaut retournée est "
+"[code]false[/code]."
#: doc/classes/Control.xml
msgid ""
@@ -20080,6 +21135,17 @@ msgid ""
" color = data[\"color\"]\n"
"[/codeblock]"
msgstr ""
+"Godot appelle cette méthode pour transmettre le résultat [code]data[/code] "
+"d'un paramètre. Godot appelle d'abord [method can_drop_data] pour tester si "
+"[code]data[/code] est autorisé à recevoir à [code]position[/code] où "
+"[code]position[/code] est local à ce contrôle.\n"
+"[codeblock]\n"
+"func can_drop_data(position, data):\n"
+" return typeof(data) == TYPE_DICTIONARY and data.has(\"color\")\n"
+"\n"
+"func drop_data(position, data):\n"
+" color = data[\"color\"]\n"
+"/[codeblock]"
#: doc/classes/Control.xml
msgid ""
@@ -20104,6 +21170,12 @@ msgid ""
"The methods [method can_drop_data] and [method drop_data] must be "
"implemented on controls that want to receive drop data."
msgstr ""
+"Force le glissage et contourne [method get_drag_data] et [method "
+"set_drag_preview] en passant [code]data[/code] et [code]preview[/code]. Le "
+"glissage va commencer même si la souris n'est ni sur, ni appuyé sur ce "
+"contrôle.\n"
+"Les méthodes [method can_drop_data] et [method drop_data] doivent être "
+"implémentées pour les contrôles qui veulent recevoir ces données de glissage."
#: doc/classes/Control.xml
msgid ""
@@ -20111,6 +21183,10 @@ msgid ""
"Margin] enum. A getter method for [member anchor_bottom], [member "
"anchor_left], [member anchor_right] and [member anchor_top]."
msgstr ""
+"Retourne l'ancre identifiée par la constante [code]margin[/code] de "
+"l'énumération [enum Margin]. Une méthode de getter pour [member "
+"anchor_bottom], [member anchor_left], [member anchor_right] et [member "
+"anchor_top]."
#: doc/classes/Control.xml
msgid ""
@@ -20143,6 +21219,29 @@ msgid ""
" modulate = get_color(\"font_color\", \"Button\")\n"
"[/codeblock]"
msgstr ""
+"Retourne un [Color] de la première correspondance dans le [Theme] de "
+"l'arborescence si ce [Theme] a un élément de couleur avec le nom [code]name[/"
+"code] et le type [code]theme_type[/code] spécifiés. Si [code]theme_type[/"
+"code] n'est pas précisé, le nom de classe du contrôle actuel sera utilisé "
+"pour le type, ou [member theme_type_variation] si elle est définie. Si le "
+"type est un nom de classe, ses classes parentes sont également testées, par "
+"ordre d'héritage.\n"
+"Pour le contrôle actuel, ses surcharges locales sont considérées en premier "
+"(voir [method add_color_override]), puis son nom [member theme]. Après le "
+"contrôle actuel, chaque contrôle parental et son [membre theme] assigné "
+"seront pris en considération ; les contrôles sans [member theme] attribué "
+"sont ignorés. Si aucune correspondance de [Theme] n'est trouvée dans "
+"l'arborescence, le [Theme] personnalisé du projet (voir [membre "
+"ProjectSettings.gui/theme/custom]) et le [Theme] par défaut seront "
+"utilisés.\n"
+"[codeblock]\n"
+"func _ready():\n"
+" # Obtenir la couleur de police définie pour la classe actuelle du "
+"Contrôle actuel, si elle existe.\n"
+" modulate = get_color(\"font_color\")\n"
+" # Obtenir la couleur de police définie pour la classe Button.\n"
+" modulate = get_color(\"font_color\", \"Button\")\n"
+"[/codeblock]"
#: doc/classes/Control.xml
msgid ""
@@ -20159,12 +21258,18 @@ msgid ""
"[code]theme_type[/code].\n"
"See [method get_color] for details."
msgstr ""
+"Retourne une constante du premier [Theme] correspondant dans l'arborescence "
+"si ce [Theme] a un élément constant avec le code nommé [code]name[/code] et "
+"le type [code]theme_type[/code].\n"
+"Voir [method get_color] pour plus de détails."
#: doc/classes/Control.xml
msgid ""
"Returns the mouse cursor shape the control displays on mouse hover. See "
"[enum CursorShape]."
msgstr ""
+"Retourne le curseur de la souris que le contrôle affiche quand la souris le "
+"survole. Voir [enum CursorShape]."
#: doc/classes/Control.xml
msgid ""
@@ -20210,6 +21315,10 @@ msgid ""
"[member focus_neighbour_left], [member focus_neighbour_right] and [member "
"focus_neighbour_top]."
msgstr ""
+"Retourne le voisin de focus identifié par la constante [code]margin[/code] "
+"de l'énumération [enum Margin]. Une méthode de getter pour [member "
+"focus_neighbour_bottom], [member focus_neighbour_left], [member "
+"focus_neighbour_right] et [member focus_neighbour_top]."
#: doc/classes/Control.xml
msgid ""
@@ -20224,12 +21333,18 @@ msgid ""
"code].\n"
"See [method get_color] for details."
msgstr ""
+"Retourne une [Font] du premier [Theme] correspondant dans l'arborescence si "
+"ce [Theme] a une propriété de police nommée [code]name[/code] et du type de "
+"thème [code]theme_type[/code].\n"
+"Voir [method get_color] pour plus de détails."
#: doc/classes/Control.xml
msgid ""
"Returns the position and size of the control relative to the top-left corner "
"of the screen. See [member rect_position] and [member rect_size]."
msgstr ""
+"Retourne la position et la taille du contrôle par rapport au coin supérieur "
+"gauche de l'écran. Voir [member rect_position] et [member rect_size]."
#: doc/classes/Control.xml
msgid ""
@@ -20238,6 +21353,10 @@ msgid ""
"code].\n"
"See [method get_color] for details."
msgstr ""
+"Retourne une icône du premier [Theme] correspondant dans l'arborescence si "
+"ce [Theme] a une propriété d'icône nommée [code]name[/code] et du type de "
+"thème [code]theme_type[/code].\n"
+"Voir [method get_color] pour plus de détails."
#: doc/classes/Control.xml
msgid ""
@@ -20245,6 +21364,10 @@ msgid ""
"Margin] enum. A getter method for [member margin_bottom], [member "
"margin_left], [member margin_right] and [member margin_top]."
msgstr ""
+"Retourne l'ancre identifiée par la constante [code]margin[/code] de "
+"l'énumeration [enum Margin]. Une méthode de getter pour [member "
+"margin_bottom], [member margin_left], [member margin_right] et [member "
+"margin_top]."
#: doc/classes/Control.xml
msgid "Returns the minimum size for this control. See [member rect_min_size]."
@@ -20265,6 +21388,8 @@ msgid ""
"Returns the position and size of the control relative to the top-left corner "
"of the parent Control. See [member rect_position] and [member rect_size]."
msgstr ""
+"Retourne la position et la taille du contrôle par rapport au coin supérieur "
+"gauche du contrôle parent. Voir [member rect_position] et [member rect_size]."
#: doc/classes/Control.xml
msgid "Returns the rotation (in radians)."
@@ -20277,6 +21402,10 @@ msgid ""
"[code]theme_type[/code].\n"
"See [method get_color] for details."
msgstr ""
+"Retourne une [StyleBox] du premier [Theme] correspondant dans l'arborescence "
+"si ce [Theme] a une propriété de boîte de style nommée [code]name[/code] et "
+"du type de thème [code]theme_type[/code].\n"
+"Voir [method get_color] pour plus de détails."
#: doc/classes/Control.xml
msgid ""
@@ -20284,6 +21413,10 @@ msgid ""
"[Theme] has a valid [member Theme.default_font] value.\n"
"See [method get_color] for details."
msgstr ""
+"Retourne la police par défaut de la première correspondance [Theme] trouvée "
+"dans l'arborescence si ce [Theme] a une valeur valide pour [member Theme."
+"default_font].\n"
+"Voir [method get_color] pour plus de détails."
#: doc/classes/Control.xml
msgid ""
@@ -20303,6 +21436,13 @@ msgid ""
"be clicked instead\n"
"[/codeblock]"
msgstr ""
+"Crée un [InputEventMouseButton] qui tente de cliquer sur le contrôle. Si "
+"l'événement est bien reçu, le contrôle prend le focus.\n"
+"[codeblock]\n"
+"func _process(delta:)\n"
+" grab_click_focus() # Lorsque vous cliquez sur un autre contrôle, ce nœud "
+"sera cliqué à la place\n"
+"/[codeblock]"
#: doc/classes/Control.xml
msgid ""
@@ -20319,6 +21459,10 @@ msgid ""
"code].\n"
"See [method get_color] for details."
msgstr ""
+"Retourne [code]true[/code] s'il y a un [Theme] correspondant dans "
+"l'arborescence qui a une propriété de couleur nommé [code]name[/code] et du "
+"type de thème [code]theme_type[/code].\n"
+"Voir [method get_color] pour plus de détails."
#: doc/classes/Control.xml
msgid ""
@@ -20337,6 +21481,10 @@ msgid ""
"[code]theme_type[/code].\n"
"See [method get_color] for details."
msgstr ""
+"Retourne [code]true[/code] s'il y a un [Theme] correspondant dans "
+"l'arborescence qui a une propriété de constante nommée [/code]name[/code] et "
+"du type de thème [code]theme_type[/code].\n"
+"Voir [method get_color] pour plus de détails."
#: doc/classes/Control.xml
msgid ""
@@ -20409,6 +21557,12 @@ msgid ""
"[b]Note:[/b] If you want to check if a point is inside the control, you can "
"use [code]get_rect().has_point(point)[/code]."
msgstr ""
+"Une méthode virtuelle à implémenter par l'utilisateur. Retourne si le "
+"[code]point[/code] donné est à l'intérieur de ce contrôle.\n"
+"Si ce n'est pas le cas, le comportement par défaut vérifie si le point se "
+"trouve dans le rectant englobant du contrôle.\n"
+"[b]Note :[/b] Si vous voulez vérifier si un point est à l'intérieur du "
+"contrôle, vous pouvez utiliser [code]get_rect().has_point(point[/code]."
#: doc/classes/Control.xml
msgid ""
@@ -20427,6 +21581,10 @@ msgid ""
"[code]theme_type[/code].\n"
"See [method get_color] for details."
msgstr ""
+"Retourne [code]true[/code] s'il y a une correspondance [Theme] dans "
+"l'arborescence qui a un élément de la boîte de style avec le code spécifié "
+"[code]name[/code] et [code]theme_type[/code].\n"
+"Voir [method get_color] pour plus de détails."
#: doc/classes/Control.xml
msgid ""
@@ -20455,11 +21613,17 @@ msgid ""
"changed. Setting [member rect_min_size] directly calls this method "
"automatically."
msgstr ""
+"Invalide le cache de taille de ce nœud et des nœuds parents jusqu'à la "
+"racine. Prévu pour être utilisé avec [method get_minimum_size] quand la "
+"valeur de retour est changée. Définir [member rect_min_size] appelle cette "
+"méthode automatiquement."
#: doc/classes/Control.xml
msgid ""
"Give up the focus. No other control will be able to receive keyboard input."
msgstr ""
+"Relâche le focus. Aucun autre contrôle ne pourra recevoir les entrées du "
+"clavier."
#: doc/classes/Control.xml
#, fuzzy
@@ -20520,7 +21684,7 @@ msgstr ""
"exemple, lorsque l'ancre gauche est fixée à 1 et que l'ancre droite a une "
"valeur de 0,5, l'ancre droite aura également une valeur de 1. Si "
"[code]push_opposite_anchor[/code] est [code]false[/code], l'ancre gauche a "
-"alors la valeur 0.5"
+"alors la valeur 0.5."
#: doc/classes/Control.xml
msgid ""
@@ -20528,12 +21692,18 @@ msgid ""
"code] argument and automatic update of margin, it allows to set the margin "
"offset yourself (see [method set_margin])."
msgstr ""
+"Fonctionne comme [method set_anchor], mais au lieu de l'argument "
+"[code]keep_margin[/code] et de la mise à jour automatique de la marge, ça "
+"permet de définir la marge de décalage par vous-même (voir [method "
+"set_margin])."
#: doc/classes/Control.xml
msgid ""
"Sets both anchor preset and margin preset. See [method set_anchors_preset] "
"and [method set_margins_preset]."
msgstr ""
+"Définit à la fois le préréglage de l'ancre et de la marge. Voir [method "
+"set_anchors_preset] et [method set_margins_preset]."
#: doc/classes/Control.xml
msgid ""
@@ -20543,6 +21713,11 @@ msgid ""
"If [code]keep_margins[/code] is [code]true[/code], control's position will "
"also be updated."
msgstr ""
+"Définit les ancres avec le préréglage [code]preset[/code] de l'énumeration "
+"[enum Control.LayoutPreset]. C'est le code équivalent à l'utilisation du "
+"menu \"Mise en page\" dans l'éditeur 2D.\n"
+"Si [code]keep_margins[/code] est [code]true[/code], la position du contrôle "
+"sera également mise à jour."
#: doc/classes/Control.xml
msgid ""
@@ -20680,6 +21855,10 @@ msgid ""
"margin_bottom], [member margin_left], [member margin_right] and [member "
"margin_top]."
msgstr ""
+"Régle la marge identifiée par la constante [code]margin[/code] de "
+"l'énumeration [enum Margin] à [code]offset[/code]. Une méthode de setter "
+"pour [member margin_bottom], [member margin_left], [member margin_right] et "
+"[member margin_top]."
#: doc/classes/Control.xml
msgid ""
@@ -20693,6 +21872,16 @@ msgid ""
"Use parameter [code]margin[/code] to determine the gap between the [Control] "
"and the edges."
msgstr ""
+"Définit les marges avec le préréglage [code]preset[/code] de l'énumeration "
+"[enum Control.LayoutPreset]. C'est le code équivalent à l'utilisation du "
+"menu Layout dans l'éditeur 2D.\n"
+"Utilisez le paramètre [code]resize_mode[/code] avec des constantes de [enum "
+"Control.LayoutPresetMode] pour mieux déterminer la taille résultante du "
+"[Control]. La taille constante sera ignorée si elle est utilisée avec des "
+"préréglages qui changent la taille, par exemple [code]PRESET_LEFT_WIDE[/"
+"code].\n"
+"Utiliser le paramètre [code]margin[/code] pour déterminer l'écart entre le "
+"[Contrôle] et les bords."
#: doc/classes/Control.xml
msgid ""
@@ -20700,6 +21889,9 @@ msgid ""
"If [code]keep_margins[/code] is [code]true[/code], control's anchors will be "
"updated instead of margins."
msgstr ""
+"Défini le [member rect_position] à la [code]position[/code] spécifiée.\n"
+"Si [code]keep_margins[/code] est [code]true[/code], les ancres du contrôle "
+"sont mis à jour au lieu des marges."
#: doc/classes/Control.xml
msgid "Sets the rotation (in radians)."
@@ -20711,6 +21903,9 @@ msgid ""
"If [code]keep_margins[/code] is [code]true[/code], control's anchors will be "
"updated instead of margins."
msgstr ""
+"Définit la taille (voir [member rect_size]).\n"
+"Si [code]keep_margins[/code] est [code]true[/code], les ancres du contrôle "
+"sont mis à jour au lieu des marges."
#: doc/classes/Control.xml
msgid ""
@@ -20722,6 +21917,15 @@ msgid ""
"If [code]exclusive[/code] is [code]true[/code], other controls will not "
"receive input and clicking outside this control will not close it."
msgstr ""
+"Affiche un contrôle en tant que modal. Le contrôle doit être une sous-"
+"fenêtre. Les contrôles de modal capturent les signaux d'entrée jusqu'à ce "
+"que la zone située à l'extérieur soit accessible. Lorsqu'un contrôle modal "
+"perd le focus, ou que la touche échap est pressée, il disparait "
+"automatiquement. Les contrôles de modal sont largement utilisés pour les "
+"dialogues surgissants (popup) et les menus.\n"
+"Si [code]exclusif[/code] est [code]true[/code], les autres contrôles ne "
+"recevront pas les entrées, et cliquer à l'extérieur de ce contrôle ne le "
+"fermera pas."
#: doc/classes/Control.xml
msgid ""
@@ -20738,6 +21942,10 @@ msgid ""
"moves or changes size. You can use one of the [enum Anchor] constants for "
"convenience."
msgstr ""
+"L'ancre du bord du bas du nœud par rapport à l'origine, le centre, ou la fin "
+"de son contrôle parent. Il modifie la mise à jour de la marge inférieure "
+"lorsque le nœud se déplace ou change la taille. Vous pouvez utiliser une des "
+"constantes de [enum Anchor] suivant les besoins."
#: doc/classes/Control.xml
msgid ""
@@ -20746,6 +21954,10 @@ msgid ""
"moves or changes size. You can use one of the [enum Anchor] constants for "
"convenience."
msgstr ""
+"L'ancre du bord gauche du nœud par rapport à l'origine, le centre ou la fin "
+"de son contrôle parent. Il modifie la mise à jour de la marge gauche lorsque "
+"le nœud se déplace ou change la taille. Vous pouvez utiliser une des "
+"constantes de [enum Anchor] suivant les besoins."
#: doc/classes/Control.xml
msgid ""
@@ -20754,6 +21966,10 @@ msgid ""
"moves or changes size. You can use one of the [enum Anchor] constants for "
"convenience."
msgstr ""
+"L'ancre du bord droit du nœud par rapport à l'origine, le centre ou la fin "
+"de son contrôle parent. Il modifie la mise à jour de la marge droite lorsque "
+"le nœud se déplace ou change la taille. Vous pouvez utiliser une des "
+"constantes de [enum Anchor] suivant les besoins."
#: doc/classes/Control.xml
msgid ""
@@ -20761,12 +21977,19 @@ msgid ""
"parent control. It changes how the top margin updates when the node moves or "
"changes size. You can use one of the [enum Anchor] constants for convenience."
msgstr ""
+"L'ancre du bord du haut du nœud par rapport à l'origine, le centre ou la fin "
+"de son contrôle parent. Il modifie la mise à jour de la marge supérieure "
+"lorsque le nœud se déplace ou change la taille. Vous pouvez utiliser une des "
+"constantes de [enum Anchor] suivant les besoins."
#: doc/classes/Control.xml
msgid ""
"The focus access mode for the control (None, Click or All). Only one Control "
"can be focused at the same time, and it will receive keyboard signals."
msgstr ""
+"Le mode de focus du contrôle (aucun, clic ou tous). Un seul contrôle peut "
+"avoir le focus à un moment donné, et il recevra des signaux des touches du "
+"clavier appuyées."
#: doc/classes/Control.xml
msgid ""
@@ -20776,6 +21999,12 @@ msgid ""
"must be a [Control]. If this property is not set, Godot will give focus to "
"the closest [Control] to the bottom of this one."
msgstr ""
+"Signale à Godot qu'il ne devrait pas donner le focus du clavier si "
+"l'utilisateur presse la flèche bas sur le clavier ou le gamepad par défaut. "
+"Vous pouvez modifier la clé en éditant l'action d'entrée [code]ui_down[/"
+"code]. Le nœud doit être un [Control]. Si cette propriété n'est pas définie, "
+"Godot placera le focus sur le [Control] le plus proche en-dessous de celui-"
+"ci."
#: doc/classes/Control.xml
msgid ""
@@ -20785,6 +22014,12 @@ msgid ""
"must be a [Control]. If this property is not set, Godot will give focus to "
"the closest [Control] to the left of this one."
msgstr ""
+"Signale à Godot qu'il ne doit pas donner le focus du clavier si "
+"l'utilisateur appuie sur la flèche gauche sur le clavier ou le gamepad par "
+"défaut. Vous pouvez modifier la clé en éditant l'action d'entrée "
+"[code]ui_left[/code]. Le nœud doit être un [Control]. Si cette propriété "
+"n'est pas définie, Godot placera le focus sur le [Control] le plus proche à "
+"gauche de celui-ci."
#: doc/classes/Control.xml
msgid ""
@@ -20794,6 +22029,12 @@ msgid ""
"must be a [Control]. If this property is not set, Godot will give focus to "
"the closest [Control] to the bottom of this one."
msgstr ""
+"Signale à Godot qu'il ne doit pas donner le focus du clavier si "
+"l'utilisateur presse la flèche droite sur le clavier ou le gamepad par "
+"défaut. Vous pouvez modifier la clé en éditant l'action d'entrée "
+"[code]ui_right[/code]. Le nœud doit être un [Control]. Si cette propriété "
+"n'est pas définie, Godot placera le focus sur le [Control] le plus proche en-"
+"dessous de celui-ci."
#: doc/classes/Control.xml
msgid ""
@@ -20803,6 +22044,12 @@ msgid ""
"[Control]. If this property is not set, Godot will give focus to the closest "
"[Control] to the bottom of this one."
msgstr ""
+"Signale à Godot qu'il ne devrait pas donner le focus du clavier si "
+"l'utilisateur appuie sur la flèche haut sur le clavier ou sur le gamepad par "
+"défaut. Vous pouvez modifier la clé en éditant l'action d'entrée "
+"[code]ui_top[/code]. Le nœud doit être un [Control]. Si cette propriété "
+"n'est pas définie, Godot placera le focus sur le [Control] le plus proche en-"
+"dessous de celui-ci."
#: doc/classes/Control.xml
msgid ""
@@ -20812,6 +22059,11 @@ msgid ""
"If this property is not set, Godot will select a \"best guess\" based on "
"surrounding nodes in the scene tree."
msgstr ""
+"Signale à Godot qu'il ne devrait pas donner le focus du clavier si "
+"l'utilisateur presse \"Tab\" sur un clavier par défaut. Vous pouvez modifier "
+"la clé en éditant l'action d'entrée [code]ui_focus_next[/code].\n"
+"Si cette propriété n'est pas définie, Godot choisira la « meilleure solution "
+"» basée sur les nœuds environnants dans l'arborescence."
#: doc/classes/Control.xml
msgid ""
@@ -20821,6 +22073,11 @@ msgid ""
"If this property is not set, Godot will select a \"best guess\" based on "
"surrounding nodes in the scene tree."
msgstr ""
+"Signale à Godot qu'il ne devrait pas donner le focus du clavier si "
+"l'utilisateur presse \"Shift+Tab\" sur un clavier par défaut. Vous pouvez "
+"modifier la clé en éditant l'action d'entrée [code]ui_focus_prev[/code].\n"
+"Si cette propriété n'est pas définie, Godot choisira la « meilleure solution "
+"» basée sur les nœuds environnants dans l'arborescence."
#: doc/classes/Control.xml
msgid ""
@@ -20828,6 +22085,10 @@ msgid ""
"grow if its horizontal minimum size is changed to be greater than its "
"current size, as the control always has to be at least the minimum size."
msgstr ""
+"Control la direction sur l'axe horizontal selon lequel le contrôle doit "
+"croître si sa taille minimale horizontale est modifiée pour être supérieure "
+"à sa taille actuelle, car le contrôle doit toujours avoir au moins sa taille "
+"minimale."
#: doc/classes/Control.xml
msgid ""
@@ -20835,6 +22096,10 @@ msgid ""
"if its vertical minimum size is changed to be greater than its current size, "
"as the control always has to be at least the minimum size."
msgstr ""
+"Control la direction sur l'axe vertical selon lequel le contrôle doit "
+"croître si sa taille minimale verticale est changée pour être supérieure à "
+"sa taille actuelle, car le contrôle doit toujours avoir au moins sa taille "
+"minimale."
#: doc/classes/Control.xml
msgid ""
@@ -20887,6 +22152,11 @@ msgid ""
"handling. The viewport first hides the modal and after marks the input as "
"handled."
msgstr ""
+"Active quand l'entrée doit se propager lorsque vous fermez le contrôle en "
+"tant que modale.\n"
+"Si [code]false[/code], arrête le traitement de l'événement lors de la "
+"manipulation de l'événement d'entrée de la fenêtre d'affichage. La fenêtre "
+"d'affichage cache d'abord la modale et après marque l'entrée comme traitée."
#: doc/classes/Control.xml
msgid ""
@@ -20955,6 +22225,11 @@ msgid ""
"[b]Note:[/b] On Linux, shapes may vary depending on the cursor theme of the "
"system."
msgstr ""
+"La forme par défaut du curseur pour ce contrôle. Utile pour les greffons de "
+"Godot et applications ou jeux qui utilisent les curseurs de souris du "
+"système.\n"
+"[b]Note :[/b] Sur Linux, les formes peuvent varier selon le thème du curseur "
+"du système."
#: doc/classes/Control.xml
msgid ""
@@ -20963,6 +22238,11 @@ msgid ""
"Also controls whether the control can receive the [signal mouse_entered], "
"and [signal mouse_exited] signals. See the constants to learn what each does."
msgstr ""
+"Contrôle si la commande sera en mesure de recevoir les événements d'entrée "
+"de la souris via [method gui_input] et comment ces événements seront "
+"traités. Contrôle également si le contrôle peut recevoir les signaux [signal "
+"mouse_entered] et [signal mouse_exited]. Voyez les constantes pour connaitre "
+"le rôle de chacun."
#: doc/classes/Control.xml
msgid ""
@@ -20970,12 +22250,18 @@ msgid ""
"to this control's rectangle. If [code]true[/code], parts of a child which "
"would be visibly outside of this control's rectangle will not be rendered."
msgstr ""
+"Active quand le rendu des [CanvasItem] enfants doit être limité au rectangle "
+"engobant de ce contrôle. Si [code]true[/code], des parties des enfants qui "
+"seraient normalement visibles en-dehors de ce rectangle des contrôles seront "
+"cachées."
#: doc/classes/Control.xml
msgid ""
"The node's global position, relative to the world (usually to the top-left "
"corner of the window)."
msgstr ""
+"La position globale du nœud, par rapport au coordonnées globales "
+"(généralement au coin haut-gauche de la fenêtre)."
#: doc/classes/Control.xml
msgid ""
@@ -20984,6 +22270,11 @@ msgid ""
"this size, even if its content is smaller. If it's set to (0, 0), the node "
"sizes automatically to fit its content, be it a texture or child nodes."
msgstr ""
+"La taille minimale du rectangle englobant. Si vous le fixez à une valeur "
+"supérieure à (0, 0), le rectangle englobant du nœud aura toujours au moins "
+"cette taille, même si son contenu est plus petit. Si cette taille est à (0, "
+"0), le nœud sera redimensionné automatiquement pour s'adapter à son contenu, "
+"qu'il s'agisse d'une texture ou d'un nœud enfant."
#: doc/classes/Control.xml
msgid ""
@@ -20992,6 +22283,10 @@ msgid ""
"around this pivot. Set this property to [member rect_size] / 2 to pivot "
"around the Control's center."
msgstr ""
+"Par défaut, et le pivot du nœud est son coin supérieur gauche. Lorsque vous "
+"modifiez son [member rect_rotation] ou [member rect_scale], il tournera ou "
+"changera d'échelle autour de ce pivot. Définir cette propriété à [member "
+"rect_size] / 2 permet de pivoter autour du centre du contrôle."
#: doc/classes/Control.xml
msgid ""
@@ -20999,12 +22294,17 @@ msgid ""
"rectangle's top-left corner. The property is not affected by [member "
"rect_pivot_offset]."
msgstr ""
+"La position du nœud, par rapport à son parent. Elle correspond au coin "
+"supérieur gauche du rectangle. La propriété n'est pas affectée par [member "
+"rect_pivot_offset]."
#: doc/classes/Control.xml
msgid ""
"The node's rotation around its pivot, in degrees. See [member "
"rect_pivot_offset] to change the pivot's position."
msgstr ""
+"La rotation du nœud autour de son pivot, en degrés. Voir [member "
+"rect_pivot_offset] pour modifier la position du pivot."
#: doc/classes/Control.xml
msgid ""
@@ -21023,12 +22323,29 @@ msgid ""
"[code]yield(get_tree(), \"idle_frame\")[/code] then set its [member "
"rect_scale] property."
msgstr ""
+"Le facteur de mise à l'échelle, relative à [member rect_size]. Changez cette "
+"propriété pour changer l'échelle du nœud centré sur [member "
+"rect_pivot_offset]. Le[member hint_tooltip] du Control sera également "
+"réduite en fonction de cette valeur.\n"
+"[b]Note :[/b] Cette propriété est principalement destinée à être utilisée "
+"pour les animation. Le texte à l'intérieur du Control sera pixelisé ou flou "
+"lorsque la mise à l'échelle change. Pour supporter plusieurs résolutions "
+"dans votre projet, utilisez un mode d'étirement approprié suivant la "
+"[url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]documentation[/"
+"url] au lieu de changer chaque Control individuellement.\n"
+"[b]Note :[/b] Si le nœud de contrôle est un enfant d'un nœud [Container], "
+"l'échelle sera réinitialisée à [code]Vector2(1, 1)[/code] lorsque la scène "
+"est instanciée. Pour définir l'échelle du Control lors de son instanciation, "
+"attendez une trame avec [code]yield(get_tree,) \"idle_frame\")[/code] puis "
+"définissez son [member rect_scale]."
#: doc/classes/Control.xml
msgid ""
"The size of the node's bounding rectangle, in pixels. [Container] nodes "
"update this property automatically."
msgstr ""
+"La taille du rectangle englobant du nœud, en pixels. Les nœuds [Container] "
+"mettent à jour cette propriété automatiquement."
#: doc/classes/Control.xml
msgid ""
@@ -21036,6 +22353,9 @@ msgid ""
"on the X axis. Use one of the [enum SizeFlags] constants to change the "
"flags. See the constants to learn what each does."
msgstr ""
+"Signale au [Container] parent qu'il devrait redimensionner et placer le nœud "
+"sur l'axe X. Utilisez l'une des constantes [enum SizeFlags] pour changer les "
+"drapeaux. Voyez les constantes pour apprendre ce que chacun fait."
#: doc/classes/Control.xml
msgid ""
@@ -21045,6 +22365,11 @@ msgid ""
"its neighbour a ratio of 1, this node will take two thirds of the available "
"space."
msgstr ""
+"Si le nœud et au moins un de ses voisins utilisent le drapeau de taille "
+"[constant SIZE_EXPAND], le [Container] parent le laissera prendre plus ou "
+"moins d'espace selon cette propriété. Si ce nœud a un rapport d'étirement de "
+"2 et son voisin un rapport de 1, ce nœud prendra les deux tiers (deux fois "
+"plus que l'autre) de l'espace disponible."
#: doc/classes/Control.xml
msgid ""
@@ -21052,12 +22377,17 @@ msgid ""
"on the Y axis. Use one of the [enum SizeFlags] constants to change the "
"flags. See the constants to learn what each does."
msgstr ""
+"Signale au [Container] parent qu'il devrait redimensionner et placer le nœud "
+"sur l'axe Y. Utilisez l'une des constantes [enum SizeFlags] pour changer les "
+"drapeaux. Voyez les constantes pour apprendre ce que chacun fait."
#: doc/classes/Control.xml
msgid ""
"Changing this property replaces the current [Theme] resource this node and "
"all its [Control] children use."
msgstr ""
+"Changer cette propriété remplace la ressource [Theme] actuelle que ce nœud "
+"et tous ses [Contrôle] enfants utilisent."
#: doc/classes/Control.xml
msgid ""
@@ -21126,6 +22456,12 @@ msgid ""
"at least until the mouse is moved to reach the parent's [code]Rect[/code] "
"area."
msgstr ""
+"Émis lorsque la souris entre dans le [code]Rect[/code] du contrôle, à "
+"condition que l'événement l'atteigne.\n"
+"[b]Note :[/b] [signal mouse_entered] ne sera pas émis si la souris entre "
+"dans un nœud [Control] enfant avant d'entrer dans le [code]Rect[/code], au "
+"moins jusqu'à ce que la souris soit déplacée pour atteindre le [code]Rect[/"
+"code] du parent."
#: doc/classes/Control.xml
msgid ""
@@ -21143,6 +22479,19 @@ msgid ""
" # Not hovering over area.\n"
"[/codeblock]"
msgstr ""
+"Émis lorsque la souris quitte la zone [code]Rect[/code] de contrôle, à "
+"condition que l'événement l'atteigne.\n"
+"[b]Note :[/b] [signal mouse_exited] sera émis si la souris entre dans un "
+"nœud [Control] enfant, même si le curseur de la souris est encore à "
+"l'intérieur de la zone [code]Rect[/code] du parent.\n"
+"Si vous voulez vérifier si la souris a vraiment quitté la zone, en ignorant "
+"les nœuds parents, vous pouvez utiliser le code comme ceci :\n"
+"[codeblock]\n"
+"func on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Ne survole pas la zone.\n"
+"[/codeblock]"
#: doc/classes/Control.xml
msgid "Emitted when the control changes size."
@@ -21153,6 +22502,8 @@ msgid ""
"Emitted when one of the size flags changes. See [member "
"size_flags_horizontal] and [member size_flags_vertical]."
msgstr ""
+"Émis lorsque l'un des drapeaux de taille change. Voir [member "
+"size_flags_horizontal] et [member size_flags_vertical]."
#: doc/classes/Control.xml
msgid "The node cannot grab focus. Use with [member focus_mode]."
@@ -21171,11 +22522,16 @@ msgid ""
"The node can grab focus on mouse click or using the arrows and the Tab keys "
"on the keyboard. Use with [member focus_mode]."
msgstr ""
+"Le nœud peut obtenir le focus lors d'un clic de souris ou en utilisant les "
+"flèches et la touche de tabulation du clavier. À utiliser avec [member "
+"focus_mode]."
#: doc/classes/Control.xml
msgid ""
"Sent when the node changes size. Use [member rect_size] to get the new size."
msgstr ""
+"Envoyé quand le nœud change de taille. Utilisez [member rect_size] pour "
+"obtenir la nouvelle taille."
#: doc/classes/Control.xml
msgid "Sent when the mouse pointer enters the node."
@@ -21199,28 +22555,38 @@ msgid ""
"control. Happens when you call one of the [code]add_*_override[/code] "
"methods."
msgstr ""
+"Envoyé lorsque le [member theme] du nœud change, juste avant que Godot ne "
+"redessine le contrôle. Ça arrive quand vous appelez l'une des méthodes "
+"[code]add_*_override[/code]."
#: doc/classes/Control.xml
msgid "Sent when an open modal dialog closes. See [method show_modal]."
msgstr ""
+"Envoyé quand un dialogue modal ouvert se ferme. Voir [method show_modal]."
#: doc/classes/Control.xml
msgid ""
"Sent when this node is inside a [ScrollContainer] which has begun being "
"scrolled."
msgstr ""
+"Envoyé quand ce nœud est à l'intérieur d'un [ScrollContainer] qui a commencé "
+"à défilé."
#: doc/classes/Control.xml
msgid ""
"Sent when this node is inside a [ScrollContainer] which has stopped being "
"scrolled."
msgstr ""
+"Envoyé quand ce nœud est à l'intérieur d'un [ScrollContainer] qui a cessé de "
+"défilé."
#: doc/classes/Control.xml
msgid ""
"Show the system's arrow mouse cursor when the user hovers the node. Use with "
"[member mouse_default_cursor_shape]."
msgstr ""
+"Affiche le curseur système de la souris quand l'utilisateur survole le nœud. "
+"À utiliser avec [member mouse_default_cursor_shape]."
#: doc/classes/Control.xml
msgid ""
@@ -21228,6 +22594,9 @@ msgid ""
"beam pointer has a shape similar to \"I\". It tells the user they can "
"highlight or insert text."
msgstr ""
+"Affiche le curseur de la souris en forme de I lorsque l'utilisateur survole "
+"le nœud. Le pointeur en I a une forme semblable à un \"I\". Il signale à "
+"l'utilisateur qu'il peut insérer ou surligner du texte."
#: doc/classes/Control.xml
msgid ""
@@ -21261,6 +22630,10 @@ msgid ""
"when the user hovers the node. It tells the user they're currently dragging "
"an item, like a node in the Scene dock."
msgstr ""
+"Affiche le curseur de la souris de déposé-glissé, souvent un poing fermé ou "
+"un symbole de croix, lorsque l'utilisateur survole le nœud. Ça précise à "
+"l'utilisateur qu'il déplace actuellement un objet, comme un nœud dans le "
+"dock de Scene."
#: doc/classes/Control.xml
msgid ""
@@ -21268,12 +22641,18 @@ msgid ""
"an open hand. It tells the user they can drop an item they're currently "
"grabbing, like a node in the Scene dock."
msgstr ""
+"Affiche le curseur de la souris lorsque l'utilisateur survole le nœud. Ça "
+"peut être une main ouverte. Ça précise à l'utilisateur qu'il peut déposer un "
+"élément qu'il était en traint de déplacer, comme un nœud dans le dock de "
+"Scene."
#: doc/classes/Control.xml
msgid ""
"Show the system's forbidden mouse cursor when the user hovers the node. "
"Often a crossed circle."
msgstr ""
+"Affiche le curseur de souris d'interdition système lorsque l'utilisateur "
+"survole le nœud. C'est souvent un cercle barré."
#: doc/classes/Control.xml
msgid ""
@@ -21281,6 +22660,10 @@ msgid ""
"node. A double-headed vertical arrow. It tells the user they can resize the "
"window or the panel vertically."
msgstr ""
+"Afficher le curseur de souris de redimensionnement vertical lorsque "
+"l'utilisateur survole le nœud. Une flèche verticale à double tête. Ça "
+"précise à l'utilisateur qu'il peut redimensionner la fenêtre ou le panneau "
+"verticalement."
#: doc/classes/Control.xml
msgid ""
@@ -21288,6 +22671,10 @@ msgid ""
"node. A double-headed horizontal arrow. It tells the user they can resize "
"the window or the panel horizontally."
msgstr ""
+"Affiche le curseur de la souris de redimensionnement horizontal lorsque "
+"l'utilisateur survole le nœud. Une flèche horizontale à double tête. Ça "
+"précise à l'utilisateur qu'il peut redimensionner la fenêtre ou le panneau "
+"horizontalement."
#: doc/classes/Control.xml
msgid ""
@@ -21296,6 +22683,11 @@ msgid ""
"top right. It tells the user they can resize the window or the panel both "
"horizontally and vertically."
msgstr ""
+"Affiche le curseur de la souris de redimensionnement de la fenêtre lorsque "
+"l'utilisateur survole le nœud. Le curseur est une flèche à double tête qui "
+"va du bas à gauche au sommet à droite. Ça précise à l'utilisateur qu'il peut "
+"redimensionner la fenêtre ou le panneau à la fois horizontalement et "
+"verticalement."
#: doc/classes/Control.xml
msgid ""
@@ -21304,6 +22696,11 @@ msgid ""
"bottom right, the opposite of [constant CURSOR_BDIAGSIZE]. It tells the user "
"they can resize the window or the panel both horizontally and vertically."
msgstr ""
+"Affiche le curseur de la souris de redimensionnement de la fenêtre lorsque "
+"l'utilisateur survole le nœud. Le curseur est une flèche à double tête qui "
+"va du haut à gauche au bas à droite, le contraire de [constant "
+"CURSOR_BDIAGSIZE]. Ça précise à l'utilisateur qu'il peut redimensionner la "
+"fenêtre ou le panneau à la fois horizontalement et verticalement."
#: doc/classes/Control.xml
msgid ""
@@ -21311,78 +22708,107 @@ msgid ""
"2 double-headed arrows at a 90 degree angle. It tells the user they can move "
"a UI element freely."
msgstr ""
+"Affiche le curseur de la souris de déplacement lorsque l'utilisateur survole "
+"le nœud. Il montre 2 flèches doubles à un angle de 90 degrés. Ça précise à "
+"l'utilisateur qu'il peut déplacer un élément d'interface librement."
#: doc/classes/Control.xml
msgid ""
"Show the system's vertical split mouse cursor when the user hovers the node. "
"On Windows, it's the same as [constant CURSOR_VSIZE]."
msgstr ""
+"Affiche le curseur système de la souris avec un séparateur vertical lorsque "
+"l'utilisateur survole le nœud. Sur Windows, il est identique à [constant "
+"CURSOR_VSIZE]."
#: doc/classes/Control.xml
msgid ""
"Show the system's horizontal split mouse cursor when the user hovers the "
"node. On Windows, it's the same as [constant CURSOR_HSIZE]."
msgstr ""
+"Affiche le curseur système de la souris avec un séparateur horizontal "
+"lorsque l'utilisateur survole le nœud. Sur Windows, il est identique à "
+"[constant CURSOR_HSIZE]."
#: doc/classes/Control.xml
msgid ""
"Show the system's help mouse cursor when the user hovers the node, a "
"question mark."
msgstr ""
+"Affiche le curseur système de la souris pour l'aide lorsque l'utilisateur "
+"survole le nœud, avec un point d'interrogation."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to the top-left of the parent control's bounds. Use with "
"[method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres jusqu'au coin gauche supérieur du rectangle "
+"englobant du contrôle parent. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to the top-right of the parent control's bounds. Use with "
"[method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres jusqu'au coin droit du rectangle englobant du "
+"contrôle parent. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to the bottom-left of the parent control's bounds. Use "
"with [method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres jusqu'au coin bas-gauche du rectangle "
+"englobant du contrôle parent. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to the bottom-right of the parent control's bounds. Use "
"with [method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres jusqu'au coin bas-droit du rectangle englobant "
+"du contrôle parent. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to the center of the left edge of the parent control's "
"bounds. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres au centre du bord gauche du rectangle "
+"englobant du contrôle parent. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to the center of the top edge of the parent control's "
"bounds. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres au centre du bord supérieur du rectangle "
+"englobant du contrôle parent. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to the center of the right edge of the parent control's "
"bounds. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres au centre du bord droit du rectangle englobant "
+"du contrôle parent. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to the center of the bottom edge of the parent control's "
"bounds. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres au centre du bord du bas du rectangle "
+"englobant du contrôle parent. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to the center of the parent control's bounds. Use with "
"[method set_anchors_preset]."
msgstr ""
+"Magnétise les 4 ancres au centre du rectangle englobant de contrôle parent. "
+"À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
@@ -21390,6 +22816,10 @@ msgid ""
"becomes relative to the left edge and the top margin relative to the top "
"left corner of the node's parent. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise les 4 ancres sur le bord gauche du contrôle parent. La marge "
+"gauche devient alors relative au bord gauche et à la marge supérieure par "
+"rapport au coin supérieur gauche du nœud parent). À utiliser avec [méthod "
+"set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
@@ -21398,6 +22828,11 @@ msgid ""
"edge, and the right margin relative to the top right corner of the node's "
"parent. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres sur le bord supérieur du contrôle parent. La "
+"marge gauche devient alors par rapport au coin supérieur gauche, à la marge "
+"supérieure par rapport au bord supérieur, et à la marge droite par rapport "
+"au coin supérieur droit du nœud parent . À utiliser avec [méthod "
+"set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
@@ -21405,6 +22840,10 @@ msgid ""
"becomes relative to the right edge and the top margin relative to the top "
"right corner of the node's parent. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise les 4 ancres au bord droit du contrôle parent. La marge droite "
+"devient alors par rapport au bord droit et à la marge supérieure par rapport "
+"au coin supérieur droit du nœud parent. À utiliser avec [méthod "
+"set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
@@ -21413,18 +22852,26 @@ msgid ""
"the bottom edge, and the right margin relative to the bottom right corner of "
"the node's parent. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise les 4 ancres au bord inférieur du contrôle parent. La marge gauche "
+"devient alors par rapport au coin inférieur gauche, à la marge inférieure "
+"par rapport au bord inférieur, et à la marge droite par rapport au coin "
+"inférieur droit du nœud parent. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to a vertical line that cuts the parent control in half. "
"Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise les 4 ancres sur une ligne verticale qui coupe le contrôle parent "
+"en deux. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
"Snap all 4 anchors to a horizontal line that cuts the parent control in "
"half. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise les 4 ancres sur une ligne horizontale qui coupe le contrôle "
+"parent en deux. À utiliser avec [méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
@@ -21433,6 +22880,11 @@ msgid ""
"parent control. This is equivalent to the \"Full Rect\" layout option in the "
"editor. Use with [method set_anchors_preset]."
msgstr ""
+"Magnétise toutes les 4 ancres aux angles respectifs du contrôle parent. "
+"Réglez toutes les 4 marges à 0 après avoir appliqué ce préréglage et le "
+"[Control] s'adaptera à son contrôle parent. Ceci est équivalent à l'option "
+"de mise en page \"Rectangle complet\" dans l'éditeur. À utiliser avec "
+"[méthod set_anchors_preset]."
#: doc/classes/Control.xml
msgid "The control will be resized to its minimum size."
@@ -21456,6 +22908,9 @@ msgid ""
"the available space without pushing any other node. Use with [member "
"size_flags_horizontal] and [member size_flags_vertical]."
msgstr ""
+"Signale au [Container] parent d'étendre les limites de ce nœud pour remplir "
+"tout l'espace disponible sans pousser un autre nœud. À utiliser avec [member "
+"size_flags_horizontal] et [member size_flags_vertical]."
#: doc/classes/Control.xml
msgid ""
@@ -21465,12 +22920,19 @@ msgid ""
"size_flags_stretch_ratio]. Use with [member size_flags_horizontal] and "
"[member size_flags_vertical]."
msgstr ""
+"Signale au [Container] parent de laisser ce nœud prendre tout l'espace "
+"disponible sur l'axe spécifié. Si plusieurs nœuds voisins sont prêts à "
+"s'étendre, ils partagent l'espace en fonction de leur rapport d'étirement. "
+"Voir [member size_flags_stretch_ratio]. À utiliser avec [member "
+"size_flags_horizontal] et [member size_flags_vertical]."
#: doc/classes/Control.xml
msgid ""
"Sets the node's size flags to both fill and expand. See the 2 constants "
"above for more information."
msgstr ""
+"Définit les drapeaux de taille du nœud pour à la fois remplir et s'étendre. "
+"Voir les 2 constantes ci-dessus pour plus d'informations."
#: doc/classes/Control.xml
msgid ""
@@ -21576,6 +23038,10 @@ msgid ""
"variables, like [member anchor_left]. To change all 4 anchors at once, use "
"[method set_anchors_preset]."
msgstr ""
+"Magnétise l'un des 4 côtés d'ancrage à l'origine de l'ancrage [code]Rect[/"
+"code], en haut à gauche. Utilisez-le avec l'une des variables membres "
+"[code]anchor_[* /code], comme [member anchor_left]. Pour modifier les 4 "
+"ancres à la fois, utilisez [method set_anchors_preset]."
#: doc/classes/Control.xml
msgid ""
@@ -21584,6 +23050,10 @@ msgid ""
"member variables, like [member anchor_left]. To change all 4 anchors at "
"once, use [method set_anchors_preset]."
msgstr ""
+"Magnétise l'un des 4 côtés d'ancrage à l'extrémité de l'extrémité "
+"[code]Rect[/code], en bas à droite. Utilisez-le avec l'une des variables "
+"membres [code]anchor_[* /code], comme [member anchor_left]. Pour modifier "
+"les 4 ancres à la fois, utilisez [method set_anchors_preset]."
#: doc/classes/ConvexPolygonShape.xml
msgid "Convex polygon shape for 3D physics."
@@ -21614,6 +23084,15 @@ msgid ""
"uses a more complex method of collision detection, and a convex one forces "
"itself to be convex in order to speed up collision detection."
msgstr ""
+"Forme polygone convexe pour la physique 2D. Un polygone convexe, quelle que "
+"soit sa forme, est décomposé en interne par d'autant de polygones convexes "
+"que nécessaire pour assurer que toutes les collisions sont toujours "
+"effectués sur les polygones convexes (ce qui sont plus rapide à vérifier).\n"
+"La principale différence entre un [ConvexPolygonShape2D] et un "
+"[ConcavePolygonShape2D] est qu'un polygone concave suppose toujours qu'il "
+"est concave et utilise une méthode plus complexe pour la détection des "
+"collisions, alors qu'un polygone convexe suppose toujours qu'il est convexe "
+"pour accélérer la détection des collisions."
#: doc/classes/ConvexPolygonShape2D.xml
msgid ""
@@ -21621,6 +23100,10 @@ msgid ""
"points] property using the convex hull algorithm. Removing all unneeded "
"points. See [method Geometry.convex_hull_2d] for details."
msgstr ""
+"Basé sur l'ensemble des points fournis, cela crée et définit la propriété "
+"[member points] en utilisant l'algorithme de découpage convexe. Ça enlève "
+"aussi tous les points inutiles. Voir [method Geometry.convex_hull_2d] pour "
+"plus de détails."
#: doc/classes/ConvexPolygonShape2D.xml
msgid ""
@@ -21629,6 +23112,10 @@ msgid ""
"[method set_point_cloud] to generate a convex hull shape from concave shape "
"points."
msgstr ""
+"La liste des sommets du polygone. Peut être dans le sens horaire ou dans le "
+"sens anti-horaire. Ne définissez cette propriété qu'avec des points d'une "
+"forme convexe, et utilisez [method set_point_cloud] pour générer une forme "
+"convexe à partir de points d'une forme concave."
#: doc/classes/CPUParticles.xml
msgid "CPU-based 3D particle emitter."
@@ -21643,12 +23130,22 @@ msgid ""
"[b]Note:[/b] Unlike [Particles], the visibility rect is generated on-the-fly "
"and doesn't need to be configured by the user."
msgstr ""
+"Un nœud pour les particules 3D fonctionnant sur le CPU utilisé pour créer "
+"une grande variété d'effets de particules.\n"
+"Voir aussi [Particles], qui fournit la même fonctionnalité mais avec "
+"l'accélération matérielle (via GPU), mais ne peut pas fonctionner sur des "
+"appareils plus anciens.\n"
+"[b]Note :[/b] Contrairement aux [Particles], le rect de visibilité est "
+"généré à lors de émission et n'a pas besoin d'être configuré par "
+"l'utilisateur."
#: doc/classes/CPUParticles.xml
msgid ""
"Sets this node's properties to match a given [Particles] node with an "
"assigned [ParticlesMaterial]."
msgstr ""
+"Génère les propriétés de ce nœud pour correspondre à un nœud [Particules] "
+"avec en plus un nœud assigné [ParticlesMaterial]."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Returns the base value of the parameter specified by [enum Parameter]."
@@ -21706,6 +23203,11 @@ msgid ""
"therefore removing all particles that were already emitted before changing "
"[member amount]."
msgstr ""
+"Le nombre de particules émises dans un cycle d'émission (correspondant à la "
+"durée [member lifetime]).\n"
+"[b]Note :[/b] Changer [member amount] réinitialisera l'émission des "
+"particules, supprimant ainsi toutes les particules déjà émises avant de "
+"changer [member amount]."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Initial rotation applied to each particle, in degrees."
@@ -21777,6 +23279,9 @@ msgid ""
"[SpatialMaterial] make sure to set [member SpatialMaterial."
"vertex_color_use_as_albedo] to [code]true[/code]."
msgstr ""
+"La couleur initiale de chaque particule. Pour utiliser cette couleur dans un "
+"[SpatialMaterial], assurez-vous de définir [membrer SpatialMaterial."
+"vertex_color_use_as_albedo] à [code]true[/code]."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21784,6 +23289,8 @@ msgid ""
"Each particle's initial color will vary along this [GradientTexture] "
"(multiplied with [member color])."
msgstr ""
+"La couleur initiale de chaque particule qui varie suivant la "
+"[GradientTexture] (multipliée avec [member color])."
#: doc/classes/CPUParticles.xml doc/classes/ParticlesMaterial.xml
msgid ""
@@ -21804,7 +23311,6 @@ msgstr "L'amortissement varie le long de cette [Curve]."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
-#, fuzzy
msgid "Damping randomness ratio."
msgstr "Ratio d’amortissement aléatoire."
@@ -21833,6 +23339,8 @@ msgid ""
"Sets the [Color]s to modulate particles by when using [constant "
"EMISSION_SHAPE_POINTS] or [constant EMISSION_SHAPE_DIRECTED_POINTS]."
msgstr ""
+"Définit les [Color] pour moduler les particules en utilisant [constant "
+"EMISSION_SHAPE_POINTS] ou [constant EMISSION_SHAPE_DIRECTED_POINTS]."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
@@ -21847,6 +23355,9 @@ msgid ""
"Sets the initial positions to spawn particles when using [constant "
"EMISSION_SHAPE_POINTS] or [constant EMISSION_SHAPE_DIRECTED_POINTS]."
msgstr ""
+"Définit les positions initiales pour les particules créées en utilisant "
+"[constant EMISSION_SHAPE_POINTS] ou [constant "
+"EMISSION_SHAPE_DIRECTED_POINTS]."
#: doc/classes/CPUParticles.xml
msgid ""
@@ -21866,6 +23377,8 @@ msgid ""
"The inner radius for the ring shaped emitter when using [constant "
"EMISSION_SHAPE_RING]."
msgstr ""
+"Le rayon intérieur de l'émetteur en anneau quand définit à [constant "
+"EMISSION_SHAPE_RING]."
#: doc/classes/CPUParticles.xml
msgid ""
@@ -21911,6 +23424,10 @@ msgid ""
"the value to 2 will make the particles render at 2 frames per second. Note "
"this does not slow down the particle system itself."
msgstr ""
+"Le nombre de trames du système de particules est fixé à une valeur. Par "
+"exemple, changer la valeur à 2 rendra les particules à 2 trames par seconde. "
+"Notez que cela ne ralentit pas le système de particules lui-même juste "
+"l'affichage final."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21934,6 +23451,8 @@ msgid ""
"Amount of [member spread] in Y/Z plane. A value of [code]1[/code] restricts "
"particles to X/Z plane."
msgstr ""
+"La quantité d'éparpillement [member spread] dans le plan Y/Z. Une valeur de "
+"[code]1[/code] limite les particules au plan X/Z."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/Particles.xml doc/classes/Particles2D.xml
@@ -21941,6 +23460,8 @@ msgid ""
"If [code]true[/code], results in fractional delta calculation which has a "
"smoother particles display effect."
msgstr ""
+"Si [code]true[/code], utilise un calcul d'étape fractionnelle qui permet "
+"affichage plus lisse des particules."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21967,6 +23488,8 @@ msgid ""
"Initial velocity magnitude for each particle. Direction comes from [member "
"spread] and the node's orientation."
msgstr ""
+"La magnitude de la vitesse initiale de chaque particule. L'orientation "
+"dépend de [member spread] et de l'orientation du nœud."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21988,6 +23511,8 @@ msgstr "Facteur d'aléatoire de la durée de vie d'une particule."
msgid ""
"Linear acceleration applied to each particle in the direction of motion."
msgstr ""
+"L'accélération linéaire appliquée à chaque particule dans la direction du "
+"mouvement."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's linear acceleration will vary along this [Curve]."
@@ -22006,6 +23531,9 @@ msgid ""
"If [code]true[/code], particles use the parent node's coordinate space. If "
"[code]false[/code], they use global coordinates."
msgstr ""
+"Si [code]true[/code], les particules utilisent l'espace de coordonnées du "
+"parent du nœud. Si [code]false[/code], ils utilisent des coordonnées "
+"globales."
#: doc/classes/CPUParticles.xml
msgid ""
@@ -22021,6 +23549,9 @@ msgid ""
"If [code]true[/code], only one emission cycle occurs. If set [code]true[/"
"code] during a cycle, emission will stop at the cycle's end."
msgstr ""
+"Si [code]true[/code], un seul cycle d'émission se produit. Si définit à "
+"[code]true[/code] pendant un cycle, l'émission s'arrêtera à la fin de ce "
+"cycle."
#: doc/classes/CPUParticles.xml
msgid ""
@@ -22030,6 +23561,11 @@ msgid ""
"This property is only available when [member flag_disable_z] is [code]true[/"
"code]."
msgstr ""
+"La vitesse orbitale appliquée à chaque particule. Fait tourner les "
+"particules autour d'origine sur le plan XY local. Spécifié en nombre de "
+"rotations complètes autour de l'origine par seconde.\n"
+"Cette propriété est uniquement disponible lorsque [member flag_disable_z] "
+"est [code]true[/code]."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's orbital velocity will vary along this [Curve]."
@@ -22046,6 +23582,8 @@ msgstr "Facteur d'aléatoire de la vélocité orbitale."
#: doc/classes/Particles2D.xml
msgid "Particle system starts as if it had already run for this many seconds."
msgstr ""
+"Le système de particules démarre comme s'il avait déjà commencé depuis "
+"plusieurs secondes."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -22092,12 +23630,17 @@ msgid ""
"Particle system's running speed scaling ratio. A value of [code]0[/code] can "
"be used to pause the particles."
msgstr ""
+"Le facteur de vitesse du système de particules. Une valeur de [code]0[/code] "
+"peut être utilisée pour arrêter les particules."
#: doc/classes/CPUParticles.xml
msgid ""
"Each particle's initial direction range from [code]+spread[/code] to [code]-"
"spread[/code] degrees. Applied to X/Z plane and Y/Z planes."
msgstr ""
+"La direction initiale de chaque particule dans l'intervalle de "
+"[code]+spread[/code] à [code]-spread[/code] degrés. Appliquée aux plans sur "
+"X/Z et aux plans sur Y/Z."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -22106,6 +23649,9 @@ msgid ""
"perpendicular to the particle's velocity giving the particles a swirling "
"motion."
msgstr ""
+"L'accélération tangentielle appliquée à chaque particule. Elle est "
+"perpendiculaire à la vitesse de la particule, ce qui donne aux particules un "
+"mouvement de glissement."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's tangential acceleration will vary along this [Curve]."
@@ -22139,30 +23685,40 @@ msgid ""
"Use with [method set_param], [method set_param_randomness], and [method "
"set_param_curve] to set initial velocity properties."
msgstr ""
+"À utiliser avec [method set_param], [method set_param_randomness], et "
+"[method set_param_curve] pour définir les propriétés de vitesse initiale."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Use with [method set_param], [method set_param_randomness], and [method "
"set_param_curve] to set angular velocity properties."
msgstr ""
+"À utiliser avec [method set_param], [method set_param_randomness], et "
+"[method set_param_curve] pour définir les propriétés de vitesse angulaire."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Use with [method set_param], [method set_param_randomness], and [method "
"set_param_curve] to set orbital velocity properties."
msgstr ""
+"À utiliser avec [method set_param], [method set_param_randomness], et "
+"[method set_param_curve] pour définir les propriétés de vitesse orbitale."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Use with [method set_param], [method set_param_randomness], and [method "
"set_param_curve] to set linear acceleration properties."
msgstr ""
+"À utiliser avec [method set_param], [method set_param_randomness], et "
+"[method set_param_curve] pour définir les propriétés d'accélération linéaire."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Use with [method set_param], [method set_param_randomness], and [method "
"set_param_curve] to set radial acceleration properties."
msgstr ""
+"À utiliser avec [method set_param], [method set_param_randomness], et "
+"[method set_param_curve] pour définir les propriétés d'accélération radiale."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
@@ -22266,6 +23822,9 @@ msgid ""
"emission_points]. Particle color will be modulated by [member "
"emission_colors]."
msgstr ""
+"Les particules seront émises à une position choisie au hasard parmi les "
+"points [member emission_points]. La couleur des particules sera modulée par "
+"[member emission_colors]."
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
@@ -22274,6 +23833,10 @@ msgid ""
"[member emission_normals]. Particle color will be modulated by [member "
"emission_colors]."
msgstr ""
+"Les particules seront émises à une position choisie au hasard parmi [member "
+"emission_points]. La vitesse et la rotation des particules seront "
+"déterminées en fonction de [member emission_normals]. La couleur des "
+"particules sera modulée par [member emission_colors]."
#: doc/classes/CPUParticles.xml doc/classes/ParticlesMaterial.xml
msgid "Particles will be emitted in a ring or cylinder."
@@ -22297,36 +23860,53 @@ msgid ""
"[b]Note:[/b] Unlike [Particles2D], the visibility rect is generated on-the-"
"fly and doesn't need to be configured by the user."
msgstr ""
+"Nœud de particules 2D calculées par le CPU pour créer une variété de "
+"systèmes et d'effets de particules.\n"
+"Voir aussi [Particles2D], qui fournit la même fonctionnalité mais en "
+"utilisant l'accélération matérielle, mais ne peut pas fonctionner sur des "
+"appareils plus anciens.\n"
+"[b]Note :[/b] Contrairement [Particles2D], le rectangle de visibilité est "
+"généré à l'émission et n'a donc pas besoin d'être définit par l'utilisateur."
#: doc/classes/CPUParticles2D.xml
msgid ""
"Sets this node's properties to match a given [Particles2D] node with an "
"assigned [ParticlesMaterial]."
msgstr ""
+"Définit les propriétés de ce nœud pour correspondre à au nœud [Particles2D] "
+"spécifié, en incluant un nœud [ParticlesMaterial]."
#: doc/classes/CPUParticles2D.xml
msgid ""
"Each particle's initial color. If [member texture] is defined, it will be "
"multiplied by this color."
msgstr ""
+"La couleur initiale de chaque particule. Si [member texture] est défini, les "
+"particules sont multipliées par cette couleur."
#: doc/classes/CPUParticles2D.xml
msgid ""
"Each particle's color will vary along this [Gradient] (multiplied with "
"[member color])."
msgstr ""
+"Chaque couleur de particle varie selon ce [Gradient] (multiplié avec [member "
+"color])."
#: doc/classes/CPUParticles2D.xml
msgid ""
"The rectangle's extents if [member emission_shape] is set to [constant "
"EMISSION_SHAPE_RECTANGLE]."
msgstr ""
+"Le rectangle d'émission si [member emission_shape] est [constant "
+"EMISSION_SHAPE_RECTANGLE]."
#: doc/classes/CPUParticles2D.xml
msgid ""
"The sphere's radius if [member emission_shape] is set to [constant "
"EMISSION_SHAPE_SPHERE]."
msgstr ""
+"Le rayon de la sphère si [member emission_shape] est [constant "
+"EMISSION_SHAPE_SPHERE]."
#: doc/classes/CPUParticles2D.xml doc/classes/Particles.xml
#: doc/classes/Particles2D.xml
@@ -22335,6 +23915,10 @@ msgid ""
"the value to 2 will make the particles render at 2 frames per second. Note "
"this does not slow down the simulation of the particle system itself."
msgstr ""
+"Le nombre de trames du système de particules est fixé à une valeur. Par "
+"exemple, changer la valeur à 2 rendra les particules à 2 trames par seconde. "
+"Notez que cela ne ralentit pas le système de particules lui-même juste "
+"l'affichage final."
#: doc/classes/CPUParticles2D.xml doc/classes/Particles2D.xml
msgid ""
@@ -22344,12 +23928,21 @@ msgid ""
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
msgstr ""
+"La texture de normale à utiliser pour la propriété [member texture].\n"
+"[b]Note :[/b] Godot s'attend à ce que la texture de normale utilise les "
+"coordonnées +X, -Y, et +Z. Voir [url=http://wiki.polycount.com/wiki/"
+"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]cette page[/url] "
+"pour une comparaison des coordonnées des textures de normales attendues par "
+"les principaux moteurs de jeu."
#: doc/classes/CPUParticles2D.xml
msgid ""
"Orbital velocity applied to each particle. Makes the particles circle around "
"origin. Specified in number of full rotations around origin per second."
msgstr ""
+"La vitesse orbitale appliquée à chaque particule. Fait tourner les "
+"particules autour de l'origine. Spécifié en nombre de rotations complètes "
+"autour de l'origine par seconde."
#: doc/classes/CPUParticles2D.xml doc/classes/ParticlesMaterial.xml
msgid ""
@@ -22376,6 +23969,8 @@ msgid ""
"Particles will be emitted on the surface of a sphere flattened to two "
"dimensions."
msgstr ""
+"Les particules seront émises à la surface d'une sphère aplatie en deux "
+"dimensions."
#: doc/classes/CPUParticles2D.xml
msgid "Particles will be emitted in the area of a rectangle."
@@ -22472,6 +24067,11 @@ msgid ""
"string-comparison-with-double-hmac-strategy]this blog post[/url] for more "
"information."
msgstr ""
+"Compare deux [PoolByteArray] pour l'égalité sans fuite temporelle "
+"d'informations afin de prévenir les attaques temporelles.\n"
+"Voir [url=https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-"
+"string-comparison-with-double-hmac-strategy]ce blog[/url] pour plus "
+"d'informations."
#: doc/classes/Crypto.xml
msgid ""
@@ -22510,6 +24110,8 @@ msgid ""
"Generates an RSA [CryptoKey] that can be used for creating self-signed "
"certificates and passed to [method StreamPeerSSL.accept_stream]."
msgstr ""
+"Génère une [CryptoKey] RSA qui peut être utilisé pour créer des certificats "
+"autosignés et transmis à [method StreamPeerSSL.accept_stream]."
#: doc/classes/Crypto.xml
msgid ""
@@ -22558,6 +24160,12 @@ msgid ""
"Currently, only [constant HashingContext.HASH_SHA256] and [constant "
"HashingContext.HASH_SHA1] are supported."
msgstr ""
+"Génère un résumé [url=https://en.wikipedia.org/wiki/HMAC]HMAC[/url] de "
+"[code]msg[/code] à partir de la clé [code]key[/code]. Le paramètre "
+"[code]hash_type[/code] est l'algorithme de hachage utilisé pour les hachages "
+"intérieurs et extérieurs.\n"
+"Actuellement, seuls les algorithmes [constant HashingContext.HASH_SHA256] et "
+"[constant HashingContext.HASH_SHA1] sont supportés."
#: doc/classes/Crypto.xml
msgid ""
@@ -22587,6 +24195,12 @@ msgid ""
"Crypto.generate_self_signed_certificate] and as private key in [method "
"StreamPeerSSL.accept_stream] along with the appropriate certificate."
msgstr ""
+"La classe CryptoKey représente une clé cryptographique. Les clés peuvent "
+"être chargées et sauvegardées comme toute autre [Resource].\n"
+"Elles peuvent être utilisées pour générer un certicat [X509Certificate] "
+"autosigné avec [method Crypto.generate_self_signed_certificate] et comme clé "
+"privée dans [method StreamPeerSSL.accept_stream] avec le certificat "
+"approprié."
#: doc/classes/CryptoKey.xml
msgid ""
@@ -22603,12 +24217,19 @@ msgid ""
"[b]Note:[/b] [code]path[/code] should be a \"*.pub\" file if "
"[code]public_only[/code] is [code]true[/code], a \"*.key\" file otherwise."
msgstr ""
+"Charge la clé à [code]path[/code]. Si [code]public_only[/code] est "
+"[code]true[/code], seule la clé publique sera chargée.\n"
+"[b]Note :[/b] [code]path[/code] doit être un fichier \"*.pub\" si "
+"[code]public_only[/code] est [code]true[/code], et un fichier \"*.key\" "
+"sinon."
#: doc/classes/CryptoKey.xml
msgid ""
"Loads a key from the given [code]string[/code]. If [code]public_only[/code] "
"is [code]true[/code], only the public key will be loaded."
msgstr ""
+"Charge une clé depuis la [code]string[/code] donnée. Si [code]public_only[/"
+"code] est [code]true[/code], seule la clé publique sera chargée."
#: doc/classes/CryptoKey.xml
msgid ""
@@ -22617,12 +24238,21 @@ msgid ""
"[b]Note:[/b] [code]path[/code] should be a \"*.pub\" file if "
"[code]public_only[/code] is [code]true[/code], a \"*.key\" file otherwise."
msgstr ""
+"Enregistre une clé au chemin [code]path[/code] spécifié. Si "
+"[code]public_only[/code] est [code]true[/code], seule la clé publique sera "
+"enregistrée.\n"
+"[b]Note :[/b] [code]path[/code] doit être un fichier avec l'extension \"."
+"pub\" si [code]public_only[/code] est [code]true[/code], et avec l'extension "
+"\".key\" sinon."
#: doc/classes/CryptoKey.xml
msgid ""
"Returns a string containing the key in PEM format. If [code]public_only[/"
"code] is [code]true[/code], only the public key will be included."
msgstr ""
+"Retourne une chaîne de caractères contenant la clé en format PEM. Si "
+"[code]public_only[/code] est [code]true[/code], seule la clé publique sera "
+"incluse."
#: modules/csg/doc_classes/CSGBox.xml
msgid "A CSG Box shape."
@@ -22685,7 +24315,6 @@ msgid ""
msgstr ""
#: modules/csg/doc_classes/CSGCylinder.xml
-#, fuzzy
msgid "A CSG Cylinder shape."
msgstr "Une forme de cylindre CSG."
@@ -22807,12 +24436,18 @@ msgid ""
"shape. If [code]false[/code] the top half of the material is repeated every "
"step of the extrusion."
msgstr ""
+"Lorsque [member mode] est [constant MODE_PATH], par défaut, la moitié "
+"supérieure du [member material] est étirée sur toute la longueur de la forme "
+"extrudée. Si [code]false[/code] la partie supérieure du matériau est répétée "
+"à chaque étape de l'extrusion."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"When [member mode] is [constant MODE_PATH], the path interval or ratio of "
"path points to extrusions."
msgstr ""
+"Lorsque [member mode] est [constant MODE_PATH], l'intervalle de chemin ou le "
+"rapport de chemin pointe vers les extrusions."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22820,6 +24455,10 @@ msgid ""
"interval should be by distance ([constant PATH_INTERVAL_DISTANCE]) or "
"subdivision fractions ([constant PATH_INTERVAL_SUBDIVIDE])."
msgstr ""
+"Lorsque [member mode] est [constant MODE_PATH], cela déterminera si "
+"l'intervalle doit être suivant la distance ([constant "
+"PATH_INTERVAL_DISTANCE]) ou suivant une fraction des sous-divisions "
+"([constant PATH_INTERVAL_SUBDIVIDE])."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22827,6 +24466,9 @@ msgid ""
"the path are joined, by adding an extrusion between the last and first "
"points of the path."
msgstr ""
+"Lorsque [member mode] est [constant MODE_PATH], si [code]true[/code] les "
+"extrémités du chemin sont jointes, en ajoutant une extrusion entre le "
+"dernier et le premier points du chemin."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22834,24 +24476,34 @@ msgid ""
"[Transform] of the [CSGPolygon] is used as the starting point for the "
"extrusions, not the [Transform] of the [member path_node]."
msgstr ""
+"Lorsque [member mode] est [constant MODE_PATH], si [code]true[/code] la "
+"[Transform] du [CSGPolygon] est utilisée comme point de départ pour les "
+"extrusions, et non pas la [Transform] du [member path_node]."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"When [member mode] is [constant MODE_PATH], the location of the [Path] "
"object used to extrude the [member polygon]."
msgstr ""
+"Lorsque [member mode] est [constant MODE_PATH], l'emplacement de l'objet "
+"[Path] utilisé pour extruder le [member polygon]."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"When [member mode] is [constant MODE_PATH], the [enum PathRotation] method "
"used to rotate the [member polygon] as it is extruded."
msgstr ""
+"Lorsque [member mode] est [constant MODE_PATH], la méthode [enum "
+"PathRotation] utilisée pour faire pivoter le [member polygon] selon son "
+"extrusion."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"When [member mode] is [constant MODE_PATH], extrusions that are less than "
"this angle, will be merged together to reduce polygon count."
msgstr ""
+"Lorsque [member mode] est [constant MODE_PATH], les extrusions qui sont "
+"inférieures à cet angle seront fusionnés pour réduire le nombre de polygones."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22859,6 +24511,10 @@ msgid ""
"path, in meters, the texture coordinates will tile. When set to 0, texture "
"coordinates will match geometry exactly with no tiling."
msgstr ""
+"Lorsque [member mode] est [constant MODE_PATH], c'est la distance le long du "
+"chemin, en mètres, que les coordonnées de texture seront répétées. Quand à "
+"0, les coordonnées de texture correspondront exactement à la géométrie sans "
+"répétition."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22869,6 +24525,12 @@ msgid ""
"[b]Note:[/b] If only 1 or 2 points are defined in [member polygon], no mesh "
"will be generated."
msgstr ""
+"Le tableau de points qui définit le polygone 2D extrudé. Cela peut être un "
+"polygone convexe ou concave avec 3 points ou plus. Le polygone ne doit "
+"[i]pas[/i] avoir de bords qui sont des intersections. Sinon, la "
+"triangulation échouera et aucun maillage ne sera généré.\n"
+"[b]Note :[/b] Si seulement 1 ou 2 points sont définis dans [member polygon], "
+"aucun maillage ne sera généré."
#: modules/csg/doc_classes/CSGPolygon.xml
#, fuzzy
@@ -22889,7 +24551,7 @@ msgstr ""
#: modules/csg/doc_classes/CSGPolygon.xml
msgid "The [member polygon] shape is extruded along the negative Z axis."
-msgstr ""
+msgstr "La forme [member polygone] est extrudée le long de l'axe Z négatif."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22903,6 +24565,8 @@ msgid ""
"The [member polygon] shape is extruded along the [Path] specified in [member "
"path_node]."
msgstr ""
+"La forme [member polygone] est extrudée le long du [Path] spécifié par "
+"[member path_node]."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22910,6 +24574,9 @@ msgid ""
"[b]Note:[/b] Requires the path's Z coordinates to continually decrease to "
"ensure viable shapes."
msgstr ""
+"La forme [member polygon] n'a pas pivoté.\n"
+"[b]Note :[/b] Nécessite que les coordonnées Z du chemin diminuent en "
+"continue pour assurer des formes viables."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22918,12 +24585,17 @@ msgid ""
"[b]Note:[/b] Requires the path's Z coordinates to continually decrease to "
"ensure viable shapes."
msgstr ""
+"La forme [member polygon] est pivotée le long du chemin, mais elle n'est pas "
+"pivotée autour de l'axe du chemin.\n"
+"[b]Note :[/b] Nécessite que les coordonnées Z du chemin diminuent en "
+"continue pour assurer des formes viables."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"The [member polygon] shape follows the path and its rotations around the "
"path axis."
msgstr ""
+"La forme [member polygon] suit le chemin et pivote autour de l'axe du chemin."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22931,12 +24603,17 @@ msgid ""
"will determine the distance, in meters, each interval of the path will "
"extrude."
msgstr ""
+"Lorsque [member mode] est défini à [constant MODE_PATH], [member "
+"path_interval] déterminera la distance, en mètres, entre chaque intervalle "
+"où le chemin s'extrudera."
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"When [member mode] is set to [constant MODE_PATH], [member path_interval] "
"will subdivide the polygons along the path."
msgstr ""
+"Lorsque [member mode] est défini [constant MODE_PATH], [member "
+"path_interval] divisera les polygones le long du chemin."
#: modules/csg/doc_classes/CSGPrimitive.xml
msgid "Base class for CSG primitives."
@@ -22984,6 +24661,9 @@ msgid ""
"node and the second is the root [Mesh] of this node. Only works when this "
"node is the root shape."
msgstr ""
+"Retourne un [Array] avec deux éléments, le premier est la [Transform] de ce "
+"nœud et le second est le [Mesh] racine de ce nœud. Ne fonctionne que lorsque "
+"ce nœud est la forme racine."
#: modules/csg/doc_classes/CSGShape.xml
msgid ""
@@ -22998,12 +24678,16 @@ msgid ""
"Sets individual bits on the layer mask. Use this if you only need to change "
"one layer's value."
msgstr ""
+"Définit des bits individuels sur le masque de calque. Utilisez ceci si vous "
+"n'avez besoin que de changer de calque."
#: modules/csg/doc_classes/CSGShape.xml doc/classes/SoftBody.xml
msgid ""
"Sets individual bits on the collision mask. Use this if you only need to "
"change one layer's value."
msgstr ""
+"Définit des bits individuels sur le masque de collision. Utilisez ceci si "
+"vous n'avez besoin que de changer de calque."
#: modules/csg/doc_classes/CSGShape.xml
msgid ""
@@ -23050,6 +24734,9 @@ msgid ""
"CSG child node as the operation is between this node and the previous child "
"of this nodes parent."
msgstr ""
+"L'opération effectuée sur cette forme. Ceci est ignoré pour le premier nœud "
+"enfant CSG puisque l'opération est entre ce nœud et l'enfant précédent de ce "
+"nœud parent."
#: modules/csg/doc_classes/CSGShape.xml
msgid ""
@@ -23064,6 +24751,9 @@ msgid ""
"always act like a static body. Note that the collision shape is still active "
"even if the CSG shape itself is hidden."
msgstr ""
+"Ajoute une forme de collision au moteur de physique pour cette forme CSG. "
+"Cela agira toujours comme un corps statique. Notez que la forme de collision "
+"est toujours active même si cette forme CSG est cachée."
#: modules/csg/doc_classes/CSGShape.xml
msgid ""
@@ -23161,6 +24851,9 @@ msgid ""
"effect making the torus seem rounded. If [code]false[/code] the torus will "
"have a flat shaded look."
msgstr ""
+"Si [code]true[/code] les normales du tore sont définies pour donner un effet "
+"lisse donnant l'impression que le tore est arrondis. Si [code]false[/code] "
+"le tore aura un aspect de rendu plat."
#: modules/mono/doc_classes/CSharpScript.xml
#, fuzzy
@@ -23177,6 +24870,9 @@ msgid ""
"class and is only available in Mono-enabled Godot builds.\n"
"See also [GodotSharp]."
msgstr ""
+"Cette classe représente un script C#. C'est l'équivalent C# de la classe "
+"[GDScript] et n'est disponible que dans les versions de Godot avec Mono.\n"
+"Voir aussi [GodotSharp]."
#: modules/mono/doc_classes/CSharpScript.xml
#: modules/gdnative/doc_classes/PluginScript.xml
@@ -23318,6 +25014,16 @@ msgid ""
"this, increase [member subdivide_depth], [member subdivide_height] and "
"[member subdivide_width] until you no longer notice UV jittering."
msgstr ""
+"Générer un cuboïde [PrimitiveMesh] aligné sur les axes.\n"
+"La projection des UV du cube est disposée selon une disposition de 3×2 qui "
+"permet de placer une texture sur chaque face individuellement. Pour "
+"appliquer la même texture sur toutes les faces, modifiez la propriété UV du "
+"matériau actif à [code]Vector3(3, 2, 1)[/code].\n"
+"[b]Note :[/b] Lors de l'utilisation d'une grande texture [CubeMesh] (par "
+"exemple pour le sol), vous pouvez tomber sur des problèmes de jittering de "
+"l'UV suivant l'angle de la caméra. Pour résoudre cela, augmentez [member "
+"subdivide_depth], [member subdivide_height] et [member subdivide_width] "
+"jusqu'à ce que vous ne remarquez plus le jittering de l'UV."
#: doc/classes/CubeMesh.xml
msgid "Size of the cuboid mesh."
@@ -23326,14 +25032,17 @@ msgstr "Taille du maillage cuboïde."
#: doc/classes/CubeMesh.xml
msgid "Number of extra edge loops inserted along the Z axis."
msgstr ""
+"Le nombre de boucles de bord supplémentaires insérées le long de l'axe Z."
#: doc/classes/CubeMesh.xml
msgid "Number of extra edge loops inserted along the Y axis."
msgstr ""
+"Le nombre de boucles de bord supplémentaires insérées le long de l'axe Y."
#: doc/classes/CubeMesh.xml
msgid "Number of extra edge loops inserted along the X axis."
msgstr ""
+"Le nombre de boucles de bord supplémentaires insérées le long de l'axe X."
#: doc/classes/CullInstance.xml
msgid "Parent of all nodes that can be culled by the Portal system."
@@ -23447,6 +25156,9 @@ msgid ""
"ranges between [code]0[/code] and [code]1[/code] on the Y axis and positions "
"points relative to the [code]0.5[/code] Y position."
msgstr ""
+"Une courbe qui peut être sauvegardée et réutilisée pour d'autres objets. Par "
+"défaut, elle va de [code]0[/code] à [code]1[/code] selon l'axe Y et les "
+"positions sont relatives à la position [code]0.5[/code] de l'axe Y."
#: doc/classes/Curve.xml
msgid ""
@@ -23456,6 +25168,12 @@ msgid ""
"assignments to the [code]*_tangent[/code] angle if [code]*_mode[/code] is "
"set to [constant TANGENT_FREE]."
msgstr ""
+"Ajoute un point à la courbe. Pour chaque côté, si le [code]*_mode[/code] est "
+"[constant TANGENT_LINEAR], l'angle [code]*_tangent[/code] (en degrés) "
+"utilise la pente de la courbe définie par rapport à la demi-distance du "
+"point adjacent. Permet des spécifier des tangentes personnalisées avec "
+"[code]*_tangent[/code] si [code]*_mode[/code] est défini à [constant "
+"TANGENT_FREE]."
#: doc/classes/Curve.xml
msgid "Recomputes the baked cache of points for the curve."
@@ -23466,6 +25184,8 @@ msgid ""
"Removes points that are closer than [code]CMP_EPSILON[/code] (0.00001) units "
"to their neighbor on the curve."
msgstr ""
+"Retire les points qui sont plus proches que [code]CMP_EPSILON[/code] "
+"(0.00001) unités à leur voisin sur la courbe."
#: doc/classes/Curve.xml doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid "Removes all points from the curve."
@@ -23510,6 +25230,8 @@ msgid ""
"Returns the Y value for the point that would exist at the X position "
"[code]offset[/code] along the curve."
msgstr ""
+"Retourne la valeur Y pour un point qui existerait à la position X "
+"[code]offset[/code] le long de la courbe."
#: doc/classes/Curve.xml
msgid ""
@@ -23517,6 +25239,9 @@ msgid ""
"[code]offset[/code] along the curve using the baked cache. Bakes the curve's "
"points if not already baked."
msgstr ""
+"Retourne la valeur Y pour un point qui existerait à la position X "
+"[code]offset[/code] le long de la courbe en utilisant le cache précalculé. "
+"Précalcule les points de la courbe suivante si ça n'a pas déjà été fait."
#: doc/classes/Curve.xml
msgid "Removes the point at [code]index[/code] from the curve."
@@ -23591,6 +25316,8 @@ msgid ""
"The curve calculates the tangent on this side of the point as the slope "
"halfway towards the adjacent point."
msgstr ""
+"La courbe calcule la tangente de ce côté du point comme la pente avec la "
+"demi-distance du point adjacent."
#: doc/classes/Curve.xml
msgid "The total number of available tangent modes."
@@ -23624,12 +25351,24 @@ msgid ""
"get_point_count][/code]), the point will be appended at the end of the point "
"list."
msgstr ""
+"Ajoute un point à une courbe à la [code]position[/code] par rapport à la "
+"position de la [Curve2D], avec des points de contrôle d'entrée [code]in[/"
+"code] et de sortie [code]out[/code].\n"
+"Si [code]at_position[/code] est spécifié, le point est inséré juste avant ce "
+"numéro de point [code]at_position[/code], en déplaçant ce point (et tous les "
+"autres points qui suivent) après le point inséré. Si [code]at_position[/"
+"code] n'est pas donné, ou est une valeur invalide ([code]at_position < 0[/"
+"code] ou [code]at_position >= [method get_point_count][/code,) le point sera "
+"ajouté en dernier."
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
"Returns the total length of the curve, based on the cached points. Given "
"enough density (see [member bake_interval]), it should be approximate enough."
msgstr ""
+"Retourne la longueur totale de la courbe, à partir de la distance entre les "
+"points mis en cache. Si la densité est suffisante (voir [member "
+"bake_interval]), cette longeur devrait être une approximation suffisante."
#: doc/classes/Curve2D.xml
msgid "Returns the cache of points as a [PoolVector2Array]."
@@ -23641,6 +25380,9 @@ msgid ""
"be used in [method interpolate_baked].\n"
"[code]to_point[/code] must be in this curve's local space."
msgstr ""
+"Retourne le décalage le plus proche de [code]to_point[/code]. Ce décalage "
+"est destiné à être utilisé dans [méthode interpolate_baked].\n"
+"[code]to_point[/code] doit être dans l'espace local de la courbe."
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
@@ -23648,6 +25390,9 @@ msgid ""
"code].\n"
"[code]to_point[/code] must be in this curve's local space."
msgstr ""
+"Retourne le point en cache le plus proche (dans l'espace local de la courbe) "
+"de [code]to_point[/code].\n"
+"[code]to_point[/code] doit être dans l'espace local de la courbe."
#: doc/classes/Curve2D.xml
msgid ""
@@ -23656,6 +25401,10 @@ msgid ""
"the index is out of bounds, the function sends an error to the console, and "
"returns [code](0, 0)[/code]."
msgstr ""
+"Retourne la position du point de contrôle menant vers le sommet [code]idx[/"
+"code]. La position retournée est relative au sommet [code]idx[/code]. Si "
+"l'index est hors limites, la fonction affiche une erreur, et retourne [code]"
+"(0, 0)[/code]."
#: doc/classes/Curve2D.xml
msgid ""
@@ -23664,6 +25413,10 @@ msgid ""
"code]. If the index is out of bounds, the function sends an error to the "
"console, and returns [code](0, 0)[/code]."
msgstr ""
+"Retourne la position du point de contrôle en partant du sommet [code]idx[/"
+"code]. La position retournée est relative au sommet [code]idx[/code]. Si "
+"l'index est hors limites, la fonction affiche une erreur, et retourne [code]"
+"(0, 0)[/code]."
#: doc/classes/Curve2D.xml
msgid ""
@@ -23671,6 +25424,8 @@ msgid ""
"bounds, the function sends an error to the console, and returns [code](0, 0)"
"[/code]."
msgstr ""
+"Retourne la position du sommet [code]idx[/code]. Si l'index est hors "
+"limites, la fonction affiche une erreur, et retourne [code](0, 0)[/code]."
#: doc/classes/Curve2D.xml
msgid ""
@@ -23683,6 +25438,14 @@ msgid ""
"vertex, and [code]t[/code] is ignored. If the curve has no points, the "
"function sends an error to the console, and returns [code](0, 0)[/code]."
msgstr ""
+"Retourne la position entre le sommet [code]idx[/code] et le sommet [code]idx "
+"+ 1[/code], où [code]t[/code] contrôle si le point est le premier sommet "
+"([code]t = 0,0[/code]), le dernier sommet ([code]t = 1.0[/code]), ou entre "
+"les deux. Les valeurs de [code]t[/code] en dehors de l'intervalle ([code]0.0 "
+">= t <=1[/code]) donnent des résultats inattendus, mais prévisibles.\n"
+"Si [code]idx[/code] est hors limites il est tronqué au premier ou au dernier "
+"sommet, et [code]t[/code] est ignoré. Si la courbe n'a pas de points, la "
+"fonction affiche une erreur, et retourne [code](0, 0)[/code]."
#: doc/classes/Curve2D.xml
msgid ""
@@ -23695,6 +25458,14 @@ msgid ""
"Cubic interpolation tends to follow the curves better, but linear is faster "
"(and often, precise enough)."
msgstr ""
+"Retourne un point dans la courbe à la position [code]offset[/code], où "
+"[code]offset[/code] est mesuré en pixels le long de la courbe.\n"
+"Pour cela, il trouve les deux points dans le cache où le [code]offset[/code] "
+"se situe entre, puis interpole les valeurs. Cette interpolation est cubique "
+"si [code]cubic[/code] est [code]true[/code], ou linéaire si est [code]false[/"
+"code].\n"
+"L'interpolation cubique tend à mieux suivre les courbes, mais "
+"l'interpolation linéaire est plus rapide (et souvent bien assez précise)."
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
@@ -23702,12 +25473,17 @@ msgid ""
"interpolate] using the integer part of [code]fofs[/code] as [code]idx[/"
"code], and its fractional part as [code]t[/code]."
msgstr ""
+"Retourne la position au sommet [code]fofs[/code]. Ça appelle [method "
+"interpolate] en utilisant la partie entière de [code]fofs[/code] pour "
+"[code]idx[/code], et sa partie décimale pour [code]t[/code]."
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
"Deletes the point [code]idx[/code] from the curve. Sends an error to the "
"console if [code]idx[/code] is out of bounds."
msgstr ""
+"Supprime le point [code]idx[/code] de la courbe. Affiche une erreur si "
+"[code]idx[/code] est hors limites."
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
@@ -23715,6 +25491,9 @@ msgid ""
"code]. If the index is out of bounds, the function sends an error to the "
"console. The position is relative to the vertex."
msgstr ""
+"Régle la position du point de contrôle menant au sommet [code]idx[/code]. Si "
+"l'index est hors limites, la fonction affiche une erreur. La position est "
+"relative au sommet."
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
@@ -23722,12 +25501,17 @@ msgid ""
"code]. If the index is out of bounds, the function sends an error to the "
"console. The position is relative to the vertex."
msgstr ""
+"Régle la position du point de contrôle partant du sommet [code]idx[/code]. "
+"Si l'index est hors limites, la fonction affiche une erreur. La position est "
+"relative au sommet."
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
"Sets the position for the vertex [code]idx[/code]. If the index is out of "
"bounds, the function sends an error to the console."
msgstr ""
+"Définit la position pour le vertex [code]idx[/code]. Si l'index est hors "
+"limites, la fonction affiche une erreur."
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
@@ -23783,6 +25567,11 @@ msgid ""
"It keeps a cache of precalculated points along the curve, to speed up "
"further calculations."
msgstr ""
+"Cette classe décrit une courbe de Bézier dans l'espace 3D. Elle est "
+"principalement utilisée pour donner une forme à un [Path], mais peut être "
+"échantillonné manuellement à d'autres fins.\n"
+"Elle conserve un cache de points précalculés le long de la courbe, pour "
+"accélérer de nouveaux calculs."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23795,6 +25584,15 @@ msgid ""
"get_point_count][/code]), the point will be appended at the end of the point "
"list."
msgstr ""
+"Ajoute un point à la courbe à [code]position[/code] par rapport à la "
+"position [Curve3D], avec des points de contrôle [code]in[/code] et "
+"[code]out[/code].\n"
+"Si [code]at_position[/code] est spécifiée, le point est inséré avant le "
+"numéro de point [code]at_position[/code], deplaçant ce point (et tous les "
+"suivants) après le point inséré. Si [code]at_position[/code] n'est pas "
+"spécifiée, ou est une valeur invalide ([code]at_position <0[/code] ou "
+"[code]at_position >= [method get_point_count][/code]), le point sera ajouté "
+"à la fin de la liste des points."
#: doc/classes/Curve3D.xml
msgid "Returns the cache of points as a [PoolVector3Array]."
@@ -23809,6 +25607,8 @@ msgid ""
"Returns the cache of up vectors as a [PoolVector3Array].\n"
"If [member up_vector_enabled] is [code]false[/code], the cache will be empty."
msgstr ""
+"Retourne le cache des vecteurs du haut dans un [PoolVector3Array].\n"
+"Si [member up_vector_enabled] est [code]false[/code], le cache sera vide."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23817,6 +25617,10 @@ msgid ""
"interpolate_baked_up_vector].\n"
"[code]to_point[/code] must be in this curve's local space."
msgstr ""
+"Retourne le décalage le plus proche de [code]to_point[/code]. Ce décalage "
+"est destiné à être utilisé dans [method interpolate_baked] ou [method "
+"interpolate_baked_up_vector].\n"
+"[code]to_point[/code] doit être dans l'espace local de cette courbe."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23825,6 +25629,10 @@ msgid ""
"the index is out of bounds, the function sends an error to the console, and "
"returns [code](0, 0, 0)[/code]."
msgstr ""
+"Retourne la position du point de contrôle menant au sommet [code]idx[/code]. "
+"La position retournée est relative au sommet [code]idx[/code]. Si l'index "
+"est hors limites, la fonction affiche une erreur, et retourne [code](0, 0, 0)"
+"[/code]."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23833,6 +25641,10 @@ msgid ""
"code]. If the index is out of bounds, the function sends an error to the "
"console, and returns [code](0, 0, 0)[/code]."
msgstr ""
+"Retourne la position du point de contrôle partant du sommet [code]idx[/"
+"code]. La position retournée est relative au sommet [code]idx[/code]. Si "
+"l'index est hors limites, la fonction affiche une erreur, et retourne [code]"
+"(0, 0, 0)[/code]."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23840,6 +25652,8 @@ msgid ""
"bounds, the function sends an error to the console, and returns [code](0, 0, "
"0)[/code]."
msgstr ""
+"Retourne la position du sommet [code]idx[/code]. Si l'index est hors "
+"limites, la fonction affiche une erreur, et retourne [code](0, 0, 0)[/code]."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23862,6 +25676,15 @@ msgid ""
"vertex, and [code]t[/code] is ignored. If the curve has no points, the "
"function sends an error to the console, and returns [code](0, 0, 0)[/code]."
msgstr ""
+"Retourne la position entre le sommet [code]idx[/code] et le sommet [code]idx "
+"+ 1[/code], où [code]t[/code] contrôle si le point est le premier sommet "
+"([code]t = 0,0[/code]), le dernier sommet ([code]t = 1.0[/code]), ou entre "
+"ces deux valeurs. Les valeurs de [code]t[/code] en dehors de l'intervalle "
+"([code]0.0 >= t <=1[/code]) donnent des résultats inattendus, mais "
+"prévisibles.\n"
+"Si [code]idx[/code] est hors limites il est tronqué au premier ou au dernier "
+"sommet, et [code]t[/code] est ignoré. Si la courbe n'a pas de points, la "
+"fonction affiche une erreur, et retourne [code](0, 0, 0)[/code]."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23874,6 +25697,14 @@ msgid ""
"Cubic interpolation tends to follow the curves better, but linear is faster "
"(and often, precise enough)."
msgstr ""
+"Retourne un point dans la courbe à la position [code]offset[/code], où "
+"[code]offset[/code] est mesuré en unités 3D le long de la courbe.\n"
+"Pour cela, il trouve les deux points dans le cache où le [code]offset[/code] "
+"se situe entre, puis interpole les valeurs. Cette interpolation est cubique "
+"si [code]cubic[/code] est [code]true[/code], ou linéaire si est [code]false[/"
+"code].\n"
+"L'interpolation cubique tend à mieux suivre les courbes, mais "
+"l'interpolation linéaire est plus rapide (et souvent bien assez précise)."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23886,6 +25717,14 @@ msgid ""
"If the curve has no up vectors, the function sends an error to the console, "
"and returns [code](0, 1, 0)[/code]."
msgstr ""
+"Retourne un vecteur haut dans la courbe à la position [code]offset[/code], "
+"où [code]offset[/code] est mesuré en unités 3D le long de la courbe.\n"
+"Pour cela, il trouve les deux vecteurs dans le cache où le [code]offset[/"
+"code] se situe entre, puis interpole les valeurs. Si [code]apply_tilt[/code] "
+"est [code]true[/code], une inclinaison interpolée est aussi appliquée au "
+"vecteur interpolé.\n"
+"Si la courbe n'a pas de vecteurs, la fonction affiche une erreur, et "
+"retourne [code](0, 1, 0)[/code]."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23895,6 +25734,11 @@ msgid ""
"the path would have. In the case of a curve controlling a [PathFollow], this "
"tilt is an offset over the natural tilt the [PathFollow] calculates."
msgstr ""
+"Définit l'angle d'inclinaison en radians pour le point [code]idx[/code]. Si "
+"l'index est hors limites, la fonction affiche une erreur.\n"
+"L'inclinaison contrôle la rotation qu'un objet parcourant la courbe aurait. "
+"Dans le cas d'une courbe contrôlant un [PathFollow], cette inclinaison est "
+"un décalage sur l'inclinaison naturelle que calcule le [PathFollow]."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23904,6 +25748,11 @@ msgid ""
"smaller the distance, the more points in the cache and the more memory it "
"will consume, so use with care."
msgstr ""
+"La distance en unités entre deux points de cache adjacents. Le changement "
+"force le cache à être recalculé la prochaine fois que la fonction [method "
+"get_baked_points] ou [method get_baked_length] sera appelée. Plus la "
+"distance est petite, plus il y aura de points dans le cache, et plus ça "
+"utilisera de mémoire, à utiliser donc avec soin."
#: doc/classes/Curve3D.xml
msgid ""
@@ -23911,6 +25760,10 @@ msgid ""
"This is used when [member PathFollow.rotation_mode] is set to [constant "
"PathFollow.ROTATION_ORIENTED]. Changing it forces the cache to be recomputed."
msgstr ""
+"Si [code]true[/code], la courbe pré-calcule des vecteurs utilisés pour "
+"l'orientation. Ceci est utilisé lorsque [member PathFollow.rotation_mode] "
+"est défini à [constant PathFollow.ROTATION_ORIENTED]. Le changer force le "
+"cache à être recalculé."
#: doc/classes/CurveTexture.xml
msgid "A texture that shows a curve."
@@ -23921,6 +25774,8 @@ msgid ""
"Renders a given [Curve] provided to it. Simplifies the task of drawing "
"curves and/or saving them as image files."
msgstr ""
+"Fait le rendu d'une [Curve] donnée. Simplifie la tâche de dessiner les "
+"courbes et/ou de les enregistrer dans des fichiers d'image."
#: doc/classes/CurveTexture.xml
#, fuzzy
@@ -23933,6 +25788,10 @@ msgid ""
"represent high-frequency data better (such as sudden direction changes), at "
"the cost of increased generation time and memory usage."
msgstr ""
+"La largeur de la texture (en pixels). Des valeurs plus élevées permettent de "
+"mieux représenter les données à haute fréquence (comme les changements "
+"soudains de direction) au coût de l'utilisation accrue du temps de "
+"génération et de la mémoire."
#: doc/classes/CylinderMesh.xml
msgid "Class representing a cylindrical [PrimitiveMesh]."
@@ -23944,12 +25803,17 @@ msgid ""
"create cones by setting either the [member top_radius] or [member "
"bottom_radius] properties to [code]0.0[/code]."
msgstr ""
+"La classe représentant un [PrimitiveMesh] cylindrique. Cette classe peut "
+"être utilisée pour créer des cônes en définissant la propriété [member "
+"top_radius] ou [member bottom_radius] à [code]0.0[/code]."
#: doc/classes/CylinderMesh.xml
msgid ""
"Bottom radius of the cylinder. If set to [code]0.0[/code], the bottom faces "
"will not be generated, resulting in a conic shape."
msgstr ""
+"Le rayon inférieur du cylindre. Si [code]0.0[/code], les faces inférieures "
+"ne seront pas générées, ce qui donne une forme conique."
#: doc/classes/CylinderMesh.xml
msgid "Full height of the cylinder."
@@ -23960,6 +25824,9 @@ msgid ""
"Number of radial segments on the cylinder. Higher values result in a more "
"detailed cylinder/cone at the cost of performance."
msgstr ""
+"Le nombre de segments radiaux sur le cylindre. Des valeurs plus élevées "
+"génèrent des cylindres/cônes plus détaillés mais peuvent réduire les "
+"performances."
#: doc/classes/CylinderMesh.xml
msgid ""
@@ -23977,6 +25844,8 @@ msgid ""
"Top radius of the cylinder. If set to [code]0.0[/code], the top faces will "
"not be generated, resulting in a conic shape."
msgstr ""
+"Le rayon supérieur du cylindre. Si [code]0.0[/code], les faces supérieures "
+"ne seront pas générées, ce qui donne une forme conique."
#: doc/classes/CylinderShape.xml
msgid "Cylinder shape for collisions."
@@ -24277,6 +26146,12 @@ msgid ""
"[b]Note:[/b] Don't erase elements while iterating over the dictionary. You "
"can iterate over the [method keys] array instead."
msgstr ""
+"Efface une paire de clé/valeur du dictionnaire spécifiée par sa clé. "
+"Retourne [code]true[/code] si la clé donnée était présente dans le "
+"dictionnaire, [code]false[/code] sinon.\n"
+"[b]Note :[/b] Ne supprimez pas les éléments pendant l'énumération du "
+"dictionnaire. Vous pouvez à la place énumérer le dictionnaire avec [method "
+"keys] qui retourne un tableau immuable."
#: doc/classes/Dictionary.xml
msgid ""
@@ -24284,6 +26159,9 @@ msgid ""
"key does not exist, the method returns the value of the optional default "
"argument, or [code]null[/code] if it is omitted."
msgstr ""
+"Retourne la valeur actuelle de la clé spécifiée dans le [Dictionnaire]. Si "
+"la clé n'existe pas, la méthode retourne la valeur de l'argument optionnel "
+"\"default\", ou [code]null[/code] si elle n'est pas spécifiée."
#: doc/classes/Dictionary.xml
msgid ""
@@ -24364,6 +26242,9 @@ msgid ""
"duplicate keys will not be copied over, unless [code]overwrite[/code] is "
"[code]true[/code]."
msgstr ""
+"Ajoute tous les éléments de [code]dictionary[/code] à ce [Dictionnaire]. Par "
+"défaut, les clés en double ne seront pas remplaçées, sauf si "
+"[code]overwrite[/code] est [code]true[/code]."
#: doc/classes/Dictionary.xml
msgid "Returns the number of keys in the dictionary."
@@ -24386,18 +26267,32 @@ msgid ""
"or moonlight. The worldspace location of the DirectionalLight transform "
"(origin) is ignored. Only the basis is used to determine light direction."
msgstr ""
+"Une lumière directionnelle est un type de nœud [Light] qui fait un rendu "
+"d'un nombre infini de rayons parallèles couvrant toute la scène. Il est "
+"utilisé pour les lumières à forte intensité qui sont situées loin de la "
+"scène pour modéliser la lumière du soleil ou du clair de lune. L'emplacement "
+"global de la DirectionalLight (son origine) est ignoré. Seule sa rotation "
+"est utilisée pour déterminer la direction de la lumière."
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
+"Si [code]true[/code], le détail des ombres est sacrifié pour obtenir des "
+"transitions plus lisses entre les fractions. Activer cette option a "
+"également un coût modéré sur les performances. Ceci est ignoré lorsque "
+"[member directional_shadow_mode] est [constant SHADOW_ORTHOGONAL]."
#: doc/classes/DirectionalLight.xml
msgid ""
@@ -24408,8 +26303,16 @@ msgstr ""
"Voir [enum ShadowDepthRange]."
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
-msgstr "Distance maximale pour les fractionnements d’ombre."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
+msgstr ""
+"La distance maximale pour les fractions des ombres. Augmenter cette valeur "
+"rendra visibles les ombres directionnelles de plus loin, mais affichera "
+"moins de détails des ombres et de moins bonnes performances (puisque plus "
+"d'objets doivent être inclus dans le rendu d'ombre directionnel)."
#: doc/classes/DirectionalLight.xml
msgid "The light's shadow rendering algorithm. See [enum ShadowMode]."
@@ -24421,29 +26324,42 @@ msgid ""
"Can be used to fix special cases of self shadowing when objects are "
"perpendicular to the light."
msgstr ""
+"Peut être utilisé pour corriger des cas spéciaux pour les ombres des objets "
+"qui sont perpendiculaires à la source de lumière."
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
+"La distance de la caméra à la division 1 de l'ombre. Relative à [member "
+"directional_shadow_max_distance]. Seulement utilisé lorsque [member "
+"directional_shadow_mode] est [constant SHADOW_PARALLEL_2_SPLITS] ou "
+"[constant SHADOW_PARALLEL_4_SPLITS]."
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
+"La distance de la division 1 à la divion 2 de l'ombre. Relative à [member "
+"directional_shadow_max_distance]. Seulement utilisé lorsque [member "
+"directional_shadow_mode] est [constant SHADOW_PARALLEL_2_SPLITS] ou "
+"[constant SHADOW_PARALLEL_4_SPLITS]."
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
+"La distance de la division 2 à la divion 3 de l'ombre. Relative à [member "
+"directional_shadow_max_distance]. Seulement utilisé lorsque [member "
+"directional_shadow_mode] est [constant SHADOW_PARALLEL_4_SPLITS]."
#: doc/classes/DirectionalLight.xml
msgid ""
@@ -24473,6 +26389,8 @@ msgid ""
"Keeps the shadow stable when the camera moves, at the cost of lower "
"effective shadow resolution."
msgstr ""
+"Garde l'ombre stable lorsque la caméra se déplace, mais la résolution de "
+"l'ombre se trouve réduite."
#: doc/classes/DirectionalLight.xml
msgid ""
@@ -24480,6 +26398,10 @@ msgid ""
"shadow edges. This mode typically works best in games where the camera will "
"often move at high speeds, such as most racing games."
msgstr ""
+"Essaye d'atteindre une résolution maximale pour l'ombre. Peut faire "
+"apparaitre un effet de scie sur les bords de l'ombre. Ce mode fonctionne "
+"généralement mieux dans les jeux où la caméra se déplace souvent à des "
+"vitesses élevées, comme la plupart des jeux de course."
#: doc/classes/Directory.xml
msgid "Type used to handle the filesystem."
@@ -24626,7 +26548,7 @@ msgid ""
"returns an empty String."
msgstr ""
"Sur Windows, retourne le nom du disque (du moins la partition) passé en "
-"argument (par exemple [code]C:[/code)].\n"
+"argument (par exemple [code]C:[/code]).\n"
"Sur macOS, retourne le chemin vers le volume monté qui est passé en "
"argument.\n"
"Sur Linux, retourne le chemin vers le volume monté, ou le favoris GTK 3, "
@@ -24995,7 +26917,7 @@ msgstr ""
"police TTF, vous pouvez utiliser [url=https://fontforge.org/]FontForge[/url] "
"pour cela. Dans FontForge, utilisez [b]Fichier > Polices Générales[/b], "
"cliquez sur [b]Options[/b], puis choisissez la fonctionnalité voulue lors de "
-"la génération de la police"
+"la génération de la police."
#: doc/classes/DynamicFont.xml
msgid "Adds a fallback font."
@@ -25008,6 +26930,10 @@ msgid ""
"If a given character is included in more than one font, it appears only once "
"in the returned string."
msgstr ""
+"Retourne une chaîne contenant tous les caractères disponibles dans la police "
+"principale et celles de repli.\n"
+"Si un caractère donné est inclus dans plus d'une police, il apparaît "
+"seulement une fois dans la chaîne retournée."
#: doc/classes/DynamicFont.xml
msgid "Returns the fallback font at index [code]idx[/code]."
@@ -25037,6 +26963,8 @@ msgid ""
"Sets the spacing for [code]type[/code] (see [enum SpacingType]) to "
"[code]value[/code] in pixels (not relative to the font size)."
msgstr ""
+"Définit l'espacement pour [code]type[/code] (voir [enum SpacingType]) à "
+"[code]value[/code] en pixels (et en fonction de la taille de la police)."
#: doc/classes/DynamicFont.xml
msgid "Extra spacing at the bottom in pixels."
@@ -25048,6 +26976,8 @@ msgid ""
"This can be a negative number to make the distance between characters "
"smaller."
msgstr ""
+"L'espacement additionnel entre chaque caratère, en pixels.\n"
+"Ceci peut être un nombre négatif pour rapprocher les caractères."
#: doc/classes/DynamicFont.xml
msgid ""
@@ -25055,6 +26985,9 @@ msgid ""
"extra_spacing_char]) in pixels.\n"
"This can be a negative number to make the distance between words smaller."
msgstr ""
+"L'espacement additionnel entre les caractères d'espace (en plus de [member "
+"extra_spacing_char]), en pixels.\n"
+"Cela peut être un nombre négatif pour rapprocher les mots."
#: doc/classes/DynamicFont.xml
msgid "Extra spacing at the top in pixels."
@@ -25072,10 +27005,17 @@ msgid ""
"black here, it won't be possible to change its color using a Label's font "
"outline modulate theme item."
msgstr ""
+"La couleur du contour de la police.\n"
+"[b]Note :[/b] Il est recommandé de laisser ceci à la valeur par défaut afin "
+"que vous puissiez l'ajuster dans les contrôles individuels. Par exemple, si "
+"le contour est déclaré ici en noir, il ne sera pas possible de modifier sa "
+"couleur même en utilisant un thème pour le Label."
#: doc/classes/DynamicFont.xml
msgid "The font outline's thickness in pixels (not relative to the font size)."
msgstr ""
+"L'épaisseur du contour de la police, en pixels (et non en fonction à la "
+"taille de la police)."
#: doc/classes/DynamicFont.xml
msgid "The font size in pixels."
@@ -25096,6 +27036,9 @@ msgid ""
"appearance when downscaling it if font oversampling is disabled or "
"ineffective."
msgstr ""
+"Si [code]true[/code], les mipmaps sont utilisées. Cela améliore l'apparence "
+"de la police lorsqu'elle est désactivée si le sur-échantillonnage de la "
+"police est désactivé ou non utilisé."
#: doc/classes/DynamicFont.xml
msgid "Spacing at the top."
@@ -25123,6 +27066,8 @@ msgid ""
"Used with [DynamicFont] to describe the location of a vector font file for "
"dynamic rendering at runtime."
msgstr ""
+"Utilisé avec [DynamicFont] pour décrire l'emplacement d'un fichier de police "
+"vectoriel pour un rendu dynamique au lancement du projet."
#: doc/classes/DynamicFontData.xml
msgid ""
@@ -25264,6 +27209,12 @@ msgid ""
"This method should not be used for System libraries as they are already "
"present on the device."
msgstr ""
+"Ajoute une bibliothèque dynamique (*.dylib, *.framework) au \"Linking "
+"Phase\" dans le projet Xcode d'iOS et l'intègre en binaire final.\n"
+"[b]Note :[/b] Pour les bibliothèques statiques (*.a), ça fonctionne de la "
+"même manière que [méthode add_ios_framework].\n"
+"Cette méthode ne devrait pas être utilisée pour les bibliothèques système "
+"car elles sont déjà présentes sur l'appareil."
#: doc/classes/EditorExportPlugin.xml
msgid ""
@@ -25282,6 +27233,8 @@ msgstr ""
#: doc/classes/EditorExportPlugin.xml
msgid "Adds a static lib from the given [code]path[/code] to the iOS project."
msgstr ""
+"Ajoute la bibliothèque statique à l'emplacement [code]path[/code] spécifié "
+"au projet iOS."
#: doc/classes/EditorExportPlugin.xml
msgid ""
@@ -25289,6 +27242,9 @@ msgid ""
"directory of macOS app bundle.\n"
"[b]Note:[/b] This is useful only for macOS exports."
msgstr ""
+"Ajoute le fichier ou le dossier correspondant à l'emplacement [code]path[/"
+"code] au dossier [code]PlugIns[/code] de l'applications macOS.\n"
+"[b]Note :[/b] Cela n'est utile que pour les exports pour macOS."
#: doc/classes/EditorExportPlugin.xml
msgid ""
@@ -25299,12 +27255,21 @@ msgid ""
"In case of a directory code-sign will error if you place non code object in "
"directory."
msgstr ""
+"Ajoute un objet partagé ou un dossier contenant uniquement des objets "
+"partagés avec les étiquettes [code]tags[/code] et le chemin de destination "
+"[code]path[/code].\n"
+"[b]Note :[/b] En cas d'exportation pour macOS, ces objets partagés seront "
+"ajoutés au dossier [code]Frameworks[/code] de l'app bundle.\n"
+"Pour les dossiers, \"code-sign\" affichera une erreur si vous placez dans ce "
+"dossier un objet qui n'est pas du code."
#: doc/classes/EditorExportPlugin.xml
msgid ""
"To be called inside [method _export_file]. Skips the current file, so it's "
"not included in the export."
msgstr ""
+"Sera appelé dans [method export_file]. Ignore le fichier actuel, il ne "
+"figurera donc pas dans l'exportation."
#: doc/classes/EditorFeatureProfile.xml
msgid ""
@@ -25324,6 +27289,17 @@ msgid ""
"To manage editor feature profiles visually, use [b]Editor > Manage Feature "
"Profiles...[/b] at the top of the editor window."
msgstr ""
+"Un profil d'éditeur peut être utilisé pour désactiver certaines "
+"fonctionnalités spécifiques de l'éditeur Godot. Lorsqu'elles sont "
+"désactivées, ces fonctionnalités n'apparaîtront pas dans l'éditeur, ce qui "
+"rend simplie l'éditeur. Cela est utile dans les milieux d'éducation pour "
+"réduire la confusion ou lorsque vous travaillez dans une équipe. Par "
+"exemple, les artistes et les concepteurs de niveau pourraient utiliser un "
+"profil de fonctionnalités qui désactive l'éditeur de script pour éviter des "
+"modifications accidentelles aux fichiers qu'ils ne sont pas censés "
+"modifier.\n"
+"Pour gérer visuellement les profils d'éditeur, utilisez [b]Éditeur > Gérer "
+"les profils de fonctionnalités.[/b] en haut de la fenêtre de l'éditeur."
#: doc/classes/EditorFeatureProfile.xml
msgid "Returns the specified [code]feature[/code]'s human-readable name."
@@ -25336,6 +27312,9 @@ msgid ""
"is disabled. When disabled, the class won't appear in the Create New Node "
"dialog."
msgstr ""
+"Retourne [code]true[/code] si la classe spécifiée par [code]class_name[/"
+"code] est désactivée. Lorsqu'elle est désactivée, la classe n'apparaitre pas "
+"dans le dialogue \"Créer un nouveau nœud\"."
#: doc/classes/EditorFeatureProfile.xml
msgid ""
@@ -25357,12 +27336,19 @@ msgid ""
"appear in the inspector when selecting a node that extends the class "
"specified by [code]class_name[/code]."
msgstr ""
+"Retourne [code]true[/code] si [code]property[/code] est désactivé dans la "
+"classe spécifiée par [code]class_name[/code]. Lorsqu'une propriété est "
+"désactivée, elle n'apparaît pas dans l'inspecteur pour un nœud qui étend la "
+"classe spécifiée par [code]class_name[/code]."
#: doc/classes/EditorFeatureProfile.xml
msgid ""
"Returns [code]true[/code] if the [code]feature[/code] is disabled. When a "
"feature is disabled, it will disappear from the editor entirely."
msgstr ""
+"Retourne [code]true[/code] si la fonctionnalité [code]feature[/code] est "
+"désactivée. Lorsqu'une fonctionnalité est désactivée, elle disparaîtra "
+"entièrement de l'éditeur."
#: doc/classes/EditorFeatureProfile.xml
msgid ""
@@ -25370,6 +27356,9 @@ msgid ""
"format obtained by using the feature profile manager's [b]Export[/b] button "
"or the [method save_to_file] method."
msgstr ""
+"Charge un profil d'éditeur depuis un fichier. Le fichier doit respecter le "
+"format JSON obtenu en utilisant le bouton [b]Export[/b] ou via la méthode "
+"[method save_to_file]."
#: doc/classes/EditorFeatureProfile.xml
msgid ""
@@ -25377,6 +27366,9 @@ msgid ""
"imported using the feature profile manager's [b]Import[/b] button or the "
"[method load_from_file] button."
msgstr ""
+"Enregistre le profil de fonctionnalité de l'éditeur dans un fichier au "
+"format JSON. Il peut ensuite être importé en utilisant le bouton [b]Import[/"
+"b] ou la méthode [method load_from_file]."
#: doc/classes/EditorFeatureProfile.xml
msgid ""
@@ -25384,6 +27376,9 @@ msgid ""
"by [code]class_name[/code]. When disabled, the class won't appear in the "
"Create New Node dialog."
msgstr ""
+"Si [code]disable[/code] est [code]true[/code], désactive la classe nommée "
+"[code]class_name[/code]. Lorsqu'elle est désactivée, la classe n'apparait "
+"pas dans le dialogue \"Créer un nouveau nœud\"."
#: doc/classes/EditorFeatureProfile.xml
msgid ""
@@ -25392,6 +27387,11 @@ msgid ""
"appear in the Create New Node dialog but the inspector will be read-only "
"when selecting a node that extends the class."
msgstr ""
+"Si [code]disable[/code] est [code]true[/code], désactive l'édition de la "
+"classe nommée [code]class_name[/code]. Lorsqu'elle est désactivée, la classe "
+"apparaîtra toujours dans le dialogue \"Créer un nouveau nœud\", mais "
+"l'inspecteur ne permettra pas de modifier ses propriétés pour les nœuds qui "
+"étendent cette classe."
#: doc/classes/EditorFeatureProfile.xml
msgid ""
@@ -25400,6 +27400,11 @@ msgid ""
"When a property is disabled, it won't appear in the inspector when selecting "
"a node that extends the class specified by [code]class_name[/code]."
msgstr ""
+"Si [code]disable[/code] est [code]true[/code], désactive l'édition de la "
+"[code]property[/code] dans la classe nommée [code]class_name[/code]. "
+"Lorsqu'une propriété est désactivée, elle n'apparaît plus dans l'inspecteur "
+"lors du choix d'un nœud qui étend la classe spécifiée par [code]class_name[/"
+"code]."
#: doc/classes/EditorFeatureProfile.xml
msgid ""
@@ -25485,6 +27490,11 @@ msgid ""
"For example, [code]\"*.tscn, *.scn; Scenes\"[/code] results in filter text "
"\"Scenes (*.tscn, *.scn)\"."
msgstr ""
+"Ajoute une option de filtrage d'extension de fichier délimitée par des "
+"virgules à [EditorFileDialog] avec une étiquette optionnelle délimitée par "
+"des point-virgules.\n"
+"Par exemple, [code]\"*.tscn, *.scn; Scenes\"[/code] donne le filtre \"Scenes "
+"(*.tscn, *.scn)\"."
#: doc/classes/EditorFileDialog.xml
msgid "Removes all filters except for \"All Files (*)\"."
@@ -25497,18 +27507,28 @@ msgid ""
"may cause a crash. If you wish to hide it or any of its children, use their "
"[member CanvasItem.visible] property."
msgstr ""
+"Retourne le [code]VBoxContainer[/code] utilisé pour afficher le système de "
+"fichiers.\n"
+"[b]Avertissement :[/b] Il s'agit d'un nœud requis en interne, l'enlever et "
+"le libérer peut causer un plantage. Si vous voulez le cacher lui ou un de "
+"ses enfants, utilisez la propriété [membre CanvasItem.visible]."
#: doc/classes/EditorFileDialog.xml
msgid ""
"Notify the [EditorFileDialog] that its view of the data is no longer "
"accurate. Updates the view contents on next view update."
msgstr ""
+"Notifie le [EditorFileDialog] que sa vue que son contenu n'est plus à jour. "
+"Mettre à jour le contenu de la vue sur la prochaine mise à jour de la vue."
#: doc/classes/EditorFileDialog.xml
msgid ""
"The location from which the user may select a file, including [code]res://[/"
"code], [code]user://[/code], and the local file system."
msgstr ""
+"L'emplacement à partir duquel l'utilisateur peut sélectionner un fichier, y "
+"compris [code]res://[/code], [code]user://[code], et le système de fichiers "
+"local."
#: doc/classes/EditorFileDialog.xml
msgid "The currently occupied directory."
@@ -25535,11 +27555,13 @@ msgid ""
"The view format in which the [EditorFileDialog] displays resources to the "
"user."
msgstr ""
+"Le format de vue dans lequel le [EditorFileDialog] affiche les ressources à "
+"l'utilisateur."
#: doc/classes/EditorFileDialog.xml
msgid ""
"The purpose of the [EditorFileDialog], which defines the allowed behaviors."
-msgstr ""
+msgstr "Le but du [EditorFileDialog], qui définit les comportements autorisés."
#: doc/classes/EditorFileDialog.xml
msgid ""
@@ -25566,6 +27588,8 @@ msgid ""
"The [EditorFileDialog] can select only one file. Accepting the window will "
"open the file."
msgstr ""
+"Le [EditorFileDialog] ne peut sélectionner qu'un seul fichier. Accepter "
+"cette fenêtre ouvrira le fichier sélectionné."
#: doc/classes/EditorFileDialog.xml
msgid ""
@@ -25580,6 +27604,8 @@ msgid ""
"The [EditorFileDialog] can select only one directory. Accepting the window "
"will open the directory."
msgstr ""
+"Le [EditorFileDialog] ne peut sélectionner qu'un seul dossier. Accepter la "
+"fenêtre ouvrira le dossier sélectionné."
#: doc/classes/EditorFileDialog.xml
msgid ""
@@ -25637,6 +27663,11 @@ msgid ""
"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
"the singleton using [method EditorInterface.get_resource_filesystem]."
msgstr ""
+"Cet objet contient des informations sur toutes les ressources du système de "
+"fichiers, leurs types, etc.\n"
+"[b]Note :[/b] Cette classe ne devrait pas être instanciée directement. "
+"Accédez plutôt à l'instance unique avec [method EditorInterface."
+"get_resource_filesystem]"
#: doc/classes/EditorFileSystem.xml
msgid ""
@@ -25644,6 +27675,10 @@ msgid ""
"string such as [code]\"Resource\"[/code] or [code]\"GDScript\"[/code], "
"[i]not[/i] a file extension such as [code]\".gd\"[/code]."
msgstr ""
+"Retourne le type de ressource du fichier, spécifié par le chemin complet. "
+"Ceci retourne une chaîne comme [code]\"Resource\"[/code] or "
+"[code]\"GDScript\"[/code], mais [i]pas[/i] l'extension du fichier comme "
+"[code]\".gd\"[/code]."
#: doc/classes/EditorFileSystem.xml
msgid "Gets the root directory object."
@@ -25658,6 +27693,8 @@ msgstr ""
#: doc/classes/EditorFileSystem.xml
msgid "Returns the scan progress for 0 to 1 if the FS is being scanned."
msgstr ""
+"Retourne la progression de l'analyse de 0 à 1 si le système de fichiers est "
+"en train d'être scanné."
#: doc/classes/EditorFileSystem.xml
#, fuzzy
@@ -25677,10 +27714,14 @@ msgid ""
"Update a file information. Call this if an external program (not Godot) "
"modified the file."
msgstr ""
+"Met à jour les informations du fichier. Appelez cette méthode si un "
+"programme externe (hors Godot) a modifié le fichier."
#: doc/classes/EditorFileSystem.xml
msgid "Scans the script files and updates the list of custom class names."
msgstr ""
+"Scanne les fichiers de script et met à jour la liste des noms de classe "
+"personnalisés."
#: doc/classes/EditorFileSystem.xml
msgid "Emitted if the filesystem changed."
@@ -25751,6 +27792,9 @@ msgid ""
"[code]idx[/code]. If the file doesn't define a script class using the "
"[code]class_name[/code] syntax, this will return an empty string."
msgstr ""
+"Retourne la classe de base de la classe de script définie dans le fichier à "
+"index [code]idx[/code]. Si le fichier ne définit pas une classe de script en "
+"utilisant la syntaxe [code]class_name[/code], une chaîne vide est retournée."
#: doc/classes/EditorFileSystemDirectory.xml
msgid ""
@@ -25758,6 +27802,9 @@ msgid ""
"code]. If the file doesn't define a script class using the [code]class_name[/"
"code] syntax, this will return an empty string."
msgstr ""
+"Retourne le nom de la classe script définie dans le fichier à index "
+"[code]idx[/code]. Si le fichier ne définit pas une classe de script en "
+"utilisant la syntaxe [code]class_name[/code], une chaîne vide est retournée."
#: doc/classes/EditorFileSystemDirectory.xml
msgid ""
@@ -25765,6 +27812,9 @@ msgid ""
"returns a string such as [code]\"Resource\"[/code] or [code]\"GDScript\"[/"
"code], [i]not[/i] a file extension such as [code]\".gd\"[/code]."
msgstr ""
+"Retourne le type de ressource du fichier à l'index [code]idx[/code]. Ceci "
+"retourne une chaîne comme [code]\"Resource\"[/code] or [code]\"GDScript\"[/"
+"code], mais [i]pas[/i] l'extension du fichier comme [code]\".gd\"[/code]."
#: doc/classes/EditorFileSystemDirectory.xml
msgid "Returns the name of this directory."
@@ -25795,6 +27845,9 @@ msgid ""
"Registers a custom resource importer in the editor. Use the class to parse "
"any file and import it as a new resource type."
msgstr ""
+"Enregistre un importateur de ressources personnalisée dans l'éditeur. "
+"Utilisez cette classe pour interpréter n'importe quel fichier pour "
+"l'importer comme nouveau type de ressource."
#: doc/classes/EditorImportPlugin.xml
msgid ""
@@ -25916,6 +27969,11 @@ msgid ""
"[code]default_value[/code], [code]property_hint[/code] (optional), "
"[code]hint_string[/code] (optional), [code]usage[/code] (optional)."
msgstr ""
+"Retourne les options et les valeurs par défaut pour le préréglage à cet "
+"index. Retourne un Array de Dictionnary avec les clés suivantes : "
+"[code]name[/code], [code]default_value[/code], [code]property_hint[/code] "
+"(optionnel), [code]hint_string[/code] (optionnel) et [code]usage[/code] "
+"(optionnel)."
#: doc/classes/EditorImportPlugin.xml
msgid ""
@@ -25926,6 +27984,13 @@ msgid ""
"code] unless overridden by a specific importer. See [enum ResourceImporter."
"ImportOrder] for some predefined values."
msgstr ""
+"Retourne l'ordre de lancement de cet importateur lors de l'importation de "
+"ressources. Les importateurs avec un ordre d'importation plus [i]bas[/i] "
+"seront appelés en premier, et des valeurs supérieures seront appelées après. "
+"Utilisez-le pour s'assurer que l'importateur fonctionne après l'importation "
+"des dépendances. L'ordre d'importation par défaut est [code]0[/code] à moins "
+"d'être remplacé par un importateur spécifique. Voir [enum ResourceImporter."
+"ImportOrder] pour certaines valeurs prédéfinies."
#: doc/classes/EditorImportPlugin.xml
msgid "Gets the unique name of the importer."
@@ -25969,6 +28034,9 @@ msgid ""
"get_import_options] to get the default options for the preset and [method "
"get_preset_name] to get the name of the preset."
msgstr ""
+"Retourne le nombre de préréglages initiaux définis par le greffon. Utilisez "
+"[method get_import_options] pour obtenir les options par défaut pour le "
+"préréglage et [method get_preset_name] pour obtenir son nom."
#: doc/classes/EditorImportPlugin.xml
msgid "Gets the name of the options preset at this index."
@@ -25979,12 +28047,17 @@ msgid ""
"Gets the priority of this plugin for the recognized extension. Higher "
"priority plugins will be preferred. The default priority is [code]1.0[/code]."
msgstr ""
+"Retourne la priorité de ce greffon pour l'extension reconnue. Des greffons "
+"le plus prioritaires seront préférés. La priorité par défaut est [code]1.0[/"
+"code]."
#: doc/classes/EditorImportPlugin.xml
msgid ""
"Gets the list of file extensions to associate with this loader (case-"
"insensitive). e.g. [code][\"obj\"][/code]."
msgstr ""
+"Retourne la liste des extensions de fichier à associer à ce chargeur "
+"(insensible à la casse). Par exemple [code][\"obj\"][/code]."
#: doc/classes/EditorImportPlugin.xml
msgid ""
@@ -26000,12 +28073,18 @@ msgid ""
"directory (see [member ProjectSettings.application/config/"
"use_hidden_project_data_directory])."
msgstr ""
+"Retourne l'extension utilisée pour sauvegarder cette ressource dans le "
+"dossier [code].import[/code] (voir [membre ProjectSettings.application/"
+"config/use_hidden_project_data_directory])."
#: doc/classes/EditorImportPlugin.xml
msgid ""
"Gets the name to display in the import window. You should choose this name "
"as a continuation to \"Import as\", e.g. \"Import as Special Mesh\"."
msgstr ""
+"Retourne le nom à afficher dans la fenêtre d'importation. Vous devriez "
+"choisir ce nom comme une suite à \"Importer comme\", par exemple \"Importer "
+"comme Maillage Spécial\"."
#: doc/classes/EditorImportPlugin.xml
msgid ""
@@ -26015,6 +28094,13 @@ msgid ""
"This method must be overridden to do the actual importing work. See this "
"class' description for an example of overriding this method."
msgstr ""
+"Importe [code]source_file[/code] dans [code]save_path[/code] avec l'option "
+"[code]options[/code] d'importation spécifié. Les tableaux "
+"[code]platform_variants[/code] et [code]gen_files[/code] seront modifiés par "
+"cette fonction.\n"
+"Cette méthode doit être surchargée pour exécuter le véritable travail "
+"d'importation. Voir la description de cette classe pour un exemple de "
+"surcharge de cette méthode."
#: doc/classes/EditorInspector.xml
#, fuzzy
@@ -26048,6 +28134,33 @@ msgid ""
"groups. So properties with group usage usually use capitalized names instead "
"of snake_cased names."
msgstr ""
+"Il s'agit du contrôle qui permet l'édition des propriétés dans les dialogues "
+"des Paramètres de l'éditeur, le dock Inspecteur, etc. Pour obtenir le "
+"[EditorInspector] utilisé dans le fichier d'inspecteur de l'éditeur, "
+"utilisez [method EditorInterface.get_inspector]\n"
+"[EditorInspector] affichera les propriétés dans le même ordre que le tableau "
+"retourné par [method Object.get_property_list]\n"
+"Si le nom d'un propriété établie est semblable à celui d'un chemin (c'est-à-"
+"dire s'il commence par des barres obliques), [EditorInspector] créera des "
+"sections imbriquées pour les « dossier » suivant le chemin. Par exemple, si "
+"une propriété est nommée [code]highlighting/gdscript/node_path_color[/code], "
+"elle sera affichée comme \"Node Path Color\" dans la section \"GDScript\" "
+"imbriquée dans la section \"Highlighting\".\n"
+"Si une propriété a l'usage [constant @GlobalScope.PROPERTY_USAGE_GROUP], "
+"elle regroupera les propriétés dont le nom commence par la chaîne d'indice "
+"de la propriété. Le groupe se termine quand une propriété ne commence pas "
+"avec cette chaîne d'indice ou quand un nouveau groupe commence. Un nom de "
+"groupe vide termine le groupe actuel. [EditorInspector] créera une section "
+"tout en haut pour chaque groupe. Par exemple, si une propriété avec "
+"l'utilisation de groupe est nommée [code]Collide With[/code] et que sa "
+"chaîne d'indice est [code]collide_with[/code], une propriété "
+"[code]collide_with_area[/code] suivante sera affichée comme \"Area\" dans la "
+"section \"Collide With\".\n"
+"[b]Note :[/b] Contrairement aux sections créées à partir de noms de "
+"propriété selon des chemins, [EditorInspector] a obtenu le nom de sections "
+"créées à partir de groupes. Ainsi, les propriétés avec l'utilisation de "
+"groupe utilisent généralement des noms capitalisés au lieu des noms en "
+"\"snake_case\"."
#: doc/classes/EditorInspector.xml
msgid ""
@@ -26057,16 +28170,24 @@ msgid ""
"code] editor setting hasn't passed yet since this method was last called. "
"(By default, this interval is set to 0.3 seconds.)"
msgstr ""
+"Actualise l'inspecteur.\n"
+"[b]Note :[/b] Pour économiser les ressources CPU, l'appel de cette méthode "
+"ne fera rien si le temps spécifié dans [code]docks/property_editor/"
+"auto_refresh_interval[/code] des réglages de l'éditeur n'a pas encore été "
+"écoulé depuis le dernier appel à cette méthode. (Par défaut, cet intervalle "
+"est de 0,3 secondes.)"
#: doc/classes/EditorInspector.xml
msgid ""
"Emitted when the Edit button of an [Object] has been pressed in the "
"inspector. This is mainly used in the remote scene tree inspector."
msgstr ""
+"Émis lorsque le bouton Edit d'un [Objet] a été pressé dans l'inspecteur. "
+"Ceci est principalement utilisé dans l'inspecteur d'une scène distante."
#: doc/classes/EditorInspector.xml
msgid "Emitted when a property is edited in the inspector."
-msgstr ""
+msgstr "Émis lorsqu'une propriété est modifiée dans l'inspecteur."
#: doc/classes/EditorInspector.xml
msgid ""
@@ -26074,10 +28195,13 @@ msgid ""
"by clicking the \"key\" icon next to a property when the Animation panel is "
"toggled."
msgstr ""
+"Émis lorsqu'une propriété est utilisée comme clé dans l'inspecteur. Les "
+"propriétés peuvent être utilisées comme clé en cliquant sur l'icône \"clé\" "
+"à côté d'une propriété lorsque le panneau \"Animation\" est ouvert."
#: doc/classes/EditorInspector.xml
msgid "Emitted when a property is selected in the inspector."
-msgstr ""
+msgstr "Émis lorsqu'une propriété est sélectionnée dans l'inspecteur."
#: doc/classes/EditorInspector.xml
msgid ""
@@ -26086,6 +28210,11 @@ msgid ""
"code] property enabled. Since this property is always enabled in the editor "
"inspector, this signal is never emitted by the editor itself."
msgstr ""
+"Émis lorsqu'une propriété booléenne est basculée dans l'inspecteur.\n"
+"[b]Note :[/b] Ce signal n'est jamais émis si la propriété interne "
+"[code]autoclear[/code] est activée. Comme cette propriété est toujours "
+"activée dans l'inspecteur de l'éditeur, ce signal n'est jamais émis par "
+"l'éditeur lui-même."
#: doc/classes/EditorInspector.xml
msgid "Emitted when a resource is selected in the inspector."
@@ -26140,18 +28269,24 @@ msgstr "Les greffons de l'inspecteur"
#: doc/classes/EditorInspectorPlugin.xml
msgid "Adds a custom control, which is not necessarily a property editor."
msgstr ""
+"Ajoute un contrôle personnalisé, qui n'est pas nécessairement un éditeur de "
+"propriété."
#: doc/classes/EditorInspectorPlugin.xml
msgid ""
"Adds a property editor for an individual property. The [code]editor[/code] "
"control must extend [EditorProperty]."
msgstr ""
+"Ajoute un éditeur de propriétés pour une seule propriété. Le contrôle "
+"[code]editor[/code] doit être une sous-classe de [EditorProperty]."
#: doc/classes/EditorInspectorPlugin.xml
msgid ""
"Adds an editor that allows modifying multiple properties. The [code]editor[/"
"code] control must extend [EditorProperty]."
msgstr ""
+"Ajoute un éditeur qui permet de modifier plusieurs propriétés. Le contrôle "
+"[code]editor[/code] doit être une sous-classe de [EditorProperty]."
#: doc/classes/EditorInspectorPlugin.xml
msgid "Returns [code]true[/code] if this object can be handled by this plugin."
@@ -26176,6 +28311,10 @@ msgid ""
"built-in editor for this property, otherwise allows to insert a custom "
"editor before the built-in one."
msgstr ""
+"Appelé pour autoriser l'ajout d'éditeurs spécifiques à la propriété dans "
+"l'inspecteur. Habituellement, ils héritent de [EditorProperty]. Retourner "
+"[code]true[/code] supprimera l'éditeur intégré pour cette propriété, c'est-à-"
+"dire que ça permet d'insérer un éditeur personnalisé avant l'éditeur intégré."
#: doc/classes/EditorInterface.xml
msgid "Godot editor's interface."
@@ -26191,18 +28330,31 @@ msgid ""
"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
"the singleton using [method EditorPlugin.get_editor_interface]."
msgstr ""
+"EditorInterface vous donne le contrôle de la fenêtre de l'éditeur Godot. Il "
+"permet de personnaliser la fenêtre, d'enregistrer et (re)charger des scènes, "
+"de faire des aperçus des mailles, d'inspecter et d'éditer des ressources et "
+"des objets, et fournit l'accès à [EditorSettings], [EditorFileSystem], "
+"[EditorResourcePreview], [ScriptEditor], la fenêtre d'affichage de l'éditeur "
+"et des informations sur les scènes.\n"
+"[b]Note :[/b] Cette classe ne doit pas être instanciée directement. Accédez "
+"plutôt au singleton en utilisant [method EditorPlugin.get_editor_interface]."
#: doc/classes/EditorInterface.xml
msgid ""
"Edits the given [Node]. The node will be also selected if it's inside the "
"scene tree."
msgstr ""
+"Édite le [Node] donné. Le nœud sera également sélectionné s'il s'agit d'une "
+"arborescence de scène."
#: doc/classes/EditorInterface.xml
msgid ""
"Edits the given [Resource]. If the resource is a [Script] you can also edit "
"it with [method edit_script] to specify the line and column position."
msgstr ""
+"Modifie la [Resource] donnée. Si la ressource est un [Script], vous pouvez "
+"également la modifier avec [method edit_script] en spécifiant la position de "
+"la ligne et de la colonne."
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26210,6 +28362,10 @@ msgid ""
"can also be specified. The script will be open with the user-configured "
"editor for the script's language which may be an external editor."
msgstr ""
+"Modifie le [Script]. La ligne et la colonne à laquelle ce script s'ouvre "
+"peut également être spécifiées. Le script sera ouvert avec l'éditeur "
+"configuré par l'utilisateur pour ce type de langage, où un éditeur externe "
+"peut être spécifié."
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26219,10 +28375,15 @@ msgid ""
"[b]Warning:[/b] Removing and freeing this node will render the editor "
"useless and may cause a crash."
msgstr ""
+"Retourne le conteneur principal de la fenêtre de l'éditeur de Godot. Par "
+"exemple, vous pouvez l'utiliser pour récupérer la taille du conteneur et "
+"placer vos contrôles en conséquence.\n"
+"[b]Avertissement :[/b] Enlever et libérer ce nœud rend l'éditeur inutile et "
+"peut causer un plantage."
#: doc/classes/EditorInterface.xml
msgid "Returns the current path being viewed in the [FileSystemDock]."
-msgstr ""
+msgstr "Retourne l'actuel chemin en train d'être vu dans le [FileSystemDock]."
#: doc/classes/EditorInterface.xml
msgid "Returns the edited (current) scene's root [Node]."
@@ -26237,6 +28398,13 @@ msgid ""
"code] and [code]interface/editor/custom_display_scale[/code] editor "
"settings. Editor must be restarted for changes to be properly applied."
msgstr ""
+"Retourne l'échelle actuelle de l'interface de l'éditeur ([code]1.0[/code] "
+"étant une échelle à 100%). Cela peut être utilisé pour régler la position et "
+"les dimensions des interfaces utilisateurs ajoutées par les greffons.\n"
+"[b]Note :[/b] Cette valeur est définie par [code]interface/editor/"
+"display_scale[/code] et [code]interface/editor/custom_display_scale[/code]. "
+"L'éditeur doit être redémarré pour que les changements soient complètement "
+"appliqués."
#: doc/classes/EditorInterface.xml
msgid "Returns the editor's [EditorSettings] instance."
@@ -26250,6 +28418,12 @@ msgid ""
"[b]Warning:[/b] Removing and freeing this node will render a part of the "
"editor useless and may cause a crash."
msgstr ""
+"Retourne le contrôle principal de l'éditeur. Utilisez-le comme parent pour "
+"les écrans principaux.\n"
+"[b]Note :[/b] Cela retourne le contrôle principal de l'éditeur contenant "
+"tout l'éditeur, pas seulement les vues 2D ou 3D.\n"
+"[b]Avertissement :[/b] Enlever et libérer ce nœud rendra une partie de "
+"l'éditeur inutile et peut causer un crash."
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26257,6 +28431,9 @@ msgid ""
"[b]Warning:[/b] Removing and freeing this node will render a part of the "
"editor useless and may cause a crash."
msgstr ""
+"Retourne l'instance [FileSystemDock] de l'éditeur.\n"
+"[b]Avertissement :[/b] Enlever et libérer ce nœud rendra une partie de "
+"l'éditeur inutile et peut causer un crash."
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26264,6 +28441,9 @@ msgid ""
"[b]Warning:[/b] Removing and freeing this node will render a part of the "
"editor useless and may cause a crash."
msgstr ""
+"Retourne l'instance [EditorInspector] de l'éditeur.\n"
+"[b]Avertissement :[/b] Enlever et libérer ce nœud rendra une partie de "
+"l'éditeur inutile et peut causer un crash."
#: doc/classes/EditorInterface.xml
msgid "Returns an [Array] with the file paths of the currently opened scenes."
@@ -26274,6 +28454,8 @@ msgid ""
"Returns the name of the scene that is being played. If no scene is currently "
"being played, returns an empty string."
msgstr ""
+"Retourne le nom de la scène qui est en train d'être jouée. Si aucune scène "
+"n'est actuellement jouée, retourne une chaîne vide."
#: doc/classes/EditorInterface.xml
msgid "Returns the editor's [EditorFileSystem] instance."
@@ -26289,6 +28471,9 @@ msgid ""
"[b]Warning:[/b] Removing and freeing this node will render a part of the "
"editor useless and may cause a crash."
msgstr ""
+"Retourne l'instance [ScriptEditor].\n"
+"[b]Avertissement :[/b] Enlever et libérer ce nœud rendra une partie de "
+"l'éditeur inutile et peut causer un crash."
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26296,6 +28481,9 @@ msgid ""
"[FileSystemDock]. If a file is selected, its base directory will be returned "
"using [method String.get_base_dir] instead."
msgstr ""
+"Retourne le chemin du dossier actuellement sélectionné dans le "
+"[FileSystemDock]. Si un fichier est sélectionné, son dossier de base sera "
+"retourné en utilisant [method String.get_base_dir]."
#: doc/classes/EditorInterface.xml
msgid "Returns the editor's [EditorSelection] instance."
@@ -26307,6 +28495,10 @@ msgid ""
"Inspector dock. If [code]inspector_only[/code] is [code]true[/code], plugins "
"will not attempt to edit [code]object[/code]."
msgstr ""
+"Affiche la propriété donnée sur le [code]object[/code] donné dans la barre "
+"d'outils de l'inspecteur de l'éditeur. Si [code]inspector_only[/code] est "
+"[code]true[/code], les greffons ne tenteront pas de modifier cet "
+"[code]object[/code]."
#: doc/classes/EditorInterface.xml
#, fuzzy
@@ -26380,6 +28572,10 @@ msgid ""
"([code]2D[/code], [code]3D[/code], [code]Script[/code], [code]AssetLib[/"
"code])."
msgstr ""
+"Spécifie l'écran principal courant de l'éditeur activé avec celui nommé "
+"[code]name[/code]. [code]name[/code] doit correspondre exactement au texte "
+"de l'onglet en question (soit [code]2D[/code], [code]3D[/code], "
+"[code]Script[/code], ou [code]AssetLib[/code])."
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26398,6 +28594,8 @@ msgid ""
"If [code]true[/code], enables distraction-free mode which hides side docks "
"to increase the space available for the main view."
msgstr ""
+"Si [code]true[/code], active le mode sans distraction qui cache les barres "
+"d'outils latérales pour augmenter l'espace disponible pour la vue principale."
#: doc/classes/EditorPlugin.xml
msgid "Used by the editor to extend its functionality."
@@ -26410,6 +28608,10 @@ msgid ""
"plugins and export plugins. See also [EditorScript] to add functions to the "
"editor."
msgstr ""
+"Les greffons sont utilisés par l'éditeur pour étendre les fonctionnalités. "
+"Les types les plus courants de greffons sont ceux qui modifient un nœud "
+"donné ou un type de ressource, les greffons d'importation et d'exportation. "
+"Voir aussi [EditorScript] pour ajouter des fonctions à l'éditeur."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26431,7 +28633,7 @@ msgstr ""
"vous de masquer le bouton si besoin. Lorsque votre greffon est désactivé, "
"assurez-vous de supprimer votre contrôle personnalisé avec [method "
"remove_control_from_bottom_panel] et de le libérer avec [method Node."
-"queue_free]"
+"queue_free]."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26452,7 +28654,7 @@ msgstr ""
"personnalisés vous-même (et probablement le cacher après l'avoir ajouté).\n"
"Lorsque votre greffon est désactivé, assurez-vous de supprimer votre "
"contrôle personnalisé avec [method remove_control_from_container] et de le "
-"libérer avec [method Node.queue_free]"
+"libérer avec [method Node.queue_free]."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26469,7 +28671,7 @@ msgstr ""
"l'éditeur enregistrera la position du dock pour d'autres sessions.\n"
"Lorsque votre greffon est désactivé, assurez-vous de supprimer votre "
"contrôle personnalisé avec [method remove_control_from_container] et de le "
-"libérer avec [method Node.queue_free]"
+"libérer avec [method Node.queue_free]."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26566,6 +28768,9 @@ msgid ""
"Registers a new [EditorSceneImporter]. Scene importers are used to import "
"custom 3D asset formats as scenes."
msgstr ""
+"Enregistre un nouveau [EditorSceneImporter]. Les importateurs de scène sont "
+"utilisés pour importer des formats d'éléments 3D personnalisés comme des "
+"scènes."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26573,6 +28778,11 @@ msgid ""
"custom gizmos to the 3D preview viewport for a [Spatial].\n"
"See [method add_inspector_plugin] for an example of how to register a plugin."
msgstr ""
+"Enregistre un nouveau [EditorSpatialGizmoPlugin]. Les greffons du "
+"manipulateur sont utilisés pour ajouter des manipulateurs personnalisés dans "
+"la fenêtre d'affichage 3D pour transformer un [Spatial].\n"
+"Voir [method add_inspector_greffon] pour un exemple sur comment enregistrer "
+"un greffon."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26596,6 +28806,13 @@ msgid ""
"This is used, for example, in shader editors to let the plugin know that it "
"must apply the shader code being written by the user to the object."
msgstr ""
+"Cette méthode est appelée lorsque l'éditeur est sur le point d'enregistrer "
+"le projet, passer à un autre onglet, etc. Il demande au greffon d'appliquer "
+"tout changement d'état qui serait en attente pour garder une certaine "
+"cohérence.\n"
+"Ceci est utilisé, par exemple, dans les éditeurs d'ombres pour signaler au "
+"greffon qu'il doit appliquer le shader d'ombre écrit par l'utilisateur à "
+"l'objet."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26605,6 +28822,13 @@ msgid ""
"code], the project will not run. The run is aborted immediately, so this "
"also prevents all other plugins' [method build] methods from running."
msgstr ""
+"Cette méthode est appelée lorsque l'éditeur est sur le point de lancer le "
+"projet. Le greffon peut ensuite effectuer les opérations requises avant le "
+"lancement du projet.\n"
+"Cette méthode doit retourner un booléen. Si cette méthode retourne "
+"[code]false[/code], le projet ne sera pas lancé. Le lancement sera "
+"immédiatement annulé, ce qui empêche également toutes les autres méthodes de "
+"fonctionnement des greffons."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26612,24 +28836,34 @@ msgid ""
"your plugin does not keep editing a currently existing node, or a node from "
"the wrong scene."
msgstr ""
+"Efface tout l'état et réinitialise à zéro l'objet modifié. Cela garantit que "
+"votre greffon ne maintient pas l'édition d'un nœud existant ou d'une autre "
+"scène."
#: doc/classes/EditorPlugin.xml
msgid ""
"Called by the engine when the user disables the [EditorPlugin] in the Plugin "
"tab of the project settings window."
msgstr ""
+"Appelé par le moteur lorsque l'utilisateur désactive le [EditorPlugin] dans "
+"l'onglet Greffon de la fenêtre des paramètres du projet."
#: doc/classes/EditorPlugin.xml
msgid ""
"This function is used for plugins that edit specific object types (nodes or "
"resources). It requests the editor to edit the given object."
msgstr ""
+"Cette fonction est utilisée pour les greffons qui modifient des types "
+"d'objets spécifiques (nœuds ou ressources). Il demande à l'éditeur de "
+"modifier l'objet spécifié."
#: doc/classes/EditorPlugin.xml
msgid ""
"Called by the engine when the user enables the [EditorPlugin] in the Plugin "
"tab of the project settings window."
msgstr ""
+"Appelé par le moteur lorsque l'utilisateur active le [EditorPlugin] dans "
+"l'onglet Greffon de la fenêtre des paramètres du projet."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26676,6 +28910,11 @@ msgid ""
"You need to enable calling of this method by using [method "
"set_force_draw_over_forwarding_enabled]."
msgstr ""
+"Cette méthode est la même que [method forward_canvas_draw_over_viewport], "
+"sauf qu'elle est dessinée au-dessus de tout le reste. Utile quand vous avez "
+"besoin d'une calque supplémentaire qui s'affiche par dessus les autres.\n"
+"Vous devez activer l'appel de cette méthode en utilisant [method "
+"set_force_draw_over_forwarding_enabled]."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26766,6 +29005,11 @@ msgid ""
"You need to enable calling of this method by using [method "
"set_force_draw_over_forwarding_enabled]."
msgstr ""
+"Cette méthode est la même que [method forward_spatial_draw_over_viewport], "
+"sauf qu'elle est dessinée au-dessus de tout le reste. Utile quand vous avez "
+"besoin d'une calque supplémentaire qui s'affiche par dessus les autres.\n"
+"Vous devez activer l'appel de cette méthode en utilisant [method "
+"set_force_draw_over_forwarding_enabled]."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26819,6 +29063,9 @@ msgid ""
"breakpoints in the format ([code]script:line[/code]), for example: "
"[code]res://path_to_script.gd:25[/code]."
msgstr ""
+"C'est pour les éditeurs qui modifient des objets basés sur des scripts. Vous "
+"pouvez retourner une liste de points d'arrêt avec le format ([code]script:"
+"line[/code]), par exemple : [code]res://path_to_script.gd:25[/code]."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26904,6 +29151,25 @@ msgid ""
" return state\n"
"[/codeblock]"
msgstr ""
+"Surchargez cette méthode pour fournir des données d'état que vous souhaitez "
+"enregistrer, comme la position de la vue, les paramètres de grille, les "
+"réductions, etc. Ceci est utilisé pour enregistrer la scène (ainsi l'état "
+"est maintenu lors de l'ouverture suivante) et pour les onglets (pour que "
+"l'état soit restauré quand l'onglet est ouvert à nouveau). Ces données sont "
+"automatiquement sauvegardées pour chaque scène dans un fichier "
+"[code]editstate[/code] dans le dossier de métadonnées de l'éditeur. Si vous "
+"souhaitez stocker des données globales (indépendantes de la scène) pour "
+"votre greffon, utilisez plutôt [method get_window_layout].\n"
+"Utilisez [method set_state] pour restaurer votre état sauvegardé.\n"
+"[b]Note :[/b] Cette méthode ne devrait pas être utilisée pour sauvegarder "
+"des paramètres importants qui devraient persister dans le projet.\n"
+"[b]Note :[/b] Vous devez implémenter [method get_greffon_name] pour que "
+"l'état soit stocké et restauré correctement.\n"
+"[codeblock]\n"
+"func get_state():\n"
+" var state = {\"zoom\": zoom, \"preferred_color\": my_color}\n"
+" return state\n"
+"[/codeblock]"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26929,6 +29195,21 @@ msgid ""
" configuration.set_value(\"MyPlugin\", \"icon_color\", $Icon.modulate)\n"
"[/codeblock]"
msgstr ""
+"Surchargez cette méthode pour fournir la mise en page de l'interface du "
+"greffon ou toute autre donnée que vous souhaitez enregistrer. Ceci est "
+"utilisé pour sauvegarder la mise en page de l'éditeur du projet lorsque "
+"[method queue_save_layout] est appelée ou la mise en page de l'éditeur a été "
+"modifiée (par exemple, changer la position d'un dock). Les données sont "
+"enregistrées dans le fichier [code]editor_layout.cfg[/code] dans le dossier "
+"des métadonnées de l'éditeur.\n"
+"Utilisez [method set_window_layout] pour restaurer la mise en page qui a été "
+"sauvegardée.\n"
+"[codeblock]\n"
+"func get_window_layout(configuration):\n"
+" configuration.set_value(\"MyPlugin\", \"window_position\", $Window."
+"position)\n"
+" configuration.set_value(\"MyPlugin\", \"icon_color\", $Icon.modulate)\n"
+"[/codeblock]"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26954,7 +29235,7 @@ msgid ""
msgstr ""
"Retourne [code]true[/code] si c'est ce greffon de l'éditeur concerne l'écran "
"principal (qui va dans le sélecteur d'espace de travail à côté de [b]2D[/b], "
-"[b]3D[/b], [b]Script[/b] et [b]AssetLib[/b)]."
+"[b]3D[/b], [b]Script[/b] et [b]AssetLib[/b])."
#: doc/classes/EditorPlugin.xml
msgid "Minimizes the bottom panel."
@@ -26971,6 +29252,11 @@ msgid ""
"Remember that you have to manage the visibility of all your editor controls "
"manually."
msgstr ""
+"Cette fonction sera appelée lorsqu'il est demandé à l'éditeur de devenir "
+"visible. Il est utilisé pour les greffons qui modifient un type d'objet "
+"spécifique.\n"
+"Rappelez-vous que vous devez gérer manuellement la visibilité de tous les "
+"contrôles de votre éditeur."
#: doc/classes/EditorPlugin.xml
msgid "Queue save the project's editor layout."
@@ -27043,6 +29329,9 @@ msgid ""
"This method is called after the editor saves the project or when it's "
"closed. It asks the plugin to save edited external scenes/resources."
msgstr ""
+"Cette méthode est appelée après que l'éditeur enregistre le projet ou "
+"lorsqu'il est fermé. Il demande au greffon d'enregistrer les scènes et "
+"ressources externes modifiées."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -27051,6 +29340,11 @@ msgid ""
"editor when their viewports are updated. You need to call this method only "
"once and it will work permanently for this plugin."
msgstr ""
+"Permet d'appeler [method forward_canvas_force_draw_over_viewport] pour "
+"l'éditeur 2D et [method forward_spatial_force_draw_over_viewport] pour "
+"l'éditeur 3D lorsque leurs fenêtres d'affichage sont mises à jour. Vous "
+"devez appeler cette méthode qu'une seule fois, et ça fonctionnera en "
+"permanence pour ce greffon."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -27058,6 +29352,9 @@ msgid ""
"inside [method forward_spatial_gui_input]. It might be especially usable if "
"your plugin will want to use raycast in the scene."
msgstr ""
+"Utilisez cette méthode si vous voulez toujours recevoir les entrées dans "
+"l'écran d'aperçu 3D dans [method forward_spatial_gui_input]. Ça peut être "
+"utile si votre greffon veut utiliser un Raycast dans la scène."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -27071,6 +29368,15 @@ msgid ""
" preferred_color = data.get(\"my_color\", Color.white)\n"
"[/codeblock]"
msgstr ""
+"Restaure l'état enregistrée par [méthode get_state]. Cette méthode est "
+"appelée lorsque l'onglet de scène actuelle est changé dans l'éditeur.\n"
+"[b]Note :[/b] Votre greffon doit implémenter [method get_greffon_name], "
+"sinon il ne sera pas reconnu et cette méthode ne sera pas appelée.\n"
+"[codeblock]\n"
+"func set_state(data):\n"
+" zoom = data.get(\"zoom\", 1.0)\n"
+" preferred_color = data.get(\"my_color\", Color.white)\n"
+"[/codeblock]"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -27085,6 +29391,17 @@ msgid ""
"Color.white)\n"
"[/codeblock]"
msgstr ""
+"Restaurer la disposition de l'interface du greffon et les données "
+"enregistrées par [method get_window_layout]. Cette méthode est appelée pour "
+"chaque greffon au démarrage de l'éditeur. Utilisez le fichier "
+"[code]configuration[/code] pour lire vos données sauvegardées.\n"
+"[codeblock]\n"
+"func set_window_layout(configuration):\n"
+" $Window.position = configuration.get_value(\"MyPlugin\", "
+"\"window_position\", Vector2())\n"
+" $Icon.modulate = configuration.get_value(\"MyPlugin\", \"icon_color\", "
+"Color.white)\n"
+"[/codeblock]"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -27094,6 +29411,11 @@ msgid ""
"forward_spatial_draw_over_viewport] and [method "
"forward_spatial_force_draw_over_viewport] to be called."
msgstr ""
+"Met à jour des sur-couches de l'éditeur 2D et 3D. Fait que les méthodes "
+"[method forward_canvas_draw_over_viewport], [method "
+"forward_canvas_force_draw_over_viewport], [method "
+"forward_spatial_draw_over_viewport] et [method "
+"forward_spatial_force_draw_over_port] seront appelées."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -27110,6 +29432,9 @@ msgid ""
"the root node of the scene that has just become active. If this scene is new "
"and empty, the argument will be [code]null[/code]."
msgstr ""
+"Émis lorsque la scène est changée dans l'éditeur. L'argument retournera le "
+"nœud racine de la scène qui vient de devenir active. Si cette scène est "
+"nouvelle et vide, l'argument sera [code]null[/code]."
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -27141,6 +29466,8 @@ msgid ""
"If any of the controls added can gain keyboard focus, add it here. This "
"ensures that focus will be restored if the inspector is refreshed."
msgstr ""
+"Si l'un des contrôles ajoutés peut récupérer le focus du clavier, ajoutez-le "
+"ici. Cela permettra de rétablir le focus si l'inspecteur est mis à jour."
#: doc/classes/EditorProperty.xml
msgid ""
@@ -27150,6 +29477,11 @@ msgid ""
"requesting this property to be refreshed (leave as [code]false[/code] if "
"unsure)."
msgstr ""
+"Si une ou plusieurs propriétés ont changé, cela doit être appelé. "
+"[code]field[/code] est utilisé au cas où votre éditeur peut modifier les "
+"champs séparément (par exemple : Vector3.x) L'argument [code]changing[/code] "
+"évite à l'éditeur de demander que cette propriété soit rafraîchie (laissez-"
+"le à [code]false[/code] en cas de doute)."
#: doc/classes/EditorProperty.xml
msgid "Gets the edited object."
@@ -27161,16 +29493,23 @@ msgid ""
"[method EditorInspectorPlugin.parse_property]), then this will return the "
"property."
msgstr ""
+"Retourne la propriété modifiée. Si votre éditeur n'est que pour une seule "
+"propriété (ajouté par [method EditorInspectorPlugin.parse_property]), cela "
+"retournera la propriété."
#: doc/classes/EditorProperty.xml
msgid "Must be implemented to provide a custom tooltip to the property editor."
msgstr ""
+"Doit être implémenté pour fournir un outil personnalisé dans l'éditeur de "
+"propriété."
#: doc/classes/EditorProperty.xml
msgid ""
"Puts the [code]editor[/code] control below the property label. The control "
"must be previously added using [method Node.add_child]."
msgstr ""
+"Place le contrôle [code]editor[/code] sous le label de la propriété. Le "
+"contrôle doit d'abord être ajouté avec [method Node.add_child]"
#: doc/classes/EditorProperty.xml
msgid "When this virtual function is called, you must update your editor."
@@ -27183,11 +29522,15 @@ msgid ""
"Used by the inspector, set to [code]true[/code] when the property is "
"checkable."
msgstr ""
+"Utilisé par l'inspecteur, défini à [code]true[/code] lorsque la propriété "
+"peut être cochée."
#: doc/classes/EditorProperty.xml
msgid ""
"Used by the inspector, set to [code]true[/code] when the property is checked."
msgstr ""
+"Utilisé par l'inspecteur, défini à [code]true[/code] quand la propriété est "
+"cochée."
#: doc/classes/EditorProperty.xml
msgid ""
@@ -27195,6 +29538,9 @@ msgid ""
"with the editor theme's warning color. This is used for editable children's "
"properties."
msgstr ""
+"Utilisé par l'inspecteur, définit à [code]true[/code] quand la propriété est "
+"affiché avec la couleur d'avertissement de l'éditeur. Ceci est utilisé pour "
+"les propriétés modifiables pour les nœuds enfants."
#: doc/classes/EditorProperty.xml
msgid ""
@@ -27215,16 +29561,23 @@ msgid ""
"Used by the inspector, set to [code]true[/code] when the property is read-"
"only."
msgstr ""
+"Utilisé par l'inspecteur, défini à [code]true[/code] quand la propriété est "
+"en lecture-seule."
#: doc/classes/EditorProperty.xml
msgid ""
"Emit it if you want multiple properties modified at the same time. Do not "
"use if added via [method EditorInspectorPlugin.parse_property]."
msgstr ""
+"Emettez-le si vous voulez plusieurs propriétés modifiées en même temps. Ne "
+"pas utiliser s'il a été ajouté avec [method EditorInspectorPlugin."
+"parse_property]"
#: doc/classes/EditorProperty.xml
msgid "Used by sub-inspectors. Emit it if what was selected was an Object ID."
msgstr ""
+"Utilisé par des sous-inspecteurs. Émettez-le si l'identifiant d'un Object a "
+"été sélectionné."
#: doc/classes/EditorProperty.xml
msgid ""
@@ -27242,10 +29595,14 @@ msgid ""
"Emit it if you want to add this value as an animation key (check for keying "
"being enabled first)."
msgstr ""
+"Émettez-le si vous voulez ajouter cette valeur comme clé d'animation "
+"(vérifiez que la clé est d'abord activée)."
#: doc/classes/EditorProperty.xml
msgid "Emit it if you want to key a property with a single value."
msgstr ""
+"Emettez-le si vous voulez définir une clé pour cette propriété avec une "
+"valeur unique."
#: doc/classes/EditorProperty.xml
msgid ""
@@ -27255,6 +29612,11 @@ msgid ""
"instantiated and can come from an ancestor scene in the inheritance/"
"instancing chain, a script or a builtin class."
msgstr ""
+"Émettez-le si vous voulez marquer (ou dé-marquer) la valeur d'une propriété "
+"pour être sauvegardée peu importe si elle est égale à la valeur par défaut.\n"
+"La valeur par défaut est celle que la propriété obtiendra lorsque le nœud "
+"est juste instancié et peut venir d'une scène instanciée ou héritée, d'un "
+"script ou d'une classe intégrée."
#: doc/classes/EditorProperty.xml
msgid ""
@@ -27282,6 +29644,13 @@ msgid ""
"[b]Note:[/b] This [Control] does not include any editor for the resource, as "
"editing is controlled by the Inspector dock itself or sub-Inspectors."
msgstr ""
+"Ce nœud [Control] est utilisé dans la barre d'outils de l'inspecteur de "
+"l'éditeur pour permettre l'édition des propriétés de type [Resource]. Il "
+"offre des options pour créer, charger, enregistrer et convertir des "
+"ressources. Peut être utilisé avec [EditorInspectorPlugin] pour recréer le "
+"même comportement.\n"
+"[b]Note :[/b] Ce [Control] n'inclut aucun éditeur de la ressource, car "
+"l'édition est contrôlée par l'inspecteur lui-même ou les sous-inspecteurs."
#: doc/classes/EditorResourcePicker.xml
msgid ""
@@ -27289,12 +29658,17 @@ msgid ""
"[member base_type]. If the [member base_type] is empty, an empty list is "
"returned."
msgstr ""
+"Retourne une liste de tous les types et sous-types autorisés correspondant "
+"au [member base_type]. Si le [member base_type] est vide, une liste vide est "
+"retournée."
#: doc/classes/EditorResourcePicker.xml
msgid ""
"This virtual method can be implemented to handle context menu items not "
"handled by default. See [method set_create_options]."
msgstr ""
+"Cette méthode virtuelle peut être implémentée pour gérer les éléments du "
+"menu contextuel non gérés par défaut. Voir [method set_create_options]."
#: doc/classes/EditorResourcePicker.xml
msgid ""
@@ -27305,12 +29679,20 @@ msgid ""
"[b]Note:[/b] Implement [method handle_menu_selected] to handle these custom "
"items."
msgstr ""
+"Cette méthode virtuelle est appelée lors de la mise à jour du menu "
+"contextuel de [EditorResourcePicker]. Implémenter cette méthode pour "
+"remplacer les éléments dans « Nouveau... » par vos propres options. "
+"[code]menu_nœud[/code] est une référence au nœud [PopupMenu].\n"
+"[b]Note :[/b] Implémentez [method handle_menu_sélection] pour traiter ces "
+"éléments personnalisés."
#: doc/classes/EditorResourcePicker.xml
msgid ""
"Sets the toggle mode state for the main button. Works only if [member "
"toggle_mode] is set to [code]true[/code]."
msgstr ""
+"Définit l'état du mode de basculement pour le bouton principal. Fonctionne "
+"uniquement si [member toggle_mode] est défini à [code]true[/code]."
#: doc/classes/EditorResourcePicker.xml
msgid ""
@@ -27333,6 +29715,9 @@ msgid ""
"If [code]true[/code], the main button with the resource preview works in the "
"toggle mode. Use [method set_toggle_pressed] to manually set the state."
msgstr ""
+"Si [code]true[/code], le bouton principal avec la prévisualisation des "
+"ressources fonctionne avec le mode de basculement. Utilisez [method "
+"set_toggle_pressed] pour définir manuellement cet état."
#: doc/classes/EditorResourcePicker.xml
#, fuzzy
@@ -27345,6 +29730,9 @@ msgid ""
"[code]edit[/code] is [code]true[/code], the signal was caused by the context "
"menu \"Edit\" option."
msgstr ""
+"Émis lorsque la valeur de ressource a été définie et que l'utilisateur a "
+"cliqué pour la modifier. Lorsque [code]edit[/code] est [code]true[/code], le "
+"signal a été causé par le menu contextuel \"Édition\"."
#: doc/classes/EditorResourcePreview.xml
msgid "Helper to generate previews of resources or files."
@@ -27356,6 +29744,11 @@ msgid ""
"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
"the singleton using [method EditorInterface.get_resource_previewer]."
msgstr ""
+"Cet objet est utilisé pour générer des aperçus pour les ressources de "
+"fichiers.\n"
+"[b]Note :[/b] Cette classe ne devrait pas être instanciée directement. "
+"Accédez plutôt à l'instance unique en utilisant [method EditorInterface."
+"get_resource_previewer]"
#: doc/classes/EditorResourcePreview.xml
msgid "Create an own, custom preview generator."
@@ -27366,6 +29759,8 @@ msgid ""
"Check if the resource changed, if so, it will be invalidated and the "
"corresponding signal emitted."
msgstr ""
+"Vérifiez si la ressource a changé, si oui, elle sera invalidée et le signal "
+"correspondant émis."
#: doc/classes/EditorResourcePreview.xml
msgid ""
@@ -27425,6 +29820,8 @@ msgid ""
"Emitted if a preview was invalidated (changed). [code]path[/code] "
"corresponds to the path of the preview."
msgstr ""
+"Émis si un aperçu a été invalidé (c'est-à-dire changé). [code]path[/code] "
+"correspond au chemin de l'aperçu."
#: doc/classes/EditorResourcePreviewGenerator.xml
msgid "Custom generator of previews."
@@ -27436,6 +29833,9 @@ msgid ""
"thumbnail_size[/code] in [EditorSettings] to find out the right size to do "
"previews at."
msgstr ""
+"Le Code personnalisé pour générer des aperçus. Veuillez cocher "
+"[code]file_dialog/thumbnail_size[/code] dans [EditorSettings] pour connaître "
+"la taille correcte des prévisualisations."
#: doc/classes/EditorResourcePreviewGenerator.xml
msgid ""
@@ -27443,6 +29843,10 @@ msgid ""
"generate] or [method generate_from_path] for small previews as well.\n"
"By default, it returns [code]false[/code]."
msgstr ""
+"Si cette fonction retourne [code]true[/code], le générateur appellera "
+"[method generate] ou [method generate_from_path] pour les aperçus de petite "
+"taille.\n"
+"Par défaut, il retourne [code]false[/code]."
#: doc/classes/EditorResourcePreviewGenerator.xml
msgid ""
@@ -27453,6 +29857,12 @@ msgid ""
"Care must be taken because this function is always called from a thread (not "
"the main thread)."
msgstr ""
+"Génère un aperçu d'une ressource donnée avec la taille spécifiée. Cela doit "
+"toujours être implémenté.\n"
+"Retourner une texture vide est une bonne façon de signaler un échec et "
+"laisser un autre générateur s'occuper de l'aperçu.\n"
+"Ça nécessite de prendre des précautions parce que cette fonction est "
+"toujours appelée à partir d'un fil d'exécution qui n'est pas celui principal."
#: doc/classes/EditorResourcePreviewGenerator.xml
msgid ""
@@ -27464,6 +29874,13 @@ msgid ""
"Care must be taken because this function is always called from a thread (not "
"the main thread)."
msgstr ""
+"Génère un aperçu directement à partir d'un chemin avec la taille spécifiée. "
+"La mise en œuvre est facultative, car le code par défaut va charger et "
+"appeler [method generate].\n"
+"Retourner une texture vide est une bonne façon de signaler un échec et "
+"laisser un autre générateur s'occuper de l'aperçu.\n"
+"Ça nécessite de prendre des précautions parce que cette fonction est "
+"toujours appelée à partir d'un fil d'exécution qui n'est pas celui principal."
#: doc/classes/EditorResourcePreviewGenerator.xml
msgid ""
@@ -27472,6 +29889,11 @@ msgid ""
"methods [method generate] or [method generate_from_path].\n"
"By default, it returns [code]false[/code]."
msgstr ""
+"Si cette fonction retourne [code]true[/code], le générateur générera "
+"automatiquement les petits aperçus à partir de la texture de "
+"prévisualisation de taille normale générée par les méthodes [method "
+"generate] ou [method generate_from_path].\n"
+"Par défaut, elle retourne [code]false[/code]."
#: doc/classes/EditorResourcePreviewGenerator.xml
msgid ""
@@ -27492,6 +29914,10 @@ msgid ""
"To use [EditorSceneImporter], register it using the [method EditorPlugin."
"add_scene_import_plugin] method first."
msgstr ""
+"[EditorSceneImporter] permet de définir un script importateur pour un format "
+"3D tiers.\n"
+"Pour utiliser [EditorSceneImporter], enregistrez-le d'abord en utilisant la "
+"méthode [method EditorPlugin.add_scene_import_greffon]."
#: modules/fbx/doc_classes/EditorSceneImporterFBX.xml
msgid "FBX 3D asset importer."
@@ -27532,6 +29958,10 @@ msgid ""
"to [EditorSceneImporterGLTF] within a script will cause an error in an "
"exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les éditeurs. Le "
+"chargement et l'enregistrement au format glTF [i]n'est pas[/i] disponible "
+"dans les projets exportés. Les références à [EditorSceneImporterGLTF] dans "
+"un script provoquent une erreur dans un projet exporté."
#: doc/classes/EditorScenePostImport.xml
msgid "Post-processes scenes after import."
@@ -27608,6 +30038,8 @@ msgid ""
"Called after the scene was imported. This method must return the modified "
"version of the scene."
msgstr ""
+"Appelé après l'importation de la scène. Cette méthode doit retourner la "
+"version modifiée de la scène."
#: doc/classes/EditorScript.xml
msgid "Base script that can be used to add extension functions to the editor."
@@ -27664,6 +30096,10 @@ msgid ""
"Adds [code]node[/code] as a child of the root node in the editor context.\n"
"[b]Warning:[/b] The implementation of this method is currently disabled."
msgstr ""
+"Ajoute [code]node[/code] comme enfant du nœud racine dans le contexte de "
+"l'éditeur.\n"
+"[b]Avertissement :[/b] L'implémentation de cette méthode est actuellement "
+"désactivée."
#: doc/classes/EditorScript.xml
msgid "Returns the [EditorInterface] singleton instance."
@@ -27678,6 +30114,8 @@ msgid ""
"Godot editor's control for selecting the [code]script[/code] property of a "
"[Node]."
msgstr ""
+"Le contrôle de l'éditeur Godot pour sélectionner la propriété [code]script[/"
+"code] d'un [Node]."
#: doc/classes/EditorScriptPicker.xml
msgid ""
@@ -27714,6 +30152,10 @@ msgid ""
"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
"the singleton using [method EditorInterface.get_selection]."
msgstr ""
+"Cet objet gère la sélection dans le SceneTree dans l'éditeur.\n"
+"[b]Note :[/b] Cette classe ne devrait pas être instanciée directement. "
+"Accédez plutôt à l'instance unique en utilisant [method EditorInterface."
+"get_selection]"
#: doc/classes/EditorSelection.xml
msgid ""
@@ -27722,6 +30164,10 @@ msgid ""
"inspector. If you want to edit a node, use [method EditorInterface."
"edit_node]."
msgstr ""
+"Ajoute un nœud à la sélection.\n"
+"[b]Note :[/b] Le nouveau nœud sélectionné ne sera pas automatiquement "
+"modifié dans l'inspecteur. Si vous souhaitez modifier un nœud, utilisez "
+"[method EditorInterface.edit_nœud]."
#: doc/classes/EditorSelection.xml
msgid "Clear the selection."
@@ -27737,6 +30183,10 @@ msgid ""
"moving them, rotating, etc). This list avoids situations where a node is "
"selected and also child/grandchild."
msgstr ""
+"Retourne la liste des nœuds sélectionnés, optimisés pour les opérations de "
+"transformation (c'est-à-dire le fait de les déplacer, les faire pivoter, "
+"etc.). Cette liste évite les situations où un nœud est sélectionné et mais "
+"aussi ses descendants."
#: doc/classes/EditorSelection.xml
msgid "Removes a node from the selection."
@@ -27794,7 +30244,7 @@ msgstr ""
"var list_of_settings = settings.get_property_list()\n"
"[/codeblock]\n"
"[b]Note :[/b] Cette classe ne devrait être pas instanciée. Accédez plutôt au "
-"singleton [method EditorInterface.get_editor_settings]"
+"singleton [method EditorInterface.get_editor_settings]."
#: doc/classes/EditorSettings.xml
msgid ""
@@ -27851,6 +30301,10 @@ msgid ""
"[code]key[/code] specified. If the metadata doesn't exist, [code]default[/"
"code] will be returned instead. See also [method set_project_metadata]."
msgstr ""
+"Retourne les métadonnées spécifiques au projet pour la [code]section[/code] "
+"et [code]key[/code] spécifiées. Si les métadonnées n'existent pas, "
+"[code]default[/code] sera retourné à la place. Voir aussi [method "
+"set_project_metadata]."
#: doc/classes/EditorSettings.xml
msgid ""
@@ -27875,6 +30329,8 @@ msgid ""
"Returns the value of the setting specified by [code]name[/code]. This is "
"equivalent to using [method Object.get] on the EditorSettings instance."
msgstr ""
+"Retourne la valeur du paramètre spécifié par [code]name[/code]. Ceci est "
+"équivalent à l'utiliser [method Object.get] sur l'instance EditorSettings."
#: doc/classes/EditorSettings.xml
msgid ""
@@ -27904,6 +30360,10 @@ msgid ""
"When this method returns [code]true[/code], a Revert button will display "
"next to the setting in the Editor Settings."
msgstr ""
+"Retourne [code]true[/code] si le paramètre spécifié par [code]name[/code] "
+"peut avoir sa valeur rétablie à cette par défaut, ou [code]false[/code] "
+"sinon. Lorsque cette méthode retourne [code]true[/code], un bouton Rétablir "
+"s'affichera à côté du réglage dans les paramètres de l'éditeur."
#: doc/classes/EditorSettings.xml
msgid ""
@@ -27911,6 +30371,9 @@ msgid ""
"This is the value that would be applied when clicking the Revert button in "
"the Editor Settings."
msgstr ""
+"Retourne la valeur par défaut du paramètre spécifié par [code]name[/code]. "
+"C'est la valeur qui sera appliquée en cliquant sur le bouton Rétablir dans "
+"les paramètres de l'éditeur."
#: doc/classes/EditorSettings.xml
msgid "Sets the list of favorite files and directories for this project."
@@ -27936,6 +30399,11 @@ msgid ""
"project folder and therefore won't be checked into version control. See also "
"[method get_project_metadata]."
msgstr ""
+"Définit des métadonnées spécifiques au projet dans la [code]section[/code], "
+"la [code]key[/code] et les [code]data[/code] spécifiées. Ces métadonnées "
+"sont enregistrées à l'extérieur du dossier du projet, et donc pas dans le "
+"système de contrôle de version (Git, etc.). Voir aussi [method "
+"get_project_metadata]."
#: doc/classes/EditorSettings.xml
msgid ""
@@ -27951,6 +30419,9 @@ msgid ""
"This is equivalent to using [method Object.set] on the EditorSettings "
"instance."
msgstr ""
+"Définit la [code]value[/code] du paramètre nommé [code]name[/code]. Cela "
+"équivaut à l'utilisation de [method Object.set] sur l'instance "
+"EditorSettings."
#: doc/classes/EditorSettings.xml
msgid "Emitted after any editor setting has changed."
@@ -27962,6 +30433,9 @@ msgid ""
"plugins to update their visuals on theme changes or logic on configuration "
"changes."
msgstr ""
+"Émis après que n'importe quel réglage de l'édiateur a changé. Il est utilisé "
+"par divers greffons de l'éditeurs pour mettre à jour leur affichage lors de "
+"changements de thème ou de configuration."
#: doc/classes/EditorSpatialGizmo.xml
msgid "Custom gizmo for editing Spatial objects."
@@ -27973,12 +30447,18 @@ msgid ""
"(handles) for 3D Spatial objects. See [EditorSpatialGizmoPlugin] for more "
"information."
msgstr ""
+"Un manipulateur personnalisé qui est utilisé pour la visualisation et "
+"l'édition personnalisées (poignets) pour les objets 3D de type Spatial. Voir "
+"[EditorSpatialGizmoPlugin] pour plus d'informations."
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
"Adds the specified [code]segments[/code] to the gizmo's collision shape for "
"picking. Call this function during [method redraw]."
msgstr ""
+"Ajoute le [code]segments[/code] spécifié à la forme de collision du "
+"manipulateur pour la sélection. Appelez cette fonction durant [method "
+"redraw]."
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
@@ -27986,6 +30466,9 @@ msgid ""
"generated from a regular [Mesh] too. Call this function during [method "
"redraw]."
msgstr ""
+"Ajoute des triangles de collision au manipulateur pour la sélection. Un "
+"[TriangleMesh] peut être généré à partir d'un [Mesh] régulier. Appelez cette "
+"fonction durant [method redraw]."
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
@@ -27994,6 +30477,10 @@ msgid ""
"There are virtual functions which will be called upon editing of these "
"handles. Call this function during [method redraw]."
msgstr ""
+"Ajoute une liste de poignées (points) qui peuvent être utilisées pour "
+"déformer l'objet en cours d'édition.\n"
+"Il y a des fonctions virtuelles qui seront appelés à l'édition de ces "
+"poignées. Appelez cette fonction durant [method redraw]."
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
@@ -28001,6 +30488,9 @@ msgid ""
"lines are used for visualizing the gizmo. Call this function during [method "
"redraw]."
msgstr ""
+"Ajoute des lignes au gizmo (une liste de paires de points), avec un matériau "
+"donné. Les lignes sont utilisées pour visualiser le manipulateur. Appelez "
+"cette fonction durant [method redraw]."
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
@@ -28009,6 +30499,11 @@ msgid ""
"is [code]true[/code], the mesh will rotate to always face the camera. Call "
"this function during [method redraw]."
msgstr ""
+"Ajoute un maillage au manipulateur avec l'état [code]billboard[/code] "
+"spécifié, [code]skeleton[/code] et [code]material[/code]. Si "
+"[code]billboard[/code] est [code]true[/code], le maillage tourne pour "
+"toujours faire toujours face à la caméra. Appelez cette fonction durant "
+"[method redraw]."
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
@@ -28037,18 +30532,28 @@ msgid ""
"by [method add_handles]).\n"
"Handles can be named for reference to the user when editing."
msgstr ""
+"Retourne le nom d'une poignée modifiée (ces poignées doivent d'abord être "
+"ajoutées avec [méthode add_handles]).\n"
+"Les poignées peuvent être nommées pour référence à l'utilisateur lors de "
+"l'édition."
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
"Gets actual value of a handle. This value can be anything and used for "
"eventually undoing the motion when calling [method commit_handle]."
msgstr ""
+"Retourne la valeur réelle d'une poignée. Cette valeur peut être n'importe "
+"quoi et utilisée pour finalement annuler le mouvement en appelant [method "
+"commit_handle]."
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
"Returns the [EditorSpatialGizmoPlugin] that owns this gizmo. It's useful to "
"retrieve materials using [method EditorSpatialGizmoPlugin.get_material]."
msgstr ""
+"Retourne le [EditorSpatialGizmoPlugin] qui possède ce manipulateur. Il est "
+"utile de récupérer les matériaux en utilisant [method "
+"EditorSpatialGizmoPlugin.get_material]"
#: doc/classes/EditorSpatialGizmo.xml
#, fuzzy
@@ -28131,6 +30636,9 @@ msgid ""
"nodes of your choice, return [code]null[/code] for the rest of nodes. See "
"also [method has_gizmo]."
msgstr ""
+"Surchargez cette méthode pour retourner un [EditorSpatialGizmo] personnalisé "
+"pour les nœuds spatiaux de votre choix, retourner [code]null[/code] pour le "
+"reste des nœuds. Voir aussi [method has_gizmo]."
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid ""
@@ -28140,6 +30648,12 @@ msgid ""
"Should not be overridden.\n"
"You can optionally provide a texture to use instead of the default icon."
msgstr ""
+"Crée un matériau de poignée avec ses variantes (sélectionnées et/ou "
+"modifiables) et les ajoute à la liste interne des matériaux. Ils peuvent "
+"ensuite être consultés avec [method get_material] et utilisés dans [method "
+"EditorSpatialGizmo.add_handles] Ne devrait pas être surchargé.\n"
+"Vous pouvez en option fournir une texture à utiliser à la place de l'icône "
+"par défaut."
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid ""
@@ -28148,6 +30662,10 @@ msgid ""
"[method get_material] and used in [method EditorSpatialGizmo."
"add_unscaled_billboard]. Should not be overridden."
msgstr ""
+"Crée un matériau d'icône avec ses variantes (sélectionnées et/ou "
+"modifiables) et les ajoute à la liste interne des matériaux. Ils peuvent "
+"ensuite être consultés avec [method get_material] et utilisés dans [method "
+"EditorSpatialGizmo.add_unscaled_billboard]. Ne devrait pas être surchargé."
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid ""
@@ -28156,6 +30674,11 @@ msgid ""
"[method get_material] and used in [method EditorSpatialGizmo.add_mesh] and "
"[method EditorSpatialGizmo.add_lines]. Should not be overridden."
msgstr ""
+"Crée un matériau non éclairé avec ses variantes (sélectionnées et/ou "
+"modifiables) et les ajoute à la liste interne des matériaux. Ils peuvent "
+"ensuite être consultés avec [method get_material] et utilisés dans [method "
+"EditorSpatialGizmo.add_mesh] et [method EditorSpatialGizmo.add_lines]. Ne "
+"devrait pas être dépassé."
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid ""
@@ -31422,6 +33945,11 @@ msgid ""
"on ([code]p1[/code], [code]q1[/code]) as well the accompanying point on "
"([code]p2[/code], [code]q2[/code])."
msgstr ""
+"À partir de deux segments 2D (de [code]p1[/code] à [code]q1[/code]) et (de "
+"[code]p2[/code] à [code]q2[/code]), retourne les deux points qui sont les "
+"plus proches de l'autre segment sur ces deux segments. Retourne un "
+"[PoolVector2Array] qui contient deux points, un sur chaque segment (de "
+"[code]p1[/code] à [code]q1[/code], et de [code]p2[/code] à [code]q2[/code])."
#: doc/classes/Geometry.xml
msgid "Used internally by the engine."
@@ -31452,6 +33980,9 @@ msgid ""
"it's located exactly [i]on[/i] the circle's boundary, otherwise returns "
"[code]false[/code]."
msgstr ""
+"Retourne [code]true[/code] si [code]point[/code] est à l'intérieur du cercle "
+"ou s'il se trouve exactement [i]sur[/i] la bordure du cercle, et retourne "
+"[code]false[/code] sinon."
#: doc/classes/Geometry.xml
msgid ""
@@ -31459,6 +33990,9 @@ msgid ""
"code] or if it's located exactly [i]on[/i] polygon's boundary, otherwise "
"returns [code]false[/code]."
msgstr ""
+"Retourne [code]true[/code] si [code]point[/code] est à l'intérieur du "
+"[code]polygon[/code] ou s'il se trouve exactement [i]sur[/i] la bodure du "
+"polygone, retourne [code]false[/code] sinon."
#: doc/classes/Geometry.xml
msgid ""
@@ -31476,6 +34010,14 @@ msgid ""
"[code]null[/code].\n"
"[b]Note:[/b] The lines are specified using direction vectors, not end points."
msgstr ""
+"Vérifie si les deux lignes (de [code]from_a[/code] et en direction de "
+"[code]dir_a[/code]) et (de [code]from_b[/code] et en direction de "
+"[code]dir_b[/code]) s'intersectent. Si oui, retourne le point d'intersection "
+"dans un [Vector2]. Si aucune intersection n'existe, retourne [code]null[/"
+"code].\n"
+"[b]Note :[/b] Ces lignes sont spécifiées en utilisant des vecteurs de "
+"direction, pas des points de fin, puisqu'une ligne n'a pas par définition de "
+"fin."
#: doc/classes/Geometry.xml
msgid ""
@@ -31484,6 +34026,11 @@ msgid ""
"[Vector2] that specifies the positions of each tile, [code]size[/code] "
"contains the overall size of the whole atlas as [Vector2]."
msgstr ""
+"À partir d'un tableau de [Vector2] représentant des tuiles, construit un "
+"atlas. Le dictionnaire retourné a deux clés : [code]points[/code] est un "
+"tableau de [Vector2] qui précise les positions de chaque tuile, et "
+"[code]size[/code] contient la taille globale de l'atlas entier sous forme de "
+"[Vector2]."
#: doc/classes/Geometry.xml
msgid ""
@@ -31494,6 +34041,12 @@ msgid ""
"polygons (holes) produced which could be distinguished by calling [method "
"is_polygon_clockwise]."
msgstr ""
+"Fusionne (combine) les polygones [code]polygon_a[/code] et [code]polygon_b[/"
+"code] et retourne un tableau de polygones fusionnés. Ça utilise "
+"[OPERATION_UNION] entre les polygones.\n"
+"L'opération peut fournir un polygone extérieur (la limite) et plusieurs "
+"polygones à intérieur (représentant les trous) qui pourraient être "
+"distingués en appelant [méthode is_polygon_clockwise]."
#: doc/classes/Geometry.xml
msgid ""
@@ -31520,6 +34073,29 @@ msgid ""
"150), Vector2(50, 150)]\n"
"[/codeblock]"
msgstr ""
+"Gonfle ou dégonfle [code]polygon[/code] par la quantité [code]delta[/code] "
+"unités (pixels) dans toutes les directions. Si [code]delta[/code] est "
+"positif, le polygone décale chaque sommet vers l'extérieur. Si [code]delta[/"
+"code] est négatif, décale chaque sommet vers l'intérieur. Retourne une liste "
+"des polygones parce que gonflage/dégonflage peut produire plusieurs "
+"polygones distinctes. Retourne un tableau vide si [code]delta[/code] est "
+"négatif et la valeur absolue de celui-ci dépasse approximativement les "
+"dimensions du rectangle minimal englobant du polygone.\n"
+"Les sommets de chaque polygone sont arrondis suivant [code]join_type[/code], "
+"voir [enum PolyJoinType].\n"
+"L'opération peut fournir un polygone extérieur (la limite extérieure) et "
+"plusieurs polygones à intérieur (représentant les trous) qui pourraient être "
+"distingués en appelant [méthode is_polygon_clockwise].\n"
+"[b]Note :[/b] Pour transformer les sommets en polygone, utilisez la méthode "
+"[méthode Transform2D.xform]:\n"
+"[codeblock]\n"
+"var polygon = PoolVector2Array([Vector2(0, 0), Vector2(100, 0), Vector2(100, "
+"100), Vector2(0, 100)])\n"
+"var offset = Vector2(50, 50)\n"
+"polygon = Transform2D(0, offset).xform(polygon)\n"
+"print(polygon) # Affiche [Vector2(50, 50), Vector2(150, 50), Vector2(150, "
+"150), Vector2(50, 150)]\n"
+"[/codeblock]"
#: doc/classes/Geometry.xml
msgid ""
@@ -31536,6 +34112,18 @@ msgid ""
"(hole) produced which could be distinguished by calling [method "
"is_polygon_clockwise]."
msgstr ""
+"par la quantité [code]delta[/code] unités (pixels) dans toutes les "
+"directions. Si [code]delta[/code] est positif, le polygone décale chaque "
+"sommet vers l'extérieur. Retourne une liste des polygones parce que gonflage/"
+"dégonflage peut produire plusieurs polygones distinctes. Si [code]delta[/"
+"code] est négatif, retourne un tableau vide.\n"
+"Les sommets de chaque polygone sont arrondis suivant [code]join_type[/code], "
+"voir [enum PolyJoinType].\n"
+"Chaque point d'extrémité du polygone sera arrondi suivant [code]end_type[/"
+"code], voir [enum PolyEndType].\n"
+"L'opération peut fournir un polygone extérieur (la limite extérieur) et "
+"plusieurs polygones à intérieur (représentant les trous) qui pourraient être "
+"distingués en appelant [method is_polygon_clockwise]."
#: doc/classes/Geometry.xml
msgid ""
@@ -31581,6 +34169,11 @@ msgid ""
"If an intersection takes place, the returned array contains the point of "
"intersection and the cylinder's normal at the point of intersection."
msgstr ""
+"Vérifie si le segment (de [code]from[/code] à [code]to[/code]) intersecte le "
+"cylindre avec la hauteur [code]height[/code] qui est centré à l'origine et a "
+"rayon de [code]radius[/code]. Si non, retourne un [PoolVector3Array] vide. "
+"S'il y une intersection, le tableau retourné contient le point et la normale "
+"de l'intersection."
#: doc/classes/Geometry.xml
msgid ""
@@ -31589,6 +34182,10 @@ msgid ""
"of intersection as [Vector2]. If no intersection takes place, returns "
"[code]null[/code]."
msgstr ""
+"Vérifie si les deux segments (de [code]from_a[/code] à [code]to_a[/code]) et "
+"(de [code]from_b[/code] à [code]to_b[/code]) intersectent. Si oui, retournez "
+"le point d'intersection dans un [Vector2]. Si aucune intersection n'a lieu, "
+"retourne [code]null[/code]."
#: doc/classes/Geometry.xml
msgid ""
@@ -31617,6 +34214,13 @@ msgid ""
"triangles). If the triangulation did not succeed, an empty [PoolIntArray] is "
"returned."
msgstr ""
+"Triangule l'aire spécifiée par un ensemble discret de [code]points[/code] de "
+"sorte qu'aucun point ne soit à l'intérieur du cercle d'un des triangles "
+"résultant. Retourne un [PoolIntArray] où chaque triangle se compose de trois "
+"indices de point consécutifs de [code]points[/code] (c'est-à-dire que le "
+"tableau retourné aura [code]n * 3[/code] éléments, avec [code]n[/code] étant "
+"le nombre de triangles trouvés). Si la triangulation n'a pas réussi, un "
+"[PoolIntArray] vide sera retourné."
#: doc/classes/Geometry.xml
msgid ""
@@ -31628,6 +34232,13 @@ msgid ""
"contour will be flipped if it's clockwise. If the triangulation did not "
"succeed, an empty [PoolIntArray] is returned."
msgstr ""
+"Triangule le polygone spécifié par les points dans [code]polygon[/code]. "
+"Retourne un [PoolIntArray] où chaque triangle se compose de trois indices de "
+"point consécutifs de [code]polygon[/code] (c'est-à-dire le tableau retourné "
+"aura [code]n * 3[/code] éléments, avec [code]n[/code] étant le nombre de "
+"triangles trouvés). Les triangles de sortie seront toujours dans le sens "
+"anti-horaire, et le contour sera inversé si c'est dans le sens horaire. Si "
+"la triangulation n'a pas réussi, un [PoolIntArray] vide sera retourné."
#: doc/classes/Geometry.xml
msgid ""
@@ -31715,12 +34326,16 @@ msgid ""
"Overrides the bounding box of this node with a custom one. To remove it, set "
"an [AABB] with all fields set to zero."
msgstr ""
+"Surcharge le rectangle englobant de ce nœud avec un personnalisé. Pour le "
+"supprimer, définissez un [AABB] avec tous les champs mis à zéro."
#: doc/classes/GeometryInstance.xml
msgid ""
"Sets the [enum GeometryInstance.Flags] specified. See [enum GeometryInstance."
"Flags] for options."
msgstr ""
+"Défini le [enum GeometryInstance.Flags] spécifiés. Voir [enum "
+"GeometryInstance.Flags] pour les options."
#: doc/classes/GeometryInstance.xml
msgid ""
@@ -31860,6 +34475,8 @@ msgid ""
"Unused in this class, exposed for consistency with [enum VisualServer."
"InstanceFlags]."
msgstr ""
+"Inutilisé dans cette classe, mais exposé pour être cohérent avec [enum "
+"VisualServer.InstanceFlags]."
#: doc/classes/GIProbe.xml
msgid "Real-time global illumination (GI) probe."
@@ -31896,10 +34513,43 @@ msgid ""
"emit light when used in a [GIProbe]. Only emissive [SpatialMaterial]s can "
"emit light in a [GIProbe]."
msgstr ""
+"[GIProbe] sont utilisées pour fournir une lumière indirecte en temps réel et "
+"en haute qualité aux scènes. Ils pré-calculent les lumières émises par "
+"objets et les effets statiques pour simuler le comportement complexe de la "
+"lumière en temps réel. Les [GIProbe] doivent être calculées avant "
+"utilisation, mais une fois calculées, les objets dynamiques recevront la "
+"lumière. De plus, les lumières peuvent être entièrement dynamiques ou "
+"calculées.\n"
+"Placer des [GIProbe] dans une scène peut réduire grandement les "
+"performances, la qualité de la sonde peut être réduite en échange de "
+"meilleures performances depuis les [ProjectSettings] en utilisant [membre "
+"ProjectSettings.rendering/quality/voxel_cone_tracing/high_quality]\n"
+"[b]La génération procédurale :[/b] Une [GIProbe] peut être calculée dans un "
+"projet exporté, ce qui lui permet d'être adaptée pour niveaux générés de "
+"manière procédurale ou construits par l'utilisateur tant que la géométrie "
+"est générée à l'avance.\n"
+"[b]Performance :[/b] La [GIProbe] est relativement exigeant pour le GPU et "
+"n'est pas adaptée au matériel d'entrée de gamme tel que les cartes "
+"graphiques intégrées (utilisez plutôt [BakedLightmap]). Pour supporter le "
+"matériel d'entrée de gamme, envisagez d'ajouter une option pour désactiver "
+"les [GIProbe] dans les menus d'options de votre projet. Une [GIProbe] peut "
+"être désactivé en cachant son nœud.\n"
+"[b]Note :[/b] Les maillages doivent avoir des murs suffisamment épais pour "
+"éviter les fuites de lumière au travers (évitez les murs qui n'ont qu'un "
+"seul côté). Pour les niveaux intérieurs, enfermez votre géométrie de niveau "
+"dans une boîte suffisamment grande bouchez les trous pour fermer le "
+"maillage. Pour éviter les fuites de lumière, vous pouvez également placer "
+"stratégiquement des nœuds [MeshInstance] temporaires avec [membre "
+"GeometryInstance.use_in_baked_light] activés. Ces nœuds temporaires peuvent "
+"alors être cachés une fois le calcul des [GIProbe] terminé.\n"
+"[b]Note :[/b] En raison d'une limitation de rendu, les [ShaderMaterial] avec "
+"émission ne peuvent pas émettre de lumière lorsqu'ils sont utilisés avec une "
+"[GIProbe]. Seuls les [SpatialMaterial] peuvent émettre de la lumière qui "
+"sera pris en compte par un [GIProbe]."
#: doc/classes/GIProbe.xml
msgid "GI probes"
-msgstr ""
+msgstr "Les sondes GI"
#: doc/classes/GIProbe.xml
msgid ""
@@ -31941,6 +34591,8 @@ msgid ""
"[i]Deprecated.[/i] This property has been deprecated due to known bugs and "
"no longer has any effect when enabled."
msgstr ""
+"[i]Obsolète.[/i] Cette propriété a été rendue obsolète en raison de bugs "
+"connus et n'a plus d'effet lorsqu'elle est activée."
#: doc/classes/GIProbe.xml
msgid "The [GIProbeData] resource that holds the data for this [GIProbe]."
@@ -32028,6 +34680,10 @@ msgid ""
"loading and saving is [i]not[/i] available in exported projects. References "
"to [GLTFAccessor] within a script will cause an error in an exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFAccessor] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFAnimation.xml
msgid ""
@@ -32036,6 +34692,10 @@ msgid ""
"to [GLTFAnimation] within a script will cause an error in an exported "
"project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFAnimation] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFBufferView.xml
msgid ""
@@ -32044,6 +34704,10 @@ msgid ""
"to [GLTFBufferView] within a script will cause an error in an exported "
"project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFBufferView] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFCamera.xml
msgid ""
@@ -32051,6 +34715,10 @@ msgid ""
"loading and saving is [i]not[/i] available in exported projects. References "
"to [GLTFCamera] within a script will cause an error in an exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFCamera] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFDocument.xml
msgid ""
@@ -32058,6 +34726,10 @@ msgid ""
"loading and saving is [i]not[/i] available in exported projects. References "
"to [GLTFDocument] within a script will cause an error in an exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFDocument] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFLight.xml
msgid ""
@@ -32065,12 +34737,18 @@ msgid ""
"loading and saving is [i]not[/i] available in exported projects. References "
"to [GLTFLight] within a script will cause an error in an exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFLight] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFLight.xml
msgid ""
"The [Color] of the light. Defaults to white. A black color causes the light "
"to have no effect."
msgstr ""
+"La [Color] de la lumière. La couleur par défauts est blanc. Une couleur "
+"noire fait que la lumière n'a aucun effet."
#: modules/gltf/doc_classes/GLTFLight.xml
msgid ""
@@ -32081,6 +34759,13 @@ msgid ""
"brightness. When creating a Godot [SpotLight], the ratio between the inner "
"and outer cone angles is used to calculate the attenuation of the light."
msgstr ""
+"L'angle intérieur du cône dans un projecteur. Doit être inférieur ou égal à "
+"l'angle de cône externe.\n"
+"Dans cet angle, la lumière est à pleine luminosité. Entre les angles "
+"intérieur et extérieur de cône, il y a une transition de la luminosité "
+"totale à aucune. Lors de la création d'un [SpotLight], le rapport entre les "
+"angles de cône intérieur et extérieur est utilisé pour calculer "
+"l'atténuation de la lumière."
#: modules/gltf/doc_classes/GLTFLight.xml
msgid ""
@@ -32089,6 +34774,10 @@ msgid ""
"directional lights. When creating a Godot light, this value is converted to "
"a unitless multiplier."
msgstr ""
+"L'intensité de la lumière. Ceci est exprimé en candelas (lumens par "
+"stéradian) pour les lumières en point et les spots, et en lux (lumens par "
+"m²) pour les lumières directionnels. En créant une lumière, cette valeur est "
+"convertie en un multiplicateur sans unité."
#: modules/gltf/doc_classes/GLTFLight.xml
msgid ""
@@ -32107,6 +34796,10 @@ msgid ""
"with no range defined behave like physical lights (which have infinite "
"range). When creating a Godot light, the range is clamped to 4096."
msgstr ""
+"La portée de la lumière, au-delà de laquelle la lumière n'a plus aucun "
+"effet. Les feux GLTF sans limite de portée définie se comportent comme des "
+"lumières physiques (qui ont une portée infinie). Lors de la création d'une "
+"lumière Godot, la portée est fixée à 4096 unités."
#: modules/gltf/doc_classes/GLTFLight.xml
msgid ""
@@ -32114,6 +34807,9 @@ msgid ""
"and \"directional\", which correspond to Godot's [OmniLight], [SpotLight], "
"and [DirectionalLight] respectively."
msgstr ""
+"Le type de lumière. Les valeurs acceptées par Godot sont « point », « spot » "
+"et « directionnelle », qui correspondent respectivement au type Godot "
+"[OmniLight], [SpotLight] et [DirectionalLight]."
#: modules/gltf/doc_classes/GLTFMesh.xml
msgid ""
@@ -32121,6 +34817,10 @@ msgid ""
"loading and saving is [i]not[/i] available in exported projects. References "
"to [GLTFMesh] within a script will cause an error in an exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFMesh] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFNode.xml
msgid ""
@@ -32128,6 +34828,10 @@ msgid ""
"loading and saving is [i]not[/i] available in exported projects. References "
"to [GLTFNode] within a script will cause an error in an exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFNode] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFSkeleton.xml
msgid ""
@@ -32135,6 +34839,10 @@ msgid ""
"loading and saving is [i]not[/i] available in exported projects. References "
"to [GLTFSkeleton] within a script will cause an error in an exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que dans les éditeurs. Le "
+"chargement et l'économie de glTF en cours est [i]not[/i] disponible dans les "
+"projets exportés. Les références à [GLTFSkeleton] dans un script causeront "
+"une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFSpecGloss.xml
msgid ""
@@ -32143,6 +34851,10 @@ msgid ""
"to [GLTFSpecGloss] within a script will cause an error in an exported "
"project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que dans les éditeurs. Le "
+"chargement et l'économie de glTF en cours est [i]not[/i] disponible dans les "
+"projets exportés. Les références à [GLTFSpecGloss] dans un script causeront "
+"une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFState.xml
msgid ""
@@ -32150,6 +34862,10 @@ msgid ""
"loading and saving is [i]not[/i] available in exported projects. References "
"to [GLTFState] within a script will cause an error in an exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFState] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/gltf/doc_classes/GLTFTexture.xml
msgid ""
@@ -32157,6 +34873,10 @@ msgid ""
"loading and saving is [i]not[/i] available in exported projects. References "
"to [GLTFTexture] within a script will cause an error in an exported project."
msgstr ""
+"[b]Note :[/b] Cette classe n'est compilée que pour les version de l'éditeur. "
+"Le chargement et l'enregistrement au format glTF n'est [i]pas[/i] disponible "
+"dans les projets exportés. Les références à [GLTFTexture] dans un script "
+"causeront une erreur dans un projet exporté."
#: modules/mono/doc_classes/GodotSharp.xml
msgid "Bridge between Godot and the Mono runtime (Mono-enabled builds only)."
@@ -32233,6 +34953,8 @@ msgid ""
"A color interpolator resource which can be used to generate colors between "
"user-defined color points."
msgstr ""
+"Une ressource d'interpolation de couleur qui peut être utilisé pour générer "
+"des couleurs entre des points de couleur définis par l'utilisateur."
#: doc/classes/Gradient.xml
msgid ""
@@ -32242,11 +34964,18 @@ msgid ""
"will initially have 2 colors (black and white), one (black) at ramp lower "
"offset 0 and the other (white) at the ramp higher offset 1."
msgstr ""
+"À partir d'un ensemble de couleurs, cette ressource les interpolera dans "
+"l'ordre. Cela signifie que si vous avez la couleur 1, la couleur 2 et la "
+"couleur 3, la rampe interpolera de la couleur 1 à la couleur 2 et de la "
+"couleur 2 à la couleur 3. La rampe aura d'abord 2 couleurs (noir et blanc), "
+"la première couleur (le noir) sera utilisé pour les positions inférieurs à 0 "
+"et l'autre (le blanc) pour les positions supérieurs à 1."
#: doc/classes/Gradient.xml
msgid ""
"Adds the specified color to the end of the ramp, with the specified offset."
msgstr ""
+"Ajoute la couleur spécifiée à la fin du dégradé, à la position spécifiée."
#: doc/classes/Gradient.xml
msgid "Returns the color of the ramp color at index [code]point[/code]."
@@ -32289,6 +35018,8 @@ msgid ""
"Defines how the colors between points of the gradient are interpolated. See "
"[enum InterpolationMode] for available modes."
msgstr ""
+"Définit comment les couleurs entre les points du dégradé sont interpolées. "
+"Voir [enum InterpolationMode] pour les modes disponibles."
#: doc/classes/Gradient.xml
msgid "Gradient's offsets returned as a [PoolRealArray]."
@@ -32300,6 +35031,9 @@ msgid ""
"uniform between. This might cause visible aliasing when used for a gradient "
"texture in some cases."
msgstr ""
+"Interpolation constante, la couleur change brusquement à chaque point et "
+"reste uniforme entre. Cela pourrait causer un crénelage visible lorsqu'elle "
+"est utilisée pour une texture de dégradé dans certains cas."
#: doc/classes/GradientTexture.xml
msgid "Gradient-filled texture."
@@ -32314,6 +35048,12 @@ msgid ""
"at fixed steps (see [member width]). See also [GradientTexture2D] and "
"[CurveTexture]."
msgstr ""
+"GradientTexture utilise un [Gradient] pour remplir la texture. Le gradient "
+"sera rempli de gauche à droite en utilisant les couleurs obtenues du "
+"dégradé. Cela signifie que la texture ne représente pas nécessairement une "
+"copie exacte du dégradé, mais plutôt une interpolation des échantillons "
+"obtenus du dégradé à des étapes fixes (voir [member width)]. Voir aussi "
+"[GradientTexture2D] et [CurveTexture]."
#: doc/classes/GradientTexture.xml
msgid "The [Gradient] that will be used to fill the texture."
@@ -32326,9 +35066,8 @@ msgstr ""
"[Gradient]."
#: doc/classes/GradientTexture2D.xml
-#, fuzzy
msgid "Gradient-filled 2D texture."
-msgstr "Texture remplie de gradients."
+msgstr "Texture de gradient 2D."
#: doc/classes/GradientTexture2D.xml
msgid ""
@@ -32340,6 +35079,13 @@ msgid ""
"[member width] and [member height]). See also [GradientTexture] and "
"[CurveTexture]."
msgstr ""
+"La texture utilise un [Gradient] pour remplir les données la texture 2D. Le "
+"dégradé est rempli selon les types spécifiés [member fill] et [member "
+"repeat] en utilisant les couleurs obtenues du dégradé. La texture ne "
+"représente pas nécessairement une copie exacte du dégradé, mais plutôt une "
+"interpolation des échantillons obtenus du dégradé à des étapes fixes (voir "
+"[member width] et [member height]). Voir aussi [GradientTexture] et "
+"[CurveTexture]."
#: doc/classes/GradientTexture2D.xml
msgid ""
@@ -32347,6 +35093,9 @@ msgid ""
"by interpolating colors starting from [member fill_from] to [member fill_to] "
"offsets."
msgstr ""
+"Le type de remplissage du dégradé, c'est l'une des valeurs de [enum Fill]. "
+"La texture est remplie par des couleurs interpolées à partir des positions "
+"de [member fill_from] à [member fill_to]."
#: doc/classes/GradientTexture2D.xml
msgid ""
@@ -32379,6 +35128,10 @@ msgid ""
"filled starting from [member fill_from] to [member fill_to] offsets by "
"default, but the gradient fill can be repeated to cover the entire texture."
msgstr ""
+"Le type de répétition du dégradé, c'est l'une des valeurs de [enum Repeat]. "
+"La texture est remplie à partir des positions de [member fill_from] à "
+"[member fill_to] par défaut, mais le remplissage peut être répété pour "
+"couvrir toute la texture."
#: doc/classes/GradientTexture2D.xml
msgid ""
@@ -32388,6 +35141,12 @@ msgid ""
"code], the generated texture will use low dynamic range; overbright colors "
"will be clamped ([constant Image.FORMAT_RGBA8] format)."
msgstr ""
+"Si [code]true[/code], la texture générée aura une gamme dynamique élevée (le "
+"format sera [constant Image.FORMAT_RGBAF]). Cela permet aux effets de lueur "
+"de fonctionner si [member Environment.glow_enabled] est [code]true[/code]. "
+"Si [code]false[/code], la texture générée utilisera une plage dynamique "
+"basse ; les couleurs trop lumineuses seront limitées (le format sera "
+"[constant Image.FORMAT_RGBA8]."
#: doc/classes/GradientTexture2D.xml
msgid ""
@@ -32399,17 +35158,19 @@ msgstr ""
#: doc/classes/GradientTexture2D.xml
msgid "The colors are linearly interpolated in a straight line."
-msgstr ""
+msgstr "Les couleurs sont linéairement interpolées selon une ligne droite."
#: doc/classes/GradientTexture2D.xml
msgid "The colors are linearly interpolated in a circular pattern."
-msgstr ""
+msgstr "Les couleurs sont linéairement interpolées selon un motif circulaire."
#: doc/classes/GradientTexture2D.xml
msgid ""
"The gradient fill is restricted to the range defined by [member fill_from] "
"to [member fill_to] offsets."
msgstr ""
+"Le remplissage du dégradé est limité à la plage définie par les positions de "
+"[member fill_from] à [member fill_to]."
#: doc/classes/GradientTexture2D.xml
msgid ""
@@ -32424,12 +35185,16 @@ msgid ""
"The texture is filled starting from [member fill_from] to [member fill_to] "
"offsets, mirroring the pattern in both directions."
msgstr ""
+"La texture est remplie à partir des positions de [member fill_from] à "
+"[member fill_to], en répétant en miroir le motif dans les deux directions."
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
"connection events between them."
msgstr ""
+"GraphEdit est une zone capable de montrer divers GraphNode. Il gère les "
+"événements de connexion entre eux."
#: doc/classes/GraphEdit.xml
msgid ""
@@ -32440,24 +35205,37 @@ msgid ""
"It is greatly advised to enable low-processor usage mode (see [member OS."
"low_processor_usage_mode]) when using GraphEdits."
msgstr ""
+"GraphEdit gère la représentation des GraphNode qu'il contient, ainsi que les "
+"connexions et les déconnections entre eux. Les signaux sont envoyés pour "
+"chacun de ces deux événements. La déconnection entre les emplacements des "
+"GraphNode est désactivé par défaut.\n"
+"Il est fortement conseillé d'activer le mode d'utilisation à faible "
+"processeur (voir [member OS.low_processor_usage_mode)] lors de l'utilisation "
+"des GraphEdit."
#: doc/classes/GraphEdit.xml
msgid ""
"Makes possible the connection between two different slot types. The type is "
"defined with the [method GraphNode.set_slot] method."
msgstr ""
+"Rend possible la connexion entre deux types différents d'emplacements. Le "
+"type est défini avec la méthode [method GraphNode.set_slot]."
#: doc/classes/GraphEdit.xml
msgid ""
"Makes possible to disconnect nodes when dragging from the slot at the left "
"if it has the specified type."
msgstr ""
+"Permet de déconnecter les nœuds en glissant l'emplacement à gauche s'il a le "
+"type spécifié."
#: doc/classes/GraphEdit.xml
msgid ""
"Makes possible to disconnect nodes when dragging from the slot at the right "
"if it has the specified type."
msgstr ""
+"Permet de déconnecter les nœuds en glissant de l'emplacement à droite s'il a "
+"le type spécifié."
#: doc/classes/GraphEdit.xml
msgid "Removes all connections between nodes."
@@ -32481,6 +35259,10 @@ msgid ""
"[code]to[/code] GraphNode. If the connection does not exist, no connection "
"is removed."
msgstr ""
+"Supprimer la connexion entre l'emplacement [code]from_port[/code] du "
+"GraphNode [code]from[/code] et l'emplacement [code]to_port[/code] du "
+"GraphNode [code]to[/code]. Si la connexion n'existe pas, aucune connexion ne "
+"sera supprimée."
#: doc/classes/GraphEdit.xml
msgid ""
@@ -32488,6 +35270,9 @@ msgid ""
"in a structure of the form [code]{ from_port: 0, from: \"GraphNode name 0\", "
"to_port: 1, to: \"GraphNode name 1\" }[/code]."
msgstr ""
+"Retourne un Array contenant la liste des connexions. Une connexion se "
+"compose d'une structure de la forme [code]{ from_port: 0, from: \"GraphNode "
+"name 0\", to_port: 1, to: \"GraphNode name 1\" }[/code]."
#: doc/classes/GraphEdit.xml
msgid ""
@@ -32498,6 +35283,13 @@ msgid ""
"may cause a crash. If you wish to hide it or any of its children, use their "
"[member CanvasItem.visible] property."
msgstr ""
+"Retourne le [HBoxContainer] qui contient les contrôles de zoom et de "
+"magnétisation de la grille en haut à gauche du graphe. Vous pouvez utiliser "
+"cette méthode pour repositionner la barre d'outils ou pour y ajouter vos "
+"propres contrôles personnalisés.\n"
+"[b]Avertissement :[/b] Il s'agit d'un nœud interne requis, l'enlever et le "
+"libérer peut causer un plantage. Si vous voulez le cacher lui ou un de ses "
+"enfants, utilisez plutôt la propriété [membre CanvasItem.visible]."
#: doc/classes/GraphEdit.xml
msgid ""
@@ -32505,28 +35297,38 @@ msgid ""
"[code]from[/code] GraphNode is connected to the [code]to_port[/code] slot of "
"the [code]to[/code] GraphNode."
msgstr ""
+"Retourne [code]true[/code] si l'emplacement [code]from_port[/code] du "
+"GraphNode [code]from[/code] est connecté à l'emplacement [code]to_port[/"
+"code] du GraphNode [code]to[/code]."
#: doc/classes/GraphEdit.xml
msgid "Returns whether it's possible to connect slots of the specified types."
msgstr ""
+"Retourne s'il est possible de connecter les emplacements des types spécifiés."
#: doc/classes/GraphEdit.xml
msgid ""
"Makes it not possible to connect between two different slot types. The type "
"is defined with the [method GraphNode.set_slot] method."
msgstr ""
+"Permet d'empêcher de connecter deux types d'emplacements différents. Le type "
+"est défini avec la méthode [method GraphNode.set_slot]."
#: doc/classes/GraphEdit.xml
msgid ""
"Removes the possibility to disconnect nodes when dragging from the slot at "
"the left if it has the specified type."
msgstr ""
+"Supprime la possibilité de déconnecter les nœuds en glissant l'emplacement "
+"de gauche si elle a le type spécifié."
#: doc/classes/GraphEdit.xml
msgid ""
"Removes the possibility to disconnect nodes when dragging from the slot at "
"the right if it has the specified type."
msgstr ""
+"Supprime la possibilité de déconnecter les nœuds en glissant l'emplacement "
+"de droite si elle a le type spécifié."
#: doc/classes/GraphEdit.xml
msgid ""
@@ -32534,6 +35336,9 @@ msgid ""
"[code]from_port[/code] and [code]to[/code]'s [code]to_port[/code] with the "
"color provided in the [code]activity[/code] theme property."
msgstr ""
+"Définit la coloration de la connexion entre [code]from[/code] de "
+"[code]from_port[/code] et [code]to[/code]) de [code]to_port[/code] avec la "
+"couleur spécifiée dans la propriété [code]activity[/code] du thème."
#: doc/classes/GraphEdit.xml
msgid "Sets the specified [code]node[/code] as the one selected."
@@ -32553,12 +35358,17 @@ msgid ""
"The size of the minimap rectangle. The map itself is based on the size of "
"the grid area and is scaled to fit this rectangle."
msgstr ""
+"La taille du rectangle de la mini-carte. La carte elle-même est basée sur la "
+"taille de la zone de grille et est mise à l'échelle pour s'adapter à ce "
+"rectangle."
#: doc/classes/GraphEdit.xml
msgid ""
"If [code]true[/code], enables disconnection of existing connections in the "
"GraphEdit by dragging the right end."
msgstr ""
+"Si [code]true[/code], permet de déconnecter les connexions existantes dans "
+"le GraphEdit en faisant glisser l'extrémité droite."
#: doc/classes/GraphEdit.xml
msgid "The scroll offset."
@@ -32607,6 +35417,8 @@ msgid ""
"Emitted when user dragging connection from input port into empty space of "
"the graph."
msgstr ""
+"Émis quand l'utilisateur fait glisser la connexion du port d'entrée vers "
+"l'espace vide du graphe."
#: doc/classes/GraphEdit.xml
msgid ""
@@ -32623,6 +35435,8 @@ msgid ""
"Emitted when user dragging connection from output port into empty space of "
"the graph."
msgstr ""
+"Émis lorsque l'utilisateur fait glisser la connexion du port de sortie vers "
+"l'espace vide du graphe."
#: doc/classes/GraphEdit.xml
msgid "Emitted when the user presses [code]Ctrl + C[/code]."
@@ -32641,6 +35455,9 @@ msgid ""
"slot of [code]from[/code] GraphNode and [code]to_slot[/code] slot of "
"[code]to[/code] GraphNode is attempted to be removed."
msgstr ""
+"Émis au GraphEdit lors d'une tentative de supprimer la connexion entre "
+"l'emplacement [code]from_slot[/code] du GraphNode [code]from[/code] et "
+"l'emplacement [code]to_slot[/code] de GraphNode [code]to[/code]."
#: doc/classes/GraphEdit.xml
msgid ""
@@ -32739,6 +35556,24 @@ msgid ""
"are on the right side of GraphNode. Only enabled slots are counted as "
"connections."
msgstr ""
+"Un GraphNode est un conteneur. Chaque GraphNode peut avoir plusieurs "
+"emplacement d'entrée et de sortie, parfois appelé ports, permettant des "
+"connexions entre les GraphNode. Pour ajouter une emplacement à un GraphNode, "
+"ajoutez-lui n'importe quel nœud enfant dérivé de [Control].\n"
+"Après l'ajout d'au moins un enfant au GraphNode, de nouvelles sections "
+"seront automatiquement créées dans l'inspecteur appelé 'Emplacement'. "
+"Lorsque cet 'Emplacement' est agrandi, vous verrez la liste avec l'index "
+"pour chaque emplacement. Vous pouvez cliquer sur chacun d'eux les agrandir "
+"davantage.\n"
+"Dans l'inspecteur, vous pouvez activer (montrer) ou désactiver (cacher) ces "
+"emplacements. Par défaut, toutes les emplacements sont désactivées afin que "
+"vous ne voyez pas d'emplacements sur votre GraphNode au début. Vous pouvez "
+"attribuer un type à chaque emplacement. Seules les emplacements du même type "
+"pourront se connecter. Vous pouvez également attribuer des couleurs aux "
+"emplacements. Une liste des entrées et sorties est défini pour chaque "
+"élément d'interface inclus dans le GraphNode. Les connexions d'entrée sont "
+"sur la gauche et les connexions de sortie sur la droite du GraphNode. Seuls "
+"les emplacements activés sont comptés comme des connexions."
#: doc/classes/GraphNode.xml
msgid "Disables all input and output slots of the GraphNode."
@@ -32834,6 +35669,21 @@ msgid ""
"Individual properties can be set using one of the [code]set_slot_*[/code] "
"methods. You must enable at least one side of the slot to do so."
msgstr ""
+"Définit les propriétés de l'emplacement avec identifiant [code]idx[/code].\n"
+"Si [code]enable_left[code]/[code]right[/code], un port apparaîtra et "
+"l'emplacement pourra être connectée de ce côté.\n"
+"[code]type_left[code]/[code]right[/code] est un type arbitraire du port. "
+"Seuls les ports avec le même type peuvent être connectés.\n"
+"[code]color_left[code]/[code]right[/code] est la teinte de l'icône du port "
+"de ce côté.\n"
+"[code]custom_left[code]/[code]right[/code] est une texture personnalisée "
+"pour le port de ce côté.\n"
+"[b]Note :[/b] Cette méthode ne définit que les propriétés de l'emplacement. "
+"Pour créer l'emplacement, ajoutez un enfant dérivé de [Control] au "
+"GraphNode.\n"
+"Les propriétés individuelles peuvent être définies en utilisant l'une des "
+"méthodes [code]set_slot_*[/code]. Vous devez activer au moins un côté de "
+"l'emplacement pour le faire."
#: doc/classes/GraphNode.xml
msgid ""
@@ -32857,6 +35707,9 @@ msgid ""
"[code]enable_left[/code] is [code]true[/code], a port will appear on the "
"left side and the slot will be able to be connected from this side."
msgstr ""
+"Bascule le côté gauche (entrée) de l'emplacement à l'index [code]idx[/code]. "
+"Si [code]enable_left[/code] est [code]true[/code], un port apparaîtra sur le "
+"côté gauche et l'emplacement pourra être connecté de ce côté."
#: doc/classes/GraphNode.xml
msgid ""
@@ -32864,6 +35717,9 @@ msgid ""
"[code]enable_right[/code] is [code]true[/code], a port will appear on the "
"right side and the slot will be able to be connected from this side."
msgstr ""
+"Bascule le côté droit (sortie) de l'emplacement à l'index [code]idx[/code]. "
+"Si [code]enable_right[/code] est [code]true[/code], un port apparaîtra sur "
+"le côté droit et l'emplacement pourra être connecté de ce côté."
#: doc/classes/GraphNode.xml
msgid ""
@@ -32903,6 +35759,9 @@ msgid ""
"[b]Note:[/b] Dragging the handle will only emit the [signal resize_request] "
"signal, the GraphNode needs to be resized manually."
msgstr ""
+"Si [code]true[/code], l'utilisateur peut redimensionner le GraphNode.\n"
+"[b]Note :[/b] Faire glisser la poignée n'émettra que le signal [signal "
+"resize_request], le GraphNode doit être redimensionné manuellement."
#: doc/classes/GraphNode.xml
msgid "If [code]true[/code], the GraphNode is selected."
@@ -32914,6 +35773,9 @@ msgid ""
"[b]Note:[/b] Pressing it will only emit the [signal close_request] signal, "
"the GraphNode needs to be removed manually."
msgstr ""
+"Si [code]true[/code], le bouton de fermeture sera visible.\n"
+"[b]Note :[/b] Appuyer ce bouton n'émettra que le signal [signal "
+"close_request], le GraphNode doit être retiré manuellement."
#: doc/classes/GraphNode.xml
msgid "The text displayed in the GraphNode's title bar."
@@ -33064,12 +35926,25 @@ msgid ""
"[b]Note:[/b] GridContainer only works with child nodes inheriting from "
"Control. It won't rearrange child nodes inheriting from Node2D."
msgstr ""
+"GridContainer arrangera ses enfants du type Control dans une structure en "
+"grille, les colonnes de la grille sont spécifiées en utilisant la propriété "
+"[member columns] et le nombre de lignes sera égal au nombre d'enfants dans "
+"le conteneur divisé par le nombre de colonnes. Par exemple, si le conteneur "
+"a 5 enfants et 2 colonnes, il y aura 3 rangées dans le conteneur.\n"
+"Notez que la mise en page des grilles conservera les colonnes et les rangées "
+"pour chaque taille du conteneur, et que les colonnes vides seront étendues "
+"automatiquement.\n"
+"[b]Note :[/b] GridContainer ne fonctionne que avec des nœuds d'enfants "
+"héritant de Control. Par exemple, elle ne réarrangera pas les nœuds enfants "
+"héritant de Node2D."
#: doc/classes/GridContainer.xml
msgid ""
"The number of columns in the [GridContainer]. If modified, [GridContainer] "
"reorders its Control-derived children to accommodate the new layout."
msgstr ""
+"Le nombre de colonnes dans le [GridContainer]. Si modifié, [GridContainer] "
+"réarrangera à ses enfants de type Control suivant la nouvelle mise en page."
#: doc/classes/GridContainer.xml doc/classes/HFlowContainer.xml
#: doc/classes/VFlowContainer.xml
@@ -33102,6 +35977,22 @@ msgid ""
"light not affect the first layer, the whole GridMap won't be lit by the "
"light in question."
msgstr ""
+"GridMap vous permet de placer de manière interactive des maillages sur une "
+"grille. Il fonctionne à la fois à partir de l'éditeur et des scripts, et "
+"vous pouvez vous en servir pour créer des éditeurs de niveau dans un jeu.\n"
+"GridMaps utilise une [MeshLibrary] qui contient une liste de tuiles. Chaque "
+"tuile est un maillage avec des matériaux, en plus de formes de collision et "
+"de navigation en option.\n"
+"Un GridMap contient une collection de cellules. Chaque cellule de grille se "
+"réfère à une tuile dans le [MeshLibrary]. Toutes les cellules de la carte "
+"ont les mêmes dimensions.\n"
+"En interne, un GridMap est divisé par des d'octants séparés pour améliorer "
+"le rendu et le traitement physique. Chaque octant a les mêmes dimensions et "
+"peut contenir plusieurs cellules.\n"
+"[b]Note :[/b] GridMap ne s'étend pas [VisualInstance] et donc de ne pas être "
+"cachés ou masqués à partir de [member VisualInstance.layers]. Si vous "
+"ajoutez une lumière qui n'affecte pas le premier calque, aucune partie de "
+"l'ensemble du GridMap ne sera éclairé par cette lumière."
#: modules/gridmap/doc_classes/GridMap.xml
msgid "Using gridmaps"
@@ -33129,6 +36020,8 @@ msgid ""
"The orientation of the cell at the grid-based X, Y and Z coordinates. -1 is "
"returned if the cell is empty."
msgstr ""
+"L'orientation de la cellule aux coordonnées X, Y et Z. -1 est retourné si la "
+"cellule est vide."
#: modules/gridmap/doc_classes/GridMap.xml
msgid "Returns an individual bit on the [member collision_layer]."
@@ -33178,6 +36071,11 @@ msgid ""
"Optionally, the item's orientation can be passed. For valid orientation "
"values, see [method Basis.get_orthogonal_index]."
msgstr ""
+"Définit l'indice de maillage de la cellule pour ces coordonnées X, Y et Z de "
+"la grille.\n"
+"Un index négatif comme [constant INVALID_CELL_ITEM] effacera la cellule.\n"
+"En option, l'orientation de l'objet peut être spécifiée. Pour les valeurs "
+"d'orientation valides, voir [method Basis.get_orthogonal_index]."
#: modules/gridmap/doc_classes/GridMap.xml
msgid "Sets an individual bit on the [member collision_layer]."
@@ -33222,6 +36120,8 @@ msgid ""
"The size of each octant measured in number of cells. This applies to all "
"three axis."
msgstr ""
+"La taille de chaque octant mesurée en nombre de cellules. Ceci s'applique "
+"aux trois axes."
#: modules/gridmap/doc_classes/GridMap.xml
msgid ""
@@ -33442,9 +36342,8 @@ msgstr ""
"valeur redimensionnera [member map_data]."
#: doc/classes/HFlowContainer.xml
-#, fuzzy
msgid "Horizontal flow container."
-msgstr "Conteneur de boîte horizontale."
+msgstr "Conteneur de flux horizontal."
#: doc/classes/HFlowContainer.xml
msgid "Horizontal version of [FlowContainer]."
@@ -33652,6 +36551,10 @@ msgid ""
"[method finish] is called to append [code]data[/code] to the message, but "
"cannot be called until [method start] has been called."
msgstr ""
+"Met à jour le message pour être un HMAC. Ceci peut être appelé plusieurs "
+"fois avant que [method finish] soit appelé pour ajouter les données "
+"[code]data[/code] au message, mais ne peut être appelé avant que [method "
+"start] ne soit appelé."
#: doc/classes/HScrollBar.xml
msgid "Horizontal scroll bar."
@@ -33669,6 +36572,9 @@ msgid ""
"Icon used as a button to scroll the [ScrollBar] left. Supports custom step "
"using the [member ScrollBar.custom_step] property."
msgstr ""
+"L'icône utilisée comme bouton pour défiler la [ScrollBar] de gauche. "
+"Supporte une valeur de déplacement personnalisé en utilisant la propriété "
+"[member ScrollBar.custom_step]."
#: doc/classes/HScrollBar.xml doc/classes/VScrollBar.xml
msgid "Displayed when the mouse cursor hovers over the decrement button."
@@ -33772,13 +36678,15 @@ msgstr ""
#: doc/classes/HSlider.xml
msgid "The background of the area to the left of the grabber."
-msgstr ""
+msgstr "L'arrière-plan de la zone à gauche du glisseur."
#: doc/classes/HSlider.xml
msgid ""
"The background for the whole slider. Determines the height of the "
"[code]grabber_area[/code]."
msgstr ""
+"L'arrière-plan pour tout le curseur. Détermine la hauteur de "
+"[code]grabber_area[/code]."
#: doc/classes/HSplitContainer.xml
msgid "Horizontal split container."
@@ -33788,7 +36696,7 @@ msgstr "Conteneur fractionné horizontal."
msgid ""
"Horizontal split container. See [SplitContainer]. This goes from left to "
"right."
-msgstr ""
+msgstr "Conteneur horizontal. Voir [SplitContainer]. Va de gauche à droite."
#: doc/classes/HSplitContainer.xml doc/classes/VSplitContainer.xml
msgid ""
@@ -33806,7 +36714,7 @@ msgstr "L'espace entre les côtés des conteneurs."
#: doc/classes/HSplitContainer.xml doc/classes/VSplitContainer.xml
msgid "The icon used for the grabber drawn in the middle area."
-msgstr ""
+msgstr "L'icône utilisée pour le glisseur affiché au milieu."
#: doc/classes/HTTPClient.xml
msgid "Low-level hyper-text transfer protocol client."
@@ -33846,6 +36754,42 @@ msgid ""
"are otherwise valid. If this is a concern, you may want to use automatically "
"managed certificates with a short validity period."
msgstr ""
+"Client de protocole de transfert hypertexte (parfois appelé \"User Agent\"). "
+"Utilisé pour faire des requêtes HTTP pour télécharger du contenu web, des "
+"fichiers et d'autres données ou communiquer avec divers services, ou pour "
+"d'autres cas d'utilisation. [b]Voir le nœud [HTTPRequest] pour une "
+"alternative de haut-niveau[/b].\n"
+"[b]Note :[/b] Ce client doit seulement se connecter à un hôte une fois (voir "
+"[method connect_to_host)] pour envoyer plusieurs requêtes. En raison de "
+"cela, les méthodes qui prennent des URL prennent généralement juste la "
+"partie après l'hôte au lieu de l'URL complète, puisque le client est déjà "
+"connecté à l'hôte. Voir [method request] pour un exemple complet pour "
+"pouvoir démarrer.\n"
+"Un [HTTPClient] devrait être réutilisé entre plusieurs requêtes ou pour se "
+"connecter à différents hôtes au lieu de créer un client par requête. "
+"Supporte les serveurs SSL et la vérification des certificats des serveurs "
+"SSL. Les codes de statut HTTP de la gamme 2xx indiquent un succès, 3xx une "
+"redirection (c.-à-d. \"essayez à nouveau, mais ici\"), 4xx que quelque chose "
+"ne va pas avec la requête, et 5xx qu'un problème est survenu du côté du "
+"serveur.\n"
+"Pour plus d'informations sur HTTP, voir [url=https://developer.mozilla.org/"
+"en-US/docs/Web/HTTP] (ou lire le RFC 2616 pour le lire directement depuis la "
+"soruce : [url=https://tools.ietf.org/html/rfc2616])\n"
+"[b]Note :[/b] Lorsque vous effectuez des requêtes HTTP d'un projet exporté "
+"vers HTML5, gardez à l'esprit que le serveur distant peut ne pas autoriser "
+"des requêtes d'origine étrangère en raison de [url=https://developer.mozilla."
+"org/en-US/docs/Web/HTTP/CORS]CORS[/url]. Si vous hébergez le serveur en "
+"question, vous devez modifier son implémentation pour permettre des requêtes "
+"d'origine étrangère en ajoutant l'en-tête HTTP [code]Access-Control-Allow-"
+"Origin: *[/code].\n"
+"[b]Note :[/b] Le support SSL/TLS est actuellement limité à TLS 1.0, TLS 1.1 "
+"et TLS 1.2. Tenter de se connecter à un serveur TLS 1.3 retournera une "
+"erreur.\n"
+"[b]Avertissement :[/b] La révocation du certificat SSL/TLS et le pinning de "
+"certificat ne sont pas supportés. Les certificats révoqués sont acceptés "
+"aussi longtemps qu'ils sont valides. Si c'est un problème, vous pouvez "
+"utiliser des certificats gérés automatiquement avec une courte période de "
+"validité."
#: doc/classes/HTTPClient.xml
msgid "Closes the current connection, allowing reuse of this [HTTPClient]."
@@ -33864,6 +36808,14 @@ msgid ""
"[code]verify_host[/code] will check the SSL identity of the host if set to "
"[code]true[/code]."
msgstr ""
+"Se connecte à un hôte. C'est nécessaire avant toute requête.\n"
+"L'hôte ne doit pas avoir \"http://\" d'ajouté au début, mais ignorera "
+"l'identifiant du protocole si fourni.\n"
+"Si aucun [code]port[/code] n'est spécifié (ou [code]-1[/code] est utilisé), "
+"il est automatiquement défini à 80 pour HTTP et 443 pour HTTPS (dans le cas "
+"où [code]use_ssl[/code] est activé).\n"
+"[code]verify_host[/code] vérifie l'identité SSL de l'hôte si elle est "
+"définie à [code]true[/code]."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -33872,6 +36824,11 @@ msgid ""
"value returned will be [code]-1[/code]. If using chunked transfer encoding, "
"the body length will also be [code]-1[/code]."
msgstr ""
+"Retourne la longueur du corps de la requête.\n"
+"[b]Note :[/b] Certains serveurs web peuvent ne pas envoyer de longueur du "
+"corps. Dans ce cas, la valeur retournée sera [code]-1[/code]. Si vous "
+"utilisez l'encodage de transfert par morceau, la longueur du corps sera "
+"également [code]-1[/code]."
#: doc/classes/HTTPClient.xml
msgid "Returns the response's HTTP status code."
@@ -33931,6 +36888,8 @@ msgid ""
"This needs to be called in order to have any request processed. Check "
"results with [method get_status]."
msgstr ""
+"Cela doit être appelé pour que les requêtes puissent être traitée. Vérifiez "
+"les résultats avec [method get_status]."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34039,6 +36998,18 @@ msgid ""
"Method].\n"
"Sends the body data raw, as a byte array and does not encode it in any way."
msgstr ""
+"Envoyez une requête brute à l'hôte connecté.\n"
+"Le paramètre URL est généralement juste la partie après le nom de l'hôte, "
+"donc pour [code]http://somehost.com/index.php[/code], c'est [code]/index."
+"php[/code]. Lors de l'envoi de requêtes vers un serveur de proxy HTTP, ça "
+"doit être une URL absolue. Pour [constant HTTPClient.METHOD_OPTIONS] "
+"requêtes, [code]*[/code] est également autorisé. Pour [constant HTTPClient."
+"METHOD_CONNECT] demande, ça doit être le composant d'autorité ([code]host:"
+"port[/code]).\n"
+"Les en-têtes sont des en-têtes de requête HTTP. Pour les méthodes HTTP "
+"disponibles, voir [enum Method].\n"
+"Envoie les données de corps brutes, comme un tableau d'octet et ne l'encode "
+"pas."
#: doc/classes/HTTPClient.xml doc/classes/HTTPRequest.xml
msgid ""
@@ -34095,6 +37066,10 @@ msgid ""
"GET request, but without the response body. This is useful to request "
"metadata like HTTP headers or to check if a resource exists."
msgstr ""
+"La méthode HTTP \"HEAD\". La méthode \"HEAD\" demande une réponse identique "
+"à celle d'une requête \"GET\", mais sans le corps de la réponse. Ceci est "
+"utile pour demander des métadonnées comme des en-têtes HTTP ou pour vérifier "
+"si une ressource existe."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34102,6 +37077,10 @@ msgid ""
"specified resource, often causing a change in state or side effects on the "
"server. This is often used for forms and submitting data or uploading files."
msgstr ""
+"La méthode HTTP \"POST\". La méthode \"POST\" est utilisée pour soumettre "
+"une entité à la ressource spécifiée, causant souvent un changement d'état "
+"sur le serveur. Ceci est souvent utilisé pour les formulaires, pour "
+"soumettre des données ou télécharger des fichiers."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34110,6 +37089,11 @@ msgid ""
"\"create or update\" and PUT as \"update\", although many services tend to "
"not make a clear distinction or change their meaning)."
msgstr ""
+"La méthode HTTP \"PUT\". La méthode \"PUT\" demander à remplacer toutes les "
+"représentations actuelles de la ressource cible par les données fournies. "
+"(Vous pouvez considérer \"POST\" comme une méthode pour \"créer ou mettre à "
+"jour\" et \"PUT\" comme \"mise à jour\", même que de nombreux services ne "
+"font pas de distinction voire en change leur sens)."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34124,6 +37108,9 @@ msgid ""
"HTTP OPTIONS method. The OPTIONS method asks for a description of the "
"communication options for the target resource. Rarely used."
msgstr ""
+"La méthode HTTP \"OPTIONS\". La méthode \"OPTIONS\" demande une description "
+"des options de communication pour la ressource cible. Elle est rarement "
+"utilisée."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34131,18 +37118,25 @@ msgid ""
"the path to the target resource. Returns the entire HTTP request received in "
"the response body. Rarely used."
msgstr ""
+"La méthode HTTP \"TRACE\". La méthode \"TRACE\" effectue un test de boucle "
+"de message suivant le chemin vers la ressource cible. Retourne toute la "
+"requête \"HTTP\" reçue dans le corps de réponse. Elle est rarement utilisée."
#: doc/classes/HTTPClient.xml
msgid ""
"HTTP CONNECT method. The CONNECT method establishes a tunnel to the server "
"identified by the target resource. Rarely used."
msgstr ""
+"La méthode HTTP \"CONNECT\". La méthode \"CONNECT\" établit un tunnel vers "
+"serveur identifié par la ressource cible. Elle est rarement utilisée."
#: doc/classes/HTTPClient.xml
msgid ""
"HTTP PATCH method. The PATCH method is used to apply partial modifications "
"to a resource."
msgstr ""
+"La méthode HTTP \"PATCH\". La méthode \"PATCH\" est utilisée pour appliquer "
+"des modifications partielles à une ressource."
#: doc/classes/HTTPClient.xml
msgid "Represents the size of the [enum Method] enum."
@@ -34161,6 +37155,7 @@ msgstr ""
#: doc/classes/HTTPClient.xml
msgid "Status: DNS failure: Can't resolve the hostname for the given URL."
msgstr ""
+"Statut: Échec du DNS : N'a pu résoudre le nom d'hôte pour l'URL spécifiée."
#: doc/classes/HTTPClient.xml
msgid "Status: Currently connecting to server."
@@ -34196,6 +37191,9 @@ msgid ""
"everything so far is OK and that the client should continue with the request "
"(or ignore this status if already finished)."
msgstr ""
+"Le code d'état HTTP [code]100 Continue[/code]. La réponse intermédiaire qui "
+"indique que tout est bon jusqu'à présent et que le client devrait continuer "
+"avec cette demande (ou ignorer ce statut s'il a déjà terminé)."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34203,6 +37201,9 @@ msgid ""
"[code]Upgrade[/code] request header by the client. Indicates the protocol "
"the server is switching to."
msgstr ""
+"Le code d'état HTTP [code]101 Switching Protocol[/code]. Envoyé en réponse à "
+"une en-tête de requête [code]Upgrade[/code] du client. Précise le nouveau "
+"protocole que le serveur utilise dès à présent."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34224,6 +37225,13 @@ msgid ""
"TRACE: The message body contains the request message as received by the "
"server."
msgstr ""
+"Le code d'état HTTP [code]200 OK[/code]. La requête a réussi. C'est la "
+"réponse par défaut pour les requêtes réussies. La signification varie selon "
+"la requête. Pour \"GET\" : La ressource a été récupérée et est transmise "
+"dans le corps du message. Pour \"HEAD\" : Les en-têtes de l'entité sont dans "
+"le corps du message. Pour \"POST\" : La ressource décrivant le résultat de "
+"l'action est transmise dans le corps du message. Pour \"TRACE\" : Le corps "
+"du message contient le message de requête reçu par le serveur."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34231,6 +37239,9 @@ msgid ""
"new resource has been created as a result of it. This is typically the "
"response sent after a PUT request."
msgstr ""
+"Le code d'état HTTP [code]201 Created[/code]. La requête a réussi et une "
+"nouvelle ressource a été créée en conséquence. C'est généralement la réponse "
+"envoyée après une requête \"PUT\"."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34240,6 +37251,11 @@ msgid ""
"processing the request. It is intended for cases where another process or "
"server handles the request, or for batch processing."
msgstr ""
+"Le code d'état HTTP [code]202 Accepted[/code]. La requête a été reçue mais "
+"n'a pas encore été traitée. Aucune réponse n'est envoyé même asynchrone "
+"indiquant le résultat du traitement de cette requête. Il est destiné aux cas "
+"où un autre processus ou un serveur traite la requête, ou pour le traitement "
+"par lots."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34249,6 +37265,11 @@ msgid ""
"party copy. Except this condition, 200 OK response should be preferred "
"instead of this response."
msgstr ""
+"Le code d'état HTTP [code]203 Non-Authoritative Information[/code]. Ce code "
+"de réponse signifie que l'ensemble de méta-donnée retournée n'est pas la "
+"copie exacte de celles sur le serveur d'origine, mais composée à partir "
+"d'une copie locale ou autre. Sauf dans ce cas, la réponse 200 \"OK\" est "
+"préférable à la place de cette réponse."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34256,6 +37277,10 @@ msgid ""
"for this request, but the headers may be useful. The user-agent may update "
"its cached headers for this resource with the new ones."
msgstr ""
+"Le code d'état HTTP [code]204 No Content[/code]. Il n'y a pas de contenu à "
+"retourner en réponse à cette requête, mais les en-têtes peuvent contenir des "
+"informations. Le user-agent peut mettre à jour les en-têtes de cette "
+"ressource qu'il a en cache avec ces nouvelles données."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34264,6 +37289,10 @@ msgid ""
"caused the request to be sent to its original state as received from the "
"origin server."
msgstr ""
+"Le code d'état HTTP [code]205 Reset Content[/code]. Le serveur a rempli la "
+"requête et souhaite que le client réinitialise son « vue de document » qui a "
+"envoyé la requête à son état original tel qu'il a été reçu du serveur "
+"d'origine."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34271,6 +37300,9 @@ msgid ""
"used because of a range header sent by the client to separate download into "
"multiple streams."
msgstr ""
+"Le code d'état HTTP [code]206 Partial Content[/code]. Ce code de réponse est "
+"utilisé suivant l'intervalle spécifié dans l'en-tête envoyé par le client "
+"pour que le téléchargement soit disponible dans plusieurs flux."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34278,6 +37310,9 @@ msgid ""
"response conveys information about multiple resources in situations where "
"multiple status codes might be appropriate."
msgstr ""
+"Le code d'état HTTP [code]207 Multi-Status[/code] (WebDAV). Une réponse "
+"multi-états qui transmet des informations sur plusieurs ressources dans des "
+"situations où plusieurs codes de statut seraient appropriés."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34285,6 +37320,10 @@ msgid ""
"DAV: propstat response element to avoid enumerating the internal members of "
"multiple bindings to the same collection repeatedly."
msgstr ""
+"Le code d'état HTTP [code]208 Already Reported[/code] (WebDAV). Utilisé à "
+"l'intérieur d'un DAV : l'élément de réponse \"propstat\" pour éviter "
+"d'énumérer plusieurs fois les membres internes de liaisons d'une même "
+"collection."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34292,6 +37331,10 @@ msgid ""
"a GET request for the resource, and the response is a representation of the "
"result of one or more instance-manipulations applied to the current instance."
msgstr ""
+"Le code d'état HTTP [code]226 IM Used[/code] (WebDAV). Le serveur a traité "
+"une requête GET pour cette ressource, et la réponse est une représentation "
+"du résultat d'une ou plusieurs manipulations d'instance appliquées à "
+"l'instance actuelle."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34299,6 +37342,10 @@ msgid ""
"one possible responses and there is no standardized way to choose one of the "
"responses. User-agent or user should choose one of them."
msgstr ""
+"Le code d'état HTTP [code]300 Multiple Choice[/code]. La requête a plusieurs "
+"réponses possibles et il n'y a pas de moyen spécifique de choisir la bonne "
+"réponse. C'est alors le user-agent ou l'utilisateur qui devrait la choisir "
+"parmi celle retournées."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34306,6 +37353,9 @@ msgid ""
"response code means the URI of requested resource has been changed. The new "
"URI is usually included in the response."
msgstr ""
+"Le code d'état HTTP [code]301 Moved Permanently[/code]. Redirection. Ce code "
+"de réponse signifie que l'URI des ressources demandées a été modifiée. La "
+"nouvelle URI est généralement retournée dans cette réponse."
#: doc/classes/HTTPClient.xml
msgid ""
@@ -34652,6 +37702,7 @@ msgid "A node with the ability to send HTTP(S) requests."
msgstr "Un nœud qui permet d'envoyer des requêtes HTTP(S)."
#: doc/classes/HTTPRequest.xml
+#, fuzzy
msgid ""
"A node with the ability to send HTTP requests. Uses [HTTPClient] "
"internally.\n"
@@ -34678,7 +37729,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -34894,13 +37945,14 @@ msgstr "Nombre maximal de redirections autorisées."
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -34962,7 +38014,6 @@ msgstr ""
"max_redirects]."
#: doc/classes/Image.xml
-#, fuzzy
msgid "Image datatype."
msgstr "Type de données d’image."
@@ -36455,7 +39506,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -37095,10 +40149,14 @@ msgstr "Type d’évènement d’entrée pour les évènements de mouvement de s
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -37109,6 +40167,15 @@ msgid "Mouse and input coordinates"
msgstr "Les coordonnées de la souris"
#: doc/classes/InputEventMouseMotion.xml
+#, fuzzy
+msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+"Retourne le nombre de disposition de clavier.\n"
+"[b]Note :[/b] Cette méthode est implémentée sous Linux, macOS et Windows."
+
+#: doc/classes/InputEventMouseMotion.xml
msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
@@ -37467,6 +40534,13 @@ msgstr ""
"automatiquement."
#: doc/classes/InterpolatedCamera.xml
+#, fuzzy
+msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+"La méthode de mise à jour de la camera. Voir [enum Camera2DProcessMode]."
+
+#: doc/classes/InterpolatedCamera.xml
msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
@@ -37638,7 +40712,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -39640,7 +42725,7 @@ msgstr ""
#: doc/classes/Light.xml
msgid "The light will affect objects in the selected layers."
-msgstr "La lumière affectera les objets dans les claques sélectionnés."
+msgstr "La lumière affectera les objets dans les calques sélectionnés."
#: doc/classes/Light.xml
msgid ""
@@ -41448,37 +44533,32 @@ msgstr ""
"un tableau des sommets donc ce tableau doit être présent."
#: doc/classes/Mesh.xml
-#, fuzzy
msgid "Mesh array contains normals."
msgstr "Un maillage de points contient des normales."
#: doc/classes/Mesh.xml
-#, fuzzy
msgid "Mesh array contains tangents."
msgstr "Un maillage de points contient des tangentes."
#: doc/classes/Mesh.xml
-#, fuzzy
msgid "Mesh array contains colors."
-msgstr "Un maillage de points contient les couleurs."
+msgstr "Un maillage de points contient des couleurs."
#: doc/classes/Mesh.xml
-#, fuzzy
msgid "Mesh array contains UVs."
-msgstr "Un maillage de points contient les UV."
+msgstr "Un maillage de points contient des UV."
#: doc/classes/Mesh.xml
msgid "Mesh array contains second UV."
-msgstr "Un maillage de points contient les UV secondaires."
+msgstr "Un maillage de points contient des UV secondaires."
#: doc/classes/Mesh.xml
-#, fuzzy
msgid "Mesh array contains bones."
-msgstr "Un maillage de points contient les os."
+msgstr "Un maillage de points contient des os."
#: doc/classes/Mesh.xml
msgid "Mesh array contains bone weights."
-msgstr "Un maillage de points contient les poids des os."
+msgstr "Un maillage de points contient des poids d'os."
#: doc/classes/Mesh.xml
msgid "Mesh array uses indices."
@@ -41903,12 +44983,17 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-#, fuzzy
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
-msgstr "Retourne le matériel affecté à la [ImmediateGeometry3D]."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
+msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+#, fuzzy
+msgid "Returns the number of surface override materials."
msgstr "Retourne le nombre de surfaces du matériau."
#: doc/classes/MeshInstance.xml
@@ -41945,7 +45030,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -42783,6 +45871,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -42829,6 +45920,9 @@ msgstr "Retourne le [RID] de la énième forme d'une zone."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -42872,6 +45966,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -42891,6 +45988,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -43046,11 +46146,47 @@ msgid "Destroys the given RID."
msgstr "Supprimer le RID renseigné."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr "Crée une nouvelle carte."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -43171,6 +46307,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Retourne [code]true[/code] si le [code]signal[/code] donné existe."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -43394,20 +46547,40 @@ msgstr "L’instance n’a pas de type."
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
-msgstr "Le rayon de l'agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
+msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -43503,6 +46676,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -43636,6 +46817,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr "Si [code]true[/code], les titres des colonnes sont visibles."
@@ -43813,7 +47004,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -45609,12 +48808,11 @@ msgid ""
msgstr ""
#: doc/classes/Node.xml
-#, fuzzy
msgid ""
"Sends a [method rpc] using an unreliable protocol. Returns [code]null[/code]."
msgstr ""
-"Envoie un [method rpc] en utilisant un protocole non fiable. Retourne un "
-"[Variant] vide."
+"Envoie un [method rpc] en utilisant un protocole non fiable. Retourne "
+"[code]null[/code]."
#: doc/classes/Node.xml
msgid ""
@@ -45839,13 +49037,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -45857,8 +49061,11 @@ msgid "Emitted when the node is renamed."
msgstr "Émis quand le nœud est renommé."
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
-msgstr "Émis quand le nœud entre dans l'arborescence."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
+msgstr ""
#: doc/classes/Node.xml
msgid "Emitted after the node exits the tree and is no longer active."
@@ -45867,15 +49074,22 @@ msgstr "Émis quand le nœud quitte l'arborescence et n'est plus actif."
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
-msgstr "La notification reçue quand un nœud entre dans le [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
+msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+#, fuzzy
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr "La notification reçue quand le nœud va quitter le [SceneTree]."
#: doc/classes/Node.xml
@@ -46152,7 +49366,7 @@ msgstr ""
#: doc/classes/Node2D.xml
msgid "Local [Transform2D]."
-msgstr "[Transform2D] local."
+msgstr "[Transform2D] locale."
#: doc/classes/Node2D.xml
msgid ""
@@ -47872,6 +51086,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -50752,7 +53970,7 @@ msgstr "Représente la taille de l'énumération [enum Monitor]."
#: doc/classes/PHashTranslation.xml
msgid "Optimized translation."
-msgstr "Translation optimisée."
+msgstr "Traduction optimisée."
#: doc/classes/PHashTranslation.xml
msgid ""
@@ -53388,6 +56606,14 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr "Change l'octet à la position donnée."
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+#, fuzzy
+msgid "Sorts the elements of the array in ascending order."
+msgstr "Retire l' élément du tableau à l'index donné."
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -53979,10 +57205,19 @@ msgstr "Un PopupMenu affiche une liste d'options."
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
-"Un [PopupMenu] est un [Control] qui affiche une liste d'options. Souvent "
-"utilisé dans les barres d'outils ou les menus contextuels."
#: doc/classes/PopupMenu.xml
msgid ""
@@ -56378,211 +59613,211 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 1."
-msgstr "Le nom facultatif pour le claque 1 de physique 2D."
+msgstr "Le nom facultatif pour le calque 1 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 10."
-msgstr "Le nom facultatif pour le claque 10 de physique 2D."
+msgstr "Le nom facultatif pour le calque 10 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 11."
-msgstr "Le nom facultatif pour le claque 11 de physique 2D."
+msgstr "Le nom facultatif pour le calque 11 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 12."
-msgstr "Le nom facultatif pour le claque 12 de physique 2D."
+msgstr "Le nom facultatif pour le calque 12 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 13."
-msgstr "Le nom facultatif pour le claque 13 de physique 2D."
+msgstr "Le nom facultatif pour le calque 13 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 14."
-msgstr "Le nom facultatif pour le claque 14 de physique 2D."
+msgstr "Le nom facultatif pour le calque 14 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 15."
-msgstr "Le nom facultatif pour le claque 15 de physique 2D."
+msgstr "Le nom facultatif pour le calque 15 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 16."
-msgstr "Le nom facultatif pour le claque 16 de physique 2D."
+msgstr "Le nom facultatif pour le calque 16 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 17."
-msgstr "Le nom facultatif pour le claque 17 de physique 2D."
+msgstr "Le nom facultatif pour le calque 17 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 18."
-msgstr "Le nom facultatif pour le claque 18 de physique 2D."
+msgstr "Le nom facultatif pour le calque 18 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 19."
-msgstr "Le nom facultatif pour le claque 19 de physique 2D."
+msgstr "Le nom facultatif pour le calque 19 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 2."
-msgstr "Le nom facultatif pour le claque 2 de physique 2D."
+msgstr "Le nom facultatif pour le calque 2 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 20."
-msgstr "Le nom facultatif pour le claque 20 de physique 2D."
+msgstr "Le nom facultatif pour le calque 20 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 21."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 21."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 21."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 22."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 22."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 22."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 23."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 23."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 23."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 24."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 24."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 24."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 25."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 25."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 25."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 26."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 26."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 26."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 27."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 27."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 27."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 28."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 28."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 28."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 29."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 29."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 29."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 3."
-msgstr "Le nom facultatif pour le claque 3 de physique 2D."
+msgstr "Le nom facultatif pour le calque 3 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 30."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 30."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 30."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 31."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 31."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 31."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 32."
-msgstr "Le nom optionnel pour le claque physique 2D numéro 32."
+msgstr "Le nom optionnel pour le calque physique 2D numéro 32."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 4."
-msgstr "Le nom facultatif pour le claque 4 de physique 2D."
+msgstr "Le nom facultatif pour le calque 4 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 5."
-msgstr "Le nom facultatif pour le claque 5 de physique 2D."
+msgstr "Le nom facultatif pour le calque 5 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 6."
-msgstr "Le nom facultatif pour le claque 6 de physique 2D."
+msgstr "Le nom facultatif pour le calque 6 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 7."
-msgstr "Le nom facultatif pour le claque 7 de physique 2D."
+msgstr "Le nom facultatif pour le calque 7 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 8."
-msgstr "Le nom facultatif pour le claque 8 de physique 2D."
+msgstr "Le nom facultatif pour le calque 8 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D physics layer 9."
-msgstr "Le nom facultatif pour le claque 9 de physique 2D."
+msgstr "Le nom facultatif pour le calque 9 de physique 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 1."
-msgstr "Le nom facultatif pour le claque 1 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 1 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 10."
-msgstr "Le nom facultatif pour le claque 10 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 10 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 11."
-msgstr "Le nom facultatif pour le claque 11 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 11 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 12."
-msgstr "Le nom facultatif pour le claque 12 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 12 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 13."
-msgstr "Le nom facultatif pour le claque 13 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 13 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 14."
-msgstr "Le nom facultatif pour le claque 14 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 14 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 15."
-msgstr "Le nom facultatif pour le claque 15 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 15 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 16."
-msgstr "Le nom facultatif pour le claque 16 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 16 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 17."
-msgstr "Le nom facultatif pour le claque 17 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 17 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 18."
-msgstr "Le nom facultatif pour le claque 18 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 18 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 19."
-msgstr "Le nom facultatif pour le claque 19 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 19 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 2."
-msgstr "Le nom facultatif pour le claque 2 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 2 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 20."
-msgstr "Le nom facultatif pour le claque 20 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 20 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 3."
-msgstr "Le nom facultatif pour le claque 3 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 3 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 4."
-msgstr "Le nom facultatif pour le claque 4 rendu 2D."
+msgstr "Le nom facultatif pour le calque 4 rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 5."
-msgstr "Le nom facultatif pour le claque 5 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 5 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 6."
-msgstr "Le nom facultatif pour le claque 6 rendu 2D."
+msgstr "Le nom facultatif pour le calque 6 rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 7."
-msgstr "Le nom facultatif pour le claque 7 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 7 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 8."
-msgstr "Le nom facultatif pour le claque 8 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 8 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 2D render layer 9."
-msgstr "Le nom facultatif pour le claque 9 de rendu 2D."
+msgstr "Le nom facultatif pour le calque 9 de rendu 2D."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -56778,212 +60013,211 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 1."
-msgstr "Le nom facultatif pour le claque 1 de physique 3D."
+msgstr "Le nom facultatif pour le calque 1 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 10."
-msgstr "Le nom facultatif pour le claque 10 de physique 3D."
+msgstr "Le nom facultatif pour le calque 10 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 11."
-msgstr "Le nom facultatif pour le claque 11 de physique 3D."
+msgstr "Le nom facultatif pour le calque 11 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 12."
-msgstr "Le nom facultatif pour le claque 12 de physique 3D."
+msgstr "Le nom facultatif pour le calque 12 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 13."
-msgstr "Le nom facultatif pour le claque 13 de physique 3D."
+msgstr "Le nom facultatif pour le calque 13 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 14."
-msgstr "Le nom facultatif pour le claque 14 de physique 3D."
+msgstr "Le nom facultatif pour le calque 14 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 15."
-msgstr "Le nom facultatif pour le claque 15 de physique 3D."
+msgstr "Le nom facultatif pour le calque 15 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 16."
-msgstr "Le nom facultatif pour le claque 16 de physique 3D."
+msgstr "Le nom facultatif pour le calque 16 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 17."
-msgstr "Le nom facultatif pour le claque 17 de physique 3D."
+msgstr "Le nom facultatif pour le calque 17 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 18."
-msgstr "Le nom facultatif pour le claque 18 de physique 3D."
+msgstr "Le nom facultatif pour le calque 18 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 19."
-msgstr "Le nom facultatif pour le claque 19 de physique 3D."
+msgstr "Le nom facultatif pour le calque 19 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 2."
-msgstr "Le nom facultatif pour le claque 2 de physique 3D."
+msgstr "Le nom facultatif pour le calque 2 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 20."
-msgstr "Le nom facultatif pour le claque 20 de physique 3D."
+msgstr "Le nom facultatif pour le calque 20 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 21."
-msgstr "Le nom facultatif pour le claque 21 de physique 3D."
+msgstr "Le nom facultatif pour le calque 21 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 22."
-msgstr "Le nom facultatif pour le claque 22 de physique 3D."
+msgstr "Le nom facultatif pour le calque 22 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 23."
-msgstr "Le nom facultatif pour le claque 23 de physique 3D."
+msgstr "Le nom facultatif pour le calque 23 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 24."
-msgstr "Le nom facultatif pour le claque 24 de physique 3D."
+msgstr "Le nom facultatif pour le calque 24 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 25."
-msgstr "Le nom facultatif pour le claque 25 de physique 3D."
+msgstr "Le nom facultatif pour le calque 25 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 26."
-msgstr "Le nom facultatif pour le claque 26 de physique 3D."
+msgstr "Le nom facultatif pour le calque 26 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 27."
-msgstr "Le nom facultatif pour le claque 27 de physique 3D."
+msgstr "Le nom facultatif pour le calque 27 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 28."
-msgstr "Le nom facultatif pour le claque 28 de physique 3D."
+msgstr "Le nom facultatif pour le calque 28 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 29."
-msgstr "Le nom facultatif pour le claque 29 de physique 3D."
+msgstr "Le nom facultatif pour le calque 29 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 3."
-msgstr "Le nom facultatif pour le claque 3 de physique 3D."
+msgstr "Le nom facultatif pour le calque 3 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 30."
-msgstr "Le nom facultatif pour le claque 30 de physique 3D."
+msgstr "Le nom facultatif pour le calque 30 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 31."
-msgstr "Le nom facultatif pour le claque 31 de physique 3D."
+msgstr "Le nom facultatif pour le calque 31 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 32."
-msgstr "Le nom facultatif pour le claque 32 de physique 3D."
+msgstr "Le nom facultatif pour le calque 32 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 4."
-msgstr "Le nom facultatif pour le claque 4 de physique 3D."
+msgstr "Le nom facultatif pour le calque 4 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 5."
-msgstr "Le nom facultatif pour le claque 5 de physique 3D."
+msgstr "Le nom facultatif pour le calque 5 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 6."
-msgstr "Le nom facultatif pour le claque 6 de physique 3D."
+msgstr "Le nom facultatif pour le calque 6 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 7."
-msgstr "Le nom facultatif pour le claque 7 de physique 3D."
+msgstr "Le nom facultatif pour le calque 7 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 8."
-msgstr "Le nom facultatif pour le claque 8 de physique 3D."
+msgstr "Le nom facultatif pour le calque 8 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 9."
-msgstr "Le nom facultatif pour le claque 9 de physique 3D."
+msgstr "Le nom facultatif pour le calque 9 de physique 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 1."
-msgstr "Le nom facultatif pour le claque 1 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 1 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 10."
-msgstr "Le nom facultatif pour le claque 10 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 10 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 11."
-msgstr "Le nom facultatif pour le claque 11 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 11 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 12."
-msgstr "Le nom facultatif pour le claque 12 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 12 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 13."
-msgstr "Le nom facultatif pour le claque 13 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 13 de rendu 3D."
#: doc/classes/ProjectSettings.xml
-#, fuzzy
msgid "Optional name for the 3D render layer 14."
-msgstr "Le nom facultatif pour le claque 14 de rendu 3D"
+msgstr "Le nom facultatif pour le calque 14 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 15."
-msgstr "Le nom facultatif pour le claque 15 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 15 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 16."
-msgstr "Le nom facultatif pour le claque 16 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 16 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 17."
-msgstr "Le nom facultatif pour le claque 17 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 17 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 18."
-msgstr "Le nom facultatif pour le claque 18 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 18 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 19."
-msgstr "Le nom facultatif pour le claque 19 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 19 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 2."
-msgstr "Le nom facultatif pour le claque 2 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 2 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 20."
-msgstr "Le nom facultatif pour le claque 20 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 20 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 3."
-msgstr "Le nom facultatif pour le claque 3 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 3 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 4."
-msgstr "Le nom facultatif pour le claque 4 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 4 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 5."
-msgstr "Le nom facultatif pour le claque 5 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 5 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 6."
-msgstr "Le nom facultatif pour le claque 6 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 6 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 7."
-msgstr "Le nom facultatif pour le claque 7 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 7 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 8."
-msgstr "Le nom facultatif pour le claque 8 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 8 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 9."
-msgstr "Le nom facultatif pour le claque 9 de rendu 3D."
+msgstr "Le nom facultatif pour le calque 9 de rendu 3D."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -57211,14 +60445,15 @@ msgid ""
msgstr ""
#: doc/classes/ProjectSettings.xml
-#, fuzzy
msgid ""
"Size of the hash table used for the broad-phase 2D hash grid algorithm.\n"
"[b]Note:[/b] Not used if [member ProjectSettings.physics/2d/use_bvh] is "
"enabled."
msgstr ""
"Taille de la table de hachage utilisée pour l'algorithme de grille de "
-"hachage 2D à large phase."
+"hachage 2D à large phase.\n"
+"[b]Note :[/b] Non utilisé si [member ProjectSettings.physics/2d/use_bvh] est "
+"actif."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -57794,20 +61029,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -57815,19 +61058,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -57859,14 +61111,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -58328,8 +61588,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -62893,6 +66153,7 @@ msgid ""
msgstr ""
#: doc/classes/SceneTreeTween.xml
+#, fuzzy
msgid ""
"[SceneTreeTween] is a tween managed by the scene tree. As opposed to "
"[Tween], it does not require the instantiation of a node.\n"
@@ -62907,24 +66168,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -62933,8 +66193,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -62942,16 +66203,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -62963,7 +66224,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
"[SceneTreeTween] est un tween géré par l'arborescence. Contrairement à un "
"[Tween], il ne nécessite pas la création d'un nœud.\n"
@@ -63078,21 +66339,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -63128,11 +66392,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -63173,13 +66437,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -63258,12 +66522,13 @@ msgstr ""
"[/codeblock]"
#: doc/classes/SceneTreeTween.xml
+#, fuzzy
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -63361,12 +66626,13 @@ msgstr ""
"[/codeblock]"
#: doc/classes/SceneTreeTween.xml
+#, fuzzy
msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -63426,16 +66692,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -63443,7 +66708,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -64809,11 +68074,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr "La [Transform] globale de ce nœud."
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -67479,10 +70763,32 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
-"Formate la chaîne de caractères en remplaçant toutes les occurences de "
-"[code]placeholder[/code] par [code]values[/code]."
#: doc/classes/String.xml
msgid "If the string is a valid file path, returns the base directory name."
@@ -67706,11 +71012,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -68206,9 +71512,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -69188,12 +72496,12 @@ msgstr ""
"[code]tab_idx[/code], le rendant non-interactif."
#: doc/classes/TabContainer.xml
-#, fuzzy
msgid ""
"If [code]hidden[/code] is [code]true[/code], hides the tab at index "
"[code]tab_idx[/code], making it disappear from the tab area."
msgstr ""
-"Retourne [code]true[/code] si la piste à l'index [code]idx[/code] est active."
+"Si [code]hidden[/code] est [code]true[/code], cache l'onglet à l'index "
+"[code]tab_idx[/code], se faisait disparaitre de l'aire des onglets."
#: doc/classes/TabContainer.xml
msgid "Sets an icon for the tab at index [code]tab_idx[/code]."
@@ -69997,6 +73305,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr "Si [code]true[/code], un clic droit affiche le menu contextuel."
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "Si [code]true[/code], la valeur peut être sélectionnée et modifiée."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -70491,7 +73804,7 @@ msgid ""
"way to render them in a hardware-accelerated manner."
msgstr ""
"Les [TextureArray] stockent un tableau de plusieurs [Image] dans une seule "
-"[Texture] de base. Chaque claque de ce tableau de textures génère ses "
+"[Texture] de base. Chaque calque de ce tableau de textures génère ses "
"propres mipmaps. C'est une bonne alternative pour les atlas de textures. "
"Voir aussi [Texture3D].\n"
"Les [TextureArray] doivent être affichés avec des shaders. Après "
@@ -72157,7 +75470,7 @@ msgstr "Retourne le [enum TileMode] de la tuile."
#: doc/classes/TileSet.xml
msgid "Returns the tile's Z index (drawing layer)."
-msgstr "Retourne l'index selon Z (le claque d'affichage) de la tuile."
+msgstr "Retourne l'index selon Z (le calque d'affichage) de la tuile."
#: doc/classes/TileSet.xml
msgid "Sets a light occluder for the tile."
@@ -72899,13 +76212,13 @@ msgstr ""
"matrice. L'axe [code]axis[/code] doit être normalisé."
#: doc/classes/Transform.xml
-#, fuzzy
msgid ""
"Returns a copy of the transform with its basis and origin scaled by the "
"given [code]scale[/code] factor, using matrix multiplication."
msgstr ""
-"Met à l'échelle le transform par le facteur d'échelle donné, en utilisant la "
-"multiplication matricielle."
+"Retourne une copie de la transformation avec sa base et son origine mis à "
+"l'échelle par le facteur [code]scale[/code], en utilisant la multiplication "
+"matricielle."
#: doc/classes/Transform.xml doc/classes/Transform2D.xml
msgid ""
@@ -73194,6 +76507,7 @@ msgid "Control to show a tree of items."
msgstr "Un contrôle pour afficher l'arborescence d'éléments."
#: doc/classes/Tree.xml
+#, fuzzy
msgid ""
"This shows a tree of items that can be selected, expanded and collapsed. The "
"tree can have multiple columns with custom controls like text editing, "
@@ -73215,7 +76529,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
"Ça affiche une arborescence d'éléments qui peuvent être sélectionnés, "
"développés ou réduits. Cette arborescence peut avoir plusieurs colonnes avec "
@@ -76007,11 +79332,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -76092,8 +79417,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -76175,9 +79500,8 @@ msgid ""
msgstr ""
#: doc/classes/VFlowContainer.xml
-#, fuzzy
msgid "Vertical flow container."
-msgstr "Conteneur vertical."
+msgstr "Conteneur de flux vertical."
#: doc/classes/VFlowContainer.xml
msgid "Vertical version of [FlowContainer]."
@@ -76662,13 +79986,12 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-#, fuzzy
msgid ""
"If [code]true[/code], the viewport will use a unique copy of the [World] "
"defined in [member world]."
msgstr ""
-"Si [code]true[/code], la fenêtre d'affichage utilisera le [World] défini par "
-"la propriété [code]world[/code]."
+"Si [code]true[/code], la fenêtre d'affichage utilisera une copie du [World] "
+"défini dans la propriété [member world]."
#: doc/classes/Viewport.xml
msgid ""
@@ -76726,9 +80049,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -76761,8 +80085,12 @@ msgstr ""
"l'arrière-plan de manière transparente."
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
-msgstr "Le mode de rendu de la fenêtre d'affichage."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
+msgstr ""
#: doc/classes/Viewport.xml
msgid ""
@@ -77315,7 +80643,7 @@ msgstr ""
#: doc/classes/VisualInstance.xml
msgid "Enables a particular layer in [member layers]."
-msgstr "Active un claque spécifique dans [member layers]."
+msgstr "Active un calque spécifique dans [member layers]."
#: doc/classes/VisualInstance.xml
msgid ""
@@ -79213,9 +82541,7 @@ msgstr ""
"RID qui est retourné. Ce RID peut être utilisé dans la plupart des fonctions "
"[code]camera_*[/code] VisualServer.\n"
"Une fois terminé avec votre RID, vous voudrez libérer le RID à l’aide de la "
-"méthode statique [method free_rid] du VisualServer.\n"
-"Pour placer dans une scène, attachez cette caméra à une instance en "
-"utilisant la [method instance_set_base] utilisant le RID retourné."
+"méthode statique [method free_rid] du VisualServer."
#: doc/classes/VisualServer.xml
msgid ""
@@ -79480,9 +82806,7 @@ msgstr ""
"consulté avec le RID qui est retourné. Ce RID peut être utilisé dans la "
"plupart des fonctions [code]canvas_light_*[/code] VisualServer.\n"
"Une fois terminé avec votre RID, vous voudrez libérer le RID à l’aide de la "
-"méthode statique [method free_rid] du VisualServer.\n"
-"Pour placer dans une scène, attachez ce canevas de lumière à une instance en "
-"utilisant la [method instance_set_base] utilisant le RID retourné."
+"méthode statique [method free_rid] du VisualServer."
#: doc/classes/VisualServer.xml
msgid ""
@@ -79503,9 +82827,7 @@ msgstr ""
"consulté avec le RID qui est retourné. Ce RID peut être utilisé dans la "
"plupart des fonctions [code]canvas_light_ocluder_*[/code] VisualServer.\n"
"Une fois terminé avec votre RID, vous voudrez libérer le RID à l’aide de la "
-"méthode statique [method free_rid] du VisualServer.\n"
-"Pour placer dans une scène, attachez ce occulteur de lumière à une instance "
-"en utilisant la [method instance_set_base] utilisant le RID retourné."
+"méthode statique [method free_rid] du VisualServer."
#: doc/classes/VisualServer.xml
msgid "Enables or disables light occluder."
@@ -79687,9 +83009,7 @@ msgstr ""
"avec le RID qui est retourné. Ce RID peut être utilisé dans la plupart des "
"fonctions [code]environment_*[/code] VisualServer.\n"
"Une fois terminé avec votre RID, vous voudrez libérer le RID à l’aide de la "
-"méthode statique [method free_rid] du VisualServer.\n"
-"Pour placer dans une scène, attachez cet environnement à une instance en "
-"utilisant la [method instance_set_base] utilisant le RID retourné."
+"méthode statique [method free_rid] du VisualServer."
#: doc/classes/VisualServer.xml
msgid ""
@@ -79722,7 +83042,7 @@ msgstr "Définit l'intensité de la couleur de l'arrière-plan."
#: doc/classes/VisualServer.xml
msgid "Sets the maximum layer to use if using Canvas background mode."
msgstr ""
-"Définit le claque maximal à utiliser si l'arrière-plan utilise un canevas."
+"Définit le calque maximal à utiliser si l'arrière-plan utilise un canevas."
#: doc/classes/VisualServer.xml
msgid ""
@@ -80516,9 +83836,7 @@ msgstr ""
"avec le RID qui est retourné. Ce RID peut être utilisé dans la plupart des "
"fonctions [code]material_*[/code] VisualServer.\n"
"Une fois terminé avec votre RID, vous voudrez libérer le RID à l’aide de la "
-"méthode statique [method free_rid] du VisualServer.\n"
-"Pour placer dans une scène, attachez cette lumière spot à une instance en "
-"utilisant la [method instance_set_base] utilisant le RID retourné."
+"méthode statique [method free_rid] du VisualServer."
#: doc/classes/VisualServer.xml
msgid "Returns the value of a certain material's parameter."
@@ -81218,9 +84536,7 @@ msgstr ""
"le RID qui est retourné. Ce RID peut être utilisé dans la plupart des "
"fonctions [code]shader_*[/code] VisualServer.\n"
"Une fois terminé avec votre RID, vous voudrez libérer le RID à l’aide de la "
-"méthode statique [method free_rid] du VisualServer.\n"
-"Pour placer dans une scène, attachez ce shader vide à une instance en "
-"utilisant la [method instance_set_base] utilisant le RID retourné."
+"méthode statique [method free_rid] du VisualServer."
#: doc/classes/VisualServer.xml
#, fuzzy
@@ -81278,9 +84594,7 @@ msgstr ""
"RID qui est retourné. Ce RID peut être utilisé dans la plupart des fonctions "
"[code]skeleton_*[/code] VisualServer.\n"
"Une fois terminé avec votre RID, vous voudrez libérer le RID à l’aide de la "
-"méthode statique [method free_rid] du VisualServer.\n"
-"Pour placer dans une scène, attachez ce squelette à une instance en "
-"utilisant la [method instance_set_base] utilisant le RID retourné."
+"méthode statique [method free_rid] du VisualServer."
#: doc/classes/VisualServer.xml
msgid "Returns the number of bones allocated for this skeleton."
@@ -81298,9 +84612,7 @@ msgstr ""
"RID qui est retourné. Ce RID peut être utilisé dans la plupart des fonctions "
"[code]sky_*[/code] VisualServer.\n"
"Une fois terminé avec votre RID, vous voudrez libérer le RID à l’aide de la "
-"méthode statique [method free_rid] du VisualServer.\n"
-"Pour placer dans une scène, attachez ce ciel vide à une instance en "
-"utilisant la [method instance_set_base] utilisant le RID retourné."
+"méthode statique [method free_rid] du VisualServer."
#: doc/classes/VisualServer.xml
msgid "Sets a sky's texture."
@@ -81346,9 +84658,7 @@ msgstr ""
"avec le RID qui est retourné. Ce RID peut être utilisé dans la plupart des "
"fonctions [code]texture_*[/code] VisualServer.\n"
"Une fois terminé avec votre RID, vous voudrez libérer le RID à l’aide de la "
-"méthode statique [method free_rid] du VisualServer.\n"
-"Pour placer dans une scène, attachez cette texture vide à une instance en "
-"utilisant la [method instance_set_base] utilisant le RID retourné."
+"méthode statique [method free_rid] du VisualServer."
#: doc/classes/VisualServer.xml
msgid ""
@@ -81779,15 +85089,16 @@ msgid "Number of weights/bones per vertex."
msgstr "Nombre de poids / os par sommet."
#: doc/classes/VisualServer.xml
+#, fuzzy
msgid "The minimum Z-layer for canvas items."
msgstr ""
-"Le niveau minimal du claque de profondeur pour les éléments de canevas."
+"Le niveau minimal du calque de profondeur pour les éléments de canevas."
#: doc/classes/VisualServer.xml
#, fuzzy
msgid "The maximum Z-layer for canvas items."
msgstr ""
-"Le niveau maximal du claque de profondeur pour les éléments de canevas."
+"Le niveau maximal du calque de profondeur pour les éléments de canevas."
#: doc/classes/VisualServer.xml
msgid ""
@@ -86051,7 +89362,7 @@ msgstr "L’espace physique du World."
#: doc/classes/World2D.xml
msgid "Class that has everything pertaining to a 2D world."
-msgstr ""
+msgstr "La classe pour tout ce qui est en rapport avec le monde 2D."
#: doc/classes/World2D.xml
msgid ""
@@ -86090,6 +89401,8 @@ msgid ""
"Default environment properties for the entire scene (post-processing "
"effects, lighting and background settings)."
msgstr ""
+"Les propriétés par défaut de l'environnement de toute la scène (effets de "
+"post-processing, éclairage et réglages de l'arrière-plan)."
#: doc/classes/WorldEnvironment.xml
msgid ""
diff --git a/doc/translations/gl.po b/doc/translations/gl.po
index 92ad8f3f22..17fb042ad7 100644
--- a/doc/translations/gl.po
+++ b/doc/translations/gl.po
@@ -395,7 +395,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1102,7 +1102,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9966,7 +9966,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10131,7 +10137,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12140,10 +12152,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19425,13 +19439,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19441,7 +19459,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19458,23 +19480,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28262,7 +28284,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28401,13 +28423,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29820,7 +29843,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30394,10 +30420,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30409,6 +30439,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30720,6 +30756,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30884,7 +30925,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34631,11 +34683,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34672,7 +34729,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35464,6 +35524,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35509,6 +35572,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35552,6 +35618,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35571,6 +35640,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35700,11 +35772,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35814,6 +35922,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36020,20 +36145,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36127,6 +36272,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36247,6 +36400,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36416,7 +36579,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38291,13 +38462,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38309,7 +38486,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38319,15 +38499,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40034,6 +40220,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45122,6 +45312,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45534,7 +45731,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49107,20 +49315,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49128,19 +49344,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49172,14 +49397,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49633,8 +49866,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53868,24 +54101,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53894,8 +54126,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53903,16 +54136,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53924,7 +54157,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53954,21 +54187,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54004,11 +54240,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54049,13 +54285,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54119,10 +54355,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54176,8 +54412,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54208,16 +54444,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54225,7 +54460,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55534,11 +55769,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58003,7 +58257,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58193,11 +58471,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58600,9 +58878,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60139,6 +60419,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63068,7 +63352,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65514,11 +65809,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65598,8 +65893,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66202,9 +66497,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66233,7 +66529,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/hi.po b/doc/translations/hi.po
index 147b3b4099..98778940cf 100644
--- a/doc/translations/hi.po
+++ b/doc/translations/hi.po
@@ -394,7 +394,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1101,7 +1101,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9965,7 +9965,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10130,7 +10136,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12139,10 +12151,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19424,13 +19438,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19440,7 +19458,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19457,23 +19479,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28261,7 +28283,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28400,13 +28422,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29819,7 +29842,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30393,10 +30419,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30408,6 +30438,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30719,6 +30755,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30883,7 +30924,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34630,11 +34682,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34671,7 +34728,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35463,6 +35523,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35508,6 +35571,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35551,6 +35617,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35570,6 +35639,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35699,11 +35771,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35813,6 +35921,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36019,20 +36144,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36126,6 +36271,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36246,6 +36399,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36415,7 +36578,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38290,13 +38461,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38308,7 +38485,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38318,15 +38498,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40033,6 +40219,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45121,6 +45311,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45533,7 +45730,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49106,20 +49314,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49127,19 +49343,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49171,14 +49396,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49632,8 +49865,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53867,24 +54100,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53893,8 +54125,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53902,16 +54135,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53923,7 +54156,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53953,21 +54186,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54003,11 +54239,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54048,13 +54284,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54118,10 +54354,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54175,8 +54411,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54207,16 +54443,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54224,7 +54459,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55533,11 +55768,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58002,7 +58256,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58192,11 +58470,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58599,9 +58877,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60138,6 +60418,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63067,7 +63351,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65513,11 +65808,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65597,8 +65892,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66201,9 +66496,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66232,7 +66528,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/hu.po b/doc/translations/hu.po
index cda670b22d..325d7d0f52 100644
--- a/doc/translations/hu.po
+++ b/doc/translations/hu.po
@@ -413,7 +413,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1120,7 +1120,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9984,7 +9984,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10149,7 +10155,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12158,10 +12170,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19443,13 +19457,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19459,7 +19477,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19476,23 +19498,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28280,7 +28302,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28419,13 +28441,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29838,7 +29861,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30412,10 +30438,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30427,6 +30457,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30738,6 +30774,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30902,7 +30943,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34649,11 +34701,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34690,7 +34747,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35482,6 +35542,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35527,6 +35590,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35570,6 +35636,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35589,6 +35658,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35718,11 +35790,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35832,6 +35940,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36038,20 +36163,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36145,6 +36290,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36265,6 +36418,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36434,7 +36597,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38309,13 +38480,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38327,7 +38504,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38337,15 +38517,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40052,6 +40238,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45140,6 +45330,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45552,7 +45749,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49125,20 +49333,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49146,19 +49362,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49190,14 +49415,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49651,8 +49884,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53886,24 +54119,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53912,8 +54144,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53921,16 +54154,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53942,7 +54175,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53972,21 +54205,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54022,11 +54258,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54067,13 +54303,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54137,10 +54373,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54194,8 +54430,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54226,16 +54462,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54243,7 +54478,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55552,11 +55787,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58021,7 +58275,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58211,11 +58489,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58618,9 +58896,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60157,6 +60437,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63086,7 +63370,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65532,11 +65827,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65616,8 +65911,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66220,9 +66515,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66251,7 +66547,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/id.po b/doc/translations/id.po
index da727b40e7..eb95a98f22 100644
--- a/doc/translations/id.po
+++ b/doc/translations/id.po
@@ -15,12 +15,13 @@
# ProgrammerIndonesia 44 <elo.jhy@gmail.com>, 2022.
# Reza Almanda <rezaalmanda27@gmail.com>, 2022.
# Tsaqib Fadhlurrahman Soka <sokatsaqib@gmail.com>, 2022.
+# yusuf afandi <afandi.yusuf.04@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-05-28 14:11+0000\n"
-"Last-Translator: Reza Almanda <rezaalmanda27@gmail.com>\n"
+"PO-Revision-Date: 2022-07-09 21:12+0000\n"
+"Last-Translator: yusuf afandi <afandi.yusuf.04@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/id/>\n"
"Language: id\n"
@@ -28,7 +29,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -122,7 +123,7 @@ msgstr "Metode ini menerima sejumlah argumen setelah yang dijelaskan di sini."
#: doc/tools/make_rst.py
msgid "This method is used to construct a type."
-msgstr ""
+msgstr "Metode ini digunakan untuk mengkonstruksi sebuah tipe."
#: doc/tools/make_rst.py
msgid ""
@@ -558,7 +559,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1505,7 +1506,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10377,7 +10378,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10542,7 +10549,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12551,10 +12564,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19838,13 +19853,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19854,7 +19873,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19871,23 +19894,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28686,7 +28709,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28825,13 +28848,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30244,7 +30268,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30818,10 +30845,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30833,6 +30864,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -31144,6 +31181,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31308,7 +31350,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -35055,12 +35108,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Mengembalikan nilai hiperbolik tangen dari parameter."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -35096,7 +35155,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35894,6 +35956,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35940,6 +36005,9 @@ msgstr "Mengembalikan nilai hiperbolik tangen dari parameter."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35983,6 +36051,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -36002,6 +36073,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36134,11 +36208,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36252,6 +36362,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Mengembalikan nilai hiperbolik tangen dari parameter."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "Mengembalikan nilai hiperbolik tangen dari parameter."
@@ -36463,20 +36590,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36571,6 +36718,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36691,6 +36846,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36860,7 +37025,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38737,13 +38910,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38755,7 +38934,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38765,15 +38947,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40482,6 +40670,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45586,6 +45778,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45998,7 +46197,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49573,20 +49783,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49594,19 +49812,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49638,14 +49865,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50099,8 +50334,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54335,24 +54570,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54361,8 +54595,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54370,16 +54605,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54391,7 +54626,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54421,21 +54656,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54471,11 +54709,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54516,13 +54754,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54586,10 +54824,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54643,8 +54881,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54675,16 +54913,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54692,7 +54929,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56001,11 +56238,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58472,7 +58728,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58662,11 +58942,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -59069,9 +59349,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60612,6 +60894,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63541,7 +63827,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65988,11 +66285,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -66072,8 +66369,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66676,9 +66973,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66707,7 +67005,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/is.po b/doc/translations/is.po
index ec65de5cfb..c68a096dfa 100644
--- a/doc/translations/is.po
+++ b/doc/translations/is.po
@@ -394,7 +394,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1101,7 +1101,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9965,7 +9965,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10130,7 +10136,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12139,10 +12151,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19424,13 +19438,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19440,7 +19458,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19457,23 +19479,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28261,7 +28283,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28400,13 +28422,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29819,7 +29842,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30393,10 +30419,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30408,6 +30438,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30719,6 +30755,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30883,7 +30924,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34630,11 +34682,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34671,7 +34728,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35463,6 +35523,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35508,6 +35571,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35551,6 +35617,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35570,6 +35639,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35699,11 +35771,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35813,6 +35921,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36019,20 +36144,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36126,6 +36271,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36246,6 +36399,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36415,7 +36578,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38290,13 +38461,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38308,7 +38485,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38318,15 +38498,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40033,6 +40219,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45121,6 +45311,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45533,7 +45730,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49106,20 +49314,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49127,19 +49343,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49171,14 +49396,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49632,8 +49865,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53867,24 +54100,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53893,8 +54125,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53902,16 +54135,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53923,7 +54156,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53953,21 +54186,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54003,11 +54239,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54048,13 +54284,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54118,10 +54354,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54175,8 +54411,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54207,16 +54443,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54224,7 +54459,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55533,11 +55768,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58002,7 +58256,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58192,11 +58470,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58599,9 +58877,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60138,6 +60418,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63067,7 +63351,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65513,11 +65808,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65597,8 +65892,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66201,9 +66496,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66232,7 +66528,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/it.po b/doc/translations/it.po
index f1a35b0de3..fd78bc8f1c 100644
--- a/doc/translations/it.po
+++ b/doc/translations/it.po
@@ -589,7 +589,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1743,7 +1743,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10991,7 +10991,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -11156,7 +11162,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -13170,10 +13182,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -20563,13 +20577,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20579,7 +20597,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20596,23 +20618,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -29446,7 +29468,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -29585,13 +29607,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -31009,7 +31032,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -31584,10 +31610,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -31598,6 +31628,13 @@ msgid "Mouse and input coordinates"
msgstr ""
#: doc/classes/InputEventMouseMotion.xml
+#, fuzzy
+msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr "Ritorna [code]true[/code] se [code]s[/code] è zero o quasi zero."
+
+#: doc/classes/InputEventMouseMotion.xml
msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
@@ -31914,6 +31951,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -32078,7 +32120,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -35845,12 +35898,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Restituisce il resto dei due vettori."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -35886,7 +35945,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -36686,6 +36748,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -36732,6 +36797,9 @@ msgstr "Restituisce il seno del parametro."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -36775,6 +36843,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -36794,6 +36865,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36930,11 +37004,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -37051,6 +37161,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Ritorna [code]true[/code] se [code]s[/code] è zero o quasi zero."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "Ritorna [code]true[/code] se [code]s[/code] è zero o quasi zero."
@@ -37267,20 +37394,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -37376,6 +37523,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -37500,6 +37655,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -37673,7 +37838,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -39558,13 +39731,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -39576,7 +39755,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -39586,15 +39768,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -41314,6 +41502,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -46442,6 +46634,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -46855,7 +47054,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -50432,20 +50642,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -50453,19 +50671,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -50497,14 +50724,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50958,8 +51193,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -55204,24 +55439,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -55230,8 +55464,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -55239,16 +55474,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -55260,7 +55495,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55290,21 +55525,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -55340,11 +55578,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55385,13 +55623,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -55455,10 +55693,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -55512,8 +55750,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -55544,16 +55782,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -55561,7 +55798,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56872,11 +57109,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -59351,7 +59607,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -59541,11 +59821,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -59948,9 +60228,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -61510,6 +61792,13 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+"Se [code] vero [/code], i nodi figli sono ordinati, altrimenti l'ordinamento "
+"è disabilitato."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -64467,7 +64756,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -66943,11 +67243,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -67027,8 +67327,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -67641,9 +67941,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -67675,7 +67976,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/ja.po b/doc/translations/ja.po
index 8bb3d16322..324df4d9ae 100644
--- a/doc/translations/ja.po
+++ b/doc/translations/ja.po
@@ -561,7 +561,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1693,7 +1693,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -12677,8 +12677,14 @@ msgstr ""
"ã¾ã™ã€‚"
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
-msgstr "ã“ã®ã‚ªãƒ¼ãƒ‡ã‚£ã‚ªãŒå†ç”Ÿã•れã¦ã„ã‚‹ãƒã‚¹ã€‚"
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
+msgstr ""
#: doc/classes/AudioStreamPlayer.xml
msgid ""
@@ -12860,9 +12866,14 @@ msgstr ""
"ã¾ã™ã€‚"
#: doc/classes/AudioStreamPlayer3D.xml
-#, fuzzy
-msgid "The bus on which this audio is playing."
-msgstr "ã“ã®ã‚ªãƒ¼ãƒ‡ã‚£ã‚ªãŒå†ç”Ÿã•れã¦ã„ã‚‹ãƒã‚¹ã€‚"
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
+msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
@@ -15107,10 +15118,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -22561,13 +22574,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -22577,7 +22594,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -22594,23 +22615,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -31499,7 +31520,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -31638,13 +31659,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -33071,7 +33093,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -33645,10 +33670,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -33659,6 +33688,14 @@ msgid "Mouse and input coordinates"
msgstr ""
#: doc/classes/InputEventMouseMotion.xml
+#, fuzzy
+msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+"文字列ã®é•·ã•㌠[code]0[/code] ã«ç­‰ã—ã‘れ㰠[code]true[/code] ã‚’è¿”ã—ã¾ã™ã€‚"
+
+#: doc/classes/InputEventMouseMotion.xml
msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
@@ -33977,6 +34014,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -34141,7 +34183,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -37961,12 +38014,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "BitmapFontã®ã‚¢ãƒˆãƒ©ã‚¹ã«å«ã¾ã‚Œã‚‹ãƒ†ã‚¯ã‚¹ãƒãƒ£æ•°ã‚’è¿”ã—ã¾ã™ã€‚"
#: doc/classes/MeshInstance.xml
msgid ""
@@ -38002,7 +38061,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -38809,6 +38871,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -38855,6 +38920,9 @@ msgstr "アニメーションã®ãƒˆãƒ©ãƒƒã‚¯æ•°ã‚’è¿”ã—ã¾ã™ã€‚"
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -38899,6 +38967,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -38918,6 +38989,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -39061,11 +39135,47 @@ msgid "Destroys the given RID."
msgstr "指定ã•れãŸé·ç§»ã‚’è¿”ã—ã¾ã™ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -39186,6 +39296,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "è«–ç†ORæ¼”ç®—å­ ([code]or[/code] ã¾ãŸã¯ [code]||[/code])。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -39407,21 +39534,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
-msgid "The radius of the agent."
-msgstr "円柱ã®åŠå¾„。"
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
+msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -39519,6 +39665,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -39642,6 +39796,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr "[code]true[/code]ã®å ´åˆã€æ³•ç·šãƒžãƒƒãƒ”ãƒ³ã‚°ãŒæœ‰åйã«ãªã‚Šã¾ã™ã€‚"
@@ -39818,7 +39982,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -41710,13 +41882,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -41728,7 +41906,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -41738,15 +41919,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -43470,6 +43657,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -48617,6 +48808,14 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+#, fuzzy
+msgid "Sorts the elements of the array in ascending order."
+msgstr "インデックスã«ã‚ˆã‚Šé…列ã‹ã‚‰è¦ç´ ã‚’削除ã—ã¾ã™ã€‚"
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -49041,7 +49240,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -52642,20 +52852,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -52663,19 +52881,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -52707,14 +52934,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -53168,8 +53403,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -57454,24 +57689,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -57480,8 +57714,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -57489,16 +57724,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -57510,7 +57745,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -57540,21 +57775,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -57590,11 +57828,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -57635,13 +57873,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -57705,10 +57943,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -57762,8 +58000,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -57794,16 +58032,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -57811,7 +58048,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -59130,11 +59367,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -61900,7 +62156,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -62090,11 +62370,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -62497,9 +62777,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -64074,6 +64356,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "[code]true[/code] ã§ã‚れã°ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã¯ä¸­å¤®ã«ãªã‚Šã¾ã™ã€‚"
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -67056,7 +67343,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -69542,11 +69840,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -69626,8 +69924,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -70244,9 +70542,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -70276,7 +70575,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/ko.po b/doc/translations/ko.po
index e3dd797c36..2f6879593c 100644
--- a/doc/translations/ko.po
+++ b/doc/translations/ko.po
@@ -15,12 +15,13 @@
# whatthesamuel <alex01763@gmail.com>, 2021.
# 한수현 <shh1473@ajou.ac.kr>, 2022.
# vrSono <global.sonogong@gmail.com>, 2022.
+# 김태우 <ogosengi3@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-06-13 03:39+0000\n"
-"Last-Translator: vrSono <global.sonogong@gmail.com>\n"
+"PO-Revision-Date: 2022-06-29 10:30+0000\n"
+"Last-Translator: 김태우 <ogosengi3@gmail.com>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/ko/>\n"
"Language: ko\n"
@@ -28,7 +29,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -88,7 +89,7 @@ msgstr "(%s를 ë®ì–´ì”€)"
#: doc/tools/make_rst.py
msgid "Default"
-msgstr ""
+msgstr "기본값"
#: doc/tools/make_rst.py
msgid "Setter"
@@ -96,7 +97,7 @@ msgstr "Setter"
#: doc/tools/make_rst.py
msgid "value"
-msgstr ""
+msgstr "ê°’"
#: doc/tools/make_rst.py
msgid "Getter"
@@ -535,7 +536,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1266,7 +1267,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10140,7 +10141,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10305,7 +10312,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12316,10 +12329,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19650,13 +19665,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19666,7 +19685,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19683,23 +19706,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28563,7 +28586,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28702,13 +28725,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30129,7 +30153,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30703,10 +30730,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30718,6 +30749,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -31030,6 +31067,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31194,7 +31236,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34946,12 +34999,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "ë‘ ë²¡í„°ì˜ ë‚˜ë¨¸ì§€ë¥¼ 반환합니다."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -34987,7 +35046,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35786,6 +35848,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35832,6 +35897,9 @@ msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35875,6 +35943,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35894,6 +35965,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36029,11 +36103,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36149,6 +36259,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
@@ -36361,20 +36488,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36470,6 +36617,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36591,6 +36746,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36761,7 +36926,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38768,13 +38941,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38786,7 +38965,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38796,15 +38978,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40517,6 +40705,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45626,6 +45818,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -46038,7 +46237,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49614,20 +49824,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49635,19 +49853,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49679,14 +49906,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50140,8 +50375,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54377,24 +54612,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54403,8 +54637,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54412,16 +54647,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54433,7 +54668,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54463,21 +54698,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54513,11 +54751,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54558,13 +54796,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54628,10 +54866,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54685,8 +54923,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54717,16 +54955,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54734,7 +54971,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56043,11 +56280,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58514,7 +58770,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58704,11 +58984,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -59111,9 +59391,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60658,6 +60940,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63590,7 +63877,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -66043,11 +66341,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -66127,8 +66425,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66747,9 +67045,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66778,7 +67077,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/lt.po b/doc/translations/lt.po
index fc686e4bb2..2468d389d3 100644
--- a/doc/translations/lt.po
+++ b/doc/translations/lt.po
@@ -404,7 +404,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1111,7 +1111,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9975,7 +9975,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10140,7 +10146,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12149,10 +12161,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19434,13 +19448,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19450,7 +19468,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19467,23 +19489,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28271,7 +28293,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28410,13 +28432,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29829,7 +29852,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30403,10 +30429,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30418,6 +30448,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30729,6 +30765,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30893,7 +30934,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34640,11 +34692,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34681,7 +34738,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35473,6 +35533,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35518,6 +35581,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35561,6 +35627,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35580,6 +35649,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35709,11 +35781,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35823,6 +35931,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36029,20 +36154,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36136,6 +36281,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36256,6 +36409,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36425,7 +36588,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38300,13 +38471,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38318,7 +38495,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38328,15 +38508,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40043,6 +40229,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45131,6 +45321,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45543,7 +45740,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49116,20 +49324,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49137,19 +49353,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49181,14 +49406,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49642,8 +49875,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53877,24 +54110,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53903,8 +54135,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53912,16 +54145,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53933,7 +54166,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53963,21 +54196,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54013,11 +54249,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54058,13 +54294,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54128,10 +54364,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54185,8 +54421,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54217,16 +54453,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54234,7 +54469,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55543,11 +55778,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58012,7 +58266,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58202,11 +58480,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58609,9 +58887,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60148,6 +60428,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63077,7 +63361,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65523,11 +65818,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65607,8 +65902,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66211,9 +66506,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66242,7 +66538,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/lv.po b/doc/translations/lv.po
index 27ebbed1af..9faf7fd017 100644
--- a/doc/translations/lv.po
+++ b/doc/translations/lv.po
@@ -409,7 +409,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1116,7 +1116,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9980,7 +9980,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10145,7 +10151,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12154,10 +12166,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19439,13 +19453,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19455,7 +19473,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19472,23 +19494,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28279,7 +28301,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28418,13 +28440,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29837,7 +29860,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30411,10 +30437,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30426,6 +30456,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30737,6 +30773,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30901,7 +30942,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34648,11 +34700,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34689,7 +34746,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35481,6 +35541,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35526,6 +35589,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35569,6 +35635,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35588,6 +35657,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35717,11 +35789,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35831,6 +35939,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36037,20 +36162,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36144,6 +36289,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36264,6 +36417,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36433,7 +36596,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38308,13 +38479,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38326,7 +38503,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38336,15 +38516,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40051,6 +40237,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45139,6 +45329,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45551,7 +45748,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49124,20 +49332,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49145,19 +49361,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49189,14 +49414,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49650,8 +49883,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53885,24 +54118,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53911,8 +54143,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53920,16 +54153,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53941,7 +54174,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53971,21 +54204,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54021,11 +54257,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54066,13 +54302,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54136,10 +54372,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54193,8 +54429,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54225,16 +54461,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54242,7 +54477,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55551,11 +55786,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58020,7 +58274,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58210,11 +58488,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58617,9 +58895,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60156,6 +60436,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63085,7 +63369,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65531,11 +65826,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65615,8 +65910,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66219,9 +66514,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66250,7 +66546,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/mr.po b/doc/translations/mr.po
index caaec0b107..c989fcc549 100644
--- a/doc/translations/mr.po
+++ b/doc/translations/mr.po
@@ -392,7 +392,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1099,7 +1099,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9963,7 +9963,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10128,7 +10134,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12137,10 +12149,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19422,13 +19436,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19438,7 +19456,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19455,23 +19477,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28259,7 +28281,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28398,13 +28420,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29817,7 +29840,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30391,10 +30417,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30406,6 +30436,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30717,6 +30753,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30881,7 +30922,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34628,11 +34680,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34669,7 +34726,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35461,6 +35521,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35506,6 +35569,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35549,6 +35615,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35568,6 +35637,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35697,11 +35769,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35811,6 +35919,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36017,20 +36142,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36124,6 +36269,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36244,6 +36397,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36413,7 +36576,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38288,13 +38459,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38306,7 +38483,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38316,15 +38496,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40031,6 +40217,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45119,6 +45309,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45531,7 +45728,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49104,20 +49312,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49125,19 +49341,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49169,14 +49394,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49630,8 +49863,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53865,24 +54098,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53891,8 +54123,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53900,16 +54133,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53921,7 +54154,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53951,21 +54184,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54001,11 +54237,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54046,13 +54282,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54116,10 +54352,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54173,8 +54409,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54205,16 +54441,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54222,7 +54457,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55531,11 +55766,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58000,7 +58254,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58190,11 +58468,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58597,9 +58875,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60136,6 +60416,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63065,7 +63349,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65511,11 +65806,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65595,8 +65890,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66199,9 +66494,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66230,7 +66526,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/nb.po b/doc/translations/nb.po
index 6bdd8e4b1e..8017f4006b 100644
--- a/doc/translations/nb.po
+++ b/doc/translations/nb.po
@@ -404,7 +404,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1111,7 +1111,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9975,7 +9975,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10140,7 +10146,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12149,10 +12161,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19434,13 +19448,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19450,7 +19468,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19467,23 +19489,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28271,7 +28293,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28410,13 +28432,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29829,7 +29852,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30403,10 +30429,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30418,6 +30448,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30729,6 +30765,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30893,7 +30934,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34640,11 +34692,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34681,7 +34738,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35473,6 +35533,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35518,6 +35581,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35561,6 +35627,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35580,6 +35649,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35709,11 +35781,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35823,6 +35931,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36029,20 +36154,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36136,6 +36281,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36256,6 +36409,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36425,7 +36588,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38300,13 +38471,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38318,7 +38495,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38328,15 +38508,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40043,6 +40229,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45131,6 +45321,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45543,7 +45740,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49116,20 +49324,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49137,19 +49353,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49181,14 +49406,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49642,8 +49875,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53877,24 +54110,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53903,8 +54135,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53912,16 +54145,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53933,7 +54166,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53963,21 +54196,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54013,11 +54249,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54058,13 +54294,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54128,10 +54364,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54185,8 +54421,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54217,16 +54453,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54234,7 +54469,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55543,11 +55778,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58012,7 +58266,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58202,11 +58480,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58609,9 +58887,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60148,6 +60428,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63077,7 +63361,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65523,11 +65818,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65607,8 +65902,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66211,9 +66506,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66242,7 +66538,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/ne.po b/doc/translations/ne.po
index d7f2a9f0cb..9a17a51fb6 100644
--- a/doc/translations/ne.po
+++ b/doc/translations/ne.po
@@ -392,7 +392,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1099,7 +1099,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9963,7 +9963,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10128,7 +10134,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12137,10 +12149,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19422,13 +19436,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19438,7 +19456,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19455,23 +19477,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28259,7 +28281,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28398,13 +28420,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29817,7 +29840,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30391,10 +30417,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30406,6 +30436,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30717,6 +30753,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30881,7 +30922,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34628,11 +34680,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34669,7 +34726,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35461,6 +35521,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35506,6 +35569,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35549,6 +35615,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35568,6 +35637,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35697,11 +35769,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35811,6 +35919,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36017,20 +36142,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36124,6 +36269,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36244,6 +36397,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36413,7 +36576,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38288,13 +38459,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38306,7 +38483,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38316,15 +38496,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40031,6 +40217,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45119,6 +45309,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45531,7 +45728,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49104,20 +49312,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49125,19 +49341,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49169,14 +49394,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49630,8 +49863,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53865,24 +54098,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53891,8 +54123,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53900,16 +54133,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53921,7 +54154,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53951,21 +54184,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54001,11 +54237,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54046,13 +54282,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54116,10 +54352,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54173,8 +54409,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54205,16 +54441,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54222,7 +54457,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55531,11 +55766,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58000,7 +58254,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58190,11 +58468,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58597,9 +58875,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60136,6 +60416,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63065,7 +63349,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65511,11 +65806,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65595,8 +65890,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66199,9 +66494,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66230,7 +66526,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/nl.po b/doc/translations/nl.po
index 71605513cd..d36175b6c2 100644
--- a/doc/translations/nl.po
+++ b/doc/translations/nl.po
@@ -453,7 +453,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1160,7 +1160,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10032,7 +10032,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10197,7 +10203,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12206,10 +12218,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19491,13 +19505,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19507,7 +19525,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19524,23 +19546,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28331,7 +28353,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28470,13 +28492,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29889,7 +29912,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30463,10 +30489,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30478,6 +30508,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30789,6 +30825,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30953,7 +30994,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34700,11 +34752,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34741,7 +34798,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35533,6 +35593,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35578,6 +35641,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35621,6 +35687,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35640,6 +35709,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35769,11 +35841,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35883,6 +35991,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36089,20 +36214,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36196,6 +36341,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36316,6 +36469,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36485,7 +36648,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38360,13 +38531,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38378,7 +38555,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38388,15 +38568,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40103,6 +40289,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45191,6 +45381,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45603,7 +45800,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49176,20 +49384,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49197,19 +49413,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49241,14 +49466,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49702,8 +49935,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53938,24 +54171,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53964,8 +54196,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53973,16 +54206,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53994,7 +54227,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54024,21 +54257,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54074,11 +54310,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54119,13 +54355,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54189,10 +54425,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54246,8 +54482,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54278,16 +54514,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54295,7 +54530,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55604,11 +55839,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58073,7 +58327,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58263,11 +58541,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58670,9 +58948,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60209,6 +60489,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63138,7 +63422,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65584,11 +65879,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65668,8 +65963,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66272,9 +66567,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66303,7 +66599,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/pl.po b/doc/translations/pl.po
index 6e5324af99..343dfb0050 100644
--- a/doc/translations/pl.po
+++ b/doc/translations/pl.po
@@ -574,7 +574,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1565,7 +1565,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10471,7 +10471,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10636,7 +10642,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12651,10 +12663,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19963,13 +19977,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19979,7 +19997,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19996,23 +20018,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28837,7 +28859,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28976,13 +28998,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30398,7 +30421,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30972,10 +30998,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30987,6 +31017,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -31302,6 +31338,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31466,7 +31507,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -35240,12 +35292,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Zwraca resztę z dwóch wektorów."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -35281,7 +35339,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -36081,6 +36142,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -36127,6 +36191,9 @@ msgstr "Zwraca sinus parametru."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -36170,6 +36237,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -36189,6 +36259,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36327,11 +36400,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36449,6 +36558,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Operator logiczny OR ([code]or[/code] or [code]||[/code])."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "Operator logiczny OR ([code]or[/code] or [code]||[/code])."
@@ -36668,20 +36794,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36777,6 +36923,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36898,6 +37052,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -37071,7 +37235,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38955,13 +39127,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38973,7 +39151,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38983,15 +39164,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40706,6 +40893,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45834,6 +46025,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -46246,7 +46444,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49822,20 +50031,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49843,19 +50060,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49887,14 +50113,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50348,8 +50582,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54596,24 +54830,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54622,8 +54855,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54631,16 +54865,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54652,7 +54886,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54682,21 +54916,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54732,11 +54969,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54777,13 +55014,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54847,10 +55084,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54904,8 +55141,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54936,16 +55173,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54953,7 +55189,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56263,11 +56499,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58737,7 +58992,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58927,11 +59206,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -59334,9 +59613,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60885,6 +61166,13 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+"Jeśli [code]true[/code], potomne węzły są sortowane. W innym przypadku jest "
+"wyłączone."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63826,7 +64114,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -66280,11 +66579,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -66364,8 +66663,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66980,9 +67279,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -67014,7 +67314,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/pt.po b/doc/translations/pt.po
index 6b214ae81a..fdb01b1579 100644
--- a/doc/translations/pt.po
+++ b/doc/translations/pt.po
@@ -9,12 +9,13 @@
# Renu <ifpilucas@gmail.com>, 2022.
# Diogo Gomes <dgomes@graphnode.com>, 2022.
# El_ExpertPlayer <xpertnathan37@gmail.com>, 2022.
+# Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-06-13 03:39+0000\n"
-"Last-Translator: El_ExpertPlayer <xpertnathan37@gmail.com>\n"
+"PO-Revision-Date: 2022-06-29 10:31+0000\n"
+"Last-Translator: Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>\n"
"Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/pt/>\n"
"Language: pt\n"
@@ -22,7 +23,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -78,7 +79,7 @@ msgstr "Herdado por:"
#: doc/tools/make_rst.py
msgid "(overrides %s)"
-msgstr ""
+msgstr "(recopiar %s)"
#: doc/tools/make_rst.py
msgid "Default"
@@ -86,7 +87,7 @@ msgstr "Padrão"
#: doc/tools/make_rst.py
msgid "Setter"
-msgstr "Definidor"
+msgstr "Setter"
#: doc/tools/make_rst.py
msgid "value"
@@ -94,13 +95,13 @@ msgstr "valor"
#: doc/tools/make_rst.py
msgid "Getter"
-msgstr "Buscador"
+msgstr "Getter"
#: doc/tools/make_rst.py
msgid ""
"This method should typically be overridden by the user to have any effect."
msgstr ""
-"Este método normalmente deve ser substituído pelo usuário para ter algum "
+"Este método normalmente deve ser reescrito pelo usuário para que tenha algum "
"efeito."
#: doc/tools/make_rst.py
@@ -534,6 +535,7 @@ msgstr ""
"inst2dict]), de volta numa instância. Útil para desserialização."
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns an \"eased\" value of [code]x[/code] based on an easing function "
"defined with [code]curve[/code]. This easing function is based on an "
@@ -548,7 +550,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -906,7 +908,6 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Linearly interpolates between two values by the factor defined in "
"[code]weight[/code]. To perform interpolation, [code]weight[/code] should be "
@@ -926,20 +927,25 @@ msgid ""
"To perform eased interpolation with [method lerp], combine it with [method "
"ease] or [method smoothstep]."
msgstr ""
-"Interpola linearmente entre dois valores através de um valor normalizado. "
-"Este método é o oposto do método [method inverse_lerp].\n"
+"Interpola linearmente entre dois valores pelo fator definido em "
+"[code]weight[/code]. Para realizar a interpolação, [code]weight[/code] deve "
+"estar entre [code]0.0[/code] e [code]1.0[/code] (inclusive). No entanto, "
+"valores fora desse intervalo são permitidos e podem ser usados para realizar "
+"[i]extrapolação[/i].\n"
"Se os argumentos [code]from[/code] e [code]to[/code] forem do tipo [int] ou "
-"[float], o retorno é um valor do tipo [float].\n"
-"Se ambos são vetores de mesmo tipo ([Vector2], [Vector3] ou [Color]), o "
-"valor retornado será do mesmo tipo ([code]lerp[/code] então chamará o método "
-"[code]lerp[/code] do tipo de vetor em questão).\n"
+"[float], o valor de retorno será um [float].\n"
+"Se ambos forem do mesmo tipo de vetor ([Vector2], [Vector3] ou [Color]), o "
+"valor de retorno será do mesmo tipo ([code]lerp[/code] então chama o método "
+"[code]linear_interpolate[/code] do tipo de vetor).\n"
"[codeblock]\n"
-"lerp(0, 4, 0.75) # Retorna 3.0\n"
-"lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Retorna Vector2(2, 3.5)\n"
-"[/codeblock]"
+"lerp(0, 4, 0,75) # Retorna 3,0\n"
+"lerp(Vetor2(1, 5), Vetor2(3, 2), 0.5) # Retorna Vetor2(2, 3.5)\n"
+"[/codeblock]\n"
+"Veja também [method inverse_lerp] que realiza o inverso desta operação. Para "
+"realizar a interpolação facilitada com [method lerp], combine-o com [method "
+"easy] ou [method smoothstep]."
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Linearly interpolates between two angles (in radians) by a normalized "
"value.\n"
@@ -962,10 +968,12 @@ msgid ""
"example, [code]lerp_angle(0, PI, weight)[/code] lerps counter-clockwise, "
"while [code]lerp_angle(0, PI + 5 * TAU, weight)[/code] lerps clockwise."
msgstr ""
-"Faz a interpolação linear entre dois ângulos (em radianos) por um valor "
+"Interpola linearmente entre dois ângulos (em radianos) por um valor "
"normalizado.\n"
-"Semelhante à [method lerp], mas faz a interpolação corretamente quando os "
-"ângulos passam através de [constant @GDScript.TAU].\n"
+"Semelhante a [method lerp], mas interpola corretamente quando os ângulos "
+"envolvem [constant @GDScript.TAU]. Para realizar a interpolação facilitada "
+"com [method lerp_angle], combine-o com [method easy] ou [method "
+"smoothstep].\n"
"[codeblock]\n"
"extends Sprite\n"
"var elapsed = 0.0\n"
@@ -974,7 +982,14 @@ msgstr ""
" var max_angle = deg2rad(90.0)\n"
" rotation = lerp_angle(min_angle, max_angle, elapsed)\n"
" elapsed += delta\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"[b]Nota:[/b] Este método lê o caminho mais curto entre [code]from[/code] e "
+"[code]to[/code]. No entanto, quando esses dois ângulos estão aproximadamente "
+"[code]PI + k * TAU[/code] separados para qualquer inteiro [code]k[/code], "
+"não é óbvio de que maneira eles interpretam devido a erros de precisão de "
+"ponto flutuante. Por exemplo, [code]lerp_angle(0, PI, weight)[/code] lê no "
+"sentido anti-horário, enquanto [code]lerp_angle(0, PI + 5 * TAU, weight)[/"
+"code] lê no sentido horário."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -1462,7 +1477,6 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Returns a random floating point value between [code]from[/code] and "
"[code]to[/code] (both endpoints inclusive).\n"
@@ -1471,12 +1485,12 @@ msgid ""
"[/codeblock]\n"
"[b]Note:[/b] This is equivalent to [code]randf() * (to - from) + from[/code]."
msgstr ""
-"Intervalo aleatório, retorna qualquer número real entre [code]from[/code] e "
-"[code]to[/code].\n"
+"Retorna um valor de ponto flutuante aleatório entre [code]from[/code] e "
+"[code]to[/code] (ambos os endpoints inclusive).\n"
"[codeblock]\n"
-"prints(rand_range(0, 1), rand_range(0, 1)) # Imprime por exemplo 0.135591 "
-"0.405263\n"
-"[/codeblock]"
+"prints(rand_range(0, 1), rand_range(0, 1)) # Prints e.g. 0.135591 0.405263\n"
+"[/codeblock]\n"
+"[b]Nota:[/b] Isso é equivalente a [code]randf() * (to - from) + from[/code]."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -1686,7 +1700,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -4578,9 +4592,8 @@ msgstr ""
#: doc/classes/AABB.xml doc/classes/Rect2.xml doc/classes/Vector2.xml
#: doc/classes/Vector3.xml
-#, fuzzy
msgid "Vector math"
-msgstr "Vetor utilizado para matemática 2D."
+msgstr "Matemática vetorial"
#: doc/classes/AABB.xml doc/classes/Rect2.xml doc/classes/Vector2.xml
#: doc/classes/Vector3.xml
@@ -5797,9 +5810,8 @@ msgstr ""
#: doc/classes/AnimationNodeOneShot.xml doc/classes/AnimationNodeOutput.xml
#: doc/classes/AnimationNodeTimeScale.xml
#: doc/classes/AnimationNodeTransition.xml
-#, fuzzy
msgid "AnimationTree"
-msgstr "Nó de animação."
+msgstr "AnimationTree"
#: doc/classes/AnimationNodeAdd3.xml doc/classes/AnimationNodeAnimation.xml
#: doc/classes/AnimationNodeBlend2.xml
@@ -6492,9 +6504,8 @@ msgid ""
msgstr ""
#: doc/classes/AnimationPlayer.xml
-#, fuzzy
msgid "Animation tutorial index"
-msgstr "Nó de animação."
+msgstr "Ãndice do tutorial de animação"
#: doc/classes/AnimationPlayer.xml
msgid ""
@@ -6783,9 +6794,8 @@ msgid ""
msgstr ""
#: doc/classes/AnimationTree.xml
-#, fuzzy
msgid "Using AnimationTree"
-msgstr "Reseta este [AnimationTreePlayer]."
+msgstr "Usando AnimationTree"
#: doc/classes/AnimationTree.xml
msgid "Manually advance the animations by the specified time (in seconds)."
@@ -10777,7 +10787,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10942,7 +10958,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12957,10 +12979,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -13748,9 +13772,8 @@ msgstr ""
"camada -1 ou abaixo)."
#: doc/classes/CanvasLayer.xml
-#, fuzzy
msgid "Canvas layers"
-msgstr "Camada para desenhar no ecrã."
+msgstr "Camadas de tela"
#: doc/classes/CanvasLayer.xml
msgid "Returns the RID of the canvas used by this layer."
@@ -14820,9 +14843,8 @@ msgstr ""
#: doc/classes/Physics2DDirectSpaceState.xml
#: doc/classes/PhysicsDirectBodyState.xml
#: doc/classes/PhysicsDirectSpaceState.xml doc/classes/RigidBody.xml
-#, fuzzy
msgid "Physics introduction"
-msgstr "Interpolação cúbica."
+msgstr "Introdução à física"
#: doc/classes/CollisionShape.xml
msgid ""
@@ -16389,9 +16411,8 @@ msgid "GUI tutorial index"
msgstr ""
#: doc/classes/Control.xml
-#, fuzzy
msgid "Control node gallery"
-msgstr "Tecla Control."
+msgstr "Galeria de *nós* de controle"
#: doc/classes/Control.xml
msgid "All GUI Demos"
@@ -20291,13 +20312,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20307,7 +20332,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20324,23 +20353,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -29145,7 +29174,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -29284,13 +29313,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30703,7 +30733,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -31277,10 +31310,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -31292,6 +31329,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -31607,6 +31650,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31771,7 +31819,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -35532,12 +35591,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Retorna o seno do parâmetro."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -35573,7 +35638,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -36365,6 +36433,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -36411,6 +36482,9 @@ msgstr "Retorna o RID do ecrã usada por essa camada."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -36454,6 +36528,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -36473,6 +36550,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36610,11 +36690,47 @@ msgid "Destroys the given RID."
msgstr "Retorna o [RID] do objeto."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36730,6 +36846,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Retorna o produto cruzado deste vetor e [code]b[/code]."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36944,21 +37077,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
-msgid "The radius of the agent."
-msgstr "A cor do texto."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
+msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -37054,6 +37206,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -37174,6 +37334,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -37343,7 +37513,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38318,7 +38496,7 @@ msgstr ""
#: doc/classes/Node.xml
msgid "Nodes and Scenes"
-msgstr ""
+msgstr "Nós e Cenas"
#: doc/classes/Node.xml
msgid "All Demos"
@@ -39227,13 +39405,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -39245,8 +39429,11 @@ msgid "Emitted when the node is renamed."
msgstr "Emitido quando o nó é renomeado."
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
-msgstr "Emitido quando o nó entra na árvore."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
+msgstr ""
#: doc/classes/Node.xml
msgid "Emitted after the node exits the tree and is no longer active."
@@ -39255,15 +39442,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40972,6 +41165,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -46063,6 +46260,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -46475,7 +46679,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49157,68 +49372,67 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 3."
-msgstr ""
+msgstr "Nome opcional para a camada 3 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 30."
-msgstr ""
+msgstr "Nome opcional para a camada 30 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 31."
-msgstr ""
+msgstr "Nome opcional para a camada 31 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 32."
-msgstr ""
+msgstr "Nome opcional para a camada 32 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 4."
-msgstr ""
+msgstr "Nome opcional para a camada 4 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 5."
-msgstr ""
+msgstr "Nome opcional para a camada 5 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 6."
-msgstr ""
+msgstr "Nome opcional para a camada 6 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 7."
-msgstr ""
+msgstr "Nome opcional para a camada 7 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 8."
-msgstr ""
+msgstr "Nome opcional para a camada 8 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D physics layer 9."
-msgstr ""
+msgstr "Nome opcional para a camada 9 de física 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 1."
-msgstr "Nome opcional para a camada 1 da renderização 3D."
+msgstr "Nome opcional para a camada 1 de renderização 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 10."
-msgstr "Nome opcional para a camada 10 da renderização 3D."
+msgstr "Nome opcional para a camada 10 de renderização 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 11."
-msgstr "Nome opcional para a camada 11 da renderização 3D."
+msgstr "Nome opcional para a camada 11 de renderização 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 12."
-msgstr "Nome opcional para a camada 12 da renderização 3D."
+msgstr "Nome opcional para a camada 12 de renderização 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 13."
-msgstr "Nome opcional para a camada 13 da renderização 3D."
+msgstr "Nome opcional para a camada 13 de renderização 3D."
#: doc/classes/ProjectSettings.xml
-#, fuzzy
msgid "Optional name for the 3D render layer 14."
-msgstr "Nome opcional para a camada 14 da renderização 3D"
+msgstr "Nome opcional para a camada 14 de renderização 3D."
#: doc/classes/ProjectSettings.xml
msgid "Optional name for the 3D render layer 15."
@@ -49281,38 +49495,53 @@ msgid ""
"The locale to fall back to if a translation isn't available in a given "
"language. If left empty, [code]en[/code] (English) will be used."
msgstr ""
+"A localidade para retornar se uma tradução não estiver disponível em um "
+"determinado idioma. Se deixado em branco, [code]en[/code] (inglês) será "
+"usado."
#: doc/classes/ProjectSettings.xml
msgid ""
"If non-empty, this locale will be used when running the project from the "
"editor."
msgstr ""
+"Se não estiver vazio, essa localidade será usada ao executar o projeto a "
+"partir do editor."
#: doc/classes/ProjectSettings.xml
msgid "If [code]true[/code], logs all output to files."
-msgstr ""
+msgstr "Se [code]true[/code], registra todas os resultados nos arquivos."
#: doc/classes/ProjectSettings.xml
msgid ""
"Desktop override for [member logging/file_logging/enable_file_logging], as "
"log files are not readily accessible on mobile/Web platforms."
msgstr ""
+"Substituição da área de trabalho para [member logging/file_logging/"
+"enable_file_logging], pois os arquivos de log não são facilmente acessíveis "
+"em plataformas móveis/Web."
#: doc/classes/ProjectSettings.xml
msgid ""
"Path to logs within the project. Using an [code]user://[/code] path is "
"recommended."
msgstr ""
+"Caminho para logs dentro do projeto. Recomenda se utilizar um caminho "
+"[code]user://[/code]."
#: doc/classes/ProjectSettings.xml
msgid "Specifies the maximum amount of log files allowed (used for rotation)."
msgstr ""
+"Especifica a quantidade máxima de arquivos de log permitidos (usados para "
+"rotação)."
#: doc/classes/ProjectSettings.xml
msgid ""
"Godot uses a message queue to defer some function calls. If you run out of "
"space on it (you will see an error), you can increase the size here."
msgstr ""
+"Godot usa uma fila de mensagens para adiar algumas chamadas de função. Se "
+"você ficar sem espaço nela (você verá um erro), você pode aumentar o tamanho "
+"aqui."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -49321,6 +49550,11 @@ msgid ""
"on threads. If servers get stalled too often when loading resources in a "
"thread, increase this number."
msgstr ""
+"Isso é usado por servidores quando usado no modo multi-threading (servidores "
+"e visual). Os RIDs são pré-alocados para evitar a interrupção do servidor "
+"que os solicita em encadeamentos. Se os servidores ficarem paralisados com "
+"muita frequência ao carregar recursos em um encadeamento, aumente esse "
+"número."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -49333,6 +49567,14 @@ msgid ""
"in the editor, which also includes C# [code]tool[/code] scripts running "
"within the editor as well as editor plugin code."
msgstr ""
+"A política a ser usada para exceções Mono (C#) não tratadas. O padrão "
+"\"Terminate Application\" sai do projeto assim que uma exceção não tratada é "
+"lançada. Em vez disso, \"Log Error\" registra uma mensagem de erro no "
+"console e não interromperá a execução do projeto quando uma exceção não "
+"tratada for lançada.\n"
+"[b]Observação:[/b] A política de exceção não tratada é sempre definida como "
+"\"Erro de log\" no editor, que também inclui scripts C# [code]tool[/code] "
+"executados no editor, bem como o código do plug-in do editor."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -49340,42 +49582,57 @@ msgid ""
"map_set_cell_height].\n"
"[b]Note:[/b] Currently not implemented."
msgstr ""
+"Altura de célula padrão para mapas de navegação 2D. Consulte [método "
+"Navigation2DServer.map_set_cell_height].\n"
+"[b]Observação:[/b] atualmente não implementado."
#: doc/classes/ProjectSettings.xml
msgid ""
"Default cell size for 2D navigation maps. See [method Navigation2DServer."
"map_set_cell_size]."
msgstr ""
+"Tamanho de célula padrão para mapas de navegação 2D. Consulte [method "
+"Navigation2DServer.map_set_cell_size]."
#: doc/classes/ProjectSettings.xml
msgid ""
"Default edge connection margin for 2D navigation maps. See [method "
"Navigation2DServer.map_set_edge_connection_margin]."
msgstr ""
+"Margem de conexão de borda padrão para mapas de navegação 2D. Consulte "
+"[method Navigation2DServer.map_set_edge_connection_margin]."
#: doc/classes/ProjectSettings.xml
msgid ""
"Default cell height for 3D navigation maps. See [method NavigationServer."
"map_set_cell_height]."
msgstr ""
+"Altura de célula padrão para mapas de navegação 3D. Consulte [method "
+"NavigationServer.map_set_cell_height]."
#: doc/classes/ProjectSettings.xml
msgid ""
"Default cell size for 3D navigation maps. See [method NavigationServer."
"map_set_cell_size]."
msgstr ""
+"Tamanho de célula padrão para mapas de navegação 3D. Consulte [method "
+"NavigationServer.map_set_cell_size]."
#: doc/classes/ProjectSettings.xml
msgid ""
"Default edge connection margin for 3D navigation maps. See [method "
"NavigationServer.map_set_edge_connection_margin]."
msgstr ""
+"Margem de conexão de borda padrão para mapas de navegação 3D. Consulte "
+"[method NavigationServer.map_set_edge_connection_margin]."
#: doc/classes/ProjectSettings.xml
msgid ""
"Default map up vector for 3D navigation maps. See [method NavigationServer."
"map_set_up]."
msgstr ""
+"Vetor de mapa padrão para mapas de navegação 3D. Consulte [method "
+"NavigationServer.map_set_up]."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -49383,6 +49640,9 @@ msgid ""
"Over this value, content is dropped. This helps not to stall the debugger "
"connection."
msgstr ""
+"Quantidade máxima de caracteres permitidos para enviar como saída do "
+"depurador. Acima desse valor, o conteúdo é descartado. Isso ajuda a não "
+"travar a conexão do depurador."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -49390,6 +49650,9 @@ msgid ""
"Over this value, content is dropped. This helps not to stall the debugger "
"connection."
msgstr ""
+"Número máximo de erros permitidos a serem enviados como saída do depurador. "
+"Acima desse valor, o conteúdo é descartado. Isso ajuda a não travar a "
+"conexão do depurador."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -49397,6 +49660,9 @@ msgid ""
"this value, content is dropped. This helps not to stall the debugger "
"connection."
msgstr ""
+"Quantidade máxima de mensagens permitidas para enviar como saída do "
+"depurador. Acima desse valor, o conteúdo é descartado. Isso ajuda a não "
+"travar a conexão do depurador."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -49404,6 +49670,9 @@ msgid ""
"Over this value, content is dropped. This helps not to stall the debugger "
"connection."
msgstr ""
+"Número máximo de avisos que podem ser enviados como saída do depurador. "
+"Acima desse valor, o conteúdo é descartado. Isso ajuda a não travar a "
+"conexão do depurador."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -49411,56 +49680,64 @@ msgid ""
"specified as a power of two). The default value [code]16[/code] is equal to "
"65,536 bytes. Over this size, data is dropped."
msgstr ""
+"Tamanho padrão do fluxo de pares de pacotes para desserializar dados Godot "
+"(em bytes, especificado como uma potência de dois). O valor padrão [code]16[/"
+"code] é igual a 65.536 bytes. Acima desse tamanho, os dados são descartados."
#: doc/classes/ProjectSettings.xml
msgid "Timeout (in seconds) for connection attempts using TCP."
-msgstr ""
+msgstr "Tempo limite (em segundos) para tentativas de conexão usando TCP."
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebRTCDataChannel] input buffer."
-msgstr ""
+msgstr "Tamanho máximo (em kiB) para o buffer de entrada [WebRTCDataChannel]."
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebSocketClient] input buffer."
-msgstr ""
+msgstr "Tamanho máximo (em kiB) para o buffer de entrada [WebSocketClient]."
#: doc/classes/ProjectSettings.xml
msgid "Maximum number of concurrent input packets for [WebSocketClient]."
msgstr ""
+"Número máximo de pacotes de entrada simultâneos para [WebSocketClient]."
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebSocketClient] output buffer."
-msgstr ""
+msgstr "Tamanho máximo (em kiB) para o buffer de saída [WebSocketClient]."
#: doc/classes/ProjectSettings.xml
msgid "Maximum number of concurrent output packets for [WebSocketClient]."
-msgstr ""
+msgstr "Número máximo de pacotes de saída simultâneos para [WebSocketClient]."
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebSocketServer] input buffer."
-msgstr ""
+msgstr "Tamanho máximo (em kiB) para o buffer de entrada [WebSocketServer]."
#: doc/classes/ProjectSettings.xml
msgid "Maximum number of concurrent input packets for [WebSocketServer]."
msgstr ""
+"Número máximo de pacotes de entrada simultâneos para [WebSocketServer]."
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebSocketServer] output buffer."
-msgstr ""
+msgstr "Tamanho máximo (em kiB) para o buffer de saída [WebSocketServer]."
#: doc/classes/ProjectSettings.xml
msgid "Maximum number of concurrent output packets for [WebSocketServer]."
-msgstr ""
+msgstr "Número máximo de pacotes de saída simultâneos para [WebSocketServer]."
#: doc/classes/ProjectSettings.xml
msgid ""
"Amount of read ahead used by remote filesystem. Higher values decrease the "
"effects of latency at the cost of higher bandwidth usage."
msgstr ""
+"Quantidade de leitura antecipada usada pelo sistema de arquivos remoto. "
+"Valores mais altos diminuem os efeitos da latência ao custo de maior uso de "
+"largura de banda."
#: doc/classes/ProjectSettings.xml
msgid "Page size used by remote filesystem (in bytes)."
-msgstr ""
+msgstr "Tamanho da página usado pelo sistema de arquivos remoto (em bytes)."
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -50052,20 +50329,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -50073,19 +50358,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -50117,14 +50411,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50578,8 +50880,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54816,24 +55118,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54842,8 +55143,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54851,16 +55153,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54872,7 +55174,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54902,21 +55204,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54952,11 +55257,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54997,13 +55302,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -55067,10 +55372,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -55124,8 +55429,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -55156,16 +55461,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -55173,7 +55477,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56484,11 +56788,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58973,7 +59296,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -59163,11 +59510,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -59570,9 +59917,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -61113,6 +61462,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "Se [code]true[/code], o objeto é desenhado por cima do pai dele."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -64049,7 +64403,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -66506,11 +66871,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -66590,8 +66955,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -67196,9 +67561,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -67227,7 +67593,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/pt_BR.po b/doc/translations/pt_BR.po
index 16779b76ff..50d4359c46 100644
--- a/doc/translations/pt_BR.po
+++ b/doc/translations/pt_BR.po
@@ -584,6 +584,7 @@ msgstr ""
"inst2dict]), de volta em uma instância. Útil para desserialização."
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns an \"eased\" value of [code]x[/code] based on an easing function "
"defined with [code]curve[/code]. This easing function is based on an "
@@ -598,7 +599,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1717,6 +1718,7 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns the result of smoothly interpolating the value of [code]s[/code] "
"between [code]0[/code] and [code]1[/code], based on the where [code]s[/code] "
@@ -1737,7 +1739,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -11023,7 +11025,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -11188,7 +11196,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -13207,10 +13221,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -20590,13 +20606,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20606,7 +20626,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20623,23 +20647,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -29478,7 +29502,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -29617,13 +29641,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -31041,7 +31066,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -31615,10 +31643,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -31630,6 +31662,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -31949,6 +31987,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -32113,7 +32156,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -35883,12 +35937,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Retorna o número de nós nesta [SceneTree]."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -35924,7 +35984,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -36724,6 +36787,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -36770,6 +36836,9 @@ msgstr "Retorna o número de nós nesta [SceneTree]."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -36813,6 +36882,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -36832,6 +36904,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36970,11 +37045,47 @@ msgid "Destroys the given RID."
msgstr "Retorna o [RID] do objeto."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -37092,6 +37203,23 @@ msgstr ""
"Retorna a [Cor] em [code]name[/code] se o tema tiver [code]node_type[/code]."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -37308,21 +37436,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
-msgid "The radius of the agent."
-msgstr "A cor do texto."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
+msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -37419,6 +37566,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -37541,6 +37696,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -37714,7 +37879,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -39600,13 +39773,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -39618,8 +39797,11 @@ msgid "Emitted when the node is renamed."
msgstr "Emitido quando o nó é renomeado."
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
-msgstr "Emitido quando o nó entra na árvore."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
+msgstr ""
#: doc/classes/Node.xml
msgid "Emitted after the node exits the tree and is no longer active."
@@ -39628,15 +39810,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -41349,6 +41537,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -46481,6 +46673,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -46893,7 +47092,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -50473,20 +50683,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -50494,19 +50712,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -50538,14 +50765,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50999,8 +51234,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -55247,24 +55482,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -55273,8 +55507,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -55282,16 +55517,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -55303,7 +55538,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55333,21 +55568,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -55383,11 +55621,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55428,13 +55666,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -55498,10 +55736,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -55555,8 +55793,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -55587,16 +55825,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -55604,7 +55841,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56917,11 +57154,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -59409,7 +59665,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -59599,11 +59879,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -60006,9 +60286,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -61567,6 +61849,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "Retorna [code]true[/code] se o script pode ser instanciado."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -64511,7 +64798,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -66973,11 +67271,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -67057,8 +67355,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -67671,9 +67969,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -67705,7 +68004,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/ro.po b/doc/translations/ro.po
index dbc5017a08..8c7112f102 100644
--- a/doc/translations/ro.po
+++ b/doc/translations/ro.po
@@ -420,7 +420,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1127,7 +1127,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9995,7 +9995,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10160,7 +10166,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12169,10 +12181,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19454,13 +19468,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19470,7 +19488,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19487,23 +19509,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28294,7 +28316,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28433,13 +28455,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29852,7 +29875,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30426,10 +30452,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30441,6 +30471,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30752,6 +30788,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30916,7 +30957,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34663,11 +34715,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34704,7 +34761,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35496,6 +35556,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35541,6 +35604,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35584,6 +35650,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35603,6 +35672,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35732,11 +35804,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35846,6 +35954,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36052,20 +36177,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36159,6 +36304,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36279,6 +36432,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36448,7 +36611,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38324,13 +38495,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38342,7 +38519,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38352,15 +38532,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40067,6 +40253,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45155,6 +45345,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45567,7 +45764,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49140,20 +49348,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49161,19 +49377,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49205,14 +49430,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49666,8 +49899,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53901,24 +54134,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53927,8 +54159,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53936,16 +54169,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53957,7 +54190,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53987,21 +54220,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54037,11 +54273,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54082,13 +54318,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54152,10 +54388,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54209,8 +54445,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54241,16 +54477,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54258,7 +54493,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55567,11 +55802,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58036,7 +58290,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58226,11 +58504,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58633,9 +58911,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60172,6 +60452,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63101,7 +63385,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65547,11 +65842,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65631,8 +65926,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66235,9 +66530,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66266,7 +66562,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/ru.po b/doc/translations/ru.po
index ec2940636f..1596ca8553 100644
--- a/doc/translations/ru.po
+++ b/doc/translations/ru.po
@@ -48,12 +48,13 @@
# Bozhko Artyom Dmitrievich <jek_sun@mail.ru>, 2022.
# FuzzMix <fmwolfiechad@gmail.com>, 2022.
# МÐÐ69К <weblate@mah69k.net>, 2022.
+# Vadim Mitroshkin <Vadim7540@yandex.ru>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-06-08 06:47+0000\n"
-"Last-Translator: FuzzMix <fmwolfiechad@gmail.com>\n"
+"PO-Revision-Date: 2022-07-03 00:44+0000\n"
+"Last-Translator: Bozhko Artyom Dmitrievich <jek_sun@mail.ru>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/ru/>\n"
"Language: ru\n"
@@ -62,7 +63,7 @@ msgstr ""
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -154,7 +155,8 @@ msgstr ""
#: doc/tools/make_rst.py
msgid ""
"This method accepts any number of arguments after the ones described here."
-msgstr "Этот метод принимает любое количеÑтво аргументов поÑле опиÑанных."
+msgstr ""
+"Этот метод принимает любое количеÑтво аргументов поÑле опиÑанных здеÑÑŒ."
#: doc/tools/make_rst.py
msgid "This method is used to construct a type."
@@ -533,7 +535,6 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Compares two values by checking their actual contents, recursing into any "
"[Array] or [Dictionary] up to its deepest level.\n"
@@ -559,9 +560,9 @@ msgstr ""
"- Ð”Ð»Ñ [code]null[/code], [code]int[/code], [code]float[/code], [code]String[/"
"code], [code]Object[/code] и [code]RID[/code], [code]deep_equal[/code] и "
"[code]==[/code] работают одинаково.\n"
-"- Ð”Ð»Ñ [code]Dictionary[/code], [code]==[/code] раÑÑматривает равенÑтво и "
-"только еÑли обе переменные указывают на один и тот же [code]Dictionary[/"
-"code], без рекурÑии или проÑмотра Ñодержимого вообще.\n"
+"- Ð”Ð»Ñ [code]Dictionary[/code], [code]==[/code] раÑÑматривает равенÑтво "
+"тогда, и только тогда, когда обе переменные указывают на один и тот же "
+"[code]Dictionary[/code], без рекурÑии или проÑмотра Ñодержимого вообще.\n"
"- Ð”Ð»Ñ [code]Array[/code], [code]==[/code] ÑчитаетÑÑ Ñ€Ð°Ð²ÐµÐ½Ñтвом тогда, и "
"только тогда, когда каждый Ñлемент в первом [code]Array[/code] равен "
"Ñлементу во втором [code]Array[/code], как Ñообщает [code]==[/code]. Это "
@@ -592,6 +593,7 @@ msgstr ""
"ÑкземплÑÑ€ объекта. Полезно Ð´Ð»Ñ Ð´ÐµÑериализации."
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns an \"eased\" value of [code]x[/code] based on an easing function "
"defined with [code]curve[/code]. This easing function is based on an "
@@ -606,7 +608,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1005,7 +1007,6 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Linearly interpolates between two angles (in radians) by a normalized "
"value.\n"
@@ -1031,7 +1032,7 @@ msgstr ""
"Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»ÑÑ†Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ Ð´Ð²ÑƒÐ¼Ñ ÑƒÐ³Ð»Ð°Ð¼Ð¸ (в радианах) по нормализованному "
"значению.\n"
"Ðналогично [методу lerp], но корректно интерполируетÑÑ, когда углы "
-"оборачивают вокруг [constant @GDScript.TAU]. Чтобы выполнить упрощенную "
+"оборачивают вокруг [конÑтанты @GDScript.TAU]. Чтобы выполнить упрощенную "
"интерполÑцию Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ [метода lerp_angle], объедините его Ñ [методом ease] "
"или [методом smoothstep].\n"
"[codeblock]\n"
@@ -1042,7 +1043,14 @@ msgstr ""
" var max_angle = deg2rad(90.0)\n"
" rotation = lerp_angle(min_angle, max_angle, elapsed)\n"
" elapsed += delta\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"[b]Примечание:[/b] Этот метод проходит через кратчайший путь между "
+"[code]from[/code] и [code]to[/code]. Тем не менее, еÑли разница между Ñтими "
+"Ð´Ð²ÑƒÐ¼Ñ ÑƒÐ³Ð»Ð°Ð¼Ð¸ и любым целым чиÑлом [code]k[/code] приблизительно [code]PI + "
+"k * TAU[/code], неочевидно в какую Ñторону [/code]из-за ошибок в точноÑти "
+"чиÑел Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой. Ðапример, [code]lerp_angle(0, PI, weight)[/code] "
+"оборачиваетÑÑ Ð¿Ñ€Ð¾Ñ‚Ð¸Ð² чаÑовой Ñтрелки, а [code]lerp_angle(0, PI + 5 * TAU, "
+"weight)[/code] оборачиваетÑÑ Ð¿Ð¾ чаÑовой."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -1291,7 +1299,6 @@ msgstr ""
"координат (оÑи X и Y)."
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Returns the integer modulus of [code]a/b[/code] that wraps equally in "
"positive and negative.\n"
@@ -1313,28 +1320,21 @@ msgstr ""
"Возвращает целочиÑленный модуль [code]a/b[/code], который одинаково "
"переноÑитÑÑ ÐºÐ°Ðº в положительный, так и в отрицательный.\n"
"[codeblock]\n"
-"var i = -6\n"
-"while i < 5:\n"
-" prints(i, posmod(i, 3))\n"
-" i += 1\n"
+"for i in range(-3, 4):\n"
+" print(\"%2d %2d %2d\" % [i, i % 3, posmod(i, 3)])\n"
"[/codeblock]\n"
"Produces:\n"
"[codeblock]\n"
-"-6 0\n"
-"-5 1\n"
-"-4 2\n"
-"-3 0\n"
-"-2 1\n"
-"-1 2\n"
-"0 0\n"
-"1 1\n"
-"2 2\n"
-"3 0\n"
-"4 1\n"
+"-3 0 0\n"
+"-2 -2 1\n"
+"-1 -1 2\n"
+" 0 0 0\n"
+" 1 1 1\n"
+" 2 2 2\n"
+" 3 0 0\n"
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Returns the result of [code]base[/code] raised to the power of [code]exp[/"
"code].\n"
@@ -1345,7 +1345,7 @@ msgstr ""
"Возвращает результат Ð²Ð¾Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ‡Ð¸Ñла [code]x[/code] в Ñтепени [code]y[/"
"code].\n"
"[codeblock]\n"
-"pow(2, 5) # Возвращает 32\n"
+"pow(2, 5) # Возвращает 32.0\n"
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
@@ -1524,7 +1524,6 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Converts an angle expressed in radians to degrees.\n"
"[codeblock]\n"
@@ -1533,7 +1532,7 @@ msgid ""
msgstr ""
"Преобразует угол, выраженный в радианах, в градуÑÑ‹.\n"
"[codeblock]\n"
-"rad2deg(0.523599) # Возвращает 30\n"
+"rad2deg(0.523599) # Возвращает 30.0\n"
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
@@ -1580,7 +1579,6 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Returns a random unsigned 32-bit integer. Use remainder to obtain a random "
"value in the interval [code][0, N - 1][/code] (where N is smaller than "
@@ -1659,6 +1657,44 @@ msgid ""
"3\n"
"[/codeblock]"
msgstr ""
+"Возвращает маÑÑив Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ñ‹Ð¼ диапазоном. [метод range] может быть вызван "
+"Ñ‚Ñ€ÐµÐ¼Ñ ÑпоÑобами:\n"
+"[code]range(n: int)[/code]: ÐачинаетÑÑ Ñ 0, увеличиваетÑÑ Ñ ÑˆÐ°Ð³Ð¾Ð¼ в 1 и "
+"оÑтанавливаетÑÑ [i]перед[/i] [code]n[/code]. Ðргумент [code]n[/code] Ñто "
+"[b]ÑкÑклюзив[/b].\n"
+"[code]range(b: int, n: int)[/code]: ÐачинаетÑÑ Ñ [code]b[/code], "
+"увеличиваетÑÑ Ñ ÑˆÐ°Ð³Ð¾Ð¼ в 1 и оÑтанавливаетÑÑ [i]перед[/i] [code]n[/code]. "
+"Ðргументы [code]b[/code] и [code]n[/code] Ñто [b]инклюзив[/b] и "
+"[b]ÑкÑклюзив[/b], ÑоответÑтвенно.\n"
+"[code]range(b: int, n: int, s: int)[/code]: ÐачинаетÑÑ Ñ [code]b[/code], "
+"увеличиваетÑÑ/уменьшаетÑÑ Ñ ÑˆÐ°Ð³Ð¾Ð¼ [code]s[/code], и оÑтанавливаетÑÑ "
+"[i]перед[/i] [code]n[/code]. Ðргументы [code]b[/code] и [code]n[/code] Ñто "
+"[b]инклюзив[/b] и [b]ÑкÑклюзив[/b], ÑоответÑтвенно. Ðргумент [code]s[/code] "
+"[b]может[/b] быть негативным, но не [code]0[/code]. ЕÑли [code]s[/code] Ñто "
+"[code]0[/code], будет выведено Ñообщение об ошибке.\n"
+"[метод range] преобразует вÑе аргументы в [int] перед обработкой.\n"
+"[b]Примечание:[/b] Возвращает пуÑтой маÑÑив, еÑли ни одно значение не "
+"удовлетворÑет ограничению на значение (e.g. [code]range(2, 5, -1)[/code] или "
+"[code]range(5, 5, 1)[/code]).\n"
+"Примеры:\n"
+"[codeblock]\n"
+"print(range(4)) # Prints [0, 1, 2, 3]\n"
+"print(range(2, 5)) # Prints [2, 3, 4]\n"
+"print(range(0, 6, 2)) # Prints [0, 2, 4]\n"
+"print(range(4, 1, -1)) # Prints [4, 3, 2]\n"
+"[/codeblock]\n"
+"Чтобы выполнить итерацию по [Array] в обратном порÑдке, иÑпользуйте:\n"
+"[codeblock]\n"
+"var array = [3, 6, 9]\n"
+"for i in range(array.size(), 0, -1):\n"
+" print(array[i - 1])\n"
+"[/codeblock]\n"
+"Вывод:\n"
+"[codeblock]\n"
+"9\n"
+"6\n"
+"3\n"
+"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -1675,7 +1711,6 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Rounds [code]s[/code] to the nearest whole number, with halfway cases "
"rounded away from zero.\n"
@@ -1686,11 +1721,14 @@ msgid ""
"[/codeblock]\n"
"See also [method floor], [method ceil], [method stepify], and [int]."
msgstr ""
-"ОкруглÑет [code]s[/code] к ближайшему целому чиÑлу, при Ñтом Ñередины "
-"округлÑÑŽÑ‚ÑÑ Ð¾Ñ‚ нулÑ.\n"
+"ОкруглÑет [code]s[/code] к ближайшему целому чиÑлу, при Ñтом 0.5 округлÑетÑÑ "
+"в большую Ñторону.\n"
"[codeblock]\n"
-"round(2.6) # Возвращает 3\n"
-"[/codeblock]"
+"a = round(2.49) # Возвращает 2.0\n"
+"a = round(2.5) # Возвращает 3.0\n"
+"a = round(2.51) # Возвращает 3.0\n"
+"[/codeblock]\n"
+"См. также[метод floor], [метод ceil], [метод stepify], и [int]."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -1772,7 +1810,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -11606,7 +11644,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -11771,7 +11815,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -13798,10 +13848,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -21230,13 +21282,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -21246,7 +21302,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -21263,23 +21323,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -30121,7 +30181,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -30260,13 +30320,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -31683,7 +31744,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -32257,10 +32321,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -32271,6 +32339,15 @@ msgid "Mouse and input coordinates"
msgstr ""
#: doc/classes/InputEventMouseMotion.xml
+#, fuzzy
+msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+"Возвращает [code]true[/code] еÑли [code]a[/code] и [code]b[/code] "
+"приблизительно равны друг другу."
+
+#: doc/classes/InputEventMouseMotion.xml
msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
@@ -32585,6 +32662,11 @@ msgstr "ЕÑли [code]true[/code], текÑтура отражена по веÑ
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -32749,7 +32831,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -36540,12 +36633,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Возвращает чиÑло Ñлементов в маÑÑиве."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -36581,7 +36680,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -37381,6 +37483,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -37427,6 +37532,9 @@ msgstr "Возвращает количеÑтво дорожек в анимац
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -37470,6 +37578,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -37489,6 +37600,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -37626,11 +37740,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -37752,6 +37902,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "ЛогичеÑкий оператор ИЛИ ([code]or[/code] или [code]||[/code])."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "ЛогичеÑкий оператор ИЛИ ([code]or[/code] или [code]||[/code])."
@@ -37968,21 +38135,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
-msgid "The radius of the agent."
-msgstr "Цвет Ñффекта отражениÑ."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
+msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -38078,6 +38264,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -38202,6 +38396,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr "ЕÑли [code]true[/code], текÑтура отражена по горизонтали."
@@ -38375,7 +38579,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -40343,13 +40555,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -40361,7 +40579,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -40371,15 +40592,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -42104,6 +42331,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -47241,6 +47472,14 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+#, fuzzy
+msgid "Sorts the elements of the array in ascending order."
+msgstr "УдалÑет Ñлемент из маÑÑива по индекÑу."
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -47667,7 +47906,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -51265,20 +51515,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -51286,19 +51544,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -51330,14 +51597,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -51791,8 +52066,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -56086,24 +56361,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -56112,8 +56386,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -56121,16 +56396,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -56142,7 +56417,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56172,21 +56447,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -56222,11 +56500,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56267,13 +56545,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -56337,10 +56615,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -56394,8 +56672,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -56426,16 +56704,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -56443,7 +56720,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -57759,11 +58036,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -60263,7 +60559,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -60453,11 +60773,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -60860,9 +61180,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -62420,6 +62742,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "ЕÑли [code]true[/code], текÑтура будет центрирована."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -65390,7 +65717,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -67978,11 +68316,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -68062,8 +68400,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -68677,9 +69015,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -68709,7 +69048,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/sk.po b/doc/translations/sk.po
index 20caeea6c2..38e701eef9 100644
--- a/doc/translations/sk.po
+++ b/doc/translations/sk.po
@@ -395,7 +395,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1102,7 +1102,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9966,7 +9966,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10131,7 +10137,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12140,10 +12152,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19425,13 +19439,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19441,7 +19459,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19458,23 +19480,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28265,7 +28287,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28404,13 +28426,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29823,7 +29846,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30397,10 +30423,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30412,6 +30442,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30723,6 +30759,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30887,7 +30928,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34634,11 +34686,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34675,7 +34732,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35467,6 +35527,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35512,6 +35575,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35555,6 +35621,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35574,6 +35643,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35703,11 +35775,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35817,6 +35925,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36023,20 +36148,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36130,6 +36275,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36250,6 +36403,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36419,7 +36582,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38294,13 +38465,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38312,7 +38489,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38322,15 +38502,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40037,6 +40223,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45125,6 +45315,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45537,7 +45734,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49110,20 +49318,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49131,19 +49347,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49175,14 +49400,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49636,8 +49869,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53871,24 +54104,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53897,8 +54129,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53906,16 +54139,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53927,7 +54160,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53957,21 +54190,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54007,11 +54243,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54052,13 +54288,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54122,10 +54358,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54179,8 +54415,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54211,16 +54447,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54228,7 +54463,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55537,11 +55772,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58006,7 +58260,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58196,11 +58474,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58603,9 +58881,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60142,6 +60422,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63071,7 +63355,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65517,11 +65812,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65601,8 +65896,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66205,9 +66500,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66236,7 +66532,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/sr_Cyrl.po b/doc/translations/sr_Cyrl.po
index 4d48a80e07..3984d209f4 100644
--- a/doc/translations/sr_Cyrl.po
+++ b/doc/translations/sr_Cyrl.po
@@ -406,7 +406,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1113,7 +1113,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9977,7 +9977,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10142,7 +10148,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12151,10 +12163,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19436,13 +19450,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19452,7 +19470,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19469,23 +19491,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28276,7 +28298,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28415,13 +28437,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29834,7 +29857,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30408,10 +30434,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30423,6 +30453,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30734,6 +30770,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30898,7 +30939,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34645,11 +34697,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34686,7 +34743,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35478,6 +35538,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35523,6 +35586,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35566,6 +35632,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35585,6 +35654,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35714,11 +35786,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35828,6 +35936,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36034,20 +36159,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36141,6 +36286,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36261,6 +36414,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36430,7 +36593,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38305,13 +38476,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38323,7 +38500,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38333,15 +38513,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40048,6 +40234,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45136,6 +45326,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45548,7 +45745,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49121,20 +49329,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49142,19 +49358,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49186,14 +49411,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49647,8 +49880,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53882,24 +54115,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53908,8 +54140,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53917,16 +54150,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53938,7 +54171,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53968,21 +54201,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54018,11 +54254,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54063,13 +54299,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54133,10 +54369,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54190,8 +54426,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54222,16 +54458,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54239,7 +54474,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55548,11 +55783,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58017,7 +58271,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58207,11 +58485,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58614,9 +58892,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60153,6 +60433,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63082,7 +63366,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65528,11 +65823,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65612,8 +65907,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66216,9 +66511,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66247,7 +66543,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/sv.po b/doc/translations/sv.po
index 4836ca862f..9be24493d7 100644
--- a/doc/translations/sv.po
+++ b/doc/translations/sv.po
@@ -395,7 +395,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1102,7 +1102,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -9966,7 +9966,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10131,7 +10137,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12140,10 +12152,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19425,13 +19439,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19441,7 +19459,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19458,23 +19480,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28262,7 +28284,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28401,13 +28423,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29820,7 +29843,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30394,10 +30420,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30409,6 +30439,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30720,6 +30756,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30884,7 +30925,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34631,11 +34683,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34672,7 +34729,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35464,6 +35524,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35509,6 +35572,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35552,6 +35618,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35571,6 +35640,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35700,11 +35772,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35814,6 +35922,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36020,20 +36145,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36127,6 +36272,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36247,6 +36400,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36416,7 +36579,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38291,13 +38462,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38309,7 +38486,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38319,15 +38499,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40034,6 +40220,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45122,6 +45312,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45534,7 +45731,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49107,20 +49315,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49128,19 +49344,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49172,14 +49397,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49633,8 +49866,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53868,24 +54101,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -53894,8 +54126,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -53903,16 +54136,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -53924,7 +54157,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -53954,21 +54187,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54004,11 +54240,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54049,13 +54285,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54119,10 +54355,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54176,8 +54412,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54208,16 +54444,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54225,7 +54460,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55534,11 +55769,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58003,7 +58257,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58193,11 +58471,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58600,9 +58878,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60139,6 +60419,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63068,7 +63352,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65514,11 +65809,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65598,8 +65893,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66202,9 +66497,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66233,7 +66529,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/th.po b/doc/translations/th.po
index 0bdffafffa..dabf3c09f3 100644
--- a/doc/translations/th.po
+++ b/doc/translations/th.po
@@ -473,7 +473,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1187,7 +1187,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10072,7 +10072,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10237,7 +10243,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12246,10 +12258,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19535,13 +19549,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19551,7 +19569,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19568,23 +19590,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28381,7 +28403,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28520,13 +28542,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29961,7 +29984,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30551,10 +30577,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30566,6 +30596,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30881,6 +30917,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31045,7 +31086,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34804,12 +34856,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "คืนค่าชื่อของอุปà¸à¸£à¸“์เสียงทั้งหมดที่ตรวจพบในระบบ"
#: doc/classes/MeshInstance.xml
msgid ""
@@ -34845,7 +34903,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35637,6 +35698,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35683,6 +35747,9 @@ msgstr "คืนค่าผà¸à¸œà¸±à¸™à¸£à¸¹à¸—สองของพารา
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35726,6 +35793,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35745,6 +35815,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35877,11 +35950,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35996,6 +36105,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "คืนค่าà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าของลำโพง"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "คืนค่าà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าของลำโพง"
@@ -36207,20 +36333,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36315,6 +36461,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36435,6 +36589,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36604,7 +36768,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38532,13 +38704,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38550,7 +38728,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38560,15 +38741,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40277,6 +40464,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45372,6 +45563,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45784,7 +45982,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49364,20 +49573,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49385,19 +49602,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49429,14 +49655,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49890,8 +50124,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54128,24 +54362,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54154,8 +54387,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54163,16 +54397,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54184,7 +54418,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54214,21 +54448,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54264,11 +54501,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54309,13 +54546,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54379,10 +54616,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54436,8 +54673,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54468,16 +54705,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54485,7 +54721,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55794,11 +56030,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58266,7 +58521,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58456,11 +58735,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58863,9 +59142,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60406,6 +60687,10 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63335,7 +63620,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65794,11 +66090,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65878,8 +66174,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66482,9 +66778,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66513,7 +66810,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/tl.po b/doc/translations/tl.po
index 5ced19938d..b100d0e612 100644
--- a/doc/translations/tl.po
+++ b/doc/translations/tl.po
@@ -441,7 +441,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1178,7 +1178,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10046,7 +10046,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10211,7 +10217,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12223,10 +12235,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19508,13 +19522,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19524,7 +19542,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19541,23 +19563,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28351,7 +28373,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28490,13 +28512,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29909,7 +29932,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30483,10 +30509,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30498,6 +30528,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30809,6 +30845,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -30973,7 +31014,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34732,11 +34784,16 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
+msgid "Returns the number of surface override materials."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -34773,7 +34830,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35565,6 +35625,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35610,6 +35673,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35653,6 +35719,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35672,6 +35741,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35804,11 +35876,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35927,6 +36035,23 @@ msgstr ""
"so-sort ay hindi pinapagana."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr ""
@@ -36133,20 +36258,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36240,6 +36385,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36360,6 +36513,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36529,7 +36692,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38404,13 +38575,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38422,7 +38599,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38432,15 +38612,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40147,6 +40333,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45238,6 +45428,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45650,7 +45847,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49223,20 +49431,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49244,19 +49460,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49288,14 +49513,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49749,8 +49982,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -53984,24 +54217,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54010,8 +54242,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54019,16 +54252,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54040,7 +54273,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54070,21 +54303,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54120,11 +54356,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54165,13 +54401,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54235,10 +54471,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54292,8 +54528,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54324,16 +54560,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54341,7 +54576,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55650,11 +55885,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58119,7 +58373,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58309,11 +58587,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58716,9 +58994,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60258,6 +60538,13 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+"Kung [code]true[/code], ang mga child nodes ay inaayos, kung hindi ang pag-"
+"so-sort ay hindi pinapagana."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63190,7 +63477,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65636,11 +65934,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65720,8 +66018,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66327,9 +66625,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66358,7 +66657,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/tr.po b/doc/translations/tr.po
index d7cc5bd8df..dc9d2524b7 100644
--- a/doc/translations/tr.po
+++ b/doc/translations/tr.po
@@ -18,12 +18,14 @@
# yigithan <yigithanermet38@gmail.com>, 2021.
# Yusuf Yavuzyigit <yusufyavuzyigit25@gmail.com>, 2021, 2022.
# Ramazan Aslan <legendraslan@gmail.com>, 2022.
+# paledega <paledega@yandex.ru>, 2022.
+# Yekez <yasintonge@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-06-13 03:39+0000\n"
-"Last-Translator: Ramazan Aslan <legendraslan@gmail.com>\n"
+"PO-Revision-Date: 2022-07-03 00:45+0000\n"
+"Last-Translator: Yekez <yasintonge@gmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/tr/>\n"
"Language: tr\n"
@@ -31,7 +33,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -83,7 +85,7 @@ msgstr "Miras:"
#: doc/tools/make_rst.py
msgid "Inherited By:"
-msgstr ""
+msgstr "Kalıtılan:"
#: doc/tools/make_rst.py
msgid "(overrides %s)"
@@ -91,19 +93,21 @@ msgstr ""
#: doc/tools/make_rst.py
msgid "Default"
-msgstr ""
+msgstr "Varsayılan"
#: doc/tools/make_rst.py
+#, fuzzy
msgid "Setter"
-msgstr ""
+msgstr "Ayarlayıcı"
#: doc/tools/make_rst.py
msgid "value"
msgstr "deÄŸer"
#: doc/tools/make_rst.py
+#, fuzzy
msgid "Getter"
-msgstr ""
+msgstr "Alıcı"
#: doc/tools/make_rst.py
msgid ""
@@ -129,13 +133,15 @@ msgstr ""
#: doc/tools/make_rst.py
msgid "This method is used to construct a type."
-msgstr ""
+msgstr "Bu method bir veri tipi oluşturmak için kullanılır."
#: doc/tools/make_rst.py
msgid ""
"This method doesn't need an instance to be called, so it can be called "
"directly using the class name."
msgstr ""
+"Bu metod çağrılmak için bir örneklemeye ihtiyaç duymaz, bu yüzden doğrudan "
+"sınıf adı ile çağırılabilir."
#: doc/tools/make_rst.py
msgid ""
@@ -554,7 +560,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1684,7 +1690,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10747,7 +10753,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10912,7 +10924,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12925,10 +12943,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -20232,13 +20252,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20248,7 +20272,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -20265,23 +20293,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -29097,7 +29125,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -29236,13 +29264,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30657,7 +30686,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -31231,10 +31263,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -31246,6 +31282,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -31560,6 +31602,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31724,7 +31771,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -35484,12 +35542,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "İki vektörün kalanını döndürür."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -35525,7 +35589,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -36324,6 +36391,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -36370,6 +36440,9 @@ msgstr "Verilen değerin sinüsünü döndürür."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -36413,6 +36486,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -36432,6 +36508,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36569,11 +36648,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36690,6 +36805,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Verilen değerin sinüsünü döndürür."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "Verilen değerin sinüsünü döndürür."
@@ -36902,20 +37034,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -37011,6 +37163,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -37132,6 +37292,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -37304,7 +37474,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -39188,13 +39366,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -39206,7 +39390,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -39216,15 +39403,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40936,6 +41129,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -46056,6 +46253,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -46468,7 +46672,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -50044,20 +50259,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -50065,19 +50288,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -50109,14 +50341,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50570,8 +50810,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54814,24 +55054,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54840,8 +55079,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54849,16 +55089,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54870,7 +55110,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54900,21 +55140,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54950,11 +55193,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54995,13 +55238,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -55065,10 +55308,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -55122,8 +55365,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -55154,16 +55397,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -55171,7 +55413,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56480,11 +56722,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58953,7 +59214,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -59143,11 +59428,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -59550,9 +59835,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -61099,6 +61386,12 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr ""
+"Eğer [code]true[/code] ise düğümler sıraya sokulur, yoksa sıraya sokulmaz."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -64032,7 +64325,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -66485,11 +66789,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -66569,8 +66873,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -67180,9 +67484,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -67213,7 +67518,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/uk.po b/doc/translations/uk.po
index 22271dc2ea..afedf189b4 100644
--- a/doc/translations/uk.po
+++ b/doc/translations/uk.po
@@ -530,7 +530,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1245,7 +1245,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10125,7 +10125,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10290,7 +10296,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12302,10 +12314,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19604,13 +19618,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19620,7 +19638,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19637,23 +19659,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28459,7 +28481,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28598,13 +28620,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30019,7 +30042,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30593,10 +30619,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30608,6 +30638,12 @@ msgstr "Мишка Ñ– координати введеннÑ"
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30920,6 +30956,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31084,7 +31125,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34836,12 +34888,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Повертає лишок за двома векторами."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -34877,7 +34935,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35677,6 +35738,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35723,6 +35787,9 @@ msgstr "Повертає ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35766,6 +35833,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35785,6 +35855,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35920,11 +35993,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36040,6 +36149,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "ОбчиÑлює векторний добуток цього вектора Ñ– [code]b[/code]."
@@ -36253,20 +36379,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36362,6 +36508,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36483,6 +36637,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36653,7 +36817,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38535,13 +38707,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38553,7 +38731,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38563,15 +38744,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40283,6 +40470,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45394,6 +45585,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45806,7 +46004,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49382,20 +49591,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49403,19 +49620,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49447,14 +49673,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49908,8 +50142,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54145,24 +54379,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54171,8 +54404,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54180,16 +54414,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54201,7 +54435,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54231,21 +54465,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54281,11 +54518,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54326,13 +54563,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54396,10 +54633,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54453,8 +54690,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54485,16 +54722,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54502,7 +54738,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55812,11 +56048,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58284,7 +58539,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58474,11 +58753,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58881,9 +59160,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60429,6 +60710,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "Повертає коÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63363,7 +63649,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65817,11 +66114,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65901,8 +66198,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66509,9 +66806,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66540,7 +66838,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/vi.po b/doc/translations/vi.po
index b813d4a4a5..ab16aa1782 100644
--- a/doc/translations/vi.po
+++ b/doc/translations/vi.po
@@ -532,7 +532,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1462,7 +1462,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10420,7 +10420,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10585,7 +10591,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12598,10 +12610,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19903,13 +19917,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19919,7 +19937,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19936,23 +19958,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28756,7 +28778,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28895,13 +28917,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -30317,7 +30340,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30891,10 +30917,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30906,6 +30936,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -31219,6 +31255,11 @@ msgstr "Nếu [code]true[/code] thì lật dá»c há»a tiết."
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31383,7 +31424,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -35137,12 +35189,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "Trả vỠphần dư của hai vector."
#: doc/classes/MeshInstance.xml
msgid ""
@@ -35178,7 +35236,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35977,6 +36038,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -36023,6 +36087,9 @@ msgstr "Trả vỠsin của tham số."
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -36066,6 +36133,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -36085,6 +36155,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -36221,11 +36294,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -36341,6 +36450,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "Trả vỠsin của tham số."
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "Trả vỠsin của tham số."
@@ -36554,20 +36680,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36663,6 +36809,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36784,6 +36938,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
#, fuzzy
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr "Nếu [code]true[/code] thì lật ngang há»a tiết."
@@ -36955,7 +37119,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38839,13 +39011,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38857,7 +39035,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38867,15 +39048,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40587,6 +40774,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45706,6 +45897,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -46118,7 +46316,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49698,20 +49907,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49719,19 +49936,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49763,14 +49989,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -50224,8 +50458,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54466,24 +54700,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54492,8 +54725,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54501,16 +54735,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54522,7 +54756,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54552,21 +54786,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54602,11 +54839,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54647,13 +54884,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54717,10 +54954,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54774,8 +55011,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54806,16 +55043,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54823,7 +55059,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -56134,11 +56370,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58607,7 +58862,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58797,11 +59076,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -59204,9 +59483,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60752,6 +61033,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "Nếu [code]true[/code], há»a tiết sẽ được căn ở trung tâm."
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63685,7 +63971,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -66142,11 +66439,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -66226,8 +66523,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66837,9 +67134,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66869,7 +67167,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/doc/translations/zh_CN.po b/doc/translations/zh_CN.po
index aed2ffbe21..d2179a01f2 100644
--- a/doc/translations/zh_CN.po
+++ b/doc/translations/zh_CN.po
@@ -62,7 +62,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-06-19 11:54+0000\n"
+"PO-Revision-Date: 2022-07-17 07:14+0000\n"
"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot-class-reference/zh_Hans/>\n"
@@ -71,7 +71,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Weblate 4.13.1-dev\n"
+"X-Generator: Weblate 4.14-dev\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -507,7 +507,7 @@ msgid ""
"a = dectime(60, 10, 0.1)) # a is 59.0\n"
"[/codeblock]"
msgstr ""
-"[b]注æ„:[/b][code]dectime[/code] 已被废弃,将在 Godot 4.0 中删除,请使用 "
+"[b]注æ„:[/b][code]dectime[/code] 已被废弃,将在 Godot 4.0 中移除,请使用 "
"[method move_toward] 代替。\n"
"返回 [code]value[/code] å‡åŽ» [code]step[/code] * [code]amount[/code] 的结"
"果。\n"
@@ -516,7 +516,6 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Compares two values by checking their actual contents, recursing into any "
"[Array] or [Dictionary] up to its deepest level.\n"
@@ -536,7 +535,7 @@ msgid ""
"want a true content-aware comparison, you have to use [code]deep_equal[/"
"code]."
msgstr ""
-"æ ¹æ®å®žé™…的内容对两个值进行比较,对于 `Array` 或 `Dictionary` 会递归至最深一"
+"æ ¹æ®å®žé™…的内容对两个值进行比较,对于 [Array] 或 [Dictionary] 会递归至最深一"
"层。\n"
"与 [code]==[/code] çš„å¼‚åŒæœ‰ï¼š\n"
"- 对于 [code]null[/code]ã€[code]int[/code]ã€[code]float[/code]ã€"
@@ -585,14 +584,14 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
msgstr ""
-"返回 [code]x[/code] “缓动åŽâ€çš„值,结果基于使用 [code]curve[/code] 值定义的缓"
-"动函数。该缓动函数是基于指数的。[code]curve[/code] 值å¯ä»¥æ˜¯ä»»æ„浮点数,具体数"
-"值会导致以下行为:\n"
+"返回 [code]x[/code]“缓动åŽâ€çš„值,结果基于使用 [code]curve[/code] 值定义的缓动"
+"函数。该缓动函数是基于指数的。[code]curve[/code] 值å¯ä»¥æ˜¯ä»»æ„浮点数,具体数值"
+"会导致以下行为:\n"
"[codeblock]\n"
"- 低于 -1.0(开区间):缓入缓出\n"
"- -1.0:线性\n"
@@ -602,9 +601,9 @@ msgstr ""
"- 1.0:线性\n"
"- 大于 1.0(开区间):缓入\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() 曲线值速查表[/url]\n"
-"请å‚阅 [method smoothstep]ã€‚å¦‚æžœä½ éœ€è¦æ‰§è¡Œæ›´é«˜çº§çš„过渡,请使用 [Tween] 或 "
+"å¦è¯·å‚阅 [method smoothstep]ã€‚å¦‚æžœä½ éœ€è¦æ‰§è¡Œæ›´é«˜çº§çš„过渡,请使用 [Tween] 或 "
"[AnimationPlayer]。"
#: modules/gdscript/doc_classes/@GDScript.xml
@@ -659,7 +658,7 @@ msgid ""
"[/codeblock]\n"
"For the integer remainder operation, use the % operator."
msgstr ""
-"返回 [code]a/b[/code] 的浮点型余数, 符å·ä¸Ž [code]a[/code]一致。\n"
+"返回 [code]a/b[/code] 的浮点型余数,符å·ä¸Ž [code]a[/code]一致。\n"
"[codeblock]\n"
"r = fmod(7, 5.5) # r = 1.5\n"
"[/codeblock]\n"
@@ -875,7 +874,7 @@ msgstr ""
"如果 [code]a[/code] 和 [code]b[/code] 彼此近似相等,则返回 [code]true[/"
"code]。\n"
"这里,近似相等æ„å‘³ç€ [code]a[/code] å’Œ [code]b[/code] 相互之间在一个å°çš„内部 "
-"ε 里,这个内部 ε éšç€æ•°å­—的大å°è€Œå˜åŒ–。 \n"
+"ε 里,这个内部 ε éšç€æ•°å­—的大å°è€Œå˜åŒ–。\n"
"相åŒç¬¦å·çš„æ— ç©·å¤§å€¼è¢«è®¤ä¸ºæ˜¯ç›¸ç­‰çš„。"
#: modules/gdscript/doc_classes/@GDScript.xml
@@ -1203,7 +1202,7 @@ msgid ""
msgstr ""
"å°† JSON 文本解æžä¸º Variant。(使用 [method typeof] 检查 Variant 的类型是å¦ç¬¦"
"åˆæ‚¨çš„æœŸæœ›ã€‚)\n"
-"[b]注æ„:[/b]JSON 规范未定义整数或浮点类型,仅定义了 [i]number[/i] 类型。 å› "
+"[b]注æ„:[/b]JSON 规范未定义整数或浮点类型,仅定义了 [i]number[/i] 类型。因"
"æ­¤ï¼Œè§£æž JSON 文本会将所有数值转æ¢ä¸º [float] 类型。\n"
"[b]注æ„:[/b]JSON 对象ä¸ä¼šåƒ Godot 字典那样ä¿ç•™é”®é¡ºåºï¼Œå› æ­¤ï¼Œå¦‚果字典是由 "
"JSON 构造的,则ä¸åº”ä¾èµ–于特定顺åºçš„键。相å,JSON 数组ä¿ç•™å…¶å…ƒç´ çš„顺åºï¼š\n"
@@ -1462,7 +1461,7 @@ msgstr ""
"[codeblock]\n"
"prints(rand_range(0, 1), rand_range(0, 1)) # 输出举例 0.135591 0.405263\n"
"[/codeblock]\n"
-"[b]注æ„:[/b]与 [code]randf() * (to - from) + from[/code] 等价。"
+"[b]注æ„:[/b]相当于 [code]randf() * (to - from) + from[/code]。"
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -1708,7 +1707,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -1725,12 +1724,12 @@ msgstr ""
"smoothstep(0, 2, -5.0) # 返回 0.0\n"
"smoothstep(0, 2, 0.5) # 返回 0.15625\n"
"smoothstep(0, 2, 1.0) # 返回 0.5\n"
-"smoothstep(0, 2, 2.0) # 返回1.0\n"
+"smoothstep(0, 2, 2.0) # 返回 1.0\n"
"[/codeblock]\n"
"与曲线值为 [code]-1.6521[/code] 的 [method ease] 相比,[method smoothstep] 返"
"回最平滑的曲线,导数没有çªç„¶å˜åŒ–ã€‚å¦‚æžœä½ éœ€è¦æ‰§è¡Œæ›´é«˜çº§çš„过渡,请使用 [Tween] "
"或 [AnimationPlayer]。\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]smoothstep() 与 ease(x, -1.6521) 返回值的比较"
"[/url]"
@@ -2029,7 +2028,7 @@ msgstr ""
"# æ— é™æ—‹è½¬ï¼ˆå¼§åº¦ï¼‰\n"
"angle = wrapf(angle + 0.1, -PI, PI)\n"
"[/codeblock]\n"
-"[b]注æ„:[/b]如果 [code]min[/code] 为 [code]0[/code],则等价于 [method "
+"[b]注æ„:[/b]如果 [code]min[/code] 为 [code]0[/code],则相当于 [method "
"fposmod],因此请改用它。\n"
"通过让用户控制最å°å€¼ï¼Œ[code]wrapf[/code] 比使用 [method fposmod] æ–¹æ³•æ›´çµæ´»ã€‚"
@@ -2061,7 +2060,7 @@ msgstr ""
"# result 是 -2\n"
"var result = wrapi(-6, -5, -1)\n"
"[/codeblock]\n"
-"[b]注æ„:[/b]如果 [code]min[/code] 为 [code]0[/code],则等价于 [method "
+"[b]注æ„:[/b]如果 [code]min[/code] 为 [code]0[/code],则相当于 [method "
"posmod],因此建议改用它。\n"
"通过让用户控制最å°å€¼ï¼Œ[code]wrapi[/code] 比使用 [method posmod] æ–¹æ³•æ›´çµæ´»ã€‚"
@@ -2150,14 +2149,14 @@ msgstr ""
msgid ""
"Constant that represents how many times the diameter of a circle fits around "
"its perimeter. This is equivalent to [code]TAU / 2[/code]."
-msgstr "常é‡ï¼Œè¡¨ç¤ºåœ†çš„周长是直径的多少å€ã€‚等价于 [code]TAU / 2[/code]。"
+msgstr "常é‡ï¼Œè¡¨ç¤ºåœ†çš„周长是直径的多少å€ã€‚相当于 [code]TAU / 2[/code]。"
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
"The circle constant, the circumference of the unit circle in radians. This "
"is equivalent to [code]PI * 2[/code], or 360 degrees in rotations."
msgstr ""
-"圆常é‡ï¼Œå•ä½åœ†çš„周长,å•ä½ä¸ºå¼§åº¦ã€‚等价于 [code]PI * 2[/code]ï¼Œå³ 360 度的旋转"
+"圆常é‡ï¼Œå•ä½åœ†çš„周长,å•ä½ä¸ºå¼§åº¦ã€‚相当于 [code]PI * 2[/code]ï¼Œå³ 360 度的旋转"
"值。"
#: modules/gdscript/doc_classes/@GDScript.xml
@@ -2638,11 +2637,11 @@ msgstr "å°é”®ç›˜çš„æ•°å­— 9。"
#: doc/classes/@GlobalScope.xml
msgid "Left Super key (Windows key)."
-msgstr "左 Super 键( Windows 键 )。"
+msgstr "左 Super 键(Windows 键)。"
#: doc/classes/@GlobalScope.xml
msgid "Right Super key (Windows key)."
-msgstr "å³ Super 键( Windows é”® )。"
+msgstr "å³ Super 键(Windows 键)。"
#: doc/classes/@GlobalScope.xml
msgid "Context menu key."
@@ -2763,31 +2762,31 @@ msgstr "å¯åŠ¨å¤šåª’ä½“é”®ã€‚"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut 0 key."
-msgstr "å¿«æ·å¯åЍ键0。"
+msgstr "å¿«æ·å¯åЍ键 0。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut 1 key."
-msgstr "å¿«æ·å¯åЍ键1。"
+msgstr "å¿«æ·å¯åЍ键 1。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut 2 key."
-msgstr "å¿«æ·å¯åЍ键2。"
+msgstr "å¿«æ·å¯åЍ键 2。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut 3 key."
-msgstr "å¿«æ·å¯åЍ键3。"
+msgstr "å¿«æ·å¯åЍ键 3。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut 4 key."
-msgstr "å¿«æ·å¯åЍ键4。"
+msgstr "å¿«æ·å¯åЍ键 4。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut 5 key."
-msgstr "å¿«æ·å¯åЍ键5。"
+msgstr "å¿«æ·å¯åЍ键 5。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut 6 key."
-msgstr "å¿«æ·å¯åЍ键6。"
+msgstr "å¿«æ·å¯åЍ键 6。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut 7 key."
@@ -2799,35 +2798,35 @@ msgstr "å¿«æ·å¯åЍ键 8。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut 9 key."
-msgstr "å¿«æ·å¯åЍ键9。"
+msgstr "å¿«æ·å¯åЍ键 9。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut A key."
-msgstr "å¿«æ·å¯åЍ键 A 。"
+msgstr "å¿«æ·å¯åЍ键 A。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut B key."
-msgstr "å¿«æ·å¯åЍ键 B 。"
+msgstr "å¿«æ·å¯åЍ键 B。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut C key."
-msgstr "å¿«æ·å¯åЍ键 C 。"
+msgstr "å¿«æ·å¯åЍ键 C。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut D key."
-msgstr "å¿«æ·å¯åЍ键 D 。"
+msgstr "å¿«æ·å¯åЍ键 D。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut E key."
-msgstr "å¿«æ·å¯åЍ键 E 。"
+msgstr "å¿«æ·å¯åЍ键 E。"
#: doc/classes/@GlobalScope.xml
msgid "Launch Shortcut F key."
-msgstr "å¿«æ·å¯åЍ键 F 。"
+msgstr "å¿«æ·å¯åЍ键 F。"
#: doc/classes/@GlobalScope.xml
msgid "Unknown key."
-msgstr "未知 键。"
+msgstr "未知键。"
#: doc/classes/@GlobalScope.xml
msgid "Space key."
@@ -3400,8 +3399,8 @@ msgid ""
"mask should be preferred to [constant KEY_MASK_META] or [constant "
"KEY_MASK_CTRL] for system shortcuts as it handles all platforms correctly."
msgstr ""
-"Command 键掩ç ã€‚在 macOS,这等åŒäºŽ [constant KEY_MASK_META]。而在其他平å°ï¼Œè¿™"
-"ç­‰åŒäºŽ [constant KEY_MASK_CTRL]。相对使用 [constant KEY_MASK_META] 或 "
+"Command 键掩ç ã€‚在 macOS 上相当于 [constant KEY_MASK_META]。而在其他平å°åˆ™ç›¸"
+"当于 [constant KEY_MASK_CTRL]。相对使用 [constant KEY_MASK_META] 或 "
"[constant KEY_MASK_CTRL] æ¥ä½œä¸ºç³»ç»Ÿå¿«æ·é”®ï¼Œåº”优先使用此掩ç ï¼Œä»¥ä¾¿èƒ½è®©æ‰€æœ‰å¹³å°"
"正确处ç†ã€‚"
@@ -3427,11 +3426,11 @@ msgstr "鼠标中键。"
#: doc/classes/@GlobalScope.xml
msgid "Extra mouse button 1 (only present on some mice)."
-msgstr "é¼ æ ‡é¢å¤–é”®1(仅在æŸäº›é¼ æ ‡ä¸Šæœ‰å®žçŽ°ï¼‰ã€‚"
+msgstr "é¼ æ ‡é¢å¤–é”® 1(仅在æŸäº›é¼ æ ‡ä¸Šæœ‰å®žçŽ°ï¼‰ã€‚"
#: doc/classes/@GlobalScope.xml
msgid "Extra mouse button 2 (only present on some mice)."
-msgstr "é¼ æ ‡é¢å¤–é”®2(仅在æŸäº›é¼ æ ‡ä¸Šæœ‰å®žçŽ°ï¼‰ã€‚"
+msgstr "é¼ æ ‡é¢å¤–é”® 2(仅在æŸäº›é¼ æ ‡ä¸Šæœ‰å®žçŽ°ï¼‰ã€‚"
#: doc/classes/@GlobalScope.xml
msgid "Mouse wheel up."
@@ -3463,11 +3462,11 @@ msgstr "鼠标中键掩ç ã€‚"
#: doc/classes/@GlobalScope.xml
msgid "Extra mouse button 1 mask."
-msgstr "é¼ æ ‡é¢å¤–é”®1掩ç ã€‚"
+msgstr "é¼ æ ‡é¢å¤–é”® 1 掩ç ã€‚"
#: doc/classes/@GlobalScope.xml
msgid "Extra mouse button 2 mask."
-msgstr "é¼ æ ‡é¢å¤–é”®2掩ç ã€‚"
+msgstr "é¼ æ ‡é¢å¤–é”® 2 掩ç ã€‚"
#: doc/classes/@GlobalScope.xml
msgid "Invalid button or axis."
@@ -3475,27 +3474,27 @@ msgstr "无效按钮或轴。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 0."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮0。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 0。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 1."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮1。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 1。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 2."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮2。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 2。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 3."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮3。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 3。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 4."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮4。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 4。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 5."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮5。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 5。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 6."
@@ -3515,55 +3514,55 @@ msgstr "æ¸¸æˆæ‰‹æŸ„按钮 9。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 10."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮10。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 10。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 11."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮11。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 11。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 12."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮12。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 12。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 13."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮13。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 13。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 14."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮14。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 14。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 15."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮15。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 15。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 16."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮16。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 16。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 17."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮17。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 17。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 18."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮18。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 18。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 19."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮19。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 19。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 20."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮20。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 20。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 21."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮21。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 21。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button 22."
-msgstr "æ¸¸æˆæ‰‹æŸ„按钮22。"
+msgstr "æ¸¸æˆæ‰‹æŸ„按钮 22。"
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -3628,35 +3627,37 @@ msgstr "任天堂控制器 Y 键。"
#: doc/classes/@GlobalScope.xml
msgid "Grip (side) buttons on a VR controller."
-msgstr "VRæŽ§åˆ¶å™¨ä¸Šçš„æ¡æŠŠï¼ˆä¾§é¢ï¼‰æŒ‰é’®ã€‚"
+msgstr "VR æŽ§åˆ¶å™¨ä¸Šçš„æ¡æŠŠï¼ˆä¾§é¢ï¼‰æŒ‰é’®ã€‚"
#: doc/classes/@GlobalScope.xml
msgid "Push down on the touchpad or main joystick on a VR controller."
-msgstr "VR控制器上的触摸æ¿/主摇æ†çš„å‘下键。"
+msgstr "VR 控制器上的触摸æ¿/主摇æ†çš„å‘下键。"
#: doc/classes/@GlobalScope.xml
msgid "Trigger on a VR controller."
-msgstr "VR控制器上的扳机键。"
+msgstr "VR 控制器上的扳机键。"
#: doc/classes/@GlobalScope.xml
msgid ""
"A button on the right Oculus Touch controller, X button on the left "
"controller (also when used in OpenVR)."
-msgstr "å³ä¾§Oculus Touch控制器的A按钮,左控制器的X按钮(需当使用OpenVR时)。"
+msgstr ""
+"Oculus Touch å³æŽ§åˆ¶å™¨çš„ A 按钮,左控制器的 X 按钮(需当使用 OpenVR 时)。"
#: doc/classes/@GlobalScope.xml
msgid ""
"B button on the right Oculus Touch controller, Y button on the left "
"controller (also when used in OpenVR)."
-msgstr "å³ä¾§Oculus Touch控制器的B按钮,左控制器的Y按钮(需当使用OpenVR时)。"
+msgstr ""
+"Oculus Touch å³æŽ§åˆ¶å™¨çš„ B 按钮,左控制器的 Y 按钮(需当使用 OpenVR 时)。"
#: doc/classes/@GlobalScope.xml
msgid "Menu button on either Oculus Touch controller."
-msgstr "ä»»æ„Oculus Touch控制器上的èœå•按钮。"
+msgstr "ä»»æ„ Oculus Touch 控制器上的èœå•按钮。"
#: doc/classes/@GlobalScope.xml
msgid "Menu button in OpenVR (Except when Oculus Touch controllers are used)."
-msgstr "OpenVR中的èœå•按钮(使用 Oculus Touch 控制器时除外)。"
+msgstr "OpenVR 中的èœå•按钮(使用 Oculus Touch 控制器时除外)。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad button Select."
@@ -3752,11 +3753,11 @@ msgstr "æ¸¸æˆæ‰‹æŸ„峿‘‡æ†åž‚直轴。"
#: doc/classes/@GlobalScope.xml
msgid "Generic gamepad axis 4."
-msgstr "é€šç”¨çš„æ¸¸æˆæ‰‹æŸ„è½´4。"
+msgstr "é€šç”¨çš„æ¸¸æˆæ‰‹æŸ„è½´ 4。"
#: doc/classes/@GlobalScope.xml
msgid "Generic gamepad axis 5."
-msgstr "é€šç”¨çš„æ¸¸æˆæ‰‹æŸ„è½´5。"
+msgstr "é€šç”¨çš„æ¸¸æˆæ‰‹æŸ„è½´ 5。"
#: doc/classes/@GlobalScope.xml
msgid "Gamepad left trigger analog axis."
@@ -3768,11 +3769,11 @@ msgstr "æ¸¸æˆæ‰‹æŸ„å³è§¦å‘模拟轴。"
#: doc/classes/@GlobalScope.xml
msgid "Generic gamepad axis 8."
-msgstr "é€šç”¨çš„æ¸¸æˆæ‰‹æŸ„è½´8。"
+msgstr "é€šç”¨çš„æ¸¸æˆæ‰‹æŸ„è½´ 8。"
#: doc/classes/@GlobalScope.xml
msgid "Generic gamepad axis 9."
-msgstr "é€šç”¨çš„æ¸¸æˆæ‰‹æŸ„è½´9。"
+msgstr "é€šç”¨çš„æ¸¸æˆæ‰‹æŸ„è½´ 9。"
#: doc/classes/@GlobalScope.xml
msgid "Represents the maximum number of joystick axes supported."
@@ -3788,23 +3789,23 @@ msgstr "æ¸¸æˆæ‰‹æŸ„å³ä¾§æ¨¡æ‹Ÿè§¦å‘器。"
#: doc/classes/@GlobalScope.xml
msgid "VR Controller analog trigger."
-msgstr "VR控制器模拟触å‘器。"
+msgstr "VR 控制器模拟触å‘器。"
#: doc/classes/@GlobalScope.xml
msgid "VR Controller analog grip (side buttons)."
-msgstr "VRæŽ§åˆ¶å™¨çš„æ¨¡æ‹Ÿæ¡æŠŠï¼ˆä¾§é¢æŒ‰é’®ï¼‰ã€‚"
+msgstr "VR æŽ§åˆ¶å™¨çš„æ¨¡æ‹Ÿæ¡æŠŠï¼ˆä¾§é¢æŒ‰é’®ï¼‰ã€‚"
#: doc/classes/@GlobalScope.xml
msgid ""
"OpenVR touchpad X axis (Joystick axis on Oculus Touch and Windows MR "
"controllers)."
-msgstr "OpenVR触摸æ¿X轴(Oculus Touchå’ŒWindows MR控制器的æ“纵æ†è½´ï¼‰ã€‚"
+msgstr "OpenVR è§¦æ‘¸æ¿ X 轴(Oculus Touch å’Œ Windows MR 控制器的æ“纵æ†è½´ï¼‰ã€‚"
#: doc/classes/@GlobalScope.xml
msgid ""
"OpenVR touchpad Y axis (Joystick axis on Oculus Touch and Windows MR "
"controllers)."
-msgstr "OpenVR触摸æ¿Y轴(Oculus Touchå’ŒWindows MR控制器的æ“纵æ†è½´ï¼‰ã€‚"
+msgstr "OpenVR è§¦æ‘¸æ¿ Y 轴(Oculus Touch å’Œ Windows MR 控制器的æ“纵æ†è½´ï¼‰ã€‚"
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -4164,7 +4165,7 @@ msgstr ""
"通过æç¤ºä¸²[code]\"min,max\"[/code] 或[code]\"min,max,step\"[/code]æ¥æç¤ºä¸€ä¸ª"
"整数或浮点数属性应当è½åœ¨æŒ‡å®šèŒƒå›´å†…。æç¤ºä¸²å¯ä»¥é€‰æ‹©æ€§åœ°åŒ…å« "
"[code]\"or_greater\"[/code] 与/或 [code]\"or_lesser\"[/code] æ¥å…许手动输入的"
-"值超过或低于最大最å°å€¼ã€‚例如: [code]\"-360,360,1,or_greater,or_lesser\"[/"
+"值超过或低于最大最å°å€¼ã€‚例如:[code]\"-360,360,1,or_greater,or_lesser\"[/"
"code]。"
#: doc/classes/@GlobalScope.xml
@@ -4179,7 +4180,7 @@ msgstr ""
"æç¤ºä¸€ä¸ªæ•´æ•°æˆ–浮点数属性应当è½åœ¨é€šè¿‡æç¤ºå­—符串[code]\"min,max\"[/code] 或"
"[code]\"min,max,step\"[/code]æ¥æŒ‡å®šçš„范围内。æç¤ºå­—符串å¯ä»¥é€‰æ‹©æ€§åœ°åŒ…å« "
"[code]\"or_greater\"[/code] 与/或 [code]\"or_lesser\"[/code] æ¥å…许手动输入的"
-"值超过最大值或低于最å°å€¼ã€‚例如: [code]\"0.01,100,0.01,or_greater\"[/code]。"
+"值超过最大值或低于最å°å€¼ã€‚例如:[code]\"0.01,100,0.01,or_greater\"[/code]。"
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -4238,13 +4239,13 @@ msgstr ""
msgid ""
"Hints that an integer property is a bitmask using the optionally named 2D "
"render layers."
-msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å¤‡æˆ–ä¸å…·å¤‡å‘½åçš„2D渲染层。"
+msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å或ä¸å…·åçš„ 2D 渲染层。"
#: doc/classes/@GlobalScope.xml
msgid ""
"Hints that an integer property is a bitmask using the optionally named 2D "
"physics layers."
-msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å¤‡æˆ–ä¸å…·å¤‡å‘½åçš„2D物ç†å±‚。"
+msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å或ä¸å…·åçš„ 2D 物ç†å±‚。"
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -4256,20 +4257,19 @@ msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å或ä¸å…·åçš„
msgid ""
"Hints that an integer property is a bitmask using the optionally named 3D "
"render layers."
-msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å¤‡æˆ–ä¸å…·å¤‡å‘½åçš„3D渲染层。"
+msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å或ä¸å…·åçš„ 3D 渲染层。"
#: doc/classes/@GlobalScope.xml
msgid ""
"Hints that an integer property is a bitmask using the optionally named 3D "
"physics layers."
-msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å¤‡æˆ–ä¸å…·å¤‡å‘½åçš„3D物ç†å±‚。"
+msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å或ä¸å…·åçš„ 3D 物ç†å±‚。"
#: doc/classes/@GlobalScope.xml
-#, fuzzy
msgid ""
"Hints that an integer property is a bitmask using the optionally named 3D "
"navigation layers."
-msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å或ä¸å…·åçš„ 2D 导航层。"
+msgstr "æç¤ºä¸€ä¸ªæ•´æ•°å±žæ€§æ˜¯ä¸€ä¸ªæŽ©ç ï¼Œä½¿ç”¨ç€å…·å或ä¸å…·åçš„ 3D 导航层。"
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -4874,7 +4874,7 @@ msgstr ""
"custom_action]ä¿¡å·ã€‚\n"
"如果[code]right[/code]为 [code]true[/code],按钮会被放置在所有åŒçº§æŒ‰é’®çš„å³"
"边。\n"
-"您å¯ä»¥ä½¿ç”¨ [method remove_button] æ–¹æ³•ä»Žå¯¹è¯æ¡†ä¸­åˆ é™¤ä½¿ç”¨æ­¤æ–¹æ³•创建的按钮。"
+"您å¯ä»¥ä½¿ç”¨ [method remove_button] æ–¹æ³•ä»Žå¯¹è¯æ¡†ä¸­ç§»é™¤ä½¿ç”¨æ­¤æ–¹æ³•创建的按钮。"
#: doc/classes/AcceptDialog.xml
msgid ""
@@ -4885,7 +4885,7 @@ msgid ""
msgstr ""
"å‘å¯¹è¯æ¡†ä¸­æ·»åŠ ä¸€ä¸ªæ ‡ç­¾ä¸º[code]name[/code]å’Œä¸€ä¸ªå–æ¶ˆåŠ¨ä½œçš„æŒ‰é’®ï¼Œç„¶åŽè¿”回这个新"
"创建的按钮。\n"
-"您å¯ä»¥ä½¿ç”¨ [method remove_button] æ–¹æ³•ä»Žå¯¹è¯æ¡†ä¸­åˆ é™¤ä½¿ç”¨æ­¤æ–¹æ³•创建的按钮。"
+"您å¯ä»¥ä½¿ç”¨ [method remove_button] æ–¹æ³•ä»Žå¯¹è¯æ¡†ä¸­ç§»é™¤ä½¿ç”¨æ­¤æ–¹æ³•创建的按钮。"
#: doc/classes/AcceptDialog.xml
msgid ""
@@ -4895,7 +4895,7 @@ msgid ""
"[member CanvasItem.visible] property."
msgstr ""
"返回内置文本所使用的标签。\n"
-"[b]警告:[/b]这是个必è¦çš„内部节点,删除和释放它有å¯èƒ½é€ æˆå´©æºƒã€‚如果你希望éšè—"
+"[b]警告:[/b]这是个必è¦çš„内部节点,移除并释放它有å¯èƒ½é€ æˆå´©æºƒã€‚如果你希望éšè—"
"它或它的任æ„一个å­èŠ‚ç‚¹ï¼Œè¯·ä½¿ç”¨å®ƒä»¬çš„ [member CanvasItem.visible] 属性。"
#: doc/classes/AcceptDialog.xml
@@ -4906,14 +4906,14 @@ msgid ""
"[member CanvasItem.visible] property."
msgstr ""
"返回确定按钮 [Button] 实例。\n"
-"[b]警告:[/b]这是个必è¦çš„内部节点,删除和释放它有å¯èƒ½é€ æˆå´©æºƒã€‚如果你希望éšè—"
+"[b]警告:[/b]这是个必è¦çš„内部节点,移除并释放它有å¯èƒ½é€ æˆå´©æºƒã€‚如果你希望éšè—"
"它或它的任æ„一个å­èŠ‚ç‚¹ï¼Œè¯·ä½¿ç”¨å®ƒä»¬çš„ [member CanvasItem.visible] 属性。"
#: doc/classes/AcceptDialog.xml
msgid ""
"Registers a [LineEdit] in the dialog. When the enter key is pressed, the "
"dialog will be accepted."
-msgstr "åœ¨å¯¹è¯æ¡†ä¸­æ³¨å†Œ [LineEdit]。 å½“æŒ‰ä¸‹å›žè½¦é”®æ—¶ï¼Œå¯¹è¯æ¡†å°†è¢«æŽ¥å—。"
+msgstr "åœ¨å¯¹è¯æ¡†ä¸­æ³¨å†Œ [LineEdit]ã€‚å½“æŒ‰ä¸‹å›žè½¦é”®æ—¶ï¼Œå¯¹è¯æ¡†å°†è¢«æŽ¥å—。"
#: doc/classes/AcceptDialog.xml
msgid ""
@@ -4945,13 +4945,13 @@ msgid ""
"dialog if the input is valid. As such, this property can't be used in "
"[FileDialog] to disable hiding the dialog when pressing OK."
msgstr ""
-"如果为 [code]true[/code],按下OKæŒ‰é’®æ—¶å¯¹è¯æ¡†å°†éšè—。如果è¦åœ¨æ”¶åˆ° [signal "
+"如果为 [code]true[/code]ï¼ŒæŒ‰ä¸‹ç¡®å®šæŒ‰é’®æ—¶å¯¹è¯æ¡†å°†éšè—。如果è¦åœ¨æ”¶åˆ° [signal "
"confirmed] ä¿¡å·æ—¶æ‰§è¡Œç±»ä¼¼è¾“入验è¯çš„æ“ä½œï¼Œåˆ™å¯ä»¥å°†å…¶è®¾ç½®ä¸º [code]false[/"
"code],然åŽåœ¨è‡ªå·±çš„逻辑中处ç†å¯¹è¯æ¡†çš„éšè—。\n"
"[b]注æ„:[/b]从此类派生的æŸäº›èŠ‚ç‚¹å¯ä»¥å…·æœ‰ä¸åŒçš„默认值,并且å¯èƒ½æœ‰è‡ªå·±çš„内置逻"
-"辑会覆盖此设置。 例如,[FileDialog] 默认其为 [code]false[/code],并在按下OK时"
-"实现了自己的输入验è¯ä»£ç ï¼Œå¦‚果输入有效,最终将éšè—å¯¹è¯æ¡†ã€‚因此,ä¸èƒ½åœ¨ "
-"[FileDialog] 中使用此属性æ¥ç¦æ­¢åœ¨æŒ‰OKæ—¶éšè—å¯¹è¯æ¡†ã€‚"
+"辑会覆盖此设置。例如,[FileDialog] 默认其为 [code]false[/code],并在按下确定"
+"时实现了自己的输入验è¯ä»£ç ï¼Œå¦‚果输入有效,最终将éšè—å¯¹è¯æ¡†ã€‚因此,ä¸èƒ½åœ¨ "
+"[FileDialog] 中使用此属性æ¥ç¦æ­¢åœ¨æŒ‰ç¡®å®šæ—¶éšè—å¯¹è¯æ¡†ã€‚"
#: doc/classes/AcceptDialog.xml
msgid "The text displayed by the dialog."
@@ -4959,15 +4959,15 @@ msgstr "å¯¹è¯æ¡†æ˜¾ç¤ºçš„æ–‡æœ¬ã€‚"
#: doc/classes/AcceptDialog.xml
msgid "Emitted when the dialog is accepted, i.e. the OK button is pressed."
-msgstr "接å—å¯¹è¯æ¡†æ—¶ï¼Œå³æŒ‰ä¸‹OK按钮时å‘出。"
+msgstr "接å—å¯¹è¯æ¡†æ—¶ï¼Œå³æŒ‰ä¸‹ç¡®å®šæŒ‰é’®æ—¶å‘出。"
#: doc/classes/AcceptDialog.xml
msgid "Emitted when a custom button is pressed. See [method add_button]."
-msgstr "按下自定义按钮时å‘出。 å‚阅[method add_button]。"
+msgstr "按下自定义按钮时å‘å‡ºã€‚è§ [method add_button]。"
#: doc/classes/AESContext.xml
msgid "Interface to low level AES encryption features."
-msgstr "低级AES加密功能接å£ã€‚"
+msgstr "底层 AES 加密功能接å£ã€‚"
#: doc/classes/AESContext.xml
msgid ""
@@ -5014,9 +5014,9 @@ msgstr ""
"var aes = AESContext.new()\n"
"\n"
"func _ready():\n"
-" var key = \"My secret key!!!\" # Key must be either 16 or 32 bytes.\n"
-" var data = \"My secret text!!\" # Data size must be multiple of 16 "
-"bytes, apply padding if needed.\n"
+" var key = \"My secret key!!!\" # 密钥必须是 16 或 32 字节。\n"
+" var data = \"My secret text!!\" # æ•°æ®å¤§å°å¿…须是 16 å­—èŠ‚çš„å€æ•°ï¼Œéœ€è¦æ—¶æ·»"
+"加补白。\n"
" # ECB 加密\n"
" aes.start(AESContext.MODE_ECB_ENCRYPT, key.to_utf8())\n"
" var encrypted = aes.update(data.to_utf8())\n"
@@ -5028,7 +5028,7 @@ msgstr ""
" # ECB 校验\n"
" assert(decrypted == data.to_utf8())\n"
"\n"
-" var iv = \"My secret iv!!!!\" # IV must be of exactly 16 bytes.\n"
+" var iv = \"My secret iv!!!!\" # IV 必须是 16 字节。\n"
" # CBC 加密\n"
" aes.start(AESContext.MODE_CBC_ENCRYPT, key.to_utf8(), iv.to_utf8())\n"
" encrypted = aes.update(data.to_utf8())\n"
@@ -5043,7 +5043,7 @@ msgstr ""
#: doc/classes/AESContext.xml
msgid "Close this AES context so it can be started again. See [method start]."
-msgstr "关闭此AES上下文,以便å¯ä»¥å†æ¬¡å¯åŠ¨å®ƒã€‚ å‚阅[method start]。"
+msgstr "关闭此 AES 上下文,以便å¯ä»¥å†æ¬¡å¯åŠ¨å®ƒã€‚è§ [method start]。"
#: doc/classes/AESContext.xml
msgid ""
@@ -5064,9 +5064,9 @@ msgid ""
"(initialization vector) of exactly 16 bytes, is only needed when [code]mode[/"
"code] is either [constant MODE_CBC_ENCRYPT] or [constant MODE_CBC_DECRYPT]."
msgstr ""
-"以给定的[code]模å¼[/code]å¯åЍAES上下文。必须始终æä¾›16或32字节的[code]key[/"
-"code],而仅当[code]mode[/code]ä¸ºä»¥ä¸‹ä¸¤ç§æƒ…况时æ‰éœ€è¦æ­£å¥½ä¸º16字节的[code]iv[/"
-"code](åˆå§‹åŒ–å‘é‡ï¼‰ [constant MODE_CBC_ENCRYPT]或[constant "
+"以给定的 [code]mode[/code] å¯åЍ AES 上下文。必须始终æä¾› 16 或 32 字节的 "
+"[code]key[/code],而仅当 [code]mode[/code] ä¸ºä»¥ä¸‹ä¸¤ç§æƒ…况时æ‰éœ€è¦æ­£å¥½ä¸º 16 å­—"
+"节的 [code]iv[/code](åˆå§‹åŒ–å‘é‡ï¼‰[constant MODE_CBC_ENCRYPT] 或 [constant "
"MODE_CBC_DECRYPT]。"
#: doc/classes/AESContext.xml
@@ -5078,24 +5078,25 @@ msgid ""
"some padding if needed."
msgstr ""
"è¿è¡Œæ­¤ AES 上下文所需的æ“作。将返回包å«åŠ å¯†ï¼ˆæˆ–è§£å¯†ï¼‰ç»™å®š [code]src[/code] 结"
-"果的[PoolByteArray] 。有关æ“作模å¼ï¼Œè¯·å‚阅[method start]。\n"
-"[b]注æ„:[/b][code]src[/code]的大å°å¿…须是16å€çš„倿•°ã€‚如果需è¦ï¼Œåº”用一些填充。"
+"果的 [PoolByteArray] 。有关æ“作模å¼ï¼Œè¯·å‚阅 [method start]。\n"
+"[b]注æ„:[/b][code]src[/code] 的大å°å¿…须是 16 å€çš„倿•°ã€‚如果需è¦ï¼Œåº”用一些填"
+"充。"
#: doc/classes/AESContext.xml
msgid "AES electronic codebook encryption mode."
-msgstr "AES电å­å¯†ç ç°¿åŠ å¯†æ¨¡å¼ã€‚"
+msgstr "AES 电å­å¯†ç ç°¿åŠ å¯†æ¨¡å¼ã€‚"
#: doc/classes/AESContext.xml
msgid "AES electronic codebook decryption mode."
-msgstr "AES电å­å¯†ç ç°¿è§£å¯†æ¨¡å¼ã€‚"
+msgstr "AES 电å­å¯†ç ç°¿è§£å¯†æ¨¡å¼ã€‚"
#: doc/classes/AESContext.xml
msgid "AES cipher blocker chaining encryption mode."
-msgstr "AES密ç å°é”器链å¼åŠ å¯†æ¨¡å¼ã€‚"
+msgstr "AES 密ç å°é”器链å¼åŠ å¯†æ¨¡å¼ã€‚"
#: doc/classes/AESContext.xml
msgid "AES cipher blocker chaining decryption mode."
-msgstr "AES密ç å°é”器链å¼è§£å¯†æ¨¡å¼ã€‚"
+msgstr "AES 密ç å°é”器链å¼è§£å¯†æ¨¡å¼ã€‚"
#: doc/classes/AESContext.xml
msgid "Maximum value for the mode enum."
@@ -5151,8 +5152,8 @@ msgid ""
"[code]true[/code], the animation will be played in reverse."
msgstr ""
"播放由 [code]anim[/code] 指定的播放。如果没有指定 [code]anim[/code] 傿•°ï¼Œåˆ™"
-"播放当å‰åŠ¨ç”»ã€‚ 如果 [code]backwards[/code] 为 [code]true[/code] ï¼Œåˆ™å€’åºæ’­æ”¾"
-"动画。"
+"播放当å‰åŠ¨ç”»ã€‚å¦‚æžœ [code]backwards[/code] 为 [code]true[/code] ï¼Œåˆ™å€’åºæ’­æ”¾åЍ"
+"画。"
#: doc/classes/AnimatedSprite.xml doc/classes/AnimatedSprite3D.xml
msgid "Stops the current animation (does not reset the frame counter)."
@@ -5168,19 +5169,19 @@ msgstr ""
#: doc/classes/AnimatedSprite.xml doc/classes/SpriteBase3D.xml
msgid "If [code]true[/code], texture will be centered."
-msgstr "为 [code]true[/code] 时纹ç†å°†è¢«å±…中。"
+msgstr "如果为 [code]true[/code],纹ç†å°†è¢«å±…中。"
#: doc/classes/AnimatedSprite.xml doc/classes/Sprite.xml
#: doc/classes/SpriteBase3D.xml doc/classes/TextureButton.xml
#: doc/classes/TextureRect.xml
msgid "If [code]true[/code], texture is flipped horizontally."
-msgstr "为 [code]true[/code] 时纹ç†å°†è¢«æ°´å¹³ç¿»è½¬ã€‚"
+msgstr "如果为 [code]true[/code],纹ç†å°†è¢«æ°´å¹³ç¿»è½¬ã€‚"
#: doc/classes/AnimatedSprite.xml doc/classes/Sprite.xml
#: doc/classes/SpriteBase3D.xml doc/classes/TextureButton.xml
#: doc/classes/TextureRect.xml
msgid "If [code]true[/code], texture is flipped vertically."
-msgstr "为 [code]true[/code] 时纹ç†å°†è¢«åž‚直翻转。"
+msgstr "如果为 [code]true[/code],纹ç†å°†è¢«åž‚直翻转。"
#: doc/classes/AnimatedSprite.xml doc/classes/AnimatedSprite3D.xml
msgid "The displayed animation frame's index."
@@ -5202,7 +5203,7 @@ msgstr "纹ç†çš„绘图åç§»é‡ã€‚"
#: doc/classes/AnimatedSprite.xml doc/classes/AnimatedSprite3D.xml
msgid "If [code]true[/code], the [member animation] is currently playing."
-msgstr "如果 [code]true[/code]ï¼Œåˆ™è¡¨ç¤ºå½“å‰æ­£åœ¨æ’­æ”¾ [member animation]。"
+msgstr "如果为 [code]true[/code]ï¼Œåˆ™è¡¨ç¤ºå½“å‰æ­£åœ¨æ’­æ”¾ [member animation]。"
#: doc/classes/AnimatedSprite.xml
msgid "The animation speed is multiplied by this value."
@@ -5219,7 +5220,7 @@ msgstr ""
#: doc/classes/AnimatedSprite.xml doc/classes/AnimatedSprite3D.xml
msgid "Emitted when [member frame] changed."
-msgstr "当[member frame]更改时å‘出。"
+msgstr "当 [member frame] 更改时å‘出。"
#: doc/classes/AnimatedSprite3D.xml
msgid ""
@@ -5281,17 +5282,17 @@ msgid ""
"[b]Note:[/b] AnimatedTexture doesn't support using [AtlasTexture]s. Each "
"frame needs to be a separate [Texture]."
msgstr ""
-"[AnimatedTexture]是一ç§èµ„æºæ ¼å¼ï¼Œç”¨äºŽåŸºäºŽå¸§çš„动画,其中多个纹ç†è‡ªåŠ¨é“¾æŽ¥èµ·æ¥ï¼Œ"
-"æ¯å¸§æœ‰é¢„定义延迟。与[AnimationPlayer]或[AnimatedSprite]ä¸åŒï¼Œå®ƒä¸æ˜¯ä¸€ä¸ª"
-"[Node],其优点是å¯åœ¨ä»»ä½•å¯ä»¥ä½¿ç”¨[Texture]资æºçš„地方使用,例如在[TileSet]"
-"中。\n"
-"动画的播放由[member fps]å±žæ€§ä»¥åŠæ¯ä¸€å¸§çš„å¯é€‰å»¶è¿ŸæŽ§åˆ¶ï¼Œå‚阅[method "
-"set_frame_delay]。动画是循环播放的,也就是说,在播放完最åŽä¸€å¸§åŽï¼Œå®ƒå°†è‡ªåŠ¨ä»Ž"
-"第0叧釿–°å¼€å§‹ã€‚\n"
-"[AnimatedTexture]ç›®å‰è¦æ±‚所有帧的纹ç†å…·æœ‰ç›¸åŒçš„尺寸,å¦åˆ™è¾ƒå¤§çš„纹ç†ä¼šè¢«è£å‰ªï¼Œ"
-"与最å°çš„纹ç†ç›¸åŒ¹é…。\n"
-"[b]注æ„:[/b]AnimatedTexture䏿”¯æŒä½¿ç”¨[AtlasTexture]。æ¯ä¸€å¸§éƒ½éœ€è¦æ˜¯ä¸€ä¸ªå•独"
-"的[Texture]。"
+"[AnimatedTexture] 是一ç§èµ„æºæ ¼å¼ï¼Œç”¨äºŽåŸºäºŽå¸§çš„动画,其中多个纹ç†è‡ªåŠ¨é“¾æŽ¥èµ·"
+"æ¥ï¼Œæ¯å¸§æœ‰é¢„定义延迟。与 [AnimationPlayer] 或 [AnimatedSprite] ä¸åŒï¼Œå®ƒä¸æ˜¯ä¸€"
+"个 [Node],其优点是å¯åœ¨ä»»ä½•å¯ä»¥ä½¿ç”¨ [Texture] 资æºçš„地方使用,例如在 "
+"[TileSet] 中。\n"
+"动画的播放由 [member fps] å±žæ€§ä»¥åŠæ¯ä¸€å¸§çš„å¯é€‰å»¶è¿ŸæŽ§åˆ¶ï¼ˆè§ [method "
+"set_frame_delay])。动画是循环播放的,也就是说,在播放完最åŽä¸€å¸§åŽï¼Œå®ƒå°†è‡ªåЍ"
+"从第 0 叧釿–°å¼€å§‹ã€‚\n"
+"[AnimatedTexture] ç›®å‰è¦æ±‚所有帧的纹ç†å…·æœ‰ç›¸åŒçš„尺寸,å¦åˆ™è¾ƒå¤§çš„纹ç†ä¼šè¢«è£"
+"剪,与最å°çš„纹ç†ç›¸åŒ¹é…。\n"
+"[b]注æ„:[/b]AnimatedTexture 䏿”¯æŒä½¿ç”¨ [AtlasTexture]。æ¯ä¸€å¸§éƒ½éœ€è¦æ˜¯ä¸€ä¸ªå•"
+"独的 [Texture]。"
#: doc/classes/AnimatedTexture.xml
msgid "Returns the given frame's delay value."
@@ -5299,7 +5300,7 @@ msgstr "返回给定帧的延迟值。"
#: doc/classes/AnimatedTexture.xml
msgid "Returns the given frame's [Texture]."
-msgstr "返回给定帧的[Texture]。"
+msgstr "返回给定帧的 [Texture]。"
#: doc/classes/AnimatedTexture.xml
msgid ""
@@ -5317,16 +5318,16 @@ msgid ""
"Total duration: 2.7 s\n"
"[/codeblock]"
msgstr ""
-"在此帧和下一帧之间设置é¢å¤–的延迟(以秒为内),该延迟将添加到 [member fps] 定"
-"义的时间间隔中。默认情况下,框架没有延迟定义。如果定义了延迟值,则此帧和下一"
-"帧之间的最终时间间隔将是 [code]1.0 / fps + delay[/code] 。\n"
-"例如,对于具有 3 帧ã€2 个 FPS å’Œ 1.2 第二帧上的帧延迟的动画,由此产生的回放将"
+"设置这一帧和下一帧之间的é¢å¤–延迟(å•ä½ä¸ºç§’),该延迟将添加到 [member fps] 定"
+"义的时间间隔中。默认情况下所有帧都没有定义延迟。如果定义了延迟值,则这一帧和"
+"下一帧之间的最终时间间隔将是 [code]1.0 / fps + delay[/code] 。\n"
+"例如,å‡è®¾æŸä¸ªåŠ¨ç”»ä¸€å…± 3 帧,FPS 为 2,第二帧上的延迟为 1.2,那么播放结果就会"
"是:\n"
"[codeblock]\n"
-"Frame 0: 0.5 s (1 / fps)\n"
-"Frame 1: 1.7 s (1 / fps + 1.2)\n"
-"Frame 2: 0.5 s (1 / fps)\n"
-"Total duration: 2.7 s\n"
+"第 0 帧:0.5 秒(1 / fps)\n"
+"第 1 帧:1.7 秒(1 / fps + 1.2)\n"
+"第 2 帧:0.5 秒(1 / fps)\n"
+"总时长:2.7 秒\n"
"[/codeblock]"
#: doc/classes/AnimatedTexture.xml
@@ -5357,11 +5358,12 @@ msgid ""
"For example, an animation with 8 frames, no frame delay and a [code]fps[/"
"code] value of 2 will run for 4 seconds, with each frame lasting 0.5 seconds."
msgstr ""
-"动画速度,以æ¯ç§’帧数为å•ä½ã€‚此值定义动画两个帧之间的默认时间间隔,并因此基于 "
-"[member frames] 属性定义动画循环的总体æŒç»­æ—¶é—´ã€‚值为 0 表示æ¯ç§’没有预定义的帧"
-"æ•°ï¼ŒåŠ¨ç”»å°†æ ¹æ®æ¯ä¸ªå¸§çš„帧延迟播放(请å‚阅 [method set_frame_delay])。\n"
-"例如,具有 8 帧,无帧延迟且 [code]fps[/code] 值为 2 的动画将è¿è¡Œ 4 秒,æ¯å¸§æŒ"
-"续 0.5 秒。"
+"动画速度,以æ¯ç§’帧数为å•ä½ã€‚这个值定义的是该动画中两个帧之间的默认时间间隔,"
+"å› æ­¤å¯ä»¥æ ¹æ® [member frames] 属性得到动画循环的总体æŒç»­æ—¶é—´ã€‚值为 0 表示没有"
+"定义æ¯ç§’帧数,该动画将根æ®å„ä¸ªå¸§çš„å¸§å»¶è¿Ÿè¿›è¡Œæ’­æ”¾ï¼ˆè§ [method "
+"set_frame_delay])。\n"
+"例如,å‡è®¾æŸä¸ªåŠ¨ç”»ä¸€å…± 8 帧,无帧延迟,则 [code]fps[/code] 值为 2 时动画将è¿"
+"行 4 秒,æ¯å¸§æŒç»­ 0.5 秒。"
#: doc/classes/AnimatedTexture.xml
msgid ""
@@ -5370,8 +5372,8 @@ msgid ""
"for the animation to take new frames into account. The maximum number of "
"frames is [constant MAX_FRAMES]."
msgstr ""
-"动画中è¦ä½¿ç”¨çš„帧数。虽然您å¯ä»¥ä½¿ç”¨[method set_frame_texture]独立创建帧,但是"
-"您需è¦ä¸ºåŠ¨ç”»è®¾ç½®æ­¤å€¼ä»¥è€ƒè™‘æ–°å¸§ã€‚æœ€å¤§å¸§æ•°ä¸º[constant MAX_FRAMES]。"
+"动画中è¦ä½¿ç”¨çš„帧数。虽然您å¯ä»¥ä½¿ç”¨ [method set_frame_texture] 独立创建帧,但"
+"是您需è¦ä¸ºåŠ¨ç”»è®¾ç½®æ­¤å€¼ä»¥è€ƒè™‘æ–°å¸§ã€‚æœ€å¤§å¸§æ•°ä¸º [constant MAX_FRAMES]。"
#: doc/classes/AnimatedTexture.xml
msgid ""
@@ -5379,8 +5381,8 @@ msgid ""
"back to the first frame after reaching the end. Note that reaching the end "
"will not set [member pause] to [code]true[/code]."
msgstr ""
-"如果 [code]true[/code]ï¼Œåˆ™åŠ¨ç”»å°†åªæ’­æ”¾ä¸€æ¬¡ï¼Œå¹¶ä¸”在到达结尾åŽå°†ä¸ä¼šå¾ªçŽ¯å›žåˆ°ç¬¬"
-"一帧。请注æ„,到达终点ä¸ä¼šå°† [member pause] 设置为 [code]true[/code]。"
+"如果为 [code]true[/code]ï¼Œåˆ™åŠ¨ç”»å°†åªæ’­æ”¾ä¸€æ¬¡ï¼Œå¹¶ä¸”在到达结尾åŽå°†ä¸ä¼šå¾ªçŽ¯å›žåˆ°"
+"第一帧。请注æ„,到达终点ä¸ä¼šå°† [member pause] 设置为 [code]true[/code]。"
#: doc/classes/AnimatedTexture.xml
msgid ""
@@ -5388,16 +5390,17 @@ msgid ""
"at [member current_frame]). The animation will continue from where it was "
"paused when changing this property to [code]false[/code]."
msgstr ""
-"如果[code]true[/code],则动画将暂åœåœ¨å½“å‰ä½ç½®ï¼ˆå³[member current_frame])。将"
-"此属性更改为 [code]false[/code] 时,动画将从暂åœå¤„继续播放。"
+"如果为 [code]true[/code],则动画将暂åœåœ¨å½“å‰ä½ç½®ï¼ˆå³ [member "
+"current_frame])。将此属性更改为 [code]false[/code] 时,动画将从暂åœå¤„ç»§ç»­æ’­"
+"放。"
#: doc/classes/AnimatedTexture.xml
msgid ""
"The maximum number of frames supported by [AnimatedTexture]. If you need "
"more frames in your animation, use [AnimationPlayer] or [AnimatedSprite]."
msgstr ""
-"[AnimatedTexture]支æŒçš„æœ€å¤§å¸§æ•°ã€‚å¦‚æžœåŠ¨ç”»ä¸­éœ€è¦æ›´å¤šå¸§ï¼Œè¯·ä½¿ç”¨"
-"[AnimationPlayer]或[AnimatedSprite]。"
+"[AnimatedTexture] 支æŒçš„æœ€å¤§å¸§æ•°ã€‚å¦‚æžœåŠ¨ç”»ä¸­éœ€è¦æ›´å¤šå¸§ï¼Œè¯·ä½¿ç”¨ "
+"[AnimationPlayer] 或 [AnimatedSprite]。"
#: doc/classes/Animation.xml
msgid "Contains data used to animate everything in the engine."
@@ -5536,32 +5539,32 @@ msgid ""
"[code]stream[/code]. The [code]track_idx[/code] must be the index of an "
"Audio Track."
msgstr ""
-"å°† [code]key_idx[/code] 所标识的键æµè®¾ç½®ä¸º[code]stream[/code]值。"
-"[code]track_idx[/code]必须是一个音频轨é“的索引。"
+"å°† [code]key_idx[/code] 所标识的键æµè®¾ç½®ä¸º [code]stream[/code] 值。"
+"[code]track_idx[/code] 必须是音频轨é“的索引。"
#: doc/classes/Animation.xml
msgid ""
"Returns the in handle of the key identified by [code]key_idx[/code]. The "
"[code]track_idx[/code] must be the index of a Bezier Track."
msgstr ""
-"返回由 [code]key_idx[/code] è¯†åˆ«çš„é”®çš„è¾“å…¥å¥æŸ„, [code]track_idx[/code] å¿…é¡»"
-"是è´å¡žå°”轨é“的索引。"
+"返回由 [code]key_idx[/code] è¯†åˆ«çš„é”®çš„è¾“å…¥å¥æŸ„,[code]track_idx[/code] 必须是"
+"è´å¡žå°”轨é“的索引。"
#: doc/classes/Animation.xml
msgid ""
"Returns the out handle of the key identified by [code]key_idx[/code]. The "
"[code]track_idx[/code] must be the index of a Bezier Track."
msgstr ""
-"返回由 [code]key_idx[/code] è¯†åˆ«çš„é”®çš„è¾“å‡ºå¥æŸ„, [code]track_idx[/code] å¿…é¡»"
-"是è´å¡žå°”轨é“的索引。"
+"返回由 [code]key_idx[/code] è¯†åˆ«çš„é”®çš„è¾“å‡ºå¥æŸ„,[code]track_idx[/code] 必须是"
+"è´å¡žå°”轨é“的索引。"
#: doc/classes/Animation.xml
msgid ""
"Returns the value of the key identified by [code]key_idx[/code]. The "
"[code]track_idx[/code] must be the index of a Bezier Track."
msgstr ""
-"返回由 [code]key_idx[/code] 识别的键的值, [code]track_idx[/code] 必须是è´å¡ž"
-"尔轨é“的索引。"
+"返回由 [code]key_idx[/code] 识别的键的值,[code]track_idx[/code] 必须是è´å¡žå°”"
+"轨é“的索引。"
#: doc/classes/Animation.xml
msgid ""
@@ -5581,7 +5584,7 @@ msgid ""
"Returns the interpolated value at the given [code]time[/code] (in seconds). "
"The [code]track_idx[/code] must be the index of a Bezier Track."
msgstr ""
-"返回给定 [code]time[/code] 处的æ’值(以秒为å•ä½ï¼‰ã€‚ [code]track_idx[/code] å¿…"
+"返回给定 [code]time[/code] 处的æ’值(以秒为å•ä½ï¼‰ã€‚[code]track_idx[/code] å¿…"
"须是è´å¡žå°”轨é“的索引。"
#: doc/classes/Animation.xml
@@ -5618,13 +5621,13 @@ msgstr "清除动画(清除所有轨é“å¹¶é‡ç½®æ‰€æœ‰ï¼‰ã€‚"
msgid ""
"Adds a new track that is a copy of the given track from [code]to_animation[/"
"code]."
-msgstr "从[code]to_animation[/code]中添加一个新的轨é“,它是给定轨é“的副本。"
+msgstr "从 [code]to_animation[/code] 中添加一个新的轨é“,它是给定轨é“的副本。"
#: doc/classes/Animation.xml
msgid ""
"Returns the index of the specified track. If the track is not found, return "
"-1."
-msgstr "返回指定轨迹的索引。如果没有找到,返回-1。"
+msgstr "返回指定轨迹的索引。如果没有找到,返回 -1。"
#: doc/classes/Animation.xml
msgid "Returns the amount of tracks in the animation."
@@ -5634,7 +5637,7 @@ msgstr "返回动画中的曲目é‡ã€‚"
msgid ""
"Returns all the key indices of a method track, given a position and delta "
"time."
-msgstr "返回给定ä½ç½®å’Œdelta时间的方法轨迹的所有关键指数。"
+msgstr "返回给定ä½ç½®å’Œ delta 时间的方法轨迹的所有关键指数。"
#: doc/classes/Animation.xml
msgid "Returns the method name of a method track."
@@ -5648,7 +5651,7 @@ msgstr "返回给定轨é“中给定键的方法轨é“上è¦è°ƒç”¨çš„傿•°å€¼ã€‚
#: doc/classes/Animation.xml
msgid "Removes a track by specifying the track index."
-msgstr "通过指定轨é“索引æ¥åˆ é™¤ä¸€ä¸ªè½¨é“。"
+msgstr "通过指定轨é“索引æ¥ç§»é™¤ä¸€ä¸ªè½¨é“。"
#: doc/classes/Animation.xml
msgid ""
@@ -5734,11 +5737,11 @@ msgstr "将轨é“上移。"
#: doc/classes/Animation.xml
msgid "Removes a key by index in a given track."
-msgstr "在指定的轨é“上按索引删除一个键。"
+msgstr "在指定的轨é“上按索引移除一个键。"
#: doc/classes/Animation.xml
msgid "Removes a key by position (seconds) in a given track."
-msgstr "按ä½ç½®ï¼ˆç§’)删除指定轨é“中的键。"
+msgstr "按ä½ç½®ï¼ˆç§’)移除指定轨é“中的键。"
#: doc/classes/Animation.xml
msgid "Enables/disables the given track. Tracks are enabled by default."
@@ -5783,11 +5786,11 @@ msgid ""
"For example, [code]\"character/skeleton:ankle\"[/code] or [code]\"character/"
"mesh:transform/local\"[/code]."
msgstr ""
-"设置轨é“的路径。路径必须是指å‘节点场景树的有效路径,必须从将è¦å®žçŽ°åŠ¨ç”»çš„èŠ‚ç‚¹"
-"的父节点开始指定。控件属性或骨骼的轨é“必须在路径åŽé¢åŠ ä¸Šå®ƒä»¬çš„å字,用"
-"[code]\":\"[/code]分隔。\n"
-"例如,[code]\"character/skeleton:ankle\"[/code] 或[code]\"character/mesh:"
-"transform/local\"[/code] 。"
+"设置轨é“的路径。路径必须是指å‘场景树节点的有效路径,必须从将è¦å®žçŽ°åŠ¨ç”»çš„èŠ‚ç‚¹"
+"的父节点开始指定。控制属性或骨骼的轨é“必须在路径åŽé¢åŠ ä¸Šå®ƒä»¬çš„å字,用 "
+"[code]\":\"[/code] 分隔。\n"
+"例如,[code]\"character/skeleton:ankle\"[/code] 或 [code]\"character/mesh:"
+"transform/local\"[/code]。"
#: doc/classes/Animation.xml
msgid ""
@@ -6069,11 +6072,11 @@ msgstr ""
#: doc/classes/AnimationNode.xml
msgid "Removes an input, call this only when inactive."
-msgstr "åˆ é™¤è¾“å…¥ï¼Œä»…åœ¨å¤„äºŽéžæ´»åŠ¨çŠ¶æ€æ—¶è°ƒç”¨æ­¤è¾“入。"
+msgstr "ç§»é™¤è¾“å…¥ï¼Œä»…åœ¨å¤„äºŽéžæ´»åŠ¨çŠ¶æ€æ—¶è°ƒç”¨æ­¤è¾“入。"
#: doc/classes/AnimationNode.xml
msgid "Adds or removes a path for the filter."
-msgstr "添加或删除筛选器的路径。"
+msgstr "添加或移除筛选器的路径。"
#: doc/classes/AnimationNode.xml
msgid ""
@@ -6089,7 +6092,7 @@ msgstr "如果为 [code]true[/code],则å¯ç”¨ç­›é€‰åŠŸèƒ½ã€‚"
#: doc/classes/AnimationNode.xml
msgid "Emitted when the node was removed from the graph."
-msgstr "当该节点从图中删除时触å‘。"
+msgstr "当该节点从图中移除时触å‘。"
#: doc/classes/AnimationNode.xml
msgid ""
@@ -6098,9 +6101,9 @@ msgid ""
"[AnimationNodeBlendSpace1D], [AnimationNodeBlendSpace2D], "
"[AnimationNodeStateMachine], and [AnimationNodeBlendTree]."
msgstr ""
-"由继承自该类且内部有树的节点å‘出,当其一个节点å‘生å˜åŒ–时。å‘出此信å·çš„节点有"
+"由继承自该类且内部有树的节点å‘出,当其一个节点å‘生å˜åŒ–时。å‘出此信å·çš„节点有 "
"[AnimationNodeBlendSpace1D]ã€[AnimationNodeBlendSpace2D]ã€"
-"[AnimationNodeStateMachine]和[AnimationNodeBlendTree]。"
+"[AnimationNodeStateMachine] 和 [AnimationNodeBlendTree]。"
#: doc/classes/AnimationNode.xml
msgid "Do not use filtering."
@@ -6127,8 +6130,8 @@ msgid ""
"A resource to add to an [AnimationNodeBlendTree]. Blends two animations "
"additively based on an amount value in the [code][0.0, 1.0][/code] range."
msgstr ""
-"添加到 [AnimationNodeBlendTree] 的资æºã€‚æ ¹æ®[code][0.0,1.0][/code]范围内的é‡"
-"值加法混åˆä¸¤ä¸ªåŠ¨ç”»ã€‚"
+"添加到 [AnimationNodeBlendTree] 的资æºã€‚æ ¹æ® [code][0.0,1.0][/code] 范围内的"
+"é‡å€¼åŠ æ³•æ··åˆä¸¤ä¸ªåŠ¨ç”»ã€‚"
#: doc/classes/AnimationNodeAdd2.xml doc/classes/AnimationNodeAdd3.xml
#: doc/classes/AnimationNodeBlend2.xml doc/classes/AnimationNodeBlend3.xml
@@ -6137,8 +6140,9 @@ msgid ""
"code] when calling [method AnimationNode.blend_input], forcing the blended "
"animations to update every frame."
msgstr ""
-"如果[code]true[/code],在调用[method AnimationNode.blend_input]时,将"
-"[code]optimization[/code] to[code]false[/code],强制混åˆåŽçš„动画æ¯ä¸€å¸§æ›´æ–°ã€‚"
+"如果为 [code]true[/code],在调用 [method AnimationNode.blend_input] 时,将 "
+"[code]optimization[/code] 设置为 [code]false[/code],强制混åˆåŽçš„动画æ¯ä¸€å¸§æ›´"
+"新。"
#: doc/classes/AnimationNodeAdd3.xml
msgid ""
@@ -6219,7 +6223,7 @@ msgid ""
"Animation to use as an output. It is one of the animations provided by "
"[member AnimationTree.anim_player]."
msgstr ""
-"作为输出使用的动画。它是[member AnimationTree.anim_player]æä¾›çš„动画之一。"
+"作为输出使用的动画。它是 [member AnimationTree.anim_player] æä¾›çš„动画之一。"
#: doc/classes/AnimationNodeBlend2.xml
msgid "Blends two animations linearly inside of an [AnimationNodeBlendTree]."
@@ -6263,8 +6267,8 @@ msgid ""
"Blends linearly between two of any number of [AnimationNode] of any type "
"placed on a virtual axis."
msgstr ""
-"åœ¨è™šæ‹Ÿè½´ä¸Šæ”¾ç½®çš„ä»»æ„æ•°é‡çš„[AnimationNode]的任æ„类型的两个[AnimationNode]之间"
-"线性混åˆã€‚"
+"åœ¨è™šæ‹Ÿè½´ä¸Šæ”¾ç½®çš„ä»»æ„æ•°é‡çš„ [AnimationNode] 的任æ„类型的两个 [AnimationNode] "
+"之间线性混åˆã€‚"
#: doc/classes/AnimationNodeBlendSpace1D.xml
msgid ""
@@ -6302,42 +6306,42 @@ msgstr "返回混åˆè½´ä¸Šçš„点的数é‡ã€‚"
msgid ""
"Returns the [AnimationNode] referenced by the point at index [code]point[/"
"code]."
-msgstr "返回索引[code]point[/code]处的点所引用的[AnimationNode]。"
+msgstr "返回索引 [code]point[/code] 处的点所引用的 [AnimationNode]。"
#: doc/classes/AnimationNodeBlendSpace1D.xml
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid "Returns the position of the point at index [code]point[/code]."
-msgstr "返回索引[code]point[/code]处的点的ä½ç½®ã€‚"
+msgstr "返回索引 [code]point[/code] 处的点的ä½ç½®ã€‚"
#: doc/classes/AnimationNodeBlendSpace1D.xml
msgid "Removes the point at index [code]point[/code] from the blend axis."
-msgstr "将索引[code]point[/code]处的点从混åˆè½´ä¸Šåˆ é™¤ã€‚"
+msgstr "将索引 [code]point[/code] 处的点从混åˆè½´ä¸Šç§»é™¤ã€‚"
#: doc/classes/AnimationNodeBlendSpace1D.xml
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid ""
"Changes the [AnimationNode] referenced by the point at index [code]point[/"
"code]."
-msgstr "改å˜ç´¢å¼•[code]point[/code]处的点所引用的[AnimationNode]。"
+msgstr "改å˜ç´¢å¼• [code]point[/code] 处的点所引用的 [AnimationNode]。"
#: doc/classes/AnimationNodeBlendSpace1D.xml
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid ""
"Updates the position of the point at index [code]point[/code] on the blend "
"axis."
-msgstr "æ›´æ–°æ··åˆè½´ä¸Šç´¢å¼•[code]point[/code]处的点的ä½ç½®ã€‚"
+msgstr "æ›´æ–°æ··åˆè½´ä¸Šç´¢å¼• [code]point[/code] 处的点的ä½ç½®ã€‚"
#: doc/classes/AnimationNodeBlendSpace1D.xml
msgid ""
"The blend space's axis's upper limit for the points' position. See [method "
"add_blend_point]."
-msgstr "æ··åˆç©ºé—´çš„轴的点的ä½ç½®ä¸Šé™ã€‚请å‚阅 [method add_blend_point]。"
+msgstr "æ··åˆç©ºé—´çš„轴的点的ä½ç½®ä¸Šé™ã€‚è§ [method add_blend_point]。"
#: doc/classes/AnimationNodeBlendSpace1D.xml
msgid ""
"The blend space's axis's lower limit for the points' position. See [method "
"add_blend_point]."
-msgstr "æ··åˆç©ºé—´çš„轴的点的ä½ç½®ä¸‹é™ã€‚请å‚阅 [method add_blend_point]。"
+msgstr "æ··åˆç©ºé—´çš„轴的点的ä½ç½®ä¸‹é™ã€‚è§ [method add_blend_point]。"
#: doc/classes/AnimationNodeBlendSpace1D.xml
msgid "Position increment to snap to when moving a point on the axis."
@@ -6351,7 +6355,7 @@ msgstr "æ··åˆç©ºé—´è™šæ‹Ÿè½´çš„æ ‡ç­¾ã€‚"
msgid ""
"Blends linearly between three [AnimationNode] of any type placed in a 2D "
"space."
-msgstr "在二维空间中放置的三个任æ„类型的[AnimationNode]之间线性èžåˆã€‚"
+msgstr "在 2D 空间中放置的三个任æ„类型的 [AnimationNode] 之间线性èžåˆã€‚"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid ""
@@ -6402,7 +6406,7 @@ msgstr "返回混åˆç©ºé—´ä¸­çš„点的数é‡ã€‚"
msgid ""
"Returns the [AnimationRootNode] referenced by the point at index "
"[code]point[/code]."
-msgstr "返回索引[code]point[/code]处的点所引用的[AnimationRootNode]。"
+msgstr "返回索引 [code]point[/code] 处的点所引用的 [AnimationRootNode]。"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid "Returns the number of triangles in the blend space."
@@ -6413,16 +6417,17 @@ msgid ""
"Returns the position of the point at index [code]point[/code] in the "
"triangle of index [code]triangle[/code]."
msgstr ""
-"返回索引[code]point[/code]处的点在索引[code]triangle[/code]的三角形中的ä½ç½®ã€‚"
+"返回索引 [code]point[/code] 处的点在索引 [code]triangle[/code] 的三角形中的ä½"
+"置。"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid "Removes the point at index [code]point[/code] from the blend space."
-msgstr "从混åˆç©ºé—´ä¸­åˆ é™¤ç´¢å¼•[code]point[/code]处的点。"
+msgstr "从混åˆç©ºé—´ä¸­ç§»é™¤ç´¢å¼• [code]point[/code] 处的点。"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid ""
"Removes the triangle at index [code]triangle[/code] from the blend space."
-msgstr "从混åˆç©ºé—´ä¸­åˆ é™¤ç´¢å¼•[code]triangle[/code]处的三角形。"
+msgstr "从混åˆç©ºé—´ä¸­ç§»é™¤ç´¢å¼• [code]triangle[/code] 处的三角形。"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid ""
@@ -6430,7 +6435,7 @@ msgid ""
"mesh updates every time you add or remove points with [method "
"add_blend_point] and [method remove_blend_point]."
msgstr ""
-"如果 [code]true[/code],混åˆç©ºé—´ä¼šè‡ªåŠ¨è¿›è¡Œä¸‰è§’æµ‹é‡ã€‚æ¯æ¬¡ä½¿ç”¨ [method "
+"如果为 [code]true[/code],混åˆç©ºé—´ä¼šè‡ªåŠ¨è¿›è¡Œä¸‰è§’æµ‹é‡ã€‚æ¯æ¬¡ä½¿ç”¨ [method "
"add_blend_point] 和 [method remove_blend_point] 添加或移除点时,网格都会更"
"新。"
@@ -6438,21 +6443,19 @@ msgstr ""
msgid ""
"Controls the interpolation between animations. See [enum BlendMode] "
"constants."
-msgstr "控制动画之间的æ’值。å‚阅 [enum BlendMode] 常é‡ã€‚"
+msgstr "控制动画之间的æ’å€¼ã€‚è§ [enum BlendMode] 常é‡ã€‚"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid ""
"The blend space's X and Y axes' upper limit for the points' position. See "
"[method add_blend_point]."
-msgstr ""
-"æ··åˆç©ºé—´çš„ X è½´å’Œ Y 轴的点的ä½ç½®ä¸Šé™ã€‚请å‚阅 [method add_blend_point]。"
+msgstr "æ··åˆç©ºé—´çš„ X è½´å’Œ Y 轴的点的ä½ç½®ä¸Šé™ã€‚è§ [method add_blend_point]。"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid ""
"The blend space's X and Y axes' lower limit for the points' position. See "
"[method add_blend_point]."
-msgstr ""
-"æ··åˆç©ºé—´çš„ X è½´å’Œ Y 轴的点的ä½ç½®ä¸‹é™ã€‚请å‚阅 [method add_blend_point]。"
+msgstr "æ··åˆç©ºé—´çš„ X è½´å’Œ Y 轴的点的ä½ç½®ä¸‹é™ã€‚è§ [method add_blend_point]。"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid "Position increment to snap to when moving a point."
@@ -6460,17 +6463,17 @@ msgstr "移动点时è¦å¯¹é½çš„ä½ç½®å¢žé‡ã€‚"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid "Name of the blend space's X axis."
-msgstr "æ··åˆç©ºé—´Xè½´çš„å称。"
+msgstr "æ··åˆç©ºé—´ X è½´çš„å称。"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid "Name of the blend space's Y axis."
-msgstr "æ··åˆç©ºé—´Yè½´çš„å称。"
+msgstr "æ··åˆç©ºé—´ Y è½´çš„å称。"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid ""
"Emitted every time the blend space's triangles are created, removed, or when "
"one of their vertices changes position."
-msgstr "æ¯å½“创建ã€åˆ é™¤æ··åˆç©ºé—´çš„三角形,或当其中一个顶点改å˜ä½ç½®æ—¶å‘出。"
+msgstr "æ¯å½“创建ã€ç§»é™¤æ··åˆç©ºé—´çš„三角形,或当其中一个顶点改å˜ä½ç½®æ—¶å‘出。"
#: doc/classes/AnimationNodeBlendSpace2D.xml
msgid "The interpolation between animations is linear."
@@ -6487,7 +6490,7 @@ msgid ""
"Similar to [constant BLEND_MODE_DISCRETE], but starts the new animation at "
"the last animation's playback position."
msgstr ""
-"类似于[constant BLEND_MODE_DISCRETE],但在最åŽä¸€ä¸ªåŠ¨ç”»çš„æ’­æ”¾ä½ç½®å¼€å§‹æ–°çš„动"
+"类似于 [constant BLEND_MODE_DISCRETE],但在最åŽä¸€ä¸ªåŠ¨ç”»çš„æ’­æ”¾ä½ç½®å¼€å§‹æ–°çš„动"
"画。"
#: doc/classes/AnimationNodeBlendTree.xml
@@ -6544,7 +6547,7 @@ msgstr "如果存在å称为 [code]name[/code] çš„å­èŠ‚ç‚¹ï¼Œåˆ™è¿”å›ž [code]t
#: doc/classes/AnimationNodeBlendTree.xml
msgid "Removes a sub-node."
-msgstr "删除一个å­èŠ‚ç‚¹ã€‚"
+msgstr "移除一个å­èŠ‚ç‚¹ã€‚"
#: doc/classes/AnimationNodeBlendTree.xml
msgid "Changes the name of a sub-node."
@@ -6611,8 +6614,8 @@ msgid ""
"seconds) between 0 and this value will be added to [member "
"autorestart_delay]."
msgstr ""
-"如果[member autorestart]为 [code]true[/code],则介于0å’Œæ­¤å€¼ä¹‹é—´çš„éšæœºé™„加延迟"
-"(以秒为å•ä½ï¼‰å°†æ·»åŠ åˆ°[member autorestart_delay]。"
+"如果 [member autorestart] 为 [code]true[/code],则介于0å’Œæ­¤å€¼ä¹‹é—´çš„éšæœºé™„加延"
+"迟(以秒为å•ä½ï¼‰å°†æ·»åŠ åˆ° [member autorestart_delay]。"
#: doc/classes/AnimationNodeOutput.xml
msgid "Generic output node to be added to [AnimationNodeBlendTree]."
@@ -6636,8 +6639,8 @@ msgid ""
"[/codeblock]"
msgstr ""
"包å«ä»£è¡¨åŠ¨ç”»çŠ¶æ€çš„多个节点,以图的形å¼è¿žæŽ¥ã€‚节点转æ¢å¯ä»¥é…置为自动å‘生或通过"
-"代ç ï¼Œä½¿ç”¨æœ€çŸ­è·¯å¾„算法。从[AnimationTree]节点中检索"
-"[AnimationNodeStateMachinePlayback]对象,对其进行编程控制。\n"
+"代ç ï¼Œä½¿ç”¨æœ€çŸ­è·¯å¾„算法。从 [AnimationTree] 节点中检索 "
+"[AnimationNodeStateMachinePlayback] 对象,对其进行编程控制。\n"
"[b]示例:[/b]\n"
"[codeblock]\n"
"var state_machine = $AnimationTree.get(\"parameters/playback\")\n"
@@ -6648,7 +6651,7 @@ msgstr ""
msgid ""
"Adds a new node to the graph. The [code]position[/code] is used for display "
"in the editor."
-msgstr "å‘图中添加一个新节点。 [code]position[/code]用于在编辑器中显示。"
+msgstr "å‘图中添加一个新节点。[code]position[/code] 用于在编辑器中显示。"
#: doc/classes/AnimationNodeStateMachine.xml
msgid "Adds a transition between the given nodes."
@@ -6737,7 +6740,7 @@ msgstr "将给定的节点设置为图形的起始点。"
#: doc/classes/AnimationNodeStateMachinePlayback.xml
msgid "Playback control for [AnimationNodeStateMachine]."
-msgstr "[AnimationNodeStateMachine]的播放控件。"
+msgstr "[AnimationNodeStateMachine] 的播放控件。"
#: doc/classes/AnimationNodeStateMachinePlayback.xml
msgid ""
@@ -6750,8 +6753,8 @@ msgid ""
"state_machine.travel(\"some_state\")\n"
"[/codeblock]"
msgstr ""
-"å…许控制用[AnimationNodeStateMachine]创建的[AnimationTree]çŠ¶æ€æœºã€‚用"
-"[code]$AnimationTree.get(\"parameters/playback\")[/code]检索。\n"
+"å…许控制用 [AnimationNodeStateMachine] 创建的 [AnimationTree] çŠ¶æ€æœºã€‚用 "
+"[code]$AnimationTree.get(\"parameters/playback\")[/code] 获å–。\n"
"[b]示例:[/b]\n"
"[codeblock]\n"
"var state_machine = $AnimationTree.get(\"parameters/playback\")\n"
@@ -6769,7 +6772,7 @@ msgstr "返回当å‰åŠ¨ç”»çŠ¶æ€å†…的播放ä½ç½®ã€‚"
#: doc/classes/AnimationNodeStateMachinePlayback.xml
msgid ""
"Returns the current travel path as computed internally by the A* algorithm."
-msgstr "返回A*算法内部计算的当å‰è¡Œè¿›è·¯å¾„。"
+msgstr "返回 A* 算法内部计算的当å‰è¡Œè¿›è·¯å¾„。"
#: doc/classes/AnimationNodeStateMachinePlayback.xml
msgid "Returns [code]true[/code] if an animation is playing."
@@ -6825,8 +6828,8 @@ msgid ""
"Don't use this transition during [method AnimationNodeStateMachinePlayback."
"travel] or [member auto_advance]."
msgstr ""
-"ä¸è¦åœ¨[method AnimationNodeStateMachinePlayback.travel]或[member "
-"auto_advance]期间使用这个过渡。"
+"ä¸è¦åœ¨ [method AnimationNodeStateMachinePlayback.travel] 或 [member "
+"auto_advance] 期间使用这个过渡。"
#: doc/classes/AnimationNodeStateMachineTransition.xml
msgid ""
@@ -6834,8 +6837,8 @@ msgid ""
"via [method AnimationNodeStateMachinePlayback.travel] or [member "
"auto_advance]."
msgstr ""
-"当通过[method AnimationNodeStateMachinePlayback.travel]或[member "
-"auto_advance]在树中旅行时,优先级较低的转场。"
+"当通过 [method AnimationNodeStateMachinePlayback.travel] 或 [member "
+"auto_advance] 在树中旅行时,优先级较低的转场。"
#: doc/classes/AnimationNodeStateMachineTransition.xml
msgid "The transition type."
@@ -6847,7 +6850,7 @@ msgstr "这个状æ€å’Œä¸‹ä¸€ä¸ªçжæ€ä¹‹é—´çš„äº¤å‰æ¸å˜æ—¶é—´ã€‚"
#: doc/classes/AnimationNodeStateMachineTransition.xml
msgid "Emitted when [member advance_condition] is changed."
-msgstr "å˜æ›´[member advance_condition]æ—¶å‘出。"
+msgstr "å˜æ›´ [member advance_condition] æ—¶å‘出。"
#: doc/classes/AnimationNodeStateMachineTransition.xml
msgid ""
@@ -6869,17 +6872,17 @@ msgstr "等待当å‰çŠ¶æ€æ’­æ”¾ç»“æŸï¼Œç„¶åŽåˆ‡æ¢åˆ°ä¸‹ä¸€ä¸ªçжæ€åŠ¨ç”»çš„
#: doc/classes/AnimationNodeTimeScale.xml
msgid "A time-scaling animation node to be used with [AnimationTree]."
-msgstr "与[AnimationTree]一起使用的时间缩放动画节点。"
+msgstr "与 [AnimationTree] 一起使用的时间缩放动画节点。"
#: doc/classes/AnimationNodeTimeScale.xml
msgid ""
"Allows scaling the speed of the animation (or reversing it) in any children "
"nodes. Setting it to 0 will pause the animation."
-msgstr "å…许缩放任何å­èŠ‚ç‚¹ä¸­åŠ¨ç”»çš„é€Ÿåº¦ï¼ˆæˆ–å转)。将其设置为0将暂åœåŠ¨ç”»ã€‚"
+msgstr "å…许缩放任何å­èŠ‚ç‚¹ä¸­åŠ¨ç”»çš„é€Ÿåº¦ï¼ˆæˆ–å转)。将其设置为 0 将暂åœåŠ¨ç”»ã€‚"
#: doc/classes/AnimationNodeTimeSeek.xml
msgid "A time-seeking animation node to be used with [AnimationTree]."
-msgstr "与[AnimationTree]é…åˆä½¿ç”¨çš„寻时动画节点。"
+msgstr "与 [AnimationTree] é…åˆä½¿ç”¨çš„寻时动画节点。"
#: doc/classes/AnimationNodeTimeSeek.xml
msgid ""
@@ -6919,7 +6922,7 @@ msgstr ""
#: doc/classes/AnimationNodeTransition.xml
msgid "A generic animation transition node for [AnimationTree]."
-msgstr "[AnimationTree]的通用动画过渡节点。"
+msgstr "[AnimationTree] 的通用动画过渡节点。"
#: doc/classes/AnimationNodeTransition.xml
msgid ""
@@ -7115,7 +7118,7 @@ msgstr "移除键å为 [code]name[/code] 的动画。"
msgid ""
"Renames an existing animation with key [code]name[/code] to [code]newname[/"
"code]."
-msgstr "将键值为[code]name[/code]的现有动画é‡å‘½å为[code]newname[/code]。"
+msgstr "将键å为 [code]name[/code] 的现有动画é‡å‘½å为 [code]newname[/code]。"
#: doc/classes/AnimationPlayer.xml
msgid ""
@@ -7183,8 +7186,8 @@ msgstr ""
"当剿’­æ”¾çš„动画的å称。如果没有动画正在播放,该属性的值是一个空字符串。改å˜è¿™"
"个值ä¸ä¼šé‡æ–°å¯åŠ¨åŠ¨ç”»ã€‚å…³äºŽæ’­æ”¾åŠ¨ç”»çš„æ›´å¤šä¿¡æ¯è¯·å‚阅 [method play]。\n"
"[b]注æ„:[/b]è™½ç„¶è¿™ä¸ªå±žæ€§ä¼šå‡ºçŽ°åœ¨æ£€æŸ¥å™¨ä¸­ï¼Œä½†å®ƒä¸æ˜¯ç”¨æ¥ç¼–辑的,也ä¸ä¼šä¿å­˜åœ¨åœº"
-"景中。该属性主è¦ç”¨äºŽèŽ·å–当剿’­æ”¾çš„动画,内部用于动画播放轨é“。有关详细信æ¯ï¼Œ"
-"请å‚阅动画 [Animation]。"
+"景中。该属性主è¦ç”¨äºŽèŽ·å–当剿’­æ”¾çš„动画,内部用于动画播放轨é“。详情请å‚阅 "
+"[Animation]。"
#: doc/classes/AnimationPlayer.xml
msgid "The length (in seconds) of the currently being played animation."
@@ -7202,7 +7205,7 @@ msgstr "æ–¹æ³•è°ƒç”¨è½¨é“æ‰€ä½¿ç”¨çš„调用模å¼ã€‚"
msgid ""
"If [code]true[/code], updates animations in response to process-related "
"notifications."
-msgstr "如果[code]true[/code]ï¼Œæ ¹æ®æµç¨‹ç›¸å…³é€šçŸ¥æ›´æ–°åŠ¨ç”»ã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œæ ¹æ®æµç¨‹ç›¸å…³é€šçŸ¥æ›´æ–°åŠ¨ç”»ã€‚"
#: doc/classes/AnimationPlayer.xml
msgid ""
@@ -7421,7 +7424,7 @@ msgstr ""
#: doc/classes/AnimationTreePlayer.xml
msgid "Adds a [code]type[/code] node to the graph with name [code]id[/code]."
-msgstr "添加[code]type[/code]节点到图示中,å称为[code]id[/code]。"
+msgstr "添加 [code]type[/code] 节点到图示中,å称为 [code]id[/code]。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
@@ -7429,35 +7432,35 @@ msgid ""
"seconds to shift. Events between the current frame and [code]delta[/code] "
"are handled."
msgstr ""
-"移动动画时间轴上的ä½ç½®ã€‚[code]delta[/code]是移动的时间,å•使˜¯ç§’。当å‰å¸§å’Œ"
-"[code]delta[/code]之间的事件被处ç†ã€‚"
+"移动动画时间轴上的ä½ç½®ã€‚[code]delta[/code] 是移动的时间,å•使˜¯ç§’。当å‰å¸§å’Œ "
+"[code]delta[/code] 之间的事件被处ç†ã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Returns the [AnimationPlayer]'s [Animation] bound to the "
"[AnimationTreePlayer]'s animation node with name [code]id[/code]."
msgstr ""
-"返回与[AnimationTreePlayer]的动画节点绑定的[Animation],å称为[code]id[/"
+"返回与 [AnimationTreePlayer] 的动画节点绑定的 [Animation],å称为 [code]id[/"
"code]。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Returns the name of the [member master_player]'s [Animation] bound to this "
"animation node."
-msgstr "返回与此动画节点绑定的[member master_player]çš„[Animation]å称。"
+msgstr "返回与此动画节点绑定的 [member master_player] çš„ [Animation] å称。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Returns the absolute playback timestamp of the animation node with name "
"[code]id[/code]."
-msgstr "返回å称为[code]id[/code]的动画节点的ç»å¯¹æ’­æ”¾æ—¶é—´æˆ³ã€‚"
+msgstr "返回å称为 [code]id[/code] 的动画节点的ç»å¯¹æ’­æ”¾æ—¶é—´æˆ³ã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Binds a new [Animation] from the [member master_player] to the "
"[AnimationTreePlayer]'s animation node with name [code]id[/code]."
msgstr ""
-"å°†å称为[code]id[/code]的新[Animation]从[member master_player]绑定到"
+"å°†å称为 [code]id[/code] 的新[Animation]从[member master_player]绑定到"
"[AnimationTreePlayer]的动画节点。"
#: doc/classes/AnimationTreePlayer.xml
@@ -7466,8 +7469,8 @@ msgid ""
"[code]id[/code] turns off the track modifying the property at [code]path[/"
"code]. The modified node's children continue to animate."
msgstr ""
-"如果[code]enable[/code]为 [code]true[/code],则ID为[code]id[/code]的动画节点"
-"将关闭修改[code]path[/code]属性的轨é“。修改åŽçš„节点的å­ä»£ç»§ç»­è¿›è¡ŒåŠ¨ç”»å¤„ç†ã€‚"
+"如果[code]enable[/code]为 [code]true[/code],则ID为 [code]id[/code] 的动画节"
+"点将关闭修改[code]path[/code]属性的轨é“。修改åŽçš„节点的å­ä»£ç»§ç»­è¿›è¡ŒåŠ¨ç”»å¤„ç†ã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
@@ -7496,7 +7499,7 @@ msgid ""
"influence of B gets raised. At 1, output is input B."
msgstr ""
"设置Blend2节点的混åˆé‡ï¼Œç»™å®šå…¶å称和值。\n"
-"一个Blend2节点混åˆä¸¤ä¸ªåŠ¨ç”»ï¼ˆAå’ŒB),混åˆé‡åœ¨0到1之间。\n"
+"一个Blend2节点混åˆä¸¤ä¸ªåŠ¨ç”»ï¼ˆAå’ŒB),混åˆé‡åœ¨0 到 1之间。\n"
"在0的时候,输出是输入A。接近1的时候,A的影å“å˜å°ï¼ŒB的影å“å˜å¤§ã€‚在1时,输出是"
"输入B。"
@@ -7506,8 +7509,8 @@ msgid ""
"[code]id[/code] turns off the track modifying the property at [code]path[/"
"code]. The modified node's children continue to animate."
msgstr ""
-"如果[code]enable[/code]是[code]true[/code],å称为[code]id[/code]çš„Blend2节点"
-"会关闭修改[code]path[/code]处属性的轨é“。被修改的节点的å­èŠ‚ç‚¹ç»§ç»­å¤„ç†åŠ¨ç”»ã€‚"
+"如果[code]enable[/code]是[code]true[/code],å称为 [code]id[/code] çš„Blend2节"
+"点会关闭修改[code]path[/code]处属性的轨é“。被修改的节点的å­èŠ‚ç‚¹ç»§ç»­å¤„ç†åŠ¨ç”»ã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns the blend amount of a Blend3 node given its name."
@@ -7526,8 +7529,8 @@ msgstr ""
"设置一个Blend3节点的混åˆå€¼ï¼Œä¼ å…¥èŠ‚ç‚¹å和混åˆå€¼ã€‚\n"
"Blend3节点使用-1~1ä¹‹é—´çš„ä¸€ä¸ªå€¼æ¥æ··åˆ3个动画 (A, B-, B+).\n"
"值为-1时,输出动画为B-;值从-1到0时,B-的影å“å‡å¼±ï¼ŒA的影å“å˜å¼ºï¼ŒB+的影å“为0ï¼›"
-"值为0时,输出为动画A;值从0到1时,A的影å“å‡å¼±ï¼ŒB+的影å“å˜å¼ºï¼ŒB-的影å“为0;值"
-"为1时,输出为动画B+。"
+"值为0时,输出为动画A;值从0 到 1时,A的影å“å‡å¼±ï¼ŒB+的影å“å˜å¼ºï¼ŒB-的影å“为0ï¼›"
+"值为1时,输出为动画B+。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns the blend amount of a Blend4 node given its name."
@@ -7547,16 +7550,16 @@ msgstr ""
msgid ""
"Connects node [code]id[/code] to [code]dst_id[/code] at the specified input "
"slot."
-msgstr "将节点[code]id[/code]è¿žæŽ¥åˆ°æŒ‡å®šè¾“å…¥æ’æ§½çš„[code]dst_id[/code]。"
+msgstr "将节点 [code]id[/code] è¿žæŽ¥åˆ°æŒ‡å®šè¾“å…¥æ’æ§½çš„ [code]dst_id[/code]。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Disconnects nodes connected to [code]id[/code] at the specified input slot."
-msgstr "æ–­å¼€åœ¨æŒ‡å®šè¾“å…¥æ’æ§½è¿žæŽ¥åˆ°[code]id[/code]的节点。"
+msgstr "æ–­å¼€åœ¨æŒ‡å®šè¾“å…¥æ’æ§½è¿žæŽ¥åˆ° [code]id[/code] 的节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns a [PoolStringArray] containing the name of all nodes."
-msgstr "è¿”å›žåŒ…å«æ‰€æœ‰èŠ‚ç‚¹åç§°çš„[PoolStringArray]。"
+msgstr "è¿”å›žåŒ…å«æ‰€æœ‰èŠ‚ç‚¹åç§°çš„ [PoolStringArray]。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns the mix amount of a Mix node given its name."
@@ -7590,7 +7593,7 @@ msgstr "返回给定其å称节点在图示中的ä½ç½®ã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid "Gets the node type, will return from [enum NodeType] enum."
-msgstr "获å–节点类型,将从[enum NodeType]枚举中返回。"
+msgstr "获å–节点类型,将从 [enum NodeType] 枚举中返回。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Renames a node in the graph."
@@ -7602,19 +7605,19 @@ msgstr "设置节点在图示中的ä½ç½®ï¼Œç»™å®šå…¶åç§°å’Œä½ç½®ã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns the autostart delay of a OneShot node given its name."
-msgstr "返回给定åç§°çš„OneShot节点的自动å¯åŠ¨å»¶è¿Ÿã€‚"
+msgstr "返回给定åç§°çš„ OneShot 节点的自动å¯åŠ¨å»¶è¿Ÿã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns the autostart random delay of a OneShot node given its name."
-msgstr "返回给定åç§°çš„OneShot节点的自动å¯åŠ¨éšæœºå»¶è¿Ÿã€‚"
+msgstr "返回给定åç§°çš„ OneShot 节点的自动å¯åŠ¨éšæœºå»¶è¿Ÿã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns the fade in time of a OneShot node given its name."
-msgstr "返回给定åç§°çš„OneShot节点的淡入时间。"
+msgstr "返回给定åç§°çš„ OneShot 节点的淡入时间。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns the fade out time of a OneShot node given its name."
-msgstr "返回给定其åç§°çš„OneShot节点的淡出时间。"
+msgstr "返回给定其åç§°çš„ OneShot 节点的淡出时间。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns whether a OneShot node will auto restart given its name."
@@ -7622,34 +7625,34 @@ msgstr "返回OneShot节点是å¦ä¼šæ ¹æ®å…¶åç§°è‡ªåŠ¨é‡æ–°å¯åŠ¨ã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid "Returns whether a OneShot node is active given its name."
-msgstr "返回指定åç§°çš„OneShot节点是å¦å¤„于活动状æ€ã€‚"
+msgstr "返回指定åç§°çš„ OneShot 节点是å¦å¤„于活动状æ€ã€‚"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Sets the autorestart property of a OneShot node given its name and value."
-msgstr "设置OneShot节点的自动å¯åŠ¨å±žæ€§ï¼Œç»™å®šå…¶å称和值。"
+msgstr "设置 OneShot 节点的自动å¯åŠ¨å±žæ€§ï¼Œç»™å®šå…¶å称和值。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Sets the autorestart delay of a OneShot node given its name and value in "
"seconds."
-msgstr "设置OneShot节点的自动å¯åŠ¨å»¶è¿Ÿï¼Œç»™å®šå…¶å称和值,å•ä½ç§’。"
+msgstr "设置 OneShot 节点的自动å¯åŠ¨å»¶è¿Ÿï¼Œç»™å®šå…¶å称和值,å•ä½ç§’。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Sets the autorestart random delay of a OneShot node given its name and value "
"in seconds."
-msgstr "设置OneShot节点的自动é‡å¯éšæœºå»¶è¿Ÿï¼Œç»™å®šå…¶å称和数值,å•ä½ç§’。"
+msgstr "设置 OneShot 节点的自动é‡å¯éšæœºå»¶è¿Ÿï¼Œç»™å®šå…¶å称和数值,å•ä½ç§’。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Sets the fade in time of a OneShot node given its name and value in seconds."
-msgstr "设置OneShot节点的淡入时间,给定其å称和数值,å•ä½ç§’。"
+msgstr "设置 OneShot 节点的淡入时间,给定其å称和数值,å•ä½ç§’。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Sets the fade out time of a OneShot node given its name and value in seconds."
-msgstr "设置OneShot节点的淡出时间,给定其å称和数值,å•ä½ç§’。"
+msgstr "设置 OneShot 节点的淡出时间,给定其å称和数值,å•ä½ç§’。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
@@ -7657,16 +7660,17 @@ msgid ""
"[code]id[/code] turns off the track modifying the property at [code]path[/"
"code]. The modified node's children continue to animate."
msgstr ""
-"如果[code]enable[/code]是[code]true[/code],ID为[code]id[/code]的OneShot节点"
-"会关闭修改[code]path[/code]处属性的轨é“。被修改的节点的å­èŠ‚ç‚¹ç»§ç»­è¿›è¡ŒåŠ¨ç”»ã€‚"
+"如果[code]enable[/code]是[code]true[/code],ID为 [code]id[/code] 的 OneShot "
+"节点会关闭修改[code]path[/code]处属性的轨é“。被修改的节点的å­èŠ‚ç‚¹ç»§ç»­è¿›è¡ŒåŠ¨"
+"画。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Starts a OneShot node given its name."
-msgstr "å¯åŠ¨æŒ‡å®šåç§°çš„OneShot节点。"
+msgstr "å¯åŠ¨æŒ‡å®šåç§°çš„ OneShot 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Stops the OneShot node with name [code]id[/code]."
-msgstr "åœæ­¢å称为[code]id[/code]çš„OneShot节点。"
+msgstr "åœæ­¢å称为 [code]id[/code] çš„ OneShot 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
@@ -7679,7 +7683,7 @@ msgstr ""
#: doc/classes/AnimationTreePlayer.xml
msgid "Removes the animation node with name [code]id[/code]."
-msgstr "移除å称为[code]id[/code]的动画节点。"
+msgstr "移除å称为 [code]id[/code] 的动画节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Resets this [AnimationTreePlayer]."
@@ -7688,7 +7692,7 @@ msgstr "é‡ç½®æ­¤ [AnimationTreePlayer]。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Returns the time scale value of the TimeScale node with name [code]id[/code]."
-msgstr "返回å称为[code]id[/code]çš„TimeScale节点的时间缩放值。"
+msgstr "返回å称为 [code]id[/code] çš„TimeScale节点的时间缩放值。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
@@ -7699,7 +7703,7 @@ msgid ""
"If applied after a blend or mix, affects all input animations to that blend "
"or mix."
msgstr ""
-"设置å称为[code]id[/code]çš„TimeScale节点的时间缩放为[code]scale[/code]。\n"
+"设置å称为 [code]id[/code] çš„TimeScale节点的时间缩放为[code]scale[/code]。\n"
"时间缩放节点用æ¥åŠ å¿«[Animation]的速度,如果缩放高于1ï¼Œå°±ä¼šå‡æ…¢å®ƒä»¬ã€‚\n"
"如果在混åˆåŽåº”用,会影å“到该混åˆçš„æ‰€æœ‰è¾“入动画。"
@@ -7710,34 +7714,35 @@ msgid ""
"This functions as a seek in the [Animation] or the blend or mix of "
"[Animation]s input in it."
msgstr ""
-"设置å称为[code]id[/code]çš„TimeSeek节点的时间查寻值为[code]seconds[/code]。\n"
+"设置å称为 [code]id[/code] çš„TimeSeek节点的时间查寻值为[code]seconds[/"
+"code]。\n"
"这在[Animation]或输入的[Animation]的混åˆä¸­èµ·åˆ°æŸ¥å¯»çš„作用。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Deletes the input at [code]input_idx[/code] for the transition node with "
"name [code]id[/code]."
-msgstr "删除å称为[code]id[/code]的过渡节点的[code]input_idx[/code]的输入。"
+msgstr "删除å称为 [code]id[/code] 的过渡节点的[code]input_idx[/code]的输入。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Returns the index of the currently evaluated input for the transition node "
"with name [code]id[/code]."
-msgstr "返回å称为[code]id[/code]的过渡节点的当å‰è¯„估输入的索引。"
+msgstr "返回å称为 [code]id[/code] 的过渡节点的当å‰è¯„估输入的索引。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Returns the number of inputs for the transition node with name [code]id[/"
"code]. You can add inputs by right-clicking on the transition node."
msgstr ""
-"返回å称为[code]id[/code]的过渡节点的输入数。你å¯ä»¥é€šè¿‡å³é”®ç‚¹å‡»è¿‡æ¸¡èŠ‚ç‚¹æ¥å¢žåŠ "
-"输入。"
+"返回å称为 [code]id[/code] 的过渡节点的输入数。你å¯ä»¥é€šè¿‡å³é”®ç‚¹å‡»è¿‡æ¸¡èŠ‚ç‚¹æ¥å¢ž"
+"加输入。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Returns the cross fade time for the transition node with name [code]id[/"
"code]."
-msgstr "返回å称为[code]id[/code]çš„è¿‡æ¸¡èŠ‚ç‚¹çš„äº¤å‰æ·¡åŒ–时间。"
+msgstr "返回å称为 [code]id[/code] çš„è¿‡æ¸¡èŠ‚ç‚¹çš„äº¤å‰æ·¡åŒ–时间。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
@@ -7745,8 +7750,8 @@ msgid ""
"transition node with name [code]id[/code] is set to automatically advance to "
"the next input upon completion."
msgstr ""
-"如果过渡节点上å称为[code]id[/code]çš„[code]input_idx[/code]的输入被设置为在完"
-"æˆåŽè‡ªåЍå‰è¿›åˆ°ä¸‹ä¸€ä¸ªè¾“入,则返回 [code]true[/code]。"
+"如果过渡节点上å称为 [code]id[/code] çš„[code]input_idx[/code]的输入被设置为在"
+"完æˆåŽè‡ªåЍå‰è¿›åˆ°ä¸‹ä¸€ä¸ªè¾“入,则返回 [code]true[/code]。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
@@ -7760,26 +7765,27 @@ msgid ""
"The transition node with name [code]id[/code] advances to its next input "
"automatically when the input at [code]input_idx[/code] completes."
msgstr ""
-"当[code]input_idx[/code]处的输入完æˆåŽï¼Œå称为[code]id[/code]的过渡节点自动进"
-"行到下一个输入。"
+"当[code]input_idx[/code]处的输入完æˆåŽï¼Œå称为 [code]id[/code] 的过渡节点自动"
+"进行到下一个输入。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"Resizes the number of inputs available for the transition node with name "
"[code]id[/code]."
-msgstr "调整å称为[code]id[/code]的过渡节点的å¯ç”¨è¾“入数。"
+msgstr "调整å称为 [code]id[/code] 的过渡节点的å¯ç”¨è¾“入数。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"The transition node with name [code]id[/code] sets its cross fade time to "
"[code]time_sec[/code]."
msgstr ""
-"å称为[code]id[/code]çš„è¿‡æ¸¡èŠ‚ç‚¹å°†å…¶äº¤å‰æ·¡åŒ–时间设置为[code]time_sec[/code]。"
+"å称为 [code]id[/code] çš„è¿‡æ¸¡èŠ‚ç‚¹å°†å…¶äº¤å‰æ·¡åŒ–时间设置为[code]time_sec[/"
+"code]。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
"If [code]true[/code], the [AnimationTreePlayer] is able to play animations."
-msgstr "如果[code]true[/code],[AnimationTreePlayer]就能够播放动画。"
+msgstr "如果为 [code]true[/code],[AnimationTreePlayer]就能够播放动画。"
#: doc/classes/AnimationTreePlayer.xml
msgid ""
@@ -7810,11 +7816,11 @@ msgstr "输出节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Animation node."
-msgstr "Animation节点。"
+msgstr "Animation 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "OneShot node."
-msgstr "OneShot节点。"
+msgstr "OneShot 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Mix node."
@@ -7822,31 +7828,31 @@ msgstr "Mix 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Blend2 node."
-msgstr "Blend2节点。"
+msgstr "Blend2 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Blend3 node."
-msgstr "Blend3节点。"
+msgstr "Blend3 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Blend4 node."
-msgstr "Blend4节点。"
+msgstr "Blend4 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "TimeScale node."
-msgstr "TimeScale节点。"
+msgstr "TimeScale 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "TimeSeek node."
-msgstr "TimeSeek节点。"
+msgstr "TimeSeek 节点。"
#: doc/classes/AnimationTreePlayer.xml
msgid "Transition node."
-msgstr "Transition节点。"
+msgstr "Transition 节点。"
#: doc/classes/Area.xml
msgid "3D area for detection and physics and audio influence."
-msgstr "用于检测和物ç†åŠéŸ³é¢‘å½±å“çš„3D区域。"
+msgstr "用于检测和物ç†åŠéŸ³é¢‘å½±å“çš„ 3D 区域。"
#: doc/classes/Area.xml
msgid ""
@@ -7854,8 +7860,8 @@ msgid ""
"exiting. Can also alter or override local physics parameters (gravity, "
"damping) and route audio to custom audio buses."
msgstr ""
-"检测[CollisionObject]节点é‡å ã€è¿›å…¥æˆ–退出的3D区域。还å¯ä»¥æ”¹å˜æˆ–覆盖局部物ç†å‚"
-"数(é‡åŠ›ã€é˜»å°¼ï¼‰ï¼Œå¹¶å°†éŸ³é¢‘路由到自定义音频总线。"
+"检测 [CollisionObject] 节点é‡å ã€è¿›å…¥æˆ–退出的 3D 区域。还å¯ä»¥æ”¹å˜æˆ–覆盖局部物"
+"ç†å‚数(é‡åŠ›ã€é˜»å°¼ï¼‰ï¼Œå¹¶å°†éŸ³é¢‘路由到自定义音频总线。"
#: doc/classes/Area.xml doc/classes/QuadMesh.xml doc/classes/Viewport.xml
#: doc/classes/ViewportTexture.xml
@@ -7871,9 +7877,9 @@ msgid ""
"list is modified once during the physics step, not immediately after objects "
"are moved. Consider using signals instead."
msgstr ""
-"返回相交的[Area]的列表。é‡å åŒºåŸŸçš„[member CollisionObject.collision_layer]å¿…"
-"须是这个区域[member CollisionObject.collision_mask]的一部分,这样æ‰èƒ½è¢«æ£€æµ‹"
-"到。\n"
+"返回相交的 [Area] 的列表。é‡å åŒºåŸŸçš„ [member CollisionObject."
+"collision_layer] 必须是这个区域 [member CollisionObject.collision_mask] 的一"
+"部分,这样æ‰èƒ½è¢«æ£€æµ‹åˆ°ã€‚\n"
"å‡ºäºŽæ€§èƒ½çš„è€ƒè™‘ï¼Œå› ç¢°æ’žéƒ½æ˜¯åŒæ—¶å¤„ç†çš„ï¼Œè¿™ä¸ªåˆ—è¡¨åœ¨ç‰©ç†æ­¥éª¤ä¸­åªä¿®æ”¹ä¸€æ¬¡ï¼Œè€Œä¸æ˜¯"
"在物体被移动åŽç«‹å³ä¿®æ”¹ã€‚è€ƒè™‘ä½¿ç”¨ä¿¡å·æ¥ä»£æ›¿ã€‚"
@@ -7886,9 +7892,9 @@ msgid ""
"list is modified once during the physics step, not immediately after objects "
"are moved. Consider using signals instead."
msgstr ""
-"返回相交的[PhysicsBody]的列表。é‡å ç‰©ä½“çš„[member CollisionObject."
-"collision_layer]必须是这个区域[member CollisionObject.collision_mask]的一部"
-"分,这样æ‰èƒ½è¢«æ£€æµ‹åˆ°ã€‚\n"
+"返回相交的 [PhysicsBody] 的列表。é‡å ç‰©ä½“çš„ [member CollisionObject."
+"collision_layer] 必须是这个区域 [member CollisionObject.collision_mask] 的一"
+"部分,这样æ‰èƒ½è¢«æ£€æµ‹åˆ°ã€‚\n"
"å‡ºäºŽæ€§èƒ½çš„è€ƒè™‘ï¼Œå› ç¢°æ’žéƒ½æ˜¯åŒæ—¶å¤„ç†çš„ï¼Œè¿™ä¸ªåˆ—è¡¨åœ¨ç‰©ç†æ­¥éª¤ä¸­åªä¿®æ”¹ä¸€æ¬¡ï¼Œè€Œä¸æ˜¯"
"在物体被移动åŽç«‹å³ä¿®æ”¹ã€‚è€ƒè™‘ä½¿ç”¨ä¿¡å·æ¥ä»£æ›¿ã€‚"
@@ -7899,7 +7905,7 @@ msgid ""
"For performance, list of overlaps is updated once per frame and before the "
"physics step. Consider using signals instead."
msgstr ""
-"如果 [code]true[/code],则给定区域与该区域é‡å .\n"
+"如果为 [code]true[/code],则给定区域与该区域é‡å .\n"
"[b]注æ„:[/b]在移动物体åŽï¼Œè¿™ä¸ªæµ‹è¯•çš„ç»“æžœä¸æ˜¯å³æ—¶çš„。为了性能,é‡å åˆ—表在æ¯ä¸€"
"å¸§å’Œç‰©ç†æ­¥éª¤ä¹‹å‰æ›´æ–°ä¸€æ¬¡ã€‚å¯ä»¥è€ƒè™‘用信å·ä»£æ›¿ã€‚"
@@ -7916,8 +7922,8 @@ msgstr ""
"如果为 [code]true[/code],则给定的物ç†ä½“与该区域é‡å .\n"
"[b]注æ„:[/b]在移动物体åŽï¼Œè¿™ä¸ªæµ‹è¯•çš„ç»“æžœä¸æ˜¯å³æ—¶çš„。为了æé«˜æ€§èƒ½ï¼Œé‡å åˆ—表在"
"æ¯ä¸€å¸§å’Œç‰©ç†æ­¥éª¤ä¹‹å‰æ›´æ–°ä¸€æ¬¡ã€‚å¯ä»¥è€ƒè™‘ä½¿ç”¨ä¿¡å·æ¥ä»£æ›¿ã€‚\n"
-"[code]body[/code]傿•°å¯ä»¥æ˜¯ä¸€ä¸ª[PhysicsBody]或一个[GridMap]实例(虽然GridMaps"
-"æœ¬èº«ä¸æ˜¯ç‰©ç†ä½“,但它们用碰撞形状注册它们的瓦片(tiles)作为一个虚拟物ç†ä½“)。"
+"[code]body[/code] 傿•°å¯ä»¥æ˜¯ [PhysicsBody] 或 [GridMap] 实例(虽然 GridMap 本"
+"èº«ä¸æ˜¯ç‰©ç†ä½“,但它们用碰撞形状注册它们的图å—作为一个虚拟物ç†ä½“)。"
#: doc/classes/Area.xml
msgid ""
@@ -7937,7 +7943,7 @@ msgstr "该区域音频总线的å称。"
#: doc/classes/Area.xml doc/classes/Area2D.xml
msgid ""
"If [code]true[/code], the area's audio bus overrides the default audio bus."
-msgstr "为 [code]true[/code] 时该区域的音频总线将覆盖默认的音频总线。"
+msgstr "如果为 [code]true[/code],该区域的音频总线将覆盖默认的音频总线。"
#: doc/classes/Area.xml
msgid ""
@@ -7959,7 +7965,7 @@ msgid ""
"If [code]true[/code], gravity is calculated from a point (set via [member "
"gravity_vec]). See also [member space_override]."
msgstr ""
-"如果 [code]true[/code],则从一个点计算é‡åŠ›ï¼ˆé€šè¿‡ [member gravity_vec] 设"
+"如果为 [code]true[/code],则从一个点计算é‡åŠ›ï¼ˆé€šè¿‡ [member gravity_vec] 设"
"置)。å‚阅 [member space_override]。"
#: doc/classes/Area.xml doc/classes/Area2D.xml
@@ -7967,8 +7973,8 @@ msgid ""
"The area's gravity vector (not normalized). If gravity is a point (see "
"[member gravity_point]), this will be the point of attraction."
msgstr ""
-"区域的未归一化的é‡åŠ›å‘é‡ã€‚如果é‡åŠ›ä½œç”¨åœ¨ä¸€ä¸ªç‚¹ä¸Šï¼Œåˆ™å®ƒå°†æ˜¯å¼•åŠ›ç‚¹ã€‚è¯·å‚阅 "
-"[member gravity_point]。"
+"区域的未归一化的é‡åŠ›å‘é‡ã€‚如果é‡åŠ›ä½œç”¨åœ¨ä¸€ä¸ªç‚¹ä¸Šï¼Œåˆ™å®ƒå°†æ˜¯å¼•åŠ›ç‚¹ï¼ˆè§ [member "
+"gravity_point])。"
#: doc/classes/Area.xml
msgid ""
@@ -7983,13 +7989,14 @@ msgstr ""
#: doc/classes/Area.xml doc/classes/Area2D.xml
msgid "If [code]true[/code], other monitoring areas can detect this area."
-msgstr "为 [code]true[/code] 时其他监测区域å¯ä»¥æ£€æµ‹åˆ°è¿™ä¸ªåŒºåŸŸã€‚"
+msgstr "如果为 [code]true[/code],其他监测区域å¯ä»¥æ£€æµ‹åˆ°è¿™ä¸ªåŒºåŸŸã€‚"
#: doc/classes/Area.xml doc/classes/Area2D.xml
msgid ""
"If [code]true[/code], the area detects bodies or areas entering and exiting "
"it."
-msgstr "为 [code]true[/code] 时该区域能够检测到进入和退出该区域的实体或区域。"
+msgstr ""
+"如果为 [code]true[/code],该区域能够检测到进入和退出该区域的实体或区域。"
#: doc/classes/Area.xml doc/classes/Area2D.xml
msgid "The area's priority. Higher priority areas are processed first."
@@ -8005,7 +8012,7 @@ msgstr ""
#: doc/classes/Area.xml
msgid "If [code]true[/code], the area applies reverb to its associated audio."
-msgstr "为 [code]true[/code] 时该区域会将混å“应用于其相关音频。"
+msgstr "如果为 [code]true[/code],该区域会将混å“应用于其相关音频。"
#: doc/classes/Area.xml
msgid "The reverb bus name to use for this area's associated audio."
@@ -8023,7 +8030,7 @@ msgstr ""
msgid ""
"Override mode for gravity and damping calculations within this area. See "
"[enum SpaceOverride] for possible values."
-msgstr "该区域内é‡åŠ›å’Œé˜»å°¼è®¡ç®—çš„è¦†ç›–æ¨¡å¼ã€‚å¯èƒ½çš„值è§[enum SpaceOverride]。"
+msgstr "该区域内é‡åŠ›å’Œé˜»å°¼è®¡ç®—çš„è¦†ç›–æ¨¡å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum SpaceOverride]。"
#: doc/classes/Area.xml
msgid ""
@@ -8079,11 +8086,11 @@ msgid ""
"[code]body[/code] the [Node], if it exists in the tree, of the other "
"[PhysicsBody] or [GridMap]."
msgstr ""
-"当[PhysicsBody]或[GridMap]进入这个区域时å‘出的。需è¦å°†ç›‘控[member monitoring]"
-"设置为 [code]true[/code]。如果[MeshLibrary]有碰撞形状[Shape],就会检测到"
-"[GridMap]。\n"
-"[code]body[/code], 如果它存在于场景树中, 是å¦ä¸€ä¸ª[PhysicsBody]或[GridMap]节点"
-"[Node]。"
+"当 [PhysicsBody] 或 [GridMap] 进入这个区域时å‘出的。需è¦å°† [member "
+"monitoring] 设置为 [code]true[/code]。如果 [MeshLibrary] 有碰撞形状 [Shape],"
+"就会检测到 [GridMap]。\n"
+"[code]body[/code], 如果它存在于场景树中, 是å¦ä¸€ä¸ª [PhysicsBody] 或 [GridMap] "
+"节点 [Node]。"
#: doc/classes/Area.xml
msgid ""
@@ -8093,11 +8100,11 @@ msgid ""
"[code]body[/code] the [Node], if it exists in the tree, of the other "
"[PhysicsBody] or [GridMap]."
msgstr ""
-"当[PhysicsBody]或[GridMap]离开这个Areaæ—¶å‘出的。需è¦å°†ç›‘控[member monitoring]"
-"设置为 [code]true[/code]。如果[MeshLibrary]有碰撞形状[Shape],就会检测到"
-"[GridMap]。\n"
-"[code]body[/code], 如果它存在于场景树中, 是其他[PhysicsBody]或[GridMap]的"
-"[Node]。"
+"当 [PhysicsBody] 或 [GridMap] 离开这个 Area æ—¶å‘出的。需è¦å°† [member "
+"monitoring] 设置为 [code]true[/code]。如果 [MeshLibrary] 有碰撞形状 [Shape],"
+"就会检测到 [GridMap]。\n"
+"[code]body[/code], 如果它存在于场景树中, 是其他 [PhysicsBody] 或 [GridMap] "
+"的 [Node]。"
#: doc/classes/Area.xml
msgid ""
@@ -8115,18 +8122,19 @@ msgid ""
"the [PhysicsServer]. Get the [CollisionShape] node with [code]self."
"shape_owner_get_owner(local_shape_index)[/code]."
msgstr ""
-"当[PhysicsBody]或[GridMap]的一个[Shape]进入这个区域的一个[Shape]时触å‘。需è¦"
-"将[member monitoring]设置为 [code]true[/code]。如果[MeshLibrary]有碰撞"
-"[Shape],就会检测到[GridMap]。\n"
-"[code]body_rid[/code] [PhysicsServer]使用的[PhysicsBody]或[MeshLibrary]的"
-"[CollisionObject]的[RID]。\n"
-"[code]body[/code] [PhysicsBody]或[GridMap]çš„[Node],如果它存在于树中的è¯ã€‚\n"
-"[code]body_shape_index[/code] [PhysicsServer]使用的[PhysicsBody]或[GridMap]的"
-"[Shape]的索引。用[code]body.shape_owner_get_owner(body_shape_index)[/code]获"
-"å–[CollisionShape]节点。\n"
-"[code]local_shape_index[/code]这个区域的[Shape]的索引,由[PhysicsServer]使"
-"用。用[code]self.shape_owner_get_owner(local_shape_index)[/code]获得"
-"[CollisionShape]节点。"
+"当 [PhysicsBody] 或 [GridMap] 的一个 [Shape] 进入这个区域的一个 [Shape] 时触"
+"å‘。需è¦å°† [member monitoring] 设置为 [code]true[/code]。如果 [MeshLibrary] "
+"有碰撞 [Shape],就会检测到 [GridMap]。\n"
+"[code]body_rid[/code] [PhysicsServer] 使用的 [PhysicsBody] 或 [MeshLibrary] "
+"的 [CollisionObject] 的 [RID]。\n"
+"[code]body[/code] [PhysicsBody] 或 [GridMap] 的 [Node],如果它存在于树中的"
+"è¯ã€‚\n"
+"[code]body_shape_index[/code] [PhysicsServer] 使用的 [PhysicsBody] 或 "
+"[GridMap] 的 [Shape]的索引。用 [code]body."
+"shape_owner_get_owner(body_shape_index)[/code] èŽ·å– [CollisionShape] 节点。\n"
+"[code]local_shape_index[/code] 这个区域的 [Shape] 的索引,由 [PhysicsServer] "
+"使用。用 [code]self.shape_owner_get_owner(local_shape_index)[/code] 获得 "
+"[CollisionShape] 节点。"
#: doc/classes/Area.xml doc/classes/Area2D.xml
msgid "This area does not affect gravity/damping."
@@ -8172,8 +8180,8 @@ msgid ""
"exiting. Can also alter or override local physics parameters (gravity, "
"damping) and route audio to a custom audio bus."
msgstr ""
-"检测[CollisionObject2D]节点é‡å ã€è¿›å…¥æˆ–退出的2D区域。还å¯ä»¥æ”¹å˜æˆ–覆盖局部物ç†"
-"傿•°ï¼ˆé‡åŠ›ã€é˜»å°¼ï¼‰ï¼Œå¹¶å°†éŸ³é¢‘路由到一个自定义的音频总线。"
+"检测 [CollisionObject2D] 节点é‡å ã€è¿›å…¥æˆ–退出的2D区域。还å¯ä»¥æ”¹å˜æˆ–覆盖局部物"
+"ç†å‚数(é‡åŠ›ã€é˜»å°¼ï¼‰ï¼Œå¹¶å°†éŸ³é¢‘路由到一个自定义的音频总线。"
#: doc/classes/Area2D.xml
msgid "Using Area2D"
@@ -8227,7 +8235,7 @@ msgid ""
"For performance, the list of overlaps is updated once per frame and before "
"the physics step. Consider using signals instead."
msgstr ""
-"如果 [code]true[/code],则给定区域与该区域é‡å ã€‚\n"
+"如果为 [code]true[/code],则给定区域与该区域é‡å ã€‚\n"
"[b]注æ„:[/b]在移动物体åŽï¼Œè¿™ä¸ªæµ‹è¯•çš„ç»“æžœä¸æ˜¯å³æ—¶çš„。为了性能,é‡å åˆ—表在æ¯ä¸€"
"å¸§å’Œç‰©ç†æ­¥éª¤ä¹‹å‰æ›´æ–°ä¸€æ¬¡ã€‚å¯ä»¥è€ƒè™‘用信å·ä»£æ›¿ã€‚"
@@ -8241,11 +8249,11 @@ msgid ""
"[TileMap] instance (while TileMaps are not physics bodies themselves, they "
"register their tiles with collision shapes as a virtual physics body)."
msgstr ""
-"如果[code]true[/code],给定的物ç†ä½“就与Area2Då‘生é‡å ã€‚\n"
+"如果为 [code]true[/code],给定的物ç†ä½“就与 Area2D å‘生é‡å ã€‚\n"
"[b]注æ„:[/b]在移动物体åŽï¼Œè¿™ä¸ªæµ‹è¯•çš„ç»“æžœä¸æ˜¯å³æ—¶çš„。为了性能,é‡å åˆ—表在æ¯ä¸€"
"å¸§å’Œç‰©ç†æ­¥éª¤ä¹‹å‰æ›´æ–°ä¸€æ¬¡ã€‚å¯ä»¥è€ƒè™‘ä½¿ç”¨ä¿¡å·æ¥ä»£æ›¿ã€‚\n"
-"[code]body[/code]傿•°å¯ä»¥æ˜¯ä¸€ä¸ª[PhysicsBody2D]或一个[TileMap]实例(虽然"
-"TileMapsæœ¬èº«ä¸æ˜¯ç‰©ç†ä½“,但它们用碰撞形状注册它们的瓦片作为一个虚拟物ç†ä½“)。"
+"[code]body[/code] 傿•°å¯ä»¥æ˜¯ [PhysicsBody2D] 或 [TileMap] 实例(虽然 TileMap "
+"æœ¬èº«ä¸æ˜¯ç‰©ç†ä½“,但它们用碰撞形状注册它们的图å—作为一个虚拟物ç†ä½“)。"
#: doc/classes/Area2D.xml
msgid ""
@@ -8284,9 +8292,9 @@ msgid ""
"to be set to [code]true[/code].\n"
"[code]area[/code] the other Area2D."
msgstr ""
-"当å¦ä¸€ä¸ªArea2D进入这个Area2Dæ—¶å‘出的。需è¦å°†ç›‘控[member monitoring]设置为 "
+"当å¦ä¸€ä¸ª Area2D 进入这个 Area2D æ—¶å‘出的。需è¦å°† [member monitoring] 设置为 "
"[code]true[/code]。\n"
-"[code]area[/code]傿•°æ˜¯å…¶ä»–Area2D。"
+"[code]area[/code] 傿•°æ˜¯å¯¹æ–¹ Area2D。"
#: doc/classes/Area2D.xml
msgid ""
@@ -8294,9 +8302,9 @@ msgid ""
"to be set to [code]true[/code].\n"
"[code]area[/code] the other Area2D."
msgstr ""
-"当å¦ä¸€ä¸ªArea2D离开这个Area2Dæ—¶å‘å‡ºçš„ã€‚è¦æ±‚监控[member monitoring]被设置为 "
+"当å¦ä¸€ä¸ª Area2D 离开这个 Area2D æ—¶å‘å‡ºçš„ã€‚è¦æ±‚ [member monitoring] 被设置为 "
"[code]true[/code]。\n"
-"[code]area[/code]傿•°æ˜¯å…¶ä»–Area2D。"
+"[code]area[/code] 傿•°æ˜¯å¯¹æ–¹ Area2D。"
#: doc/classes/Area2D.xml
msgid ""
@@ -8312,17 +8320,18 @@ msgid ""
"used by the [Physics2DServer]. Get the [CollisionShape2D] node with "
"[code]self.shape_owner_get_owner(local_shape_index)[/code]."
msgstr ""
-"当å¦ä¸€ä¸ªArea2Dçš„[Shape2D]进入此Area2Dçš„[Shape2D]时触å‘。需è¦å°† [member "
-"monitoring] 设置为 [code]true[/code]。\n"
-"[code]area_rid[/code] 由[Physics2DServer]使用的其他Area2D的"
-"[CollisionObject2D]的[RID]。\n"
-"[code]area[/code] 其他Area2D。\n"
-"[code]area_shape_index[/code][Physics2DServer]使用的其他Area2D的[Shape2D]的索"
-"引。用[code]area.shape_owner_get_owner(area_shape_index)[/code]获得"
-"[CollisionShape2D]节点。\n"
-"[code]local_shape_index[/code]此Area2D的[Shape2D]的索引,由[Physics2DServer]"
-"使用。用[code]self.shape_owner_get_owner(local_shape_index)[/code]获å–"
-"[CollisionShape2D]节点。"
+"当å¦ä¸€ä¸ª Area2D çš„ [Shape2D] 进入这个 Area2D çš„æŸä¸ª [Shape2D] 时触å‘ã€‚è¦æ±‚ "
+"[member monitoring] 设置为 [code]true[/code]。\n"
+"[code]area_rid[/code] 由 [Physics2DServer] 使用的对方 Area2D 的 "
+"[CollisionObject2D] 的 [RID]。\n"
+"[code]area[/code] 对方 Area2D。\n"
+"[code]area_shape_index[/code] [Physics2DServer] 使用的对方 Area2D 的 "
+"[Shape2D] 的索引。用 [code]area.shape_owner_get_owner(area_shape_index)[/"
+"code] 获得 [CollisionShape2D] 节点。\n"
+"[code]local_shape_index[/code] 此 Area2D 的 [Shape2D] 的索引,由 "
+"[Physics2DServer] 使用。用 [code]self."
+"shape_owner_get_owner(local_shape_index)[/code] èŽ·å– [CollisionShape2D] 节"
+"点。"
#: doc/classes/Area2D.xml
msgid ""
@@ -8338,17 +8347,18 @@ msgid ""
"used by the [Physics2DServer]. Get the [CollisionShape2D] node with "
"[code]self.shape_owner_get_owner(local_shape_index)[/code]."
msgstr ""
-"当å¦ä¸€ä¸ªArea2Dçš„[Shape2D]退出这个Area2Dçš„[Shape2D]之一时触å‘ã€‚è¦æ±‚[member "
-"monitoring] 被设置为 [code]true[/code]。\n"
-"[code]area_rid[/code] 由[Physics2DServer]使用的其他Area2D的"
-"[CollisionObject2D]的[RID]。\n"
-"[code]area[/code] 其他Area2D。\n"
-"[code]area_shape_index[/code][Physics2DServer]使用的其他Area2D的[Shape2D]的索"
-"引。用[code]area.shape_owner_get_owner(area_shape_index)[/code]获å–"
-"[CollisionShape2D]节点。\n"
-"[code]local_shape_index[/code]这个Area2D的[Shape2D]的索引,由"
-"[Physics2DServer]使用。用[code]self.shape_owner_get_owner(local_shape_index)"
-"[/code]获得[CollisionShape2D]节点。"
+"当å¦ä¸€ä¸ª Area2D çš„ [Shape2D] 退出这个 Area2D çš„æŸä¸ª [Shape2D] 时触å‘ã€‚è¦æ±‚ "
+"[member monitoring] 设置为 [code]true[/code]。\n"
+"[code]area_rid[/code] 由 [Physics2DServer] 使用的对方 Area2D 的 "
+"[CollisionObject2D] 的 [RID]。\n"
+"[code]area[/code] 对方 Area2D。\n"
+"[code]area_shape_index[/code] [Physics2DServer] 使用的对方 Area2D 的 "
+"[Shape2D] 的索引。用 [code]area.shape_owner_get_owner(area_shape_index)[/"
+"code] èŽ·å– [CollisionShape2D] 节点。\n"
+"[code]local_shape_index[/code] 这个 Area2D 的 [Shape2D] 的索引,由 "
+"[Physics2DServer] 使用。用 [code]self."
+"shape_owner_get_owner(local_shape_index)[/code] 获得 [CollisionShape2D] 节"
+"点。"
#: doc/classes/Area2D.xml
msgid ""
@@ -8358,11 +8368,11 @@ msgid ""
"[code]body[/code] the [Node], if it exists in the tree, of the other "
"[PhysicsBody2D] or [TileMap]."
msgstr ""
-"当一个[PhysicsBody2D]或[TileMap]进入这个Area2Dæ—¶å‘出的。需è¦å°†ç›‘控[member "
-"monitoring]设置为 [code]true[/code]。如果[TileSet]有碰撞形状[Shape2D],则检测"
-"到[TileMap]。\n"
-"[code]body[/code]傿•°æ˜¯å…¶ä»–[PhysicsBody2D]或[TileMap]çš„[Node],如果它存在于树"
-"中。"
+"当一个 [PhysicsBody2D] 或 [TileMap] 进入这个 Area2D æ—¶å‘出的。需è¦å°† [member "
+"monitoring] 设置为 [code]true[/code]。如果 [TileSet] 有碰撞形状 [Shape2D],则"
+"检测到 [TileMap]。\n"
+"[code]body[/code] 傿•°æ˜¯å…¶ä»– [PhysicsBody2D] 或 [TileMap] çš„ [Node],如果它存"
+"在于树中。"
#: doc/classes/Area2D.xml
msgid ""
@@ -8396,19 +8406,20 @@ msgid ""
"used by the [Physics2DServer]. Get the [CollisionShape2D] node with "
"[code]self.shape_owner_get_owner(local_shape_index)[/code]."
msgstr ""
-"当[PhysicsBody2D]或[TileMap]的[Shape2D]之一进入此Area2D的[Shape2D]之一时触"
-"å‘。需è¦å°†[member monitoring]设置为 [code]true[/code]。如果[TileSet]有"
-"Collision[Shape2D],就会检测到[TileMap]。\n"
-"[code]body_rid[/code] [Physics2DServer]使用的[PhysicsBody2D]或[TileSet]的"
-"[CollisionObject2D]的[RID]。\n"
-"[code]body[/code] [PhysicsBody2D]或[TileMap]的[Node],如果它在树上存在的"
+"当 [PhysicsBody2D] 或 [TileMap] 的 [Shape2D] 之一进入此 Area2D 的 [Shape2D] "
+"之一时触å‘。需è¦å°† [member monitoring] 设置为 [code]true[/code]。如果 "
+"[TileSet] 有 Collision [Shape2D],就会检测到 [TileMap]。\n"
+"[code]body_rid[/code] [Physics2DServer] 使用的 [PhysicsBody2D] 或 [TileSet] "
+"的 [CollisionObject2D] 的 [RID]。\n"
+"[code]body[/code] [PhysicsBody2D] 或 [TileMap] 的 [Node],如果它在树上存在的"
"è¯ã€‚\n"
-"[code]body_shape_index[/code] [Physics2DServer]使用的[PhysicsBody2D]或"
-"[TileMap]的[Shape2D]的索引。用[code]body."
-"shape_owner_get_owner(body_shape_index)[/code]获得[CollisionShape2D]节点。\n"
-"[code]local_shape_index[/code]此Area2D的[Shape2D]的索引,由[Physics2DServer]"
-"使用。用[code]self.shape_owner_get_owner(local_shape_index)[/code]获得"
-"[CollisionShape2D]节点。"
+"[code]body_shape_index[/code] [Physics2DServer] 使用的 [PhysicsBody2D] 或 "
+"[TileMap] 的 [Shape2D] 的索引。用[code]body."
+"shape_owner_get_owner(body_shape_index)[/code] 获得 [CollisionShape2D] 节"
+"点。\n"
+"[code]local_shape_index[/code] 这个 Area2D 的 [Shape2D] 的索引,由 "
+"[Physics2DServer] 使用。用[code]self.shape_owner_get_owner(local_shape_index)"
+"[/code]获得[CollisionShape2D]节点。"
#: doc/classes/Area2D.xml
msgid ""
@@ -8428,19 +8439,20 @@ msgid ""
"used by the [Physics2DServer]. Get the [CollisionShape2D] node with "
"[code]self.shape_owner_get_owner(local_shape_index)[/code]."
msgstr ""
-"当[PhysicsBody2D]或[TileMap]的一个[Shape2D]退出这个Area2D的一个[Shape2D]æ—¶å‘"
-"出的。需è¦å°†[member monitoring]设置为 [code]true[/code]。如果[TileSet]有碰撞"
-"[Shape2D],就会检测到[TileMap]。\n"
-"[code]body_rid[/code] 是[Physics2DServer]使用的[PhysicsBody2D]或[TileSet]的"
-"[CollisionObject2D]的[RID]。\n"
-"[code]body[/code] [PhysicsBody2D]或[TileMap]的[Node],如果它在树上存在的"
+"当 [PhysicsBody2D] 或 [TileMap] 的一个 [Shape2D] 退出这个 Area2D 的一个 "
+"[Shape2D] æ—¶å‘出的。需è¦å°† [member monitoring] 设置为 [code]true[/code]。如果"
+"[TileSet] 有碰撞 [Shape2D],就会检测到 [TileMap]。\n"
+"[code]body_rid[/code] 是[Physics2DServer] 使用的 [PhysicsBody2D] 或 "
+"[TileSet] 的 [CollisionObject2D] 的 [RID]。\n"
+"[code]body[/code] [PhysicsBody2D] 或 [TileMap] 的 [Node],如果它在树上存在的"
"è¯ã€‚\n"
-"[code]body_shape_index[/code] [Physics2DServer]使用的[PhysicsBody2D]或"
-"[TileMap]的[Shape2D]的索引。用[code]body."
-"shape_owner_get_owner(body_shape_index)[/code]获å–[CollisionShape2D]节点。\n"
-"[code]local_shape_index[/code]此Area2D的[Shape2D]的索引,由[Physics2DServer]"
-"使用。用[code]self.shape_owner_get_owner(local_shape_index)[/code]获å–"
-"[CollisionShape2D]节点。"
+"[code]body_shape_index[/code] [Physics2DServer] 使用的 [PhysicsBody2D] 或 "
+"[TileMap] 的 [Shape2D]的索引。用[code]body."
+"shape_owner_get_owner(body_shape_index)[/code] èŽ·å– [CollisionShape2D] 节"
+"点。\n"
+"[code]local_shape_index[/code] 这个 Area2D 的 [Shape2D] 的索引,由 "
+"[Physics2DServer] 使用。用 [code]self."
+"shape_owner_get_owner(local_shape_index)[/code]获å–[CollisionShape2D]节点。"
#: doc/classes/Array.xml
msgid "A generic array datatype."
@@ -8659,7 +8671,7 @@ msgstr ""
msgid ""
"Clears the array. This is equivalent to using [method resize] with a size of "
"[code]0[/code]."
-msgstr "清空数组。与调用 [method resize] 时指定大å°ä¸º [code]0[/code] 等价。"
+msgstr "清空数组。相当于调用 [method resize] 时指定大å°ä¸º [code]0[/code]。"
#: doc/classes/Array.xml doc/classes/PoolByteArray.xml
#: doc/classes/PoolColorArray.xml doc/classes/PoolIntArray.xml
@@ -8781,7 +8793,7 @@ msgstr ""
"[\"inside\", 7].has(7) # True\n"
"[\"inside\", 7].has(\"7\") # False\n"
"[/codeblock]\n"
-"[b]注æ„:[/b]这等åŒäºŽä½¿ç”¨ [code]in[/code] æ“作符,如下所示。\n"
+"[b]注æ„:[/b]相当于使用 [code]in[/code] æ“作符,如下所示。\n"
"[codeblock]\n"
"# 将评估为 `true`。\n"
"if 2 in [2, 4, 6, 8]:\n"
@@ -8854,13 +8866,13 @@ msgid ""
"removed element. The larger the array and the lower the index of the removed "
"element, the slower [method pop_at] will be."
msgstr ""
-"移除并返回索引[code]position[/code]处的数组元素。如果是负数,[code]position[/"
-"code]被认为是相对于数组的末端。如果数组是空的或者被越界访问,则ä¿ç•™æ•°ç»„ä¸åŠ¨ï¼Œ"
-"并返回 [code]null[/code]。当数组被越界访问时,会打å°å‡ºä¸€æ¡é”™è¯¯ä¿¡æ¯ï¼Œä½†å½“数组"
-"为空时,则ä¸ä¼šã€‚\n"
-"[b]注æ„:[/b]在大的数组上,这个方法å¯èƒ½æ¯”[method pop_back]æ…¢ï¼Œå› ä¸ºå®ƒå°†é‡æ–°ç´¢"
-"引ä½äºŽè¢«ç§»é™¤å…ƒç´ ä¹‹åŽçš„æ•°ç»„元素。数组越大,被移除元素的索引越低,[method "
-"pop_at]的速度就越慢。"
+"移除并返回索引 [code]position[/code] 处的数组元素。如果是负数,会认为 "
+"[code]position[/code] 是相对于数组的末端。如果数组是空的或者被越界访问,则ä¿"
+"留数组ä¸åŠ¨ï¼Œå¹¶è¿”å›ž [code]null[/code]。当数组被越界访问时,会打å°å‡ºä¸€æ¡é”™è¯¯ä¿¡"
+"æ¯ï¼Œä½†å½“数组为空时,则ä¸ä¼šã€‚\n"
+"[b]注æ„:[/b]在大的数组上,这个方法å¯èƒ½æ¯” [method pop_back] æ…¢ï¼Œå› ä¸ºå®ƒå°†é‡æ–°"
+"索引ä½äºŽè¢«ç§»é™¤å…ƒç´ ä¹‹åŽçš„æ•°ç»„元素。数组越大,被移除元素的索引越低,[method "
+"pop_at] 的速度就越慢。"
#: doc/classes/Array.xml
msgid ""
@@ -8868,7 +8880,7 @@ msgid ""
"if the array is empty, without printing an error message. See also [method "
"pop_front]."
msgstr ""
-"删除并返回数组中的末尾元素。数组为空时,返回 [code]null[/code]。å¦è¯·å‚阅 "
+"移除并返回数组中的末尾元素。数组为空时,返回 [code]null[/code]。å¦è¯·å‚阅 "
"[method pop_front]。"
#: doc/classes/Array.xml
@@ -9128,11 +9140,11 @@ msgstr ""
#: doc/classes/ArrayMesh.xml
msgid "Removes all blend shapes from this [ArrayMesh]."
-msgstr "删除此[ArrayMesh]的所有混åˆå½¢çŠ¶ã€‚"
+msgstr "移除此 [ArrayMesh] 的所有混åˆå½¢çŠ¶ã€‚"
#: doc/classes/ArrayMesh.xml
msgid "Removes all surfaces from this [ArrayMesh]."
-msgstr "删除此[ArrayMesh]的所有表é¢ã€‚"
+msgstr "移除此 [ArrayMesh] 的所有表é¢ã€‚"
#: doc/classes/ArrayMesh.xml
msgid "Returns the number of blend shapes that the [ArrayMesh] holds."
@@ -9146,25 +9158,25 @@ msgstr "返回此索引处的混åˆå½¢çŠ¶çš„å称。"
msgid ""
"Will perform a UV unwrap on the [ArrayMesh] to prepare the mesh for "
"lightmapping."
-msgstr "将在[ArrayMesh]上执行UV展开,以准备用于光照贴图的网格。"
+msgstr "将在 [ArrayMesh] 上执行 UV 展开,以准备用于光照贴图的网格。"
#: doc/classes/ArrayMesh.xml
msgid "Will regenerate normal maps for the [ArrayMesh]."
-msgstr "将为[ArrayMesh]釿–°ç”Ÿæˆæ³•线图。"
+msgstr "将为 [ArrayMesh] 釿–°ç”Ÿæˆæ³•线图。"
#: doc/classes/ArrayMesh.xml
msgid ""
"Returns the index of the first surface with this name held within this "
"[ArrayMesh]. If none are found, -1 is returned."
msgstr ""
-"返回此[ArrayMesh]中带有此å称的第一个曲é¢çš„索引。如果没有找到,则返回-1。"
+"返回此 [ArrayMesh] 中带有此å称的第一个曲é¢çš„索引。如果没有找到,则返回 -1。"
#: doc/classes/ArrayMesh.xml
msgid ""
"Returns the length in indices of the index array in the requested surface "
"(see [method add_surface_from_arrays])."
msgstr ""
-"返回请求的曲é¢çš„索引数组的长度,以指数为å•ä½ï¼ˆè¯·å‚阅 [method "
+"返回请求的曲é¢çš„索引数组的长度,以指数为å•ä½ï¼ˆè§ [method "
"add_surface_from_arrays])。"
#: doc/classes/ArrayMesh.xml
@@ -9172,14 +9184,13 @@ msgid ""
"Returns the length in vertices of the vertex array in the requested surface "
"(see [method add_surface_from_arrays])."
msgstr ""
-"返回所请求曲é¢ä¸­é¡¶ç‚¹æ•°ç»„的顶点长度(请å‚阅[method "
-"add_surface_from_arrays])。"
+"返回所请求曲é¢ä¸­é¡¶ç‚¹æ•°ç»„çš„é¡¶ç‚¹é•¿åº¦ï¼ˆè§ [method add_surface_from_arrays])。"
#: doc/classes/ArrayMesh.xml
msgid ""
"Returns the format mask of the requested surface (see [method "
"add_surface_from_arrays])."
-msgstr "返回所请求表é¢çš„æ ¼å¼æŽ©ç ï¼ˆè¯·å‚阅[method add_surface_from_arrays])。"
+msgstr "返回所请求表é¢çš„æ ¼å¼æŽ©ç ï¼ˆè§ [method add_surface_from_arrays])。"
#: doc/classes/ArrayMesh.xml
msgid "Gets the name assigned to this surface."
@@ -9189,15 +9200,15 @@ msgstr "获å–分é…给此表é¢çš„å称。"
msgid ""
"Returns the primitive type of the requested surface (see [method "
"add_surface_from_arrays])."
-msgstr "返回所请求曲é¢çš„图元类型(请å‚阅 [method add_surface_from_arrays])。"
+msgstr "返回所请求曲é¢çš„å›¾å…ƒç±»åž‹ï¼ˆè§ [method add_surface_from_arrays])。"
#: doc/classes/ArrayMesh.xml
msgid ""
"Removes a surface at position [code]surf_idx[/code], shifting greater "
"surfaces one [code]surf_idx[/code] slot down."
msgstr ""
-"移除ä½ç½®[code]surf_idx[/code]的一个é¢ï¼Œå°†è¾ƒå¤§çš„é¢å‘下移动一个[code]surf_idx[/"
-"code]槽。"
+"移除ä½ç½® [code]surf_idx[/code] 的一个é¢ï¼Œå°†è¾ƒå¤§çš„é¢å‘下移动一个 "
+"[code]surf_idx[/code] 槽。"
#: doc/classes/ArrayMesh.xml
msgid "Sets a name for a given surface."
@@ -9223,7 +9234,7 @@ msgid ""
"Especially useful to avoid unexpected culling when using a shader to offset "
"vertices."
msgstr ""
-"ç”¨ç”¨æˆ·å®šä¹‰çš„ç”¨äºŽä½¿ç”¨è§†é”¥å‰”é™¤çš„ä¸€ç§æ›¿ä»£[AABB]。在使用ç€è‰²å™¨å移顶点时,é¿å…éž"
+"ç”¨ç”¨æˆ·å®šä¹‰çš„ç”¨äºŽä½¿ç”¨è§†é”¥å‰”é™¤çš„ä¸€ç§æ›¿ä»£ [AABB]。在使用ç€è‰²å™¨å移顶点时,é¿å…éž"
"预期的剔除特别有用。"
#: doc/classes/ArrayMesh.xml
@@ -9236,7 +9247,7 @@ msgstr "æ¯ä¸ªé¡¶ç‚¹çš„æƒé‡/骨指数é‡ï¼ˆå§‹ç»ˆä¸º 4)。"
#: doc/classes/ArrayMesh.xml
msgid "[PoolVector3Array], [PoolVector2Array], or [Array] of vertex positions."
-msgstr "[PoolVector3Array], [PoolVector2Array], 或[Array]的顶点ä½ç½®ã€‚"
+msgstr "[PoolVector3Array]ã€[PoolVector2Array] 或 [Array] 的顶点ä½ç½®ã€‚"
#: doc/classes/ArrayMesh.xml
msgid "[PoolVector3Array] of vertex normals."
@@ -9248,8 +9259,8 @@ msgid ""
"first 3 floats determine the tangent, and the last the binormal direction as "
"-1 or 1."
msgstr ""
-"顶点切线的[PoolRealArray]。æ¯ä¸ªå…ƒç´ ä»¥4个浮点数为一组,å‰3个浮点数决定切线,最"
-"åŽä¸€ä¸ªæ˜¯-1或1çš„åŒæ³•线方å‘。"
+"顶点切线的 [PoolRealArray]。æ¯ä¸ªå…ƒç´ ä»¥ 4 ä¸ªæµ®ç‚¹æ•°ä¸ºä¸€ç»„ï¼Œå‰ 3 个浮点数决定切"
+"线,最åŽä¸€ä¸ªæ˜¯ -1 或 1 çš„åŒæ³•线方å‘。"
#: doc/classes/ArrayMesh.xml
msgid "[PoolColorArray] of vertex colors."
@@ -9257,21 +9268,22 @@ msgstr "[PoolColorArray] 顶点颜色。"
#: doc/classes/ArrayMesh.xml
msgid "[PoolVector2Array] for UV coordinates."
-msgstr "[PoolVector2Array] 用于UVåæ ‡ã€‚"
+msgstr "[PoolVector2Array] 用于 UV åæ ‡ã€‚"
#: doc/classes/ArrayMesh.xml
msgid "[PoolVector2Array] for second UV coordinates."
-msgstr "[PoolVector2Array]用于第二UVåæ ‡ã€‚"
+msgstr "[PoolVector2Array] 用于第二 UV åæ ‡ã€‚"
#: doc/classes/ArrayMesh.xml
msgid ""
"[PoolRealArray] or [PoolIntArray] of bone indices. Each element in groups of "
"4 floats."
-msgstr "[PoolRealArray]或[PoolIntArray]的骨骼索引。æ¯ä¸ªå…ƒç´ ä»¥4个浮点数为一组。"
+msgstr ""
+"[PoolRealArray] 或 [PoolIntArray] 的骨骼索引。æ¯ä¸ªå…ƒç´ ä»¥ 4 个浮点数为一组。"
#: doc/classes/ArrayMesh.xml
msgid "[PoolRealArray] of bone weights. Each element in groups of 4 floats."
-msgstr "骨骼æƒé‡çš„[PoolRealArray]。æ¯ä¸ªå…ƒç´ ä»¥4个浮点数为一组。"
+msgstr "骨骼æƒé‡çš„ [PoolRealArray]。æ¯ä¸ªå…ƒç´ ä»¥ 4 个浮点数为一组。"
#: doc/classes/ArrayMesh.xml
msgid ""
@@ -9295,7 +9307,7 @@ msgstr ""
#: doc/classes/ArrayMesh.xml doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Represents the size of the [enum ArrayType] enum."
-msgstr "表示[enum ArrayType]枚举的大å°ã€‚"
+msgstr "表示 [enum ArrayType] 枚举的大å°ã€‚"
#: doc/classes/ArrayMesh.xml
msgid "Array format will include vertices (mandatory)."
@@ -9315,7 +9327,7 @@ msgstr "数组格å¼å°†åŒ…括一个颜色数组。"
#: doc/classes/ArrayMesh.xml
msgid "Array format will include UVs."
-msgstr "数组格å¼å°†åŒ…括UV。"
+msgstr "数组格å¼å°†åŒ…括 UV。"
#: doc/classes/ArrayMesh.xml
msgid "Array format will include another set of UVs."
@@ -9335,7 +9347,7 @@ msgstr "将使用索引数组。"
#: doc/classes/ARVRAnchor.xml
msgid "An anchor point in AR space."
-msgstr "AR空间中的锚点。"
+msgstr "AR 空间中的锚点。"
#: doc/classes/ARVRAnchor.xml
msgid ""
@@ -9353,12 +9365,12 @@ msgid ""
"more about the real world out there especially if only part of the surface "
"is in view."
msgstr ""
-"[ARVRAnchor]点是空间节点,它将ARå¹³å°è¯†åˆ«çš„现实世界的ä½ç½®æ˜ å°„到游æˆä¸–界中相应"
-"ä½ç½®ã€‚例如,åªè¦ARKitä¸­çš„å¹³é¢æ£€æµ‹å¼€å¯ï¼ŒARKit就会识别并更新平é¢ï¼ˆæ¡Œå­ã€åœ°æ¿"
-"等)的ä½ç½®ï¼Œå¹¶ä¸ºå…¶åˆ›å»ºé”šç‚¹ã€‚\n"
-"此节点通过其特有ID映射到其中一个锚点。当你收到一个新锚点å¯ç”¨çš„ä¿¡å·æ—¶ï¼Œåœ¨ä½ çš„"
-"场景中,应该为该锚点添加这个节点。你å¯ä»¥é¢„先定义节点并设置ID;节点将简å•地ä¿"
-"æŒåœ¨0,0,0,直到一个平é¢è¢«è¯†åˆ«ã€‚\n"
+"[ARVRAnchor] 点是空间节点,它将 AR å¹³å°è¯†åˆ«çš„现实世界的ä½ç½®æ˜ å°„到游æˆä¸–界中相"
+"应ä½ç½®ã€‚例如,åªè¦ ARKit ä¸­çš„å¹³é¢æ£€æµ‹å¼€å¯ï¼ŒARKit 就会识别并更新平é¢ï¼ˆæ¡Œå­ã€åœ°"
+"æ¿ç­‰ï¼‰çš„ä½ç½®ï¼Œå¹¶ä¸ºå…¶åˆ›å»ºé”šç‚¹ã€‚\n"
+"此节点通过其特有 ID 映射到其中一个锚点。当你收到一个新锚点å¯ç”¨çš„ä¿¡å·æ—¶ï¼Œåœ¨ä½ "
+"的场景中,应该为该锚点添加这个节点。你å¯ä»¥é¢„先定义节点并设置ID;节点将简å•地"
+"ä¿æŒåœ¨ 0,0,0,直到一个平é¢è¢«è¯†åˆ«ã€‚\n"
"请记ä½ï¼Œåªè¦å¯ç”¨äº†å¹³é¢æ£€æµ‹ï¼Œé”šçš„大å°ã€ä½ç½®å’Œæ–¹å‘就会éšç€æ£€æµ‹é€»è¾‘对外é¢çœŸå®žä¸–"
"界的信æ¯è€Œæ›´æ–°ï¼Œç‰¹åˆ«æ˜¯åœ¨åªæœ‰éƒ¨åˆ†è¡¨é¢åœ¨è§†é‡Žä¸­çš„æƒ…况下。"
@@ -9471,7 +9483,7 @@ msgstr ""
"è¿™æ˜¯é“¾æŽ¥åˆ°æŽ§åˆ¶å™¨è·Ÿè¸ªçš„è¾…åŠ©ç©ºé—´èŠ‚ç‚¹ã€‚å®ƒè¿˜ä¸ºæŽ§åˆ¶å™¨ä¸Šçš„æŒ‰é’®ç­‰çŠ¶æ€æä¾›äº†å‡ ä¸ªä¾¿æ·"
"的通é“。\n"
"控制器通过它们的 ID 链接。你å¯ä»¥åœ¨æŽ§åˆ¶å™¨å¯ç”¨ä¹‹å‰åˆ›å»ºæŽ§åˆ¶å™¨èŠ‚ç‚¹ã€‚å¦‚æžœä½ çš„æ¸¸æˆ"
-"æ€»æ˜¯ä½¿ç”¨ä¸¤ä¸ªæŽ§åˆ¶å™¨ï¼Œå³æ¯åªæ‰‹ä¸€ä¸ªï¼Œä½ å¯ä»¥é¢„先定义 ID 为 1 å’Œ 2 的控制器;一旦"
+"总是使用两个控制器(æ¯åªæ‰‹ä¸€ä¸ªï¼‰ï¼Œä½ å¯ä»¥é¢„先定义 ID 为 1 å’Œ 2 的控制器;一旦"
"确定了控制器,它们就会被激活。如果你希望使用é¢å¤–的控制器,应该对信å·åР以处"
"ç†ï¼Œå¹¶å°† ARVRController 节点添加到您场景中。\n"
"控制器节点的ä½ç½®ç”± [ARVRServer] 自动更新。这使得该节点éžå¸¸é€‚åˆæ·»åŠ å­èŠ‚ç‚¹ä»¥å®ž"
@@ -9481,14 +9493,14 @@ msgstr ""
msgid ""
"If active, returns the name of the associated controller if provided by the "
"AR/VR SDK used."
-msgstr "如果激活,如果由使用的AR/VR SDKæä¾›ï¼Œåˆ™è¿”回相关控制器的å称。"
+msgstr "如果激活,如果由使用的 AR/VR SDK æä¾›ï¼Œåˆ™è¿”回相关控制器的å称。"
#: doc/classes/ARVRController.xml
msgid ""
"Returns the hand holding this controller, if known. See [enum "
"ARVRPositionalTracker.TrackerHand]."
msgstr ""
-"è¿”å›žæŒæœ‰æ­¤æŽ§åˆ¶å™¨çš„æ‰‹ï¼Œå¦‚果知é“çš„è¯ã€‚å‚阅[enum ARVRPositionalTracker."
+"è¿”å›žæŒæœ‰æ­¤æŽ§åˆ¶å™¨çš„æ‰‹ï¼Œå¦‚果知é“çš„è¯ã€‚è§ [enum ARVRPositionalTracker."
"TrackerHand]。"
#: doc/classes/ARVRController.xml
@@ -9514,10 +9526,10 @@ msgid ""
"the AR/VR controllers. This ID is purely offered as information so you can "
"link up the controller with its joystick entry."
msgstr ""
-"返回与此绑定的摇æ†å¯¹è±¡çš„ID。由[ARVRServer]跟踪的æ¯ä¸ªæŽ§åˆ¶å™¨ï¼Œå¦‚果有按钮和轴,"
-"也将被注册为Godot中的摇æ†ã€‚è¿™æ„å‘³ç€æ‰€æœ‰æ­£å¸¸çš„æ‘‡æ†è·Ÿè¸ªå’Œè¾“入映射将对AR/VR控制"
-"器上的按钮和轴起作用。这个IDçº¯ç²¹æ˜¯ä½œä¸ºä¿¡æ¯æä¾›çš„ï¼Œè¿™æ ·ä½ å°±å¯ä»¥æŠŠæŽ§åˆ¶å™¨å’Œå®ƒçš„"
-"æ‘‡æ†æ¡ç›®å…³è”èµ·æ¥ã€‚"
+"返回与此绑定的摇æ†å¯¹è±¡çš„ ID。由 [ARVRServer] 跟踪的æ¯ä¸ªæŽ§åˆ¶å™¨ï¼Œå¦‚果有按钮和"
+"轴,也将被注册为 Godot 中的摇æ†ã€‚è¿™æ„å‘³ç€æ‰€æœ‰æ­£å¸¸çš„æ‘‡æ†è·Ÿè¸ªå’Œè¾“入映射将对 AR/"
+"VR 控制器上的按钮和轴起作用。这个 ID çº¯ç²¹æ˜¯ä½œä¸ºä¿¡æ¯æä¾›çš„ï¼Œè¿™æ ·ä½ å°±å¯ä»¥æŠŠæŽ§åˆ¶"
+"å™¨å’Œå®ƒçš„æ‘‡æ†æ¡ç›®å…³è”èµ·æ¥ã€‚"
#: doc/classes/ARVRController.xml
msgid ""
@@ -9532,8 +9544,8 @@ msgid ""
"pressed. See [enum JoystickList], in particular the [code]JOY_VR_*[/code] "
"constants."
msgstr ""
-"如果索引 [code]button[/code] 处的按钮被按下,则返回 [code]true[/code]。请å‚"
-"阅 [enum JoystickList] 中的 [code]JOY_VR_*[/code] 常é‡ã€‚"
+"如果索引 [code]button[/code] 处的按钮被按下,则返回 [code]true[/code]ã€‚è§ "
+"[enum JoystickList] 中的 [code]JOY_VR_*[/code] 常é‡ã€‚"
#: doc/classes/ARVRController.xml
msgid ""
@@ -9563,8 +9575,9 @@ msgid ""
"This is a useful property to animate if you want the controller to vibrate "
"for a limited duration."
msgstr ""
-"控制器振动的程度。范围从[code]0.0[/code]到[code]1.0[/code],精度[code].01[/"
-"code]。如果更改,会相应地更新[member ARVRPositionalTracker.rumble]。\n"
+"控制器振动的程度。范围从 [code]0.0[/code] 到 [code]1.0[/code],精度 "
+"[code].01[/code]。如果更改,会相应地更新 [member ARVRPositionalTracker."
+"rumble]。\n"
"如果你想让控制器在é™å®šæ—¶é—´å†…振动,这是一个有用的属性,å¯ä»¥å°†å…¶åŠ¨ç”»åŒ–ã€‚"
#: doc/classes/ARVRController.xml
@@ -9581,12 +9594,12 @@ msgid ""
"becomes available. Generally speaking this will be a static mesh after "
"becoming available."
msgstr ""
-"当与控制器相关的Meshå‘生å˜åŒ–或å˜å¾—å¯ç”¨æ—¶è§¦å‘。一般æ¥è¯´ï¼Œè¿™å°†æ˜¯ä¸€ä¸ªå˜å¾—å¯ç”¨åŽ"
-"çš„é™æ€ç½‘格。"
+"当与控制器相关的 Mesh å‘生å˜åŒ–或å˜å¾—å¯ç”¨æ—¶è§¦å‘。一般æ¥è¯´ï¼Œè¿™å°†æ˜¯ä¸€ä¸ªå˜å¾—å¯ç”¨"
+"åŽçš„陿€ç½‘格。"
#: doc/classes/ARVRInterface.xml
msgid "Base class for an AR/VR interface implementation."
-msgstr "AR/VR接å£å®žçŽ°çš„åŸºç±»ã€‚"
+msgstr "AR/VR 接å£å®žçŽ°çš„åŸºç±»ã€‚"
#: doc/classes/ARVRInterface.xml
msgid ""
@@ -9600,8 +9613,8 @@ msgid ""
"[ARVRServer]."
msgstr ""
"需è¦å®žçŽ°è¿™ä¸ªç±»æ‰èƒ½ä½¿ AR 或 VR å¹³å°å¯ä¾› Godot 使用,并且应实现为 C++ æ¨¡å—æˆ– "
-"GDNative 模å—,注æ„,对于 GDNative,应使用å­ç±» ARVRScriptInterface。部分接å£"
-"å‘ GDScript 公开,因而,您å¯ä»¥æ£€æµ‹ã€å¯ç”¨å’Œé…ç½® AR 或 VR å¹³å°ã€‚\n"
+"GDNative 模å—(注æ„,对于 GDNative,应使用å­ç±» ARVRScriptInterface)。部分接"
+"å£å‘ GDScript 公开,因而,您å¯ä»¥æ£€æµ‹ã€å¯ç”¨å’Œé…ç½® AR 或 VR å¹³å°ã€‚\n"
"接å£åº”以这样的方å¼ç¼–写,åªéœ€å¯ç”¨å®ƒä»¬å°±å¯ä»¥ä¸ºæˆ‘们æä¾›å·¥ä½œé…置。您å¯ä»¥é€šè¿‡ "
"[ARVRServer] 查询å¯ç”¨æŽ¥å£ã€‚"
@@ -9611,18 +9624,18 @@ msgid ""
"background, this method returns the feed ID in the [CameraServer] for this "
"interface."
msgstr ""
-"å¦‚æžœè¿™æ˜¯ä¸€ä¸ªéœ€è¦æ˜¾ç¤ºç›¸æœºç”»é¢ä½œä¸ºèƒŒæ™¯çš„AR界é¢ï¼Œæ­¤æ–¹æ³•返回该界é¢çš„"
-"[CameraServer]中的画é¢ID。"
+"å¦‚æžœè¿™æ˜¯ä¸€ä¸ªéœ€è¦æ˜¾ç¤ºç›¸æœºç”»é¢ä½œä¸ºèƒŒæ™¯çš„ AR 界é¢ï¼Œæ­¤æ–¹æ³•返回该界é¢çš„ "
+"[CameraServer] ä¸­çš„ç”»é¢ ID。"
#: doc/classes/ARVRInterface.xml
msgid ""
"Returns a combination of [enum Capabilities] flags providing information "
"about the capabilities of this interface."
-msgstr "返回[enum Capabilities]标签的组åˆï¼Œæä¾›å…³äºŽè¿™ä¸ªæŽ¥å£åŠŸèƒ½çš„ä¿¡æ¯ã€‚"
+msgstr "返回 [enum Capabilities] 标签的组åˆï¼Œæä¾›å…³äºŽè¿™ä¸ªæŽ¥å£åŠŸèƒ½çš„ä¿¡æ¯ã€‚"
#: doc/classes/ARVRInterface.xml
msgid "Returns the name of this interface (OpenVR, OpenHMD, ARKit, etc)."
-msgstr "返回该接å£çš„å称,如OpenVRã€OpenHMDã€ARKit等。"
+msgstr "返回该接å£çš„å称(OpenVRã€OpenHMDã€ARKit 等)。"
#: doc/classes/ARVRInterface.xml
msgid ""
@@ -9693,12 +9706,12 @@ msgstr "[code]true[/code] 如果这是个主接å£ã€‚"
#: doc/classes/ARVRInterface.xml
msgid "No ARVR capabilities."
-msgstr "没有ARVR功能。"
+msgstr "没有 ARVR 功能。"
#: doc/classes/ARVRInterface.xml
msgid ""
"This interface can work with normal rendering output (non-HMD based AR)."
-msgstr "此接å£å¯ä»¥ä¸Žæ­£å¸¸çš„æ¸²æŸ“输出一起工作,éžåŸºäºŽHMDçš„AR。"
+msgstr "此接å£å¯ä»¥ä¸Žæ­£å¸¸çš„æ¸²æŸ“输出一起工作(éžåŸºäºŽ HMD çš„ AR)。"
#: doc/classes/ARVRInterface.xml
msgid "This interface supports stereoscopic rendering."
@@ -9706,7 +9719,7 @@ msgstr "è¯¥æŽ¥å£æ”¯æŒç«‹ä½“渲染。"
#: doc/classes/ARVRInterface.xml
msgid "This interface supports AR (video background and real world tracking)."
-msgstr "è¯¥æŽ¥å£æ”¯æŒ AR,视频背景和真实世界跟踪。"
+msgstr "è¯¥æŽ¥å£æ”¯æŒ AR(视频背景和真实世界跟踪)。"
#: doc/classes/ARVRInterface.xml
msgid ""
@@ -9726,7 +9739,7 @@ msgid ""
"information for our camera node or when stereo scopic rendering is not "
"supported."
msgstr ""
-"Monoè¾“å‡ºï¼Œè¿™ä¸»è¦æ˜¯åœ¨ç›¸æœºèŠ‚ç‚¹æ£€ç´¢å®šä½ä¿¡æ¯æ—¶ï¼Œæˆ–è€…åœ¨ä¸æ”¯æŒç«‹ä½“视景渲染时,内部"
+"Mono è¾“å‡ºï¼Œè¿™ä¸»è¦æ˜¯åœ¨ç›¸æœºèŠ‚ç‚¹æ£€ç´¢å®šä½ä¿¡æ¯æ—¶ï¼Œæˆ–è€…åœ¨ä¸æ”¯æŒç«‹ä½“视景渲染时,内部"
"使用。"
#: doc/classes/ARVRInterface.xml
@@ -9749,7 +9762,7 @@ msgstr "追踪行为符åˆé¢„期。"
msgid ""
"Tracking is hindered by excessive motion (the player is moving faster than "
"tracking can keep up)."
-msgstr "过度è¿åŠ¨ä¼šé˜»ç¢è¿½è¸ªï¼Œå³çŽ©å®¶çš„ç§»åŠ¨é€Ÿåº¦è¶…è¿‡è¿½è¸ªçš„é€Ÿåº¦ã€‚"
+msgstr "过度è¿åŠ¨ä¼šé˜»ç¢è¿½è¸ªï¼ˆçŽ©å®¶çš„ç§»åŠ¨é€Ÿåº¦å¤§äºŽè¿½è¸ªçš„é€Ÿåº¦ï¼‰ã€‚"
#: doc/classes/ARVRInterface.xml
msgid ""
@@ -9767,11 +9780,11 @@ msgstr "我们ä¸çŸ¥é“跟踪的状æ€ï¼Œæˆ–è€…è¿™ä¸ªæŽ¥å£æœªæä¾›å馈。"
msgid ""
"Tracking is not functional (camera not plugged in or obscured, lighthouses "
"turned off, etc.)."
-msgstr "追踪功能失效,å³ç›¸æœºæœªæ’ç”µæˆ–è¢«é®æŒ¡ï¼Œç¯å¡”关闭,等等。"
+msgstr "追踪功能失效(相机未æ’ç”µæˆ–è¢«é®æŒ¡ã€ç¯å¡”关闭,等等)。"
#: modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
msgid "GDNative wrapper for an ARVR interface."
-msgstr "ARVR接å£çš„GDNative包装器。"
+msgstr "ARVR 接å£çš„ GDNative 包装器。"
#: modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
msgid ""
@@ -9784,7 +9797,7 @@ msgstr ""
#: doc/classes/ARVROrigin.xml
msgid "The origin point in AR/VR."
-msgstr "AR/VR的原点。"
+msgstr "AR/VR 的原点。"
#: doc/classes/ARVROrigin.xml
msgid ""
@@ -9816,9 +9829,9 @@ msgid ""
"assume a scale of 1 game world unit = 1 real world meter.\n"
"[b]Note:[/b] This method is a passthrough to the [ARVRServer] itself."
msgstr ""
-"å…许你根æ®ä½ çš„æ¸¸æˆçš„å•使¥è°ƒæ•´æ¯”例。大多数AR/VRå¹³å°å‡å®š1个游æˆä¸–界的å•ä½=1个"
-"现实世界的米的比例。\n"
-"[b]注æ„:[/b]è¿™ç§æ–¹æ³•是通过[ARVRServer]本身的。"
+"å…许你根æ®ä½ çš„æ¸¸æˆçš„å•使¥è°ƒæ•´æ¯”例。大多数 AR/VR å¹³å°å‡å®š 1 个游æˆä¸–界的å•ä½ "
+"= 1 个现实世界的米的比例。\n"
+"[b]注æ„:[/b]è¿™ç§æ–¹æ³•是通过 [ARVRServer] 本身的。"
#: doc/classes/ARVRPositionalTracker.xml
msgid "A tracked object."
@@ -9849,14 +9862,14 @@ msgstr ""
msgid ""
"Returns the hand holding this tracker, if known. See [enum TrackerHand] "
"constants."
-msgstr "è¿”å›žæŒæœ‰æ­¤è¿½è¸ªå™¨çš„æ‰‹ï¼Œå¦‚果知é“。å‚阅[enum TrackerHand]常é‡ã€‚"
+msgstr "è¿”å›žæŒæœ‰æ­¤è¿½è¸ªå™¨çš„æ‰‹ï¼Œå¦‚果知é“ã€‚è§ [enum TrackerHand] 常é‡ã€‚"
#: doc/classes/ARVRPositionalTracker.xml
msgid ""
"If this is a controller that is being tracked, the controller will also be "
"represented by a joystick entry with this ID."
msgstr ""
-"如果这是一个正在被追踪的控制器,该控制器将由一个具有此IDçš„æ“çºµæ†æ¡ç›®è¡¨ç¤ºã€‚"
+"如果这是一个正在被追踪的控制器,该控制器将由一个具有此 ID çš„æ“çºµæ†æ¡ç›®è¡¨ç¤ºã€‚"
#: doc/classes/ARVRPositionalTracker.xml
msgid ""
@@ -9962,7 +9975,7 @@ msgid ""
"button on a controller for a short period of time, or when implementing a "
"teleport mechanism."
msgstr ""
-"这是正确ç†è§£çš„é‡è¦åŠŸèƒ½ã€‚ AR å’Œ VR å¹³å°å¤„ç†å®šä½çš„æ–¹å¼ç•¥æœ‰ä¸åŒã€‚\n"
+"这是正确ç†è§£çš„é‡è¦åŠŸèƒ½ã€‚AR å’Œ VR å¹³å°å¤„ç†å®šä½çš„æ–¹å¼ç•¥æœ‰ä¸åŒã€‚\n"
"å¯¹äºŽä¸æä¾›ç©ºé—´è·Ÿè¸ªçš„å¹³å°ï¼Œæˆ‘们的原点 (0,0,0) 是 HMD çš„ä½ç½®ï¼Œä½†æ‚¨å‡ ä¹Žæ— æ³•控制"
"玩家在现实世界中é¢å¯¹çš„æ–¹å‘。\n"
"对于æä¾›ç©ºé—´è·Ÿè¸ªçš„å¹³å°ï¼Œæˆ‘们的原点在很大程度上å–决于系统。对于 OpenVR,原点通"
@@ -10073,8 +10086,8 @@ msgid ""
"Allows you to adjust the scale to your game's units. Most AR/VR platforms "
"assume a scale of 1 game world unit = 1 real world meter."
msgstr ""
-"å…许你根æ®ä½ çš„æ¸¸æˆçš„å•使¥è°ƒæ•´ç¼©æ”¾ã€‚大多数AR/VRå¹³å°å‡å®š1个游æˆä¸–界å•ä½=1个现"
-"实世界的米。"
+"å…许你根æ®ä½ çš„æ¸¸æˆçš„å•使¥è°ƒæ•´ç¼©æ”¾ã€‚大多数 AR/VR å¹³å°å‡å®š 1 个游æˆä¸–界å•ä½ = "
+"1 个现实世界的米。"
#: doc/classes/ARVRServer.xml
msgid "Emitted when a new interface has been added."
@@ -10082,7 +10095,7 @@ msgstr "æ·»åŠ æ–°æŽ¥å£æ—¶è§¦å‘。"
#: doc/classes/ARVRServer.xml
msgid "Emitted when an interface is removed."
-msgstr "当接å£è¢«åˆ é™¤æ—¶è§¦å‘。"
+msgstr "当接å£è¢«ç§»é™¤æ—¶è§¦å‘。"
#: doc/classes/ARVRServer.xml
msgid ""
@@ -10091,9 +10104,9 @@ msgid ""
"important to react to this signal to add the appropriate [ARVRController] or "
"[ARVRAnchor] nodes related to this new tracker."
msgstr ""
-"当新的追踪器被添加时触å‘。如果你ä¸ä½¿ç”¨å›ºå®šæ•°é‡çš„æŽ§åˆ¶å™¨ï¼Œæˆ–者你在AR解决方案中"
-"使用[ARVRAnchor],那么对这个信å·åšå‡ºå应,以添加与这个新追踪器相关的适当的"
-"[ARVRController]或[ARVRAnchor]节点,将会很é‡è¦ã€‚"
+"当新的追踪器被添加时触å‘。如果你ä¸ä½¿ç”¨å›ºå®šæ•°é‡çš„æŽ§åˆ¶å™¨ï¼Œæˆ–者你在 AR 解决方案"
+"中使用 [ARVRAnchor],那么对这个信å·åšå‡ºå应,以添加与这个新追踪器相关的适当"
+"çš„ [ARVRController] 或 [ARVRAnchor] 节点,将会很é‡è¦ã€‚"
#: doc/classes/ARVRServer.xml
msgid ""
@@ -10103,9 +10116,9 @@ msgid ""
"available (i.e. a new controller is switched on that takes the place of the "
"previous one)."
msgstr ""
-"删除跟踪器时触å‘。如果适当,您应该删除所有 [ARVRController] 或 [ARVRAnchor] "
-"ç‚¹ã€‚è¿™ä¸æ˜¯å¼ºåˆ¶æ€§çš„ï¼ŒèŠ‚ç‚¹åªæ˜¯å˜ä¸ºä¸æ´»åŠ¨çŠ¶æ€ï¼Œå½“新的跟踪器å¯ç”¨æ—¶å°†å†æ¬¡æ¿€æ´»ï¼Œå³"
-"打开一个新的控制器æ¥ä»£æ›¿å‰ä¸€ä¸ªæŽ§åˆ¶å™¨ã€‚"
+"移除跟踪器时触å‘。如果适当,您应该删除所有 [ARVRController] 或 [ARVRAnchor] "
+"ç‚¹ã€‚è¿™ä¸æ˜¯å¼ºåˆ¶æ€§çš„ï¼ŒèŠ‚ç‚¹åªæ˜¯å˜ä¸ºä¸æ´»åŠ¨çŠ¶æ€ï¼Œå½“新的跟踪器å¯ç”¨æ—¶å°†å†æ¬¡æ¿€æ´»ï¼ˆå³"
+"打开一个新的控制器æ¥ä»£æ›¿å‰ä¸€ä¸ªæŽ§åˆ¶å™¨ï¼‰ã€‚"
#: doc/classes/ARVRServer.xml
msgid "The tracker tracks the location of a controller."
@@ -10137,7 +10150,8 @@ msgid ""
"user is looking to in the real world. The user will look dead ahead in the "
"virtual world."
msgstr ""
-"完全é‡ç½®HMD的方å‘。无论用户在现实世界中看å‘哪个方å‘。将在虚拟世界中é”定视角。"
+"完全é‡ç½® HMD 的方å‘。无论用户在现实世界中看å‘哪个方å‘。将在虚拟世界中é”定视"
+"角。"
#: doc/classes/ARVRServer.xml
msgid ""
@@ -10151,7 +10165,7 @@ msgstr ""
msgid ""
"Does not reset the orientation of the HMD, only the position of the player "
"gets centered."
-msgstr "ä¸é‡ç½®HMD的方å‘,åªè®©çŽ©å®¶çš„ä½ç½®å±…中。"
+msgstr "ä¸é‡ç½® HMD 的方å‘,åªè®©çŽ©å®¶çš„ä½ç½®å±…中。"
#: doc/classes/AspectRatioContainer.xml
msgid "Container that preserves its child controls' aspect ratio."
@@ -10190,7 +10204,7 @@ msgid ""
"The aspect ratio to enforce on child controls. This is the width divided by "
"the height. The ratio depends on the [member stretch_mode]."
msgstr ""
-"å¯¹å­æŽ§ä»¶å¼ºåˆ¶å®žæ–½çš„é•¿å®½æ¯”ã€‚è¿™æ˜¯å®½åº¦é™¤ä»¥é«˜åº¦ã€‚è¿™ä¸ªæ¯”ä¾‹å–决于[member "
+"å¯¹å­æŽ§ä»¶å¼ºåˆ¶å®žæ–½çš„é•¿å®½æ¯”ã€‚è¿™æ˜¯å®½åº¦é™¤ä»¥é«˜åº¦ã€‚è¿™ä¸ªæ¯”ä¾‹å–决于 [member "
"stretch_mode]。"
#: doc/classes/AspectRatioContainer.xml
@@ -10232,7 +10246,7 @@ msgstr ""
#: doc/classes/AspectRatioContainer.xml
msgid ""
"Aligns child controls with the beginning (left or top) of the container."
-msgstr "å°†å­æŽ§ä»¶ä¸Žå®¹å™¨çš„å¼€å¤´å¯¹é½ï¼Œå·¦ä¾§æˆ–顶部。"
+msgstr "å°†å­æŽ§ä»¶ä¸Žå®¹å™¨çš„å¼€å¤´å¯¹é½ï¼ˆå·¦ä¾§æˆ–顶部)。"
#: doc/classes/AspectRatioContainer.xml
msgid "Aligns child controls with the center of the container."
@@ -10240,7 +10254,7 @@ msgstr "ä½¿å­æŽ§ä»¶ä¸Žå®¹å™¨çš„ä¸­å¿ƒå¯¹é½ã€‚"
#: doc/classes/AspectRatioContainer.xml
msgid "Aligns child controls with the end (right or bottom) of the container."
-msgstr "å°†å­æŽ§ä»¶ä¸Žå®¹å™¨çš„æœ«ç«¯å¯¹é½ï¼Œå³ä¾§æˆ–底部。"
+msgstr "å°†å­æŽ§ä»¶ä¸Žå®¹å™¨çš„æœ«ç«¯å¯¹é½ï¼ˆå³ä¾§æˆ–底部)。"
#: doc/classes/AStar.xml
msgid ""
@@ -10560,13 +10574,13 @@ msgstr ""
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
"Returns the position of the point associated with the given [code]id[/code]."
-msgstr "返回与给定[code]id[/code]相关è”的点的ä½ç½®ã€‚"
+msgstr "返回与给定 [code]id[/code] 相关è”的点的ä½ç½®ã€‚"
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
"Returns the weight scale of the point associated with the given [code]id[/"
"code]."
-msgstr "返回与给定[code]id[/code]å…³è”的点的æƒé‡æ¯”例。"
+msgstr "返回与给定 [code]id[/code] å…³è”的点的æƒé‡æ¯”例。"
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid "Returns an array of all points."
@@ -10575,7 +10589,7 @@ msgstr "返回所有点的数组。"
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
"Returns whether a point associated with the given [code]id[/code] exists."
-msgstr "返回与给定[code]id[/code]相关è”的点是å¦å­˜åœ¨ã€‚"
+msgstr "返回与给定 [code]id[/code] 相关è”的点是å¦å­˜åœ¨ã€‚"
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
@@ -10587,7 +10601,7 @@ msgstr "返回是å¦ç¦ç”¨ç‚¹ä»¥è¿›è¡Œå¯»è·¯ã€‚默认情况下,所有点å‡å¤„
msgid ""
"Removes the point associated with the given [code]id[/code] from the points "
"pool."
-msgstr "从积分池中删除与给定[code]id[/code]å…³è”的积分。"
+msgstr "从点池中移除与给定 [code]id[/code] å…³è”的点。"
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
@@ -10595,8 +10609,8 @@ msgid ""
"you're adding a known large number of points at once, for a grid for "
"instance. New capacity must be greater or equals to old capacity."
msgstr ""
-"在内部为[code]num_nodes[/code]个点ä¿ç•™ç©ºé—´ï¼Œå¦‚æžœæ‚¨ä¸€æ¬¡è¦æ·»åŠ ä¸€ä¸ªå·²çŸ¥çš„å¤§é‡ç‚¹"
-"(例如对于一个网格),则很有用。新容é‡å¿…须大于或等于旧容é‡ã€‚"
+"在内部为 [code]num_nodes[/code] 个点ä¿ç•™ç©ºé—´ï¼Œå¦‚果你想è¦ä¸€æ¬¡æ€§æ·»åР大é‡çš„点且"
+"æ•°é‡å·²çŸ¥ï¼ˆä¾‹å¦‚网格),那么就会很有用。新容é‡å¿…须大于或等于旧容é‡ã€‚"
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
@@ -10607,7 +10621,7 @@ msgstr "ç¦ç”¨æˆ–å¯ç”¨æŒ‡å®šç‚¹çš„寻路功能。用于制作临时障ç¢ç‰©ã€‚
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
"Sets the [code]position[/code] for the point with the given [code]id[/code]."
-msgstr "为具有给定[code]id[/code]的点设置[code]position[/code]。"
+msgstr "为具有给定 [code]id[/code] 的点设置ä½ç½® [code]position[/code]。"
#: doc/classes/AStar.xml doc/classes/AStar2D.xml
msgid ""
@@ -10616,13 +10630,13 @@ msgid ""
"_compute_cost] when determining the overall cost of traveling across a "
"segment from a neighboring point to this point."
msgstr ""
-"为给定的[code]id[/code]的点设置[code]weight_scale[/code]。在确定从邻接点到这"
-"ä¸ªç‚¹çš„ä¸€æ®µè·¯ç¨‹çš„æ€»æˆæœ¬æ—¶ï¼Œ[code]weight_scale[/code]è¦ä¹˜ä»¥[method "
-"_compute_cost]的结果。"
+"为给定的 [code]id[/code] 的点设置 [code]weight_scale[/code]。在确定从邻接点到"
+"è¿™ä¸ªç‚¹çš„ä¸€æ®µè·¯ç¨‹çš„æ€»æˆæœ¬æ—¶ï¼Œ[code]weight_scale[/code] è¦ä¹˜ä»¥ [method "
+"_compute_cost] 的结果。"
#: doc/classes/AStar2D.xml
msgid "AStar class representation that uses 2D vectors as edges."
-msgstr "使用二维å‘é‡ä½œä¸ºè¾¹ç¼˜çš„AStar类表示。"
+msgstr "使用 2D å‘é‡ä½œä¸ºè¾¹ç¼˜çš„ AStar 类表示。"
#: doc/classes/AStar2D.xml
msgid ""
@@ -10843,16 +10857,16 @@ msgid ""
"FLAG_REPEAT] and [constant Texture.FLAG_MIRRORED_REPEAT] flags are ignored "
"when using an AtlasTexture."
msgstr ""
-"[Texture]资æºï¼Œç”±[member region]定义,è£å‰ªå‡º[member atlas]纹ç†çš„一个部分。主"
-"è¦çš„用例是从纹ç†å›¾é›†ä¸­è£å‰ªå‡ºçº¹ç†ï¼Œä¸€ä¸ªå¤§çš„çº¹ç†æ–‡ä»¶ï¼ŒåŒ…å«äº†å¤šä¸ªè¾ƒå°çš„纹ç†ã€‚ç”± "
-"[member atlas]çš„[Texture]ã€å®šä¹‰ä½¿ç”¨ [member atlas]区域的[member region]和定义"
-"边界宽度的[member margin]组æˆã€‚\n"
-"[AtlasTexture]ä¸èƒ½åœ¨[AnimatedTexture]中使用,ä¸èƒ½åœ¨[TextureRect]等节点中平"
-"铺,如果在其他[AtlasTexture]资æºå†…部使用,将ä¸èƒ½æ­£å¸¸å·¥ä½œã€‚多个[AtlasTexture]"
-"资æºå¯ä»¥ç”¨æ¥è£å‰ªå›¾é›†ä¸­çš„多个纹ç†ã€‚ä¸Žä½¿ç”¨å¤šä¸ªå°æ–‡ä»¶ç›¸æ¯”,使用一个纹ç†å›¾é›†æœ‰åŠ©"
-"于优化视频内存消耗和渲染调用。\n"
-"[b]注æ„:[/b]AtlasTextures䏿”¯æŒé‡å¤ã€‚当使用AtlasTexture时,[constant "
-"Texture.FLAG_REPEAT]和[constant Texture.FLAG_MIRRORED_REPEAT]标志被忽略。"
+"[Texture] 资æºï¼Œç”± [member region] 定义,è£å‰ªå‡º [member atlas] 纹ç†çš„一个部"
+"分。主è¦çš„用例是从纹ç†å›¾é›†ä¸­è£å‰ªå‡ºçº¹ç†ï¼Œä¸€ä¸ªå¤§çš„çº¹ç†æ–‡ä»¶ï¼ŒåŒ…å«äº†å¤šä¸ªè¾ƒå°çš„纹"
+"ç†ã€‚ç”± [member atlas] çš„ [Texture]ã€å®šä¹‰ä½¿ç”¨ [member atlas] 区域的 [member "
+"region] 和定义边界宽度的 [member margin] 组æˆã€‚\n"
+"[AtlasTexture] ä¸èƒ½åœ¨ [AnimatedTexture] 中使用,ä¸èƒ½åœ¨ [TextureRect] 等节点中"
+"平铺,如果在其他 [AtlasTexture] 资æºå†…部使用,将ä¸èƒ½æ­£å¸¸å·¥ä½œã€‚多个"
+"[AtlasTexture] 资æºå¯ä»¥ç”¨æ¥è£å‰ªå›¾é›†ä¸­çš„多个纹ç†ã€‚ä¸Žä½¿ç”¨å¤šä¸ªå°æ–‡ä»¶ç›¸æ¯”,使用一"
+"个纹ç†å›¾é›†æœ‰åŠ©äºŽä¼˜åŒ–è§†é¢‘å†…å­˜æ¶ˆè€—å’Œæ¸²æŸ“è°ƒç”¨ã€‚\n"
+"[b]注æ„:[/b]AtlasTexture 䏿”¯æŒé‡å¤ã€‚当使用 AtlasTexture 时,[constant "
+"Texture.FLAG_REPEAT] 和 [constant Texture.FLAG_MIRRORED_REPEAT] 标志被忽略。"
#: doc/classes/AtlasTexture.xml
msgid "The texture that contains the atlas. Can be any [Texture] subtype."
@@ -10923,7 +10937,8 @@ msgid ""
"Amount of amplification in decibels. Positive values make the sound louder, "
"negative values make it quieter. Value can range from -80 to 24."
msgstr ""
-"以分è´ä¸ºå•ä½çš„æ”¾å¤§é‡ã€‚正值使声音更å“亮,负值使声音更安é™ã€‚数值范围从-80到24。"
+"以分è´ä¸ºå•ä½çš„æ”¾å¤§é‡ã€‚正值使声音更å“亮,负值使声音更安é™ã€‚数值范围从 -80 到 "
+"24。"
#: doc/classes/AudioEffectBandLimitFilter.xml
msgid "Adds a band limit filter to the audio bus."
@@ -10934,8 +10949,8 @@ msgid ""
"Limits the frequencies in a range around the [member AudioEffectFilter."
"cutoff_hz] and allows frequencies outside of this range to pass."
msgstr ""
-"é™åˆ¶[member AudioEffectFilter.cutoff_hz]周围范围内的频率,å…许这个范围外的频"
-"率通过。"
+"é™åˆ¶ [member AudioEffectFilter.cutoff_hz] 周围范围内的频率,å…许这个范围外的"
+"频率通过。"
#: doc/classes/AudioEffectBandPassFilter.xml
msgid "Adds a band pass filter to the audio bus."
@@ -10946,8 +10961,8 @@ msgid ""
"Attenuates the frequencies inside of a range around the [member "
"AudioEffectFilter.cutoff_hz] and cuts frequencies outside of this band."
msgstr ""
-"è¡°å‡[member AudioEffectFilter.cutoff_hz]周围范围内的频率,并切断这个频段之外"
-"的频率。"
+"è¡°å‡ [member AudioEffectFilter.cutoff_hz] 周围范围内的频率,并切断这个频段之"
+"外的频率。"
#: doc/classes/AudioEffectCapture.xml
msgid "Captures audio from an audio bus in real-time."
@@ -11092,9 +11107,9 @@ msgid ""
"punchy."
msgstr ""
"动æ€èŒƒå›´åŽ‹ç¼©å™¨åœ¨æŒ¯å¹…è¶…è¿‡ä¸€å®šçš„é˜ˆå€¼ï¼ˆä»¥åˆ†è´ä¸ºå•ä½ï¼‰æ—¶ï¼Œé™ä½Žå£°éŸ³çš„电平。压缩器"
-"的主è¦ç”¨é€”之一是通过尽å¯èƒ½å°‘的削波(当声音超过0dB时)æ¥å¢žåŠ åŠ¨æ€èŒƒå›´ã€‚\n"
+"的主è¦ç”¨é€”之一是通过尽å¯èƒ½å°‘的削波(当声音超过 0dB 时)æ¥å¢žåŠ åŠ¨æ€èŒƒå›´ã€‚\n"
"压缩器在混音中的用途很多。\n"
-"- 在主总线上压缩整个输出(虽然[AudioEffectLimiter]å¯èƒ½æ›´å¥½äº›ï¼‰ã€‚\n"
+"- 在主总线上压缩整个输出(虽然 [AudioEffectLimiter] å¯èƒ½æ›´å¥½äº›ï¼‰ã€‚\n"
"- 在声音通é“中,以确ä¿å®ƒä»¬å¬èµ·æ¥å°½å¯èƒ½çš„平衡。\n"
"- 侧链。这å¯ä»¥é™ä½Žä¸Žå¦ä¸€æ¡éŸ³é¢‘æ€»çº¿ä¾§é“¾çš„å£°éŸ³çº§åˆ«ï¼Œä»¥è¿›è¡Œé˜ˆå€¼æ£€æµ‹ã€‚è¿™ç§æŠ€æœ¯åœ¨"
"è§†é¢‘æ¸¸æˆæ··éŸ³ä¸­å¾ˆå¸¸è§ï¼Œä»¥éŸ³ä¹å’ŒSFX的级别,从而声音被å¬åˆ°ã€‚\n"
@@ -11104,7 +11119,8 @@ msgstr ""
msgid ""
"Compressor's reaction time when the signal exceeds the threshold, in "
"microseconds. Value can range from 20 to 2000."
-msgstr "当信å·è¶…过阈值时,压缩器的å应时间,以微秒为å•ä½ã€‚数值范围从20到2000。"
+msgstr ""
+"当信å·è¶…过阈值时,压缩器的å应时间,以微秒为å•ä½ã€‚数值范围从 20 到 2000。"
#: doc/classes/AudioEffectCompressor.xml
msgid "Gain applied to the output signal."
@@ -11114,7 +11130,8 @@ msgstr "应用于输出信å·çš„增益。"
msgid ""
"Balance between original signal and effect signal. Value can range from 0 "
"(totally dry) to 1 (totally wet)."
-msgstr "原始信å·å’Œæ•ˆæžœä¿¡å·ä¹‹é—´çš„平衡。数值范围从0(完全干燥)到1(完全浸润)。"
+msgstr ""
+"原始信å·å’Œæ•ˆæžœä¿¡å·ä¹‹é—´çš„平衡。数值范围从 0(完全干燥)到 1(完全浸润)。"
#: doc/classes/AudioEffectCompressor.xml
msgid ""
@@ -11123,7 +11140,7 @@ msgid ""
"compressed. Value can range from 1 to 48."
msgstr ""
"音频通过阈值级别åŽï¼Œåº”用于音频的压缩é‡ã€‚比率越高,音频的大声部分将被压缩。数"
-"值范围从1到48。"
+"值范围从 1 到 48。"
#: doc/classes/AudioEffectCompressor.xml
msgid ""
@@ -11141,7 +11158,7 @@ msgstr "使用å¦ä¸€æ¡éŸ³é¢‘总线进行阈值检测,é™ä½Žå£°éŸ³çº§åˆ«ã€‚"
msgid ""
"The level above which compression is applied to the audio. Value can range "
"from -60 to 0."
-msgstr "对音频进行压缩的级别。数值范围从-60到0。"
+msgstr "对音频进行压缩的级别。数值范围从 -60 到 0。"
#: doc/classes/AudioEffectDelay.xml
msgid ""
@@ -11170,7 +11187,7 @@ msgstr "原始声音的输出百分比。为 0 时,åªè¾“出延迟的声音。
#: doc/classes/AudioEffectDelay.xml
msgid "If [code]true[/code], feedback is enabled."
-msgstr "如果[code]true[/code],则å¯ç”¨å馈。"
+msgstr "如果为 [code]true[/code],则å¯ç”¨å馈。"
#: doc/classes/AudioEffectDelay.xml
msgid "Feedback delay time in milliseconds."
@@ -11203,7 +11220,7 @@ msgstr ""
#: doc/classes/AudioEffectDelay.xml
msgid "If [code]true[/code], [code]tap2[/code] will be enabled."
-msgstr "如果[code]true[/code],将å¯ç”¨[code]tap2[/code]。"
+msgstr "如果为 [code]true[/code],将å¯ç”¨[code]tap2[/code]。"
#: doc/classes/AudioEffectDelay.xml
msgid "[b]Tap2[/b] delay time in milliseconds."
@@ -11256,7 +11273,7 @@ msgid ""
"High-pass filter, in Hz. Frequencies higher than this value will not be "
"affected by the distortion. Value can range from 1 to 20000."
msgstr ""
-"高通滤波器,å•ä½ä¸ºHz。高于此值的频率ä¸ä¼šå—到失真的影å“。该值的范围为1至"
+"高通滤波器,å•ä½ä¸º Hz。高于此值的频率ä¸ä¼šå—到失真的影å“。该值的范围为 1 至 "
"20000。"
#: doc/classes/AudioEffectDistortion.xml
@@ -11267,13 +11284,13 @@ msgstr "失真类型."
msgid ""
"Increases or decreases the volume after the effect. Value can range from -80 "
"to 24."
-msgstr "增加或å‡å°‘效果åŽçš„音é‡ã€‚数值范围从-80到24。"
+msgstr "增加或å‡å°‘效果åŽçš„音é‡ã€‚数值范围从 -80 到 24。"
#: doc/classes/AudioEffectDistortion.xml
msgid ""
"Increases or decreases the volume before the effect. Value can range from "
"-60 to 60."
-msgstr "增加或å‡å°‘效果å‰çš„音é‡ã€‚值的范围为-60至60。"
+msgstr "增加或å‡å°‘效果å‰çš„音é‡ã€‚值的范围为 -60 至 60。"
#: doc/classes/AudioEffectDistortion.xml
msgid ""
@@ -11306,7 +11323,7 @@ msgid ""
"or [AudioEffectEQ21] don't fit your needs."
msgstr ""
"音频å‡è¡¡å™¨çš„基础类。让你å¯ä»¥æŽ§åˆ¶é¢‘率。\n"
-"如果 [AudioEffectEQ6], [AudioEffectEQ10] 或 [AudioEffectEQ21]ä¸ç¬¦åˆæ‚¨çš„需求,"
+"如果 [AudioEffectEQ6]ã€[AudioEffectEQ10] 或 [AudioEffectEQ21]ä¸ç¬¦åˆæ‚¨çš„需求,"
"请使用它æ¥åˆ›å»ºä¸€ä¸ªè‡ªå®šä¹‰å‡è¡¡å™¨ã€‚"
#: doc/classes/AudioEffectEQ.xml
@@ -11328,11 +11345,11 @@ msgstr "返回å‡è¡¡å™¨çš„频段数。"
#: doc/classes/AudioEffectEQ.xml
msgid "Returns the band's gain at the specified index, in dB."
-msgstr "返回指定索引处的波段增益,å•ä½ä¸ºdB。"
+msgstr "返回指定索引处的波段增益,å•ä½ä¸º dB。"
#: doc/classes/AudioEffectEQ.xml
msgid "Sets band's gain at the specified index, in dB."
-msgstr "设置指定索引处的波段增益,å•ä½ä¸ºdB。"
+msgstr "设置指定索引处的波段增益,å•ä½ä¸º dB。"
#: doc/classes/AudioEffectEQ10.xml
msgid ""
@@ -11465,11 +11482,11 @@ msgstr "为音频总线添加一个滤波器。"
#: doc/classes/AudioEffectFilter.xml
msgid "Allows frequencies other than the [member cutoff_hz] to pass."
-msgstr "å…许通过[member cutoff_hz]以外的频率。"
+msgstr "å…许通过 [member cutoff_hz] 以外的频率。"
#: doc/classes/AudioEffectFilter.xml
msgid "Threshold frequency for the filter, in Hz."
-msgstr "滤波器的阈值频率,å•ä½ä¸ºHz。"
+msgstr "滤波器的阈值频率,å•ä½ä¸º Hz。"
#: doc/classes/AudioEffectFilter.xml
msgid "Gain amount of the frequencies after the filter."
@@ -11488,11 +11505,11 @@ msgid ""
"Cuts frequencies lower than the [member AudioEffectFilter.cutoff_hz] and "
"allows higher frequencies to pass."
msgstr ""
-"å‰Šå‡æ¯”[member AudioEffectFilter.cutoff_hz]更低的频率,å…许更高的频率通过。"
+"å‰Šå‡æ¯” [member AudioEffectFilter.cutoff_hz] 更低的频率,å…许更高的频率通过。"
#: doc/classes/AudioEffectHighShelfFilter.xml
msgid "Reduces all frequencies above the [member AudioEffectFilter.cutoff_hz]."
-msgstr "é™ä½Žæ‰€æœ‰é«˜äºŽ[member AudioEffectFilter.cutoff_hz]的频率。"
+msgstr "é™ä½Žæ‰€æœ‰é«˜äºŽ [member AudioEffectFilter.cutoff_hz] 的频率。"
#: doc/classes/AudioEffectLimiter.xml
msgid "Adds a soft-clip limiter audio effect to an Audio bus."
@@ -11507,8 +11524,8 @@ msgid ""
"and progressively increases its effect as the input level increases such "
"that the threshold is never exceeded."
msgstr ""
-"é™åˆ¶å™¨ç±»ä¼¼äºŽåŽ‹ç¼©å™¨ï¼Œä½†çµæ´»æ€§è¾ƒå·®ï¼Œå¹¶ä¸”设计为ä¸å…许声音超过给定的dB阈值。始终"
-"建议在主总线中添加一个以å‡å°‘削波的影å“。\n"
+"é™åˆ¶å™¨ç±»ä¼¼äºŽåŽ‹ç¼©å™¨ï¼Œä½†çµæ´»æ€§è¾ƒå·®ï¼Œå¹¶ä¸”设计为ä¸å…许声音超过给定的 dB 阈值。始"
+"终建议在主总线中添加一个以å‡å°‘削波的影å“。\n"
"软削波开始将峰值é™ä½Žåˆ°ç•¥ä½ŽäºŽé˜ˆå€¼æ°´å¹³ï¼Œå¹¶éšç€è¾“å…¥æ°´å¹³çš„å¢žåŠ è€Œé€æ¸å¢žå¼ºå…¶æ•ˆæžœï¼Œ"
"从而永ä¸è¶…过阈值。"
@@ -11516,19 +11533,19 @@ msgstr ""
msgid ""
"The waveform's maximum allowed value, in decibels. Value can range from -20 "
"to -0.1."
-msgstr "波形的最大å…许值,å•使˜¯åˆ†è´ã€‚数值范围从-20到-0.1。"
+msgstr "波形的最大å…许值,å•使˜¯åˆ†è´ã€‚数值范围从 -20 到 -0.1。"
#: doc/classes/AudioEffectLimiter.xml
msgid ""
"Applies a gain to the limited waves, in decibels. Value can range from 0 to "
"6."
-msgstr "将增益应用于有é™çš„æ³¢ï¼Œä»¥åˆ†è´ä¸ºå•ä½ã€‚å–值范围是0到6。"
+msgstr "将增益应用于有é™çš„æ³¢ï¼Œä»¥åˆ†è´ä¸ºå•ä½ã€‚å–值范围是 0 到 6。"
#: doc/classes/AudioEffectLimiter.xml
msgid ""
"Threshold from which the limiter begins to be active, in decibels. Value can "
"range from -30 to 0."
-msgstr "é™åˆ¶å™¨å¼€å§‹ç”Ÿæ•ˆçš„阈值,以分è´ä¸ºå•ä½ã€‚值的范围å¯ä»¥ä»Ž-30到0。"
+msgstr "é™åˆ¶å™¨å¼€å§‹ç”Ÿæ•ˆçš„阈值,以分è´ä¸ºå•ä½ã€‚值的范围å¯ä»¥ä»Ž -30 到 0。"
#: doc/classes/AudioEffectLowPassFilter.xml
msgid "Adds a low-pass filter to the Audio bus."
@@ -11539,11 +11556,11 @@ msgid ""
"Cuts frequencies higher than the [member AudioEffectFilter.cutoff_hz] and "
"allows lower frequencies to pass."
msgstr ""
-"å‰Šå‡æ¯”[member AudioEffectFilter.cutoff_hz]更低的频率,å…许更高的频率通过。"
+"å‰Šå‡æ¯” [member AudioEffectFilter.cutoff_hz] 更低的频率,å…许更高的频率通过。"
#: doc/classes/AudioEffectLowShelfFilter.xml
msgid "Reduces all frequencies below the [member AudioEffectFilter.cutoff_hz]."
-msgstr "é™ä½Ž[member AudioEffectFilter.cutoff_hz]以下的所有频率。"
+msgstr "é™ä½Ž [member AudioEffectFilter.cutoff_hz] 以下的所有频率。"
#: doc/classes/AudioEffectNotchFilter.xml
msgid "Adds a notch filter to the Audio bus."
@@ -11554,8 +11571,8 @@ msgid ""
"Attenuates frequencies in a narrow band around the [member AudioEffectFilter."
"cutoff_hz] and cuts frequencies outside of this range."
msgstr ""
-"è¡°å‡[member AudioEffectFilter.cutoff_hz]周围窄带的频率,并切断这个范围以外的"
-"频率。"
+"è¡°å‡ [member AudioEffectFilter.cutoff_hz] 周围窄带的频率,并切断这个范围以外"
+"的频率。"
#: doc/classes/AudioEffectPanner.xml
msgid "Adds a panner audio effect to an Audio bus. Pans sound left or right."
@@ -11568,7 +11585,7 @@ msgstr "决定å‘左峿€»çº¿å‘é€çš„音频信å·é‡ã€‚"
#: doc/classes/AudioEffectPanner.xml
msgid "Pan position. Value can range from -1 (fully left) to 1 (fully right)."
-msgstr "平移ä½ç½®ã€‚值的范围å¯ä»¥ä»Ž-1(完全左)到1(完全å³ï¼‰ã€‚"
+msgstr "平移ä½ç½®ã€‚值的范围å¯ä»¥ä»Ž -1(完全左)到1(完全å³ï¼‰ã€‚"
#: doc/classes/AudioEffectPhaser.xml
msgid ""
@@ -11592,29 +11609,29 @@ msgid ""
"can range from 0.1 to 4."
msgstr ""
"控制滤波器频率扫æçš„频率。较低的值将主è¦å½±å“低音频率。高值å¯ä»¥æŽ¨é«˜é«˜éŸ³ã€‚值的"
-"范围å¯ä»¥ä»Ž0.1到4。"
+"范围å¯ä»¥ä»Ž 0.1 到 4。"
#: doc/classes/AudioEffectPhaser.xml
msgid "Output percent of modified sound. Value can range from 0.1 to 0.9."
-msgstr "修改åŽå£°éŸ³çš„输出百分比。数值范围从0.1到0.9。"
+msgstr "修改åŽå£°éŸ³çš„输出百分比。数值范围从 0.1 到 0.9。"
#: doc/classes/AudioEffectPhaser.xml
msgid ""
"Determines the maximum frequency affected by the LFO modulations, in Hz. "
"Value can range from 10 to 10000."
-msgstr "å†³å®šå— LFO 调制影å“的最大频率,å•ä½ä¸º Hz。数值范围为10-10000。"
+msgstr "å†³å®šå— LFO 调制影å“的最大频率,å•ä½ä¸º Hz。数值范围为 10-10000。"
#: doc/classes/AudioEffectPhaser.xml
msgid ""
"Determines the minimum frequency affected by the LFO modulations, in Hz. "
"Value can range from 10 to 10000."
-msgstr "å†³å®šå— LFO 调制影å“的最å°é¢‘率,å•ä½ä¸º Hz。数值范围为10-10000。"
+msgstr "å†³å®šå— LFO 调制影å“的最å°é¢‘率,å•ä½ä¸º Hz。数值范围为 10-10000。"
#: doc/classes/AudioEffectPhaser.xml
msgid ""
"Adjusts the rate in Hz at which the effect sweeps up and down across the "
"frequency range."
-msgstr "以Hz为å•ä½è°ƒæ•´æ•ˆæžœåœ¨æ•´ä¸ªé¢‘率范围内上下扫æçš„速度。"
+msgstr "以 Hz 为å•ä½è°ƒæ•´æ•ˆæžœåœ¨æ•´ä¸ªé¢‘率范围内上下扫æçš„速度。"
#: doc/classes/AudioEffectPitchShift.xml
msgid ""
@@ -11648,8 +11665,8 @@ msgid ""
"are more demanding on the CPU and may cause audio cracking if the CPU can't "
"keep up."
msgstr ""
-"è¦ä½¿ç”¨çš„è¿‡é‡‡æ ·ç³»æ•°ã€‚æ›´é«˜çš„å€¼ä¼šå¸¦æ¥æ›´å¥½çš„è´¨é‡ï¼Œä½†å¯¹CPUçš„è¦æ±‚更高,如果CPUè·Ÿä¸"
-"上,å¯èƒ½ä¼šå¯¼è‡´éŸ³é¢‘破裂。"
+"è¦ä½¿ç”¨çš„è¿‡é‡‡æ ·ç³»æ•°ã€‚æ›´é«˜çš„å€¼ä¼šå¸¦æ¥æ›´å¥½çš„è´¨é‡ï¼Œä½†å¯¹ CPU çš„è¦æ±‚更高,如果 CPU "
+"è·Ÿä¸ä¸Šï¼Œå¯èƒ½ä¼šå¯¼è‡´éŸ³é¢‘破裂。"
#: doc/classes/AudioEffectPitchShift.xml
msgid ""
@@ -11708,7 +11725,7 @@ msgstr ""
#: doc/classes/AudioEffectPitchShift.xml
#: doc/classes/AudioEffectSpectrumAnalyzer.xml
msgid "Represents the size of the [enum FFT_Size] enum."
-msgstr "表示[enum FFT_Size]枚举的大å°ã€‚"
+msgstr "表示 [enum FFT_Size] 枚举的大å°ã€‚"
#: doc/classes/AudioEffectRecord.xml
msgid "Audio effect used for recording the sound from an audio bus."
@@ -11746,14 +11763,15 @@ msgid ""
"If [code]true[/code], the sound will be recorded. Note that restarting the "
"recording will remove the previously recorded sample."
msgstr ""
-"如果[code]true[/code],将录制声音。请注æ„ï¼Œé‡æ–°å¼€å§‹å½•音将删除先å‰å½•音的样本。"
+"如果为 [code]true[/code],将录制声音。请注æ„ï¼Œé‡æ–°å¼€å§‹å½•音将移除先å‰å½•音的样"
+"本。"
#: doc/classes/AudioEffectRecord.xml
msgid ""
"Specifies the format in which the sample will be recorded. See [enum "
"AudioStreamSample.Format] for available formats."
msgstr ""
-"指定录音样本的格å¼ã€‚请å‚阅[enum AudioStreamSample.Format]了解å¯ç”¨çš„æ ¼å¼ã€‚"
+"指定录音样本的格å¼ã€‚请å‚阅 [enum AudioStreamSample.Format] 了解å¯ç”¨çš„æ ¼å¼ã€‚"
#: doc/classes/AudioEffectReverb.xml
msgid ""
@@ -11774,7 +11792,7 @@ msgstr "模拟ä¸åŒå¤§å°çš„æˆ¿é—´ã€‚其傿•°å¯ä»¥è°ƒæ•´ï¼Œä»¥æ¨¡æ‹Ÿç‰¹å®šæˆ¿
msgid ""
"Defines how reflective the imaginary room's walls are. Value can range from "
"0 to 1."
-msgstr "定义虚拟房间墙å£çš„å射程度。值的范围是0到1。"
+msgstr "定义虚拟房间墙å£çš„å射程度。值的范围是 0 到 1。"
#: doc/classes/AudioEffectReverb.xml
msgid ""
@@ -11789,11 +11807,11 @@ msgid ""
"cutoff frequency. Value can range from 0 to 1."
msgstr ""
"高通滤波器通过频率高于æŸä¸€æˆªæ­¢é¢‘率的信å·ï¼Œè¡°å‡é¢‘率低于截止频率的信å·ã€‚数值范"
-"围为0~1。"
+"围为 0 到 1。"
#: doc/classes/AudioEffectReverb.xml
msgid "Output percent of predelay. Value can range from 0 to 1."
-msgstr "预延迟的输出百分比。数值范围为0~1。"
+msgstr "预延迟的输出百分比。数值范围为 0 到 1。"
#: doc/classes/AudioEffectReverb.xml
msgid ""
@@ -11805,13 +11823,13 @@ msgstr "原始信å·ä¸Žæ··å“ä¿¡å·æ—©æœŸå射之间的时间,以毫秒为å•
msgid ""
"Dimensions of simulated room. Bigger means more echoes. Value can range from "
"0 to 1."
-msgstr "模拟房间的尺寸。越大表示回声越多。值的范围å¯ä»¥ä»Ž0到1。"
+msgstr "模拟房间的尺寸。越大表示回声越多。值的范围å¯ä»¥ä»Ž 0 到 1。"
#: doc/classes/AudioEffectReverb.xml
msgid ""
"Widens or narrows the stereo image of the reverb tail. 1 means fully widens. "
"Value can range from 0 to 1."
-msgstr "æ‰©å¤§æˆ–ç¼©å°æ··å“尾音的立体声图åƒã€‚1表示完全扩大。值的范围是0到1。"
+msgstr "æ‰©å¤§æˆ–ç¼©å°æ··å“尾音的立体声图åƒã€‚1 表示完全扩大。值的范围是 0 到 1。"
#: doc/classes/AudioEffectReverb.xml
msgid ""
@@ -11842,7 +11860,7 @@ msgstr "音频频谱演示"
#: doc/classes/AudioStreamGenerator.xml
#: doc/classes/AudioStreamGeneratorPlayback.xml
msgid "Godot 3.2 will get new audio features"
-msgstr "Godot 3.2将获得新的音频功能"
+msgstr "Godot 3.2 将获得新的音频功能"
#: doc/classes/AudioEffectSpectrumAnalyzer.xml
msgid ""
@@ -11882,7 +11900,7 @@ msgid ""
"charge of creating sample data (playable audio) as well as its playback via "
"a voice interface."
msgstr ""
-"[AudioServer]是一个音频访问的低级æœåŠ¡å™¨æŽ¥å£ã€‚它负责创建样本数æ®ï¼ˆå¯æ’­æ”¾çš„音"
+"[AudioServer] 是用于音频访问的底层æœåŠ¡å™¨æŽ¥å£ã€‚它负责创建样本数æ®ï¼ˆå¯æ’­æ”¾çš„音"
"频)以åŠé€šè¿‡è¯­éŸ³æŽ¥å£è¿›è¡Œæ’­æ”¾ã€‚"
#: doc/classes/AudioServer.xml doc/classes/AudioStreamPlayer.xml
@@ -11907,19 +11925,19 @@ msgstr "返回系统上检测到的所有音频输入设备的å称。"
#: doc/classes/AudioServer.xml
msgid "Generates an [AudioBusLayout] using the available buses and effects."
-msgstr "使用å¯ç”¨çš„æ€»çº¿å’Œæ•ˆæžœç”Ÿæˆ[AudioBusLayout]。"
+msgstr "使用å¯ç”¨çš„æ€»çº¿å’Œæ•ˆæžœæ¥ç”Ÿæˆ [AudioBusLayout]。"
#: doc/classes/AudioServer.xml
msgid ""
"Returns the amount of channels of the bus at index [code]bus_idx[/code]."
-msgstr "返回索引为[code]bus_idx[/code]çš„æ€»çº¿é€šé“æ•°ã€‚"
+msgstr "返回索引为 [code]bus_idx[/code] çš„æ€»çº¿çš„é€šé“æ•°ã€‚"
#: doc/classes/AudioServer.xml
msgid ""
"Returns the [AudioEffect] at position [code]effect_idx[/code] in bus "
"[code]bus_idx[/code]."
msgstr ""
-"返回总线 [code]bus_idx[/code] in [code]effect_idx[/code] ä½ç½®çš„ "
+"返回总线 [code]bus_idx[/code] 中ä½äºŽ [code]effect_idx[/code] çš„ "
"[AudioEffect]。"
#: doc/classes/AudioServer.xml
@@ -11931,41 +11949,41 @@ msgid ""
"Returns the [AudioEffectInstance] assigned to the given bus and effect "
"indices (and optionally channel)."
msgstr ""
-"返回分é…给给定总线和效果指数(以åŠå¯é€‰çš„通é“)的[AudioEffectInstance]。"
+"返回分é…给给定总线和效果指数(以åŠå¯é€‰çš„通é“)的 [AudioEffectInstance]。"
#: doc/classes/AudioServer.xml
msgid "Returns the index of the bus with the name [code]bus_name[/code]."
-msgstr "返回å称为[code]bus_name[/code]的总线的索引。"
+msgstr "返回å称为 [code]bus_name[/code] 的总线的索引。"
#: doc/classes/AudioServer.xml
msgid "Returns the name of the bus with the index [code]bus_idx[/code]."
-msgstr "返回索引为 [code]bus_idx[/code] 的总线å称。"
+msgstr "返回索引为 [code]bus_idx[/code] 的总线的å称。"
#: doc/classes/AudioServer.xml
msgid ""
"Returns the peak volume of the left speaker at bus index [code]bus_idx[/"
"code] and channel index [code]channel[/code]."
msgstr ""
-"返回总线索引[code]bus_idx[/code]和通é“索引[code]channel[/code]处左扬声器的峰"
-"值音é‡ã€‚"
+"返回总线索引 [code]bus_idx[/code] 和通é“索引 [code]channel[/code] 处左扬声器"
+"的峰值音é‡ã€‚"
#: doc/classes/AudioServer.xml
msgid ""
"Returns the peak volume of the right speaker at bus index [code]bus_idx[/"
"code] and channel index [code]channel[/code]."
msgstr ""
-"返回总线索引[code]bus_idx[/code]和通é“索引[code]channel[/code]处峿‰¬å£°å™¨çš„å³°"
-"值音é‡ã€‚"
+"返回总线索引 [code]bus_idx[/code] 和通é“索引 [code]channel[/code] 处峿‰¬å£°å™¨"
+"的峰值音é‡ã€‚"
#: doc/classes/AudioServer.xml
msgid ""
"Returns the name of the bus that the bus at index [code]bus_idx[/code] sends "
"to."
-msgstr "返回ä½äºŽç´¢å¼•[code]bus_idx[/code]处的总线所å‘é€çš„æ€»çº¿å称。"
+msgstr "返回ä½äºŽç´¢å¼• [code]bus_idx[/code] 处的总线所å‘é€çš„æ€»çº¿å称。"
#: doc/classes/AudioServer.xml
msgid "Returns the volume of the bus at index [code]bus_idx[/code] in dB."
-msgstr "返回索引[code]bus_idx[/code]处总线的音é‡ï¼Œå•ä½ä¸ºdB。"
+msgstr "返回索引 [code]bus_idx[/code] 处总线的音é‡ï¼Œå•ä½ä¸º dB。"
#: doc/classes/AudioServer.xml
msgid "Returns the names of all audio devices detected on the system."
@@ -12008,13 +12026,13 @@ msgstr ""
#: doc/classes/AudioServer.xml
msgid "If [code]true[/code], the bus at index [code]bus_idx[/code] is muted."
-msgstr "如果为 [code]true[/code],则索引[code]bus_idx[/code]处的总线被é™éŸ³ã€‚"
+msgstr "如果为 [code]true[/code],则索引 [code]bus_idx[/code] 处的总线被é™éŸ³ã€‚"
#: doc/classes/AudioServer.xml
msgid ""
"If [code]true[/code], the bus at index [code]bus_idx[/code] is in solo mode."
msgstr ""
-"如果为 [code]true[/code],则索引[code]bus_idx[/code]处的总线处于solo模å¼ã€‚"
+"如果为 [code]true[/code],则索引 [code]bus_idx[/code] å¤„çš„æ€»çº¿å¤„äºŽç‹¬å¥æ¨¡å¼ã€‚"
#: doc/classes/AudioServer.xml
msgid ""
@@ -12027,28 +12045,28 @@ msgstr ""
#: doc/classes/AudioServer.xml
msgid ""
"Moves the bus from index [code]index[/code] to index [code]to_index[/code]."
-msgstr "将总线从索引[code]index[/code]移动到索引[code]to_index[/code]。"
+msgstr "将总线从索引 [code]index[/code] 移动到索引 [code]to_index[/code]。"
#: doc/classes/AudioServer.xml
msgid "Removes the bus at index [code]index[/code]."
-msgstr "移除索引[code]index[/code]处的总线。"
+msgstr "移除索引 [code]index[/code] 处的总线。"
#: doc/classes/AudioServer.xml
msgid ""
"Removes the effect at index [code]effect_idx[/code] from the bus at index "
"[code]bus_idx[/code]."
msgstr ""
-"将索引 [code]effect_idx[/code] 的效果从索引 [code]bus_idx[/code] 的总线上删"
+"将索引 [code]effect_idx[/code] 的效果从索引 [code]bus_idx[/code] 的总线上移"
"除。"
#: doc/classes/AudioServer.xml
msgid "Overwrites the currently used [AudioBusLayout]."
-msgstr "覆盖当å‰ä½¿ç”¨çš„[AudioBusLayout]。"
+msgstr "覆盖当å‰ä½¿ç”¨çš„ [AudioBusLayout]。"
#: doc/classes/AudioServer.xml
msgid ""
"Sets the name of the bus at index [code]bus_idx[/code] to [code]name[/code]."
-msgstr "将索引[code]bus_idx[/code]处的总线å称设置为[code]name[/code]。"
+msgstr "将索引 [code]bus_idx[/code] 处的总线å称设置为 [code]name[/code]。"
#: doc/classes/AudioServer.xml
msgid ""
@@ -12066,7 +12084,7 @@ msgstr ""
#: doc/classes/AudioServer.xml
msgid "Swaps the position of two effects in bus [code]bus_idx[/code]."
-msgstr "在[code]bus_idx[/code]中交æ¢ä¸¤ä¸ªæ•ˆæžœçš„ä½ç½®ã€‚"
+msgstr "在 [code]bus_idx[/code] 中交æ¢ä¸¤ä¸ªæ•ˆæžœçš„ä½ç½®ã€‚"
#: doc/classes/AudioServer.xml
msgid ""
@@ -12111,11 +12129,12 @@ msgid ""
"Scales the rate at which audio is played (i.e. setting it to [code]0.5[/"
"code] will make the audio be played twice as fast)."
msgstr ""
-"缩放播放音频的速率(å³å°†å…¶è®¾ç½®ä¸º[code]0.5[/code]将使音频播放速度æé«˜ä¸€å€ï¼‰ã€‚"
+"缩放播放音频的速率(å³å°†å…¶è®¾ç½®ä¸º [code]0.5[/code] 将使音频播放速度æé«˜ä¸€"
+"å€ï¼‰ã€‚"
#: doc/classes/AudioServer.xml
msgid "Emitted when the [AudioBusLayout] changes."
-msgstr "当[AudioBusLayout]æ”¹å˜æ—¶å‘出。"
+msgstr "当 [AudioBusLayout] æ”¹å˜æ—¶å‘出。"
#: doc/classes/AudioServer.xml
msgid "Two or fewer speakers were detected."
@@ -12123,15 +12142,15 @@ msgstr "检测到两个或更少的扬声器。"
#: doc/classes/AudioServer.xml
msgid "A 3.1 channel surround setup was detected."
-msgstr "检测到3.1声é“环绕声设置。"
+msgstr "检测到 3.1 声é“环绕声设置。"
#: doc/classes/AudioServer.xml
msgid "A 5.1 channel surround setup was detected."
-msgstr "检测到5.1声é“环绕声设置。"
+msgstr "检测到 5.1 声é“环绕声设置。"
#: doc/classes/AudioServer.xml
msgid "A 7.1 channel surround setup was detected."
-msgstr "检测到7.1声é“环绕声设置。"
+msgstr "检测到 7.1 声é“环绕声设置。"
#: doc/classes/AudioStream.xml
msgid "Base class for audio streams."
@@ -12143,8 +12162,8 @@ msgid ""
"music playback, and support WAV (via [AudioStreamSample]) and OGG (via "
"[AudioStreamOGGVorbis]) file formats."
msgstr ""
-"音频æµçš„基类。音频æµç”¨äºŽå£°éŸ³æ•ˆæžœå’ŒéŸ³ä¹æ’­æ”¾ï¼Œæ”¯æŒ WAV(通过"
-"[AudioStreamSample])和 OGG(通过[AudioStreamOGGVorbis])文件格å¼ã€‚"
+"音频æµçš„基类。音频æµç”¨äºŽå£°éŸ³æ•ˆæžœå’ŒéŸ³ä¹æ’­æ”¾ï¼Œæ”¯æŒ WAV(通过 "
+"[AudioStreamSample])和 OGG(通过 [AudioStreamOGGVorbis])文件格å¼ã€‚"
#: doc/classes/AudioStream.xml doc/classes/AudioStreamPlayer.xml
msgid "Audio streams"
@@ -12176,7 +12195,7 @@ msgid ""
"class from GDScript, consider using a lower [member mix_rate] such as 11,025 "
"Hz or 22,050 Hz."
msgstr ""
-"此音频æµä¸æ’­æ”¾å£°éŸ³ï¼Œéœ€è¦è„šæœ¬ä¸ºå…¶ç”ŸæˆéŸ³é¢‘æ•°æ®ã€‚å‚阅"
+"此音频æµä¸æ’­æ”¾å£°éŸ³ï¼Œéœ€è¦è„šæœ¬ä¸ºå…¶ç”ŸæˆéŸ³é¢‘æ•°æ®ã€‚å¦è¯·å‚阅 "
"[AudioStreamGeneratorPlayback]。\n"
"å¦è¯·å‚阅 [AudioEffectSpectrumAnalyzer] 用于执行实时音频频谱分æžã€‚\n"
"[b]注æ„:[/b]由于性能é™åˆ¶ï¼Œæœ€å¥½ä»Ž C# 或通过 GDNative 编译的语言中使用此类。如"
@@ -12221,7 +12240,7 @@ msgstr ""
#: doc/classes/AudioStreamGeneratorPlayback.xml
msgid "Plays back audio generated using [AudioStreamGenerator]."
-msgstr "播放使用[AudioStreamGenerator]生æˆçš„音频。"
+msgstr "播放使用 [AudioStreamGenerator] 生æˆçš„音频。"
#: doc/classes/AudioStreamGeneratorPlayback.xml
msgid ""
@@ -12287,7 +12306,7 @@ msgstr "包å«ä»¥å­—节为å•ä½çš„音频数æ®ã€‚"
msgid ""
"If [code]true[/code], the stream will automatically loop when it reaches the "
"end."
-msgstr "如果[code]true[/code],当æµåˆ°è¾¾æœ«å°¾æ—¶å°†è‡ªåŠ¨å¾ªçŽ¯ã€‚"
+msgstr "如果为 [code]true[/code],当æµåˆ°è¾¾æœ«å°¾æ—¶å°†è‡ªåŠ¨å¾ªçŽ¯ã€‚"
#: modules/minimp3/doc_classes/AudioStreamMP3.xml
#: modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml
@@ -12321,8 +12340,8 @@ msgid ""
"[AudioStreamPlayer3D] instead of [AudioStreamPlayer]."
msgstr ""
"以éžä½ç½®æ–¹å¼æ”¯æŒæ’­æ”¾éŸ³é¢‘æµã€‚\n"
-"è¦åœ¨ä½ç½®ä¸Šæ’­æ”¾éŸ³é¢‘,请使用[AudioStreamPlayer2D]或[AudioStreamPlayer3D]è€Œä¸æ˜¯"
-"[AudioStreamPlayer]。"
+"è¦åœ¨ä½ç½®ä¸Šæ’­æ”¾éŸ³é¢‘,请使用 [AudioStreamPlayer2D] 或 [AudioStreamPlayer3D] 而"
+"䏿˜¯ [AudioStreamPlayer]。"
#: doc/classes/AudioStreamPlayer.xml
msgid "Returns the position in the [AudioStream] in seconds."
@@ -12350,18 +12369,24 @@ msgstr "åœæ­¢éŸ³é¢‘。"
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
msgid "If [code]true[/code], audio plays when added to scene tree."
-msgstr "为 [code]true[/code] 时在添加到场景树时播放音频。"
+msgstr "如果为 [code]true[/code],在添加到场景树时将播放音频。"
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
-msgstr "播放此音频的总线。"
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
+msgstr ""
#: doc/classes/AudioStreamPlayer.xml
msgid ""
"If the audio configuration has more than two speakers, this sets the target "
"channels. See [enum MixTarget] constants."
msgstr ""
-"如果音频é…置有两个以上的扬声器,则设置目标通é“。请å‚阅[enum MixTarget]常é‡ã€‚"
+"如果音频é…置有两个以上的扬声器,则设置目标通é“ã€‚è§ [enum MixTarget] 常é‡ã€‚"
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12373,19 +12398,19 @@ msgstr "音频的音高和节å¥ï¼Œä½œä¸ºéŸ³é¢‘æ ·æœ¬çš„é‡‡æ ·çŽ‡çš„å€æ•°ã€‚"
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
#: doc/classes/AudioStreamPlayer3D.xml
msgid "If [code]true[/code], audio is playing."
-msgstr "如果[code]true[/code],则播放音频。"
+msgstr "如果为 [code]true[/code],则播放音频。"
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
msgid "The [AudioStream] object to be played."
-msgstr "è¦æ’­æ”¾çš„[AudioStream]对象。"
+msgstr "è¦æ’­æ”¾çš„ [AudioStream] 对象。"
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
msgid ""
"If [code]true[/code], the playback is paused. You can resume it by setting "
"[code]stream_paused[/code] to [code]false[/code]."
msgstr ""
-"如果 [code]true[/code]ï¼Œåˆ™æš‚åœæ’­æ”¾ã€‚您å¯ä»¥é€šè¿‡å°† [code]stream_paused[/code] "
-"设置为 [code]false[/code] æ¥æ¢å¤æ’­æ”¾ã€‚"
+"如果为 [code]true[/code]ï¼Œåˆ™æš‚åœæ’­æ”¾ã€‚您å¯ä»¥é€šè¿‡å°† [code]stream_paused[/"
+"code] 设置为 [code]false[/code] æ¥æ¢å¤æ’­æ”¾ã€‚"
#: doc/classes/AudioStreamPlayer.xml
msgid "Volume of sound, in dB."
@@ -12423,10 +12448,10 @@ msgid ""
"audible to human hearing)."
msgstr ""
"播放音频,éšç€ä¸Žå±å¹•中心的è·ç¦»è€Œå‡å¼±ã€‚\n"
-"å‚阅[AudioStreamPlayer]æ¥æ’­æ”¾éžä½ç½®æ€§çš„声音。\n"
-"[b]注æ„:[/b]éšè—一个[AudioStreamPlayer2D]节点并ä¸èƒ½ç¦ç”¨å…¶éŸ³é¢‘è¾“å‡ºã€‚è¦æš‚æ—¶ç¦"
-"用[AudioStreamPlayer2D]的音频输出,请将[member volume_db]设置为一个éžå¸¸ä½Žçš„"
-"值,如[code]-100[/code](人的å¬è§‰å¬ä¸åˆ°ï¼‰ã€‚"
+"å‚阅 [AudioStreamPlayer] æ¥æ’­æ”¾éžä½ç½®æ€§çš„声音。\n"
+"[b]注æ„:[/b]éšè—一个 [AudioStreamPlayer2D] 节点并ä¸èƒ½ç¦ç”¨å…¶éŸ³é¢‘è¾“å‡ºã€‚è¦æš‚æ—¶"
+"ç¦ç”¨ [AudioStreamPlayer2D] 的音频输出,请将 [member volume_db] 设置为一个éžå¸¸"
+"低的值,如[code]-100[/code](人的å¬è§‰å¬ä¸åˆ°ï¼‰ã€‚"
#: doc/classes/AudioStreamPlayer2D.xml doc/classes/AudioStreamPlayer3D.xml
msgid "Returns the position in the [AudioStream]."
@@ -12502,7 +12527,7 @@ msgstr ""
msgid ""
"Returns the [AudioStreamPlayback] object associated with this "
"[AudioStreamPlayer3D]."
-msgstr "返回与该[AudioStreamPlayer3D]相关è”çš„[AudioStreamPlayback]对象。"
+msgstr "返回与这个 [AudioStreamPlayer3D] 相关è”çš„ [AudioStreamPlayback] 对象。"
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
@@ -12543,12 +12568,18 @@ msgid ""
"If [code]true[/code], audio plays when the AudioStreamPlayer3D node is added "
"to scene tree."
msgstr ""
-"如果 [code]true[/code],则在将 AudioStreamPlayer3D 节点添加到场景树时播放音"
+"如果为 [code]true[/code],则在将 AudioStreamPlayer3D 节点添加到场景树时播放音"
"频。"
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
-msgstr "播放此音频的总线。"
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
+msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
@@ -12571,7 +12602,7 @@ msgstr "音频到达相机的角度,ä¸å—è¡°å‡ã€‚"
msgid ""
"If [code]true[/code], the audio should be dampened according to the "
"direction of the sound."
-msgstr "如果[code]true[/code],则应根æ®å£°éŸ³çš„æ–¹å‘对音频进行衰å‡ã€‚"
+msgstr "如果为 [code]true[/code],则应根æ®å£°éŸ³çš„æ–¹å‘对音频进行衰å‡ã€‚"
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
@@ -12599,15 +12630,15 @@ msgstr "决定当音æºè¶…出 [member max_distance] 范围时,是å¦åº”该暂å
#: doc/classes/AudioStreamPlayer3D.xml
msgid "The [AudioStream] resource to be played."
-msgstr "è¦æ’­æ”¾çš„[AudioStream]资æºã€‚"
+msgstr "è¦æ’­æ”¾çš„ [AudioStream] 资æºã€‚"
#: doc/classes/AudioStreamPlayer3D.xml
msgid ""
"If [code]true[/code], the playback is paused. You can resume it by setting "
"[member stream_paused] to [code]false[/code]."
msgstr ""
-"如果[code]true[/code],则播放会暂åœã€‚ä½ å¯ä»¥é€šè¿‡è®¾ç½®[member stream_paused]为 "
-"[code]false[/code]æ¥æ¢å¤å®ƒã€‚"
+"如果为 [code]true[/code],则播放会暂åœã€‚ä½ å¯ä»¥é€šè¿‡å°† [member stream_paused] "
+"设置为 [code]false[/code]æ¥æ¢å¤å®ƒã€‚"
#: doc/classes/AudioStreamPlayer3D.xml
msgid "The base sound level unaffected by dampening, in decibels."
@@ -12639,7 +12670,7 @@ msgid ""
"greater than [code]0.0[/code] to achieve linear attenuation clamped to a "
"sphere of a defined size."
msgstr ""
-"ä¸ä¼šæ ¹æ®è·ç¦»è¡°å‡å“度。与 [AudioStreamPlayer] ä¸åŒï¼Œå£°éŸ³ä»ä¼šåœ¨ä½ç½®ä¸Šè¢«å¬åˆ°ã€‚ "
+"ä¸ä¼šæ ¹æ®è·ç¦»è¡°å‡å“度。与 [AudioStreamPlayer] ä¸åŒï¼Œå£°éŸ³ä»ä¼šåœ¨ä½ç½®ä¸Šè¢«å¬åˆ°ã€‚"
"[constant ATTENUATION_DISABLED] å¯ä»¥ä¸Žå¤§äºŽ [code]0.0[/code] çš„ [member "
"max_distance] 值结åˆä½¿ç”¨ï¼Œä»¥å®žçŽ°çº¿æ€§è¡°å‡ï¼Œé™åˆ¶åœ¨å®šä¹‰çš„çƒä½“大å°ã€‚"
@@ -12685,7 +12716,7 @@ msgstr "æ¯æ¬¡å¼€å§‹æ—¶éšæœºå˜æ¢éŸ³é«˜ã€‚"
#: doc/classes/AudioStreamRandomPitch.xml
msgid "The current [AudioStream]."
-msgstr "当å‰çš„[AudioStream]。"
+msgstr "当å‰çš„ [AudioStream]。"
#: doc/classes/AudioStreamRandomPitch.xml
msgid "The intensity of random pitch variation."
@@ -12693,7 +12724,7 @@ msgstr "éšæœºéŸ³é«˜å˜åŒ–的强度。"
#: doc/classes/AudioStreamSample.xml
msgid "Stores audio data loaded from WAV files."
-msgstr "存储从WAV文件加载的音频数æ®ã€‚"
+msgstr "存储从 WAV 文件加载的音频数æ®ã€‚"
#: doc/classes/AudioStreamSample.xml
msgid ""
@@ -12717,10 +12748,10 @@ msgid ""
"[b]Note:[/b] A [code].wav[/code] extension is automatically appended to "
"[code]path[/code] if it is missing."
msgstr ""
-"å°†AudioStreamSample作为WAV文件ä¿å­˜åˆ°[code]path[/code]。无法ä¿å­˜IMA ADPCMæ ¼å¼"
-"的样本。\n"
-"[b]注æ„:[/b]如果缺少[code].wav[/code]扩展å,则会自动将其附加到[code]path[/"
-"code]。"
+"å°† AudioStreamSample 作为 WAV 文件ä¿å­˜åˆ° [code]path[/code]。无法ä¿å­˜ IMA "
+"ADPCM æ ¼å¼çš„æ ·æœ¬ã€‚\n"
+"[b]注æ„:[/b]如果缺少 [code].wav[/code] 扩展å,则会自动将其附加到 "
+"[code]path[/code]。"
#: doc/classes/AudioStreamSample.xml
msgid ""
@@ -12734,7 +12765,7 @@ msgstr ""
#: doc/classes/AudioStreamSample.xml
msgid "Audio format. See [enum Format] constants for values."
-msgstr "音频格å¼ã€‚å‚阅[enum Format]常é‡çš„值。"
+msgstr "音频格å¼ã€‚å‚阅 [enum Format] 常é‡çš„值。"
#: doc/classes/AudioStreamSample.xml
msgid ""
@@ -12850,9 +12881,9 @@ msgid ""
"derived nodes as [i]siblings[/i] to the BackBufferCopy node instead of "
"adding them as children."
msgstr ""
-"用于对当å‰å±å¹•显示进行åŽå°ç¼“冲的节点。 BackBufferCopy 节点中定义的区域与其覆"
-"ç›–å±å¹•çš„å†…å®¹ä¸€èµ·ç¼“å†²ï¼Œæˆ–è€…æ ¹æ®æ‹·è´æ¨¡å¼è®¾ç½®çš„æ•´ä¸ªå±å¹•进行缓冲。在ç€è‰²å™¨è„šæœ¬ä¸­"
-"使用 [code]texture(SCREEN_TEXTURE, ...)[/code] 函数æ¥è®¿é—®ç¼“冲区。\n"
+"用于对当å‰å±å¹•显示进行åŽå°ç¼“冲的节点。BackBufferCopy 节点中定义的区域与其覆盖"
+"å±å¹•çš„å†…å®¹ä¸€èµ·ç¼“å†²ï¼Œæˆ–è€…æ ¹æ®æ‹·è´æ¨¡å¼è®¾ç½®çš„æ•´ä¸ªå±å¹•进行缓冲。在ç€è‰²å™¨è„šæœ¬ä¸­ä½¿"
+"用 [code]texture(SCREEN_TEXTURE, ...)[/code] 函数æ¥è®¿é—®ç¼“冲区。\n"
"[b]注æ„:[/b]由于该节点继承自 [Node2D] è€Œéž [Control],锚点和边è·å°†ä¸ä¼šåº”用于"
"从 [Control] 派生的å­èŠ‚ç‚¹ã€‚è¿™åœ¨è°ƒæ•´çª—å£å¤§å°æ—¶å¯èƒ½ä¼šå‡ºçŽ°é—®é¢˜ã€‚ä¸ºé¿å…è¿™ç§æƒ…况,"
"请将 [Control] 派生节点添加为 BackBufferCopy 节点的[i]åŒçº§[/i],ä¸è¦å°†å®ƒä»¬æ·»"
@@ -12860,7 +12891,7 @@ msgstr ""
#: doc/classes/BackBufferCopy.xml
msgid "Buffer mode. See [enum CopyMode] constants."
-msgstr "缓冲区模å¼ã€‚å‚阅 [enum CopyMode] 常é‡ã€‚"
+msgstr "缓冲区模å¼ã€‚è§ [enum CopyMode] 常é‡ã€‚"
#: doc/classes/BackBufferCopy.xml
msgid ""
@@ -12919,10 +12950,10 @@ msgid ""
"If no save path is provided it will try to match the path from the current "
"[member light_data]."
msgstr ""
-"烘焙光照贴图,从给定的[code]from_node[/code]根节点扫æï¼Œå¹¶å°†äº§ç”Ÿçš„"
-"[BakedLightmapData]ä¿å­˜åœ¨[code]data_save_path[/code]中。如果没有æä¾›æ ¹èŠ‚ç‚¹ï¼Œ"
-"此节点的父节点将作为根节点。如果没有æä¾›ä¿å­˜è·¯å¾„,将å°è¯•匹é…当å‰[member "
-"light_data]的路径。"
+"烘焙光照贴图,从给定的 [code]from_node[/code] 根节点扫æï¼Œå¹¶å°†äº§ç”Ÿçš„ "
+"[BakedLightmapData] ä¿å­˜åœ¨ [code]data_save_path[/code] 中。如果没有æä¾›æ ¹èŠ‚"
+"点,此节点的父节点将作为根节点。如果没有æä¾›ä¿å­˜è·¯å¾„,将å°è¯•匹é…å½“å‰ [member "
+"light_data] 的路径。"
#: doc/classes/BakedLightmap.xml
msgid ""
@@ -12969,11 +13000,11 @@ msgid ""
"[b]Note:[/b] [member bounce_indirect_energy] only has an effect if [member "
"bounces] is set to a value greater than or equal to [code]1[/code]."
msgstr ""
-"æ¯æ¬¡å弹的能é‡ä¹˜æ•°ã€‚较高的值将使间接照明更亮。 [code]1.0[/code] 的值表示与物"
-"ç†ç›¸ä¸€è‡´çš„行为,但在使用少é‡å弹时,å¯ä»¥ä½¿ç”¨æ›´é«˜çš„值使间接照明传播更明显。这"
-"å¯ç”¨äºŽé€šè¿‡é™ä½Ž [member bounces] 的数é‡ç„¶åŽå¢žåŠ  [member "
-"bounce_indirect_energy] æ¥åŠ å¿«çƒ˜ç„™æ—¶é—´ã€‚ä¸Ž [member BakedLightmapData.energy] "
-"ä¸åŒï¼Œæ­¤å±žæ€§ä¸ä¼šå½±å“ç¯å…‰èŠ‚ç‚¹ã€å‘å…‰æè´¨å’ŒçŽ¯å¢ƒå‘出的直接光照。\n"
+"æ¯æ¬¡å弹的能é‡ä¹˜æ•°ã€‚较高的值将使间接照明更亮。[code]1.0[/code] 的值表示与物ç†"
+"相一致的行为,但在使用少é‡å弹时,å¯ä»¥ä½¿ç”¨æ›´é«˜çš„值使间接照明传播更明显。这å¯"
+"用于通过é™ä½Ž [member bounces] 的数é‡ç„¶åŽå¢žåŠ  [member bounce_indirect_energy] "
+"æ¥åŠ å¿«çƒ˜ç„™æ—¶é—´ã€‚ä¸Ž [member BakedLightmapData.energy] ä¸åŒï¼Œæ­¤å±žæ€§ä¸ä¼šå½±å“ç¯å…‰"
+"节点ã€å‘å…‰æè´¨å’ŒçŽ¯å¢ƒå‘出的直接光照。\n"
"[b]注æ„:[/b][member bounce_indirect_energy] 仅在 [member bounces] 设置为大于"
"等于 [code]1[/code] 的值时有效。"
@@ -12981,7 +13012,8 @@ msgstr ""
msgid ""
"Number of light bounces that are taken into account during baking. See also "
"[member bounce_indirect_energy]."
-msgstr "烘焙过程中考虑的光线å射次数。å‚阅 [member bounce_indirect_energy]。"
+msgstr ""
+"烘焙过程中考虑的光线å射次数。å¦è¯·å‚阅 [member bounce_indirect_energy]。"
#: doc/classes/BakedLightmap.xml
msgid "Grid size used for real-time capture information on dynamic objects."
@@ -13228,7 +13260,7 @@ msgid ""
"directly (it doesn't display anything). Other types of buttons inherit from "
"it."
msgstr ""
-"BaseButton是按钮的抽象基类,所以ä¸åº”è¯¥ç›´æŽ¥ä½¿ç”¨å®ƒï¼ˆå®ƒä¸æ˜¾ç¤ºä»»ä½•东西)。其他类"
+"BaseButton 是按钮的抽象基类,所以ä¸åº”è¯¥ç›´æŽ¥ä½¿ç”¨å®ƒï¼ˆå®ƒä¸æ˜¾ç¤ºä»»ä½•东西)。其他类"
"型的按钮都继承自它。"
#: doc/classes/BaseButton.xml
@@ -13242,7 +13274,7 @@ msgstr ""
#: doc/classes/BaseButton.xml
msgid ""
"Called when the button is toggled (only if [member toggle_mode] is active)."
-msgstr "å½“æŒ‰é’®è¢«åˆ‡æ¢æ—¶è°ƒç”¨(仅当 [member toggle_mode] å¤„äºŽæ´»åŠ¨çŠ¶æ€æ—¶)。"
+msgstr "å½“æŒ‰é’®è¢«åˆ‡æ¢æ—¶è°ƒç”¨ï¼ˆä»…当 [member toggle_mode] å¤„äºŽæ´»åŠ¨çŠ¶æ€æ—¶ï¼‰ã€‚"
#: doc/classes/BaseButton.xml
msgid ""
@@ -13269,10 +13301,10 @@ msgid ""
"[b]Note:[/b] This method doesn't unpress other buttons in its button [member "
"group]."
msgstr ""
-"æ”¹å˜æŒ‰é’®çš„[member pressed]状æ€ï¼Œä¸è§¦å‘[signal toggled]ã€‚å½“ä½ åªæƒ³æ”¹å˜æŒ‰é’®çš„状"
-"æ€è€Œä¸å‘逿Œ‰ä¸‹äº‹ä»¶æ—¶ä½¿ç”¨ï¼ˆä¾‹å¦‚,在åˆå§‹åŒ–åœºæ™¯æ—¶ï¼‰ã€‚åªæœ‰å½“[member toggle_mode]"
-"是[code]true[/code] æ—¶æ‰æœ‰æ•ˆã€‚\n"
-"[b]注æ„:[/b]这个方法ä¸ä¼šé‡Šæ”¾å…¶æŒ‰é’®[member group] 中的其他按钮。"
+"æ”¹å˜æŒ‰é’®çš„ [member pressed] 状æ€ï¼Œä¸è§¦å‘ [signal toggled]ã€‚å½“ä½ åªæƒ³æ”¹å˜æŒ‰é’®çš„"
+"状æ€è€Œä¸å‘逿Œ‰ä¸‹äº‹ä»¶æ—¶ä½¿ç”¨ï¼ˆä¾‹å¦‚,在åˆå§‹åŒ–åœºæ™¯æ—¶ï¼‰ã€‚åªæœ‰å½“ [member "
+"toggle_mode] 是 [code]true[/code] æ—¶æ‰æœ‰æ•ˆã€‚\n"
+"[b]注æ„:[/b]这个方法ä¸ä¼šé‡Šæ”¾å…¶æŒ‰é’® [member group] 中的其他按钮。"
#: doc/classes/BaseButton.xml
msgid ""
@@ -13294,7 +13326,7 @@ msgstr ""
msgid ""
"If [code]true[/code], the button is in disabled state and can't be clicked "
"or toggled."
-msgstr "如果[code]true[/code],则该按钮处于ç¦ç”¨çжæ€ï¼Œæ— æ³•点击或切æ¢ã€‚"
+msgstr "如果为 [code]true[/code],则该按钮处于ç¦ç”¨çжæ€ï¼Œæ— æ³•点击或切æ¢ã€‚"
#: doc/classes/BaseButton.xml
msgid ""
@@ -13302,12 +13334,12 @@ msgid ""
"will be removed in Godot 4.0. This property no longer has any effect when "
"set. Please use [member Control.focus_mode] instead."
msgstr ""
-"[i]已弃用。[/i] 由于冗余,此属性已弃用,将在 Godot 4.0 中删除。此属性在设置åŽ"
+"[i]已弃用。[/i]由于冗余,此属性已弃用,将在 Godot 4.0 中移除。此属性在设置åŽ"
"ä¸ä¼šæœ‰ä»»ä½•å½±å“。请改用 [member Control.focus_mode]。"
#: doc/classes/BaseButton.xml
msgid "[ButtonGroup] associated to the button."
-msgstr "与按钮相关è”çš„[ButtonGroup]。"
+msgstr "与按钮相关è”çš„ [ButtonGroup]。"
#: doc/classes/BaseButton.xml
msgid ""
@@ -13317,7 +13349,8 @@ msgid ""
"Signals will be emitted at the same moment regardless of this property's "
"value."
msgstr ""
-"如果[code]true[/code]ï¼Œå½“æŒ‰ä¸‹æŒ‰é’®æ—¶å°†å…‰æ ‡ç§»åˆ°æŒ‰é’®å¤–æ—¶ï¼ŒæŒ‰é’®ä¼šä¿æŒæŒ‰ä¸‹çжæ€ã€‚\n"
+"如果为 [code]true[/code]ï¼Œå½“æŒ‰ä¸‹æŒ‰é’®æ—¶å°†å…‰æ ‡ç§»åˆ°æŒ‰é’®å¤–æ—¶ï¼ŒæŒ‰é’®ä¼šä¿æŒæŒ‰ä¸‹çж"
+"æ€ã€‚\n"
"[b]注æ„:[/b]该属性åªå½±å“按钮的视觉表现。无论该属性的值是多少,信å·éƒ½ä¼šåœ¨åŒä¸€"
"时刻å‘出。"
@@ -13330,7 +13363,7 @@ msgid ""
"emitted. If you want to change the pressed state without emitting that "
"signal, use [method set_pressed_no_signal]."
msgstr ""
-"如果 [code]true[/code],按钮为按下状æ€ã€‚表示按钮被按下或切æ¢ï¼ˆå¦‚æžœ [member "
+"如果为 [code]true[/code],按钮为按下状æ€ã€‚表示按钮被按下或切æ¢ï¼ˆå¦‚æžœ [member "
"toggle_mode] 处于激活状æ€ï¼‰ã€‚仅当 [member toggle_mode] 为 [code]true[/code] "
"æ—¶æ‰æœ‰æ•ˆã€‚\n"
"[b]注æ„:[/b]设置 [member pressed] 将导致 [signal toggled] 触å‘。如果你想在ä¸"
@@ -13338,21 +13371,21 @@ msgstr ""
#: doc/classes/BaseButton.xml
msgid "[ShortCut] associated to the button."
-msgstr "与按钮相关è”çš„[ShortCut]。"
+msgstr "与按钮相关è”çš„ [ShortCut]。"
#: doc/classes/BaseButton.xml
msgid ""
"If [code]true[/code], the button will add information about its shortcut in "
"the tooltip."
-msgstr "如果[code]true[/code],按钮将在工具æç¤ºä¸­æ·»åŠ å…¶å¿«æ·æ–¹å¼çš„ä¿¡æ¯ã€‚"
+msgstr "如果为 [code]true[/code],按钮将在工具æç¤ºä¸­æ·»åŠ å…¶å¿«æ·æ–¹å¼çš„ä¿¡æ¯ã€‚"
#: doc/classes/BaseButton.xml
msgid ""
"If [code]true[/code], the button is in toggle mode. Makes the button flip "
"state between pressed and unpressed each time its area is clicked."
msgstr ""
-"如果[code]true[/code]ï¼Œåˆ™æŒ‰é’®å¤„äºŽåˆ‡æ¢æ¨¡å¼ã€‚ä½¿æŒ‰é’®åœ¨æ¯æ¬¡ç‚¹å‡»å…¶åŒºåŸŸæ—¶ï¼Œåœ¨æŒ‰ä¸‹å’Œ"
-"未按下之间转æ¢çжæ€ã€‚"
+"如果为 [code]true[/code]ï¼Œåˆ™æŒ‰é’®å¤„äºŽåˆ‡æ¢æ¨¡å¼ã€‚ä½¿æŒ‰é’®åœ¨æ¯æ¬¡ç‚¹å‡»å…¶åŒºåŸŸæ—¶ï¼Œåœ¨æŒ‰"
+"下和未按下之间转æ¢çжæ€ã€‚"
#: doc/classes/BaseButton.xml
msgid "Emitted when the button starts being held down."
@@ -13382,14 +13415,14 @@ msgid ""
"(only if [member toggle_mode] is active). The new state is contained in the "
"[code]button_pressed[/code] argument."
msgstr ""
-"当按钮刚刚在按下和正常状æ€ä¹‹é—´åˆ‡æ¢æ—¶å‘出(仅当[member toggle_mode]处于活动状æ€"
-"æ—¶)。新状æ€åŒ…å«åœ¨[code]button_pressed[/code]傿•°ä¸­ã€‚"
+"当按钮刚刚在按下和正常状æ€ä¹‹é—´åˆ‡æ¢æ—¶å‘出(仅当 [member toggle_mode] 处于活动"
+"çŠ¶æ€æ—¶ï¼‰ã€‚新状æ€åŒ…å«åœ¨ [code]button_pressed[/code] 傿•°ä¸­ã€‚"
#: doc/classes/BaseButton.xml
msgid ""
"The normal state (i.e. not pressed, not hovered, not toggled and enabled) of "
"buttons."
-msgstr "按钮的正常状æ€(峿²¡æœ‰æŒ‰ä¸‹ã€æ²¡æœ‰æ‚¬åœã€æ²¡æœ‰åˆ‡æ¢å’Œå¯ç”¨)。"
+msgstr "按钮的正常状æ€ï¼ˆå³æœªæŒ‰ä¸‹ã€æœªæ‚¬åœã€æœªåˆ‡æ¢å’Œå¯ç”¨ï¼‰ã€‚"
#: doc/classes/BaseButton.xml
msgid "The state of buttons are pressed."
@@ -13419,7 +13452,7 @@ msgstr "è¦æ±‚按下åŽå†é‡Šæ”¾ï¼Œæ‰ç®—点击了按钮。"
#: doc/classes/Basis.xml
msgid "3×3 matrix datatype."
-msgstr "3×3矩阵数æ®ç±»åž‹ã€‚"
+msgstr "3×3 矩阵数æ®ç±»åž‹ã€‚"
#: doc/classes/Basis.xml
msgid ""
@@ -13436,8 +13469,8 @@ msgid ""
msgstr ""
"用于 3D 旋转和缩放的 3×3 çŸ©é˜µã€‚å‡ ä¹Žæ€»æ˜¯ç”¨ä½œå˜æ¢çš„æ­£äº¤åŸºã€‚\n"
"åŒ…å« 3 个å‘é‡å­—段 Xã€Y å’Œ Z ä½œä¸ºå…¶åˆ—ï¼Œé€šå¸¸è¢«è§£é‡Šä¸ºå˜æ¢çš„局部基å‘é‡ã€‚对于这ç§"
-"用途,它由一个缩放矩阵和一个旋转矩阵组æˆï¼Œä¾æ¬¡ä¸º (M=R.S)。\n"
-"也å¯ä»¥ä½œä¸ºä¸‰ç»´å‘é‡çš„æ•°ç»„æ¥è®¿é—®ã€‚这些å‘é‡é€šå¸¸æ˜¯ç›¸äº’正交的,但ä¸ä¸€å®šæ˜¯å½’一化的"
+"ç”¨é€”ï¼Œå®ƒä¾æ¬¡ç”±ä¸€ä¸ªç¼©æ”¾çŸ©é˜µå’Œä¸€ä¸ªæ—‹è½¬çŸ©é˜µç»„æˆï¼ˆM=R.S)。\n"
+"也å¯ä»¥ä½œä¸º 3D å‘é‡çš„æ•°ç»„æ¥è®¿é—®ã€‚这些å‘é‡é€šå¸¸æ˜¯ç›¸äº’正交的,但ä¸ä¸€å®šæ˜¯å½’一化的"
"(由于缩放)。\n"
"更多信æ¯è¯·é˜…è¯»æ–‡æ¡£ä¸­çš„ã€ŠçŸ©é˜µå’Œå˜æ¢ã€‹ä¸€æ–‡ã€‚"
@@ -13588,14 +13621,14 @@ msgstr ""
#: doc/classes/Basis.xml
msgid ""
"Introduce an additional scaling specified by the given 3D scaling factor."
-msgstr "引入一个由给定的3Dç¼©æ”¾å› å­æŒ‡å®šçš„附加缩放。"
+msgstr "引入一个由给定的 3D ç¼©æ”¾å› å­æŒ‡å®šçš„附加缩放。"
#: doc/classes/Basis.xml
msgid ""
"Assuming that the matrix is a proper rotation matrix, slerp performs a "
"spherical-linear interpolation with another rotation matrix."
msgstr ""
-"å‡è®¾è¯¥çŸ©é˜µæ˜¯ä¸€ä¸ªåˆé€‚的旋转矩阵,slerp与å¦ä¸€ä¸ªæ—‹è½¬çŸ©é˜µè¿›è¡Œçƒé¢ç›´çº¿æ’值。"
+"å‡è®¾è¯¥çŸ©é˜µæ˜¯ä¸€ä¸ªåˆé€‚的旋转矩阵,slerp 与å¦ä¸€ä¸ªæ—‹è½¬çŸ©é˜µè¿›è¡Œçƒé¢ç›´çº¿æ’值。"
#: doc/classes/Basis.xml
msgid "Transposed dot product with the X axis of the matrix."
@@ -13630,7 +13663,7 @@ msgstr ""
msgid ""
"The basis matrix's X vector (column 0). Equivalent to array index [code]0[/"
"code]."
-msgstr "基矩阵的 X å‘é‡ï¼ˆç¬¬ 0 列)。等效于数组索引 [code]0[/code]。"
+msgstr "基矩阵的 X å‘é‡ï¼ˆç¬¬ 0 列)。相当于数组索引 [code]0[/code]。"
#: doc/classes/Basis.xml doc/classes/Transform2D.xml
msgid ""
@@ -13779,10 +13812,10 @@ msgid ""
"alignment for the character and [code]advance[/code] is the (optional) "
"advance."
msgstr ""
-"添加一个字符到字体中,其中[code]character[/code]是Unicode值,[code]texture[/"
-"code]是纹ç†ç´¢å¼•,[code]rect[/code]是纹ç†ä¸­çš„区域(以åƒç´ ä¸ºå•ä½ï¼ï¼‰ï¼Œ"
-"[code]align[/code]æ˜¯å­—ç¬¦çš„å¯¹é½æ–¹å¼ï¼ˆå¯é€‰ï¼‰ï¼Œ[code]advance[/code]是å‰è¿›æ–¹å¼"
-"(å¯é€‰ï¼‰ã€‚"
+"添加一个字符到字体中,其中 [code]character[/code] 是 Unicode值,"
+"[code]texture[/code] 是纹ç†ç´¢å¼•,[code]rect[/code] 是纹ç†ä¸­çš„区域(以åƒç´ ä¸ºå•"
+"ä½ï¼ï¼‰ï¼Œ[code]align[/code] æ˜¯å­—ç¬¦çš„å¯¹é½æ–¹å¼ï¼ˆå¯é€‰ï¼‰ï¼Œ[code]advance[/code] 是"
+"步进长度(å¯é€‰ï¼‰ã€‚"
#: doc/classes/BitmapFont.xml
msgid ""
@@ -13794,7 +13827,7 @@ msgstr ""
#: doc/classes/BitmapFont.xml
msgid "Adds a texture to the [BitmapFont]."
-msgstr "为[BitmapFont]添加一个纹ç†ã€‚"
+msgstr "为 [BitmapFont] 添加一个纹ç†ã€‚"
#: doc/classes/BitmapFont.xml
msgid "Clears all the font data and settings."
@@ -13811,11 +13844,11 @@ msgstr "返回字å¶çš„差值。"
#: doc/classes/BitmapFont.xml
msgid "Returns the font atlas texture at index [code]idx[/code]."
-msgstr "返回ä½äºŽç´¢å¼•[code]idx[/code]处的字体Atlas纹ç†ã€‚"
+msgstr "返回ä½äºŽç´¢å¼• [code]idx[/code] 处的字体 Atlas 纹ç†ã€‚"
#: doc/classes/BitmapFont.xml
msgid "Returns the number of textures in the BitmapFont atlas."
-msgstr "返回BitmapFont图谱中纹ç†çš„æ•°é‡ã€‚"
+msgstr "返回 BitmapFont 图谱中纹ç†çš„æ•°é‡ã€‚"
#: doc/classes/BitmapFont.xml
msgid "Ascent (number of pixels above the baseline)."
@@ -13823,7 +13856,7 @@ msgstr "上å‡ï¼ˆåŸºçº¿ä»¥ä¸Šçš„åƒç´ æ•°ï¼‰ã€‚"
#: doc/classes/BitmapFont.xml
msgid "If [code]true[/code], distance field hint is enabled."
-msgstr "如果[code]true[/code],则å¯ç”¨è·ç¦»åœºæç¤ºã€‚"
+msgstr "如果为 [code]true[/code],则å¯ç”¨è·ç¦»åœºæç¤ºã€‚"
#: doc/classes/BitmapFont.xml
msgid "The fallback font."
@@ -13860,12 +13893,12 @@ msgstr ""
#: doc/classes/Bone2D.xml
msgid "Stores the node's current transforms in [member rest]."
-msgstr "将节点当å‰çš„å˜æ¢å­˜å‚¨åœ¨[member rest]中。"
+msgstr "将节点当å‰çš„å˜æ¢å­˜å‚¨åœ¨ [member rest] 中。"
#: doc/classes/Bone2D.xml
msgid ""
"Returns the node's index as part of the entire skeleton. See [Skeleton2D]."
-msgstr "返回节点的索引,作为整个骨架的一部分。请å‚阅 [Skeleton2D]。"
+msgstr "返回节点在整个骨架中的索引å·ã€‚è§ [Skeleton2D]。"
#: doc/classes/Bone2D.xml
msgid ""
@@ -13885,11 +13918,11 @@ msgid ""
"Rest transform of the bone. You can reset the node's transforms to this "
"value using [method apply_rest]."
msgstr ""
-"éª¨éª¼çš„é™æ­¢å˜æ¢ã€‚您å¯ä»¥ä½¿ç”¨[method apply_rest]å°†èŠ‚ç‚¹çš„å˜æ¢é‡ç½®ä¸ºè¿™ä¸ªå€¼ã€‚"
+"骨骼的放æ¾å˜æ¢ã€‚您å¯ä»¥ä½¿ç”¨ [method apply_rest] å°†èŠ‚ç‚¹çš„å˜æ¢é‡ç½®ä¸ºè¿™ä¸ªå€¼ã€‚"
#: doc/classes/BoneAttachment.xml
msgid "A node that will attach to a bone."
-msgstr "一个会附ç€åœ¨éª¨éª¼ä¸Šçš„节点。"
+msgstr "会附ç€åœ¨éª¨éª¼ä¸Šçš„节点。"
#: doc/classes/BoneAttachment.xml
msgid ""
@@ -13897,7 +13930,7 @@ msgid ""
"for this node to attach to. The BoneAttachment node will copy the transform "
"of the selected bone."
msgstr ""
-"此节点必须是 [Skeleton] 节点的å­èŠ‚ç‚¹ã€‚ç„¶åŽï¼Œä½ å¯ä»¥ä¸ºæ­¤èŠ‚ç‚¹é€‰æ‹©è¦é™„加的骨骼。 "
+"此节点必须是 [Skeleton] 节点的å­èŠ‚ç‚¹ã€‚ç„¶åŽï¼Œä½ å¯ä»¥ä¸ºæ­¤èŠ‚ç‚¹é€‰æ‹©è¦é™„加的骨骼。"
"BoneAttachment èŠ‚ç‚¹å°†æ‹·è´æ‰€é€‰éª¨éª¼çš„å˜æ¢ã€‚"
#: doc/classes/BoneAttachment.xml
@@ -13957,13 +13990,13 @@ msgid ""
" can_shoot = true\n"
"[/codeblock]"
msgstr ""
-"布尔是内置类型。有两个布尔值。[code]true[/code]å’Œ[code]false[/code]。你å¯ä»¥æŠŠ"
-"å®ƒæƒ³è±¡æˆæœ‰å¼€æˆ–关状æ€çš„开关(1或0)。布尔在编程中用于æ¡ä»¶è¯­å¥çš„逻辑,如"
-"[code]if[/code]语å¥ã€‚\n"
-"布尔å¯ä»¥ç›´æŽ¥ç”¨äºŽ[code]if[/code]语å¥ä¸­ã€‚下é¢çš„代ç åœ¨[code]if can_shoot:[/code]"
-"行中演示了这一点。你ä¸éœ€è¦ä½¿ç”¨[code]==true[/code],你åªéœ€è¦[code]if "
-"can_shoot:[/code]ã€‚åŒæ ·åœ°ï¼Œä½¿ç”¨[code]if not can_shoot:[/code]è€Œä¸æ˜¯[code]== "
-"false[/code]。\n"
+"布尔是内置类型。布尔值有两个:[code]true[/code] å’Œ [code]false[/code]。你å¯ä»¥"
+"把它想象æˆå¼€å…³ï¼ˆ1 或 0)。布尔在编程中用于æ¡ä»¶è¯­å¥çš„逻辑,如 [code]if[/code] "
+"语å¥ã€‚\n"
+"布尔å¯ä»¥ç›´æŽ¥ç”¨äºŽ [code]if[/code] 语å¥ä¸­ã€‚下é¢çš„代ç åœ¨ [code]if can_shoot:[/"
+"code] 行中对此进行了演示。你ä¸éœ€è¦ä½¿ç”¨ [code]== true[/code],你åªéœ€è¦ "
+"[code]if can_shoot:[/code]ã€‚åŒæ ·åœ°ï¼Œè¯·ä½¿ç”¨ [code]if not can_shoot:[/code] 而"
+"䏿˜¯ [code]== false[/code]。\n"
"[codeblock]\n"
"var can_shoot = true\n"
"\n"
@@ -13972,8 +14005,8 @@ msgstr ""
" pass # 在此执行射击。\n"
"[/codeblock]\n"
"下é¢çš„代ç åªæœ‰åœ¨ä¸¤ä¸ªæ¡ä»¶éƒ½æ»¡è¶³çš„æƒ…况下æ‰ä¼šäº§ç”Ÿå­å¼¹ï¼šåŠ¨ä½œâ€œshootâ€è¢«æŒ‰ä¸‹ï¼Œå¹¶ä¸”如"
-"果[code]can_shoot[/code]是[code]true[/code]。\n"
-"[b]注æ„:[/b][code]Input.is_action_pressed(\"shoot\")[/code]也是一个布尔值,"
+"果 [code]can_shoot[/code] 为 [code]true[/code]。\n"
+"[b]注æ„:[/b][code]Input.is_action_pressed(\"shoot\")[/code] 也是一个布尔值,"
"当“shootâ€è¢«æŒ‰ä¸‹æ—¶ä¸º [code]true[/code],当“shootâ€æ²¡æœ‰è¢«æŒ‰ä¸‹æ—¶ä¸º [code]false[/"
"code]。\n"
"[codeblock]\n"
@@ -13983,8 +14016,8 @@ msgstr ""
" if can_shoot and Input.is_action_pressed(\"shoot\"):\n"
" create_bullet()\n"
"[/codeblock]\n"
-"下é¢çš„代ç å°†æŠŠ[code]can_shoot[/code]设置为 [code]false[/code]å¹¶å¯åŠ¨ä¸€ä¸ªå®šæ—¶"
-"器。这将阻止玩家射击,直到定时器用完。然åŽ[code]can_shoot[/code]设置为 "
+"下é¢çš„代ç å°†æŠŠ [code]can_shoot[/code] 设置为 [code]false[/code] å¹¶å¯åŠ¨ä¸€ä¸ªå®š"
+"时器。这将阻止玩家射击,直到定时器用完。然åŽå°† [code]can_shoot[/code] 设置为 "
"[code]true[/code]ï¼Œå†æ¬¡å…许玩家进行射击。\n"
"[codeblock]\n"
"var can_shoot = true\n"
@@ -14217,11 +14250,11 @@ msgstr "将文本å‘å³å¯¹é½ã€‚"
#: doc/classes/Button.xml
msgid "Default text [Color] of the [Button]."
-msgstr "[Button]的默认文本[Color]。"
+msgstr "[Button] 的默认文本 [Color]。"
#: doc/classes/Button.xml
msgid "Text [Color] used when the [Button] is disabled."
-msgstr "ç¦ç”¨[Button]时使用的文本[Color]。"
+msgstr "ç¦ç”¨ [Button] 时使用的文本 [Color]。"
#: doc/classes/Button.xml
msgid ""
@@ -14229,12 +14262,12 @@ msgid ""
"text color of the button. Disabled, hovered, and pressed states take "
"precedence over this color."
msgstr ""
-"当[Button]获得焦点时使用的文本[Color]。åªå–代按钮的正常文本颜色。ç¦ç”¨ã€æ‚¬åœå’Œ"
-"按下状æ€ä¼˜å…ˆäºŽè¿™ä¸ªé¢œè‰²ã€‚"
+"当 [Button] 获得焦点时使用的文本 [Color]。åªå–代按钮的正常文本颜色。ç¦ç”¨ã€æ‚¬"
+"åœå’ŒæŒ‰ä¸‹çжæ€ä¼˜å…ˆäºŽè¿™ä¸ªé¢œè‰²ã€‚"
#: doc/classes/Button.xml
msgid "Text [Color] used when the [Button] is being hovered."
-msgstr "悬åœ[Button]时使用的文本[Color]。"
+msgstr "æ‚¬åœ [Button] 时使用的文本 [Color]。"
#: doc/classes/Button.xml
msgid "Text [Color] used when the [Button] is being pressed."
@@ -14242,11 +14275,11 @@ msgstr "正在按下 [Button] 时使用的文本 [Color] 。"
#: doc/classes/Button.xml
msgid "The horizontal space between [Button]'s icon and text."
-msgstr "[Button]的图标和文本之间的水平间è·ã€‚"
+msgstr "[Button] 的图标和文本之间的水平间è·ã€‚"
#: doc/classes/Button.xml
msgid "[Font] of the [Button]'s text."
-msgstr "[Button]文本的[Font]。"
+msgstr "[Button] 文本的 [Font]。"
#: doc/classes/Button.xml
msgid "[StyleBox] used when the [Button] is disabled."
@@ -14258,20 +14291,20 @@ msgid ""
"current [StyleBox], so using [StyleBoxEmpty] will just disable the focus "
"visual effect."
msgstr ""
-"当[Button]获得焦点时使用的[StyleBox]。它显示在当å‰çš„[StyleBox]之上,所以使用"
-"[StyleBoxEmpty]åªæ˜¯ç¦ç”¨ç„¦ç‚¹è§†è§‰æ•ˆæžœã€‚"
+"当 [Button] 获得焦点时使用的 [StyleBox]。它显示在当å‰çš„ [StyleBox] 之上,所以"
+"使用 [StyleBoxEmpty] åªæ˜¯ç¦ç”¨ç„¦ç‚¹è§†è§‰æ•ˆæžœã€‚"
#: doc/classes/Button.xml
msgid "[StyleBox] used when the [Button] is being hovered."
-msgstr "悬åœ[Button]时使用的[StyleBox]。"
+msgstr "æ‚¬åœ [Button] 时使用的 [StyleBox]。"
#: doc/classes/Button.xml
msgid "Default [StyleBox] for the [Button]."
-msgstr "[Button]的默认[StyleBox]。"
+msgstr "[Button] 的默认 [StyleBox]。"
#: doc/classes/Button.xml
msgid "[StyleBox] used when the [Button] is being pressed."
-msgstr "按下[Button]时使用的[StyleBox]。"
+msgstr "按下 [Button] 时使用的 [StyleBox]。"
#: doc/classes/ButtonGroup.xml
msgid "Group of Buttons."
@@ -14291,8 +14324,8 @@ msgid ""
"Returns an [Array] of [Button]s who have this as their [ButtonGroup] (see "
"[member BaseButton.group])."
msgstr ""
-"返回一个[Button]çš„[Array],这些[Button]çš„[ButtonGroup]都有这个功能(å‚阅"
-"[member BaseButton.group])。"
+"返回一个 [Button] 的 [Array],这些 [Button] 的 [ButtonGroup] 都有这个功能"
+"ï¼ˆè§ [member BaseButton.group])。"
#: doc/classes/ButtonGroup.xml
msgid "Returns the current pressed button."
@@ -14374,9 +14407,9 @@ msgid ""
"to the position and orientation of the camera by subclassed cameras such as "
"[ClippedCamera], [InterpolatedCamera] and [ARVRCamera]."
msgstr ""
-"è¿”å›žç›¸æœºçš„å˜æ¢åŠ ä¸Šåž‚ç›´[member v_offset]和水平[member h_offset]çš„åç§»é‡ï¼›ä»¥åŠ"
-"ç”±å­ç±»ç›¸æœºå¦‚[ClippedCamera]ã€[InterpolatedCamera]å’Œ[ARVRCamera]对相机的ä½ç½®å’Œ"
-"æ–¹å‘åšå‡ºçš„任何其他调整。"
+"è¿”å›žç›¸æœºçš„å˜æ¢åŠ ä¸Šåž‚ç›´ [member v_offset] 和水平 [member h_offset] çš„åç§»é‡ï¼›"
+"以åŠç”±å­ç±»ç›¸æœºå¦‚ [ClippedCamera]ã€[InterpolatedCamera] å’Œ [ARVRCamera] 对相机"
+"çš„ä½ç½®å’Œæ–¹å‘åšå‡ºçš„任何其他调整。"
#: doc/classes/Camera.xml
msgid ""
@@ -14477,7 +14510,7 @@ msgid ""
msgstr ""
"通过在世界空间å•ä½ä¸­æŒ‡å®š [code]size[/code] å’Œ [code]z_near[/code] å’Œ "
"[code]z_far[/code] 剪è£å¹³é¢ï¼Œå°†ç›¸æœºæŠ•影设置为正交模å¼ï¼Œè¯·å‚阅 [constant "
-"PROJECTION_ORTHOGONAL]。 (æç¤ºï¼š2D 游æˆç»å¸¸ä½¿ç”¨è¿™ç§æŠ•影,以åƒç´ ä¸ºå•使Œ‡å®š"
+"PROJECTION_ORTHOGONAL]。(æç¤ºï¼š2D 游æˆç»å¸¸ä½¿ç”¨è¿™ç§æŠ•影,以åƒç´ ä¸ºå•使Œ‡å®š"
"值。)"
#: doc/classes/Camera.xml
@@ -14487,8 +14520,8 @@ msgid ""
"angle in degrees, and the [code]z_near[/code] and [code]z_far[/code] clip "
"planes in world space units."
msgstr ""
-"å°†æ‘„åƒæœºçš„æŠ•影设置为é€è§†æ¨¡å¼ï¼Œå‚阅[constant PROJECTION_PERSPECTIVE]),指定"
-"[code]fov[/code] 视野角度,å•ä½åº¦ï¼Œä»¥åŠä¸–界空间å•ä½çš„[code]z_near[/code]å’Œ"
+"å°†æ‘„åƒæœºçš„æŠ•影设置为é€è§†æ¨¡å¼ï¼ˆè§ [constant PROJECTION_PERSPECTIVE]),指定 "
+"[code]fov[/code] 视野角度,å•ä½ä¸ºåº¦ï¼Œä»¥åŠä¸–界空间å•ä½çš„[code]z_near[/code]å’Œ"
"[code]z_far[/code]è£å‰ªå¹³é¢ã€‚"
#: doc/classes/Camera.xml
@@ -14528,7 +14561,8 @@ msgstr "æè¿°æ­¤ç›¸æœºæ¸²æŸ“哪些 3D 渲染层的剔除掩ç ã€‚"
#: doc/classes/Camera.xml
msgid ""
"If [code]true[/code], the ancestor [Viewport] is currently using this camera."
-msgstr "如果[code]true[/code],则说明祖级的[Viewport]当剿­£åœ¨ä½¿ç”¨è¿™ä¸ªæ‘„åƒå¤´ã€‚"
+msgstr ""
+"如果为 [code]true[/code],则说明祖级的 [Viewport] 当剿­£åœ¨ä½¿ç”¨è¿™ä¸ªæ‘„åƒå¤´ã€‚"
#: doc/classes/Camera.xml
msgid ""
@@ -14552,7 +14586,7 @@ msgstr ""
#: doc/classes/Camera.xml
msgid "The [Environment] to use for this camera."
-msgstr "此相机è¦ä½¿ç”¨çš„[Environment]。"
+msgstr "此相机è¦ä½¿ç”¨çš„ [Environment]。"
#: doc/classes/Camera.xml
msgid ""
@@ -14574,7 +14608,7 @@ msgid ""
msgstr ""
"相机的视野角度,以度为å•ä½ã€‚仅适用于é€è§†æ¨¡å¼ã€‚由于 [member keep_aspect] é”定"
"一个轴,因此 [code]fov[/code] 设置å¦ä¸€ä¸ªè½´çš„视角。\n"
-"作为å‚考,默认的垂直视野值([code]70.0[/code])等效于以下水平 FOV:\n"
+"作为å‚考,默认的垂直视野值([code]70.0[/code])相当于以下水平 FOV:\n"
"- 在 4:3 视窗中约86.07 度\n"
"- 在 16:10 视窗中约 96.50 度\n"
"- 在 16:9 视窗中约102.45 度\n"
@@ -14598,8 +14632,8 @@ msgid ""
"The axis to lock during [member fov]/[member size] adjustments. Can be "
"either [constant KEEP_WIDTH] or [constant KEEP_HEIGHT]."
msgstr ""
-"在[member fov]/[member size]调整时è¦é”定的轴。å¯ä»¥æ˜¯[constant KEEP_WIDTH]或"
-"[constant KEEP_HEIGHT]。"
+"在 [member fov]/[member size] 调整时è¦é”定的轴。å¯ä»¥æ˜¯ [constant KEEP_WIDTH] "
+"或 [constant KEEP_HEIGHT]。"
#: doc/classes/Camera.xml
msgid ""
@@ -14613,8 +14647,8 @@ msgid ""
"objects' Z distance from the camera's local space scales their perceived "
"size."
msgstr ""
-"相机的投影模å¼ã€‚在[constant PROJECTION_PERSPECTIVE]模å¼ä¸‹ï¼Œç‰©ä½“与相机局部空间"
-"çš„Zè·ç¦»ä¼šå½±å“其感知的大å°ã€‚"
+"相机的投影模å¼ã€‚在 [constant PROJECTION_PERSPECTIVE] 模å¼ä¸‹ï¼Œç‰©ä½“与相机局部空"
+"é—´çš„Zè·ç¦»ä¼šå½±å“其感知的大å°ã€‚"
#: doc/classes/Camera.xml
msgid ""
@@ -14646,8 +14680,8 @@ msgid ""
"Frustum projection. This mode allows adjusting [member frustum_offset] to "
"create \"tilted frustum\" effects."
msgstr ""
-"Frustum投影。通过该模å¼å¯ä»¥è°ƒæ•´[member frustum_offset]æ¥åˆ›å»º \"tilted "
-"frustum \"效果。"
+"Frustum 投影。通过该模å¼å¯ä»¥è°ƒæ•´ [member frustum_offset] æ¥åˆ›å»ºâ€œtilted "
+"frustumâ€æ•ˆæžœã€‚"
#: doc/classes/Camera.xml
msgid ""
@@ -14655,8 +14689,8 @@ msgid ""
"usually the best option for projects running in portrait mode, as taller "
"aspect ratios will benefit from a wider vertical FOV."
msgstr ""
-"ä¿ç•™æ°´å¹³é•¿å®½æ¯”,也称为Vert-ç¼©æ”¾ã€‚è¿™é€šå¸¸æ˜¯åœ¨çºµå‘æ¨¡å¼ä¸‹è¿è¡Œçš„项目的最佳选择,因"
-"为较高的纵横比将从更宽的垂直视场中å—益。"
+"ä¿ç•™æ°´å¹³é•¿å®½æ¯”,也称为 Vert- ç¼©æ”¾ã€‚è¿™é€šå¸¸æ˜¯åœ¨çºµå‘æ¨¡å¼ä¸‹è¿è¡Œçš„项目的最佳选择,"
+"因为较高的纵横比将从更宽的垂直视场中å—益。"
#: doc/classes/Camera.xml
msgid ""
@@ -14748,7 +14782,7 @@ msgstr "将相机与跟踪的节点对é½ã€‚"
msgid ""
"Removes any [Camera2D] from the ancestor [Viewport]'s internal currently-"
"assigned camera."
-msgstr "从父级[Viewport]的内部当å‰åˆ†é…的相机中删除任何[Camera2D]。"
+msgstr "从父级 [Viewport] 的内部当å‰åˆ†é…的相机中移除任何 [Camera2D]。"
#: doc/classes/Camera2D.xml
msgid "Forces the camera to update scroll immediately."
@@ -14783,16 +14817,16 @@ msgid ""
"Returns the specified margin. See also [member drag_margin_bottom], [member "
"drag_margin_top], [member drag_margin_left], and [member drag_margin_right]."
msgstr ""
-"返回指定的边è·ã€‚å¦è¯·å‚阅[member drag_margin_bottom],[member "
-"drag_margin_top],[member drag_margin_left]和[member drag_margin_right]。"
+"返回指定的边è·ã€‚å¦è¯·å‚阅 [member drag_margin_bottom]ã€[member "
+"drag_margin_top]ã€[member drag_margin_left] å’Œ [member drag_margin_right]。"
#: doc/classes/Camera2D.xml
msgid ""
"Returns the specified camera limit. See also [member limit_bottom], [member "
"limit_top], [member limit_left], and [member limit_right]."
msgstr ""
-"返回指定的相机é™åˆ¶ã€‚请å‚阅 [member limit_bottom]ã€[member limit_top]ã€"
-"[member limit_left]和[member limit_right]。"
+"返回指定的相机é™åˆ¶ã€‚å¦è¯·å‚阅 [member limit_bottom]ã€[member limit_top]ã€"
+"[member limit_left] 和 [member limit_right]。"
#: doc/classes/Camera2D.xml
msgid ""
@@ -14816,7 +14850,7 @@ msgid ""
"drag_margin_top], [member drag_margin_left], and [member drag_margin_right]."
msgstr ""
"设置指定的边è·ã€‚å¦è¯·å‚阅 [member drag_margin_bottom]ã€[member "
-"drag_margin_top]ã€[member drag_margin_left]å’Œ [member drag_margin_right]。"
+"drag_margin_top]ã€[member drag_margin_left] å’Œ [member drag_margin_right]。"
#: doc/classes/Camera2D.xml
msgid ""
@@ -14824,11 +14858,11 @@ msgid ""
"limit_top], [member limit_left], and [member limit_right]."
msgstr ""
"设置指定的相机é™åˆ¶ã€‚å¦è¯·å‚阅 [member limit_bottom]ã€[member limit_top]ã€"
-"[member limit_left]和[member limit_right]。"
+"[member limit_left] 和 [member limit_right]。"
#: doc/classes/Camera2D.xml
msgid "The Camera2D's anchor point. See [enum AnchorMode] constants."
-msgstr "Camera2D的锚点。å‚阅[enum AnchorMode]常é‡ã€‚"
+msgstr "Camera2D çš„é”šç‚¹ã€‚è§ [enum AnchorMode] 常é‡ã€‚"
#: doc/classes/Camera2D.xml
msgid ""
@@ -14836,8 +14870,8 @@ msgid ""
"Only one camera can be current, so setting a different camera [code]current[/"
"code] will disable this one."
msgstr ""
-"如果 [code]true[/code],相机是当å‰åœºæ™¯çš„æ´»åŠ¨ç›¸æœºã€‚å½“å‰åªèƒ½æœ‰ä¸€å°ç›¸æœºï¼Œæ‰€ä»¥è®¾"
-"ç½®ä¸åŒçš„相机[code]current[/code]å°†ç¦ç”¨è¿™å°ç›¸æœºã€‚"
+"如果为 [code]true[/code],相机是当å‰åœºæ™¯çš„æ´»åŠ¨ç›¸æœºã€‚å½“å‰åªèƒ½æœ‰ä¸€å°ç›¸æœºï¼Œæ‰€ä»¥"
+"设置ä¸åŒçš„相机[code]current[/code]å°†ç¦ç”¨è¿™å°ç›¸æœºã€‚"
#: doc/classes/Camera2D.xml
msgid ""
@@ -14852,7 +14886,8 @@ msgid ""
"Bottom margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-"拖动相机所需的底边è·ã€‚值为[code]1[/code]时,相机仅在到达å±å¹•边缘时æ‰ä¼šç§»åŠ¨ã€‚"
+"拖动相机所需的底边è·ã€‚值为 [code]1[/code] 时,相机仅在到达å±å¹•边缘时æ‰ä¼šç§»"
+"动。"
#: doc/classes/Camera2D.xml
msgid ""
@@ -14860,29 +14895,32 @@ msgid ""
"drag margins. If [code]false[/code], the camera moves horizontally "
"regardless of margins."
msgstr ""
-"如果 [code]true[/code]ï¼Œç›¸æœºä»…åœ¨è¾¾åˆ°æ°´å¹³æ‹–åŠ¨è¾¹è·æ—¶æ‰ç§»åŠ¨ã€‚å¦‚æžœ[code]false[/"
-"code],相机会水平移动而ä¸ç®¡è¾¹è·ã€‚"
+"如果为 [code]true[/code]ï¼Œç›¸æœºä»…åœ¨è¾¾åˆ°æ°´å¹³æ‹–åŠ¨è¾¹è·æ—¶æ‰ç§»åŠ¨ã€‚å¦‚æžœä¸º "
+"[code]false[/code],相机会水平移动而ä¸ç®¡è¾¹è·ã€‚"
#: doc/classes/Camera2D.xml
msgid ""
"Left margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-"拖动相机所需的左边缘。值为[code]1[/code]时,相机仅在到达å±å¹•边缘时æ‰ä¼šç§»åŠ¨ã€‚"
+"拖动相机所需的左边缘。值为 [code]1[/code] 时,相机仅在到达å±å¹•边缘时æ‰ä¼šç§»"
+"动。"
#: doc/classes/Camera2D.xml
msgid ""
"Right margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-"拖动相机所需的å³è¾¹ç¼˜ã€‚值为[code]1[/code]时,相机仅在到达å±å¹•边缘时æ‰ä¼šç§»åŠ¨ã€‚"
+"拖动相机所需的å³è¾¹ç¼˜ã€‚值为 [code]1[/code] 时,相机仅在到达å±å¹•边缘时æ‰ä¼šç§»"
+"动。"
#: doc/classes/Camera2D.xml
msgid ""
"Top margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-"拖动相机所需的上边è·ã€‚值为[code]1[/code]时,相机仅在到达å±å¹•边缘时æ‰ä¼šç§»åŠ¨ã€‚"
+"拖动相机所需的上边è·ã€‚值为 [code]1[/code] 时,相机仅在到达å±å¹•边缘时æ‰ä¼šç§»"
+"动。"
#: doc/classes/Camera2D.xml
msgid ""
@@ -14890,23 +14928,23 @@ msgid ""
"margins. If [code]false[/code], the camera moves vertically regardless of "
"margins."
msgstr ""
-"如果 [code]true[/code]ï¼Œç›¸æœºä»…åœ¨è¾¾åˆ°åž‚ç›´æ‹–åŠ¨è¾¹è·æ—¶æ‰ç§»åŠ¨ã€‚å¦‚æžœ[code]false[/"
-"code],相机会垂直移动而ä¸ç®¡è¾¹è·ã€‚"
+"如果为 [code]true[/code]ï¼Œç›¸æœºä»…åœ¨è¾¾åˆ°åž‚ç›´æ‹–åŠ¨è¾¹è·æ—¶æ‰ç§»åŠ¨ã€‚å¦‚æžœä¸º "
+"[code]false[/code],相机会垂直移动而ä¸ç®¡è¾¹è·ã€‚"
#: doc/classes/Camera2D.xml
msgid ""
"If [code]true[/code], draws the camera's drag margin rectangle in the editor."
-msgstr "如果[code]true[/code],在编辑器中绘制相机的拖动边è·çŸ©å½¢ã€‚"
+msgstr "如果为 [code]true[/code],在编辑器中绘制相机的拖动边è·çŸ©å½¢ã€‚"
#: doc/classes/Camera2D.xml
msgid ""
"If [code]true[/code], draws the camera's limits rectangle in the editor."
-msgstr "如果[code]true[/code],在编辑器中绘制相机的æžé™çŸ©å½¢ã€‚"
+msgstr "如果为 [code]true[/code],在编辑器中绘制相机的æžé™çŸ©å½¢ã€‚"
#: doc/classes/Camera2D.xml
msgid ""
"If [code]true[/code], draws the camera's screen rectangle in the editor."
-msgstr "如果[code]true[/code],在编辑器中绘制相机的画é¢çŸ©å½¢ã€‚"
+msgstr "如果为 [code]true[/code],在编辑器中绘制相机的画é¢çŸ©å½¢ã€‚"
#: doc/classes/Camera2D.xml
msgid ""
@@ -14935,7 +14973,7 @@ msgid ""
"without smoothing, even with this setting enabled, invoke [method "
"reset_smoothing]."
msgstr ""
-"为 [code]true[/code] 时,相机会在达到æžé™æ—¶å¹³æ»‘åœ°åœæ­¢ã€‚\n"
+"如果为 [code]true[/code],相机会在达到æžé™æ—¶å¹³æ»‘åœ°åœæ­¢ã€‚\n"
"当 [member smoothing_enabled] 为 [code]false[/code] 时,该属性无效。\n"
"[b]注æ„:[/b]è¦ç«‹å³å°†ç›¸æœºçš„ä½ç½®æ›´æ–°åˆ°é™åˆ¶èŒƒå›´å†…而ä¸è¿›è¡Œå¹³æ»‘,å³ä½¿å¯ç”¨äº†æ­¤è®¾"
"置,也è¦è°ƒç”¨ [method reset_smoothing]。"
@@ -14976,23 +15014,23 @@ msgstr "相机的过程回调。请å‚阅[enum Camera2DProcessMode]。"
#: doc/classes/Camera2D.xml
msgid "If [code]true[/code], the camera view rotates with the target."
-msgstr "为 [code]true[/code] 时,相机视图将éšç›®æ ‡æ—‹è½¬ã€‚"
+msgstr "如果为 [code]true[/code],相机视图将éšç›®æ ‡æ—‹è½¬ã€‚"
#: doc/classes/Camera2D.xml
msgid ""
"If [code]true[/code], the camera smoothly moves towards the target at "
"[member smoothing_speed]."
msgstr ""
-"为 [code]true[/code] 时,相机将以 [member smoothing_speed] 的速度平滑地æœç›®æ ‡"
-"移动。"
+"如果为 [code]true[/code],相机将以 [member smoothing_speed] 的速度平滑地æœç›®"
+"标移动。"
#: doc/classes/Camera2D.xml
msgid ""
"Speed in pixels per second of the camera's smoothing effect when [member "
"smoothing_enabled] is [code]true[/code]."
msgstr ""
-"当[member smoothing_enabled]为 [code]true[/code] 时,相机平滑效果的速度,以æ¯"
-"ç§’åƒç´ ä¸ºå•ä½ã€‚"
+"当 [member smoothing_enabled] 为 [code]true[/code] 时,相机平滑效果的速度,以"
+"æ¯ç§’åƒç´ ä¸ºå•ä½ã€‚"
#: doc/classes/Camera2D.xml
msgid ""
@@ -15018,10 +15056,12 @@ msgid ""
msgstr "相机的ä½ç½®è¦è€ƒè™‘垂直/æ°´å¹³å移和å±å¹•尺寸。"
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr "相机通过 [code]_physics_process[/code] 回调进行更新。"
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr "相机通过 [code]_process[/code] 回调进行更新。"
@@ -15060,7 +15100,7 @@ msgstr "返回设备上的相机ä½ç½®ã€‚"
#: doc/classes/CameraFeed.xml
msgid "If [code]true[/code], the feed is active."
-msgstr "如果[code]true[/code]ï¼Œåˆ™æºæ˜¯æ¿€æ´»çš„。"
+msgstr "如果为 [code]true[/code]ï¼Œåˆ™æºæ˜¯æ¿€æ´»çš„。"
#: doc/classes/CameraFeed.xml
msgid "The transform applied to the camera's image."
@@ -15171,7 +15211,7 @@ msgid ""
"a shader."
msgstr ""
"该纹ç†å¯ä»¥è®¿é—® [CameraFeed] æä¾›çš„相机纹ç†ã€‚\n"
-"[b]注æ„:[/b]许多相机æä¾›éœ€è¦åœ¨ç€è‰²å™¨ä¸­è½¬æ¢çš„ YCbCr 图åƒã€‚"
+"[b]注æ„:[/b]许多相机æä¾›çš„都是 YCbCr 图åƒï¼Œéœ€è¦åœ¨ç€è‰²å™¨ä¸­è¿›è¡Œè½¬æ¢ã€‚"
#: doc/classes/CameraTexture.xml
msgid "The ID of the [CameraFeed] for which we want to display the image."
@@ -15660,7 +15700,7 @@ msgid ""
"Hide the [CanvasItem] if it's currently visible. This is equivalent to "
"setting [member visible] to [code]false[/code]."
msgstr ""
-"如果该 [CanvasItem] ç›®å‰æ˜¯å¯è§çš„,则将其éšè—。等价于将 [member visible] 设为 "
+"如果该 [CanvasItem] ç›®å‰æ˜¯å¯è§çš„,则将其éšè—。相当于将 [member visible] 设为 "
"[code]false[/code]。"
#: doc/classes/CanvasItem.xml
@@ -15740,7 +15780,7 @@ msgid ""
"[Popup], the correct way to make them visible is to call one of the multiple "
"[code]popup*()[/code] functions instead."
msgstr ""
-"如果该 [CanvasItem] ç›®å‰æ˜¯éšè—的,则将其显示。等价于将 [member visible] 设为 "
+"如果该 [CanvasItem] ç›®å‰æ˜¯éšè—的,则将其显示。相当于将 [member visible] 设为 "
"[code]true[/code]。对于继承自 [Popup] 的控件,让它们å¯è§çš„æ­£ç¡®åšæ³•æ˜¯æ¢æˆè°ƒç”¨"
"å„ç§ [code]popup*()[/code] 函数的其中之一。"
@@ -15749,17 +15789,17 @@ msgid ""
"Queue the [CanvasItem] for update. [constant NOTIFICATION_DRAW] will be "
"called on idle time to request redraw."
msgstr ""
-"将[CanvasItem]排队等待更新。在空闲时间将调用[constant NOTIFICATION_DRAW]以请"
-"求é‡ç»˜ã€‚"
+"将 [CanvasItem] 排队等待更新。在空闲时间将调用 [constant NOTIFICATION_DRAW] "
+"以请求é‡ç»˜ã€‚"
#: doc/classes/CanvasItem.xml
msgid ""
"The rendering layers in which this [CanvasItem] responds to [Light2D] nodes."
-msgstr "æ­¤[CanvasItem]在其中å“应[Light2D]节点的渲染层。"
+msgstr "æ­¤ [CanvasItem] 在其中å“应 [Light2D] 节点的渲染层。"
#: doc/classes/CanvasItem.xml
msgid "The material applied to textures on this [CanvasItem]."
-msgstr "在此[CanvasItem]上应用于纹ç†çš„æè´¨ã€‚"
+msgstr "在此 [CanvasItem] 上应用于纹ç†çš„æè´¨ã€‚"
#: doc/classes/CanvasItem.xml
msgid "The color applied to textures on this [CanvasItem]."
@@ -15774,19 +15814,19 @@ msgstr ""
#: doc/classes/CanvasItem.xml
msgid "If [code]true[/code], the object draws behind its parent."
-msgstr "如果[code]true[/code],则对象在其父对象åŽé¢ç»˜åˆ¶ã€‚"
+msgstr "如果为 [code]true[/code],则对象在其父对象åŽé¢ç»˜åˆ¶ã€‚"
#: doc/classes/CanvasItem.xml
msgid "If [code]true[/code], the object draws on top of its parent."
-msgstr "如果[code]true[/code],则对象在其父对象的顶部绘制。"
+msgstr "如果为 [code]true[/code],则对象在其父对象的顶部绘制。"
#: doc/classes/CanvasItem.xml
msgid ""
"If [code]true[/code], the parent [CanvasItem]'s [member material] property "
"is used as this one's material."
msgstr ""
-"如果[code]true[/code],则将父级[CanvasItem]的[member material]属性用作此项的"
-"æè´¨ã€‚"
+"如果为 [code]true[/code],则将父级[CanvasItem]的[member material]属性用作此项"
+"çš„æè´¨ã€‚"
#: doc/classes/CanvasItem.xml
msgid ""
@@ -15797,9 +15837,9 @@ msgid ""
"visible is to call one of the multiple [code]popup*()[/code] functions "
"instead."
msgstr ""
-"如果[code]true[/code],这个[CanvasItem]è¢«ç»˜åˆ¶ã€‚åªæœ‰å½“它的所有父节点也å¯è§æ—¶ï¼Œ"
-"è¯¥èŠ‚ç‚¹æ‰æ˜¯å¯è§çš„(æ¢å¥è¯è¯´ï¼Œ[method is_visible_in_tree]必须返回 [code]true[/"
-"code])。\n"
+"如果为 [code]true[/code],这个[CanvasItem]è¢«ç»˜åˆ¶ã€‚åªæœ‰å½“它的所有父节点也å¯è§"
+"æ—¶ï¼Œè¯¥èŠ‚ç‚¹æ‰æ˜¯å¯è§çš„(æ¢å¥è¯è¯´ï¼Œ[method is_visible_in_tree]必须返回 "
+"[code]true[/code])。\n"
"[b]注æ„:[/b]对于继承了[Popup]的控件,使其å¯è§çš„æ­£ç¡®æ–¹æ³•是调用多个"
"[code]popup*()[/code]函数之一。"
@@ -15820,8 +15860,8 @@ msgid ""
"or when an action is taking place that may have impacted these boundaries (e."
"g. changing [member Sprite.texture])."
msgstr ""
-"在物体[Rect2]边缘(ä½ç½®æˆ–大å°ï¼‰æ”¹å˜ï¼Œæˆ–有影å“到边缘的æ“作(比如修改[member "
-"Sprite.texture])时触å‘。"
+"在物体 [Rect2] 边缘(ä½ç½®æˆ–大å°ï¼‰æ”¹å˜ï¼Œæˆ–有影å“到边缘的æ“作(比如修改 "
+"[member Sprite.texture])时触å‘。"
#: doc/classes/CanvasItem.xml
msgid "Emitted when the visibility (hidden/visible) changes."
@@ -15933,7 +15973,7 @@ msgid ""
"[b]Note:[/b] This property is only used and visible in the editor if [member "
"particles_animation] is [code]true[/code]."
msgstr ""
-"如果 [code]true[/code],粒å­åŠ¨ç”»å°†å¾ªçŽ¯æ’­æ”¾ã€‚\n"
+"如果为 [code]true[/code],粒å­åŠ¨ç”»å°†å¾ªçŽ¯æ’­æ”¾ã€‚\n"
"[b]注æ„:[/b]åªæœ‰å½“ [member particles_animation] 为 [code]true[/code] 时,该"
"属性æ‰ä¼šåœ¨ç¼–辑器中使用并å¯è§ã€‚"
@@ -16008,7 +16048,7 @@ msgid ""
"Hides any [CanvasItem] under this [CanvasLayer]. This is equivalent to "
"setting [member visible] to [code]false[/code]."
msgstr ""
-"éšè—该 [CanvasLayer] 下的所有 [CanvasItem]。等价于将 [member visible] 设为 "
+"éšè—该 [CanvasLayer] 下的所有 [CanvasItem]。相当于将 [member visible] 设为 "
"[code]false[/code]。"
#: doc/classes/CanvasLayer.xml
@@ -16016,7 +16056,7 @@ msgid ""
"Shows any [CanvasItem] under this [CanvasLayer]. This is equivalent to "
"setting [member visible] to [code]true[/code]."
msgstr ""
-"显示该 [CanvasLayer] 下的所有 [CanvasItem]。等价于将 [member visible] 设为 "
+"显示该 [CanvasLayer] 下的所有 [CanvasItem]。相当于将 [member visible] 设为 "
"[code]true[/code]。"
#: doc/classes/CanvasLayer.xml
@@ -16256,8 +16296,8 @@ msgid ""
"reflow to take the space of hidden characters. If this is not desired, set "
"their [member color] to [code]Color(1, 1, 1, 0)[/code] instead."
msgstr ""
-"如果[code]true[/code],将绘制字符。如果[code]false[/code],则éšè—字符。éšè—å­—"
-"符周围的字符将回æµä»¥å ç”¨éšè—字符的空间。如果ä¸å¸Œæœ›è¿™æ ·åšï¼Œå¯ä»¥å°†å®ƒä»¬çš„"
+"如果为 [code]true[/code],将绘制字符。如果为 [code]false[/code],则éšè—字符。"
+"éšè—字符周围的字符将回æµä»¥å ç”¨éšè—字符的空间。如果ä¸å¸Œæœ›è¿™æ ·åšï¼Œå¯ä»¥å°†å®ƒä»¬çš„"
"[member color]设置为[code]Color(1, 1, 1, 0)[/code]。"
#: doc/classes/CheckBox.xml
@@ -16605,7 +16645,7 @@ msgid ""
"usage)[/code]."
msgstr ""
"返回 [code]class[/code] 或其父级的[code]ä¿¡å·[/code]æ•°æ®ã€‚返回 [Dictionary] å¹¶"
-"带有以下键: [code]args[/code], [code]default_args[/code], [code]flags[/"
+"带有以下键:[code]args[/code], [code]default_args[/code], [code]flags[/"
"code], [code]id[/code], [code]name[/code], [code]return:(class_name, hint, "
"hint_string, name, type, usage)[/code]。"
@@ -16707,7 +16747,7 @@ msgstr "添加碰撞例外,以使相机ä¸ä¼šä¸ŽæŒ‡å®šçš„[RID]碰撞。"
#: doc/classes/ClippedCamera.xml
msgid "Removes all collision exceptions."
-msgstr "删除所有碰撞例外。"
+msgstr "移除所有碰撞例外。"
#: doc/classes/ClippedCamera.xml
msgid "Returns the distance the camera has been offset due to a collision."
@@ -16723,11 +16763,11 @@ msgstr ""
#: doc/classes/ClippedCamera.xml
msgid "Removes a collision exception with the specified node."
-msgstr "删除与指定节点的碰撞例外。"
+msgstr "移除与指定节点的碰撞例外。"
#: doc/classes/ClippedCamera.xml
msgid "Removes a collision exception with the specified [RID]."
-msgstr "删除指定 [RID] 的碰撞例外。"
+msgstr "移除指定 [RID] 的碰撞例外。"
#: doc/classes/ClippedCamera.xml
msgid ""
@@ -16739,11 +16779,11 @@ msgstr ""
#: doc/classes/ClippedCamera.xml
msgid "If [code]true[/code], the camera stops on contact with [Area]s."
-msgstr "为 [code]true[/code] 时,相机将在与 [Area] æŽ¥è§¦æ—¶åœæ­¢ã€‚"
+msgstr "如果为 [code]true[/code],相机将在与 [Area] æŽ¥è§¦æ—¶åœæ­¢ã€‚"
#: doc/classes/ClippedCamera.xml
msgid "If [code]true[/code], the camera stops on contact with [PhysicsBody]s."
-msgstr "为 [code]true[/code] 时,相机将在与 [PhysicsBody] æŽ¥è§¦æ—¶åœæ­¢ã€‚"
+msgstr "如果为 [code]true[/code],相机将在与 [PhysicsBody] æŽ¥è§¦æ—¶åœæ­¢ã€‚"
#: doc/classes/ClippedCamera.xml
msgid ""
@@ -16791,7 +16831,7 @@ msgid ""
"surface at that point. Connect to the [signal input_event] signal to easily "
"pick up these events."
msgstr ""
-"接收未处ç†çš„事件 [InputEvent]。 [code]position[/code] 是鼠标指针在具有索引 "
+"接收未处ç†çš„事件 [InputEvent]。[code]position[/code] 是鼠标指针在具有索引 "
"[code]shape_idx[/code] 的形状表é¢åœ¨ä¸–界空间中的ä½ç½®ï¼Œ[code]normal[/code] 是该"
"点表é¢çš„æ³•å‘é‡ã€‚连接到 [signal input_event] ä¿¡å·ä»¥è½»æ¾èŽ·å–这些事件。"
@@ -16832,7 +16872,7 @@ msgstr ""
#: doc/classes/CollisionObject.xml doc/classes/CollisionObject2D.xml
msgid "If [code]true[/code], the shape owner and its shapes are disabled."
-msgstr "如果[code]true[/code],则ç¦ç”¨å½¢çŠ¶æ‰€æœ‰è€…åŠå…¶å½¢çŠ¶ã€‚"
+msgstr "如果为 [code]true[/code],则ç¦ç”¨å½¢çŠ¶æ‰€æœ‰è€…åŠå…¶å½¢çŠ¶ã€‚"
#: doc/classes/CollisionObject.xml doc/classes/CollisionObject2D.xml
msgid "Removes the given shape owner."
@@ -16894,19 +16934,19 @@ msgstr "返回具有给定形状所有者的给定 id 的形状 [Shape] çš„å­ç´
#: doc/classes/CollisionObject.xml
msgid "Returns the shape owner's [Transform]."
-msgstr "返回形状所有者的[Transform]。"
+msgstr "返回形状所有者的 [Transform]。"
#: doc/classes/CollisionObject.xml doc/classes/CollisionObject2D.xml
msgid "Removes a shape from the given shape owner."
-msgstr "从给定的形状所有者中删除一个形状。"
+msgstr "从给定的形状所有者中移除一个形状。"
#: doc/classes/CollisionObject.xml doc/classes/CollisionObject2D.xml
msgid "If [code]true[/code], disables the given shape owner."
-msgstr "如果[code]true[/code],则ç¦ç”¨ç»™å®šçš„形状所有者。"
+msgstr "如果为 [code]true[/code],则ç¦ç”¨ç»™å®šçš„形状所有者。"
#: doc/classes/CollisionObject.xml
msgid "Sets the [Transform] of the given shape owner."
-msgstr "设置给定形状所有者的[Transform]。"
+msgstr "设置给定形状所有者的 [Transform]。"
#: doc/classes/CollisionObject.xml
msgid ""
@@ -16945,8 +16985,8 @@ msgid ""
"If [code]true[/code], the [CollisionObject] will continue to receive input "
"events as the mouse is dragged across its shapes."
msgstr ""
-"如果[code]true[/code],[CollisionObject] 将在鼠标拖过其形状时继续接收输入事"
-"件。"
+"如果为 [code]true[/code],[CollisionObject] 将在鼠标拖过其形状时继续接收输入"
+"事件。"
#: doc/classes/CollisionObject.xml doc/classes/CollisionObject2D.xml
msgid ""
@@ -16965,7 +17005,7 @@ msgid ""
"the shape with index [code]shape_idx[/code] and [code]normal[/code] is the "
"normal vector of the surface at that point."
msgstr ""
-"当对象收到未处ç†çš„ [InputEvent] æ—¶å‘出。 [code]position[/code] 是鼠标指针在具"
+"当对象收到未处ç†çš„ [InputEvent] æ—¶å‘出。[code]position[/code] 是鼠标指针在具"
"有索引 [code]shape_idx[/code] 的形状表é¢åœ¨ä¸–界空间中的ä½ç½®ï¼Œ[code]normal[/"
"code] 是该点表é¢çš„æ³•å‘é‡ã€‚"
@@ -16979,7 +17019,7 @@ msgstr "当鼠标指针退出此对象的所有形状时å‘出。"
#: doc/classes/CollisionObject2D.xml
msgid "Base node for 2D collision objects."
-msgstr "二维碰撞对象的基础节点。"
+msgstr "2D 碰撞对象的基础节点。"
#: doc/classes/CollisionObject2D.xml
msgid ""
@@ -17006,16 +17046,16 @@ msgid ""
"[Shape2D]. Connect to the [code]input_event[/code] signal to easily pick up "
"these events."
msgstr ""
-"æŽ¥å—æœªå¤„ç†çš„[InputEvent]ã€‚è¦æ±‚[member input_pickable]为 [code]true[/code]。 "
-"[code]shape_idx[/code]被点击的[Shape2D]çš„å­ç´¢å¼•。连接到[code]input_event[/"
-"code]ä¿¡å·å³å¯è½»æ¾æŽ¥æ”¶è¿™äº›äº‹ä»¶ã€‚"
+"æŽ¥å—æœªå¤„ç†çš„ [InputEvent]ã€‚è¦æ±‚ [member input_pickable] 为 [code]true[/"
+"code]。[code]shape_idx[/code] 是被点击的 [Shape2D] çš„å­ç´¢å¼•。连接到 "
+"[code]input_event[/code] ä¿¡å·å³å¯è½»æ¾æŽ¥æ”¶è¿™äº›äº‹ä»¶ã€‚"
#: doc/classes/CollisionObject2D.xml
msgid ""
"Returns the [code]one_way_collision_margin[/code] of the shape owner "
"identified by given [code]owner_id[/code]."
msgstr ""
-"返回由给定的[code]owner_id[/code]标识的形状所有者的"
+"返回由给定的 [code]owner_id[/code] 标识的形状所有者的 "
"[code]one_way_collision_margin[/code]。"
#: doc/classes/CollisionObject2D.xml
@@ -17024,26 +17064,26 @@ msgid ""
"this [CollisionObject2D] will not be reported to collided with "
"[CollisionObject2D]s."
msgstr ""
-"返回 [code]true[/code],如果æºäºŽè¿™ä¸ª[CollisionObject2D]的形状所有者的碰撞ä¸ä¼š"
-"被报告给[CollisionObject2D]s。"
+"返回 [code]true[/code],如果æºäºŽè¿™ä¸ª [CollisionObject2D] 的形状所有者的碰撞ä¸"
+"会被报告给 [CollisionObject2D]。"
#: doc/classes/CollisionObject2D.xml
msgid "Adds a [Shape2D] to the shape owner."
-msgstr "给形状所有者添加一个[Shape2D]。"
+msgstr "给形状所有者添加一个 [Shape2D]。"
#: doc/classes/CollisionObject2D.xml
msgid "Returns the [Shape2D] with the given id from the given shape owner."
-msgstr "从给定的形状所有者那里返回给定id的[Shape2D]。"
+msgstr "从给定的形状所有者那里返回给定 id 的 [Shape2D]。"
#: doc/classes/CollisionObject2D.xml
msgid ""
"Returns the child index of the [Shape2D] with the given id from the given "
"shape owner."
-msgstr "从给定的形状所有者那里返回给定idçš„[Shape2D]çš„å­ç´¢å¼•。"
+msgstr "从给定的形状所有者那里返回给定 id çš„ [Shape2D] çš„å­ç´¢å¼•。"
#: doc/classes/CollisionObject2D.xml
msgid "Returns the shape owner's [Transform2D]."
-msgstr "返回形状所有者的[Transform2D]。"
+msgstr "返回形状所有者的 [Transform2D]。"
#: doc/classes/CollisionObject2D.xml
msgid ""
@@ -17051,20 +17091,20 @@ msgid ""
"originating from this [CollisionObject2D] will not be reported to collided "
"with [CollisionObject2D]s."
msgstr ""
-"如果[code]enable[/code]为 [code]true[/code],则æºè‡ªè¿™ä¸ª[CollisionObject2D]çš„"
-"形状所有者的碰撞将ä¸ä¼šè¢«æŠ¥å‘Šç»™[CollisionObject2D]。"
+"如果 [code]enable[/code] 为 [code]true[/code],则æºè‡ªè¿™ä¸ª "
+"[CollisionObject2D] 的形状所有者的碰撞将ä¸ä¼šè¢«æŠ¥å‘Šç»™ [CollisionObject2D]。"
#: doc/classes/CollisionObject2D.xml
msgid ""
"Sets the [code]one_way_collision_margin[/code] of the shape owner identified "
"by given [code]owner_id[/code] to [code]margin[/code] pixels."
msgstr ""
-"将由给定的[code]owner_id[/code]标识的形状所有者的"
-"[code]one_way_collision_margin[/code]设置为[code]margin[/code]åƒç´ ã€‚"
+"将由给定的 [code]owner_id[/code] 标识的形状所有者的 "
+"[code]one_way_collision_margin[/code] 设置为 [code]margin[/code] åƒç´ ã€‚"
#: doc/classes/CollisionObject2D.xml
msgid "Sets the [Transform2D] of the given shape owner."
-msgstr "设置给定形状所有者的[Transform2D]。"
+msgstr "设置给定形状所有者的 [Transform2D]。"
#: doc/classes/CollisionObject2D.xml
msgid ""
@@ -17114,8 +17154,8 @@ msgid ""
"[member input_pickable] to be [code]true[/code] and at least one "
"[code]collision_layer[/code] bit to be set."
msgstr ""
-"当鼠标指针进入此对象的任何形状时触å‘ã€‚è¦æ±‚[member input_pickable]为 "
-"[code]true[/code],并且至少è¦è®¾ç½®ä¸€ä¸ª[code]collision_layer[/code]ä½ã€‚"
+"当鼠标指针进入此对象的任何形状时触å‘ã€‚è¦æ±‚ [member input_pickable] 为 "
+"[code]true[/code],并且至少è¦è®¾ç½®ä¸€ä¸ª [code]collision_layer[/code] ä½ã€‚"
#: doc/classes/CollisionObject2D.xml
msgid ""
@@ -17123,12 +17163,12 @@ msgid ""
"[member input_pickable] to be [code]true[/code] and at least one "
"[code]collision_layer[/code] bit to be set."
msgstr ""
-"当鼠标指针退出此对象的所有形状时å‘å‡ºã€‚è¦æ±‚[member input_pickable]为 "
-"[code]true[/code],并且至少è¦è®¾ç½®ä¸€ä¸ª[code]collision_layer[/code]ä½ã€‚"
+"当鼠标指针退出此对象的所有形状时å‘å‡ºã€‚è¦æ±‚ [member input_pickable] 为 "
+"[code]true[/code],并且至少è¦è®¾ç½®ä¸€ä¸ª [code]collision_layer[/code] ä½ã€‚"
#: doc/classes/CollisionPolygon.xml
msgid "Editor-only class for defining a collision polygon in 3D space."
-msgstr "ä»…é™ç¼–辑器的类,用于在3D空间中定义碰撞多边形。"
+msgstr "ä»…é™ç¼–辑器的类,用于在 3D 空间中定义碰撞多边形。"
#: doc/classes/CollisionPolygon.xml
msgid ""
@@ -17149,13 +17189,13 @@ msgstr "产生的碰撞在垂直于其多边形的任一方å‘上延伸的长度
#: doc/classes/CollisionPolygon.xml
msgid "If [code]true[/code], no collision will be produced."
-msgstr "如果[code]true[/code],将ä¸ä¼šäº§ç”Ÿç¢°æ’žã€‚"
+msgstr "如果为 [code]true[/code],将ä¸ä¼šäº§ç”Ÿç¢°æ’žã€‚"
#: doc/classes/CollisionPolygon.xml
msgid ""
"The collision margin for the generated [Shape]. See [member Shape.margin] "
"for more details."
-msgstr "生æˆçš„[Shape]的碰撞边。å‚阅[member Shape.margin]èŽ·å–æ›´å¤šç»†èŠ‚ã€‚"
+msgstr "生æˆçš„ [Shape] 的碰撞边。详情请å‚阅 [member Shape.margin]。"
#: doc/classes/CollisionPolygon.xml
msgid ""
@@ -17173,19 +17213,19 @@ msgstr ""
#: doc/classes/CollisionPolygon2D.xml
msgid "Defines a 2D collision polygon."
-msgstr "定义2D碰撞多边形。"
+msgstr "定义 2D 碰撞多边形。"
#: doc/classes/CollisionPolygon2D.xml
msgid ""
"Provides a 2D collision polygon to a [CollisionObject2D] parent. Polygons "
"can be drawn in the editor or specified by a list of vertices."
msgstr ""
-"为[CollisionObject2D]父级æä¾›2D碰撞多边形。多边形å¯ä»¥åœ¨ç¼–辑器中绘制,也å¯ä»¥ç”±"
-"顶点列表指定。"
+"为 [CollisionObject2D] 父级æä¾› 2D 碰撞多边形。多边形å¯ä»¥åœ¨ç¼–辑器中绘制,也å¯"
+"以由顶点列表指定。"
#: doc/classes/CollisionPolygon2D.xml
msgid "Collision build mode. Use one of the [enum BuildMode] constants."
-msgstr "碰撞构建模å¼ã€‚使用[enum BuildMode]常é‡ä¹‹ä¸€ã€‚"
+msgstr "碰撞构建模å¼ã€‚使用 [enum BuildMode] 常é‡ä¹‹ä¸€ã€‚"
#: doc/classes/CollisionPolygon2D.xml
msgid "If [code]true[/code], no collisions will be detected."
@@ -17231,7 +17271,7 @@ msgstr "碰撞将仅包括多边形边缘。"
#: doc/classes/CollisionShape.xml
msgid "Node that represents collision shape data in 3D space."
-msgstr "表示3D空间中的碰撞形状数æ®çš„节点。"
+msgstr "表示 3D 空间中的碰撞形状数æ®çš„节点。"
#: doc/classes/CollisionShape.xml
msgid ""
@@ -17289,9 +17329,9 @@ msgid ""
"shape_owner_get_shape] to get the actual shape."
msgstr ""
"编辑器功能,用于在2D空间中创建和编辑碰撞形状。您å¯ä»¥ä½¿ç”¨æ­¤èŠ‚ç‚¹è¡¨ç¤ºå„ç§ç¢°æ’žå½¢"
-"状,例如,将其添加到[Area2D]以æä¾›æ£€æµ‹å½¢çŠ¶ï¼Œæˆ–å°†å…¶æ·»åŠ åˆ°[PhysicsBody2D]以创建"
-"实体。 [b]é‡è¦äº‹é¡¹[/b]:这是创建形状的仅编辑器助手,请使用[method "
-"CollisionObject2D.shape_owner_get_shape]获å–实际形状。"
+"状,例如,将其添加到 [Area2D] 以æä¾›æ£€æµ‹å½¢çŠ¶ï¼Œæˆ–å°†å…¶æ·»åŠ åˆ° [PhysicsBody2D] 以"
+"创建实体。[b]é‡è¦äº‹é¡¹[/b]:这是创建形状的仅编辑器助手,请使用 [method "
+"CollisionObject2D.shape_owner_get_shape] 获å–实际形状。"
#: doc/classes/CollisionShape2D.xml doc/classes/KinematicBody2D.xml
#: doc/classes/RectangleShape2D.xml doc/classes/TileMap.xml
@@ -17432,8 +17472,7 @@ msgid ""
msgstr ""
"æ ¹æ® RGBA 值构造颜色,通常介于 0 å’Œ 1 之间。\n"
"[codeblock]\n"
-"var color = Color(0.2, 1.0, 0.7, 0.8) # Similar to Color8(51, 255, 178, "
-"204)\n"
+"var color = Color(0.2, 1.0, 0.7, 0.8) # 类似于 Color8(51, 255, 178, 204)\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17467,7 +17506,7 @@ msgstr ""
"返回对比度最高的颜色。\n"
"[codeblock]\n"
"var color = Color(0.3, 0.4, 0.9)\n"
-"var contrasted_color = color.contrasted() # 等价于 RGBA(204, 229, 102, 255)\n"
+"var contrasted_color = color.contrasted() # 相当于 RGBA(204, 229, 102, 255)\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17479,7 +17518,7 @@ msgid ""
"var darkgreen = green.darkened(0.2) # 20% darker than regular green\n"
"[/codeblock]"
msgstr ""
-"返回一个新的颜色,这个颜色按指定的百分比(比例从0到1ï¼‰å˜æš—。\n"
+"返回一个新的颜色,这个颜色按指定的百分比(比例从0 到 1ï¼‰å˜æš—。\n"
"[codeblock]\n"
"var green = Color(0.0, 1.0, 0.0)\n"
"var darkgreen = green.darkened(0.2) # 20% darker than regular green\n"
@@ -17497,7 +17536,7 @@ msgstr ""
"从 HSV é…置文件中构建一个颜色。[code]h[/code]ã€[code]s[/code] å’Œ [code]v[/"
"code] 是 0 和 1 之间的值。\n"
"[codeblock]\n"
-"var color = Color.from_hsv(0.58, 0.5, 0.79, 0.8) # 等价于 HSV(210, 50, 79, "
+"var color = Color.from_hsv(0.58, 0.5, 0.79, 0.8) # 相当于 HSV(210, 50, 79, "
"0.8) 或 Color8(100, 151, 201, 0.8)\n"
"[/codeblock]"
@@ -17537,7 +17576,7 @@ msgstr ""
"返回å色 [code](1 - r, 1 - g, 1 - b, a)[/code]。\n"
"[codeblock]\n"
"var color = Color(0.3, 0.4, 0.9)\n"
-"var inverted_color = color.inverted() # 等价于 Color(0.7, 0.6, 0.1)\n"
+"var inverted_color = color.inverted() # 相当于 Color(0.7, 0.6, 0.1)\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17558,10 +17597,10 @@ msgid ""
"var lightgreen = green.lightened(0.2) # 20% lighter than regular green\n"
"[/codeblock]"
msgstr ""
-"返回将此颜色按指定百分比(比例从0到1ï¼‰å˜æµ…åŽäº§ç”Ÿçš„æ–°é¢œè‰²ã€‚\n"
+"返回将此颜色按指定百分比(比例从 0 到 1ï¼‰å˜æµ…åŽäº§ç”Ÿçš„æ–°é¢œè‰²ã€‚\n"
"[codeblock]\n"
"var green = Color(0.0, 1.0, 0.0)\n"
-"var lightgreen = green.lightened(0.2) # 20% lighter than regular green\n"
+"var lightgreen = green.lightened(0.2) # æ¯”æ™®é€šçš„ç»¿è‰²è¦æ·¡ 20%\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17579,8 +17618,7 @@ msgstr ""
"[codeblock]\n"
"var c1 = Color(1.0, 0.0, 0.0)\n"
"var c2 = Color(0.0, 1.0, 0.0)\n"
-"var li_c = c1.linear_interpolate(c2, 0.5) # Equivalent to Color(0.5, 0.5, "
-"0.0)\n"
+"var li_c = c1.linear_interpolate(c2, 0.5) # 相当于 Color(0.5, 0.5, 0.0)\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17593,11 +17631,11 @@ msgid ""
"print(color.to_abgr32()) # Prints 4281565439\n"
"[/codeblock]"
msgstr ""
-"返回转æ¢ä¸º ABGR æ ¼å¼çš„ 32 使•´æ•°çš„颜色,æ¯ä¸ªå­—节代表一个颜色通é“。 ABGR 是默"
-"认格å¼çš„转置版本。\n"
+"返回转æ¢ä¸º ABGR æ ¼å¼çš„ 32 使•´æ•°çš„颜色,æ¯ä¸ªå­—节代表一个颜色通é“。ABGR 是默认"
+"æ ¼å¼çš„转置版本。\n"
"[codeblock]\n"
"var color = Color(1, 0.5, 0.2)\n"
-"print(color.to_abgr32()) # Prints 4281565439\n"
+"print(color.to_abgr32()) # 输出 4281565439\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17610,11 +17648,11 @@ msgid ""
"print(color.to_abgr64()) # Prints -225178692812801\n"
"[/codeblock]"
msgstr ""
-"返回转æ¢ä¸º ABGR æ ¼å¼çš„ 64 使•´æ•°çš„颜色,æ¯ä¸ªå­—代表一个颜色通é“。 ABGR 是默认"
-"æ ¼å¼çš„转置版本。\n"
+"返回转æ¢ä¸º ABGR æ ¼å¼çš„ 64 使•´æ•°çš„颜色,æ¯ä¸ªå­—代表一个颜色通é“。ABGR 是默认格"
+"å¼çš„转置版本。\n"
"[codeblock]\n"
"var color = Color(1, 0.5, 0.2)\n"
-"print(color.to_abgr64()) # Prints -225178692812801\n"
+"print(color.to_abgr64()) # 输出 -225178692812801\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17626,11 +17664,11 @@ msgid ""
"print(color.to_argb32()) # Prints 4294934323\n"
"[/codeblock]"
msgstr ""
-"返回转æ¢ä¸º ARGB æ ¼å¼çš„ 32 使•´æ•°çš„颜色,æ¯ä¸ªå­—节代表一个颜色通é“。 ARGB 与 "
+"返回转æ¢ä¸º ARGB æ ¼å¼çš„ 32 使•´æ•°çš„颜色,æ¯ä¸ªå­—节代表一个颜色通é“。ARGB 与 "
"DirectX 更加兼容。\n"
"[codeblock]\n"
"var color = Color(1, 0.5, 0.2)\n"
-"print(color.to_argb32()) # Prints 4294934323\n"
+"print(color.to_argb32()) # 输出 4294934323\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17642,11 +17680,11 @@ msgid ""
"print(color.to_argb64()) # Prints -2147470541\n"
"[/codeblock]"
msgstr ""
-"返回转æ¢ä¸º ARGB æ ¼å¼çš„ 64 使•´æ•°çš„颜色,æ¯ä¸ªå­—代表一个颜色通é“。 ARGB 与 "
+"返回转æ¢ä¸º ARGB æ ¼å¼çš„ 64 使•´æ•°çš„颜色,æ¯ä¸ªå­—代表一个颜色通é“。ARGB 与 "
"DirectX 更加兼容。\n"
"[codeblock]\n"
"var color = Color(1, 0.5, 0.2)\n"
-"print(color.to_argb64()) # Prints -2147470541\n"
+"print(color.to_argb64()) # 输出 -2147470541\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17679,11 +17717,11 @@ msgid ""
"print(color.to_rgba32()) # Prints 4286526463\n"
"[/codeblock]"
msgstr ""
-"返回转æ¢ä¸º RGBA æ ¼å¼çš„ 32 使•´æ•°çš„颜色,æ¯ä¸ªå­—节代表一个颜色通é“。 RGBA 是 "
+"返回转æ¢ä¸º RGBA æ ¼å¼çš„ 32 使•´æ•°çš„颜色,æ¯ä¸ªå­—节代表一个颜色通é“。RGBA 是 "
"Godot 的默认格å¼ã€‚\n"
"[codeblock]\n"
"var color = Color(1, 0.5, 0.2)\n"
-"print(color.to_rgba32()) # Prints 4286526463\n"
+"print(color.to_rgba32()) # 输出 4286526463\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17695,11 +17733,11 @@ msgid ""
"print(color.to_rgba64()) # Prints -140736629309441\n"
"[/codeblock]"
msgstr ""
-"返回转æ¢ä¸º RGBA æ ¼å¼çš„ 64 使•´æ•°çš„颜色,æ¯ä¸ªå­—代表一个颜色通é“。 RGBA 是 "
+"返回转æ¢ä¸º RGBA æ ¼å¼çš„ 64 使•´æ•°çš„颜色,æ¯ä¸ªå­—代表一个颜色通é“。RGBA 是 "
"Godot 的默认格å¼ã€‚\n"
"[codeblock]\n"
"var color = Color(1, 0.5, 0.2)\n"
-"print(color.to_rgba64()) # Prints -140736629309441\n"
+"print(color.to_rgba64()) # 输出 -140736629309441\n"
"[/codeblock]"
#: doc/classes/Color.xml
@@ -17713,7 +17751,7 @@ msgstr ""
#: doc/classes/Color.xml
msgid "Wrapper for [member a] that uses the range 0 to 255 instead of 0 to 1."
-msgstr "[member a]的包装程åºï¼Œä½¿ç”¨çš„范围是0到255ï¼Œè€Œä¸æ˜¯0到1。"
+msgstr "[member a] çš„å°è£…器,使用的范围是 0 到 255ï¼Œè€Œä¸æ˜¯ 0 到 1。"
#: doc/classes/Color.xml
msgid "The color's blue component, typically on the range of 0 to 1."
@@ -17721,7 +17759,7 @@ msgstr "颜色的è“色分é‡ï¼Œä¸€èˆ¬åœ¨ 0 到 1 的范围内。"
#: doc/classes/Color.xml
msgid "Wrapper for [member b] that uses the range 0 to 255 instead of 0 to 1."
-msgstr "[member b]çš„å°è£…器,使用0到255çš„èŒƒå›´ï¼Œè€Œä¸æ˜¯0到1。"
+msgstr "[member b] çš„å°è£…器,使用 0 到 255 çš„èŒƒå›´ï¼Œè€Œä¸æ˜¯ 0 到 1。"
#: doc/classes/Color.xml
msgid "The color's green component, typically on the range of 0 to 1."
@@ -17729,27 +17767,27 @@ msgstr "颜色的绿色分é‡ï¼Œä¸€èˆ¬åœ¨ 0 到 1 的范围内。"
#: doc/classes/Color.xml
msgid "Wrapper for [member g] that uses the range 0 to 255 instead of 0 to 1."
-msgstr "[member g]çš„å°è£…器,使用范围0到255è€Œä¸æ˜¯0到1。"
+msgstr "[member g] çš„å°è£…器,使用范围 0 到 255 è€Œä¸æ˜¯ 0 到 1。"
#: doc/classes/Color.xml
msgid "The HSV hue of this color, on the range 0 to 1."
-msgstr "这个颜色的HSV色相,范围是0到1。"
+msgstr "这个颜色的 HSV 色相,范围是 0 到 1。"
#: doc/classes/Color.xml
msgid "The color's red component, typically on the range of 0 to 1."
-msgstr "颜色的红色分é‡ï¼Œé€šå¸¸åœ¨0到1的范围内。"
+msgstr "颜色的红色分é‡ï¼Œé€šå¸¸åœ¨ 0 到 1 的范围内。"
#: doc/classes/Color.xml
msgid "Wrapper for [member r] that uses the range 0 to 255 instead of 0 to 1."
-msgstr "[member r]çš„å°è£…器,使用0到255çš„èŒƒå›´è€Œä¸æ˜¯0到1。"
+msgstr "[member r] çš„å°è£…器,使用 0 到 255 çš„èŒƒå›´è€Œä¸æ˜¯ 0 到 1。"
#: doc/classes/Color.xml
msgid "The HSV saturation of this color, on the range 0 to 1."
-msgstr "该颜色的HSV饱和度,范围为0到1。"
+msgstr "这个颜色的 HSV 饱和度,范围为 0 到 1。"
#: doc/classes/Color.xml
msgid "The HSV value (brightness) of this color, on the range 0 to 1."
-msgstr "该颜色的HSV值(亮度),范围为0至1。"
+msgstr "这个颜色的 HSV 值(亮度),范围为 0 至 1。"
#: doc/classes/Color.xml
msgid "Alice blue color."
@@ -17761,27 +17799,27 @@ msgstr "å¤è‘£ç™½ã€‚"
#: doc/classes/Color.xml
msgid "Aqua color."
-msgstr "水色."
+msgstr "水色。"
#: doc/classes/Color.xml
msgid "Aquamarine color."
-msgstr "æµ·è“色."
+msgstr "æµ·è“色。"
#: doc/classes/Color.xml
msgid "Azure color."
-msgstr "天è“色."
+msgstr "天è“色。"
#: doc/classes/Color.xml
msgid "Beige color."
-msgstr "米黄色."
+msgstr "米黄色。"
#: doc/classes/Color.xml
msgid "Bisque color."
-msgstr "橘黄色."
+msgstr "橘黄色。"
#: doc/classes/Color.xml
msgid "Black color."
-msgstr "黑色."
+msgstr "黑色。"
#: doc/classes/Color.xml
msgid "Blanche almond color."
@@ -17789,7 +17827,7 @@ msgstr "布兰奇æä»è‰²ã€‚"
#: doc/classes/Color.xml
msgid "Blue color."
-msgstr "è“色."
+msgstr "è“色。"
#: doc/classes/Color.xml
msgid "Blue violet color."
@@ -17797,7 +17835,7 @@ msgstr "è“紫色的颜色。"
#: doc/classes/Color.xml
msgid "Brown color."
-msgstr "棕色."
+msgstr "棕色。"
#: doc/classes/Color.xml
msgid "Burly wood color."
@@ -17809,15 +17847,15 @@ msgstr "军æœè“。"
#: doc/classes/Color.xml
msgid "Chartreuse color."
-msgstr "黄è¤è‰²."
+msgstr "黄è¤è‰²ã€‚"
#: doc/classes/Color.xml
msgid "Chocolate color."
-msgstr "巧克力色."
+msgstr "巧克力色。"
#: doc/classes/Color.xml
msgid "Coral color."
-msgstr "çŠç‘šè‰²."
+msgstr "çŠç‘šè‰²ã€‚"
#: doc/classes/Color.xml
msgid "Cornflower color."
@@ -18363,7 +18401,7 @@ msgstr ""
#: doc/classes/ColorPicker.xml
msgid ""
"Removes the given color from the list of color presets of this color picker."
-msgstr "从这个å–色器的颜色预设列表中删除给定的颜色。"
+msgstr "从这个å–色器的颜色预设列表中移除给定的颜色。"
#: doc/classes/ColorPicker.xml
msgid "Returns the list of colors in the presets of the color picker."
@@ -18379,8 +18417,8 @@ msgid ""
"mouse button, otherwise it will apply immediately even in mouse motion event "
"(which can cause performance issues)."
msgstr ""
-"如果[code]true[/code]ï¼Œåªæœ‰åœ¨ç”¨æˆ·æ¾å¼€é¼ æ ‡æŒ‰é’®åŽæ‰ä¼šåº”用颜色,å¦åˆ™å³ä½¿åœ¨é¼ æ ‡ç§»"
-"动事件中也会立å³åº”用(ä¼šé€ æˆæ€§èƒ½é—®é¢˜)。"
+"如果为 [code]true[/code]ï¼Œåªæœ‰åœ¨ç”¨æˆ·æ¾å¼€é¼ æ ‡æŒ‰é’®åŽæ‰ä¼šåº”用颜色,å¦åˆ™å³ä½¿åœ¨é¼ "
+"标移动事件中也会立å³åº”ç”¨ï¼ˆä¼šé€ æˆæ€§èƒ½é—®é¢˜ï¼‰ã€‚"
#: doc/classes/ColorPicker.xml
msgid "If [code]true[/code], shows an alpha channel slider (opacity)."
@@ -18424,7 +18462,7 @@ msgstr "添加预设时å‘出。"
#: doc/classes/ColorPicker.xml
msgid "Emitted when a preset is removed."
-msgstr "删除预设时å‘出。"
+msgstr "移除预设时å‘出。"
#: doc/classes/ColorPicker.xml
msgid "The width of the hue selection slider."
@@ -18502,14 +18540,15 @@ msgid ""
msgstr ""
"返回控件的 [PopupPanel],它å…许你连接到弹出信å·ã€‚è¿™å…许你在显示或éšè— "
"ColorPicker 时事件处ç†ã€‚\n"
-"[b]警告:[/b]这是一个必需的内部节点,删除和释放它å¯èƒ½ä¼šå¯¼è‡´å´©æºƒã€‚如果你希望éš"
+"[b]警告:[/b]这是一个必需的内部节点,移除并释放它å¯èƒ½ä¼šå¯¼è‡´å´©æºƒã€‚如果你希望éš"
"è—它或其任何å­é¡¹ï¼Œè¯·ä½¿ç”¨å…¶ [member CanvasItem.visible] 属性。"
#: doc/classes/ColorPickerButton.xml
msgid ""
"If [code]true[/code], the alpha channel in the displayed [ColorPicker] will "
"be visible."
-msgstr "如果 [code]true[/code],则显示的 [ColorPicker] 中的 Alpha 通é“å°†å¯è§ã€‚"
+msgstr ""
+"如果为 [code]true[/code],则显示的 [ColorPicker] 中的 Alpha 通é“å°†å¯è§ã€‚"
#: doc/classes/ColorPickerButton.xml
msgid "Emitted when the color changes."
@@ -18608,7 +18647,7 @@ msgid ""
msgstr ""
"填充颜色。\n"
"[codeblock]\n"
-"$ColorRect.color = Color(1, 0, 0, 1) # Set ColorRect's color to red.\n"
+"$ColorRect.color = Color(1, 0, 0, 1) # 将 ColorRect 设为红色。\n"
"[/codeblock]"
#: doc/classes/ConcavePolygonShape.xml
@@ -18664,7 +18703,7 @@ msgstr ""
#: doc/classes/ConcavePolygonShape2D.xml
msgid ""
"The array of points that make up the [ConcavePolygonShape2D]'s line segments."
-msgstr "组æˆ[ConcavePolygonShape2D]线段的点的数组。"
+msgstr "ç»„æˆ [ConcavePolygonShape2D] 线段的点的数组。"
#: doc/classes/ConeTwistJoint.xml
msgid "A twist joint between two 3D PhysicsBodies."
@@ -18725,7 +18764,7 @@ msgid ""
"Twist is locked if below 0.05."
msgstr ""
"扭曲是绕扭曲轴的旋转,此值定义了关节å¯ä»¥æ‰­æ›²å¤šè¿œã€‚\n"
-"如果低于0.05,则扭曲被é”定。"
+"如果低于 0.05,则扭曲被é”定。"
#: doc/classes/ConeTwistJoint.xml doc/classes/Generic6DOFJoint.xml
#: doc/classes/HingeJoint.xml doc/classes/Light.xml doc/classes/SliderJoint.xml
@@ -18862,7 +18901,7 @@ msgstr ""
#: doc/classes/ConfigFile.xml
msgid "Removes the entire contents of the config."
-msgstr "删除é…置的全部内容。"
+msgstr "移除é…置的全部内容。"
#: doc/classes/ConfigFile.xml
msgid ""
@@ -18895,9 +18934,9 @@ msgid ""
"[code]default[/code] value. If [code]default[/code] is not specified or set "
"to [code]null[/code], an error is also raised."
msgstr ""
-"返回指定部分和键的当å‰å€¼ã€‚如果节或键ä¸å­˜åœ¨ï¼Œæœ¬æ–¹æ³•返回åŽå¤‡å€¼[code]default[/"
-"code]。如果没有指定[code]default[/code]或者设置为[code]null[/code],也会引å‘"
-"一个错误。"
+"返回指定部分和键的当å‰å€¼ã€‚如果节或键ä¸å­˜åœ¨ï¼Œæœ¬æ–¹æ³•返回åŽå¤‡å€¼ [code]default[/"
+"code]。如果没有指定 [code]default[/code] 或者设置为 [code]null[/code],也会引"
+"å‘一个错误。"
#: doc/classes/ConfigFile.xml
msgid "Returns [code]true[/code] if the specified section exists."
@@ -18914,9 +18953,9 @@ msgid ""
"on.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
-"åŠ è½½æŒ‡å®šä¸ºå‚æ•°çš„é…ç½®æ–‡ä»¶ã€‚è§£æžæ–‡ä»¶çš„内容并将其加载到调用该方法的[ConfigFile]"
-"对象中。\n"
-"返回[enum Error]代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
+"åŠ è½½æŒ‡å®šä¸ºå‚æ•°çš„é…ç½®æ–‡ä»¶ã€‚è§£æžæ–‡ä»¶çš„内容并将其加载到调用该方法的 "
+"[ConfigFile] 对象中。\n"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
#: doc/classes/ConfigFile.xml
msgid ""
@@ -18925,9 +18964,9 @@ msgid ""
"the [ConfigFile] object which the method was called on.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
-"åŠ è½½æŒ‡å®šä¸ºå‚æ•°çš„加密é…置文件,使用æä¾›çš„[code]key[/code]å¯¹å…¶è§£å¯†ã€‚è§£æžæ–‡ä»¶çš„"
-"内容并将其加载到调用该方法的[ConfigFile]对象中。\n"
-"返回[enum Error]代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
+"åŠ è½½æŒ‡å®šä¸ºå‚æ•°çš„加密é…置文件,使用æä¾›çš„ [code]key[/code] å¯¹å…¶è§£å¯†ã€‚è§£æžæ–‡ä»¶"
+"的内容并将其加载到调用该方法的 [ConfigFile] 对象中。\n"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
#: doc/classes/ConfigFile.xml
msgid ""
@@ -18936,9 +18975,9 @@ msgid ""
"loaded in the [ConfigFile] object which the method was called on.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
-"åŠ è½½ä½œä¸ºå‚æ•°çš„加密é…置文件,使用æä¾›çš„[code]password[/code]解密。该文件的内容"
-"被解æžå¹¶åŠ è½½åˆ°è°ƒç”¨è¯¥æ–¹æ³•çš„ [ConfigFile] 对象中。\n"
-"返回[enum Error]代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
+"åŠ è½½ä½œä¸ºå‚æ•°çš„加密é…置文件,使用æä¾›çš„ [code]password[/code] 解密。该文件的内"
+"容被解æžå¹¶åŠ è½½åˆ°è°ƒç”¨è¯¥æ–¹æ³•çš„ [ConfigFile] 对象中。\n"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
#: doc/classes/ConfigFile.xml
msgid ""
@@ -18956,9 +18995,9 @@ msgid ""
"parameter. The output file uses an INI-style structure.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
-"å°†[ConfigFile]对象的内容ä¿å­˜åˆ°æŒ‡å®šä¸ºå‚数的文件中。输出文件使用INIæ ·å¼çš„结"
+"å°† [ConfigFile] 对象的内容ä¿å­˜åˆ°æŒ‡å®šä¸ºå‚数的文件中。输出文件使用 INI æ ·å¼çš„结"
"构。\n"
-"返回[enum Error]代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
#: doc/classes/ConfigFile.xml
msgid ""
@@ -18967,9 +19006,9 @@ msgid ""
"The output file uses an INI-style structure.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
-"使用æä¾›çš„[code]key[/code]å°†[ConfigFile]对象的内容ä¿å­˜åˆ°ä½œä¸ºå‚数指定的AES-256"
-"加密文件中。输出文件使用INIæ ·å¼çš„结构。\n"
-"返回[enum Error]代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
+"使用æä¾›çš„ [code]key[/code] å°† [ConfigFile] 对象的内容ä¿å­˜åˆ°ä½œä¸ºå‚数指定的 "
+"AES-256 加密文件中。输出文件使用 INI æ ·å¼çš„结构。\n"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
#: doc/classes/ConfigFile.xml
msgid ""
@@ -18978,9 +19017,9 @@ msgid ""
"encrypt it. The output file uses an INI-style structure.\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
-"å°†[ConfigFile]对象的内容ä¿å­˜åˆ°ä½œä¸ºå‚数指定的AES-256加密文件中,使用æä¾›çš„"
-"[code]password[/code]进行加密。输出文件使用 INI 风格的结构。\n"
-"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ (æˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
+"å°† [ConfigFile] 对象的内容ä¿å­˜åˆ°ä½œä¸ºå‚数指定的 AES-256 加密文件中,使用æä¾›"
+"的 [code]password[/code]进行加密。输出文件使用 INI 风格的结构。\n"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
#: doc/classes/ConfigFile.xml
msgid ""
@@ -18989,9 +19028,9 @@ msgid ""
"code] value deletes the specified key if it exists, and deletes the section "
"if it ends up empty once the key has been removed."
msgstr ""
-"为指定章节的指定键赋值。如果节或键ä¸å­˜åœ¨ï¼Œåˆ™åˆ›å»ºå®ƒä»¬ã€‚如果指定的键存在,传递"
-"一个[code]null[/code]的值就会删除指定的键,如果键被删除åŽï¼Œé”®æœ€ç»ˆæ˜¯ç©ºçš„,就会"
-"删除节。"
+"为指定章节的指定键赋值。如果节或键ä¸å­˜åœ¨ï¼Œåˆ™åˆ›å»ºå®ƒä»¬ã€‚如果指定的键存在,传递 "
+"[code]null[/code] 值就会移除指定的键,如果键被移除åŽï¼Œé”®æœ€ç»ˆæ˜¯ç©ºçš„,就会移除"
+"节。"
#: doc/classes/ConfirmationDialog.xml
msgid "Dialog for confirmation of actions."
@@ -19007,7 +19046,7 @@ msgid ""
"get_cancel().connect(\"pressed\", self, \"cancelled\")\n"
"[/codeblock]."
msgstr ""
-"用于确认æ“ä½œçš„å¯¹è¯æ¡†ã€‚è¿™ä¸ªå¯¹è¯æ¡†ç»§æ‰¿è‡ª[AcceptDialog]ï¼Œä½†é»˜è®¤æœ‰ä¸€ä¸ªç¡®å®šå’Œå–æ¶ˆ"
+"用于确认æ“ä½œçš„å¯¹è¯æ¡†ã€‚è¿™ä¸ªå¯¹è¯æ¡†ç»§æ‰¿è‡ª [AcceptDialog]ï¼Œä½†é»˜è®¤æœ‰ä¸€ä¸ªç¡®å®šå’Œå–æ¶ˆ"
"按钮(按主机æ“作系统顺åºï¼‰ã€‚\n"
"è¦èŽ·å¾—å–æ¶ˆæ“作,你å¯ä»¥ä½¿ç”¨\n"
"[codeblock]\n"
@@ -19022,7 +19061,7 @@ msgid ""
"[member CanvasItem.visible] property."
msgstr ""
"è¿”å›žå–æ¶ˆæŒ‰é’®ã€‚\n"
-"[b]警告:[/b]这是一个必需的内部节点,删除和释放它å¯èƒ½ä¼šå¯¼è‡´å´©æºƒã€‚如果你希望éš"
+"[b]警告:[/b]这是一个必需的内部节点,移除并释放它å¯èƒ½ä¼šå¯¼è‡´å´©æºƒã€‚如果你希望éš"
"è—它或其任何å­é¡¹ï¼Œè¯·ä½¿ç”¨å…¶ [member CanvasItem.visible] 属性。"
#: doc/classes/Container.xml
@@ -19103,26 +19142,26 @@ msgid ""
"code] methods provided by this class."
msgstr ""
"所有 UI 相关节点的基类。[Control] 具有定义其范围的边界矩形ã€ç›¸å¯¹äºŽå…¶çˆ¶æŽ§ä»¶æˆ–"
-"当å‰è§†çª—的锚点ä½ç½®ä»¥åŠè¡¨ç¤ºé”šç‚¹å移的边è·ã€‚ 当节点ã€å…¶ä»»ä½•父节点或å±å¹•尺寸å‘生"
+"当å‰è§†çª—的锚点ä½ç½®ä»¥åŠè¡¨ç¤ºé”šç‚¹å移的边è·ã€‚当节点ã€å…¶ä»»ä½•父节点或å±å¹•尺寸å‘生"
"å˜åŒ–时,边è·ä¼šè‡ªåŠ¨æ›´æ–°ã€‚\n"
-"更多关于 Godot çš„ UI 系统ã€é”šç‚¹ã€è¾¹è·å’Œå®¹å™¨çš„ä¿¡æ¯ï¼Œè¯·å‚阅手册中的相关教程。 "
-"è¦æž„å»ºçµæ´»çš„ UIï¼Œæ‚¨éœ€è¦æ··åˆä½¿ç”¨ä»Ž [Control] å’Œ [Container] 节点继承的 UI å…ƒ"
+"更多关于 Godot çš„ UI 系统ã€é”šç‚¹ã€è¾¹è·å’Œå®¹å™¨çš„ä¿¡æ¯ï¼Œè¯·å‚阅手册中的相关教程。è¦"
+"æž„å»ºçµæ´»çš„ UIï¼Œæ‚¨éœ€è¦æ··åˆä½¿ç”¨ä»Ž [Control] å’Œ [Container] 节点继承的 UI å…ƒ"
"素。\n"
"[b]用户界é¢èŠ‚ç‚¹å’Œè¾“å…¥[/b]\n"
-"Godot 首先通过调用 [method Node._input] 将输入事件å‘é€åˆ°åœºæ™¯çš„æ ¹èŠ‚ç‚¹ã€‚ "
-"[method Node._input] 将事件沿节点树å‘下转å‘到鼠标光标下或键盘焦点上的节点。 "
-"为此,它调用 [method MainLoop._input_event]。 调用 [method accept_event] 以便"
-"没有其他节点收到该事件。 一旦你接å—一个输入,它就会被处ç†ï¼Œæ‰€ä»¥ [method Node."
+"Godot 首先通过调用 [method Node._input] 将输入事件å‘é€åˆ°åœºæ™¯çš„æ ¹èŠ‚ç‚¹ã€‚"
+"[method Node._input] 将事件沿节点树å‘下转å‘到鼠标光标下或键盘焦点上的节点。为"
+"此,它调用 [method MainLoop._input_event]。调用 [method accept_event] 以便没"
+"有其他节点收到该事件。一旦你接å—一个输入,它就会被处ç†ï¼Œæ‰€ä»¥ [method Node."
"_unhandled_input] ä¸ä¼šå¤„ç†å®ƒã€‚\n"
-"åªæœ‰ä¸€ä¸ª [Control] 节点å¯ä»¥å¤„于键盘焦点。 åªæœ‰å¤„于焦点的节点æ‰ä¼šæŽ¥æ”¶é”®ç›˜äº‹"
-"件。 è¦èŽ·å¾—ç„¦ç‚¹ï¼Œè¯·è°ƒç”¨ [method grab_focus]。在å¦ä¸€ä¸ªèŠ‚ç‚¹èŽ·å¾—èšç„¦æ—¶ "
-"[Control] 节点会失去焦点,或者您éšè—焦点中的节点。\n"
+"åªæœ‰ä¸€ä¸ª [Control] 节点å¯ä»¥å¤„äºŽé”®ç›˜ç„¦ç‚¹ã€‚åªæœ‰å¤„于焦点的节点æ‰ä¼šæŽ¥æ”¶é”®ç›˜äº‹ä»¶ã€‚"
+"è¦èŽ·å¾—ç„¦ç‚¹ï¼Œè¯·è°ƒç”¨ [method grab_focus]。在å¦ä¸€ä¸ªèŠ‚ç‚¹èŽ·å¾—èšç„¦æ—¶ [Control] 节点"
+"会失去焦点,或者您éšè—焦点中的节点。\n"
"将 [member mouse_filter] 设置为 [constant MOUSE_FILTER_IGNORE] 以告诉 "
-"[Control] 节点忽略鼠标或触摸事件。 如果您在按钮顶部放置一个图标,您将需è¦"
+"[Control] 节点忽略鼠标或触摸事件。如果您在按钮顶部放置一个图标,您将需è¦"
"它。\n"
-"[Theme] èµ„æºæ›´æ”¹æŽ§ä»¶çš„外观。 如果您更改 [Control] 节点上的 [Theme],则会影å“"
-"其所有å­èŠ‚ç‚¹ã€‚ è¦è¦†ç›–æŸäº›ä¸»é¢˜çš„傿•°ï¼Œè¯·è°ƒç”¨ [code]add_*_override[/code] 方法"
-"之一,例如 [method add_font_override]。 您å¯ä»¥ä½¿ç”¨æ£€æŸ¥å™¨è¦†ç›–主题。\n"
+"[Theme] èµ„æºæ›´æ”¹æŽ§ä»¶çš„外观。如果您更改 [Control] 节点上的 [Theme],则会影å“å…¶"
+"所有å­èŠ‚ç‚¹ã€‚è¦è¦†ç›–æŸäº›ä¸»é¢˜çš„傿•°ï¼Œè¯·è°ƒç”¨ [code]add_*_override[/code] 方法之"
+"一,例如 [method add_font_override]。您å¯ä»¥ä½¿ç”¨æ£€æŸ¥å™¨è¦†ç›–主题。\n"
"[b]注æ„:[/b]主题项目[i]䏿˜¯[/i] [Object] 的属性。这æ„味ç€ä½ æ— æ³•使用 [method "
"Object.get] å’Œ [method Object.set] 访问它们的值。请æ¢ç”¨ [method get_color]ã€"
"[method get_constant]ã€[method get_font]ã€[method get_icon]ã€[method "
@@ -19249,7 +19288,7 @@ msgid ""
"[/codeblock]"
msgstr ""
"由用户实现的虚方法。返回一个 [Control] 节点,该节点应用作工具æç¤ºè€Œä¸æ˜¯é»˜è®¤èŠ‚"
-"点。 [code]for_text[/code] åŒ…å« [member hint_tooltip] 属性的内容。\n"
+"点。[code]for_text[/code] åŒ…å« [member hint_tooltip] 属性的内容。\n"
"返回的节点必须是 [Control] 或 Control-derived 类型。它å¯ä»¥æœ‰ä»»ä½•类型的å­èŠ‚"
"点。当工具æç¤ºæ¶ˆå¤±æ—¶å®ƒä¼šè¢«é‡Šæ”¾ï¼Œå› æ­¤è¯·ç¡®ä¿ä½ å§‹ç»ˆæä¾›ä¸€ä¸ªæ–°å®žä¾‹ï¼ˆå¦‚果你想使用"
"场景树中预先存在的节点,å¯ä»¥å¤åˆ¶å®ƒå¹¶ä¼ é€’å¤åˆ¶çš„实例)。当返回 [code]null[/"
@@ -19448,10 +19487,10 @@ msgid ""
" color = data[\"color\"]\n"
"[/codeblock]"
msgstr ""
-"Godot调用此方法以将控件的[method get_drag_data]结果中的[code]data[/code]传递"
-"给您。 Godot首先调用[method can_drop_data]æ¥æµ‹è¯•是å¦å…许[code]data[/code]在"
-"[code]position[/code]处删除,其中[code]position[/code]对于此控件而言是本地"
-"的。\n"
+"Godot 调用此方法以将控件的 [method get_drag_data] 结果中的 [code]data[/code] "
+"传递给您。Godot 首先调用 [method can_drop_data] æ¥æµ‹è¯•是å¦å…许 [code]data[/"
+"code] 在 [code]position[/code] 处删除,其中 [code]position[/code] 对于此控件"
+"而言是本地的。\n"
"[codeblock]\n"
"func can_drop_data(position, data):\n"
" return typeof(data) == TYPE_DICTIONARY and data.has(\"color\")\n"
@@ -19463,12 +19502,12 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
"Finds the next (below in the tree) [Control] that can receive the focus."
-msgstr "找到下一个å¯ä»¥æŽ¥å—焦点的[Control],在树的下方。"
+msgstr "找到下一个å¯ä»¥æŽ¥å—焦点的 [Control],在树的下方。"
#: doc/classes/Control.xml
msgid ""
"Finds the previous (above in the tree) [Control] that can receive the focus."
-msgstr "找到å¯ä»¥æŽ¥æ”¶ç„¦ç‚¹çš„上一个[Control],在树的上方。"
+msgstr "找到å¯ä»¥æŽ¥æ”¶ç„¦ç‚¹çš„上一个 [Control],在树的上方。"
#: doc/classes/Control.xml
msgid ""
@@ -19479,11 +19518,11 @@ msgid ""
"The methods [method can_drop_data] and [method drop_data] must be "
"implemented on controls that want to receive drop data."
msgstr ""
-"通过传递[code]data[/code]和[code]preview[/code]强制拖动并绕过[method "
-"get_drag_data]å’Œ[method set_drag_preview]。å³ä½¿é¼ æ ‡æ—¢ä¸åœ¨è¯¥æŽ§ä»¶ä¸Šï¼Œä¹Ÿæœªåœ¨è¯¥æŽ§"
-"件上按下,都将开始拖动。\n"
-"方法[method can_drop_data]å’Œ[method drop_data]å¿…é¡»åœ¨è¦æŽ¥æ”¶æ”¾ç½®æ•°æ®çš„æŽ§ä»¶ä¸Šå®ž"
-"现。"
+"通过传递 [code]data[/code] 和 [code]preview[/code] 强制拖动并绕过 [method "
+"get_drag_data] å’Œ [method set_drag_preview]。å³ä½¿é¼ æ ‡æ—¢ä¸åœ¨è¯¥æŽ§ä»¶ä¸Šï¼Œä¹Ÿæœªåœ¨è¯¥"
+"控件上按下,都将开始拖动。\n"
+"[method can_drop_data] å’Œ [method drop_data] æ–¹æ³•å¿…é¡»åœ¨è¦æŽ¥æ”¶æ”¾ç½®æ•°æ®çš„æŽ§ä»¶ä¸Š"
+"实现。"
#: doc/classes/Control.xml
msgid ""
@@ -19548,7 +19587,8 @@ msgstr ""
msgid ""
"Returns combined minimum size from [member rect_min_size] and [method "
"get_minimum_size]."
-msgstr "返回[member rect_min_size]å’Œ[method get_minimum_size]çš„ç»„åˆæœ€å°å¤§å°ã€‚"
+msgstr ""
+"返回 [member rect_min_size] å’Œ [method get_minimum_size] çš„ç»„åˆæœ€å°å¤§å°ã€‚"
#: doc/classes/Control.xml
msgid ""
@@ -19584,12 +19624,12 @@ msgid ""
" return mydata\n"
"[/codeblock]"
msgstr ""
-"Godot调用此方法æ¥èŽ·å–å¯ä»¥æ‹–放到期望放置数æ®çš„æŽ§ä»¶ä¸Šçš„æ•°æ®ã€‚å¦‚æžœæ²¡æœ‰è¦æ‹–动的数"
-"æ®ï¼Œåˆ™è¿”回 [code]null[/code]ã€‚æƒ³è¦æŽ¥æ”¶æ”¾ç½®æ•°æ®çš„æŽ§ä»¶åº”实现[method "
-"can_drop_data]和[method drop_data]。 [code]position[/code]在此控件中是本地"
-"的。å¯ä»¥ä½¿ç”¨[method force_drag]强制拖动。\n"
-"å¯ä»¥ä½¿ç”¨[method set_drag_preview]设置跟éšé¼ æ ‡çš„预览,该预览将代表数æ®ã€‚设置预"
-"è§ˆçš„å¥½æ—¶æœºå°±æ˜¯è¿™ç§æ–¹æ³•。\n"
+"Godot 调用此方法æ¥èŽ·å–å¯ä»¥æ‹–放到期望放置数æ®çš„æŽ§ä»¶ä¸Šçš„æ•°æ®ã€‚å¦‚æžœæ²¡æœ‰è¦æ‹–动的"
+"æ•°æ®ï¼Œåˆ™è¿”回 [code]null[/code]ã€‚æƒ³è¦æŽ¥æ”¶æ”¾ç½®æ•°æ®çš„æŽ§ä»¶åº”实现 [method "
+"can_drop_data] 和 [method drop_data]。[code]position[/code] 在此控件中是本地"
+"的。å¯ä»¥ä½¿ç”¨ [method force_drag] 强制拖动。\n"
+"å¯ä»¥ä½¿ç”¨ [method set_drag_preview] 设置跟éšé¼ æ ‡çš„预览,该预览将代表数æ®ã€‚设置"
+"é¢„è§ˆçš„å¥½æ—¶æœºå°±æ˜¯è¿™ç§æ–¹æ³•。\n"
"[codeblock]\n"
"func get_drag_data(position):\n"
" var mydata = make_data()\n"
@@ -19599,7 +19639,7 @@ msgstr ""
#: doc/classes/Control.xml
msgid "Returns [member margin_right] and [member margin_bottom]."
-msgstr "返回[member margin_right]和[member margin_bottom]。"
+msgstr "返回 [member margin_right] 和 [member margin_bottom]。"
#: doc/classes/Control.xml
msgid ""
@@ -19608,9 +19648,9 @@ msgid ""
"[member focus_neighbour_left], [member focus_neighbour_right] and [member "
"focus_neighbour_top]."
msgstr ""
-"返回由[enum Margin]枚举的[code]margin[/code]叏釿 ‡è¯†çš„焦点邻居。 [member "
-"focus_neighbour_bottom],[member focus_neighbour_left],[member "
-"focus_neighbour_right]å’Œ[member focus_neighbour_top]çš„èŽ·å–æ–¹æ³•。"
+"返回由 [enum Margin] 枚举的 [code]margin[/code] 叏釿 ‡è¯†çš„焦点邻居。[member "
+"focus_neighbour_bottom]ã€[member focus_neighbour_left]ã€[member "
+"focus_neighbour_right]ã€[member focus_neighbour_top] çš„èŽ·å–æ–¹æ³•。"
#: doc/classes/Control.xml
msgid ""
@@ -19633,7 +19673,7 @@ msgid ""
"Returns the position and size of the control relative to the top-left corner "
"of the screen. See [member rect_position] and [member rect_size]."
msgstr ""
-"返回控件相对于å±å¹•左上角的ä½ç½®å’Œå¤§å°ã€‚请å‚阅[member rect_position]å’Œ[member "
+"返回控件相对于å±å¹•左上角的ä½ç½®å’Œå¤§å°ã€‚è§ [member rect_position] å’Œ [member "
"rect_size]。"
#: doc/classes/Control.xml
@@ -19659,7 +19699,7 @@ msgstr ""
#: doc/classes/Control.xml
msgid "Returns the minimum size for this control. See [member rect_min_size]."
-msgstr "返回此控件的最å°å°ºå¯¸ã€‚å‚阅[member rect_min_size]。"
+msgstr "返回此控件的最å°å°ºå¯¸ã€‚è§ [member rect_min_size]。"
#: doc/classes/Control.xml
msgid "Returns the width/height occupied in the parent control."
@@ -19674,7 +19714,7 @@ msgid ""
"Returns the position and size of the control relative to the top-left corner "
"of the parent Control. See [member rect_position] and [member rect_size]."
msgstr ""
-"返回相对于父控件左上角的控件的ä½ç½®å’Œå¤§å°ã€‚请å‚阅[member rect_position]å’Œ"
+"返回相对于父控件左上角的控件的ä½ç½®å’Œå¤§å°ã€‚è§ [member rect_position] å’Œ "
"[member rect_size]。"
#: doc/classes/Control.xml
@@ -19975,7 +20015,7 @@ msgid ""
"also be updated."
msgstr ""
"将锚点设置为预设 [code]preset[/code],å–值范围为 [enum Control.LayoutPreset] "
-"枚举。等效于在 2D 编辑器中使用布局èœå•。\n"
+"枚举。相当于在 2D 编辑器中使用布局èœå•。\n"
"如果 [code]keep_margins[/code] 是 [code]true[/code],控件的ä½ç½®ä¹Ÿä¼šæ›´æ–°ã€‚"
#: doc/classes/Control.xml
@@ -20106,9 +20146,9 @@ msgid ""
"margin_bottom], [member margin_left], [member margin_right] and [member "
"margin_top]."
msgstr ""
-"设置由[enum Margin]枚举到[code]offset[/code]çš„[code]margin[/code]叏釿‰€æ ‡è¯†çš„"
-"è¾¹è·ã€‚用于[member margin_bottom],[member margin_left],[member margin_right]"
-"和[member margin_top]的设置方法。"
+"设置由 [enum Margin] 枚举到 [code]offset[/code] çš„ [code]margin[/code] 叏釿‰€"
+"标识的边è·ã€‚用于 [member margin_bottom]ã€[member margin_left]ã€[member "
+"margin_right]ã€[member margin_top] 的设置方法。"
#: doc/classes/Control.xml
msgid ""
@@ -20122,8 +20162,8 @@ msgid ""
"Use parameter [code]margin[/code] to determine the gap between the [Control] "
"and the edges."
msgstr ""
-"从 [enum Control.LayoutPreset] 枚举将边è·è®¾ç½®ä¸º [code]preset[/code]。这是等效"
-"于在 2D 编辑器中使用布局èœå•的编ç ã€‚\n"
+"从 [enum Control.LayoutPreset] 枚举将边è·è®¾ç½®ä¸º [code]preset[/code]。相当于"
+"在 2D 编辑器中使用布局èœå•的编ç ã€‚\n"
"ä½¿ç”¨å‚æ•° [code]resize_mode[/code] å’Œ [enum Control.LayoutPresetMode] 中的常é‡"
"æ¥æ›´å¥½åœ°ç¡®å®š [Control] 的最终大å°ã€‚如果与更改大å°çš„预设一起使用,则常规大å°å°†"
"被忽略,例如[code]PRESET_LEFT_WIDE[/code]。\n"
@@ -20149,8 +20189,8 @@ msgid ""
"If [code]keep_margins[/code] is [code]true[/code], control's anchors will be "
"updated instead of margins."
msgstr ""
-"设置控件的大å°(å‚阅[member rect_size])。\n"
-"如果[code]keep_margins[/code]是[code]true[/code]ï¼Œåˆ™ä¼šæ›´æ–°æŽ§ä»¶çš„é”šç‚¹è€Œä¸æ˜¯é¡µ"
+"设置控件的大å°ï¼ˆè§ [member rect_size])。\n"
+"如果 [code]keep_margins[/code] 为 [code]true[/code]ï¼Œåˆ™ä¼šæ›´æ–°æŽ§ä»¶çš„é”šç‚¹è€Œä¸æ˜¯"
"è¾¹è·ã€‚"
#: doc/classes/Control.xml
@@ -20184,8 +20224,8 @@ msgid ""
"moves or changes size. You can use one of the [enum Anchor] constants for "
"convenience."
msgstr ""
-"å°†èŠ‚ç‚¹çš„åº•éƒ¨è¾¹ç¼˜é”šå®šåˆ°å…¶çˆ¶æŽ§ä»¶çš„åŽŸç‚¹ï¼Œä¸­å¿ƒæˆ–æœ«ç«¯ã€‚å½“èŠ‚ç‚¹ç§»åŠ¨æˆ–æ›´æ”¹å¤§å°æ—¶ï¼Œå®ƒ"
-"会更改底部边è·çš„æ›´æ–°æ–¹å¼ã€‚为了方便起è§ï¼Œå¯ä»¥ä½¿ç”¨ [enum Anchor] 常é‡ä¹‹ä¸€ã€‚"
+"å°†èŠ‚ç‚¹çš„åº•è¾¹ç¼˜é”šå®šåˆ°å…¶çˆ¶æŽ§ä»¶çš„åŽŸç‚¹ï¼Œä¸­å¿ƒæˆ–æœ«ç«¯ã€‚å½“èŠ‚ç‚¹ç§»åŠ¨æˆ–æ›´æ”¹å¤§å°æ—¶ï¼Œå®ƒä¼š"
+"更改底部边è·çš„æ›´æ–°æ–¹å¼ã€‚为了方便起è§ï¼Œå¯ä»¥ä½¿ç”¨ [enum Anchor] 常é‡ä¹‹ä¸€ã€‚"
#: doc/classes/Control.xml
msgid ""
@@ -20376,7 +20416,7 @@ msgid ""
"you should not modify them manually if your node is a direct child of a "
"[Container]. Margins update automatically when you move or resize the node."
msgstr ""
-"节点底边与其父控件之间的è·ç¦»ï¼ŒåŸºäºŽ [member anchor_bottom]。\n"
+"节点的底边缘与其父控件之间的è·ç¦»ï¼ŒåŸºäºŽ [member anchor_bottom]。\n"
"è¾¹è·é€šå¸¸ç”±ä¸€ä¸ªæˆ–多个父 [Container] 节点控制,因此,如果您的节点是 "
"[Container] 的直接å­çº§ï¼Œåˆ™ä¸åº”æ‰‹åŠ¨ä¿®æ”¹å®ƒä»¬ã€‚å½“æ‚¨ç§»åŠ¨æˆ–è°ƒæ•´èŠ‚ç‚¹å¤§å°æ—¶ï¼Œè¾¹è·ä¼š"
"自动更新。"
@@ -20415,7 +20455,7 @@ msgid ""
"you should not modify them manually if your node is a direct child of a "
"[Container]. Margins update automatically when you move or resize the node."
msgstr ""
-"节点的顶边与其父控件之间的è·ç¦»ï¼ŒåŸºäºŽ [member anchor_top]。\n"
+"节点的顶边缘与其父控件之间的è·ç¦»ï¼ŒåŸºäºŽ [member anchor_top]。\n"
"è¾¹è·é€šå¸¸ç”±ä¸€ä¸ªæˆ–多个父 [Container] 节点控制,所以如果您的节点是 [Container] "
"的直接å­èŠ‚ç‚¹ï¼Œæ‚¨ä¸åº”è¯¥æ‰‹åŠ¨ä¿®æ”¹å®ƒä»¬ã€‚å½“æ‚¨ç§»åŠ¨æˆ–è°ƒæ•´èŠ‚ç‚¹å¤§å°æ—¶ï¼Œè¾¹è·ä¼šè‡ªåŠ¨æ›´"
"新。"
@@ -20427,9 +20467,9 @@ msgid ""
"[b]Note:[/b] On Linux, shapes may vary depending on the cursor theme of the "
"system."
msgstr ""
-"此控件的默认光标形状。对于Godotæ’ä»¶å’Œä½¿ç”¨ç³»ç»Ÿé¼ æ ‡å…‰æ ‡çš„åº”ç”¨ç¨‹åºæˆ–游æˆå¾ˆæœ‰"
+"此控件的默认光标形状。对于 Godot æ’ä»¶å’Œä½¿ç”¨ç³»ç»Ÿé¼ æ ‡å…‰æ ‡çš„åº”ç”¨ç¨‹åºæˆ–游æˆå¾ˆæœ‰"
"用。\n"
-"[b]注æ„:[/b]在Linux上,形状å¯èƒ½ä¼šæœ‰æ‰€ä¸åŒï¼Œå…·ä½“å–决于系统的光标主题。"
+"[b]注æ„:[/b]在 Linux 上,形状å¯èƒ½ä¼šæœ‰æ‰€ä¸åŒï¼Œå…·ä½“å–决于系统的光标主题。"
#: doc/classes/Control.xml
msgid ""
@@ -20438,9 +20478,9 @@ msgid ""
"Also controls whether the control can receive the [signal mouse_entered], "
"and [signal mouse_exited] signals. See the constants to learn what each does."
msgstr ""
-"控制控件是å¦èƒ½å¤Ÿé€šè¿‡[method _gui_input]接收鼠标按钮输入事件,以åŠå¦‚何处ç†è¿™äº›"
-"事件。还控制控件是å¦èƒ½æŽ¥æ”¶[signal mouse_entered]å’Œ[signal mouse_exited]ä¿¡å·ã€‚"
-"å‚é˜…å¸¸é‡æ¥äº†è§£æ¯ä¸ªå¸¸é‡çš„作用。"
+"控制控件是å¦èƒ½å¤Ÿé€šè¿‡ [method _gui_input] 接收鼠标按钮输入事件,以åŠå¦‚何处ç†è¿™"
+"些事件。还控制控件是å¦èƒ½æŽ¥æ”¶ [signal mouse_entered] å’Œ [signal mouse_exited] "
+"ä¿¡å·ã€‚å‚é˜…å¸¸é‡æ¥äº†è§£æ¯ä¸ªå¸¸é‡çš„作用。"
#: doc/classes/Control.xml
msgid ""
@@ -20448,8 +20488,8 @@ msgid ""
"to this control's rectangle. If [code]true[/code], parts of a child which "
"would be visibly outside of this control's rectangle will not be rendered."
msgstr ""
-"å¯ç”¨æ˜¯å¦åº”将基于[CanvasItem]çš„å­æŽ§ä»¶æ¸²æŸ“åˆ°è¯¥æŽ§ä»¶çš„çŸ©å½¢ä¸Šã€‚å¦‚æžœ[code]true[/"
-"code],则ä¸ä¼šæ¸²æŸ“å­æŽ§ä»¶ä¸­æ˜Žæ˜¾åœ¨çŸ©å½¢ä¹‹å¤–çš„éƒ¨åˆ†ã€‚"
+"å¯ç”¨æ˜¯å¦åº”将基于 [CanvasItem] çš„å­æŽ§ä»¶æ¸²æŸ“åˆ°è¯¥æŽ§ä»¶çš„çŸ©å½¢ä¸Šã€‚å¦‚æžœä¸º "
+"[code]true[/code],则ä¸ä¼šæ¸²æŸ“å­æŽ§ä»¶ä¸­æ˜Žæ˜¾åœ¨çŸ©å½¢ä¹‹å¤–çš„éƒ¨åˆ†ã€‚"
#: doc/classes/Control.xml
msgid ""
@@ -20464,9 +20504,9 @@ msgid ""
"this size, even if its content is smaller. If it's set to (0, 0), the node "
"sizes automatically to fit its content, be it a texture or child nodes."
msgstr ""
-"节点的边界矩形的最å°å°ºå¯¸ã€‚如果你将它设置为大于(0,0)的值,节点的边界矩形将始"
-"终至少有这个大å°ï¼Œå³ä½¿å®ƒçš„内容更å°ã€‚如果设置为(0,0),节点的大å°ä¼šè‡ªåŠ¨é€‚åº”å…¶"
-"内容,无论是纹ç†è¿˜æ˜¯å­èŠ‚ç‚¹ã€‚"
+"节点的边界矩形的最å°å°ºå¯¸ã€‚如果你将它设置为大于 (0,0) 的值,节点的边界矩形将"
+"始终至少有这个大å°ï¼Œå³ä½¿å®ƒçš„内容更å°ã€‚如果设置为 (0,0),节点的大å°ä¼šè‡ªåŠ¨é€‚åº”"
+"其内容,无论是纹ç†è¿˜æ˜¯å­èŠ‚ç‚¹ã€‚"
#: doc/classes/Control.xml
msgid ""
@@ -20529,7 +20569,7 @@ msgstr ""
msgid ""
"The size of the node's bounding rectangle, in pixels. [Container] nodes "
"update this property automatically."
-msgstr "节点边界矩形的大å°ï¼Œä»¥åƒç´ ä¸ºå•ä½ã€‚ [Container]节点会自动更新此属性。"
+msgstr "节点边界矩形的大å°ï¼Œä»¥åƒç´ ä¸ºå•ä½ã€‚[Container]节点会自动更新此属性。"
#: doc/classes/Control.xml
msgid ""
@@ -20537,8 +20577,8 @@ msgid ""
"on the X axis. Use one of the [enum SizeFlags] constants to change the "
"flags. See the constants to learn what each does."
msgstr ""
-"告诉父[Container]节点应如何调整尺寸并将其放置在X轴上。使用[enum SizeFlags]常"
-"é‡ä¹‹ä¸€æ›´æ”¹æ ‡å¿—。查看常é‡ä»¥äº†è§£æ¯ä¸ªå¸¸é‡çš„作用。"
+"告诉父 [Container] 节点应如何调整尺寸并将其放置在 X 轴上。使用 [enum "
+"SizeFlags] 常é‡ä¹‹ä¸€æ›´æ”¹æ ‡å¿—。查看常é‡ä»¥äº†è§£æ¯ä¸ªå¸¸é‡çš„作用。"
#: doc/classes/Control.xml
msgid ""
@@ -20558,14 +20598,14 @@ msgid ""
"on the Y axis. Use one of the [enum SizeFlags] constants to change the "
"flags. See the constants to learn what each does."
msgstr ""
-"告诉父[Container]节点应如何调整尺寸并将其放置在X轴上。使用[enum SizeFlags]常"
-"é‡ä¹‹ä¸€æ›´æ”¹æ ‡å¿—。查看常é‡ä»¥äº†è§£æ¯ä¸ªå¸¸é‡çš„作用。"
+"告诉父 [Container] 节点应如何调整尺寸并将其放置在 X 轴上。使用 [enum "
+"SizeFlags] 常é‡ä¹‹ä¸€æ›´æ”¹æ ‡å¿—。查看常é‡ä»¥äº†è§£æ¯ä¸ªå¸¸é‡çš„作用。"
#: doc/classes/Control.xml
msgid ""
"Changing this property replaces the current [Theme] resource this node and "
"all its [Control] children use."
-msgstr "更改此属性将替æ¢è¯¥èŠ‚ç‚¹åŠå…¶æ‰€æœ‰[Control]å­çº§ä½¿ç”¨çš„当å‰[Theme]资æºã€‚"
+msgstr "更改此属性将替æ¢è¯¥èŠ‚ç‚¹åŠå…¶æ‰€æœ‰ [Control] å­çº§ä½¿ç”¨çš„å½“å‰ [Theme] 资æºã€‚"
#: doc/classes/Control.xml
msgid ""
@@ -20615,7 +20655,7 @@ msgstr "当节点的最å°å¤§å°æ›´æ”¹æ—¶å‘出。"
#: doc/classes/Control.xml
msgid "Emitted when a modal [Control] is closed. See [method show_modal]."
-msgstr "å½“æ¨¡æ€æŽ§ä»¶[Control]被关闭时触å‘。å‚阅[method show_modal]。"
+msgstr "å½“æ¨¡æ€æŽ§ä»¶ [Control] 被关闭时触å‘ã€‚è§ [method show_modal]。"
#: doc/classes/Control.xml
msgid ""
@@ -20669,7 +20709,7 @@ msgid ""
"Emitted when one of the size flags changes. See [member "
"size_flags_horizontal] and [member size_flags_vertical]."
msgstr ""
-"当大尿 ‡å¿—之一更改时å‘出。请å‚阅[member size_flags_horizontal]å’Œ[member "
+"当大尿 ‡å¿—之一更改时å‘å‡ºã€‚è§ [member size_flags_horizontal] å’Œ [member "
"size_flags_vertical]。"
#: doc/classes/Control.xml
@@ -20692,7 +20732,7 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
"Sent when the node changes size. Use [member rect_size] to get the new size."
-msgstr "å½“èŠ‚ç‚¹æ›´æ”¹å¤§å°æ—¶å‘é€ã€‚使用[member rect_size]èŽ·å–æ–°å¤§å°ã€‚"
+msgstr "å½“èŠ‚ç‚¹æ›´æ”¹å¤§å°æ—¶å‘é€ã€‚使用 [member rect_size] èŽ·å–æ–°å¤§å°ã€‚"
#: doc/classes/Control.xml
msgid "Sent when the mouse pointer enters the node."
@@ -20721,27 +20761,27 @@ msgstr ""
#: doc/classes/Control.xml
msgid "Sent when an open modal dialog closes. See [method show_modal]."
-msgstr "当一个打开的模æ€å¯¹è¯æ¡†å…³é—­æ—¶å‘é€ã€‚å‚阅[method show_modal]。"
+msgstr "当一个打开的模æ€å¯¹è¯æ¡†å…³é—­æ—¶å‘é€ã€‚è§ [method show_modal]。"
#: doc/classes/Control.xml
msgid ""
"Sent when this node is inside a [ScrollContainer] which has begun being "
"scrolled."
-msgstr "当此节点在已开始滚动的[ScrollContainer]内部时å‘é€ã€‚"
+msgstr "当此节点在已开始滚动的 [ScrollContainer] 内部时å‘é€ã€‚"
#: doc/classes/Control.xml
msgid ""
"Sent when this node is inside a [ScrollContainer] which has stopped being "
"scrolled."
-msgstr "å½“æ­¤èŠ‚ç‚¹åœ¨å·²åœæ­¢æ»šåŠ¨çš„[ScrollContainer]内部时å‘é€ã€‚"
+msgstr "å½“æ­¤èŠ‚ç‚¹åœ¨å·²åœæ­¢æ»šåŠ¨çš„ [ScrollContainer] 内部时å‘é€ã€‚"
#: doc/classes/Control.xml
msgid ""
"Show the system's arrow mouse cursor when the user hovers the node. Use with "
"[member mouse_default_cursor_shape]."
msgstr ""
-"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçš„箭头鼠标光标。与[member "
-"mouse_default_cursor_shape]æˆå‘˜ä¸€èµ·ä½¿ç”¨ã€‚"
+"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçš„箭头鼠标光标。与 [member "
+"mouse_default_cursor_shape] æˆå‘˜ä¸€èµ·ä½¿ç”¨ã€‚"
#: doc/classes/Control.xml
msgid ""
@@ -20749,7 +20789,7 @@ msgid ""
"beam pointer has a shape similar to \"I\". It tells the user they can "
"highlight or insert text."
msgstr ""
-"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçš„I型光æŸé¼ æ ‡å…‰æ ‡ã€‚å·¥å­—æ¢æŒ‡é’ˆçš„形状类似于“ Iâ€ã€‚它"
+"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçš„I型光æŸé¼ æ ‡å…‰æ ‡ã€‚å·¥å­—æ¢æŒ‡é’ˆçš„形状类似于“Iâ€ã€‚它"
"告诉用户他们å¯ä»¥çªå‡ºæ˜¾ç¤ºæˆ–æ’入文本。"
#: doc/classes/Control.xml
@@ -20833,8 +20873,8 @@ msgid ""
"they can resize the window or the panel both horizontally and vertically."
msgstr ""
"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçª—å£è°ƒæ•´å¤§å°çš„鼠标光标。光标是一个åŒå‘箭头,从左"
-"上角到å³ä¸‹è§’,与[constant CURSOR_BDIAGSIZE]相å。它告诉用户å¯ä»¥æ°´å¹³å’Œåž‚直调整"
-"çª—å£æˆ–颿¿çš„大å°ã€‚"
+"上角到å³ä¸‹è§’,与 [constant CURSOR_BDIAGSIZE] 相å。它告诉用户å¯ä»¥æ°´å¹³å’Œåž‚ç›´è°ƒ"
+"æ•´çª—å£æˆ–颿¿çš„大å°ã€‚"
#: doc/classes/Control.xml
msgid ""
@@ -20843,23 +20883,23 @@ msgid ""
"a UI element freely."
msgstr ""
"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçš„移动鼠标光标。它以90度角显示2个åŒå‘箭头。它告诉"
-"用户他们å¯ä»¥è‡ªç”±ç§»åЍUI元素。"
+"用户他们å¯ä»¥è‡ªç”±ç§»åЍ UI 元素。"
#: doc/classes/Control.xml
msgid ""
"Show the system's vertical split mouse cursor when the user hovers the node. "
"On Windows, it's the same as [constant CURSOR_VSIZE]."
msgstr ""
-"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçš„垂直拆分鼠标光标。在 Windows 上,它与 "
-"[constant CURSOR_VSIZE] 相åŒã€‚"
+"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçš„垂直拆分鼠标光标。在 Windows 上与 [constant "
+"CURSOR_VSIZE] 相åŒã€‚"
#: doc/classes/Control.xml
msgid ""
"Show the system's horizontal split mouse cursor when the user hovers the "
"node. On Windows, it's the same as [constant CURSOR_HSIZE]."
msgstr ""
-"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçš„æ°´å¹³æ‹†åˆ†é¼ æ ‡å…‰æ ‡ã€‚在Windows上,它与[constant "
-"CURSOR_HSIZE]相åŒã€‚"
+"å½“ç”¨æˆ·å°†èŠ‚ç‚¹æ‚¬åœæ—¶ï¼Œæ˜¾ç¤ºç³»ç»Ÿçš„æ°´å¹³æ‹†åˆ†é¼ æ ‡å…‰æ ‡ã€‚在 Windows 上与 [constant "
+"CURSOR_HSIZE] 相åŒã€‚"
#: doc/classes/Control.xml
msgid ""
@@ -21004,7 +21044,7 @@ msgid ""
"editor. Use with [method set_anchors_preset]."
msgstr ""
"将所有 4 个锚点对é½åˆ°çˆ¶æŽ§ä»¶çš„å„个角。应用此预设åŽï¼Œå°†æ‰€æœ‰ 4 个页边è·è®¾ç½®ä¸º "
-"0,[Control] 将适åˆå…¶ä¸Šçº§æŽ§ä»¶ã€‚这等效于编辑器中的“整个矩形â€å¸ƒå±€é€‰é¡¹ã€‚与 "
+"0,[Control] 将适åˆå…¶ä¸Šçº§æŽ§ä»¶ã€‚相当于编辑器中的“整个矩形â€å¸ƒå±€é€‰é¡¹ã€‚与 "
"[method set_anchors_preset] 一起使用。"
#: doc/classes/Control.xml
@@ -21070,9 +21110,9 @@ msgid ""
"flags. Use with [member size_flags_horizontal] and [member "
"size_flags_vertical]."
msgstr ""
-"告诉父级[Container]将节点与其末端(底部或å³ä¾§ï¼‰å¯¹é½ã€‚它ä¸é€‚用于fill或expand "
-"size标志。与[member size_flags_horizontal]和[member size_flags_vertical]一起"
-"使用。"
+"告诉父级 [Container] 将节点与其末端(底部或å³ä¾§ï¼‰å¯¹é½ã€‚它ä¸é€‚用于 fill 或 "
+"expand size 标志。与 [member size_flags_horizontal] 和 [member "
+"size_flags_vertical] 一起使用。"
#: doc/classes/Control.xml
msgid ""
@@ -21163,20 +21203,20 @@ msgstr ""
#: doc/classes/ConvexPolygonShape.xml
msgid "Convex polygon shape for 3D physics."
-msgstr "用于3D物ç†çš„凸多边形形状。"
+msgstr "用于 3D 物ç†çš„凸多边形形状。"
#: doc/classes/ConvexPolygonShape.xml
msgid ""
"Convex polygon shape resource, which can be added to a [PhysicsBody] or area."
-msgstr "凸多边形形状资æºï¼Œå¯ä»¥æ·»åŠ åˆ°[PhysicsBody]或area区域。"
+msgstr "凸多边形形状资æºï¼Œå¯ä»¥æ·»åŠ åˆ° [PhysicsBody] 或区域。"
#: doc/classes/ConvexPolygonShape.xml
msgid "The list of 3D points forming the convex polygon shape."
-msgstr "å½¢æˆå‡¸å¤šè¾¹å½¢çš„3D点列表。"
+msgstr "å½¢æˆå‡¸å¤šè¾¹å½¢çš„ 3D 点列表。"
#: doc/classes/ConvexPolygonShape2D.xml
msgid "Convex polygon shape for 2D physics."
-msgstr "用于2D物ç†çš„凸多边形形状。"
+msgstr "用于 2D 物ç†çš„凸多边形形状。"
#: doc/classes/ConvexPolygonShape2D.xml
msgid ""
@@ -21189,12 +21229,12 @@ msgid ""
"uses a more complex method of collision detection, and a convex one forces "
"itself to be convex in order to speed up collision detection."
msgstr ""
-"用于2D物ç†çš„凸多边形形状。凸多边形,无论其形状如何,都å¯ä»¥åœ¨å†…部分解为所需数"
-"é‡çš„凸多边形,以确ä¿å§‹ç»ˆå¯¹å‡¸å¤šè¾¹å½¢æ‰§è¡Œæ‰€æœ‰é’ˆå¯¹å®ƒçš„碰撞检查(检查速度更"
+"用于 2D 物ç†çš„凸多边形形状。凸多边形,无论其形状如何,都å¯ä»¥åœ¨å†…部分解为所需"
+"æ•°é‡çš„凸多边形,以确ä¿å§‹ç»ˆå¯¹å‡¸å¤šè¾¹å½¢æ‰§è¡Œæ‰€æœ‰é’ˆå¯¹å®ƒçš„碰撞检查(检查速度更"
"快)。\n"
-"[ConvexPolygonShape2D]å’Œ[ConcavePolygonShape2D]之间的主è¦åŒºåˆ«åœ¨äºŽï¼Œå‡¹é¢å¤šè¾¹å½¢"
-"å‡å®šå…¶ä¸ºå‡¹é¢ï¼Œå¹¶ä½¿ç”¨æ›´å¤æ‚的碰撞检测方法,而凸é¢å¤šè¾¹å½¢åˆ™å°†è‡ªèº«å¼ºåˆ¶å˜ä¸ºå‡¸é¢ï¼Œ"
-"以加快碰撞检测的速度。"
+"[ConvexPolygonShape2D] å’Œ [ConcavePolygonShape2D] 之间的主è¦åŒºåˆ«åœ¨äºŽï¼Œå‡¹é¢å¤š"
+"边形å‡å®šå…¶ä¸ºå‡¹é¢ï¼Œå¹¶ä½¿ç”¨æ›´å¤æ‚的碰撞检测方法,而凸é¢å¤šè¾¹å½¢åˆ™å°†è‡ªèº«å¼ºåˆ¶å˜ä¸ºå‡¸"
+"é¢ï¼Œä»¥åŠ å¿«ç¢°æ’žæ£€æµ‹çš„é€Ÿåº¦ã€‚"
#: doc/classes/ConvexPolygonShape2D.xml
msgid ""
@@ -21202,8 +21242,8 @@ msgid ""
"points] property using the convex hull algorithm. Removing all unneeded "
"points. See [method Geometry.convex_hull_2d] for details."
msgstr ""
-"基于所æä¾›ç‚¹çš„集åˆï¼Œä½¿ç”¨å‡¸åŒ…ç®—æ³•åˆ›å»ºå’Œåˆ†é… [member points]属性。删除所有ä¸éœ€"
-"è¦çš„点。å‚阅[method Geometry.convex_hull_2d]。"
+"基于所æä¾›ç‚¹çš„集åˆï¼Œä½¿ç”¨å‡¸åŒ…ç®—æ³•åˆ›å»ºå’Œåˆ†é… [member points]属性。移除所有ä¸éœ€"
+"è¦çš„点。详情请å‚阅 [method Geometry.convex_hull_2d]。"
#: doc/classes/ConvexPolygonShape2D.xml
msgid ""
@@ -21242,21 +21282,21 @@ msgstr ""
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Returns the base value of the parameter specified by [enum Parameter]."
-msgstr "返回由[enum Parameter]æŒ‡å®šçš„å‚æ•°çš„基值。"
+msgstr "返回由 [enum Parameter] æŒ‡å®šçš„å‚æ•°çš„基值。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Returns the [Curve] of the parameter specified by [enum Parameter]."
-msgstr "返回由[enum Parameter]æŒ‡å®šçš„å‚æ•°çš„[Curve]。"
+msgstr "返回由 [enum Parameter] æŒ‡å®šçš„å‚æ•°çš„ [Curve]。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Returns the randomness factor of the parameter specified by [enum Parameter]."
-msgstr "返回[enum Parameter]æŒ‡å®šçš„å‚æ•°çš„éšæœºæ€§ç³»æ•°ã€‚"
+msgstr "返回由 [enum Parameter] æŒ‡å®šçš„å‚æ•°çš„éšæœºæ€§ç³»æ•°ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Returns the enabled state of the given flag (see [enum Flags] for options)."
-msgstr "返回给定标志的å¯ç”¨çжæ€ï¼ˆæœ‰å…³é€‰é¡¹ï¼Œè¯·å‚阅[enum Flags])。"
+msgstr "返回给定标志的å¯ç”¨çжæ€ï¼ˆæœ‰å…³é€‰é¡¹ï¼Œè¯·å‚阅 [enum Flags])。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Restarts the particle emitter."
@@ -21264,20 +21304,20 @@ msgstr "釿–°å¯åŠ¨ç²’å­å‘射器。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Sets the base value of the parameter specified by [enum Parameter]."
-msgstr "设置[enum Parameter]æŒ‡å®šçš„å‚æ•°çš„基值。"
+msgstr "设置 [enum Parameter] æŒ‡å®šçš„å‚æ•°çš„基值。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Sets the [Curve] of the parameter specified by [enum Parameter]."
-msgstr "设置[enum Parameter]æŒ‡å®šçš„å‚æ•°çš„[Curve]。"
+msgstr "设置 [enum Parameter] æŒ‡å®šçš„å‚æ•°çš„ [Curve]。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Sets the randomness factor of the parameter specified by [enum Parameter]."
-msgstr "设置[enum Parameter]æŒ‡å®šçš„å‚æ•°çš„éšæœºæ€§å› å­ã€‚"
+msgstr "设置 [enum Parameter] æŒ‡å®šçš„å‚æ•°çš„éšæœºæ€§å› å­ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Enables or disables the given flag (see [enum Flags] for options)."
-msgstr "å¯ç”¨æˆ–ç¦ç”¨ç»™å®šæ ‡å¿—(有关选项,请å‚阅[enum Flags])。"
+msgstr "å¯ç”¨æˆ–ç¦ç”¨ç»™å®šæ ‡å¿—(有关选项,请å‚阅 [enum Flags])。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/Particles.xml doc/classes/Particles2D.xml
@@ -21288,9 +21328,9 @@ msgid ""
"therefore removing all particles that were already emitted before changing "
"[member amount]."
msgstr ""
-"在一个å‘å°„å‘¨æœŸå†…æŽ’æ”¾çš„ç²’å­æ•°ï¼ˆå¯¹åº”于[member lifetime])。\n"
-"[b]注æ„:[/b]改å˜[member amount]å°†é‡ç½®ç²’å­å‘射,因此,在改å˜[member amount]之"
-"å‰å·²ç»æŽ’放的所有粒å­å°†è¢«ç§»é™¤ã€‚"
+"在一个å‘å°„å‘¨æœŸå†…æŽ’æ”¾çš„ç²’å­æ•°ï¼ˆå¯¹åº”于 [member lifetime])。\n"
+"[b]注æ„:[/b]æ”¹å˜ [member amount] å°†é‡ç½®ç²’å­å‘å°„ï¼Œå› æ­¤ï¼Œåœ¨æ”¹å˜ [member "
+"amount] 之å‰å·²ç»æŽ’放的所有粒å­å°†è¢«ç§»é™¤ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Initial rotation applied to each particle, in degrees."
@@ -21298,7 +21338,7 @@ msgstr "应用于æ¯ä¸ªç²’å­çš„åˆå§‹æ—‹è½¬ï¼ˆä»¥åº¦ä¸ºå•ä½ï¼‰ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's rotation will be animated along this [Curve]."
-msgstr "æ¯ä¸ªç²’å­çš„æ—‹è½¬å°†æ²¿æ­¤[Curve]进行动画处ç†ã€‚"
+msgstr "æ¯ä¸ªç²’å­çš„æ—‹è½¬å°†æ²¿æ­¤ [Curve] 进行动画处ç†ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21313,7 +21353,7 @@ msgstr "应用于æ¯ä¸ªç²’å­çš„åˆå§‹è§’速度,å•ä½ä¸º[i]度[/i]æ¯ç§’。è®
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's angular velocity will vary along this [Curve]."
-msgstr "æ¯ä¸ªç²’å­çš„角速度将沿此[Curve]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„角速度将沿此 [Curve] å˜åŒ–。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21327,7 +21367,7 @@ msgstr "ç²’å­åŠ¨ç”»åç§»é‡ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's animation offset will vary along this [Curve]."
-msgstr "æ¯ä¸ªç²’å­çš„动画å移将沿此[Curve]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„动画å移将沿此 [Curve] å˜åŒ–。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21341,7 +21381,7 @@ msgstr "ç²’å­åŠ¨ç”»é€Ÿåº¦ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's animation speed will vary along this [Curve]."
-msgstr "æ¯ä¸ªç²’å­çš„动画速度将沿此[Curve]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„动画速度将沿此 [Curve] å˜åŒ–。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21370,8 +21410,8 @@ msgid ""
"Each particle's color will vary along this [GradientTexture] over its "
"lifetime (multiplied with [member color])."
msgstr ""
-"æ¯ä¸ªç²’å­çš„颜色将在其生命周期内éšç€è¿™ä¸ª[GradientTexture]å˜åŒ–,å³ä¸Ž[member "
-"color]相乘。"
+"æ¯ä¸ªç²’å­çš„颜色将在其生命周期内éšç€è¿™ä¸ª [GradientTexture] å˜åŒ–(与 [member "
+"color] 相乘)。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21380,7 +21420,7 @@ msgstr "ç²’å­å¤±åŽ»é€Ÿåº¦çš„é€ŸçŽ‡ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Damping will vary along this [Curve]."
-msgstr "阻尼将沿ç€è¿™æ¡[Gradient]å˜åŒ–。"
+msgstr "阻尼将沿ç€è¿™æ¡ [Gradient] å˜åŒ–。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21395,7 +21435,7 @@ msgstr "指定粒å­å‘å°„æ–¹å‘çš„å•ä½å‘é‡ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/Particles.xml doc/classes/Particles2D.xml
msgid "Particle draw order. Uses [enum DrawOrder] values."
-msgstr "ç²’å­ç»˜åˆ¶é¡ºåºã€‚使用[enum DrawOrder]值。"
+msgstr "ç²’å­ç»˜åˆ¶é¡ºåºã€‚使用 [enum DrawOrder] 值。"
#: doc/classes/CPUParticles.xml
msgid ""
@@ -21410,65 +21450,65 @@ msgid ""
"Sets the [Color]s to modulate particles by when using [constant "
"EMISSION_SHAPE_POINTS] or [constant EMISSION_SHAPE_DIRECTED_POINTS]."
msgstr ""
-"设置[Color]以使用[constant EMISSION_SHAPE_POINTS]或[constant "
-"EMISSION_SHAPE_DIRECTED_POINTS]æ¥è°ƒåˆ¶ç²’å­ã€‚"
+"设置 [Color] 以使用 [constant EMISSION_SHAPE_POINTS] 或 [constant "
+"EMISSION_SHAPE_DIRECTED_POINTS] æ¥è°ƒåˆ¶ç²’å­ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Sets the direction the particles will be emitted in when using [constant "
"EMISSION_SHAPE_DIRECTED_POINTS]."
-msgstr "设置使用[constant EMISSION_SHAPE_DIRECTED_POINTS]æ—¶ç²’å­å‘射的方å‘。"
+msgstr "设置使用 [constant EMISSION_SHAPE_DIRECTED_POINTS] æ—¶ç²’å­å‘射的方å‘。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Sets the initial positions to spawn particles when using [constant "
"EMISSION_SHAPE_POINTS] or [constant EMISSION_SHAPE_DIRECTED_POINTS]."
msgstr ""
-"设置使用[constant EMISSION_SHAPE_POINTS]或[constant "
-"EMISSION_SHAPE_DIRECTED_POINTS]时产生粒å­çš„åˆå§‹ä½ç½®ã€‚"
+"设置使用 [constant EMISSION_SHAPE_POINTS] 或 [constant "
+"EMISSION_SHAPE_DIRECTED_POINTS] 时产生粒å­çš„åˆå§‹ä½ç½®ã€‚"
#: doc/classes/CPUParticles.xml
msgid ""
"The axis for the ring shaped emitter when using [constant "
"EMISSION_SHAPE_RING]."
-msgstr "使用[constant EMISSION_SHAPE_RING]时,环形å‘射器的轴。"
+msgstr "使用 [constant EMISSION_SHAPE_RING] 时,环形å‘射器的轴。"
#: doc/classes/CPUParticles.xml
msgid ""
"The height for the ring shaped emitter when using [constant "
"EMISSION_SHAPE_RING]."
-msgstr "使用[constant EMISSION_SHAPE_RING]时,环形å‘射器的高度。"
+msgstr "使用 [constant EMISSION_SHAPE_RING] 时,环形å‘射器的高度。"
#: doc/classes/CPUParticles.xml
msgid ""
"The inner radius for the ring shaped emitter when using [constant "
"EMISSION_SHAPE_RING]."
-msgstr "使用[constant EMISSION_SHAPE_RING]时,环形å‘射器的内åŠå¾„。"
+msgstr "使用 [constant EMISSION_SHAPE_RING] 时,环形å‘射器的内åŠå¾„。"
#: doc/classes/CPUParticles.xml
msgid ""
"The radius for the ring shaped emitter when using [constant "
"EMISSION_SHAPE_RING]."
-msgstr "使用[constant EMISSION_SHAPE_RING]时,环形å‘射器的åŠå¾„。"
+msgstr "使用 [constant EMISSION_SHAPE_RING] 时,环形å‘射器的åŠå¾„。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
"Particles will be emitted inside this region. See [enum EmissionShape] for "
"possible values."
-msgstr "ç²’å­å°†åœ¨æ­¤åŒºåŸŸå†…å‘射。有关å¯èƒ½çš„值,请å‚阅[enum EmissionShape]。"
+msgstr "ç²’å­å°†åœ¨æ­¤åŒºåŸŸå†…å‘射。å¯èƒ½çš„å–å€¼è§ [enum EmissionShape]。"
#: doc/classes/CPUParticles.xml
msgid ""
"The sphere's radius if [enum EmissionShape] is set to [constant "
"EMISSION_SHAPE_SPHERE]."
msgstr ""
-"如果[enum EmissionShape]设置为[constant EMISSION_SHAPE_SPHERE],则çƒä½“çš„åŠ"
+"如果 [enum EmissionShape] 设置为 [constant EMISSION_SHAPE_SPHERE],则çƒä½“çš„åŠ"
"径。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/Particles.xml doc/classes/Particles2D.xml
msgid "If [code]true[/code], particles are being emitted."
-msgstr "如果[code]true[/code],则正在å‘å°„ç²’å­ã€‚"
+msgstr "如果为 [code]true[/code],则正在å‘å°„ç²’å­ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/Particles2D.xml
@@ -21486,8 +21526,8 @@ msgid ""
"the value to 2 will make the particles render at 2 frames per second. Note "
"this does not slow down the particle system itself."
msgstr ""
-"ç²’å­ç³»ç»Ÿçš„帧速率固定为一个值。例如,将值更改为2将使粒å­ä»¥æ¯ç§’2帧的速度渲染。"
-"请注æ„,这ä¸ä¼šå‡æ…¢ç²’å­ç³»ç»Ÿæœ¬èº«çš„速度。"
+"ç²’å­ç³»ç»Ÿçš„帧速率固定为一个值。例如,将值更改为 2 将使粒å­ä»¥æ¯ç§’ 2 帧的速度渲"
+"染。请注æ„,这ä¸ä¼šå‡æ…¢ç²’å­ç³»ç»Ÿæœ¬èº«çš„速度。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21516,7 +21556,8 @@ msgid ""
"If [code]true[/code], results in fractional delta calculation which has a "
"smoother particles display effect."
msgstr ""
-"如果[code]true[/code],将导致分数增é‡è®¡ç®—ï¼Œè¯¥æ˜¾ç¤ºå…·æœ‰æ›´å¹³æ»‘çš„ç²’å­æ˜¾ç¤ºæ•ˆæžœã€‚"
+"如果为 [code]true[/code],将导致分数增é‡è®¡ç®—ï¼Œè¯¥æ˜¾ç¤ºå…·æœ‰æ›´å¹³æ»‘çš„ç²’å­æ˜¾ç¤ºæ•ˆ"
+"果。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21567,7 +21608,7 @@ msgstr "沿è¿åŠ¨æ–¹å‘æ–½åŠ åˆ°æ¯ä¸ªç²’å­çš„线性加速度。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's linear acceleration will vary along this [Curve]."
-msgstr "æ¯ä¸ªç²’å­çš„线性加速度将沿此[Curve]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„线性加速度将沿此 [Curve] å˜åŒ–。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21580,14 +21621,14 @@ msgid ""
"If [code]true[/code], particles use the parent node's coordinate space. If "
"[code]false[/code], they use global coordinates."
msgstr ""
-"如果[code]true[/code],则粒å­å°†ä½¿ç”¨çˆ¶èŠ‚ç‚¹çš„åæ ‡ç©ºé—´ã€‚如果[code]false[/code],"
-"åˆ™ä½¿ç”¨å…¨å±€åæ ‡ã€‚"
+"如果为 [code]true[/code],则粒å­å°†ä½¿ç”¨çˆ¶èŠ‚ç‚¹çš„åæ ‡ç©ºé—´ã€‚如果为 [code]false[/"
+"code]ï¼Œåˆ™ä½¿ç”¨å…¨å±€åæ ‡ã€‚"
#: doc/classes/CPUParticles.xml
msgid ""
"The [Mesh] used for each particle. If [code]null[/code], particles will be "
"spheres."
-msgstr "æ¯ä¸ªç²’å­ä½¿ç”¨çš„[Mesh]。如果[code]null[/code],则粒å­å°†æ˜¯çƒå½¢ã€‚"
+msgstr "æ¯ä¸ªç²’å­ä½¿ç”¨çš„ [Mesh]。如果为 [code]null[/code],则粒å­å°†ä¸ºçƒå½¢ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/Particles2D.xml
@@ -21595,7 +21636,7 @@ msgid ""
"If [code]true[/code], only one emission cycle occurs. If set [code]true[/"
"code] during a cycle, emission will stop at the cycle's end."
msgstr ""
-"如果 [code]true[/code],则åªå‘生一个排放周期。如果在周期内设置 [code]true[/"
+"如果为 [code]true[/code],则åªå‘生一个排放周期。如果在周期内设置 [code]true[/"
"code]ï¼Œåˆ™æŽ’æ”¾å°†åœ¨å‘¨æœŸç»“æŸæ—¶åœæ­¢ã€‚"
#: doc/classes/CPUParticles.xml
@@ -21612,7 +21653,7 @@ msgstr ""
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's orbital velocity will vary along this [Curve]."
-msgstr "æ¯ä¸ªç²’å­çš„轨é“速度将沿此[Curve]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„轨é“速度将跟éšè¿™ä¸ª [Curve] å˜åŒ–。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21633,7 +21674,7 @@ msgstr "径å‘加速度应用于æ¯ä¸ªç²’å­ã€‚使粒å­åŠ é€Ÿè¿œç¦»åŽŸç‚¹ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's radial acceleration will vary along this [Curve]."
-msgstr "æ¯ä¸ªç²’å­çš„径å‘加速度将沿此[Curve]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„径å‘加速度将跟éšè¿™ä¸ª [Curve] å˜åŒ–。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21648,31 +21689,31 @@ msgstr "å‘å°„å¯¿å‘½éšæœºçŽ‡ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
msgid "Initial scale applied to each particle."
-msgstr "åˆå§‹æ¯”例应用于æ¯ä¸ªç²’å­ã€‚"
+msgstr "æ¯ä¸ªç²’å­çš„åˆå§‹ç¼©æ”¾ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's scale will vary along this [Curve]."
-msgstr "æ¯ä¸ªç²’å­çš„æ¯”例将éšç€[Curve]çš„å˜åŒ–而å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„缩放将跟éšè¿™ä¸ª [Curve] å˜åŒ–。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
msgid "Scale randomness ratio."
-msgstr "æ ‡åº¦éšæœºçŽ‡ã€‚"
+msgstr "ç¼©æ”¾éšæœºçŽ‡ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/Particles2D.xml
msgid ""
"Particle system's running speed scaling ratio. A value of [code]0[/code] can "
"be used to pause the particles."
-msgstr "ç²’å­ç³»ç»Ÿçš„è¿è¡Œé€Ÿåº¦ç¼©æ”¾æ¯”例。值[code]0[/code]å¯ç”¨äºŽæš‚åœç²’å­ã€‚"
+msgstr "ç²’å­ç³»ç»Ÿçš„è¿è¡Œé€Ÿåº¦ç¼©æ”¾æ¯”例。将值设为 [code]0[/code] å¯ç”¨äºŽæš‚åœç²’å­ã€‚"
#: doc/classes/CPUParticles.xml
msgid ""
"Each particle's initial direction range from [code]+spread[/code] to [code]-"
"spread[/code] degrees. Applied to X/Z plane and Y/Z planes."
msgstr ""
-"æ¯ä¸ªç²’å­çš„åˆå§‹æ–¹å‘范围为[code]+spread[/code]至[code]-spread[/code]度。适用于"
-"X/Zå¹³é¢å’ŒY/Zå¹³é¢ã€‚"
+"æ¯ä¸ªç²’å­çš„åˆå§‹æ–¹å‘范围为 [code]+spread[/code] 至 [code]-spread[/code] 度。适"
+"用于 X/Z å¹³é¢å’Œ Y/Z å¹³é¢ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21685,7 +21726,7 @@ msgstr ""
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Each particle's tangential acceleration will vary along this [Curve]."
-msgstr "æ¯ä¸ªç²’å­çš„切å‘加速度将沿此[Curve]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„切å‘加速度将跟éšè¿™ä¸ª [Curve] å˜åŒ–。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21805,7 +21846,7 @@ msgstr ""
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
msgid "Represents the size of the [enum Parameter] enum."
-msgstr "表示[enum Parameter]枚举的大å°ã€‚"
+msgstr "表示 [enum Parameter] 枚举的大å°ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid "Use with [method set_particle_flag] to set [member flag_align_y]."
@@ -21823,7 +21864,7 @@ msgstr "用于在 [method set_particle_flag] 中设置 [member flag_disable_z]ã€
#: doc/classes/GeometryInstance.xml doc/classes/ParticlesMaterial.xml
#: doc/classes/SpatialMaterial.xml
msgid "Represents the size of the [enum Flags] enum."
-msgstr "表示[enum Flags]枚举的大å°ã€‚"
+msgstr "表示 [enum Flags] 枚举的大å°ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
@@ -21844,8 +21885,8 @@ msgid ""
"emission_points]. Particle color will be modulated by [member "
"emission_colors]."
msgstr ""
-"ç²’å­å°†åœ¨[member emission_points]ä¸­éšæœºé€‰æ‹©çš„ä½ç½®å‘射。粒å­é¢œè‰²å°†é€šè¿‡[member "
-"emission_colors]进行调制。"
+"ç²’å­å°†åœ¨ [member emission_points] ä¸­éšæœºé€‰æ‹©çš„ä½ç½®å‘射。粒å­é¢œè‰²å°†é€šè¿‡ "
+"[member emission_colors] 进行调制。"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
msgid ""
@@ -21854,9 +21895,9 @@ msgid ""
"[member emission_normals]. Particle color will be modulated by [member "
"emission_colors]."
msgstr ""
-"ç²’å­å°†åœ¨[member emission_points]ä¸­éšæœºé€‰æ‹©çš„ä½ç½®å‘射。粒å­çš„速度和旋转将基于"
-"[member emission_normals]进行设置。粒å­é¢œè‰²å°†é€šè¿‡[member emission_colors]进行"
-"调制。"
+"ç²’å­å°†åœ¨ [member emission_points] ä¸­éšæœºé€‰æ‹©çš„ä½ç½®å‘射。粒å­çš„速度和旋转将基"
+"于 [member emission_normals] 进行设置。粒å­é¢œè‰²å°†é€šè¿‡ [member "
+"emission_colors] 进行调制。"
#: doc/classes/CPUParticles.xml doc/classes/ParticlesMaterial.xml
msgid "Particles will be emitted in a ring or cylinder."
@@ -21865,7 +21906,7 @@ msgstr "ç²’å­å°†ä»¥çŽ¯å½¢æˆ–åœ†æŸ±çš„å½¢å¼å‘射出æ¥ã€‚"
#: doc/classes/CPUParticles.xml doc/classes/CPUParticles2D.xml
#: doc/classes/ParticlesMaterial.xml
msgid "Represents the size of the [enum EmissionShape] enum."
-msgstr "表示[enum EmissionShape]枚举的大å°ã€‚"
+msgstr "表示 [enum EmissionShape] 枚举的大å°ã€‚"
#: doc/classes/CPUParticles2D.xml
msgid "CPU-based 2D particle emitter."
@@ -21881,7 +21922,7 @@ msgid ""
"fly and doesn't need to be configured by the user."
msgstr ""
"基于 CPU çš„ 2D ç²’å­èŠ‚ç‚¹ï¼Œç”¨äºŽåˆ›å»ºå„ç§ç²’å­ç³»ç»Ÿå’Œæ•ˆæžœã€‚\n"
-"å‚阅 [Particles2D],它通过硬件加速æä¾›ç›¸åŒçš„功能,但å¯èƒ½æ— æ³•在旧设备上è¿"
+"å¦è¯·å‚阅 [Particles2D],它通过硬件加速æä¾›ç›¸åŒçš„功能,但å¯èƒ½æ— æ³•在旧设备上è¿"
"行。\n"
"[b]注æ„:[/b]其与 [Particles2D] ä¸åŒï¼Œå¯è§æ€§çŸ©å½¢æ˜¯å³æ—¶ç”Ÿæˆçš„,ä¸éœ€è¦ç”¨æˆ·é…"
"置。"
@@ -21904,23 +21945,23 @@ msgstr "æ¯ä¸ªç²’å­çš„åˆå§‹é¢œè‰²ã€‚如果定义了 [member texture],它将ä
msgid ""
"Each particle's color will vary along this [Gradient] (multiplied with "
"[member color])."
-msgstr "æ¯ä¸ªç²’å­çš„颜色将éšç€è¿™ä¸ª[Gradient]å˜åŒ–,å³ä¸Ž[member color]相乘。"
+msgstr "æ¯ä¸ªç²’å­çš„颜色将éšç€è¿™ä¸ª [Gradient] å˜åŒ–(与 [member color] 相乘)。"
#: doc/classes/CPUParticles2D.xml
msgid ""
"The rectangle's extents if [member emission_shape] is set to [constant "
"EMISSION_SHAPE_RECTANGLE]."
msgstr ""
-"如果 [member emission_shape] 设置为 [constant EMISSION_SHAPE_RECTANGLE],则矩"
-"形的范围。"
+"[member emission_shape] 设置为 [constant EMISSION_SHAPE_RECTANGLE] 时,该矩形"
+"的范围。"
#: doc/classes/CPUParticles2D.xml
msgid ""
"The sphere's radius if [member emission_shape] is set to [constant "
"EMISSION_SHAPE_SPHERE]."
msgstr ""
-"如果 [member emission_shape] 设置为 [constant EMISSION_SHAPE_SPHERE],则çƒä½“"
-"çš„åŠå¾„。"
+"[member emission_shape] 设置为 [constant EMISSION_SHAPE_SPHERE] 时,该çƒä½“çš„"
+"åŠå¾„。"
#: doc/classes/CPUParticles2D.xml doc/classes/Particles.xml
#: doc/classes/Particles2D.xml
@@ -21958,15 +21999,15 @@ msgid ""
"Each particle's initial direction range from [code]+spread[/code] to [code]-"
"spread[/code] degrees."
msgstr ""
-"æ¯ä¸ªç²’å­çš„åˆå§‹æ–¹å‘范围为[code]+spread[/code] 到 [code]-spread[/code]度。"
+"æ¯ä¸ªç²’å­çš„åˆå§‹æ–¹å‘范围为 [code]+spread[/code] 到 [code]-spread[/code] 度。"
#: doc/classes/CPUParticles2D.xml doc/classes/Particles2D.xml
msgid "Particle texture. If [code]null[/code], particles will be squares."
-msgstr "ç²’å­çº¹ç†ã€‚如果[code]null[/code],则粒å­å°†ä¸ºæ­£æ–¹å½¢ã€‚"
+msgstr "ç²’å­çº¹ç†ã€‚如果为 [code]null[/code],则粒å­å°†ä¸ºæ­£æ–¹å½¢ã€‚"
#: doc/classes/CPUParticles2D.xml
msgid "Present for consistency with 3D particle nodes, not used in 2D."
-msgstr "为了与3Dç²’å­èŠ‚ç‚¹ä¿æŒä¸€è‡´è€Œå­˜åœ¨ï¼Œåœ¨2D中ä¸ä½¿ç”¨ã€‚"
+msgstr "为了与 3D ç²’å­èŠ‚ç‚¹ä¿æŒä¸€è‡´è€Œå­˜åœ¨ï¼Œåœ¨ 2D 中ä¸ä½¿ç”¨ã€‚"
#: doc/classes/CPUParticles2D.xml
msgid ""
@@ -22022,9 +22063,9 @@ msgid ""
"[/codeblock]\n"
"[b]Note:[/b] Not available in HTML5 exports."
msgstr ""
-"Cryptoç±»å…许您访问Godot中的一些更高级的加密功能。\n"
-"ç›®å‰ï¼Œè¿™åŒ…括生æˆåŠ å¯†å®‰å…¨çš„éšæœºå­—节,RSA密钥和自签åX509è¯ä¹¦ç”Ÿæˆï¼Œéžå¯¹ç§°å¯†é’¥åŠ "
-"密/解密以åŠç­¾å/验è¯ã€‚\n"
+"Crypto ç±»å…许您访问 Godot 中的一些更高级的加密功能。\n"
+"ç›®å‰ï¼Œè¿™åŒ…括生æˆåŠ å¯†å®‰å…¨çš„éšæœºå­—节,RSA 密钥和自签å X509 è¯ä¹¦ç”Ÿæˆï¼Œéžå¯¹ç§°å¯†"
+"钥加密/解密以åŠç­¾å/验è¯ã€‚\n"
"[codeblock]\n"
"extends Node\n"
"\n"
@@ -22033,30 +22074,30 @@ msgstr ""
"var cert = X509Certificate.new()\n"
"\n"
"func _ready():\n"
-" # Generate new RSA key.\n"
+" # ç”Ÿæˆæ–°çš„ RSA 密钥。\n"
" key = crypto.generate_rsa(4096)\n"
-" # Generate new self-signed certificate with the given key.\n"
+" # ä½¿ç”¨ç»™å®šçš„å¯†é’¥ç”Ÿæˆæ–°çš„自签åè¯ä¹¦ã€‚\n"
" cert = crypto.generate_self_signed_certificate(key, \"CN=mydomain.com,"
"O=My Game Company,C=IT\")\n"
-" # Save key and certificate in the user folder.\n"
+" # 将密钥和è¯ä¹¦ä¿å­˜åˆ°ç”¨æˆ·æ–‡ä»¶å¤¹ä¸­ã€‚\n"
" key.save(\"user://generated.key\")\n"
" cert.save(\"user://generated.crt\")\n"
-" # Encryption\n"
-" var data = \"Some data\"\n"
+" # 加密\n"
+" var data = \"具体的数æ®\"\n"
" var encrypted = crypto.encrypt(key, data.to_utf8())\n"
-" # Decryption\n"
+" # 解密\n"
" var decrypted = crypto.decrypt(key, encrypted)\n"
-" # Signing\n"
+" # ç­¾å\n"
" var signature = crypto.sign(HashingContext.HASH_SHA256, data."
"sha256_buffer(), key)\n"
-" # Verifying\n"
+" # 验è¯\n"
" var verified = crypto.verify(HashingContext.HASH_SHA256, data."
"sha256_buffer(), signature, key)\n"
-" # Checks\n"
+" # 检查\n"
" assert(verified)\n"
" assert(data.to_utf8() == decrypted)\n"
"[/codeblock]\n"
-"[b]注æ„:[/b]在HTML5导出中ä¸å¯ç”¨ã€‚"
+"[b]注æ„:[/b]在 HTML5 导出中ä¸å¯ç”¨ã€‚"
#: doc/classes/Crypto.xml
msgid ""
@@ -22066,7 +22107,7 @@ msgid ""
"string-comparison-with-double-hmac-strategy]this blog post[/url] for more "
"information."
msgstr ""
-"比较两个[PoolByteArray]是å¦ç›¸ç­‰ï¼Œè€Œä¸æ³„露时间信æ¯ï¼Œä»¥é˜²æ­¢è®¡æ—¶æ”»å‡»ã€‚\n"
+"比较两个 [PoolByteArray] 是å¦ç›¸ç­‰ï¼Œè€Œä¸æ³„露时间信æ¯ï¼Œä»¥é˜²æ­¢è®¡æ—¶æ”»å‡»ã€‚\n"
"更多信æ¯å‚阅[url=https://paragonie.com/blog/2015/11/preventing-timing-"
"attacks-on-string-comparison-with-double-hmac-strategy]è¿™ç¯‡åšæ–‡[/url]。"
@@ -22101,7 +22142,7 @@ msgid ""
"Generates an RSA [CryptoKey] that can be used for creating self-signed "
"certificates and passed to [method StreamPeerSSL.accept_stream]."
msgstr ""
-"生æˆå¯ç”¨äºŽåˆ›å»ºè‡ªç­¾åè¯ä¹¦å¹¶ä¼ é€’ç»™[method StreamPeerSSL.accept_stream]çš„RSA "
+"生æˆå¯ç”¨äºŽåˆ›å»ºè‡ªç­¾åè¯ä¹¦å¹¶ä¼ é€’ç»™ [method StreamPeerSSL.accept_stream] çš„ RSA "
"[CryptoKey]。"
#: doc/classes/Crypto.xml
@@ -22123,17 +22164,18 @@ msgid ""
"Game Company,C=IT\")\n"
"[/codeblock]"
msgstr ""
-"æ ¹æ®ç»™å®šçš„[CryptoKey]å’Œ[code]issuer_name[/code]生æˆè‡ªç­¾åçš„"
-"[X509Certificate]。è¯ä¹¦çš„æœ‰æ•ˆæ€§å°†ç”±[code]not_before[/code]å’Œ[code]not_after[/"
-"code](第一个有效日期和最åŽä¸€ä¸ªæœ‰æ•ˆæ—¥æœŸï¼‰å®šä¹‰ã€‚ [code]issuer_name[/code]å¿…é¡»"
-"至少包å«â€œ CN =“(通用å称,å³åŸŸå),“ O =â€ï¼ˆç»„ç»‡ï¼Œå³æ‚¨çš„å…¬å¸å称),“ C "
-"=“(国家,å³2个字æ¯çš„ISO) -3166组织所在国家/地区的代ç ï¼‰ã€‚\n"
-"一个生æˆRSA密钥和X509自签åè¯ä¹¦çš„å°ç¤ºä¾‹ã€‚\n"
+"æ ¹æ®ç»™å®šçš„ [CryptoKey] å’Œ [code]issuer_name[/code] 生æˆè‡ªç­¾åçš„ "
+"[X509Certificate]。è¯ä¹¦çš„æœ‰æ•ˆæ€§å°†ç”± [code]not_before[/code] å’Œ "
+"[code]not_after[/code](第一个有效日期和最åŽä¸€ä¸ªæœ‰æ•ˆæ—¥æœŸï¼‰å®šä¹‰ã€‚"
+"[code]issuer_name[/code] 必须至少包å«â€œCN=â€ï¼ˆé€šç”¨å称,å³åŸŸå),“O=â€ï¼ˆç»„织,"
+"峿‚¨çš„å…¬å¸å称),“C=â€ï¼ˆå›½å®¶ï¼Œå³ 2 个字æ¯çš„ ISO-3166 组织所在国家/地区的代"
+"ç ï¼‰ã€‚\n"
+"ç”Ÿæˆ RSA 密钥和 X509 自签åè¯ä¹¦çš„å°ç¤ºä¾‹ã€‚\n"
"[codeblock]\n"
"var crypto = Crypto.new()\n"
-"# Generate 4096 bits RSA key.\n"
+"# ç”Ÿæˆ 4096 比特 RSA 密钥。\n"
"var key = crypto.generate_rsa(4096)\n"
-"# Generate self-signed certificate using the given key.\n"
+"# 使用给定的密钥生æˆè‡ªç­¾åè¯ä¹¦ã€‚\n"
"var cert = crypto.generate_self_signed_certificate(key, \"CN=example.com,O=A "
"Game Company,C=IT\")\n"
"[/codeblock]"
@@ -22148,7 +22190,7 @@ msgid ""
"HashingContext.HASH_SHA1] are supported."
msgstr ""
"使用 [code]key[/code] ç”Ÿæˆ [code]msg[/code] çš„ [url=https://en.wikipedia.org/"
-"wiki/HMAC]HMAC[/url] 摘è¦ã€‚ [code]hash_type[/code] 傿•°æ˜¯ç”¨äºŽå†…部和外部哈希的"
+"wiki/HMAC]HMAC[/url] 摘è¦ã€‚[code]hash_type[/code] 傿•°æ˜¯ç”¨äºŽå†…部和外部哈希的"
"哈希算法。\n"
"ç›®å‰ä»…æ”¯æŒ [constant HashingContext.HASH_SHA256] å’Œ [constant HashingContext."
"HASH_SHA1]。"
@@ -22158,16 +22200,16 @@ msgid ""
"Sign a given [code]hash[/code] of type [code]hash_type[/code] with the "
"provided private [code]key[/code]."
msgstr ""
-"使用æä¾›çš„ç§æœ‰[code]key[/code]对类型为[code]hash_type[/code]的给定的"
-"[code]hash[/code]进行签å。"
+"使用æä¾›çš„ç§é’¥ [code]key[/code] 对类型为 [code]hash_type[/code] 的给定的 "
+"[code]hash[/code] 进行签å。"
#: doc/classes/Crypto.xml
msgid ""
"Verify that a given [code]signature[/code] for [code]hash[/code] of type "
"[code]hash_type[/code] against the provided public [code]key[/code]."
msgstr ""
-"对照æä¾›çš„公共[code]key[/code]验è¯ç±»åž‹ä¸º[code]hash_type[/code]çš„"
-"[code]hash_type[/code]的给定[code]ç­¾å[/code]。"
+"使用æä¾›çš„公钥 [code]key[/code] 验è¯ç±»åž‹ä¸º [code]hash_type[/code] çš„ "
+"[code]hash_type[/code] 的给定签å [code]signature[/code]。"
#: doc/classes/CryptoKey.xml
msgid "A cryptographic key (RSA)."
@@ -22192,7 +22234,7 @@ msgid ""
"Return [code]true[/code] if this CryptoKey only has the public part, and not "
"the private one."
msgstr ""
-"如果此CryptoKeyä»…å…·æœ‰å…¬å…±éƒ¨åˆ†ï¼Œè€Œæ²¡æœ‰ç§æœ‰éƒ¨åˆ†ï¼Œåˆ™è¿”回 [code]true[/code]。"
+"如果此 CryptoKey ä»…å…·æœ‰å…¬å…±éƒ¨åˆ†ï¼Œè€Œæ²¡æœ‰ç§æœ‰éƒ¨åˆ†ï¼Œåˆ™è¿”回 [code]true[/code]。"
#: doc/classes/CryptoKey.xml
msgid ""
@@ -22201,8 +22243,8 @@ msgid ""
"[b]Note:[/b] [code]path[/code] should be a \"*.pub\" file if "
"[code]public_only[/code] is [code]true[/code], a \"*.key\" file otherwise."
msgstr ""
-"从[code]path[/code]加载一个密钥。如果[code]public_only[/code]是[code]true[/"
-"code],将åªåŠ è½½å…¬é’¥ã€‚\n"
+"从 [code]path[/code] 加载一个密钥。如果 [code]public_only[/code] 是 "
+"[code]true[/code],将åªåŠ è½½å…¬é’¥ã€‚\n"
"[b]注æ„:[/b]如果 [code]public_only[/code] 为 [code]true[/code],则 "
"[code]path[/code] 应该是一个“*.pubâ€æ–‡ä»¶ï¼Œå¦åˆ™æ˜¯â€œ*.keyâ€æ–‡ä»¶ã€‚"
@@ -22211,8 +22253,8 @@ msgid ""
"Loads a key from the given [code]string[/code]. If [code]public_only[/code] "
"is [code]true[/code], only the public key will be loaded."
msgstr ""
-"从给定的[code]string[/code]加载密钥。如果[code]public_only[/code]为 "
-"[code]true[/code],则仅会加载公共密钥。"
+"从给定的 [code]string[/code] 加载密钥。如果 [code]public_only[/code] 为 "
+"[code]true[/code],则仅会加载公钥。"
#: doc/classes/CryptoKey.xml
msgid ""
@@ -22223,16 +22265,16 @@ msgid ""
msgstr ""
"将密钥ä¿å­˜åˆ°ç»™å®šçš„ [code]path[/code]。如果 [code]public_only[/code] 为 "
"[code]true[/code],则åªä¼šä¿å­˜å…¬é’¥ã€‚\n"
-"[b]注æ„:[/b]如果[code]public_only[/code]是[code]true[/code],则[code]path[/"
-"code]应该是一个\"*.pub\"文件,å¦åˆ™æ˜¯\"*.key\"文件。"
+"[b]注æ„:[/b]如果 [code]public_only[/code] 是 [code]true[/code],则 "
+"[code]path[/code] 应该是一个“*.pubâ€æ–‡ä»¶ï¼Œå¦åˆ™æ˜¯â€œ*.keyâ€æ–‡ä»¶ã€‚"
#: doc/classes/CryptoKey.xml
msgid ""
"Returns a string containing the key in PEM format. If [code]public_only[/"
"code] is [code]true[/code], only the public key will be included."
msgstr ""
-"返回包å«PEMæ ¼å¼çš„密钥的字符串。如果[code]public_only[/code]为 [code]true[/"
-"code],则仅包å«å…¬å…±å¯†é’¥ã€‚"
+"è¿”å›žåŒ…å« PEM æ ¼å¼çš„密钥的字符串。如果 [code]public_only[/code] 为 "
+"[code]true[/code],则仅包å«å…¬é’¥ã€‚"
#: modules/csg/doc_classes/CSGBox.xml
msgid "A CSG Box shape."
@@ -22332,7 +22374,7 @@ msgstr ""
msgid ""
"If [code]true[/code] a cone is created, the [member radius] will only apply "
"to one side."
-msgstr "如果创建了[code]true[/code]圆锥,则[member radius]将仅应用于一侧。"
+msgstr "如果为 [code]true[/code],则创建圆锥,仅在一侧应用 [member radius]。"
#: modules/csg/doc_classes/CSGCylinder.xml
msgid "The height of the cylinder."
@@ -22358,12 +22400,12 @@ msgid ""
"effect making the cylinder seem rounded. If [code]false[/code] the cylinder "
"will have a flat shaded look."
msgstr ""
-"如果[code]true[/code]ï¼Œåˆ™å°†åœ†æŸ±ä½“çš„æ³•çº¿è®¾ç½®ä¸ºå…·æœ‰å¹³æ»‘æ•ˆæžœï¼Œä½¿åœ†æŸ±ä½“çœ‹èµ·æ¥æ˜¯åœ†"
-"形的。如果[code]false[/code],则圆柱体将具有平å¦çš„阴影表现。"
+"如果为 [code]true[/code],则将圆柱体的法线设置为具有平滑效果,使圆柱体看起æ¥"
+"是圆形的。如果为 [code]false[/code],则圆柱体将具有平å¦çš„阴影表现。"
#: modules/csg/doc_classes/CSGMesh.xml
msgid "A CSG Mesh shape that uses a mesh resource."
-msgstr "使用网格资æºçš„CSG网格形状。"
+msgstr "使用网格资æºçš„ CSG 网格形状。"
#: modules/csg/doc_classes/CSGMesh.xml
msgid ""
@@ -22398,14 +22440,14 @@ msgid ""
"If a flat shader is required, ensure that all faces' vertex normals are "
"parallel."
msgstr ""
-"用æ¥ä½œä¸ºCSG形状的[Mesh]资æºã€‚\n"
-"[b]注æ„:[/b]当使用[ArrayMesh]时,除éžéœ€è¦ä¸€ä¸ªå¹³é¢ç€è‰²å™¨ï¼Œå¦åˆ™è¦é¿å…使用顶点"
-"法线的网格。默认情况下,CSGMesh会忽略网格的顶点法线,并使用é¢çš„æ³•线计算平整的"
-"ç€è‰²å™¨ã€‚如果需è¦ä½¿ç”¨å¹³é¢ç€è‰²å™¨ï¼Œè¯·ç¡®ä¿æ‰€æœ‰é¢çš„顶点法线是平行的。"
+"用æ¥ä½œä¸º CSG 形状的 [Mesh] 资æºã€‚\n"
+"[b]注æ„:[/b]当使用 [ArrayMesh] 时,除éžéœ€è¦ä¸€ä¸ªå¹³é¢ç€è‰²å™¨ï¼Œå¦åˆ™è¦é¿å…使用顶"
+"点法线的网格。默认情况下,CSGMesh 会忽略网格的顶点法线,并使用é¢çš„æ³•线计算平"
+"æ•´çš„ç€è‰²å™¨ã€‚如果需è¦ä½¿ç”¨å¹³é¢ç€è‰²å™¨ï¼Œè¯·ç¡®ä¿æ‰€æœ‰é¢çš„顶点法线是平行的。"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid "Extrudes a 2D polygon shape to create a 3D mesh."
-msgstr "拉伸2D多边形形状以创建3D网格。"
+msgstr "拉伸 2D 多边形形状以创建 3D 网格。"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22427,7 +22469,7 @@ msgstr ""
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"When [member mode] is [constant MODE_DEPTH], the depth of the extrusion."
-msgstr "当[member mode]为[constant MODE_DEPTH]时,挤出的深度。"
+msgstr "当 [member mode] 为 [constant MODE_DEPTH] 时,挤出的深度。"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22436,9 +22478,9 @@ msgid ""
"V around the outline of the [member polygon]), the bottom-left quarter to "
"the front end face, and the bottom-right quarter to the back end face."
msgstr ""
-"用于生æˆçš„网格的æè´¨ã€‚UVå°†æè´¨çš„上åŠéƒ¨åˆ†æ˜ å°„到挤出的形状,å³U沿挤出物的长度,"
-"V围绕 [member polygon]的轮廓,左下角的四分之一映射到å‰ç«¯é¢ï¼Œå³ä¸‹è§’的四分之一"
-"映射到åŽç«¯é¢ã€‚"
+"用于生æˆçš„网格的æè´¨ã€‚UV å°†æè´¨çš„上åŠéƒ¨åˆ†æ˜ å°„到挤出的形状(U 沿挤出物的长度,"
+"V 围绕 [member polygon] 的轮廓),左下角的四分之一映射到å‰ç«¯é¢ï¼Œå³ä¸‹è§’的四分"
+"之一映射到åŽç«¯é¢ã€‚"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid "The [member mode] used to extrude the [member polygon]."
@@ -22451,15 +22493,16 @@ msgid ""
"shape. If [code]false[/code] the top half of the material is repeated every "
"step of the extrusion."
msgstr ""
-"当 [member mode] 为[constant MODE_PATH]时,默认情况下, [member material]的上"
-"åŠéƒ¨åˆ†ä¼šæ²¿ç€æŒ¤å‡ºå½¢çŠ¶çš„æ•´ä¸ªé•¿åº¦è¢«æ‹‰ä¼¸ã€‚å¦‚æžœ[code]false[/code],挤出的æ¯ä¸€æ­¥éƒ½"
-"会é‡å¤æè´¨çš„上åŠéƒ¨åˆ†ã€‚"
+"当 [member mode] 为[constant MODE_PATH] 时,默认情况下,[member material] 的"
+"上åŠéƒ¨åˆ†ä¼šæ²¿ç€æŒ¤å‡ºå½¢çŠ¶çš„æ•´ä¸ªé•¿åº¦è¢«æ‹‰ä¼¸ã€‚å¦‚æžœä¸º [code]false[/code],挤出的æ¯ä¸€"
+"步都会é‡å¤æè´¨çš„上åŠéƒ¨åˆ†ã€‚"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"When [member mode] is [constant MODE_PATH], the path interval or ratio of "
"path points to extrusions."
-msgstr "当[member mode] 为[constant MODE_PATH]时,路径间隔或路径点比例挤出。"
+msgstr ""
+"当 [member mode] 为 [constant MODE_PATH] 时,路径间隔或路径点比例挤出。"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22485,8 +22528,8 @@ msgid ""
"[Transform] of the [CSGPolygon] is used as the starting point for the "
"extrusions, not the [Transform] of the [member path_node]."
msgstr ""
-"当[member mode]为[constant MODE_PATH]时,如果[code]true[/code],则使用"
-"[CSGPolygon]çš„[Transform]ä½œä¸ºæŒ¤å‡ºçš„èµ·ç‚¹ï¼Œè€Œä¸æ˜¯[member path_node]çš„"
+"当 [member mode] 为 [constant MODE_PATH] 时,如果为 [code]true[/code],则使"
+"用 [CSGPolygon] çš„ [Transform] ä½œä¸ºæŒ¤å‡ºçš„èµ·ç‚¹ï¼Œè€Œä¸æ˜¯ [member path_node] çš„ "
"[Transform]。"
#: modules/csg/doc_classes/CSGPolygon.xml
@@ -22494,8 +22537,8 @@ msgid ""
"When [member mode] is [constant MODE_PATH], the location of the [Path] "
"object used to extrude the [member polygon]."
msgstr ""
-"[member mode] 为[constant MODE_PATH]时,用于挤出 [member polygon] 的 [Path] "
-"å¯¹è±¡çš„åæ ‡ã€‚"
+"当 [member mode] 为 [constant MODE_PATH] 时,用于挤出 [member polygon] 的 "
+"[Path] å¯¹è±¡çš„åæ ‡ã€‚"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22519,8 +22562,8 @@ msgid ""
"path, in meters, the texture coordinates will tile. When set to 0, texture "
"coordinates will match geometry exactly with no tiling."
msgstr ""
-"当[member mode] 为[constant MODE_PATH] 时,这是纹ç†å标沿ç€è·¯å¾„çš„è·ç¦»ï¼Œä»¥ç±³ä¸º"
-"å•ä½ï¼Œå°†è¿›è¡Œå¹³é“ºã€‚当设置为0时,纹ç†å标将与几何图形完全匹é…,没有平铺。"
+"当 [member mode] 为 [constant MODE_PATH] 时,这是纹ç†å标沿ç€è·¯å¾„çš„è·ç¦»ï¼Œä»¥ç±³"
+"为å•ä½ï¼Œå°†è¿›è¡Œå¹³é“ºã€‚当设置为0时,纹ç†å标将与几何图形完全匹é…,没有平铺。"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22539,14 +22582,15 @@ msgstr ""
#: modules/csg/doc_classes/CSGPolygon.xml
msgid "If [code]true[/code], applies smooth shading to the extrusions."
-msgstr "如果[code]true[/code],则对挤出应用平滑ç€è‰²ã€‚"
+msgstr "如果为 [code]true[/code],则对挤出应用平滑ç€è‰²ã€‚"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"When [member mode] is [constant MODE_SPIN], the total number of degrees the "
"[member polygon] is rotated when extruding."
msgstr ""
-"当[member mode]为[constant MODE_SPIN],[member polygon]在挤出时旋转的总度数。"
+"当 [member mode] 为 [constant MODE_SPIN],[member polygon] 在挤出时旋转的总度"
+"数。"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22560,7 +22604,7 @@ msgstr "[member polygon] 形状沿负 Z 轴挤出。"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
"The [member polygon] shape is extruded by rotating it around the Y axis."
-msgstr "[member polygon]形状通过围绕Yè½´æ—‹è½¬æ¥æŒ¤å‡ºã€‚"
+msgstr "[member polygon] 形状通过围绕 Y è½´æ—‹è½¬æ¥æŒ¤å‡ºã€‚"
#: modules/csg/doc_classes/CSGPolygon.xml
msgid ""
@@ -22638,7 +22682,7 @@ msgstr "å转网格的é¢ã€‚"
#: modules/csg/doc_classes/CSGShape.xml
msgid "The CSG base class."
-msgstr "CSG基类。"
+msgstr "CSG 基类。"
#: modules/csg/doc_classes/CSGShape.xml
msgid ""
@@ -22667,7 +22711,7 @@ msgid ""
"node and the second is the root [Mesh] of this node. Only works when this "
"node is the root shape."
msgstr ""
-"返回带有两个元素的[Array],第一个是此节点的[Transform],第二个是此节点的根"
+"返回带有两个元素的 [Array],第一个是此节点的 [Transform],第二个是此节点的根 "
"[Mesh]ã€‚ä»…å½“æ­¤èŠ‚ç‚¹ä¸ºæ ¹å½¢æ—¶æ‰æœ‰æ•ˆã€‚"
#: modules/csg/doc_classes/CSGShape.xml
@@ -22693,8 +22737,8 @@ msgid ""
"Calculate tangents for the CSG shape which allows the use of normal maps. "
"This is only applied on the root shape, this setting is ignored on any child."
msgstr ""
-"计算å…许使用法线贴图的CSG形状的切线。这仅适用于根部形状,此设置将在所有å­çº§ä¸Š"
-"å‡è¢«å¿½ç•¥ã€‚"
+"计算å…许使用法线贴图的 CSG 形状的切线。这仅适用于根部形状,此设置将在所有å­çº§"
+"上å‡è¢«å¿½ç•¥ã€‚"
#: modules/csg/doc_classes/CSGShape.xml
msgid ""
@@ -22752,17 +22796,17 @@ msgid ""
"always act like a static body. Note that the collision shape is still active "
"even if the CSG shape itself is hidden."
msgstr ""
-"为我们的CSG形状å‘物ç†å¼•擎添加碰撞形状。这将始终åƒä¸€ä¸ªé™æ€ç‰©ä½“。请注æ„,å³ä½¿"
+"为我们的 CSG 形状å‘物ç†å¼•擎添加碰撞形状。这将始终åƒä¸€ä¸ªé™æ€ç‰©ä½“。请注æ„,å³ä½¿"
"CSG形状本身被éšè—,碰撞形状ä»å¤„于活动状æ€ã€‚"
#: modules/csg/doc_classes/CSGShape.xml
msgid ""
"Geometry of both primitives is merged, intersecting geometry is removed."
-msgstr "åˆå¹¶ä¸¤ä¸ªå›¾å…ƒçš„几何体,删除相交的几何体。"
+msgstr "åˆå¹¶ä¸¤ä¸ªå›¾å…ƒçš„几何体,移除相交的几何体。"
#: modules/csg/doc_classes/CSGShape.xml
msgid "Only intersecting geometry remains, the rest is removed."
-msgstr "ä»…ä¿ç•™ç›¸äº¤çš„几何,其余的将被删除。"
+msgstr "ä»…ä¿ç•™ç›¸äº¤çš„几何,其余的将被移除。"
#: modules/csg/doc_classes/CSGShape.xml
msgid ""
@@ -22771,7 +22815,7 @@ msgstr "从第一个形状å‡åŽ»ç¬¬äºŒä¸ªå½¢çŠ¶ï¼Œç•™ä¸‹ä¸€ä¸ªå¸¦æœ‰å…¶å½¢çŠ¶çš„
#: modules/csg/doc_classes/CSGSphere.xml
msgid "A CSG Sphere shape."
-msgstr "CSGçƒå½¢å½¢çŠ¶ã€‚"
+msgstr "CSG çƒå½¢å½¢çŠ¶ã€‚"
#: modules/csg/doc_classes/CSGSphere.xml
msgid ""
@@ -22810,12 +22854,12 @@ msgid ""
"effect making the sphere seem rounded. If [code]false[/code] the sphere will "
"have a flat shaded look."
msgstr ""
-"如果[code]true[/code]ï¼Œåˆ™å°†åœ†æŸ±ä½“çš„æ³•çº¿è®¾ç½®ä¸ºå…·æœ‰å¹³æ»‘æ•ˆæžœï¼Œä½¿åœ†æŸ±ä½“çœ‹èµ·æ¥æ˜¯åœ†"
-"形的。如果[code]false[/code],则圆柱体将具有平å¦çš„阴影表现。"
+"如果为 [code]true[/code],则将圆柱体的法线设置为具有平滑效果,使圆柱体看起æ¥"
+"是圆形的。如果为 [code]false[/code],则圆柱体将具有平å¦çš„阴影表现。"
#: modules/csg/doc_classes/CSGTorus.xml
msgid "A CSG Torus shape."
-msgstr "CSG圆环形状。"
+msgstr "CSG 圆环形状。"
#: modules/csg/doc_classes/CSGTorus.xml
msgid ""
@@ -22859,7 +22903,7 @@ msgid ""
"have a flat shaded look."
msgstr ""
"如果[code]true[/code]设置圆环的法线以æä¾›å¹³æ»‘æ•ˆæžœï¼Œåˆ™ä½¿åœ†çŽ¯çœ‹èµ·æ¥æ˜¯åœ†å½¢çš„。如"
-"æžœ[code]false[/code],则圆环将具有平å¦çš„阴影表现。"
+"果为 [code]false[/code],则圆环将具有平å¦çš„阴影表现。"
#: modules/mono/doc_classes/CSharpScript.xml
msgid ""
@@ -22921,7 +22965,7 @@ msgstr ""
msgid ""
"The render flags for the [CubeMap]. See the [enum Flags] constants for "
"details."
-msgstr "[CubeMap] 的渲染标志。有关详细信æ¯ï¼Œè¯·å‚阅 [enum Flags] 常é‡ã€‚"
+msgstr "[CubeMap] 的渲染标志。有关详细信æ¯ï¼Œè¯¦æƒ…请å‚阅 [enum Flags] 常é‡ã€‚"
#: doc/classes/CubeMap.xml
msgid ""
@@ -22933,11 +22977,11 @@ msgstr ""
#: doc/classes/CubeMap.xml
msgid "The [CubeMap]'s storage mode. See [enum Storage] constants."
-msgstr "[CubeMap] 的存储模å¼ã€‚å‚阅 [enum Storage] 常é‡ã€‚"
+msgstr "[CubeMap] 的存储模å¼ã€‚è§ [enum Storage] 常é‡ã€‚"
#: doc/classes/CubeMap.xml
msgid "Store the [CubeMap] without any compression."
-msgstr "存储[CubeMap]而ä¸è¿›è¡Œä»»ä½•压缩。"
+msgstr "存储 [CubeMap] 而ä¸è¿›è¡Œä»»ä½•压缩。"
#: doc/classes/CubeMap.xml
msgid "Store the [CubeMap] with strong compression that reduces image quality."
@@ -23086,11 +23130,11 @@ msgid ""
"This can be used to control autoplacement of building exteriors in an outer "
"[RoomGroup]."
msgstr ""
-"当设置为[code]0[/code]时,[CullInstance]将被自动放置在具有最高优先级的[Room]"
-"中。\n"
-"当设置为[code]0[/code]以外的值时,系统将å°è¯•在具有[code]autoplace_priority[/"
-"code]çš„[Room]中自动放置,如果它存在的è¯ã€‚\n"
-"è¿™å¯ä»¥ç”¨æ¥æŽ§åˆ¶å»ºç­‘外é¢çš„在外部[RoomGroup]的自动放置。"
+"当设置为 [code]0[/code] 时,[CullInstance] 将被自动放置在具有最高优先级的 "
+"[Room] 中。\n"
+"当设置为 [code]0[/code] 以外的值时,系统将å°è¯•在具有 "
+"[code]autoplace_priority[/code] çš„ [Room] 中自动放置,如果它存在的è¯ã€‚\n"
+"è¿™å¯ä»¥ç”¨æ¥æŽ§åˆ¶å»ºç­‘外é¢çš„在外部 [RoomGroup] 的自动放置。"
#: doc/classes/CullInstance.xml
msgid ""
@@ -23153,7 +23197,7 @@ msgstr "用于在 [Room] [b]之间[/b]移动的实例——例如玩家。"
msgid ""
"Use for instances that will be frustum culled only - e.g. first person "
"weapon, debug."
-msgstr "用于åªä¼šè¢«è§†é”¥å‰”除的实例——例如第一人称武器,调试。"
+msgstr "用于åªä¼šè¢«è§†é”¥å‰”除的实例——例如第一人称武器ã€è°ƒè¯•。"
#: doc/classes/CullInstance.xml
msgid ""
@@ -23165,7 +23209,7 @@ msgstr ""
#: doc/classes/Curve.xml
msgid "A mathematic curve."
-msgstr "ä¸€æ¡æ•°å­¦æ›²çº¿ã€‚"
+msgstr "数学曲线。"
#: doc/classes/Curve.xml
msgid ""
@@ -23173,8 +23217,8 @@ msgid ""
"ranges between [code]0[/code] and [code]1[/code] on the Y axis and positions "
"points relative to the [code]0.5[/code] Y position."
msgstr ""
-"å¯ä»¥ä¿å­˜å¹¶é‡æ–°ç”¨äºŽå…¶ä»–对象的曲线。默认情况下,它在Y轴上的范围在 [code]0[/"
-"code] 到 [code]1[/code]之间,并且ä½ç½®ç‚¹ç›¸å¯¹äºŽ [code]0.5[/code] Y ä½ç½®ã€‚"
+"å¯ä»¥ä¿å­˜å¹¶é‡æ–°ç”¨äºŽå…¶ä»–对象的曲线。默认情况下,它在 Y 轴上的范围在 [code]0[/"
+"code] 到 [code]1[/code] 之间,并且ä½ç½®ç‚¹ç›¸å¯¹äºŽ [code]0.5[/code] Y ä½ç½®ã€‚"
#: doc/classes/Curve.xml
msgid ""
@@ -23184,10 +23228,10 @@ msgid ""
"assignments to the [code]*_tangent[/code] angle if [code]*_mode[/code] is "
"set to [constant TANGENT_FREE]."
msgstr ""
-"在曲线上添加一个点。对于æ¯ä¸€ä¾§ï¼Œå¦‚æžœ[code]*_mode[/code]为[constant "
-"TANGENT_LINEAR],则[code]*_tangent[/code]角度(以度为å•ä½ï¼‰å°†ä½¿ç”¨æ›²çº¿åˆ°é‚»è¿‘点"
-"的一åŠçš„æ–œçŽ‡ã€‚å¦‚æžœ[code]*_mode[/code]设置为[constant TANGENT_FREE],则å…许自"
-"定义分é…ç»™[code]*_tangent[/code]角度。"
+"在曲线上添加一个点。对于æ¯ä¸€ä¾§ï¼Œå¦‚æžœ [code]*_mode[/code] 为 [constant "
+"TANGENT_LINEAR],则 [code]*_tangent[/code] 角度(以度为å•ä½ï¼‰å°†ä½¿ç”¨æ›²çº¿åˆ°é‚»è¿‘"
+"点的一åŠçš„æ–œçŽ‡ã€‚å¦‚æžœ [code]*_mode[/code] 设置为 [constant TANGENT_FREE],则å…"
+"许自定义分é…ç»™ [code]*_tangent[/code] 的角度。"
#: doc/classes/Curve.xml
msgid "Recomputes the baked cache of points for the curve."
@@ -23197,11 +23241,11 @@ msgstr "釿–°è®¡ç®—曲线的烘焙点缓存。"
msgid ""
"Removes points that are closer than [code]CMP_EPSILON[/code] (0.00001) units "
"to their neighbor on the curve."
-msgstr "删除比曲线上的相邻点近[code]CMP_EPSILON[/code](0.00001)个å•ä½çš„点。"
+msgstr "移除比曲线上的相邻点近[code]CMP_EPSILON[/code](0.00001)个å•ä½çš„点。"
#: doc/classes/Curve.xml doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid "Removes all points from the curve."
-msgstr "从曲线中删除所有点。"
+msgstr "从曲线中移除所有点。"
#: doc/classes/Curve.xml doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid "Returns the number of points describing the curve."
@@ -23237,7 +23281,7 @@ msgstr "返回 [code]index[/code]处的点的左切线角(以度为å•ä½ï¼‰ã€
msgid ""
"Returns the Y value for the point that would exist at the X position "
"[code]offset[/code] along the curve."
-msgstr "返回沿曲线的Xä½ç½®[code]offset[/code]处将存在的点的Y值。"
+msgstr "返回沿曲线的 X ä½ç½® [code]offset[/code] 处将存在的点的 Y 值。"
#: doc/classes/Curve.xml
msgid ""
@@ -23245,19 +23289,20 @@ msgid ""
"[code]offset[/code] along the curve using the baked cache. Bakes the curve's "
"points if not already baked."
msgstr ""
-"使用烘焙的缓存返回沿曲线的Xä½ç½®[code]offset[/code]处将存在的点的Y值。如果尚未"
-"烘焙曲线的点,则将其烘焙。"
+"使用烘焙的缓存返回沿曲线的 X ä½ç½® [code]offset[/code] 处将存在的点的 Y 值。如"
+"果尚未烘焙曲线的点,则将其烘焙。"
#: doc/classes/Curve.xml
msgid "Removes the point at [code]index[/code] from the curve."
-msgstr "从曲线中删除[code]index[/code]处的点。"
+msgstr "从曲线中移除 [code]index[/code] 处的点。"
#: doc/classes/Curve.xml
msgid ""
"Sets the left [enum TangentMode] for the point at [code]index[/code] to "
"[code]mode[/code]."
msgstr ""
-"将[code]index[/code]处的点的左侧[enum TangentMode]设置为[code]mode[/code]。"
+"将 [code]index[/code] 处的点的左侧 [enum TangentMode] 设置为 [code]mode[/"
+"code]。"
#: doc/classes/Curve.xml
msgid ""
@@ -23267,26 +23312,27 @@ msgstr "将点的左切线角度设置为 [code]index[/code] 至 [code]tangent[/
#: doc/classes/Curve.xml
msgid "Sets the offset from [code]0.5[/code]."
-msgstr "设置相对于[code]0.5[/code]çš„åç§»é‡ã€‚"
+msgstr "设置相对于 [code]0.5[/code] çš„åç§»é‡ã€‚"
#: doc/classes/Curve.xml
msgid ""
"Sets the right [enum TangentMode] for the point at [code]index[/code] to "
"[code]mode[/code]."
msgstr ""
-"å°†[code]index[/code]上的点的å³ä¾§[enum TangentMode]设置为[code]mode[/code]。"
+"å°† [code]index[/code] 上的点的å³ä¾§ [enum TangentMode] 设置为 [code]mode[/"
+"code]。"
#: doc/classes/Curve.xml
msgid ""
"Sets the right tangent angle for the point at [code]index[/code] to "
"[code]tangent[/code]."
-msgstr "设置[code]index[/code]至[code]tangent[/code]处的点的å³åˆ‡çº¿è§’。"
+msgstr "设置 [code]index[/code] 至 [code]tangent[/code] 处的点的å³åˆ‡çº¿è§’。"
#: doc/classes/Curve.xml
msgid ""
"Assigns the vertical position [code]y[/code] to the point at [code]index[/"
"code]."
-msgstr "将垂直ä½ç½®[code]y[/code]分é…ç»™[code]index[/code]处的点。"
+msgstr "将垂直ä½ç½® [code]y[/code] 分é…ç»™ [code]index[/code] 处的点。"
#: doc/classes/Curve.xml
msgid "The number of points to include in the baked (i.e. cached) curve data."
@@ -23357,12 +23403,12 @@ msgid ""
"Returns the total length of the curve, based on the cached points. Given "
"enough density (see [member bake_interval]), it should be approximate enough."
msgstr ""
-"æ ¹æ®ç¼“存的点,返回曲线的总长度。给予足够的密度(å‚阅[member bake_interval]),"
+"æ ¹æ®ç¼“å­˜çš„ç‚¹ï¼Œè¿”å›žæ›²çº¿çš„æ€»é•¿åº¦ã€‚ç»™äºˆè¶³å¤Ÿçš„å¯†åº¦ï¼ˆè§ [member bake_interval]),"
"它应该是足够近似的。"
#: doc/classes/Curve2D.xml
msgid "Returns the cache of points as a [PoolVector2Array]."
-msgstr "以[PoolVector2Array]的形å¼è¿”回缓存的点。"
+msgstr "以 [PoolVector2Array] 的形å¼è¿”回缓存的点。"
#: doc/classes/Curve2D.xml
msgid ""
@@ -23483,16 +23529,16 @@ msgid ""
"code]. If the index is out of bounds, the function sends an error to the "
"console. The position is relative to the vertex."
msgstr ""
-"设置从顶点[code]idx[/code]引出的控制点ä½ç½®ã€‚å¦‚æžœç´¢å¼•è¶…å‡ºèŒƒå›´ï¼Œè¯¥å‡½æ•°ä¼šå‘æŽ§åˆ¶"
-"å°å‘é€é”™è¯¯ã€‚ä½ç½®æ˜¯ç›¸å¯¹äºŽé¡¶ç‚¹çš„。"
+"设置从顶点 [code]idx[/code] 引出的控制点ä½ç½®ã€‚å¦‚æžœç´¢å¼•è¶…å‡ºèŒƒå›´ï¼Œè¯¥å‡½æ•°ä¼šå‘æŽ§"
+"制å°å‘é€é”™è¯¯ã€‚ä½ç½®æ˜¯ç›¸å¯¹äºŽé¡¶ç‚¹çš„。"
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
"Sets the position for the vertex [code]idx[/code]. If the index is out of "
"bounds, the function sends an error to the console."
msgstr ""
-"设置顶点[code]idx[/code]çš„ä½ç½®ã€‚å¦‚æžœç´¢å¼•è¶…å‡ºèŒƒå›´ï¼Œå‡½æ•°ä¼šå‘æŽ§åˆ¶å°å‘é€ä¸€ä¸ªé”™è¯¯"
-"ä¿¡æ¯ã€‚"
+"设置顶点 [code]idx[/code] çš„ä½ç½®ã€‚å¦‚æžœç´¢å¼•è¶…å‡ºèŒƒå›´ï¼Œå‡½æ•°ä¼šå‘æŽ§åˆ¶å°å‘é€ä¸€ä¸ªé”™"
+"误信æ¯ã€‚"
#: doc/classes/Curve2D.xml doc/classes/Curve3D.xml
msgid ""
@@ -23527,13 +23573,13 @@ msgid ""
"smaller the distance, the more points in the cache and the more memory it "
"will consume, so use with care."
msgstr ""
-"相邻两个缓存点之间的è·ç¦»ï¼Œä»¥åƒç´ ä¸ºå•ä½ã€‚改å˜å®ƒå°†è¿«ä½¿ç¼“存在下次调用[method "
-"get_baked_points]或[method get_baked_length]å‡½æ•°æ—¶é‡æ–°è®¡ç®—。è·ç¦»è¶Šå°ï¼Œç¼“存中"
-"的点越多,å ç”¨çš„å†…å­˜ä¹Ÿè¶Šå¤šï¼Œæ‰€ä»¥ä½¿ç”¨æ—¶è¦æ³¨æ„。"
+"相邻两个缓存点之间的è·ç¦»ï¼Œä»¥åƒç´ ä¸ºå•ä½ã€‚改å˜å®ƒå°†è¿«ä½¿ç¼“存在下次调用 [method "
+"get_baked_points] 或 [method get_baked_length] å‡½æ•°æ—¶é‡æ–°è®¡ç®—。è·ç¦»è¶Šå°ï¼Œç¼“å­˜"
+"中的点越多,å ç”¨çš„å†…å­˜ä¹Ÿè¶Šå¤šï¼Œæ‰€ä»¥ä½¿ç”¨æ—¶è¦æ³¨æ„。"
#: doc/classes/Curve3D.xml
msgid "Describes a Bézier curve in 3D space."
-msgstr "æè¿°äºŒç»´ç©ºé—´çš„è´å…¹å°”曲线。"
+msgstr "æè¿° 3D 空间的è´å…¹å°”曲线。"
#: doc/classes/Curve3D.xml
msgid ""
@@ -23709,9 +23755,9 @@ msgid ""
"smaller the distance, the more points in the cache and the more memory it "
"will consume, so use with care."
msgstr ""
-"相邻两个缓存点之间的è·ç¦»ï¼Œå•ä½ä¸ºç±³ã€‚改å˜å®ƒå°†è¿«ä½¿ç¼“存在下次调用[method "
-"get_baked_points]或[method get_baked_length]å‡½æ•°æ—¶é‡æ–°è®¡ç®—。è·ç¦»è¶Šå°ï¼Œç¼“存中"
-"的点越多,å ç”¨çš„å†…å­˜ä¹Ÿè¶Šå¤šï¼Œæ‰€ä»¥ä½¿ç”¨æ—¶è¦æ³¨æ„。"
+"相邻两个缓存点之间的è·ç¦»ï¼Œå•ä½ä¸ºç±³ã€‚改å˜å®ƒå°†è¿«ä½¿ç¼“存在下次调用 [method "
+"get_baked_points] 或 [method get_baked_length] å‡½æ•°æ—¶é‡æ–°è®¡ç®—。è·ç¦»è¶Šå°ï¼Œç¼“å­˜"
+"中的点越多,å ç”¨çš„å†…å­˜ä¹Ÿè¶Šå¤šï¼Œæ‰€ä»¥ä½¿ç”¨æ—¶è¦æ³¨æ„。"
#: doc/classes/Curve3D.xml
msgid ""
@@ -23719,7 +23765,7 @@ msgid ""
"This is used when [member PathFollow.rotation_mode] is set to [constant "
"PathFollow.ROTATION_ORIENTED]. Changing it forces the cache to be recomputed."
msgstr ""
-"如果[code]true[/code],曲线将烘焙出用于定å‘çš„å‘é‡ã€‚当[member PathFollow."
+"如果为 [code]true[/code],曲线将烘焙出用于定å‘çš„å‘é‡ã€‚当[member PathFollow."
"rotation_mode]被设置为[constant PathFollow.ROTATION_ORIENTED]时,就会使用这个"
"功能。改å˜å®ƒå°†å¼ºåˆ¶é‡æ–°è®¡ç®—缓存。"
@@ -23731,7 +23777,7 @@ msgstr "显示曲线的纹ç†ã€‚"
msgid ""
"Renders a given [Curve] provided to it. Simplifies the task of drawing "
"curves and/or saving them as image files."
-msgstr "渲染æä¾›ç»™å®ƒçš„[Curve]。简化了绘制曲线和/或ä¿å­˜ä¸ºå›¾åƒæ–‡ä»¶çš„任务。"
+msgstr "渲染æä¾›ç»™å®ƒçš„ [Curve]。简化了绘制曲线和/或ä¿å­˜ä¸ºå›¾åƒæ–‡ä»¶çš„任务。"
#: doc/classes/CurveTexture.xml
msgid "The [Curve] that is rendered onto the texture."
@@ -23764,7 +23810,7 @@ msgid ""
"Bottom radius of the cylinder. If set to [code]0.0[/code], the bottom faces "
"will not be generated, resulting in a conic shape."
msgstr ""
-"圆柱体的底部åŠå¾„。如果设置为[code]0.0[/code],而ä¸ä¼šç”Ÿæˆåº•é¢ï¼Œä»Žè€Œå½¢æˆåœ†é”¥"
+"圆柱体的底部åŠå¾„。如果设置为 [code]0.0[/code],而ä¸ä¼šç”Ÿæˆåº•é¢ï¼Œä»Žè€Œå½¢æˆåœ†é”¥"
"体。"
#: doc/classes/CylinderMesh.xml
@@ -24007,7 +24053,7 @@ msgstr ""
" # 这里我们ä¸èƒ½ä½¿ç”¨ç‚¹ï¼Œå› ä¸ºâ€˜my_color’是个å˜é‡ã€‚\n"
" var points = points_dir[my_color]\n"
"[/codeblock]\n"
-"在上方的代ç ä¸­ï¼Œ[code]points[/code] 会被赋值为 [code]my_color[/code]中选å–çš„"
+"在上é¢çš„代ç ä¸­ï¼Œ[code]points[/code] 会被赋值为 [code]my_color[/code] 中选å–çš„"
"颜色。\n"
"å­—å…¸å¯ä»¥å®¹çº³æ›´åР夿‚的数æ®ï¼š\n"
"[codeblock]\n"
@@ -24016,13 +24062,13 @@ msgstr ""
"如果想è¦ç»™å­—典添加一个键,å¯ä»¥åƒè®¿é—®å·²æœ‰çš„键一样:\n"
"[codeblock]\n"
"var points_dir = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
-"points_dir[\"Blue\"] = 150 # 添加键\"Blue\",并将其数值设定为150\n"
+"points_dir[\"Blue\"] = 150 # 添加键 \"Blue\",并将其数值设定为 150\n"
"[/codeblock]\n"
"最终,åŒä¸€ä¸ªå­—典内å¯ä»¥å®¹çº³ä¸åŒç±»åž‹çš„键和值:\n"
"[codeblock]\n"
"# è¿™æ˜¯ä¸€ä¸ªåˆæ³•的字典。\n"
-"# 使用`my_dir.sub_dir.sub_key`或`my_dir[\"sub_dir\"][\"sub_key\"]`æ¥è®¿é—®ä¸‹æ–¹"
-"的字符串\"Nested value\"。\n"
+"# 使用 `my_dir.sub_dir.sub_key` 或 `my_dir[\"sub_dir\"][\"sub_key\"]` æ¥è®¿é—®"
+"下方的字符串 \"Nested value\"。\n"
"# æ ¹æ®ä½ ä¸åŒçš„需求å¯ä»¥ä¿®æ”¹ç´¢å¼•æ ·å¼ã€‚\n"
"var my_dir = {\n"
" \"String Key\": 5,\n"
@@ -24037,13 +24083,13 @@ msgstr ""
"array2 = [1, 2, 3]\n"
"\n"
"func compare_arrays():\n"
-" print(array1 == array2) # 会输出true。\n"
+" print(array1 == array2) # 会输出 true。\n"
"\n"
"dir1 = {\"a\": 1, \"b\": 2, \"c\": 3}\n"
"dir2 = {\"a\": 1, \"b\": 2, \"c\": 3}\n"
"\n"
"func compare_dictionaries():\n"
-" print(dir1 == dir2) # ä¸ä¼šè¾“出true。\n"
+" print(dir1 == dir2) # ä¸ä¼šè¾“出 true。\n"
"[/codeblock]\n"
"想è¦å¯¹æ¯”字典,首先需è¦ç”¨ [method hash] 计算字典哈希。\n"
"[codeblock]\n"
@@ -24051,11 +24097,11 @@ msgstr ""
"dir2 = {\"a\": 1, \"b\": 2, \"c\": 3}\n"
"\n"
"func compare_dictionaries():\n"
-" print(dir1.hash() == dir2.hash()) # 会输出true。\n"
+" print(dir1.hash() == dir2.hash()) # 会输出 true。\n"
"[/codeblock]\n"
"[b]注æ„:[/b]当使用 [code]const[/code] æ¥å£°æ˜Žå­—典时,字典本身ä¾ç„¶å¯ä»¥é€šè¿‡å®šä¹‰"
-"键的数值æ¥è¿›è¡Œä¿®æ”¹ã€‚使用 [code]const[/code] åªèƒ½é˜²æ­¢åœ¨å®ƒåˆå§‹åŒ–完æˆåŽè¢«ç»™äºˆå¦"
-"一个数值。"
+"键的数值æ¥è¿›è¡Œä¿®æ”¹ã€‚使用 [code]const[/code] åªèƒ½é˜²æ­¢åœ¨å¸¸é‡åœ¨åˆå§‹åŒ–完æˆåŽè¢«èµ‹"
+"为其他值。"
#: doc/classes/Dictionary.xml
msgid "GDScript basics: Dictionary"
@@ -24063,7 +24109,7 @@ msgstr "GDScript 基础:字典"
#: doc/classes/Dictionary.xml
msgid "Clear the dictionary, removing all key/value pairs."
-msgstr "清除字典,删除所有键/值对。"
+msgstr "清除字典,移除所有键/值对。"
#: doc/classes/Dictionary.xml
msgid ""
@@ -24113,7 +24159,7 @@ msgid ""
"code]."
msgstr ""
"如果字典有一个给定的键,返回 [code]true[/code]。\n"
-"[b]注æ„:[/b]这相当于使用 [code]in[/code] è¿ç®—符,如下所示:\n"
+"[b]注æ„:[/b]相当于使用 [code]in[/code] è¿ç®—符,如下所示:\n"
"[codeblock]\n"
"# 估值为 `true`。\n"
"if \"godot\" in {\"godot\": \"engine\"}:\n"
@@ -24160,7 +24206,7 @@ msgstr ""
#: doc/classes/Dictionary.xml
msgid "Returns the list of keys in the [Dictionary]."
-msgstr "返回[Dictionary]中的键列表。"
+msgstr "返回 [Dictionary] 中的键列表。"
#: doc/classes/Dictionary.xml
msgid ""
@@ -24177,7 +24223,7 @@ msgstr "返回字典中键的数é‡ã€‚"
#: doc/classes/Dictionary.xml
msgid "Returns the list of values in the [Dictionary]."
-msgstr "返回[Dictionary]中的值列表。"
+msgstr "返回 [Dictionary] 中的值列表。"
#: doc/classes/DirectionalLight.xml
msgid "Directional light from a distance, as from the Sun."
@@ -24198,31 +24244,44 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
"远处阴影分裂的é¢å¤–åç½®é‡ã€‚如果自身阴影åªäº§ç”Ÿè¿œå¤„的分裂,增加这个值å¯ä»¥ä¿®å¤å®ƒ"
-"们。"
+"们。当 [member directional_shadow_mode] 为 [constant SHADOW_ORTHOGONAL] 时会"
+"被忽略。"
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
-"如果[code]true[/code],则会牺牲阴影细节,以æ¢å–更平滑的分割之间的过渡。"
+"如果为 [code]true[/code],会牺牲阴影的细节,æ¢å–分割区域之间更平滑的过渡。å¯"
+"用阴影混åˆåˆ†å‰²åŒæ—¶ä¹Ÿä¼šå¸¦æ¥ä¸€äº›æ€§èƒ½æ¶ˆè€—。当 [member directional_shadow_mode] "
+"为 [constant SHADOW_ORTHOGONAL] 时会被忽略。"
#: doc/classes/DirectionalLight.xml
msgid ""
"Optimizes shadow rendering for detail versus movement. See [enum "
"ShadowDepthRange]."
-msgstr "优化阴影渲染的细节与è¿åŠ¨ã€‚å‚阅[enum ShadowDepthRange]。"
+msgstr "优化阴影渲染的细节与è¿åŠ¨ã€‚è§ [enum ShadowDepthRange]。"
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
-msgstr "阴影分割的最大è·ç¦»ã€‚"
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
+msgstr ""
+"阴影分割的最大è·ç¦»ã€‚将这个值增大会让方å‘阴影在更远处å¯è§ï¼Œä»£ä»·æ˜¯æ•´ä½“的阴影细"
+"节é™ä½Žå’Œæ€§èƒ½ï¼ˆå› ä¸ºæ¸²æŸ“æ–¹å‘阴影时需è¦åŒ…嫿›´å¤šçš„对象)。"
#: doc/classes/DirectionalLight.xml
msgid "The light's shadow rendering algorithm. See [enum ShadowMode]."
-msgstr "ç¯å…‰çš„阴影渲染算法。å‚阅[enum ShadowMode]。"
+msgstr "ç¯å…‰çš„é˜´å½±æ¸²æŸ“ç®—æ³•ã€‚è§ [enum ShadowMode]。"
#: doc/classes/DirectionalLight.xml
msgid ""
@@ -24234,33 +24293,33 @@ msgstr "当物体垂直于光线时,å¯ç”¨äºŽä¿®å¤è‡ªèº«é˜´å½±çš„特殊情况
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
-"相机到影å­åˆ†å‰²1çš„è·ç¦»ã€‚相对于[member directional_shadow_max_distance]ã€‚åªæœ‰å½“"
-"[member directional_shadow_mode]是[code]SHADOW_PARALLEL_2_SPLITS[/code]或"
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]æ—¶æ‰ä½¿ç”¨ã€‚"
+"相机到阴影分割 1 çš„è·ç¦»ã€‚相对于 [member directional_shadow_max_distance]。åª"
+"有当 [member directional_shadow_mode] 为 [constant SHADOW_PARALLEL_2_SPLITS] "
+"或 [constant SHADOW_PARALLEL_4_SPLITS] æ—¶æ‰ä½¿ç”¨ã€‚"
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
-"阴影分割1到分割2çš„è·ç¦»ã€‚相对于[member directional_shadow_max_distance]。仅在"
-"[member directional_shadow_mode]为[code]SHADOW_PARALLEL_2_SPLITS[/code]或"
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]时使用。"
+"阴影分割 1 到分割 2 çš„è·ç¦»ã€‚相对于 [member directional_shadow_max_distance]。"
+"仅在 [member directional_shadow_mode] 为 [constant SHADOW_PARALLEL_2_SPLITS] "
+"或 [constant SHADOW_PARALLEL_4_SPLITS] 时使用。"
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
-"从影å­åˆ†å‰²2到分割3çš„è·ç¦»ã€‚相对于[member directional_shadow_max_distance]。åª"
-"有当[member directional_shadow_mode]为[code]SHADOW_PARALLEL_4_SPLITS[/code]时"
-"æ‰ä½¿ç”¨ã€‚"
+"从阴影分割 2 到分割 3 çš„è·ç¦»ã€‚相对于 [member "
+"directional_shadow_max_distance]ã€‚åªæœ‰å½“ [member directional_shadow_mode] 为 "
+"[constant SHADOW_PARALLEL_4_SPLITS] æ—¶æ‰ä½¿ç”¨ã€‚"
#: doc/classes/DirectionalLight.xml
msgid ""
@@ -24368,10 +24427,10 @@ msgid ""
"code] or [code]res://somedir/newdir[/code]).\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
-"将当剿‰“å¼€çš„ç›®å½•æ”¹ä¸ºå‚æ•°ä¼ é€’çš„ç›®å½•ã€‚å‚æ•°å¯ä»¥æ˜¯ç›¸å¯¹äºŽå½“å‰ç›®å½•çš„(例如 "
-"[code]newdir[/code] 或 [code].../newdir[/code]),也å¯ä»¥æ˜¯ç»å¯¹è·¯å¾„(例如 "
-"[code]/tmp/newdir[/code] 或 [code]res://somedir/newdir[/code])。\n"
-"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ ([code]OK[/code] æˆåŠŸæ—¶)。"
+"将当剿‰“å¼€çš„ç›®å½•æ”¹ä¸ºå‚æ•°ä¼ é€’çš„ç›®å½•ã€‚å‚æ•°å¯ä»¥æ˜¯ç›¸å¯¹äºŽå½“å‰ç›®å½•的(例如 "
+"[code]newdir[/code] 或 [code].../newdir[/code]),也å¯ä»¥æ˜¯ç»å¯¹è·¯å¾„(例如 "
+"[code]/tmp/newdir[/code] 或 [code]res://somedir/newdir[/code])。\n"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆ[code]OK[/code] æˆåŠŸæ—¶ï¼‰ã€‚"
#: doc/classes/Directory.xml
msgid ""
@@ -24383,7 +24442,7 @@ msgid ""
msgstr ""
"å°† [code]from[/code] 文件å¤åˆ¶åˆ° [code]to[/code] 目标ä½ç½®ã€‚ä¸¤ä¸ªå‚æ•°éƒ½åº”该是相"
"对或ç»å¯¹æ–‡ä»¶çš„è·¯å¾„ã€‚å¦‚æžœç›®æ ‡æ–‡ä»¶å­˜åœ¨ä¸”æ²¡æœ‰è®¿é—®ä¿æŠ¤ï¼Œåˆ™ä¼šè¢«è¦†ç›–ã€‚\n"
-"返回[enum Error]代ç å¸¸é‡ä¹‹ä¸€(æˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
#: doc/classes/Directory.xml
msgid ""
@@ -24500,8 +24559,8 @@ msgid ""
"Closes the current stream opened with [method list_dir_begin] (whether it "
"has been fully processed with [method get_next] does not matter)."
msgstr ""
-"关闭用[method list_dir_begin]æ‰“å¼€çš„å½“å‰æµï¼Œå¹¶ä¸å…³æ³¨æ˜¯å¦å·²ç»ç”¨[method "
-"get_next]完æˆå¤„ç†ã€‚"
+"关闭用 [method list_dir_begin] æ‰“å¼€çš„å½“å‰æµï¼ˆå¹¶ä¸å…³æ³¨æ˜¯å¦å·²ç»ç”¨ [method "
+"get_next] 完æˆå¤„ç†ï¼‰ã€‚"
#: doc/classes/Directory.xml
msgid ""
@@ -24525,7 +24584,7 @@ msgid ""
msgstr ""
"通过递归调用 [method make_dir]方法,创建一个目标目录和其路径中所有必è¦çš„中间"
"ç›®å½•ã€‚å‚æ•°å¯ä»¥æ˜¯ç›¸å¯¹äºŽå½“å‰ç›®å½•的,也å¯ä»¥æ˜¯ç»å¯¹è·¯å¾„。\n"
-"返回[enum Error]代ç å¸¸é‡ä¹‹ä¸€(æˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
#: doc/classes/Directory.xml
msgid ""
@@ -24535,11 +24594,11 @@ msgid ""
"filesystem (e.g. [code]/tmp/folder[/code] or [code]C:\\tmp\\folder[/code]).\n"
"Returns one of the [enum Error] code constants ([code]OK[/code] on success)."
msgstr ""
-"打开文件系统的现有目录。 [code]path[/code]傿•°å¯ä»¥ä½äºŽé¡¹ç›®æ ‘([code]res:// "
-"folder[/code]),用户目录([code]user:// folder[/code])或以下ä½ç½®çš„ç»å¯¹è·¯å¾„"
-"内:用户文件系统(例如[code]/ tmp / folder[/code]或[code]C:\\ tmp \\ "
-"folder[/code])。\n"
-"返回[enum Error]代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
+"打开文件系统的现有目录。[code]path[/code] 傿•°å¯ä»¥ä½äºŽé¡¹ç›®æ ‘([code]res:// "
+"folder[/code]),用户目录([code]user:// folder[/code])或以下ä½ç½®çš„ç»å¯¹è·¯å¾„"
+"内:用户文件系统(例如 [code]/tmp/folder[/code] 或 [code]C:\\tmp\\folder[/"
+"code])。\n"
+"返回 [enum Error] 代ç å¸¸é‡ä¹‹ä¸€ï¼ˆæˆåŠŸæ—¶è¿”å›ž [code]OK[/code])。"
#: doc/classes/Directory.xml
msgid ""
@@ -24570,7 +24629,7 @@ msgstr ""
#: doc/classes/DTLSServer.xml
msgid "Helper class to implement a DTLS server."
-msgstr "实现DTLSæœåŠ¡å™¨çš„è¾…åŠ©ç±»ã€‚"
+msgstr "实现 DTLS æœåŠ¡å™¨çš„è¾…åŠ©ç±»ã€‚"
#: doc/classes/DTLSServer.xml
msgid ""
@@ -24715,8 +24774,8 @@ msgid ""
"[constant PacketPeerDTLS.STATUS_HANDSHAKING], as it is normal that 50% of "
"the new connections will be invalid due to cookie exchange."
msgstr ""
-"å°è¯•与给定的 [code]udp_peer[/code] å¯åЍ DTLS æ¡æ‰‹ï¼Œè¯¥ peer 必须已ç»è¿žæŽ¥ï¼Œè¯·å‚"
-"阅 [method PacketPeerUDP.connect_to_host]。\n"
+"å°è¯•与给定的 [code]udp_peer[/code] å¯åЍ DTLS æ¡æ‰‹ï¼Œè¯¥ peer 必须已ç»è¿žæŽ¥ï¼ˆè§ "
+"[method PacketPeerUDP.connect_to_host])。\n"
"[b]注æ„:[/b]你必须检查返回 PacketPeerUDP çš„çŠ¶æ€æ˜¯å¦ä¸º [constant "
"PacketPeerDTLS.STATUS_HANDSHAKING],因为正常情况下,50% 的新连接会因为 "
"cookie 交æ¢è€Œæ— æ•ˆã€‚"
@@ -24786,7 +24845,7 @@ msgstr ""
#: doc/classes/DynamicFont.xml
msgid "Returns the fallback font at index [code]idx[/code]."
-msgstr "返回ä½äºŽç´¢å¼•[code]idx[/code]处的åŽå¤‡å­—体。"
+msgstr "返回ä½äºŽç´¢å¼• [code]idx[/code] 处的åŽå¤‡å­—体。"
#: doc/classes/DynamicFont.xml
msgid "Returns the number of fallback fonts."
@@ -24795,7 +24854,7 @@ msgstr "返回åŽå¤‡å­—体的数é‡ã€‚"
#: doc/classes/DynamicFont.xml
msgid ""
"Returns the spacing for the given [code]type[/code] (see [enum SpacingType])."
-msgstr "返回给定[code]type[/code]的间è·(å‚阅[enum SpacingType])。"
+msgstr "返回给定 [code]type[/code] 的间è·ï¼ˆè§ [enum SpacingType])。"
#: doc/classes/DynamicFont.xml
msgid "Removes the fallback font at index [code]idx[/code]."
@@ -24810,8 +24869,8 @@ msgid ""
"Sets the spacing for [code]type[/code] (see [enum SpacingType]) to "
"[code]value[/code] in pixels (not relative to the font size)."
msgstr ""
-"ç»™[code]type[/code]设置间è·(å‚阅[enum SpacingType])为[code]value[/code],å•ä½"
-"为åƒç´ (ä¸Žå­—ä½“å¤§å°æ— å…³)。"
+"ç»™ [code]type[/code] 设置间è·ï¼ˆè§ [enum SpacingType])为 [code]value[/code],"
+"å•ä½ä¸ºåƒç´ ï¼ˆä¸Žå­—体大尿— å…³ï¼‰ã€‚"
#: doc/classes/DynamicFont.xml
msgid "Extra spacing at the bottom in pixels."
@@ -24832,7 +24891,7 @@ msgid ""
"extra_spacing_char]) in pixels.\n"
"This can be a negative number to make the distance between words smaller."
msgstr ""
-"空格字符的é¢å¤–é—´è·ï¼Œå•使˜¯åƒç´ ï¼Œé™¤äº†[member extra_spacing_char]。\n"
+"空格字符(在 [member extra_spacing_char] 之外)的é¢å¤–é—´è·ï¼Œå•ä½ä¸ºåƒç´ ã€‚\n"
"è¿™å¯ä»¥æ˜¯è´Ÿæ•°ï¼Œä½¿å­—符之间的è·ç¦»æ›´å°ã€‚"
#: doc/classes/DynamicFont.xml
@@ -24872,9 +24931,9 @@ msgid ""
"control whose size changes over time, unless a pixel art aesthetic is "
"desired."
msgstr ""
-"为 [code]true[/code] 时将使用过滤功能。如果字体过度采样被ç¦ç”¨æˆ–无效,这将使字"
-"体在缩放时å˜å¾—模糊,而éžåƒç´ åŒ–ã€‚å½“åœ¨å°ºå¯¸éšæ—¶å˜åŒ–的控件中使用字体时,建议å¯ç”¨"
-"è¿™ä¸ªåŠŸèƒ½ï¼Œé™¤éžæ˜¯åƒç´ è®¾è®¡ã€‚"
+"如果为 [code]true[/code],将使用过滤功能。如果字体过度采样被ç¦ç”¨æˆ–无效,这将"
+"使字体在缩放时å˜å¾—模糊,而éžåƒç´ åŒ–ã€‚å½“åœ¨å°ºå¯¸éšæ—¶å˜åŒ–的控件中使用字体时,建议"
+"å¯ç”¨è¿™ä¸ªåŠŸèƒ½ï¼Œé™¤éžæ˜¯åƒç´ è®¾è®¡ã€‚"
#: doc/classes/DynamicFont.xml
msgid ""
@@ -24882,8 +24941,8 @@ msgid ""
"appearance when downscaling it if font oversampling is disabled or "
"ineffective."
msgstr ""
-"为 [code]true[/code] 时将使用 mipmap 多级æ¸è¿œçº¹ç†ã€‚在字体过度采样被ç¦ç”¨æˆ–无效"
-"æ—¶ï¼Œå¯æ”¹å–„å­—ä½“ç¼©å°æ—¶çš„表现。"
+"如果为 [code]true[/code],将使用 mipmap 多级æ¸è¿œçº¹ç†ã€‚在字体过度采样被ç¦ç”¨æˆ–"
+"æ— æ•ˆæ—¶ï¼Œå¯æ”¹å–„å­—ä½“ç¼©å°æ—¶çš„表现。"
#: doc/classes/DynamicFont.xml
msgid "Spacing at the top."
@@ -24917,8 +24976,8 @@ msgid ""
"If [code]true[/code], the font is rendered with anti-aliasing. This property "
"applies both to the main font and its outline (if it has one)."
msgstr ""
-"为 [code]true[/code] æ—¶å°†ä»¥æŠ—é”¯é½¿æ–¹å¼æ¸²æŸ“该字体。此属性既适用于主字体,也适用"
-"于其轮廓(如果有)。"
+"如果为 [code]true[/code]ï¼Œå°†ä»¥æŠ—é”¯é½¿æ–¹å¼æ¸²æŸ“该字体。此属性既适用于主字体,也"
+"适用于其轮廓(如果有)。"
#: doc/classes/DynamicFontData.xml
msgid "The path to the vector font file."
@@ -25267,7 +25326,7 @@ msgstr "å¯¼å…¥æ‰©å±•é¢æ¿ã€‚如果ç¦ç”¨æ­¤åŠŸèƒ½ï¼Œåˆ™å¯¼å…¥æ‰©å±•é¢æ¿å°†ä¸
#: doc/classes/EditorFeatureProfile.xml doc/classes/SpatialMaterial.xml
msgid "Represents the size of the [enum Feature] enum."
-msgstr "表示[enum Feature]枚举的大å°ã€‚"
+msgstr "表示 [enum Feature] 枚举的大å°ã€‚"
#: doc/classes/EditorFileDialog.xml
msgid "A modified version of [FileDialog] used by the editor."
@@ -25287,7 +25346,7 @@ msgstr ""
#: doc/classes/EditorFileDialog.xml
msgid "Removes all filters except for \"All Files (*)\"."
-msgstr "删除除“All Files(*)â€ç­›é€‰å™¨ä¹‹å¤–的所有筛选器。"
+msgstr "移除“All Files(*)â€ç­›é€‰å™¨ä¹‹å¤–的所有筛选器。"
#: doc/classes/EditorFileDialog.xml
msgid ""
@@ -25305,15 +25364,15 @@ msgid ""
"Notify the [EditorFileDialog] that its view of the data is no longer "
"accurate. Updates the view contents on next view update."
msgstr ""
-"通知[EditorFileDialog]它的数æ®è§†å›¾ä¸å†å‡†ç¡®ã€‚在下次视图更新时更新视图内容。"
+"通知 [EditorFileDialog] 它的数æ®è§†å›¾ä¸å†å‡†ç¡®ã€‚在下次视图更新时更新视图内容。"
#: doc/classes/EditorFileDialog.xml
msgid ""
"The location from which the user may select a file, including [code]res://[/"
"code], [code]user://[/code], and the local file system."
msgstr ""
-"用户å¯ä»¥é€‰æ‹©æ–‡ä»¶çš„ä½ç½®ï¼ŒåŒ…括[code]res://[/code]ã€[code]user://[/code]和本地文"
-"件系统。"
+"用户å¯ä»¥é€‰æ‹©æ–‡ä»¶çš„ä½ç½®ï¼ŒåŒ…括 [code]res://[/code]ã€[code]user://[/code] 和本地"
+"文件系统。"
#: doc/classes/EditorFileDialog.xml
msgid "The currently occupied directory."
@@ -25332,13 +25391,13 @@ msgid ""
"If [code]true[/code], the [EditorFileDialog] will not warn the user before "
"overwriting files."
msgstr ""
-"如果[code]true[/code],[EditorFileDialog]å°†ä¸ä¼šåœ¨è¦†ç›–文件之å‰è­¦å‘Šç”¨æˆ·ã€‚"
+"如果为 [code]true[/code],[EditorFileDialog] å°†ä¸ä¼šåœ¨è¦†ç›–文件之å‰è­¦å‘Šç”¨æˆ·ã€‚"
#: doc/classes/EditorFileDialog.xml
msgid ""
"The view format in which the [EditorFileDialog] displays resources to the "
"user."
-msgstr "[EditorFileDialog]å‘用户显示资æºçš„视图格å¼ã€‚"
+msgstr "[EditorFileDialog] å‘用户显示资æºçš„视图格å¼ã€‚"
#: doc/classes/EditorFileDialog.xml
msgid ""
@@ -25349,7 +25408,8 @@ msgstr "[EditorFileDialog] 的用途,它定义了å…许的行为。"
msgid ""
"If [code]true[/code], hidden files and directories will be visible in the "
"[EditorFileDialog]."
-msgstr "如果[code]true[/code],éšè—的文件和目录将在[EditorFileDialog]中å¯è§ã€‚"
+msgstr ""
+"如果为 [code]true[/code],éšè—的文件和目录将在 [EditorFileDialog] 中å¯è§ã€‚"
#: doc/classes/EditorFileDialog.xml
msgid "Emitted when a directory is selected."
@@ -25439,8 +25499,9 @@ msgid ""
"string such as [code]\"Resource\"[/code] or [code]\"GDScript\"[/code], "
"[i]not[/i] a file extension such as [code]\".gd\"[/code]."
msgstr ""
-"返回文件的资æºç±»åž‹ï¼Œç»™å®šå®Œæ•´è·¯å¾„。这将返回字符串,如[code]\"Resource\"[/code]"
-"或[code]\"GDScript\"[/code],[i]䏿˜¯[/i]文件扩展å,如[code]\".gd\"[/code]。"
+"返回文件的资æºç±»åž‹ï¼Œç»™å®šå®Œæ•´è·¯å¾„。这将返回字符串,如 [code]\"Resource\"[/"
+"code] 或 [code]\"GDScript\"[/code],[i]䏿˜¯[/i]文件扩展å,如 [code]\".gd\"[/"
+"code]。"
#: doc/classes/EditorFileSystem.xml
msgid "Gets the root directory object."
@@ -25452,7 +25513,7 @@ msgstr "返回在 [code]path[/code] 文件系统的视图。"
#: doc/classes/EditorFileSystem.xml
msgid "Returns the scan progress for 0 to 1 if the FS is being scanned."
-msgstr "如果文件系统正在被扫æï¼Œè¿”回扫æçš„进度,值为0-1。"
+msgstr "如果文件系统正在被扫æï¼Œè¿”回扫æçš„进度,值为 0-1。"
#: doc/classes/EditorFileSystem.xml
msgid "Returns [code]true[/code] if the filesystem is being scanned."
@@ -25470,7 +25531,7 @@ msgstr "æ£€æŸ¥æ˜¯å¦æ›´æ”¹äº†å·²å¯¼å…¥èµ„æºçš„æ¥æºã€‚"
msgid ""
"Update a file information. Call this if an external program (not Godot) "
"modified the file."
-msgstr "更新文件信æ¯ã€‚如果外部程åº(䏿˜¯Godot)修改了该文件,则调用此函数。"
+msgstr "更新文件信æ¯ã€‚如果外部程åºï¼ˆä¸æ˜¯ Godot)修改了该文件,则调用此函数。"
#: doc/classes/EditorFileSystem.xml
msgid "Scans the script files and updates the list of custom class names."
@@ -25534,7 +25595,7 @@ msgstr ""
#: doc/classes/EditorFileSystemDirectory.xml
msgid "Returns the path to the file at index [code]idx[/code]."
-msgstr "返回索引为[code]idx[/code] 文件的路径。"
+msgstr "返回索引为 [code]idx[/code] 文件的路径。"
#: doc/classes/EditorFileSystemDirectory.xml
msgid ""
@@ -25542,9 +25603,8 @@ msgid ""
"[code]idx[/code]. If the file doesn't define a script class using the "
"[code]class_name[/code] syntax, this will return an empty string."
msgstr ""
-"返回这个文件中脚本类(script class)在索引处[code]idx[/code]定义的基类(base "
-"class)。如果这个文件没有使用 [code]class_name[/code] 关键字定义脚本类,将返回"
-"一个空字符串。"
+"返回这个文件中脚本类在索引 [code]idx[/code] 处定义的基类。如果这个文件没有使"
+"用 [code]class_name[/code] 关键字定义脚本类,将返回一个空字符串。"
#: doc/classes/EditorFileSystemDirectory.xml
msgid ""
@@ -25561,9 +25621,9 @@ msgid ""
"returns a string such as [code]\"Resource\"[/code] or [code]\"GDScript\"[/"
"code], [i]not[/i] a file extension such as [code]\".gd\"[/code]."
msgstr ""
-"返回索引[code]idx[/code]处文件的资æºç±»åž‹ã€‚这将返回字符串,如"
-"[code]\"Resource\"[/code]或[code]\"GDScript\"[/code],[i]䏿˜¯[/i]文件扩展å,"
-"如[code]\".gd\"[/code]。"
+"返回索引 [code]idx[/code] 处文件的资æºç±»åž‹ã€‚这将返回字符串,如 "
+"[code]\"Resource\"[/code] 或 [code]\"GDScript\"[/code],[i]䏿˜¯[/i]文件扩展"
+"å,如 [code]\".gd\"[/code]。"
#: doc/classes/EditorFileSystemDirectory.xml
msgid "Returns the name of this directory."
@@ -25755,8 +25815,7 @@ msgstr ""
"其他选项的选项,如果其中一个选项被ç¦ç”¨ã€‚例如:\n"
"[codeblock]\n"
"func get_option_visibility(option, options):\n"
-" # Only show the lossy quality setting if the compression mode is set to "
-"\"Lossy\".\n"
+" # åªæœ‰åœ¨åŽ‹ç¼©æ¨¡å¼ä¸ºâ€œLossyâ€æ—¶æ˜¾ç¤º Lossy Quality 设置。\n"
" if option == \"compress/lossy_quality\" and options.has(\"compress/"
"mode\"):\n"
" return int(options[\"compress/mode\"]) == COMPRESS_LOSSY\n"
@@ -25771,8 +25830,8 @@ msgid ""
"get_import_options] to get the default options for the preset and [method "
"get_preset_name] to get the name of the preset."
msgstr ""
-"èŽ·å–æ’件定义的åˆå§‹é¢„置数é‡ã€‚使用[method get_import_options]获å–预设的默认选"
-"项,使用[method get_preset_name]获å–预设的å称。"
+"èŽ·å–æ’件定义的åˆå§‹é¢„置数é‡ã€‚使用 [method get_import_options] 获å–预设的默认选"
+"项,使用 [method get_preset_name] 获å–预设的å称。"
#: doc/classes/EditorImportPlugin.xml
msgid "Gets the name of the options preset at this index."
@@ -25783,7 +25842,7 @@ msgid ""
"Gets the priority of this plugin for the recognized extension. Higher "
"priority plugins will be preferred. The default priority is [code]1.0[/code]."
msgstr ""
-"获å–该æ’件对识别的扩展的优先级。优先级越高的æ’件会被优先选择。默认的优先级是"
+"获å–该æ’件对识别的扩展的优先级。优先级越高的æ’件会被优先选择。默认的优先级是 "
"[code]1.0[/code]。"
#: doc/classes/EditorImportPlugin.xml
@@ -25799,7 +25858,7 @@ msgid ""
"Gets the Godot resource type associated with this loader. e.g. "
"[code]\"Mesh\"[/code] or [code]\"Animation\"[/code]."
msgstr ""
-"获å–与此加载程åºå…³è”çš„Godot资æºç±»åž‹ï¼Œä¾‹å¦‚ [code]\"Mesh\"[/code] 或 "
+"获å–与此加载程åºå…³è”çš„ Godot 资æºç±»åž‹ï¼Œä¾‹å¦‚ [code]\"Mesh\"[/code] 或 "
"[code]\"Animation\"[/code]。"
#: doc/classes/EditorImportPlugin.xml
@@ -25808,8 +25867,8 @@ msgid ""
"directory (see [member ProjectSettings.application/config/"
"use_hidden_project_data_directory])."
msgstr ""
-"获å–用于在[code].import[/code]目录中ä¿å­˜æ­¤èµ„æºçš„æ‰©å±•å,å‚阅[member "
-"ProjectSettings.application/config/use_hidden_project_data_directory]。"
+"获å–用于在 [code].import[/code] 目录中ä¿å­˜æ­¤èµ„æºçš„æ‰©å±•åï¼ˆè§ [member "
+"ProjectSettings.application/config/use_hidden_project_data_directory])。"
#: doc/classes/EditorImportPlugin.xml
msgid ""
@@ -25901,7 +25960,7 @@ msgstr ""
msgid ""
"Emitted when the Edit button of an [Object] has been pressed in the "
"inspector. This is mainly used in the remote scene tree inspector."
-msgstr "在检查器中按下[Object]的编辑按钮时触å‘。主è¦ç”¨äºŽè¿œç¨‹åœºæ™¯æ ‘检查器中。"
+msgstr "在检查器中按下 [Object] 的编辑按钮时触å‘。主è¦ç”¨äºŽè¿œç¨‹åœºæ™¯æ ‘检查器中。"
#: doc/classes/EditorInspector.xml
msgid "Emitted when a property is edited in the inspector."
@@ -25913,8 +25972,8 @@ msgid ""
"by clicking the \"key\" icon next to a property when the Animation panel is "
"toggled."
msgstr ""
-"当属性在检查器中被键入时触å‘。当切æ¢åŠ¨ç”»é¢æ¿æ—¶ï¼Œå¯é€šè¿‡ç‚¹å‡»å±žæ€§æ—边的 \"é”® "
-"\"图标对属性进行键控。"
+"当属性在检查器中被键入时触å‘ã€‚å½“åŠ¨ç”»é¢æ¿æ‰“开时,å¯é€šè¿‡ç‚¹å‡»å±žæ€§æ—边的“钥匙â€å›¾"
+"标为属性添加关键帧。"
#: doc/classes/EditorInspector.xml
msgid "Emitted when a property is selected in the inspector."
@@ -25928,8 +25987,9 @@ msgid ""
"inspector, this signal is never emitted by the editor itself."
msgstr ""
"在检查器中切æ¢å¸ƒå°”属性时å‘出。\n"
-"[b]注æ„:[/b]如果å¯ç”¨äº†å†…部[code]autoclear[/code]å±žæ€§ï¼Œåˆ™è¯¥ä¿¡å·æ°¸è¿œä¸ä¼šè§¦å‘。"
-"由于该属性在编辑器检查器中始终处于å¯ç”¨çжæ€ï¼Œå› æ­¤ç¼–辑器本身ç»ä¸ä¼šå‘出该信å·ã€‚"
+"[b]注æ„:[/b]如果å¯ç”¨äº†å†…部 [code]autoclear[/code] å±žæ€§ï¼Œåˆ™è¯¥ä¿¡å·æ°¸è¿œä¸ä¼šè§¦"
+"å‘。由于该属性在编辑器检查器中始终处于å¯ç”¨çжæ€ï¼Œå› æ­¤ç¼–辑器本身ç»ä¸ä¼šå‘出该信"
+"å·ã€‚"
#: doc/classes/EditorInspector.xml
msgid "Emitted when a resource is selected in the inspector."
@@ -25987,14 +26047,15 @@ msgid ""
"Adds a property editor for an individual property. The [code]editor[/code] "
"control must extend [EditorProperty]."
msgstr ""
-"为å•独的属性添加属性编辑器。[code]editor[/code]控件必须扩展[EditorProperty]。"
+"为å•独的属性添加属性编辑器。[code]editor[/code] 控件必须扩展 "
+"[EditorProperty]。"
#: doc/classes/EditorInspectorPlugin.xml
msgid ""
"Adds an editor that allows modifying multiple properties. The [code]editor[/"
"code] control must extend [EditorProperty]."
msgstr ""
-"添加一个编辑器,å…许修改多个属性。[code]editor[/code]控件必须扩展"
+"添加一个编辑器,å…许修改多个属性。[code]editor[/code] 控件必须扩展 "
"[EditorProperty]。"
#: doc/classes/EditorInspectorPlugin.xml
@@ -26020,7 +26081,7 @@ msgid ""
"built-in editor for this property, otherwise allows to insert a custom "
"editor before the built-in one."
msgstr ""
-"å…许被调用在检查器中添加特定属性的编辑器。通常这些编辑器继承"
+"å…许被调用在检查器中添加特定属性的编辑器。通常这些编辑器继承 "
"[EditorProperty]。返回 [code]true[/code]删除该属性的内置编辑器,å¦åˆ™å…许在内"
"ç½®ç¼–è¾‘å™¨ä¹‹å‰æ’入一个自定义编辑器。"
@@ -26098,8 +26159,8 @@ msgid ""
"code] and [code]interface/editor/custom_display_scale[/code] editor "
"settings. Editor must be restarted for changes to be properly applied."
msgstr ""
-"返回编辑器用户 UI 的实际比例,[code]1.0[/code] 比例为 100%。这å¯ä»¥ç”¨æ¥è°ƒæ•´ç”±"
-"æ’件添加的用户 UI çš„ä½ç½®å’Œå°ºå¯¸ã€‚\n"
+"返回编辑器用户 UI 的实际比例([code]1.0[/code] 表示比例为 100%)。这å¯ä»¥ç”¨æ¥"
+"调整由æ’件添加的用户 UI çš„ä½ç½®å’Œå°ºå¯¸ã€‚\n"
"[b]注æ„:[/b]这个值是通过 [code]interface/editor/display_scale[/code] å’Œ "
"[code]interface/editor/custom_display_scale[/code] 编辑器设置项æ¥è®¾ç½®ã€‚编辑器"
"å¿…é¡»é‡æ–°å¯åЍæ‰èƒ½æ­£ç¡®åº”用这些å˜åŒ–。"
@@ -26141,7 +26202,7 @@ msgstr ""
#: doc/classes/EditorInterface.xml
msgid "Returns an [Array] with the file paths of the currently opened scenes."
-msgstr "返回包å«å½“剿‰“开的场景的文件路径的数组[Array]。"
+msgstr "返回包å«å½“剿‰“开的场景的文件路径的数组 [Array]。"
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26151,11 +26212,11 @@ msgstr "返回正在播放的场景åç§°ã€‚å¦‚æžœå½“å‰æ²¡æœ‰åœºæ™¯æ­£åœ¨æ’­æ”¾
#: doc/classes/EditorInterface.xml
msgid "Returns the editor's [EditorFileSystem] instance."
-msgstr "返回编辑器的[EditorFileSystem]实例。"
+msgstr "返回编辑器的 [EditorFileSystem] 实例。"
#: doc/classes/EditorInterface.xml
msgid "Returns the editor's [EditorResourcePreview] instance."
-msgstr "返回编辑器的[EditorResourcePreview]实例。"
+msgstr "返回编辑器的 [EditorResourcePreview] 实例。"
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26172,13 +26233,13 @@ msgid ""
"[FileSystemDock]. If a file is selected, its base directory will be returned "
"using [method String.get_base_dir] instead."
msgstr ""
-"返回当å‰åœ¨[FileSystemDock]中选择的目录的路径,如果选择了一个文件,将使用"
-"[method String.get_base_dir]返回其基本目录。如果选择了一个文件,将使用"
-"[method String.get_base_dir]返回它的基本目录。"
+"返回当å‰åœ¨ [FileSystemDock] 中选择的目录的路径,如果选择了一个文件,将使用 "
+"[method String.get_base_dir] 返回其基本目录。如果选择了一个文件,将使用 "
+"[method String.get_base_dir] 返回它的基本目录。"
#: doc/classes/EditorInterface.xml
msgid "Returns the editor's [EditorSelection] instance."
-msgstr "返回编辑器的[EditorSelection]实例。"
+msgstr "返回编辑器的 [EditorSelection] 实例。"
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26209,7 +26270,7 @@ msgstr ""
#: doc/classes/EditorInterface.xml
msgid ""
"Returns mesh previews rendered at the given size as an [Array] of [Texture]s."
-msgstr "返回 [Array] 数组包å«ç»™å®šå°ºå¯¸æ¸²æŸ“的网格预览图[Texture]。"
+msgstr "返回 [Array] 数组包å«ç»™å®šå°ºå¯¸æ¸²æŸ“的网格预览图 [Texture]。"
#: doc/classes/EditorInterface.xml
msgid "Opens the scene at the given path."
@@ -26236,12 +26297,12 @@ msgid ""
"Saves the scene. Returns either [code]OK[/code] or [code]ERR_CANT_CREATE[/"
"code] (see [@GlobalScope] constants)."
msgstr ""
-"ä¿å­˜åœºæ™¯ã€‚返回 [code]OK[/code] 或 [code]ERR_CANT_CREATE[/code] (å‚阅 "
-"[@GlobalScope] 常é‡)。"
+"ä¿å­˜åœºæ™¯ã€‚返回 [code]OK[/code] 或 [code]ERR_CANT_CREATE[/code]ï¼ˆè§ "
+"[@GlobalScope] 常é‡ï¼‰ã€‚"
#: doc/classes/EditorInterface.xml
msgid "Saves the scene as a file at [code]path[/code]."
-msgstr "将场景ä¿å­˜ä¸º[code]path[/code]处的文件。"
+msgstr "将场景ä¿å­˜ä¸º [code]path[/code] 处的文件。"
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26256,9 +26317,9 @@ msgid ""
"([code]2D[/code], [code]3D[/code], [code]Script[/code], [code]AssetLib[/"
"code])."
msgstr ""
-"将编辑器的当å‰ä¸»ç•Œé¢è®¾ç½®ä¸º [code]name[/code] 中指定的界é¢ã€‚[code]name[/code]"
-"必须与相关选项å¡çš„æ–‡æœ¬å®Œå…¨åŒ¹é…([code]2D[/code], [code]3D[/code], "
-"[code]Script[/code], [code]AssetLib[/code])。"
+"将编辑器的当å‰ä¸»ç•Œé¢è®¾ç½®ä¸º [code]name[/code] 中指定的界é¢ã€‚[code]name[/code] "
+"必须与相关选项å¡çš„æ–‡æœ¬å®Œå…¨åŒ¹é…([code]2D[/code]ã€[code]3D[/code]ã€"
+"[code]Script[/code]ã€[code]AssetLib[/code])。"
#: doc/classes/EditorInterface.xml
msgid ""
@@ -26275,8 +26336,8 @@ msgid ""
"If [code]true[/code], enables distraction-free mode which hides side docks "
"to increase the space available for the main view."
msgstr ""
-"为 [code]true[/code] æ—¶å°†å¯ç”¨ä¸“注模å¼ï¼Œè¯¥æ¨¡å¼ä¼šéšè—ä¾§è¾¹é¢æ¿ï¼Œå¢žåŠ ä¸»è§†å›¾çš„å¯ç”¨"
-"空间。"
+"如果为 [code]true[/code],将å¯ç”¨ä¸“注模å¼ï¼Œè¯¥æ¨¡å¼ä¼šéšè—ä¾§è¾¹é¢æ¿ï¼Œå¢žåŠ ä¸»è§†å›¾çš„"
+"å¯ç”¨ç©ºé—´ã€‚"
#: doc/classes/EditorPlugin.xml
msgid "Used by the editor to extend its functionality."
@@ -26290,7 +26351,7 @@ msgid ""
"editor."
msgstr ""
"编辑器使用æ’ä»¶æ¥æ‰©å±•功能。最常è§çš„æ’ä»¶ç±»åž‹æ˜¯ç¼–è¾‘ç»™å®šçš„èŠ‚ç‚¹æˆ–èµ„æºç±»åž‹ã€å¯¼å…¥æ’"
-"件和导出æ’件。å¦è¯·å‚阅[EditorScript]å‘编辑器添加函数。"
+"件和导出æ’件。å¦è¯·å‚阅 [EditorScript] å‘编辑器添加函数。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26309,7 +26370,7 @@ msgstr ""
"å°†æŽ§ä»¶æ·»åŠ åˆ°åº•éƒ¨é¢æ¿ï¼ˆåŒ…å«â€œè¾“出â€â€œè°ƒè¯•â€â€œåŠ¨ç”»â€ç­‰ï¼‰ã€‚返回对添加的按钮的引用。您"
"å¯ä»¥æ ¹æ®éœ€è¦éšè—/显示按钮。åœç”¨æ’ä»¶åŽï¼Œè¯·ç¡®ä¿ä½¿ç”¨ [method "
"remove_control_from_bottom_panel] 移除自定义控件,并使用 [method Node."
-"queue_free] 释放。"
+"queue_free] 将其释放。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26322,11 +26383,11 @@ msgid ""
"with [method remove_control_from_container] and free it with [method Node."
"queue_free]."
msgstr ""
-"将自定义控件添加到容器中(å‚阅 [enum CustomControlContainer])。在编辑器用户"
-"界é¢ä¸­ï¼Œæœ‰è®¸å¤šä½ç½®å¯ä»¥æ·»åŠ è‡ªå®šä¹‰æŽ§ä»¶ã€‚\n"
+"å°†è‡ªå®šä¹‰æŽ§ä»¶æ·»åŠ åˆ°å®¹å™¨ä¸­ï¼ˆè§ [enum CustomControlContainer])。在编辑器用户界"
+"é¢ä¸­ï¼Œæœ‰è®¸å¤šä½ç½®å¯ä»¥æ·»åŠ è‡ªå®šä¹‰æŽ§ä»¶ã€‚\n"
"请记ä½ï¼Œæ‚¨å¿…é¡»è‡ªå·±ç®¡ç†æ‚¨çš„自定义控件的å¯è§æ€§ï¼ˆå¹¶ä¸”很å¯èƒ½åœ¨æ·»åŠ åŽéšè—它)。\n"
-"当你的æ’ä»¶åœç”¨æ—¶ï¼Œè¯·ç¡®ä¿ä½¿ç”¨ [method remove_control_from_container] 删除你的"
-"自定义控件,并使用 [method Node.queue_free] 释放它。"
+"当你的æ’件被åœç”¨æ—¶ï¼Œè¯·ç¡®ä¿ä½¿ç”¨ [method remove_control_from_container] 删除你"
+"的自定义控件,并使用 [method Node.queue_free] 将其释放。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26407,7 +26468,7 @@ msgid ""
" remove_inspector_plugin(inspector_plugin)\n"
"[/codeblock]"
msgstr ""
-"注册一个新的编辑器属性检查器æ’ä»¶[EditorInspectorPlugin]。检查器æ’件用于扩展 "
+"注册一个新的编辑器属性检查器æ’ä»¶ [EditorInspectorPlugin]。检查器æ’件用于扩展 "
"[EditorInspector] 并为你的对象属性æä¾›è‡ªå®šä¹‰é…置工具。\n"
"[b]注æ„:[/b]当你的 [EditorPlugin] 被ç¦ç”¨æ—¶ï¼Œä¸€å®šè¦ä½¿ç”¨ [method "
"remove_inspector_plugin] æ¥åˆ é™¤æ³¨å†Œçš„ [EditorInspectorPlugin],以防止泄æ¼å’Œå‡º"
@@ -26458,7 +26519,7 @@ msgid ""
"[code]submenu[/code] should be an object of class [PopupMenu]. This submenu "
"should be cleaned up using [code]remove_tool_menu_item(name)[/code]."
msgstr ""
-"在[b]项目 > 工具[/b]下添加å为 [code]name[/code] 的自定义å­èœå•。 "
+"在[b]项目 > 工具[/b]下添加å为 [code]name[/code] 的自定义å­èœå•。"
"[code]submenu[/code] 应该是 [PopupMenu] 类的对象。此å­èœå•应使用 "
"[code]remove_tool_menu_item(name)[/code] 进行清ç†ã€‚"
@@ -26500,7 +26561,7 @@ msgstr ""
msgid ""
"Called by the engine when the user disables the [EditorPlugin] in the Plugin "
"tab of the project settings window."
-msgstr "当用户在项目设置窗å£çš„æ’ä»¶é€‰é¡¹å¡ä¸­ç¦ç”¨[EditorPlugin]时,由引擎调用。"
+msgstr "当用户在项目设置窗å£çš„æ’ä»¶é€‰é¡¹å¡ä¸­ç¦ç”¨ [EditorPlugin] 时,由引擎调用。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26534,8 +26595,8 @@ msgid ""
" return false\n"
"[/codeblock]"
msgstr ""
-"当2D编辑器的视窗被更新时,由引擎调用。使用 [code]overlay[/code] [Control] 进"
-"行绘制。你å¯ä»¥é€šè¿‡è°ƒç”¨ [method update_overlays] 手动更新视窗。\n"
+"引擎会在 2D 编辑器的视区å‘生更新时调用。使用 [code]overlay[/code] [Control] "
+"进行绘制。你å¯ä»¥é€šè¿‡è°ƒç”¨ [method update_overlays] 手动更新视窗。\n"
"[codeblock]\n"
"func forward_canvas_draw_over_viewport(overlay):\n"
" # 在光标ä½ç½®ç”»ä¸€ä¸ªåœ†ã€‚\n"
@@ -26626,7 +26687,7 @@ msgid ""
" return false\n"
"[/codeblock]"
msgstr ""
-"当3D编辑器的视窗被更新时,由引擎调用。使用 [code]overlay[/code] 控件 "
+"引擎会在 3D 编辑器的视区å‘生更新时调用。使用 [code]overlay[/code] 控件 "
"[Control] 进行绘制。你å¯ä»¥é€šè¿‡è°ƒç”¨ [method update_overlays] 更新覆盖手动更新"
"视窗。\n"
"[codeblock]\n"
@@ -26707,14 +26768,14 @@ msgid ""
"[code]res://path_to_script.gd:25[/code]."
msgstr ""
"这是为编辑基于脚本的对象的编辑器。您å¯ä»¥è¿”回格å¼ä¸­çš„æ–­ç‚¹åˆ—表([code]script:"
-"line[/code]),例如:[code]res://path_to_script.gd:25[/code]。"
+"line[/code]),例如:[code]res://path_to_script.gd:25[/code]。"
#: doc/classes/EditorPlugin.xml
msgid ""
"Returns the [EditorInterface] object that gives you control over Godot "
"editor's window and its functionalities."
msgstr ""
-"返回[EditorInterface]对象,该对象使您å¯ä»¥æŽ§åˆ¶Godot编辑器的窗å£åŠå…¶åŠŸèƒ½ã€‚"
+"返回 [EditorInterface] 对象,该对象使您å¯ä»¥æŽ§åˆ¶ Godot 编辑器的窗å£åŠå…¶åŠŸèƒ½ã€‚"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26734,9 +26795,9 @@ msgid ""
"[/codeblock]"
msgstr ""
"在你的æ’ä»¶ä¸­è¦†ç›–è¿™ä¸ªæ–¹æ³•ï¼Œè¿”å›žä¸€ä¸ªçº¹ç† [Texture],以便给它一个图标。\n"
-"对于主界é¢çš„æ’ä»¶ï¼Œå®ƒå‡ºçŽ°åœ¨å±å¹•的顶部,在 \"2D\"ã€\"3D\"ã€\"Script \"å’Œ "
-"\"AssetLib \"按钮的å³è¾¹ã€‚\n"
-"ç†æƒ³æƒ…况下,æ’ä»¶çš„å›¾æ ‡åº”è¯¥æ˜¯é€æ˜ŽèƒŒæ™¯çš„白色,尺寸为16x16åƒç´ ã€‚\n"
+"对于主界é¢çš„æ’ä»¶ï¼Œå®ƒå‡ºçŽ°åœ¨å±å¹•的顶部,在“2Dâ€â€œ3Dâ€â€œScriptâ€â€œAssetLibâ€æŒ‰é’®çš„å³"
+"边。\n"
+"ç†æƒ³æƒ…况下,æ’ä»¶çš„å›¾æ ‡åº”è¯¥æ˜¯é€æ˜ŽèƒŒæ™¯çš„白色,尺寸为 16x16 åƒç´ ã€‚\n"
"[codeblock]\n"
"func get_plugin_icon():\n"
" # ä½ å¯ä»¥ä½¿ç”¨ä¸€ä¸ªè‡ªå®šä¹‰çš„图标。\n"
@@ -26753,9 +26814,8 @@ msgid ""
"For main screen plugins, this appears at the top of the screen, to the right "
"of the \"2D\", \"3D\", \"Script\", and \"AssetLib\" buttons."
msgstr ""
-"在Godot编辑器中显示时,请在æ’件中覆盖此方法以æä¾›æ’ä»¶çš„å称。\n"
-"对于主å±å¹•æ’件,它显示在å±å¹•顶部,在“ 2Dâ€ï¼Œâ€œ 3Dâ€ï¼Œâ€œè„šæœ¬â€å’Œâ€œ AssetLibâ€æŒ‰é’®çš„å³"
-"侧。"
+"在 Godot 编辑器中显示时,请在æ’件中覆盖此方法以æä¾›æ’ä»¶çš„å称。\n"
+"对于主å±å¹•æ’件,它显示在å±å¹•顶部,在“2Dâ€â€œ3Dâ€â€œè„šæœ¬â€â€œAssetLibâ€æŒ‰é’®çš„å³ä¾§ã€‚"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26858,8 +26918,8 @@ msgid ""
"the workspace selector together with [b]2D[/b], [b]3D[/b], [b]Script[/b] and "
"[b]AssetLib[/b])."
msgstr ""
-"如果这是一个主å±å¹•编辑æ’件,返回 [code]true[/code](它与[b]2D[/b]ã€[b]3D[/b]ã€"
-"[b]Script[/b]和[b]AssetLib[/b]一起放在工作区选择器中)。"
+"如果这是一个主å±å¹•编辑æ’件,返回 [code]true[/code](它与 [b]2D[/b]ã€[b]3D[/"
+"b]ã€[b]Script[/b]ã€[b]AssetLib[/b] 一起放在工作区选择器中)。"
#: doc/classes/EditorPlugin.xml
msgid "Minimizes the bottom panel."
@@ -26885,25 +26945,25 @@ msgstr "排队ä¿å­˜é¡¹ç›®çš„编辑器布局。"
#: doc/classes/EditorPlugin.xml
msgid "Removes an Autoload [code]name[/code] from the list."
-msgstr "从列表中删除自动加载[code]name[/code]。"
+msgstr "从列表中删除自动加载 [code]name[/code]。"
#: doc/classes/EditorPlugin.xml
msgid ""
"Removes the control from the bottom panel. You have to manually [method Node."
"queue_free] the control."
-msgstr "ä»Žåº•éƒ¨é¢æ¿ä¸Šåˆ é™¤æŽ§ä»¶ã€‚您必须手动[method Node.queue_free]释放控件。"
+msgstr "ä»Žåº•éƒ¨é¢æ¿ä¸Šåˆ é™¤æŽ§ä»¶ã€‚您必须手动 [method Node.queue_free] 释放控件。"
#: doc/classes/EditorPlugin.xml
msgid ""
"Removes the control from the specified container. You have to manually "
"[method Node.queue_free] the control."
-msgstr "从指定的容器中删除控件。您必须手动[method Node.queue_free]释放控件。"
+msgstr "从指定的容器中删除控件。您必须手动 [method Node.queue_free] 释放控件。"
#: doc/classes/EditorPlugin.xml
msgid ""
"Removes the control from the dock. You have to manually [method Node."
"queue_free] the control."
-msgstr "ä»Žæ‰©å±•é¢æ¿ä¸­åˆ é™¤æŽ§ä»¶ã€‚您必须手动[method Node.queue_free]释放控件。"
+msgstr "ä»Žæ‰©å±•é¢æ¿ä¸­åˆ é™¤æŽ§ä»¶ã€‚您必须手动 [method Node.queue_free] 释放控件。"
#: doc/classes/EditorPlugin.xml
msgid "Removes a custom type added by [method add_custom_type]."
@@ -26932,7 +26992,7 @@ msgstr "删除由 [method add_spatial_gizmo_plugin] 注册的控制器æ’件。"
#: doc/classes/EditorPlugin.xml
msgid "Removes a menu [code]name[/code] from [b]Project > Tools[/b]."
-msgstr "从[b]项目 > 工具[/b]中删除èœå•[code]name[/code]。"
+msgstr "从[b]项目 > 工具[/b]中删除èœå• [code]name[/code]。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26949,9 +27009,9 @@ msgid ""
"editor when their viewports are updated. You need to call this method only "
"once and it will work permanently for this plugin."
msgstr ""
-"å¯ç”¨2D编辑器的 [method forward_canvas_force_draw_over_viewport] å’Œ3D编辑器的 "
-"[method forward_spatial_force_draw_over_viewport] 在其视窗更新时的调用。你åª"
-"需è¦è°ƒç”¨è¿™ä¸ªæ–¹æ³•一次,它就会对这个æ’件永久起作用。"
+"å¯ç”¨ 2D 编辑器的 [method forward_canvas_force_draw_over_viewport] å’Œ 3D 编辑"
+"器的 [method forward_spatial_force_draw_over_viewport] 在其视窗更新时的调用。"
+"ä½ åªéœ€è¦è°ƒç”¨è¿™ä¸ªæ–¹æ³•一次,它就会对这个æ’件永久起作用。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26959,9 +27019,9 @@ msgid ""
"inside [method forward_spatial_gui_input]. It might be especially usable if "
"your plugin will want to use raycast in the scene."
msgstr ""
-"如果你想在[method forward_spatial_gui_input]é‡Œé¢æŽ¥æ”¶æ¥è‡ª3D视图å±å¹•的输入,请"
-"使用这个方法。如果你的æ’件想è¦åœ¨åœºæ™¯ä¸­ä½¿ç”¨å…‰çº¿å¹¿æ’­ï¼Œé‚£ä¹ˆè¿™ä¸ªæ–¹æ³•å¯èƒ½ç‰¹åˆ«æœ‰"
-"用。"
+"如果你想在 [method forward_spatial_gui_input] é‡Œé¢æŽ¥æ”¶æ¥è‡ª 3D 视图å±å¹•的输"
+"入,请使用这个方法。如果你的æ’件想è¦åœ¨åœºæ™¯ä¸­ä½¿ç”¨å…‰çº¿æŠ•射,那么这个方法å¯èƒ½ç‰¹"
+"别有用。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -27028,8 +27088,8 @@ msgid ""
"Emitted when user changes the workspace ([b]2D[/b], [b]3D[/b], [b]Script[/"
"b], [b]AssetLib[/b]). Also works with custom screens defined by plugins."
msgstr ""
-"当用户改å˜å·¥ä½œç©ºé—´([b]2D[/b], [b]3D[/b], [b]Script[/b], [b]AssetLib[/b])时触"
-"å‘。也适用于由æ’件定义的自定义å±å¹•。"
+"当用户改å˜å·¥ä½œç©ºé—´ï¼ˆ[b]2D[/b]ã€[b]3D[/b]ã€[b]Script[/b]ã€[b]AssetLib[/b])时"
+"触å‘。也适用于由æ’件定义的自定义å±å¹•。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -27048,7 +27108,7 @@ msgstr "当用户关闭场景时触å‘ã€‚å‚æ•°æ˜¯å…³é—­åœºæ™¯çš„æ–‡ä»¶è·¯å¾„。
#: doc/classes/EditorPlugin.xml
msgid "Represents the size of the [enum DockSlot] enum."
-msgstr "表示[enum DockSlot]枚举的大å°ã€‚"
+msgstr "表示 [enum DockSlot] 枚举的大å°ã€‚"
#: doc/classes/EditorProperty.xml
msgid "Custom control to edit properties for adding into the inspector."
@@ -27078,9 +27138,10 @@ msgid ""
"requesting this property to be refreshed (leave as [code]false[/code] if "
"unsure)."
msgstr ""
-"如果一个或几个属性å‘生了å˜åŒ–,必然会调用这个函数。[code]field[/code]是在你的"
-"编辑器å¯ä»¥å•独修改字段的情况下使用的(比如Vector3.x)。[code]changing[/code]"
-"傿•°å¯ä»¥é¿å…ç¼–è¾‘å™¨è¦æ±‚刷新这个属性(如果ä¸ç¡®å®šçš„è¯ï¼Œå°±ç”¨[code]false[/code])。"
+"如果一个或几个属性å‘生了å˜åŒ–,必然会调用这个函数。[code]field[/code] 是在你的"
+"编辑器å¯ä»¥å•独修改字段的情况下使用的(比如 Vector3.x)。[code]changing[/"
+"code] 傿•°å¯ä»¥é¿å…ç¼–è¾‘å™¨è¦æ±‚刷新这个属性(如果ä¸ç¡®å®šçš„è¯ï¼Œè¯·ä¿æŒ "
+"[code]false[/code])。"
#: doc/classes/EditorProperty.xml
msgid "Gets the edited object."
@@ -27233,7 +27294,7 @@ msgid ""
"This virtual method can be implemented to handle context menu items not "
"handled by default. See [method set_create_options]."
msgstr ""
-"此虚拟法å¯ä»¥å®žçް处ç†é»˜è®¤æœªå¤„ç†çš„上下文èœå•项目。å‚è§ [method "
+"此虚拟法å¯ä»¥å®žçް处ç†é»˜è®¤æœªå¤„ç†çš„上下文èœå•é¡¹ç›®ã€‚è§ [method "
"set_create_options]。"
#: doc/classes/EditorResourcePicker.xml
@@ -27266,7 +27327,7 @@ msgstr "å…许资æºç±»åž‹çš„基本类型。å¯ä»¥æ˜¯å‡ ä¸ªé€‰é¡¹çš„逗å·åˆ†ç¦»
#: doc/classes/EditorResourcePicker.xml
msgid "If [code]true[/code], the value can be selected and edited."
-msgstr "如果 [code]true[/code],则å¯ä»¥é€‰æ‹©å’Œç¼–辑该值。"
+msgstr "如果为 [code]true[/code],则å¯ä»¥é€‰æ‹©å’Œç¼–辑该值。"
#: doc/classes/EditorResourcePicker.xml
msgid "The edited resource value."
@@ -27277,7 +27338,7 @@ msgid ""
"If [code]true[/code], the main button with the resource preview works in the "
"toggle mode. Use [method set_toggle_pressed] to manually set the state."
msgstr ""
-"如果 [code]true[/code],带有资æºé¢„è§ˆçš„ä¸»æŒ‰é’®åœ¨åˆ‡æ¢æ¨¡å¼ä¸‹å·¥ä½œã€‚使用 [method "
+"如果为 [code]true[/code],带有资æºé¢„è§ˆçš„ä¸»æŒ‰é’®åœ¨åˆ‡æ¢æ¨¡å¼ä¸‹å·¥ä½œã€‚使用 [method "
"set_toggle_pressed] æ¥æ‰‹åŠ¨è®¾ç½®çŠ¶æ€ã€‚"
#: doc/classes/EditorResourcePicker.xml
@@ -27367,7 +27428,7 @@ msgstr "移除自定义预览生æˆå™¨ã€‚"
msgid ""
"Emitted if a preview was invalidated (changed). [code]path[/code] "
"corresponds to the path of the preview."
-msgstr "预览无效(更改)时触å‘。[code]path[/code]对应的预览路径。"
+msgstr "预览无效(更改)时触å‘。[code]path[/code] 对应的预览路径。"
#: doc/classes/EditorResourcePreviewGenerator.xml
msgid "Custom generator of previews."
@@ -27379,7 +27440,7 @@ msgid ""
"thumbnail_size[/code] in [EditorSettings] to find out the right size to do "
"previews at."
msgstr ""
-"è‡ªå®šä¹‰ä»£ç æ¥ç”Ÿæˆé¢„览。请查看[EditorSettings]中的[code]file_dialog/"
+"è‡ªå®šä¹‰ä»£ç æ¥ç”Ÿæˆé¢„览。请查看 [EditorSettings] 中的 [code]file_dialog/"
"thumbnail_size[/code],找出适åˆåšé¢„览的尺寸。"
#: doc/classes/EditorResourcePreviewGenerator.xml
@@ -27388,8 +27449,8 @@ msgid ""
"generate] or [method generate_from_path] for small previews as well.\n"
"By default, it returns [code]false[/code]."
msgstr ""
-"如果该函数返回 [code]true[/code],生æˆå™¨å°†è°ƒç”¨[method generate]或[method "
-"generate_from_path]æ¥è¿›è¡Œå°åž‹é¢„览。\n"
+"如果该函数返回 [code]true[/code],生æˆå™¨å°†è°ƒç”¨ [method generate] 或 [method "
+"generate_from_path] æ¥è¿›è¡Œå°åž‹é¢„览。\n"
"默认情况下,它会返回 [code]false[/code]。"
#: doc/classes/EditorResourcePreviewGenerator.xml
@@ -27440,7 +27501,7 @@ msgstr ""
#: doc/classes/EditorSceneImporter.xml
msgid "Imports scenes from third-parties' 3D files."
-msgstr "从第三方的3D文件中导入场景。"
+msgstr "从第三方的 3D 文件中导入场景。"
#: doc/classes/EditorSceneImporter.xml
msgid ""
@@ -27555,16 +27616,16 @@ msgstr ""
"[method post_import]回调接收导入场景的根节点,并返回场景的修改版本。使用示"
"例。\n"
"[codeblock]\n"
-"tool # Needed so it runs in editor\n"
+"tool # 因为需è¦åœ¨ç¼–辑器中è¿è¡Œ\n"
"extends EditorScenePostImport\n"
"\n"
-"# This sample changes all node names\n"
+"# 这个实例会修改所有节点的åç§°\n"
"\n"
-"# Called right after the scene is imported and gets the root node\n"
+"# 会在场景导入åŽç«‹å³è°ƒç”¨ï¼ŒèŽ·å–到的是根节点\n"
"func post_import(scene):\n"
-" # Change all node names to \"modified_[oldnodename]\"\n"
+" # 将所有节点的å称都改æˆâ€œmodified_[节点原å]â€\n"
" iterate(scene)\n"
-" return scene # Remember to return the imported scene\n"
+" return scene # è®°å¾—è¦è¿”回导入的场景\n"
"\n"
"func iterate(node):\n"
" if node != null:\n"
@@ -27577,7 +27638,7 @@ msgstr ""
msgid ""
"Returns the source file path which got imported (e.g. [code]res://scene.dae[/"
"code])."
-msgstr "è¿”å›žå¯¼å…¥çš„æºæ–‡ä»¶è·¯å¾„(如[code]res://scene.dae[/code])。"
+msgstr "è¿”å›žå¯¼å…¥çš„æºæ–‡ä»¶è·¯å¾„(如[code]res://scene.dae[/code])。"
#: doc/classes/EditorScenePostImport.xml
msgid "Returns the resource folder the imported scene file is located in."
@@ -27613,9 +27674,9 @@ msgid ""
"is visible in the console window started with the Editor (stdout) instead of "
"the usual Godot [b]Output[/b] dock."
msgstr ""
-"扩展该类并实现其 [method _run] 方法的脚本å¯ä»¥åœ¨ç¼–辑器è¿è¡Œæ—¶é€šè¿‡è„šæœ¬ç¼–è¾‘å™¨çš„ "
-"[b]File > Run[/b] èœå•选项(或按 [code]Ctrl+Shift+X[/code]ï¼‰æ‰§è¡Œã€‚è¿™å¯¹äºŽå‘ "
-"Godotæ·»åŠ è‡ªå®šä¹‰çš„ç¼–è¾‘å†…åŠŸèƒ½å¾ˆæœ‰ç”¨ã€‚å¯¹äºŽæ›´å¤æ‚的添加,å¯ä»¥è€ƒè™‘使用 "
+"扩展该类并实现其 [method _run] 方法的脚本å¯ä»¥åœ¨ç¼–辑器è¿è¡Œæ—¶é€šè¿‡è„šæœ¬ç¼–è¾‘å™¨çš„"
+"[b]文件 > è¿è¡Œ[/b]èœå•选项(或按 [code]Ctrl+Shift+X[/code]ï¼‰æ‰§è¡Œã€‚è¿™å¯¹äºŽå‘ "
+"Godot æ·»åŠ è‡ªå®šä¹‰çš„ç¼–è¾‘å†…åŠŸèƒ½å¾ˆæœ‰ç”¨ã€‚å¯¹äºŽæ›´å¤æ‚的添加,å¯ä»¥è€ƒè™‘使用 "
"[EditorPlugin] 代替。\n"
"[b]注æ„:[/b]扩展脚本需è¦å¯ç”¨ [code]tool[/code] 工具模å¼ã€‚\n"
"[b]示例脚本:[/b]\n"
@@ -27638,12 +27699,12 @@ msgid ""
"Adds [code]node[/code] as a child of the root node in the editor context.\n"
"[b]Warning:[/b] The implementation of this method is currently disabled."
msgstr ""
-"å°†[code]node[/code]添加为编辑器上下文中根节点的å­çº§ã€‚\n"
+"å°† [code]node[/code] 添加为编辑器上下文中根节点的å­çº§ã€‚\n"
"[b]警告:[/b]此方法的实现å‰å¤„于ç¦ç”¨çжæ€ã€‚"
#: doc/classes/EditorScript.xml
msgid "Returns the [EditorInterface] singleton instance."
-msgstr "返回[EditorInterface]å•例的实例。"
+msgstr "返回 [EditorInterface] å•例的实例。"
#: doc/classes/EditorScript.xml
msgid "Returns the Editor's currently active scene."
@@ -27680,7 +27741,7 @@ msgstr "æŒæœ‰è¢«ç¼–辑资æºçš„脚本属性的所有者 [Node]。"
#: doc/classes/EditorSelection.xml
msgid "Manages the SceneTree selection in the editor."
-msgstr "管ç†ç¼–辑器中的SceneTree选择。"
+msgstr "管ç†ç¼–辑器中的 SceneTree 选择。"
#: doc/classes/EditorSelection.xml
msgid ""
@@ -27688,7 +27749,7 @@ msgid ""
"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
"the singleton using [method EditorInterface.get_selection]."
msgstr ""
-"这个对象管ç†ç¼–辑器中的SceneTree选择。\n"
+"这个对象管ç†ç¼–辑器中的 SceneTree 选择。\n"
"[b]注æ„:[/b]这个类ä¸åº”该直接实例化。相å,使用[method EditorInterface."
"get_selection]访问å•例。"
@@ -27794,10 +27855,10 @@ msgid ""
"editor_settings.add_property_info(property_info)\n"
"[/codeblock]"
msgstr ""
-"å°†è‡ªå®šä¹‰å±žæ€§ä¿¡æ¯æ·»åŠ åˆ°å±žæ€§ã€‚è¯¥è¯å…¸å¿…须包å«ï¼š\n"
-"-[code]åç§°[/code]:[String](属性å称)\n"
-"-[code]类型[/code]:[int](请å‚阅[enum Variant.Type])\n"
-"-(å¯é€‰ï¼‰[code]æç¤º[/code]:[int](请å‚阅[enum PropertyHint])和"
+"å°†è‡ªå®šä¹‰å±žæ€§ä¿¡æ¯æ·»åŠ åˆ°å±žæ€§ã€‚è¯¥å­—å…¸å¿…é¡»åŒ…å«ï¼š\n"
+"-[code]name[/code]:[String](该属性的å称)\n"
+"-[code]type[/code]:[int]ï¼ˆè§ [enum Variant.Type])\n"
+"-(å¯é€‰ï¼‰[code]hint[/code]:[int]ï¼ˆè§ [enum PropertyHint])和 "
"[code]hint_string[/code]:[String]\n"
"[b]示例:[/b]\n"
"[codeblock]\n"
@@ -27815,7 +27876,7 @@ msgstr ""
#: doc/classes/EditorSettings.xml
msgid "Erases the setting whose name is specified by [code]property[/code]."
-msgstr "删除å称为指定[code]property[/code]的设置。"
+msgstr "删除å称为指定 [code]property[/code] 的设置。"
#: doc/classes/EditorSettings.xml
msgid "Returns the list of favorite files and directories for this project."
@@ -27827,8 +27888,9 @@ msgid ""
"[code]key[/code] specified. If the metadata doesn't exist, [code]default[/"
"code] will be returned instead. See also [method set_project_metadata]."
msgstr ""
-"返回指定的[code]section[/code]å’Œ[code]key[/code]的特定项目元数æ®ã€‚如果元数æ®"
-"ä¸å­˜åœ¨ï¼Œå°†è¿”回 [code]default[/code]。å¦è¯·å‚阅 [method set_project_metadata]。"
+"返回指定的 [code]section[/code] å’Œ [code]key[/code] 的特定项目元数æ®ã€‚如果元"
+"æ•°æ®ä¸å­˜åœ¨ï¼Œå°†è¿”回 [code]default[/code]。å¦è¯·å‚阅 [method "
+"set_project_metadata]。"
#: doc/classes/EditorSettings.xml
msgid ""
@@ -27850,7 +27912,7 @@ msgid ""
"Returns the value of the setting specified by [code]name[/code]. This is "
"equivalent to using [method Object.get] on the EditorSettings instance."
msgstr ""
-"返回 [code]name[/code] 指定的设置的值。这相当于在EditorSettings实例上使用"
+"返回 [code]name[/code] 指定的设置的值。相当于在 EditorSettings 实例上使用 "
"[method Object.get]。"
#: doc/classes/EditorSettings.xml
@@ -27861,8 +27923,8 @@ msgid ""
"[code]settings/templates[/code] - Where export templates are located"
msgstr ""
"获å–引擎的全局设置路径。在此路径内,您å¯ä»¥æ‰¾åˆ°ä¸€äº›æ ‡å‡†è·¯å¾„,例如:\n"
-"[code]settings / tmp[/code]-用于文件的临时存储\n"
-"[code]settings/templates[/code]-å¯¼å‡ºæ¨¡æ¿æ‰€åœ¨çš„ä½ç½®"
+"[code]settings/tmp[/code] - 用于文件的临时存储\n"
+"[code]settings/templates[/code] - å¯¼å‡ºæ¨¡æ¿æ‰€åœ¨çš„ä½ç½®"
#: doc/classes/EditorSettings.xml
msgid ""
@@ -27879,7 +27941,7 @@ msgid ""
"When this method returns [code]true[/code], a Revert button will display "
"next to the setting in the Editor Settings."
msgstr ""
-"如果[code]name[/code]指定的设置å¯ä»¥å°†å…¶å€¼è¿˜åŽŸä¸ºé»˜è®¤å€¼ï¼Œåˆ™è¿”å›ž [code]true[/"
+"如果 [code]name[/code] 指定的设置å¯ä»¥å°†å…¶å€¼è¿˜åŽŸä¸ºé»˜è®¤å€¼ï¼Œåˆ™è¿”å›ž [code]true[/"
"code],å¦åˆ™è¿”回 [code]false[/code]。当此方法返回 [code]true[/code] 时,编辑器"
"设置中的设置æ—边会显示一个还原按钮。"
@@ -27889,8 +27951,8 @@ msgid ""
"This is the value that would be applied when clicking the Revert button in "
"the Editor Settings."
msgstr ""
-"返回 [code]name[/code] 指定的设置的默认值。当点击编辑器设置中的 \"还原 \"按钮"
-"时,该值将被应用。"
+"返回 [code]name[/code] æŒ‡å®šçš„è®¾ç½®çš„é»˜è®¤å€¼ã€‚å½“ç‚¹å‡»ç¼–è¾‘å™¨è®¾ç½®ä¸­çš„â€œè¿˜åŽŸâ€æŒ‰é’®æ—¶ï¼Œ"
+"该值将被应用。"
#: doc/classes/EditorSettings.xml
msgid "Sets the list of favorite files and directories for this project."
@@ -27930,8 +27992,8 @@ msgid ""
"This is equivalent to using [method Object.set] on the EditorSettings "
"instance."
msgstr ""
-"设置 [code]name[/code] 指定的设置的 [code]value[/code]。这相当于在"
-"EditorSettings实例上使用[method Object.set]。"
+"将 [code]name[/code] 指定的设置项设置为 [code]value[/code]。相当于在 "
+"EditorSettings 实例上使用 [method Object.set]。"
#: doc/classes/EditorSettings.xml
msgid "Emitted after any editor setting has changed."
@@ -27964,8 +28026,8 @@ msgid ""
"Adds the specified [code]segments[/code] to the gizmo's collision shape for "
"picking. Call this function during [method redraw]."
msgstr ""
-"将指定的[code]segments[/code]添加到gizmo的碰撞形状中,以便挑选。在[method "
-"redraw]时调用此函数。"
+"将指定的 [code]segments[/code] 添加到 gizmo 的碰撞形状中,以便挑选。在 "
+"[method redraw] 时调用此函数。"
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
@@ -27973,8 +28035,8 @@ msgid ""
"generated from a regular [Mesh] too. Call this function during [method "
"redraw]."
msgstr ""
-"将碰撞三角形添加到å°å·¥å…·ä¸­ï¼Œä¾›æŒ‘选。也å¯ä»¥ä»Žæ™®é€šçš„[Mesh]生æˆ[TriangleMesh]。"
-"在[method redraw]时调用此函数。"
+"将碰撞三角形添加到å°å·¥å…·ä¸­ï¼Œä¾›æŒ‘选。也å¯ä»¥ä»Žæ™®é€šçš„ [Mesh] ç”Ÿæˆ "
+"[TriangleMesh]。在 [method redraw] 时调用此函数。"
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
@@ -27992,8 +28054,8 @@ msgid ""
"lines are used for visualizing the gizmo. Call this function during [method "
"redraw]."
msgstr ""
-"用给定的æè´¨åœ¨å°å·¥å…·ä¸Šæ·»åŠ çº¿æ¡åˆ°gizmo (作为2个点的集åˆï¼‰ã€‚线æ¡ç”¨äºŽå¯è§†åŒ–"
-"gizmo。在[method redraw]时调用此函数。"
+"用给定的æè´¨åœ¨å°å·¥å…·ä¸Šæ·»åŠ çº¿æ¡åˆ° gizmo(作为 2 个点的集åˆï¼‰ã€‚线æ¡ç”¨äºŽå¯è§†åŒ– "
+"gizmo。在 [method redraw] 时调用此函数。"
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
@@ -28011,7 +28073,7 @@ msgstr ""
msgid ""
"Adds an unscaled billboard for visualization. Call this function during "
"[method redraw]."
-msgstr "添加一个未缩放的广告牌以实现å¯è§†åŒ–。在[method redraw]时调用此函数。"
+msgstr "添加一个未缩放的广告牌以实现å¯è§†åŒ–。在 [method redraw] 时调用此函数。"
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
@@ -28090,15 +28152,14 @@ msgid ""
"Sets the gizmo's hidden state. If [code]true[/code], the gizmo will be "
"hidden. If [code]false[/code], it will be shown."
msgstr ""
-"设置工具的éšè—状æ€ã€‚如果[code]true[/code]ï¼Œåˆ™å°æŽ§ä»¶å°†è¢«éšè—。如果"
+"设置工具的éšè—状æ€ã€‚如果为 [code]true[/code]ï¼Œåˆ™å°æŽ§ä»¶å°†è¢«éšè—。如果为 "
"[code]false[/code],将显示它。"
#: doc/classes/EditorSpatialGizmo.xml
msgid ""
"Sets the reference [Spatial] node for the gizmo. [code]node[/code] must "
"inherit from [Spatial]."
-msgstr ""
-"设置工具的å‚考 [Spatial] 节点。 [code]node[/code]必须继承自 [Spatial]。"
+msgstr "设置工具的å‚考 [Spatial] 节点。[code]node[/code]必须继承自 [Spatial]。"
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid "Used by the editor to define Spatial gizmo types."
@@ -28132,13 +28193,13 @@ msgid ""
"Override this method to define whether the gizmo can be hidden or not. "
"Returns [code]true[/code] if not overridden."
msgstr ""
-"é‡å†™æ­¤æ–¹æ³•以定义是å¦å¯ä»¥éšè—Gizmo。如果未覆盖,则返回 [code]true[/code]。"
+"é‡å†™æ­¤æ–¹æ³•以定义是å¦å¯ä»¥éšè— Gizmo。如果未覆盖,则返回 [code]true[/code]。"
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid ""
"Override this method to commit gizmo handles. Called for this plugin's "
"active gizmos."
-msgstr "é‡å†™æ­¤æ–¹æ³•以æäº¤Gizmo奿Ÿ„。调用此æ’件的活动辅助工具。"
+msgstr "é‡å†™æ­¤æ–¹æ³•以æäº¤ Gizmo 奿Ÿ„。调用此æ’件的活动辅助工具。"
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid ""
@@ -28189,13 +28250,13 @@ msgstr ""
msgid ""
"Override this method to provide gizmo's handle names. Called for this "
"plugin's active gizmos."
-msgstr "é‡å†™æ­¤æ–¹æ³•以æä¾›Gizmoçš„å¥æŸ„å称。调用此æ’件的活动工具。"
+msgstr "é‡å†™æ­¤æ–¹æ³•以æä¾› Gizmo çš„å¥æŸ„å称。调用此æ’件的活动工具。"
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid ""
"Gets actual value of a handle from gizmo. Called for this plugin's active "
"gizmos."
-msgstr "从Gizmo获å–奿Ÿ„的实际值。调用此æ’件的活动工具。"
+msgstr "从 Gizmo 获å–奿Ÿ„的实际值。调用此æ’件的活动工具。"
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid ""
@@ -28264,7 +28325,7 @@ msgstr "æ›´æ–°å¥æŸ„åŽæ›´æ–°å…¶å€¼ã€‚调用此æ’件的活动工具。"
#: doc/classes/EditorSpinSlider.xml
msgid "Godot editor's control for editing numeric values."
-msgstr "Godot编辑器用于编辑数值的控件。"
+msgstr "Godot 编辑器用于编辑数值的控件。"
#: doc/classes/EditorSpinSlider.xml
msgid ""
@@ -28336,8 +28397,8 @@ msgid ""
"Fetches new changes from the remote, but doesn't write changes to the "
"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
-"ä»Žè¿œç¨‹ä»“åº“ä¸­æŠ“å–æ–°ä¿®æ”¹ï¼Œä½†ä¸å°†ä¿®æ”¹å†™å…¥å½“å‰å·¥ä½œç›®å½•。与 [code]git fetch[/"
-"code] 等效。"
+"ä»Žè¿œç¨‹ä»“åº“ä¸­æŠ“å–æ–°ä¿®æ”¹ï¼Œä½†ä¸å°†ä¿®æ”¹å†™å…¥å½“å‰å·¥ä½œç›®å½•。相当于 [code]git fetch[/"
+"code]。"
#: doc/classes/EditorVCSInterface.xml
msgid ""
@@ -28358,7 +28419,7 @@ msgid ""
"file path, returns a file diff, and if it is a commit identifier, then "
"returns a commit diff."
msgstr ""
-"返回 [Dictionary] 字典项的 [Array] 数组(请å‚阅 [method create_diff_file]ã€"
+"返回 [Dictionary] 字典项的 [Array] æ•°ç»„ï¼ˆè§ [method create_diff_file]ã€"
"[method create_diff_hunk]ã€[method create_diff_line]ã€[method "
"add_line_diffs_into_diff_hunk]ã€[method add_diff_hunks_into_diff_file]),æ¯"
"一项都包å«ä¸€ä¸ªå·®å¼‚的信æ¯ã€‚如果 [code]identifier[/code] 是文件路径,则返回文件"
@@ -28370,25 +28431,25 @@ msgid ""
"each containing a line diff between a file at [code]file_path[/code] and the "
"[code]text[/code] which is passed in."
msgstr ""
-"返回 [Dictionary] 字典项的 [Array] 数组(请å‚阅 [method create_diff_hunk]),"
-"æ¯ä¸€é¡¹éƒ½åŒ…å«ä½äºŽ [code]file_path[/code] 的文件与传入的 [code]text[/code] 之间"
-"çš„å•行差异。"
+"返回 [Dictionary] 字典项的 [Array] æ•°ç»„ï¼ˆè§ [method create_diff_hunk]),æ¯ä¸€"
+"项都包å«ä½äºŽ [code]file_path[/code] 的文件与传入的 [code]text[/code] 之间的å•"
+"行差异。"
#: doc/classes/EditorVCSInterface.xml
msgid ""
"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
"each containing the status data of every modified file in the project folder."
msgstr ""
-"返回 [Dictionary] 字典项的 [Array] 数组(请å‚阅 [method "
-"create_status_file]),æ¯ä¸€é¡¹éƒ½åŒ…å«é¡¹ç›®æ–‡ä»¶å¤¹ä¸­æ¯ä¸ªå·²ä¿®æ”¹çš„æ–‡ä»¶çš„çŠ¶æ€æ•°æ®ã€‚"
+"返回 [Dictionary] 字典项的 [Array] æ•°ç»„ï¼ˆè§ [method create_status_file]),æ¯"
+"一项都包å«é¡¹ç›®æ–‡ä»¶å¤¹ä¸­æ¯ä¸ªå·²ä¿®æ”¹çš„æ–‡ä»¶çš„çŠ¶æ€æ•°æ®ã€‚"
#: doc/classes/EditorVCSInterface.xml
msgid ""
"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
"containing the data for a past commit."
msgstr ""
-"返回 [Dictionary] 字典项的 [Array] 数组(请å‚阅 [method create_commit]),æ¯"
-"一项都包å«ä¸€ä¸ªè¿‡åŽ»æäº¤çš„æ•°æ®ã€‚"
+"返回 [Dictionary] 字典项的 [Array] æ•°ç»„ï¼ˆè§ [method create_commit]),æ¯ä¸€é¡¹"
+"都包å«ä¸€ä¸ªè¿‡åŽ»æäº¤çš„æ•°æ®ã€‚"
#: doc/classes/EditorVCSInterface.xml
msgid ""
@@ -28590,19 +28651,19 @@ msgid ""
"This class is used internally by the editor inspector and script debugger, "
"but can also be used in plugins to pass and display objects as their IDs."
msgstr ""
-"实用类,它拥有对[Object]实例的内部标识符的引用,该标识符由[method Object."
-"get_instance_id]给出。这个IDå¯ä»¥é€šè¿‡[method @GDScript.instance_from_id]æ¥æ£€ç´¢"
-"对象实例。\n"
+"实用类,它拥有对 [Object] 实例的内部标识符的引用,该标识符由 [method Object."
+"get_instance_id] 给出。这个 ID å¯ä»¥é€šè¿‡ [method @GDScript.instance_from_id] "
+"æ¥æ£€ç´¢å¯¹è±¡å®žä¾‹ã€‚\n"
"这个类在内部被编辑器检查器和脚本调试器使用,但也å¯ä»¥åœ¨æ’件中使用,以传递和显"
-"示对象作为它们的ID。"
+"示对象作为它们的 ID。"
#: doc/classes/EncodedObjectAsID.xml
msgid ""
"The [Object] identifier stored in this [EncodedObjectAsID] instance. The "
"object instance can be retrieved with [method @GDScript.instance_from_id]."
msgstr ""
-"存储在这个[EncodedObjectAsID]实例中的[Object]标识符。对象实例å¯ä»¥ç”¨[method "
-"@GDScript.instance_from_id]检索。"
+"存储在这个 [EncodedObjectAsID] 实例中的 [Object] 标识符。对象实例å¯ä»¥ç”¨ "
+"[method @GDScript.instance_from_id] 检索。"
#: doc/classes/Engine.xml
msgid "Access to engine properties."
@@ -28613,7 +28674,7 @@ msgid ""
"The [Engine] singleton allows you to query and modify the project's run-time "
"parameters, such as frames per second, time scale, and others."
msgstr ""
-"[Engine]å•例使您å¯ä»¥æŸ¥è¯¢å’Œä¿®æ”¹é¡¹ç›®çš„è¿è¡Œæ—¶å‚数,例如æ¯ç§’帧数,时间范围等。"
+"[Engine] å•例使您å¯ä»¥æŸ¥è¯¢å’Œä¿®æ”¹é¡¹ç›®çš„è¿è¡Œæ—¶å‚数,例如æ¯ç§’帧数,时间范围等。"
#: doc/classes/Engine.xml
msgid ""
@@ -28809,7 +28870,8 @@ msgid ""
"Returns [code]true[/code] if a singleton with given [code]name[/code] exists "
"in global scope."
msgstr ""
-"如果全局范围内存在具有给定[code]name[/code]çš„å•例,则返回 [code]true[/code]。"
+"如果全局范围内存在具有给定 [code]name[/code] çš„å•例,则返回 [code]true[/"
+"code]。"
#: doc/classes/Engine.xml
msgid ""
@@ -28838,7 +28900,7 @@ msgid ""
"the editor and when running the project from the editor, but it will "
"evaluate to [code]false[/code] when the code is run from an exported project."
msgstr ""
-"为 [code]true[/code] æ—¶è¡¨ç¤ºè¯¥è„šæœ¬ç›®å‰æ­£åœ¨ç¼–辑器内è¿è¡Œã€‚这对 [code]tool[/"
+"如果为 [code]true[/code]ï¼Œè¡¨ç¤ºè¯¥è„šæœ¬ç›®å‰æ­£åœ¨ç¼–辑器内è¿è¡Œã€‚这对 [code]tool[/"
"code] 脚本很有用,å¯ä»¥åœ¨ç‰¹å®šæ¡ä»¶ä¸‹ç»˜åˆ¶ç¼–辑器辅助内容,或者防止在编辑器中æ„外"
"地è¿è¡Œä¼šå½±å“场景状æ€çš„“游æˆâ€ä»£ç ã€‚\n"
"[codeblock]\n"
@@ -28920,7 +28982,7 @@ msgid ""
"running a project from the editor."
msgstr ""
"如果为 [code]false[/code]ï¼Œåˆ™åœæ­¢æ‰“å°é”™è¯¯å’Œè­¦å‘Šä¿¡æ¯åˆ°æŽ§åˆ¶å°å’Œç¼–辑器输出日志。"
-"è¿™å¯ä»¥ç”¨æ¥åœ¨å•元测试套件è¿è¡ŒæœŸé—´éšè—错误和警告信æ¯ã€‚这个属性等åŒäºŽ [member "
+"è¿™å¯ä»¥ç”¨æ¥åœ¨å•元测试套件è¿è¡ŒæœŸé—´éšè—错误和警告信æ¯ã€‚这个属性相当于 [member "
"ProjectSettings.application/run/disable_stderr] 项目设置。\n"
"[b]警告:[/b]如果你在项目的任æ„ä½ç½®å°†å…¶è®¾ç½®ä¸º [code]false[/code],é‡è¦çš„错误"
"ä¿¡æ¯å¯èƒ½ä¼šè¢«éšè—,å³ä½¿å®ƒä»¬æ˜¯ç”±å…¶ä»–脚本触å‘。如果在 [code]tool[/code] 脚本中把"
@@ -29055,17 +29117,17 @@ msgid ""
"[code]adjustment_*[/code] properties will have no effect on the rendered "
"scene."
msgstr ""
-"如果 [code]true[/code],则å¯ç”¨æ­¤èµ„æºæä¾›çš„ [code]adjusting_*[/code] 属性。如"
-"æžœ[code]false[/code],对[code]adjustment_*[/code]属性的修改将ä¸ä¼šå¯¹æ¸²æŸ“的场景"
-"产生影å“。"
+"如果为 [code]true[/code],则å¯ç”¨æ­¤èµ„æºæä¾›çš„ [code]adjusting_*[/code] 属性。"
+"如果为 [code]false[/code],对[code]adjustment_*[/code]属性的修改将ä¸ä¼šå¯¹æ¸²æŸ“"
+"的场景产生影å“。"
#: doc/classes/Environment.xml
msgid ""
"The global color saturation value of the rendered scene (default value is "
"1). Effective only if [code]adjustment_enabled[/code] is [code]true[/code]."
msgstr ""
-"渲染场景的全局色彩饱和度值,默认值为1ã€‚åªæœ‰åœ¨[code]adjustment_enabled[/code]"
-"为 [code]true[/code] æ—¶æ‰æœ‰æ•ˆã€‚"
+"渲染场景的全局色彩饱和度值(默认值为 1ï¼‰ã€‚åªæœ‰åœ¨ [code]adjustment_enabled[/"
+"code] 为 [code]true[/code] æ—¶æ‰æœ‰æ•ˆã€‚"
#: doc/classes/Environment.xml
msgid "The ambient light's [Color]."
@@ -29100,8 +29162,8 @@ msgid ""
"determine the exposure setting to adapt to the scene's illumination and the "
"observed light."
msgstr ""
-"如果[code]true[/code],å¯ç”¨åœºæ™¯æ¸²æŸ“器的色调映射自动æ›å…‰æ¨¡å¼ã€‚如果[code]true[/"
-"code],渲染器将自动确定æ›å…‰è®¾ç½®ï¼Œä»¥é€‚应场景的照明和观察到的光线。"
+"如果为 [code]true[/code],å¯ç”¨åœºæ™¯æ¸²æŸ“器的色调映射自动æ›å…‰æ¨¡å¼ã€‚如果为 "
+"[code]true[/code],渲染器将自动确定æ›å…‰è®¾ç½®ï¼Œä»¥é€‚应场景的照明和观察到的光线。"
#: doc/classes/Environment.xml
msgid "The maximum luminance value for the auto exposure."
@@ -29125,21 +29187,21 @@ msgstr "自动æ›å…‰æ•ˆæžœçš„速度。影å“相机执行自动æ›å…‰æ‰€éœ€çš„æ—¶
#: doc/classes/Environment.xml
msgid "The ID of the camera feed to show in the background."
-msgstr "在背景中显示的相机æºçš„ID。"
+msgstr "在背景中显示的相机æºçš„ ID。"
#: doc/classes/Environment.xml
msgid ""
"The maximum layer ID to display. Only effective when using the [constant "
"BG_CANVAS] background mode."
-msgstr "è¦æ˜¾ç¤ºçš„æœ€å¤§å›¾å±‚IDã€‚åªæœ‰åœ¨ä½¿ç”¨ [constant BG_CANVAS] èƒŒæ™¯æ¨¡å¼æ—¶æœ‰æ•ˆã€‚"
+msgstr "è¦æ˜¾ç¤ºçš„æœ€å¤§å›¾å±‚ IDã€‚åªæœ‰åœ¨ä½¿ç”¨ [constant BG_CANVAS] èƒŒæ™¯æ¨¡å¼æ—¶æœ‰æ•ˆã€‚"
#: doc/classes/Environment.xml
msgid ""
"The [Color] displayed for clear areas of the scene. Only effective when "
"using the [constant BG_COLOR] or [constant BG_COLOR_SKY] background modes)."
msgstr ""
-"场景中清除区域显示的[Color]。仅在使用[constant BG_COLOR]或[constant "
-"BG_COLOR_SKY]èƒŒæ™¯æ¨¡å¼æ—¶æœ‰æ•ˆã€‚"
+"场景中清除区域显示的 [Color]。仅在使用 [constant BG_COLOR] 或 [constant "
+"BG_COLOR_SKY] èƒŒæ™¯æ¨¡å¼æ—¶æœ‰æ•ˆã€‚"
#: doc/classes/Environment.xml
msgid "The power of the light emitted by the background."
@@ -29147,7 +29209,7 @@ msgstr "背景å‘出的光的功率。"
#: doc/classes/Environment.xml
msgid "The background mode. See [enum BGMode] for possible values."
-msgstr "背景模å¼ã€‚请å‚阅[enum BGMode]了解å¯èƒ½çš„值。"
+msgstr "背景模å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum BGMode]。"
#: doc/classes/Environment.xml
msgid "The [Sky] resource defined as background."
@@ -29180,7 +29242,7 @@ msgstr "è¿œæ™¯æ¨¡ç³Šæ•ˆæžœå½±å“æ¸²æŸ“çš„è·ç¦»ã€‚"
#: doc/classes/Environment.xml
msgid "If [code]true[/code], enables the depth-of-field far blur effect."
-msgstr "如果[code]true[/code],å¯ç”¨æ™¯æ·±è¿œæ™¯æ¨¡ç³Šæ•ˆæžœã€‚"
+msgstr "如果为 [code]true[/code],å¯ç”¨æ™¯æ·±è¿œæ™¯æ¨¡ç³Šæ•ˆæžœã€‚"
#: doc/classes/Environment.xml
msgid ""
@@ -29205,7 +29267,7 @@ msgstr "è¿‘ä¼¼æ¨¡ç³Šæ•ˆæžœå½±å“æ¸²æŸ“的地方与相机的è·ç¦»ã€‚"
#: doc/classes/Environment.xml
msgid "If [code]true[/code], enables the depth-of-field near blur effect."
-msgstr "如果[code]true[/code],å¯ç”¨æ™¯æ·±è¿‘模糊效果。"
+msgstr "如果为 [code]true[/code],å¯ç”¨æ™¯æ·±è¿‘模糊效果。"
#: doc/classes/Environment.xml
msgid ""
@@ -29221,7 +29283,7 @@ msgstr "近模糊和无模糊区域之间的过渡长度。"
#: doc/classes/Environment.xml
msgid "The fog's [Color]."
-msgstr "雾的[Color]。"
+msgstr "雾的 [Color]。"
#: doc/classes/Environment.xml
msgid "The fog's depth starting distance from the camera."
@@ -29247,8 +29309,8 @@ msgid ""
"The fog's depth end distance from the camera. If this value is set to 0, it "
"will be equal to the current camera's [member Camera.far] value."
msgstr ""
-"é›¾çš„æ·±åº¦ç»ˆç‚¹ä¸Žæ‘„åƒæœºçš„è·ç¦»ã€‚如果此值被设置为0ï¼Œåˆ™ç­‰äºŽå½“å‰æ‘„åƒæœºçš„[member "
-"Camera.far]值。"
+"é›¾çš„æ·±åº¦ç»ˆç‚¹ä¸Žæ‘„åƒæœºçš„è·ç¦»ã€‚如果此值被设置为0ï¼Œåˆ™ç­‰äºŽå½“å‰æ‘„åƒæœºçš„ [member "
+"Camera.far] 值。"
#: doc/classes/Environment.xml
msgid ""
@@ -29256,8 +29318,8 @@ msgid ""
"and/or [member fog_depth_enabled] must be set to [code]true[/code] to "
"actually display fog."
msgstr ""
-"如果[code]true[/code],则å¯ç”¨é›¾åŒ–效果。必须将[member fog_height_enabled]å’Œ/或"
-"[member fog_depth_enabled]设置为 [code]true[/code],æ‰èƒ½å®žé™…显示雾气。"
+"如果为 [code]true[/code],则å¯ç”¨é›¾åŒ–效果。必须将 [member fog_height_enabled] "
+"å’Œ/或 [member fog_depth_enabled] 设置为 [code]true[/code],æ‰èƒ½å®žé™…显示雾气。"
#: doc/classes/Environment.xml
msgid ""
@@ -29273,8 +29335,8 @@ msgid ""
"performance cost compared to a dedicated shader."
msgstr ""
"如果为 [code]true[/code],则å¯ç”¨é«˜åº¦é›¾åŒ–效果。å¯ç”¨åŽï¼Œæ— è®ºä¸Žç›¸æœºçš„è·ç¦»æœ‰å¤š"
-"远,雾气都会出现在规定的高度范围内。这å¯ä»¥ç”¨æ¥æ¨¡æ‹Ÿ \"深水 \"效果,与专用ç€è‰²"
-"å™¨ç›¸æ¯”ï¼Œæ€§èƒ½æˆæœ¬æ›´ä½Žã€‚"
+"远,雾气都会出现在规定的高度范围内。这å¯ä»¥ç”¨æ¥æ¨¡æ‹Ÿâ€œæ·±æ°´â€æ•ˆæžœï¼Œä¸Žä¸“用ç€è‰²å™¨ç›¸"
+"æ¯”ï¼Œæ€§èƒ½æˆæœ¬æ›´ä½Žã€‚"
#: doc/classes/Environment.xml
msgid ""
@@ -29282,8 +29344,8 @@ msgid ""
"value is greater than [member fog_height_min], fog will be displayed from "
"bottom to top. Otherwise, it will be displayed from top to bottom."
msgstr ""
-"雾气高度最强的Yåæ ‡ã€‚如果这个值大于[member fog_height_min],雾气将从下往上显"
-"示。å¦åˆ™ï¼Œå°†ä»Žä¸Šåˆ°ä¸‹æ˜¾ç¤ºã€‚"
+"雾气高度最强的 Y åæ ‡ã€‚如果这个值大于 [member fog_height_min],雾气将从下往上"
+"显示。å¦åˆ™ï¼Œå°†ä»Žä¸Šåˆ°ä¸‹æ˜¾ç¤ºã€‚"
#: doc/classes/Environment.xml
msgid ""
@@ -29291,8 +29353,8 @@ msgid ""
"value is greater than [member fog_height_max], fog will be displayed from "
"top to bottom. Otherwise, it will be displayed from bottom to top."
msgstr ""
-"雾气高度最弱的Yåæ ‡ã€‚如果这个值大于[member fog_height_max],雾气将从上到下显"
-"示。å¦åˆ™ï¼Œå°†ä»Žä¸‹å¾€ä¸Šæ˜¾ç¤ºã€‚"
+"雾气高度最弱的 Y åæ ‡ã€‚如果这个值大于 [member fog_height_max],雾气将从上到下"
+"显示。å¦åˆ™ï¼Œå°†ä»Žä¸‹å¾€ä¸Šæ˜¾ç¤ºã€‚"
#: doc/classes/Environment.xml
msgid ""
@@ -29305,7 +29367,7 @@ msgstr ""
#: doc/classes/Environment.xml
msgid "The depth fog's [Color] when looking towards the sun."
-msgstr "æœå¤ªé˜³çœ‹æ—¶ï¼Œæ·±é›¾çš„[Color]。"
+msgstr "æœå¤ªé˜³çœ‹æ—¶ï¼Œæ·±é›¾çš„ [Color]。"
#: doc/classes/Environment.xml
msgid ""
@@ -29318,8 +29380,8 @@ msgid ""
"Enables fog's light transmission effect. If [code]true[/code], light will be "
"more visible in the fog to simulate light scattering as in real life."
msgstr ""
-"å¯ç”¨é›¾çš„é€å…‰æ•ˆæžœã€‚如果[code]true[/code],光线在雾中会更加明显,以模拟现实生活"
-"中的光散射。"
+"å¯ç”¨é›¾çš„é€å…‰æ•ˆæžœã€‚如果为 [code]true[/code],光线在雾中会更加明显,以模拟现实"
+"生活中的光散射。"
#: doc/classes/Environment.xml
msgid ""
@@ -29329,8 +29391,8 @@ msgid ""
"GPU supports the [code]GL_EXT_gpu_shader4[/code] extension."
msgstr ""
"以牺牲性能为代价,消除由更高级别采样产生的å—状效应。\n"
-"[b]注æ„:[/b]使用 GLES2æ¸²æŸ“å™¨æ—¶ï¼Œåªæœ‰GPUæ”¯æŒ [code]GL_EXT_gpu_shader4[/code] "
-"扩展时æ‰å¯ç”¨ã€‚"
+"[b]注æ„:[/b]使用 GLES2 æ¸²æŸ“å™¨æ—¶ï¼Œåªæœ‰ GPU æ”¯æŒ [code]GL_EXT_gpu_shader4[/"
+"code] 扩展时æ‰å¯ç”¨ã€‚"
#: doc/classes/Environment.xml
msgid "The glow blending mode."
@@ -29491,7 +29553,7 @@ msgstr "å±å¹•空间å射的最大步数。数值越高,速度越慢。"
msgid ""
"If [code]true[/code], screen-space reflections will take the material "
"roughness into account."
-msgstr "如果 [code]true[/code],å±å¹•空间å射将考虑æè´¨ç²—糙度。"
+msgstr "如果为 [code]true[/code],å±å¹•空间å射将考虑æè´¨ç²—糙度。"
#: doc/classes/Environment.xml
msgid ""
@@ -29507,14 +29569,14 @@ msgid ""
"The screen-space ambient occlusion bias. This should be kept high enough to "
"prevent \"smooth\" curves from being affected by ambient occlusion."
msgstr ""
-"å±å¹•空间环境光é®è”½åå·®ã€‚è¯¥å€¼åº”ä¿æŒåœ¨è¶³å¤Ÿé«˜çš„æ°´å¹³ï¼Œä»¥é˜²æ­¢â€œå¹³æ»‘â€æ›²çº¿å—到环境光"
+"å±å¹•空间环境光é®è”½åç½®ã€‚è¯¥å€¼åº”ä¿æŒåœ¨è¶³å¤Ÿé«˜çš„æ°´å¹³ï¼Œä»¥é˜²æ­¢â€œå¹³æ»‘â€æ›²çº¿å—到环境光"
"é®è”½çš„å½±å“。"
#: doc/classes/Environment.xml
msgid ""
"The screen-space ambient occlusion blur quality. See [enum SSAOBlur] for "
"possible values."
-msgstr "å±å¹•空间环境光é®è”½è´¨é‡ã€‚å¯èƒ½çš„值请å‚阅 [enum SSAOBlur]。"
+msgstr "å±å¹•空间环境光é®è”½è´¨é‡ã€‚å¯èƒ½çš„å–å€¼è§ [enum SSAOBlur]。"
#: doc/classes/Environment.xml
msgid "The screen-space ambient occlusion color."
@@ -29534,8 +29596,8 @@ msgid ""
"a costly effect and should be disabled first when running into performance "
"issues."
msgstr ""
-"如果[code]true[/code],å¯ç”¨å±å¹•空间环境光é®è”½æ•ˆæžœã€‚这将使物体的角è½å’Œç©ºæ´žå˜"
-"暗,以模拟现实生活中环境光无法到达整个物体。这对于å°åž‹çš„动æ€ç‰©ä½“æ¥è¯´æ•ˆæžœå¾ˆ"
+"如果为 [code]true[/code],å¯ç”¨å±å¹•空间环境光é®è”½æ•ˆæžœã€‚这将使物体的角è½å’Œç©ºæ´ž"
+"å˜æš—,以模拟现实生活中环境光无法到达整个物体。这对于å°åž‹çš„动æ€ç‰©ä½“æ¥è¯´æ•ˆæžœå¾ˆ"
"å¥½ï¼Œä½†åœ¨å¤§åž‹é™æ€ç‰©ä½“上,烘焙的照明或环境光é®è”½çº¹ç†ä¼šæ›´å¥½åœ°æ˜¾ç¤ºçŽ¯å¢ƒå…‰é®è”½ã€‚è¿™"
"是一个昂贵的效果,当é‡åˆ°æ€§èƒ½é—®é¢˜æ—¶ï¼Œåº”该首先ç¦ç”¨ã€‚"
@@ -29543,13 +29605,13 @@ msgstr ""
msgid ""
"The primary screen-space ambient occlusion intensity. See also [member "
"ssao_radius]."
-msgstr "主è¦çš„å±å¹•空间环境光é®è”½å¼ºåº¦ã€‚å‚阅[member ssao_radius]。"
+msgstr "主å±å¹•的空间环境光é®è”½å¼ºåº¦ã€‚å¦è¯·å‚阅 [member ssao_radius]。"
#: doc/classes/Environment.xml
msgid ""
"The secondary screen-space ambient occlusion intensity. See also [member "
"ssao_radius2]."
-msgstr "主è¦çš„å±å¹•空间环境光é®è”½å¼ºåº¦ã€‚å‚阅 [member ssao_radius]。"
+msgstr "次å±å¹•的空间环境光é®è”½å¼ºåº¦ã€‚å¦è¯·å‚阅 [member ssao_radius2]。"
#: doc/classes/Environment.xml
msgid ""
@@ -29626,8 +29688,8 @@ msgid ""
"Clears the background using the clear color defined in [member "
"ProjectSettings.rendering/environment/default_clear_color]."
msgstr ""
-"使用[member ProjectSettings.rendering/environment/default_clear_color]中定义"
-"的底色清除背景。"
+"使用 [member ProjectSettings.rendering/environment/default_clear_color] 中定"
+"义的底色清除背景。"
#: doc/classes/Environment.xml
msgid "Clears the background using a custom clear color."
@@ -29644,13 +29706,13 @@ msgid ""
"BG_SKY] and should be preferred in scenes where reflections can be visible, "
"but the sky itself never is (e.g. top-down camera)."
msgstr ""
-"ä½¿ç”¨è‡ªå®šä¹‰çš„é€æ˜Žé¢œè‰²æ¸…除背景,并å…许定义天空的阴影和åå°„ã€‚è¿™ç§æ¨¡å¼æ¯”"
-"[constant BG_SKY]ç¨å¿«ï¼Œåº”是在å¯ä»¥çœ‹åˆ°å射,但天空本身ä¸å¯è§çš„场景中的首选,例"
-"如,自上而下的相机。"
+"ä½¿ç”¨è‡ªå®šä¹‰çš„é€æ˜Žé¢œè‰²æ¸…除背景,并å…许定义天空的阴影和åå°„ã€‚è¿™ç§æ¨¡å¼æ¯” "
+"[constant BG_SKY] ç¨å¿«ï¼Œåº”是在å¯ä»¥çœ‹åˆ°å射,但天空本身ä¸å¯è§çš„场景中的首选"
+"(例如,自上而下的相机)。"
#: doc/classes/Environment.xml
msgid "Displays a [CanvasLayer] in the background."
-msgstr "在背景中显示[CanvasLayer]。"
+msgstr "在背景中显示 [CanvasLayer]。"
#: doc/classes/Environment.xml
msgid "Displays a camera feed in the background."
@@ -29658,7 +29720,7 @@ msgstr "在背景中显示相机æºã€‚"
#: doc/classes/Environment.xml
msgid "Represents the size of the [enum BGMode] enum."
-msgstr "表示[enum BGMode]枚举的大å°ã€‚"
+msgstr "表示 [enum BGMode] 枚举的大å°ã€‚"
#: doc/classes/Environment.xml
msgid ""
@@ -29763,15 +29825,15 @@ msgstr "å±å¹•ç©ºé—´çŽ¯å¢ƒé®æŒ¡æ•ˆæžœä¸æ¨¡ç³Šï¼ˆæœ€å¿«ï¼‰ã€‚"
#: doc/classes/Environment.xml
msgid "1×1 blur for the screen-space ambient occlusion effect."
-msgstr "1×1模糊的å±å¹•ç©ºé—´çŽ¯å¢ƒé®æŒ¡æ•ˆæžœã€‚"
+msgstr "1×1 模糊的å±å¹•ç©ºé—´çŽ¯å¢ƒé®æŒ¡æ•ˆæžœã€‚"
#: doc/classes/Environment.xml
msgid "2×2 blur for the screen-space ambient occlusion effect."
-msgstr "2×2模糊的å±å¹•ç©ºé—´çŽ¯å¢ƒé®æŒ¡æ•ˆæžœã€‚"
+msgstr "2×2 模糊的å±å¹•ç©ºé—´çŽ¯å¢ƒé®æŒ¡æ•ˆæžœã€‚"
#: doc/classes/Environment.xml
msgid "3×3 blur for the screen-space ambient occlusion effect (slowest)."
-msgstr "3×3模糊的å±å¹•ç©ºé—´çŽ¯å¢ƒé®æŒ¡æ•ˆæžœï¼ˆæœ€æ…¢ï¼‰ã€‚"
+msgstr "3×3 模糊的å±å¹•ç©ºé—´çŽ¯å¢ƒé®æŒ¡æ•ˆæžœï¼ˆæœ€æ…¢ï¼‰ã€‚"
#: doc/classes/Environment.xml
msgid "Low quality for the screen-space ambient occlusion effect (fastest)."
@@ -29787,7 +29849,7 @@ msgstr "高质é‡çš„å±å¹•ç©ºé—´çŽ¯å¢ƒé®æŒ¡æ•ˆæžœï¼ˆæœ€æ…¢ï¼‰ã€‚"
#: doc/classes/Expression.xml
msgid "A class that stores an expression you can execute."
-msgstr "一个存储你å¯ä»¥æ‰§è¡Œçš„表达å¼çš„类。"
+msgstr "存储你å¯ä»¥æ‰§è¡Œçš„表达å¼çš„类。"
#: doc/classes/Expression.xml
msgid ""
@@ -29816,9 +29878,9 @@ msgid ""
msgstr ""
"表达å¼å¯ä»¥ç”±ä»»ä½•算术è¿ç®—ã€å†…置数学函数调用ã€ä¼ é€’实例的方法调用或内置类型构造"
"调用组æˆã€‚\n"
-"ä¸€ä¸ªä½¿ç”¨å†…ç½®æ•°å­¦å‡½æ•°çš„è¡¨è¾¾å¼æ–‡æœ¬ç¤ºä¾‹å¯ä»¥æ˜¯[code]sqrt(pow(3,2)+pow(4,2))[/"
+"ä¸€ä¸ªä½¿ç”¨å†…ç½®æ•°å­¦å‡½æ•°çš„è¡¨è¾¾å¼æ–‡æœ¬ç¤ºä¾‹å¯ä»¥æ˜¯ [code]sqrt(pow(3,2)+pow(4,2))[/"
"code]。\n"
-"在下é¢çš„例å­ä¸­ï¼Œæˆ‘们使用一个[LineEdit]节点æ¥å†™æˆ‘们的表达å¼å¹¶æ˜¾ç¤ºç»“果。\n"
+"在下é¢çš„例å­ä¸­ï¼Œæˆ‘们使用 [LineEdit] 节点æ¥å†™æˆ‘们的表达å¼å¹¶æ˜¾ç¤ºç»“果。\n"
"[codeblock]\n"
"onready var expression = Expression.new()\n"
"\n"
@@ -29843,18 +29905,18 @@ msgid ""
"If you defined input variables in [method parse], you can specify their "
"values in the inputs array, in the same order."
msgstr ""
-"执行之å‰ç”±[method parse]è§£æžçš„表达å¼ï¼Œå¹¶è¿”回结果。在使用返回的对象之å‰ï¼Œåº”该"
-"通过调用 [method has_execute_failed] æ¥æ£€æŸ¥æ–¹æ³•是å¦å¤±è´¥ã€‚\n"
+"执行之å‰ç”± [method parse] è§£æžçš„表达å¼ï¼Œå¹¶è¿”回结果。在使用返回的对象之å‰ï¼Œåº”"
+"该通过调用 [method has_execute_failed] æ¥æ£€æŸ¥æ–¹æ³•是å¦å¤±è´¥ã€‚\n"
"如果你在 [method parse] 中定义了输入å˜é‡ï¼Œä½ å¯ä»¥åœ¨è¾“å…¥æ•°ç»„ä¸­ä»¥åŒæ ·çš„é¡ºåºæŒ‡å®š"
"它们的值。"
#: doc/classes/Expression.xml
msgid "Returns the error text if [method parse] has failed."
-msgstr "如果[method parse]失败了,返回错误文本。"
+msgstr "如果 [method parse] 失败了,返回错误文本。"
#: doc/classes/Expression.xml
msgid "Returns [code]true[/code] if [method execute] has failed."
-msgstr "如果[method execute]失败,返回 [code]true[/code]。"
+msgstr "如果 [method execute] 失败,返回 [code]true[/code]。"
#: doc/classes/Expression.xml
msgid ""
@@ -29863,13 +29925,13 @@ msgid ""
"expression with [code]input_names[/code], so that you can bind them when it "
"gets executed."
msgstr ""
-"è§£æžè¡¨è¾¾å¼å¹¶è¿”回一个[enum Error]代ç ã€‚\n"
-"ä½ å¯ä»¥é€‰æ‹©ç”¨[code]input_names[/code]指定å¯èƒ½å‡ºçŽ°åœ¨è¡¨è¾¾å¼ä¸­çš„å˜é‡å称,这样你"
-"å°±å¯ä»¥åœ¨è¡¨è¾¾å¼è¢«æ‰§è¡Œæ—¶ç»‘定它们。"
+"è§£æžè¡¨è¾¾å¼å¹¶è¿”回一个 [enum Error] 代ç ã€‚\n"
+"ä½ å¯ä»¥é€‰æ‹©ç”¨ [code]input_names[/code] 指定å¯èƒ½å‡ºçŽ°åœ¨è¡¨è¾¾å¼ä¸­çš„å˜é‡å称,这样"
+"ä½ å°±å¯ä»¥åœ¨è¡¨è¾¾å¼è¢«æ‰§è¡Œæ—¶ç»‘定它们。"
#: doc/classes/ExternalTexture.xml
msgid "Enable OpenGL ES external texture extension."
-msgstr "å¯ç”¨OpenGL ESå¤–éƒ¨çº¹ç†æ‰©å±•。"
+msgstr "å¯ç”¨ OpenGL ES å¤–éƒ¨çº¹ç†æ‰©å±•。"
#: doc/classes/ExternalTexture.xml
msgid ""
@@ -29878,10 +29940,10 @@ msgid ""
"OES_EGL_image_external.txt]OES_EGL_image_external[/url].\n"
"[b]Note:[/b] This is only supported for Android platforms."
msgstr ""
-"å¯ç”¨å¯¹OpenGL ESå¤–éƒ¨çº¹ç†æ‰©å±•的支æŒï¼Œå¦‚[url=https://www.khronos.org/registry/"
-"OpenGL/extensions/OES/OES_EGL_image_external.txt]OES_EGL_image_external[/url]"
-"所定义。\n"
-"[b]注æ„:[/b]è¿™åªæ”¯æŒAndroidå¹³å°ã€‚"
+"å¯ç”¨å¯¹ OpenGL ES å¤–éƒ¨çº¹ç†æ‰©å±•的支æŒï¼Œå¦‚ [url=https://www.khronos.org/"
+"registry/OpenGL/extensions/OES/OES_EGL_image_external."
+"txt]OES_EGL_image_external[/url] 所定义。\n"
+"[b]注æ„:[/b]è¿™åªæ”¯æŒ Android å¹³å°ã€‚"
#: doc/classes/ExternalTexture.xml
msgid "Returns the external texture name."
@@ -30131,7 +30193,7 @@ msgstr ""
msgid ""
"Returns an MD5 String representing the file at the given path or an empty "
"[String] on failure."
-msgstr "返回一个给定路径文件的MD5字符串,如果失败则返回一个空的[String]。"
+msgstr "返回一个给定路径文件的 MD5 字符串,如果失败则返回一个空的 [String]。"
#: doc/classes/File.xml
msgid ""
@@ -30140,9 +30202,9 @@ msgid ""
"timestamp can be converted to datetime by using [method OS."
"get_datetime_from_unix_time]."
msgstr ""
-"返回unixæ ¼å¼çš„æ—¶é—´æˆ³[code]file[/code]为文件的最åŽä¿®æ”¹æ—¶é—´ï¼Œæˆ–者返回一个"
-"[String]\"ERROR IN [code]file[/code]\"。这个unix时间戳å¯ä»¥é€šè¿‡ä½¿ç”¨[method OS."
-"get_datetime_from_unix_time]转æ¢ä¸ºæ•°æ®æ—¶é—´ã€‚"
+"返回文件 [code]file[/code] 的最åŽä¿®æ”¹æ—¶é—´çš„ unix æ ¼å¼çš„æ—¶é—´æˆ³ï¼Œæˆ–者返回一个 "
+"[String] \"ERROR IN [code]file[/code]\"。这个 unix 时间戳å¯ä»¥é€šè¿‡ä½¿ç”¨ "
+"[method OS.get_datetime_from_unix_time] 转æ¢ä¸ºæ•°æ®æ—¶é—´ã€‚"
#: doc/classes/File.xml
msgid ""
@@ -30368,8 +30430,8 @@ msgid ""
"store the length of the string).\n"
"Text will be encoded as UTF-8."
msgstr ""
-"将给定的[String]以Pascalæ ¼å¼å­˜å‚¨åœ¨æ–‡ä»¶ä¸­ï¼ˆä¾‹å¦‚,也将字符串长度存储)。\n"
-"文本将被编ç ä¸ºUTF-8。"
+"将给定的 [String] 以 Pascal æ ¼å¼å­˜å‚¨åœ¨æ–‡ä»¶ä¸­ï¼ˆå³åŒæ—¶å­˜å‚¨å­—符串的长度)。\n"
+"将使用 UTF-8 ç¼–ç æ–‡æœ¬ã€‚"
#: doc/classes/File.xml
msgid "Stores a floating-point number in the file."
@@ -30432,8 +30494,8 @@ msgstr ""
"%E5%AD%97%E8%8A%82%E5%BA%8F]字节åº[/url]读å–。为 [code]false[/code] 时文件以"
"å°ç«¯å­—节åºè¯»å–。如果ä¸ç¡®å®šï¼Œè¯·å°†å…¶ä¿ç•™ä¸º [code]false[/code],因为大多数文件都"
"是以å°ç«¯å­—节åºç¼–写的。\n"
-"[b]注æ„:[/b][member endian_swap] åªæ˜¯æ–‡ä»¶æ ¼å¼ï¼Œä¸Ž CPU 类型无关。 CPU 字节åº"
-"ä¸ä¼šå½±å“写入文件的默认字节åºã€‚\n"
+"[b]注æ„:[/b][member endian_swap] åªæ˜¯æ–‡ä»¶æ ¼å¼ï¼Œä¸Ž CPU 类型无关。CPU 字节åºä¸"
+"会影å“写入文件的默认字节åºã€‚\n"
"[b]注æ„:[/b]æ¯å½“您打开文件时,它总是é‡ç½®ä¸º [code]false[/code]。因此,必须在"
"[i]打开文件之åŽ[/i]设置 [member endian_swap]ï¼Œè€Œä¸æ˜¯ä¹‹å‰ã€‚"
@@ -30588,7 +30650,7 @@ msgid ""
"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
"å¯ç”¨çš„æ–‡ä»¶ç±»åž‹è¿‡æ»¤å™¨ã€‚例如,这仅显示 [code].png[/code] å’Œ [code].gd[/code] æ–‡"
-"件: [code]set_filters(PoolStringArray([\"*.png ; PNG Images\", \"*.gd ; "
+"件:[code]set_filters(PoolStringArray([\"*.png ; PNG Images\", \"*.gd ; "
"GDScript Files\" ]))[/code]。å•个过滤器中也å¯ä»¥æŒ‡å®šå¤šä¸ªæ–‡ä»¶ç±»åž‹ã€‚选中 "
"[code]\"*.png, *.jpg, *.jpeg ; Supported Images\"[/code] åŽä¼š PNG å’Œ JPEG æ–‡"
"件都会显示。"
@@ -30606,12 +30668,12 @@ msgid ""
"window title accordingly (e.g. setting mode to [constant MODE_OPEN_FILE] "
"will change the window title to \"Open a File\")."
msgstr ""
-"如果 [code]true[/code],更改 [code]Mode[/code] å±žæ€§å°†ç›¸åº”åœ°è®¾ç½®çª—å£æ ‡é¢˜ï¼ˆä¾‹"
+"如果为 [code]true[/code],更改 [code]Mode[/code] å±žæ€§å°†ç›¸åº”åœ°è®¾ç½®çª—å£æ ‡é¢˜ï¼ˆä¾‹"
"如,将模å¼è®¾ç½®ä¸º [constant MODE_OPEN_FILE] ä¼šå°†çª—å£æ ‡é¢˜æ›´æ”¹ä¸ºâ€œæ‰“开文件â€ï¼‰ã€‚"
#: doc/classes/FileDialog.xml
msgid "If [code]true[/code], the dialog will show hidden files."
-msgstr "如果[code]true[/code]ï¼Œå¯¹è¯æ¡†å°†æ˜¾ç¤ºå‡ºéšè—文件。"
+msgstr "如果为 [code]true[/code]ï¼Œå¯¹è¯æ¡†å°†æ˜¾ç¤ºå‡ºéšè—文件。"
#: doc/classes/FileDialog.xml
msgid "Emitted when the user selects a directory."
@@ -30653,7 +30715,7 @@ msgstr "å½“æ–‡ä»¶å­˜åœ¨æ—¶ï¼Œå¯¹è¯æ¡†ä¼šå‘出警告。"
msgid ""
"The dialog only allows accessing files under the [Resource] path "
"([code]res://[/code])."
-msgstr "è¯¥å¯¹è¯æ¡†åªå…许访问[Resource]路径下的文件([code]res://[/code])。"
+msgstr "è¯¥å¯¹è¯æ¡†åªå…许访问 [Resource] 路径下的文件([code]res://[/code])。"
#: doc/classes/FileDialog.xml
msgid ""
@@ -30673,7 +30735,7 @@ msgstr "应用于文件图标的颜色调制。"
msgid ""
"The color tint for disabled files (when the [FileDialog] is used in open "
"folder mode)."
-msgstr "ç¦ç”¨æ–‡ä»¶çš„色调(当[FileDialog]在打开文件夹模å¼ä¸‹ä½¿ç”¨æ—¶ï¼‰ã€‚"
+msgstr "ç¦ç”¨æ–‡ä»¶çš„色调(当 [FileDialog] 在打开文件夹模å¼ä¸‹ä½¿ç”¨æ—¶ï¼‰ã€‚"
#: doc/classes/FileDialog.xml
msgid "The color modulation applied to the folder icon."
@@ -30832,8 +30894,8 @@ msgid ""
"from the top, [i]ascent[/i] must be added to the Y axis.\n"
"See also [method CanvasItem.draw_string]."
msgstr ""
-"在给定ä½ç½®ä½¿ç”¨å­—体将[code]string[/code]绘制到画布项目中,并使用"
-"[code]modulate[/code]颜色,并å¯ä»¥é€‰æ‹©è£å‰ªå®½åº¦ã€‚ [code]position[/code]指定基"
+"在给定ä½ç½®ä½¿ç”¨å­—体将 [code]string[/code] 绘制到画布项目中,并使用 "
+"[code]modulate[/code] 颜色,并å¯ä»¥é€‰æ‹©è£å‰ªå®½åº¦ã€‚[code]position[/code] 指定基"
"çº¿ï¼Œè€Œä¸æ˜¯é¡¶éƒ¨ã€‚è¦ä»Žé¡¶éƒ¨ç»˜åˆ¶ï¼Œå¿…须在 Y 轴上添加[i]å‡éƒ¨[/i]。\n"
"å¦è¯·å‚阅 [method CanvasItem.draw_string]。"
@@ -30969,10 +31031,10 @@ msgid ""
"function, a reference to a function in a given object can be created, passed "
"around and called."
msgstr ""
-"在GDScriptä¸­ï¼Œå‡½æ•°ä¸æ˜¯[i]第一类对象[/i]。这æ„味ç€ä¸å¯èƒ½å°†å®ƒä»¬ç›´æŽ¥ä½œä¸ºå˜é‡å­˜"
+"在 GDScript ä¸­ï¼Œå‡½æ•°ä¸æ˜¯[i]第一类对象[/i]。这æ„味ç€ä¸å¯èƒ½å°†å®ƒä»¬ç›´æŽ¥ä½œä¸ºå˜é‡å­˜"
"储,从å¦ä¸€ä¸ªå‡½æ•°ä¸­è¿”å›žï¼Œæˆ–å°†å®ƒä»¬ä½œä¸ºå‚æ•°ä¼ é€’。\n"
-"然而,通过使用[method @GDScript.funcref]函数创建一个[FuncRef],å¯ä»¥åˆ›å»ºã€ä¼ é€’"
-"和调用给定对象中的一个函数的引用。"
+"然而,通过使用 [method @GDScript.funcref] 函数创建一个 [FuncRef],å¯ä»¥åˆ›å»ºã€"
+"传递和调用给定对象中的一个函数的引用。"
#: doc/classes/FuncRef.xml
msgid ""
@@ -31002,8 +31064,8 @@ msgid ""
"actually inheriting from [Object], not a built-in type such as [int], "
"[Vector2] or [Dictionary]."
msgstr ""
-"包å«è¢«å¼•用函数的对象。这个对象必须是实际继承自[Object]çš„ç±»åž‹ï¼Œè€Œä¸æ˜¯åƒ[int]ã€"
-"[Vector2]或[Dictionary]这样的内置类型。"
+"包å«è¢«å¼•用函数的对象。这个对象必须是实际继承自 [Object] çš„ç±»åž‹ï¼Œè€Œä¸æ˜¯åƒ "
+"[int]ã€[Vector2]ã€[Dictionary] 这样的内置类型。"
#: doc/classes/FuncRef.xml
msgid "The name of the referenced function."
@@ -31012,7 +31074,7 @@ msgstr "被引用函数的å称。"
#: modules/gdnative/doc_classes/GDNativeLibrary.xml
msgid ""
"An external library containing functions or script classes to use in Godot."
-msgstr "一个包å«å‡½æ•°æˆ–脚本类的外部库,å¯ä»¥åœ¨Godot中使用。"
+msgstr "包å«å‡½æ•°æˆ–脚本类的外部库,å¯ä»¥åœ¨ Godot 中使用。"
#: modules/gdnative/doc_classes/GDNativeLibrary.xml
msgid ""
@@ -31066,8 +31128,8 @@ msgid ""
"[code]reloadable[/code] must be [code]false[/code]. Otherwise, the editor "
"will attempt to unload the tool scripts while they're in use and crash."
msgstr ""
-"如果[code]true[/code],æ¯å½“ç”¨æˆ·ç¦»å¼€ç¼–è¾‘å™¨çª—å£æ—¶ï¼Œç¼–辑器会暂时å¸è½½åº“,å…许用户"
-"釿–°ç¼–译库,而ä¸éœ€è¦é‡æ–°å¯åЍGodot。\n"
+"如果为 [code]true[/code],æ¯å½“ç”¨æˆ·ç¦»å¼€ç¼–è¾‘å™¨çª—å£æ—¶ï¼Œç¼–辑器会暂时å¸è½½åº“,å…许"
+"ç”¨æˆ·é‡æ–°ç¼–译库,而ä¸éœ€è¦é‡æ–°å¯åЍGodot。\n"
"[b]注æ„:[/b]如果库定义了在编辑器内è¿è¡Œçš„工具脚本,[code]reloadable[/code]å¿…"
"须是[code]false[/code]。å¦åˆ™ï¼Œç¼–辑器会在工具脚本正在使用的时候å°è¯•å¸è½½å®ƒä»¬æ—¶"
"而崩溃。"
@@ -31081,8 +31143,8 @@ msgid ""
"loaded as long as Godot is running.\n"
"[b]Note:[/b] A singleton library cannot be [member reloadable]."
msgstr ""
-"如果[code]true[/code],Godot会在å¯åŠ¨æ—¶åŠ è½½åº“ï¼Œè€Œä¸æ˜¯åœ¨è„šæœ¬ç¬¬ä¸€æ¬¡ä½¿ç”¨åº“æ—¶ï¼Œåœ¨"
-"åˆå§‹åŒ–库åŽè°ƒç”¨[code]{prefix}gdnative_singleton[/code](其中[code]{prefix}[/"
+"如果为 [code]true[/code],Godot会在å¯åŠ¨æ—¶åŠ è½½åº“ï¼Œè€Œä¸æ˜¯åœ¨è„šæœ¬ç¬¬ä¸€æ¬¡ä½¿ç”¨åº“æ—¶ï¼Œ"
+"在åˆå§‹åŒ–库åŽè°ƒç”¨[code]{prefix}gdnative_singleton[/code](其中[code]{prefix}[/"
"code]是[member symbol_prefix]的值)。åªè¦Godot在è¿è¡Œï¼Œè¯¥åº“就一直被加载。\n"
"[b]注æ„:[/b]å•例库ä¸èƒ½æ˜¯[member reloadable]。"
@@ -31101,7 +31163,7 @@ msgstr ""
#: modules/gdscript/doc_classes/GDScript.xml
msgid "A script implemented in the GDScript programming language."
-msgstr "一个用 GDScript 编程语言实现的脚本。"
+msgstr "用 GDScript 编程语言实现的脚本。"
#: modules/gdscript/doc_classes/GDScript.xml
msgid ""
@@ -31140,7 +31202,7 @@ msgstr ""
#: modules/gdscript/doc_classes/GDScriptFunctionState.xml
msgid "State of a function call after yielding."
-msgstr "一个函数在调用åŽå¤±æ•ˆçš„状æ€ã€‚"
+msgstr "函数调用在 yield åŽæ‰€å¤„的状æ€ã€‚"
#: modules/gdscript/doc_classes/GDScriptFunctionState.xml
msgid ""
@@ -31180,7 +31242,7 @@ msgid ""
msgstr ""
"继续执行让步的函数调用。\n"
"å¦‚æžœä¼ é€’äº†ä¸€ä¸ªå‚æ•°ï¼Œåˆ™ä»Žäº§ç”Ÿçš„函数调用中的 [method @GDScript.yield] 调用返回"
-"傿•°ã€‚ä½ å¯ä»¥é€šè¿‡ä¾‹å¦‚一个 [Array] æ¥å¤„ç†å¤šä¸ªå‚数。 \n"
+"傿•°ã€‚ä½ å¯ä»¥é€šè¿‡ä¾‹å¦‚一个 [Array] æ¥å¤„ç†å¤šä¸ªå‚数。\n"
"此函数返回接续的函数调用åŽè¿”å›žçš„å†…å®¹ï¼Œå¦‚æžœå†æ¬¡æ¢å¤è°ƒç”¨ï¼Œå¯èƒ½æ˜¯å¦ä¸€ä¸ªå‡½æ•°çж"
"æ€ã€‚"
@@ -31188,7 +31250,8 @@ msgstr ""
msgid ""
"The generic 6-degrees-of-freedom joint can implement a variety of joint "
"types by locking certain axes' rotation or translation."
-msgstr "通用的6度自由度关节å¯ä»¥é€šè¿‡é”定æŸäº›è½´çš„æ—‹è½¬æˆ–平移æ¥å®žçްå„ç§å…³èŠ‚ç±»åž‹ã€‚"
+msgstr ""
+"通用的 6 度自由度关节å¯ä»¥é€šè¿‡é”定æŸäº›è½´çš„æ—‹è½¬æˆ–平移æ¥å®žçްå„ç§å…³èŠ‚ç±»åž‹ã€‚"
#: doc/classes/Generic6DOFJoint.xml
msgid ""
@@ -31196,8 +31259,8 @@ msgid ""
"and the latter 3 DOF axes represent the angular motion. Each axis can be "
"either locked, or limited."
msgstr ""
-"å‰3个DOF轴是线性轴,代表物体的平移,åŽ3个DOF轴代表角è¿åŠ¨ã€‚æ¯ä¸ªè½´å¯ä»¥è¢«é”定,"
-"也å¯ä»¥è¢«é™åˆ¶ã€‚"
+"å‰ 3 个 DOF è½´æ˜¯çº¿æ€§è½´ï¼Œä»£è¡¨ç‰©ä½“çš„å¹³ç§»ï¼ŒåŽ 3 个 DOF 轴代表角è¿åŠ¨ã€‚æ¯ä¸ªè½´å¯ä»¥"
+"被é”定,也å¯ä»¥è¢«é™åˆ¶ã€‚"
#: doc/classes/Generic6DOFJoint.xml
msgid ""
@@ -31634,8 +31697,8 @@ msgid ""
"at the origin. The box size is defined by [code]extents[/code], which "
"represents one (positive) corner of the box (i.e. half its actual size)."
msgstr ""
-"返回一个包å«6个[Plane]的数组,æè¿°ä»¥åŽŸç‚¹ä¸ºä¸­å¿ƒçš„ç›’å­çš„边。盒å­çš„大å°ç”±"
-"[code]extents[/code]定义,它代表盒å­çš„一个(正)角(å³å…¶å®žé™…大å°çš„一åŠï¼‰ã€‚"
+"è¿”å›žä¸€ä¸ªåŒ…å« 6 个 [Plane] 的数组,æè¿°ä»¥åŽŸç‚¹ä¸ºä¸­å¿ƒçš„ç›’å­çš„边。盒å­çš„大å°ç”± "
+"[code]extents[/code] 定义,它代表盒å­çš„一个(正)角(å³å…¶å®žé™…大å°çš„一åŠï¼‰ã€‚"
#: doc/classes/Geometry.xml
msgid ""
@@ -31647,10 +31710,11 @@ msgid ""
"[code]axis[/code] describes the axis along which the capsule is oriented (0 "
"for X, 1 for Y, 2 for Z)."
msgstr ""
-"返回一个[Plane]数组,该数组紧密地绑定ç€ä¸€ä¸ªä»¥åŽŸç‚¹ä¸ºä¸­å¿ƒï¼ŒåŠå¾„为[code]radius[/"
-"code],高度为[code]height[/code]çš„é¢çŠ¶èƒ¶å›Šã€‚å‚æ•°[code]side[/code]定义了将为胶"
-"囊的侧é¢éƒ¨åˆ†ç”Ÿæˆå¤šå°‘个平é¢ï¼Œè€Œ[code]lats[/code]则给出了胶囊底部和顶部的纬å‘阶"
-"æ¢¯æ•°ã€‚å‚æ•°[code]axis[/code]æè¿°äº†èƒ¶å›Šçš„æ–¹å‘轴(0为X,1为Y,2为Z)。"
+"返回一个 [Plane] 数组,该数组紧密地绑定ç€ä¸€ä¸ªä»¥åŽŸç‚¹ä¸ºä¸­å¿ƒï¼ŒåŠå¾„为 "
+"[code]radius[/code],高度为 [code]height[/code] çš„é¢çŠ¶èƒ¶å›Šã€‚å‚æ•° [code]side[/"
+"code] 定义了将为胶囊的侧é¢éƒ¨åˆ†ç”Ÿæˆå¤šå°‘个平é¢ï¼Œè€Œ [code]lats[/code] 则给出了胶"
+"囊底部和顶部的纬å‘é˜¶æ¢¯æ•°ã€‚å‚æ•° [code]axis[/code] æè¿°äº†èƒ¶å›Šçš„æ–¹å‘轴(0 代表 "
+"Xã€1 代表 Yã€2 代表 Z)。"
#: doc/classes/Geometry.xml
msgid ""
@@ -31661,18 +31725,18 @@ msgid ""
"describes the axis along which the cylinder is oriented (0 for X, 1 for Y, 2 "
"for Z)."
msgstr ""
-"返回一个[Plane]数组,该数组紧密绑定以原点为中心的切é¢åœ†æŸ±ä½“,其åŠå¾„为"
-"[code]radius[/code],高度为[code]height[/code]ã€‚å‚æ•°[code]side[/code]定义了将"
-"为圆柱体的圆形部分生æˆå¤šå°‘个平é¢ã€‚傿•°[code]axis[/code]æè¿°äº†åœ†æŸ±ä½“的方å‘è½´"
-"(0代表X,1代表Y,2代表Z)。"
+"返回一个 [Plane] 数组,该数组紧密绑定以原点为中心的切é¢åœ†æŸ±ä½“,其åŠå¾„为 "
+"[code]radius[/code],高度为 [code]height[/code]ã€‚å‚æ•° [code]side[/code] 定义"
+"了将为圆柱体的圆形部分生æˆå¤šå°‘个平é¢ã€‚傿•° [code]axis[/code] æè¿°äº†åœ†æŸ±ä½“的方"
+"å‘轴(0 代表 Xã€1 代表 Yã€2 代表 Z)。"
#: doc/classes/Geometry.xml
msgid ""
"Clips the polygon defined by the points in [code]points[/code] against the "
"[code]plane[/code] and returns the points of the clipped polygon."
msgstr ""
-"将[code]point[/code]中的点所定义的多边形与[code]plane[/code]进行对比,并返回"
-"被剪切的多边形的点。"
+"将 [code]point[/code] 中的点所定义的多边形与 [code]plane[/code] 进行对比,并"
+"返回被剪切的多边形的点。"
#: doc/classes/Geometry.xml
msgid ""
@@ -31684,11 +31748,13 @@ msgid ""
"outer polygon (boundary) and inner polygon (hole) which could be "
"distinguished by calling [method is_polygon_clockwise]."
msgstr ""
-"将[code]polygon_a[/code]与[code]polygon_b[/code]进行对比,并返回一个被剪切的"
-"多边形数组。这在多边形之间执行[constant OPERATION_DIFFERENCE]。如果"
-"[code]polygon_b[/code]与[code]polygon_a[/code]完全é‡åˆï¼Œåˆ™è¿”回一个空数组。\n"
-"如果[code]polygon_b[/code]被[code]polygon_a[/code]包围,返回一个外部多边形"
-"(边界)和内部多边形(孔),å¯ä»¥é€šè¿‡è°ƒç”¨[method is_polygon_clockwise]æ¥åŒºåˆ†ã€‚"
+"将 [code]polygon_a[/code] 与 [code]polygon_b[/code] 进行对比,并返回一个被剪"
+"切的多边形数组。这在多边形之间执行 [constant OPERATION_DIFFERENCE]。如果 "
+"[code]polygon_b[/code] 与 [code]polygon_a[/code] 完全é‡åˆï¼Œåˆ™è¿”回一个空数"
+"组。\n"
+"如果 [code]polygon_b[/code] 被 [code]polygon_a[/code] 包围,返回一个外部多边"
+"形(边界)和内部多边形(孔),å¯ä»¥é€šè¿‡è°ƒç”¨ [method is_polygon_clockwise] æ¥åŒº"
+"分。"
#: doc/classes/Geometry.xml
msgid ""
@@ -31697,16 +31763,16 @@ msgid ""
"between the polyline and the polygon. This operation can be thought of as "
"cutting a line with a closed shape."
msgstr ""
-"将[code]polyline[/code]与[code]polygon[/code]相对应,并返回一个折线数组。在折"
-"线和多边形之间执行[constant OPERATION_DIFFERENCE]。这个æ“作å¯ä»¥è¢«è®¤ä¸ºæ˜¯ç”¨ä¸€ä¸ª"
-"å°é—­çš„形状切割一æ¡çº¿ã€‚"
+"将 [code]polyline[/code] 与 [code]polygon[/code] 相对应,并返回一个折线数组。"
+"在折线和多边形之间执行 [constant OPERATION_DIFFERENCE]。这个æ“作å¯ä»¥è¢«è®¤ä¸ºæ˜¯"
+"用一个å°é—­çš„形状切割一æ¡çº¿ã€‚"
#: doc/classes/Geometry.xml
msgid ""
"Given an array of [Vector2]s, returns the convex hull as a list of points in "
"counterclockwise order. The last point is the same as the first one."
msgstr ""
-"给出一个[Vector2]s的数组,以逆时针的顺åºè¿”回凸é¢çš„点的列表。最åŽä¸€ä¸ªç‚¹ä¸Žç¬¬ä¸€"
+"给出一个 [Vector2] 的数组,以逆时针的顺åºè¿”回凸é¢çš„点的列表。最åŽä¸€ä¸ªç‚¹ä¸Žç¬¬ä¸€"
"个点相åŒã€‚"
#: doc/classes/Geometry.xml
@@ -31733,8 +31799,8 @@ msgid ""
"that is closest to [code]point[/code]. The returned point will always be "
"inside the specified segment."
msgstr ""
-"返回3D部份([code]s1[/code], [code]s2[/code])上离[code]point[/code]最近的3D"
-"点。返回的点将总是在指定的部份内。"
+"返回 3D 线段([code]s1[/code], [code]s2[/code])上离 [code]point[/code] 最近"
+"的 3D 点。返回的点将总是在指定的部份内。"
#: doc/classes/Geometry.xml
msgid ""
@@ -31742,8 +31808,8 @@ msgid ""
"that is closest to [code]point[/code]. The returned point will always be "
"inside the specified segment."
msgstr ""
-"返回2D段([code]s1[/code], [code]s2[/code])上最接近[code]point[/code]的2D"
-"点。返回的点将总是在指定的线段内。"
+"返回 2D 线段 ([code]s1[/code], [code]s2[/code]) 上离 [code]point[/code] 最近"
+"的 2D 点。返回的点将总是在指定的线段内。"
#: doc/classes/Geometry.xml
msgid ""
@@ -31763,9 +31829,9 @@ msgid ""
"inside the segment ([code]s1[/code], [code]s2[/code]) or outside of it, i.e. "
"somewhere on the line extending from the segment."
msgstr ""
-"返回由([code]s1[/code], [code]s2[/code])定义的二维线上最接近[code]point[/"
-"code]的二维点。返回的点å¯ä»¥åœ¨çº¿æ®µï¼ˆ[code]s1[/code], [code]s2[/code])内,也å¯"
-"以在线段外,å³åœ¨ä»Žçº¿æ®µå»¶ä¼¸å‡ºæ¥çš„æŸå¤„ã€‚"
+"返回由 ([code]s1[/code], [code]s2[/code]) 定义的 2D 线上最接近 [code]point[/"
+"code] çš„ 2D 点。返回的点å¯ä»¥åœ¨çº¿æ®µ ([code]s1[/code], [code]s2[/code]) 内,也"
+"å¯ä»¥åœ¨çº¿æ®µå¤–,å³åœ¨ä»Žçº¿æ®µå»¶ä¼¸å‡ºæ¥çš„æŸå¤„ã€‚"
#: doc/classes/Geometry.xml
msgid ""
@@ -31988,8 +32054,8 @@ msgid ""
msgstr ""
"给出2D线段([code]segment_from[/code],[code]segment_to[/code]),返回线段上"
"与圆心为 [code]circle_position[/code] ã€åŠå¾„为 [code]circle_radius[/code] 圆"
-"的相交ä½ç½®ï¼ˆä»¥0到1之间的数字)。如果线段没有与圆相交,则返回-1(如果延伸线段"
-"çš„çº¿æ®µä¸Žåœ†ç›¸äº¤ï¼Œä½†çº¿æ®µæ²¡æœ‰ç›¸äº¤ï¼Œä¹Ÿæ˜¯è¿™ç§æƒ…况)。"
+"的相交ä½ç½®ï¼ˆä»¥0 到 1之间的数字)。如果线段没有与圆相交,则返回-1(如果延伸线"
+"æ®µçš„çº¿æ®µä¸Žåœ†ç›¸äº¤ï¼Œä½†çº¿æ®µæ²¡æœ‰ç›¸äº¤ï¼Œä¹Ÿæ˜¯è¿™ç§æƒ…况)。"
#: doc/classes/Geometry.xml
msgid ""
@@ -32109,7 +32175,7 @@ msgstr "åˆ›å»ºä¸»ä½“æˆ–å‰ªè¾‘å¤šè¾¹å½¢è¢«å¡«å……çš„åŒºåŸŸï¼Œä½†ä¸æ˜¯ä¸¤è€…都被
msgid ""
"Squaring is applied uniformally at all convex edge joins at [code]1 * delta[/"
"code]."
-msgstr "在[code]1 * delta[/code]的所有凸边连接处å‡åŒ€åœ°åº”用平方。"
+msgstr "在 [code]1 * delta[/code] 的所有凸边连接处å‡åŒ€åœ°åº”用平方。"
#: doc/classes/Geometry.xml
msgid ""
@@ -32133,13 +32199,13 @@ msgstr ""
msgid ""
"Endpoints are joined using the [enum PolyJoinType] value and the path filled "
"as a polygon."
-msgstr "端点使用[enum PolyJoinType]值连接,路径被填充为多边形。"
+msgstr "端点使用 [enum PolyJoinType] 值连接,路径被填充为多边形。"
#: doc/classes/Geometry.xml
msgid ""
"Endpoints are joined using the [enum PolyJoinType] value and the path filled "
"as a polyline."
-msgstr "端点使用[enum PolyJoinType]值连接,路径被填充为多边形线。"
+msgstr "端点使用 [enum PolyJoinType] 值连接,路径被填充为多边形线。"
#: doc/classes/Geometry.xml
msgid "Endpoints are squared off with no extension."
@@ -32147,11 +32213,11 @@ msgstr "端点是方形的,没有延伸。"
#: doc/classes/Geometry.xml
msgid "Endpoints are squared off and extended by [code]delta[/code] units."
-msgstr "端点被平方化并扩展了[code]delta[/code]å•ä½ã€‚"
+msgstr "端点被平方化并扩展了 [code]delta[/code] å•ä½ã€‚"
#: doc/classes/Geometry.xml
msgid "Endpoints are rounded off and extended by [code]delta[/code] units."
-msgstr "端点被四èˆäº”入,并以[code]delta[/code]为å•ä½è¿›è¡Œæ‰©å±•。"
+msgstr "端点被四èˆäº”入,并以 [code]delta[/code] 为å•ä½è¿›è¡Œæ‰©å±•。"
#: doc/classes/GeometryInstance.xml
msgid "Base node for geometry-based visual instances."
@@ -32167,7 +32233,7 @@ msgstr ""
#: doc/classes/GeometryInstance.xml
msgid ""
"Returns the [enum GeometryInstance.Flags] that have been set for this object."
-msgstr "返回为此对象设置的[enum GeometryInstance.Flags] 。"
+msgstr "返回为此对象设置的 [enum GeometryInstance.Flags] 。"
#: doc/classes/GeometryInstance.xml
msgid ""
@@ -32189,8 +32255,7 @@ msgstr ""
msgid ""
"The selected shadow casting flag. See [enum ShadowCastingSetting] for "
"possible values."
-msgstr ""
-"选择的阴影投射标志。转到 [enum ShadowCastingSetting] æ¥æŸ¥çœ‹è¯¥å±žæ€§å¯èƒ½çš„值。"
+msgstr "选择的阴影投射标志。å¯èƒ½çš„å–å€¼è§ [enum ShadowCastingSetting]。"
#: doc/classes/GeometryInstance.xml
msgid ""
@@ -32269,8 +32334,8 @@ msgid ""
"If [code]true[/code], this GeometryInstance will be used when baking lights "
"using a [GIProbe] or [BakedLightmap]."
msgstr ""
-"如果 [code]true[/code],则在使用 [GIProbe] 或 [BakedLightmap] 烘焙ç¯å…‰æ—¶å°†ä½¿"
-"用此 GeometryInstance。"
+"如果为 [code]true[/code],则在使用 [GIProbe] 或 [BakedLightmap] 烘焙ç¯å…‰æ—¶å°†"
+"使用此 GeometryInstance。"
#: doc/classes/GeometryInstance.xml
msgid "The generated lightmap texture will have the original size."
@@ -32324,8 +32389,8 @@ msgid ""
"Will allow the GeometryInstance to be used when baking lights using a "
"[GIProbe] or [BakedLightmap]."
msgstr ""
-"å°†å…许在使用[GIProbe]或[BakedLightmap]进行ç¯å…‰çƒ˜ç„™æ—¶ä½¿ç”¨GeometryInstance几何"
-"实例。"
+"å°†å…许在使用 [GIProbe] 或 [BakedLightmap] 进行ç¯å…‰çƒ˜ç„™æ—¶ä½¿ç”¨ "
+"GeometryInstance 几何实例。"
#: doc/classes/GeometryInstance.xml
msgid ""
@@ -32503,16 +32568,16 @@ msgid ""
"Use 64 subdivisions. This is the lowest quality setting, but the fastest. "
"Use it if you can, but especially use it on lower-end hardware."
msgstr ""
-"使用64分区,这是最低的质é‡è®¾ç½®ï¼Œä½†ä¹Ÿæ˜¯æœ€å¿«çš„。如果你能使用它,特别是在低端硬"
-"件上使用它。"
+"使用 64 分区,这是最低的质é‡è®¾ç½®ï¼Œä½†ä¹Ÿæ˜¯æœ€å¿«çš„。如果你能使用它,特别是在低端"
+"硬件上使用它。"
#: doc/classes/GIProbe.xml
msgid "Use 128 subdivisions. This is the default quality setting."
-msgstr "使用128个分区。这是默认的质é‡è®¾ç½®ã€‚"
+msgstr "使用 128 个分区。这是默认的质é‡è®¾ç½®ã€‚"
#: doc/classes/GIProbe.xml
msgid "Use 256 subdivisions."
-msgstr "使用256个分区。"
+msgstr "使用 256 个分区。"
#: doc/classes/GIProbe.xml
msgid ""
@@ -32592,7 +32657,7 @@ msgstr ""
msgid ""
"The [Color] of the light. Defaults to white. A black color causes the light "
"to have no effect."
-msgstr "ç¯çš„[Color]。默认为白色。黑色会导致ç¯å…‰æ— æ•ˆã€‚"
+msgstr "ç¯çš„ [Color]。默认为白色。黑色会导致ç¯å…‰æ— æ•ˆã€‚"
#: modules/gltf/doc_classes/GLTFLight.xml
msgid ""
@@ -32638,8 +32703,8 @@ msgid ""
"with no range defined behave like physical lights (which have infinite "
"range). When creating a Godot light, the range is clamped to 4096."
msgstr ""
-"ç¯å…‰çš„范围,超过这个范围ç¯å…‰æ— æ•ˆã€‚没有定义范围的GLTFç¯å…‰çš„行为与无é™èŒƒå›´çš„物"
-"ç†ç¯å…‰ä¸€æ ·ã€‚当创建Godotç¯å…‰æ—¶ï¼ŒèŒƒå›´é™åˆ¶åœ¨4096。"
+"ç¯å…‰çš„范围,超过这个范围ç¯å…‰æ— æ•ˆã€‚没有定义范围的 GLTF ç¯å…‰çš„行为与无é™èŒƒå›´çš„"
+"物ç†ç¯å…‰ä¸€æ ·ã€‚当创建 Godot ç¯å…‰æ—¶ï¼ŒèŒƒå›´é™åˆ¶åœ¨ 4096。"
#: modules/gltf/doc_classes/GLTFLight.xml
msgid ""
@@ -32647,8 +32712,8 @@ msgid ""
"and \"directional\", which correspond to Godot's [OmniLight], [SpotLight], "
"and [DirectionalLight] respectively."
msgstr ""
-"ç¯å…‰çš„类型。Godot接å—的值是 \"point\"ã€\"spot\"å’Œ \"directional\",分别对应于"
-"Godotçš„[OmniLight]ã€[SpotLight]å’Œ[DirectionalLight]。"
+"ç¯å…‰çš„类型。Godot 接å—的值是“pointâ€â€œspotâ€â€œdirectionalâ€ï¼Œåˆ†åˆ«å¯¹åº”于 Godot çš„ "
+"[OmniLight]ã€[SpotLight]ã€[DirectionalLight]。"
#: modules/gltf/doc_classes/GLTFMesh.xml
msgid ""
@@ -32711,7 +32776,7 @@ msgstr ""
#: modules/mono/doc_classes/GodotSharp.xml
msgid "Bridge between Godot and the Mono runtime (Mono-enabled builds only)."
-msgstr "Godotå’ŒMonoè¿è¡Œæ—¶ä¹‹é—´çš„æ¡¥æ¢ï¼ˆä»…支æŒMono的构建)。"
+msgstr "Godot å’Œ Mono è¿è¡Œæ—¶ä¹‹é—´çš„æ¡¥æ¢ï¼ˆä»…æ”¯æŒ Mono 的构建)。"
#: modules/mono/doc_classes/GodotSharp.xml
msgid ""
@@ -32720,17 +32785,17 @@ msgid ""
"builds.\n"
"See also [CSharpScript]."
msgstr ""
-"该类是连接Godotå’ŒMonoè¿è¡Œæ—¶çš„æ¡¥æ¢ã€‚它暴露了一些低级别的æ“作,åªåœ¨æ”¯æŒMonoçš„"
-"Godot构建中å¯ç”¨ã€‚\n"
-"å‚阅[CSharpScript] 。"
+"该类是连接 Godot å’Œ Mono è¿è¡Œæ—¶çš„æ¡¥æ¢ã€‚它暴露了一些低级别的æ“作,åªåœ¨æ”¯æŒ "
+"Mono çš„ Godot 构建中å¯ç”¨ã€‚\n"
+"å‚阅 [CSharpScript] 。"
#: modules/mono/doc_classes/GodotSharp.xml
msgid "Attaches the current thread to the Mono runtime."
-msgstr "将当å‰çº¿ç¨‹è¿žæŽ¥åˆ°Monoè¿è¡Œæ—¶ã€‚"
+msgstr "将当å‰çº¿ç¨‹è¿žæŽ¥åˆ° Mono è¿è¡Œæ—¶ã€‚"
#: modules/mono/doc_classes/GodotSharp.xml
msgid "Detaches the current thread from the Mono runtime."
-msgstr "将当å‰çº¿ç¨‹ä»ŽMonoè¿è¡Œæ—¶ä¸­åˆ†ç¦»å‡ºæ¥ã€‚"
+msgstr "将当å‰çº¿ç¨‹ä»Ž Mono è¿è¡Œæ—¶ä¸­åˆ†ç¦»å‡ºæ¥ã€‚"
#: modules/mono/doc_classes/GodotSharp.xml
msgid ""
@@ -32739,9 +32804,9 @@ msgid ""
"(use [method is_runtime_initialized] to check). If the Mono runtime isn't "
"initialized at the time this method is called, the engine will crash."
msgstr ""
-"返回当å‰çš„MonoDomain ID。\n"
-"[b]注æ„:[/b]Monoè¿è¡Œæ—¶å¿…须被åˆå§‹åŒ–,这个方法æ‰èƒ½å·¥ä½œï¼ˆä½¿ç”¨ [method "
-"is_runtime_initialized] æ¥æ£€æŸ¥ï¼‰ã€‚如果在调用这个方法的时候,Monoè¿è¡Œæ—¶æ²¡æœ‰è¢«"
+"返回当å‰çš„ MonoDomain ID。\n"
+"[b]注æ„:[/b]Mono è¿è¡Œæ—¶å¿…须被åˆå§‹åŒ–,这个方法æ‰èƒ½å·¥ä½œï¼ˆä½¿ç”¨ [method "
+"is_runtime_initialized] æ¥æ£€æŸ¥ï¼‰ã€‚如果在调用这个方法的时候,Mono è¿è¡Œæ—¶æ²¡æœ‰è¢«"
"åˆå§‹åŒ–,引擎将崩溃。"
#: modules/mono/doc_classes/GodotSharp.xml
@@ -32752,10 +32817,10 @@ msgid ""
"(use [method is_runtime_initialized] to check). If the Mono runtime isn't "
"initialized at the time this method is called, the engine will crash."
msgstr ""
-"返回scripts MonoDomainçš„ID。这将是与 [method get_domain_id] 相åŒçš„MonoDomain "
-"ID,除éžscripts domain没有被加载。\n"
-"[b]注æ„:[/b]Monoè¿è¡Œæ—¶å¿…须被åˆå§‹åŒ–,这个方法æ‰èƒ½å·¥ä½œï¼ˆä½¿ç”¨ [method "
-"is_runtime_initialized] æ¥æ£€æŸ¥ï¼‰ã€‚如果在调用这个方法的时候,Monoè¿è¡Œæ—¶æ²¡æœ‰è¢«"
+"返回脚本 MonoDomain çš„ ID。这将是与 [method get_domain_id] 相åŒçš„ MonoDomain "
+"ID,除éžè„šæœ¬åŸŸæ²¡æœ‰è¢«åŠ è½½ã€‚\n"
+"[b]注æ„:[/b]Mono è¿è¡Œæ—¶å¿…须被åˆå§‹åŒ–,这个方法æ‰èƒ½å·¥ä½œï¼ˆä½¿ç”¨ [method "
+"is_runtime_initialized] æ¥æ£€æŸ¥ï¼‰ã€‚如果在调用这个方法的时候,Mono è¿è¡Œæ—¶æ²¡æœ‰è¢«"
"åˆå§‹åŒ–,引擎将会崩溃。"
#: modules/mono/doc_classes/GodotSharp.xml
@@ -32770,7 +32835,7 @@ msgid ""
"Returns [code]true[/code] if the Mono runtime is initialized, [code]false[/"
"code] otherwise."
msgstr ""
-"如果Monoè¿è¡Œæ—¶è¢«åˆå§‹åŒ–,返回 [code]true[/code] ,å¦åˆ™è¿”回 [code]false[/"
+"如果 Mono è¿è¡Œæ—¶è¢«åˆå§‹åŒ–,返回 [code]true[/code] ,å¦åˆ™è¿”回 [code]false[/"
"code] 。"
#: modules/mono/doc_classes/GodotSharp.xml
@@ -32778,7 +32843,7 @@ msgid ""
"Returns [code]true[/code] if the Mono runtime is shutting down, [code]false[/"
"code] otherwise."
msgstr ""
-"如果Monoè¿è¡Œæ—¶æ­£åœ¨å…³é—­ï¼Œè¿”回 [code]true[/code] ,å¦åˆ™è¿”回 [code]false[/"
+"如果 Mono è¿è¡Œæ—¶æ­£åœ¨å…³é—­ï¼Œè¿”回 [code]true[/code] ,å¦åˆ™è¿”回 [code]false[/"
"code] 。"
#: modules/mono/doc_classes/GodotSharp.xml
@@ -32884,11 +32949,11 @@ msgstr ""
#: doc/classes/GradientTexture.xml
msgid "The [Gradient] that will be used to fill the texture."
-msgstr "将用于填充纹ç†çš„[Gradient]。"
+msgstr "将用于填充纹ç†çš„ [Gradient]。"
#: doc/classes/GradientTexture.xml
msgid "The number of color samples that will be obtained from the [Gradient]."
-msgstr "将从[Gradient]中获得的颜色样本的数é‡ã€‚"
+msgstr "将从 [Gradient] 中获得的颜色样本的数é‡ã€‚"
#: doc/classes/GradientTexture2D.xml
msgid "Gradient-filled 2D texture."
@@ -33127,17 +33192,17 @@ msgid ""
"[code]from_port[/code] and [code]to[/code]'s [code]to_port[/code] with the "
"color provided in the [code]activity[/code] theme property."
msgstr ""
-"将[code]from[/code]的[code]from_port[/code]和[code]to[/code]的[code]to_port[/"
-"code]之间的连接的颜色纹ç†è®¾ç½®ä¸ºå½“剿­£åœ¨ä½¿ç”¨[code]activity[/code]的主题中的颜"
-"色。"
+"将 [code]from[/code] 的 [code]from_port[/code] 和 [code]to[/code] 的 "
+"[code]to_port[/code] 之间的连接的颜色纹ç†è®¾ç½®ä¸ºå½“剿­£åœ¨ä½¿ç”¨ [code]activity[/"
+"code] 的主题中的颜色。"
#: doc/classes/GraphEdit.xml
msgid "Sets the specified [code]node[/code] as the one selected."
-msgstr "选中一个特定的节点[code]node[/code]."
+msgstr "选中一个特定的节点 [code]node[/code]."
#: doc/classes/GraphEdit.xml
msgid "If [code]true[/code], the minimap is visible."
-msgstr "如果[code]true[/code],å°å›¾æ˜¯å¯è§çš„。"
+msgstr "如果为 [code]true[/code],å°å›¾æ˜¯å¯è§çš„。"
#: doc/classes/GraphEdit.xml
msgid "The opacity of the minimap rectangle."
@@ -33154,7 +33219,8 @@ msgid ""
"If [code]true[/code], enables disconnection of existing connections in the "
"GraphEdit by dragging the right end."
msgstr ""
-"如果[code]true[/code],通过拖动å³ç«¯ï¼Œå¯ä»¥æ–­å¼€å›¾å½¢ç¼–辑GraphEdit中现有的连接。"
+"如果为 [code]true[/code],通过拖动å³ç«¯ï¼Œå¯ä»¥æ–­å¼€å›¾å½¢ç¼–辑GraphEdit中现有的连"
+"接。"
#: doc/classes/GraphEdit.xml
msgid "The scroll offset."
@@ -33165,11 +33231,11 @@ msgid ""
"If [code]true[/code], makes a label with the current zoom level visible. The "
"zoom value is displayed in percents."
msgstr ""
-"如果[code]true[/code],则使当å‰ç¼©æ”¾çº§åˆ«çš„æ ‡ç­¾å¯è§ã€‚缩放值以百分比显示。"
+"如果为 [code]true[/code],则使当å‰ç¼©æ”¾çº§åˆ«çš„æ ‡ç­¾å¯è§ã€‚缩放值以百分比显示。"
#: doc/classes/GraphEdit.xml
msgid "The snapping distance in pixels."
-msgstr "å¸é™„è·ç¦»(以åƒç´ ä¸ºå•ä½)。"
+msgstr "å¸é™„è·ç¦»ï¼Œå•ä½ä¸ºåƒç´ ã€‚"
#: doc/classes/GraphEdit.xml
msgid "If [code]true[/code], enables snapping."
@@ -33193,11 +33259,11 @@ msgstr "æ¯ä¸ªç¼©æ”¾çº§åˆ«çš„æ­¥é•¿ã€‚"
#: doc/classes/GraphEdit.xml
msgid "Emitted at the beginning of a GraphNode movement."
-msgstr "在图形节点GraphNode移动开始时å‘出。"
+msgstr "在 GraphNode 移动开始时å‘出。"
#: doc/classes/GraphEdit.xml
msgid "Emitted at the end of a GraphNode movement."
-msgstr "在图形节点GraphNodeç§»åŠ¨ç»“æŸæ—¶å‘出。"
+msgstr "在 GraphNode ç§»åŠ¨ç»“æŸæ—¶å‘出。"
#: doc/classes/GraphEdit.xml
msgid ""
@@ -33223,7 +33289,7 @@ msgstr "当用户将输出端å£è¿žæŽ¥åˆ°å›¾å½¢çš„ç©ºä½æ—¶å‘出。"
#: doc/classes/GraphEdit.xml
msgid "Emitted when the user presses [code]Ctrl + C[/code]."
-msgstr "当用户按[code]Ctrl + C[/code]时触å‘。"
+msgstr "当用户按 [code]Ctrl + C[/code] 时触å‘。"
#: doc/classes/GraphEdit.xml
msgid ""
@@ -33247,15 +33313,15 @@ msgstr ""
#: doc/classes/GraphEdit.xml
msgid ""
"Emitted when a GraphNode is attempted to be duplicated in the GraphEdit."
-msgstr "当图形节点GraphNode试图在图形编辑GraphEdit中被å¤åˆ¶æ—¶å‘出的。"
+msgstr "当 GraphNode 试图在 GraphEdit 中被å¤åˆ¶æ—¶å‘出的。"
#: doc/classes/GraphEdit.xml
msgid "Emitted when a GraphNode is selected."
-msgstr "当图形节点GraphNode被选择时å‘出。"
+msgstr "当 GraphNode 被选择时å‘出。"
#: doc/classes/GraphEdit.xml
msgid "Emitted when the user presses [code]Ctrl + V[/code]."
-msgstr "当用户按下[code]Ctrl + V[/code]时触å‘。"
+msgstr "当用户按下 [code]Ctrl + V[/code] 时触å‘。"
#: doc/classes/GraphEdit.xml
msgid ""
@@ -33263,8 +33329,8 @@ msgid ""
"GraphEdit. [code]position[/code] is the position of the mouse pointer when "
"the signal is sent."
msgstr ""
-"å½“è¯·æ±‚å¼¹å‡ºçª—å£æ—¶å‘出。在图形编辑GraphEdit中å³é”®å•击时å‘ç”Ÿã€‚åæ ‡"
-"[code]position[/code] 是å‘é€ä¿¡å·æ—¶é¼ æ ‡æŒ‡é’ˆçš„ä½ç½®ã€‚"
+"å½“è¯·æ±‚å¼¹å‡ºçª—å£æ—¶å‘出。在 GraphEdit 中å³é”®å•击时å‘ç”Ÿã€‚åæ ‡ [code]position[/"
+"code] 是å‘é€ä¿¡å·æ—¶é¼ æ ‡æŒ‡é’ˆçš„ä½ç½®ã€‚"
#: doc/classes/GraphEdit.xml
msgid ""
@@ -33291,11 +33357,11 @@ msgstr "选择的矩形的轮廓颜色。"
#: doc/classes/GraphEdit.xml
msgid ""
"The horizontal range within which a port can be grabbed (on both sides)."
-msgstr "一个端å£å¯ä»¥è¢«æŠ“å–的水平范围(两侧)。"
+msgstr "端å£å¯ä»¥è¢«æŠ“å–的水平范围(两侧)。"
#: doc/classes/GraphEdit.xml
msgid "The vertical range within which a port can be grabbed (on both sides)."
-msgstr "一个端å£å¯ä»¥è¢«æŠ“å–的垂直范围(两侧)。"
+msgstr "端å£å¯ä»¥è¢«æŠ“å–的垂直范围(两侧)。"
#: doc/classes/GraphEdit.xml
msgid "The icon for the zoom out button."
@@ -33492,17 +33558,19 @@ msgstr ""
msgid ""
"Sets the left (input) type of the slot [code]idx[/code] to [code]type_left[/"
"code]."
-msgstr "å°†æ’æ§½[code]idx[/code]的左侧(输入)类型设置为[code]type_left[/code]。"
+msgstr ""
+"å°†æ’æ§½ [code]idx[/code] 的左侧(输入)类型设置为 [code]type_left[/code]。"
#: doc/classes/GraphNode.xml
msgid ""
"Sets the right (output) type of the slot [code]idx[/code] to "
"[code]type_right[/code]."
-msgstr "å°†æ’æ§½[code]idx[/code]çš„å³ï¼ˆè¾“出)类型设置为[code]type_right[/code]。"
+msgstr ""
+"å°†æ’æ§½ [code]idx[/code] çš„å³ä¾§ï¼ˆè¾“出)类型设置为 [code]type_right[/code]。"
#: doc/classes/GraphNode.xml
msgid "If [code]true[/code], the GraphNode is a comment node."
-msgstr "如果å¯ç”¨[code]true[/code],则GraphNode就是一个注释节点。"
+msgstr "如果为 [code]true[/code],则 GraphNode 是注释节点。"
#: doc/classes/GraphNode.xml
msgid ""
@@ -33511,12 +33579,12 @@ msgid ""
"[b]Note:[/b] You cannot use position directly, as [GraphEdit] is a "
"[Container]."
msgstr ""
-"图形节点 GraphNode çš„åç§»é‡ï¼Œä¸Ž [GraphEdit] 的滚动åç§»é‡ç›¸å…³ã€‚\n"
+"GraphNode çš„åç§»é‡ï¼Œä¸Ž [GraphEdit] 的滚动åç§»é‡ç›¸å…³ã€‚\n"
"[b]注æ„:[/b]由于 [GraphEdit] 是 [Container],因此ä¸èƒ½ç›´æŽ¥ä½¿ç”¨ä½ç½®ã€‚"
#: doc/classes/GraphNode.xml
msgid "Sets the overlay shown above the GraphNode. See [enum Overlay]."
-msgstr "设置在图形节点GraphNode上方显示的å åŠ å±‚ã€‚å‚阅[enum Overlay]。"
+msgstr "设置在 GraphNode 上方显示的å åŠ å±‚ã€‚è§ [enum Overlay]。"
#: doc/classes/GraphNode.xml
msgid ""
@@ -33524,13 +33592,13 @@ msgid ""
"[b]Note:[/b] Dragging the handle will only emit the [signal resize_request] "
"signal, the GraphNode needs to be resized manually."
msgstr ""
-"如果[code]true[/code],用户å¯ä»¥è°ƒæ•´å›¾å½¢èŠ‚ç‚¹GraphNode的大å°ã€‚\n"
+"如果为 [code]true[/code],用户å¯ä»¥è°ƒæ•´å›¾å½¢èŠ‚ç‚¹GraphNode的大å°ã€‚\n"
"[b]注æ„:[/b]拖动手柄åªä¼šå‘出 [signal resize_request] ä¿¡å·ï¼Œå›¾å½¢èŠ‚ç‚¹GraphNode"
"éœ€è¦æ‰‹åŠ¨è°ƒæ•´å¤§å°ã€‚"
#: doc/classes/GraphNode.xml
msgid "If [code]true[/code], the GraphNode is selected."
-msgstr "如果[code]true[/code],图形节点GraphNode被选中。"
+msgstr "如果为 [code]true[/code],图形节点GraphNode被选中。"
#: doc/classes/GraphNode.xml
msgid ""
@@ -33538,44 +33606,44 @@ msgid ""
"[b]Note:[/b] Pressing it will only emit the [signal close_request] signal, "
"the GraphNode needs to be removed manually."
msgstr ""
-"如果[code]true[/code],则关闭按钮将å¯è§ã€‚\n"
+"如果为 [code]true[/code],则关闭按钮将å¯è§ã€‚\n"
"[b]注æ„:[/b]按下它åªä¼šå‘出[signal close_request]ä¿¡å·ï¼Œéœ€è¦æ‰‹åŠ¨åˆ é™¤å›¾å½¢èŠ‚ç‚¹"
"GraphNode。"
#: doc/classes/GraphNode.xml
msgid "The text displayed in the GraphNode's title bar."
-msgstr "显示在图形节点GraphNode标题æ ä¸­çš„æ–‡æœ¬ã€‚"
+msgstr "显示在 GraphNode 标题æ ä¸­çš„æ–‡æœ¬ã€‚"
#: doc/classes/GraphNode.xml
msgid ""
"Emitted when the GraphNode is requested to be closed. Happens on clicking "
"the close button (see [member show_close])."
msgstr ""
-"当图形节点GraphNode被请求关闭时å‘出。在点击关闭按钮时å‘生(è§[member "
+"当 GraphNode 被请求关闭时å‘出。在点击关闭按钮时å‘ç”Ÿï¼ˆè§ [member "
"show_close])。"
#: doc/classes/GraphNode.xml
msgid "Emitted when the GraphNode is dragged."
-msgstr "当图形节点GraphNode被拖动时å‘出。"
+msgstr "当 GraphNode 被拖动时å‘出。"
#: doc/classes/GraphNode.xml
msgid "Emitted when the GraphNode is moved."
-msgstr "当图形节点GraphNode被移动时触å‘。"
+msgstr "当 GraphNode 被移动时触å‘。"
#: doc/classes/GraphNode.xml
msgid ""
"Emitted when the GraphNode is requested to be displayed over other ones. "
"Happens on focusing (clicking into) the GraphNode."
msgstr ""
-"当图形节点GraphNodeè¢«è¦æ±‚显示在其他节点之上时触å‘。在GraphNode获得焦点时触"
-"å‘,å³é¼ æ ‡ç‚¹å‡»è¿›å…¥ã€‚"
+"当 GraphNode è¢«è¦æ±‚显示在其他节点之上时触å‘。在 GraphNode 获得焦点时触å‘,å³"
+"鼠标点击进入。"
#: doc/classes/GraphNode.xml
msgid ""
"Emitted when the GraphNode is requested to be resized. Happens on dragging "
"the resizer handle (see [member resizable])."
msgstr ""
-"当图形节点GraphNodeè¢«è¦æ±‚è°ƒæ•´å¤§å°æ—¶å‘出。在拖动调整器手柄时å‘生(è§[member "
+"当 GraphNode è¢«è¦æ±‚è°ƒæ•´å¤§å°æ—¶å‘出。在拖动调整器手柄时å‘ç”Ÿï¼ˆè§ [member "
"resizable])。"
#: doc/classes/GraphNode.xml
@@ -33588,15 +33656,15 @@ msgstr "没有显示覆盖层。"
#: doc/classes/GraphNode.xml
msgid "Show overlay set in the [code]breakpoint[/code] theme property."
-msgstr "显示在[code]breakpoint[/code]主题属性中设置的覆盖层。"
+msgstr "显示在主题属性 [code]breakpoint[/code] 中设置的覆盖层。"
#: doc/classes/GraphNode.xml
msgid "Show overlay set in the [code]position[/code] theme property."
-msgstr "æ˜¾ç¤ºåœ¨ä¸»é¢˜åæ ‡[code]position[/code]属性中设置的å åŠ å±‚ã€‚"
+msgstr "显示在主题属性 [code]position[/code] 中设置的覆盖层。"
#: doc/classes/GraphNode.xml
msgid "The color modulation applied to the close button icon."
-msgstr "应用于关闭按钮图标的颜色调制(modulation)。"
+msgstr "应用于关闭按钮图标的颜色调制。"
#: doc/classes/GraphNode.xml
msgid "The color modulation applied to the resizer icon."
@@ -33629,7 +33697,7 @@ msgstr "对标题文本应用的字体。"
#: doc/classes/GraphNode.xml
msgid ""
"The icon for the close button, visible when [member show_close] is enabled."
-msgstr "关闭按钮的图标会在å¯ç”¨[member show_close]æ—¶å¯è§ã€‚"
+msgstr "关闭按钮的图标会在å¯ç”¨ [member show_close] æ—¶å¯è§ã€‚"
#: doc/classes/GraphNode.xml
msgid "The icon used for representing ports."
@@ -33637,23 +33705,25 @@ msgstr "该图标用于表示端å£ã€‚"
#: doc/classes/GraphNode.xml
msgid "The icon used for resizer, visible when [member resizable] is enabled."
-msgstr "用于调整大å°çš„图标,在 [member resizable]被å¯ç”¨æ—¶å¯è§ã€‚"
+msgstr "用于调整大å°çš„图标,在 [member resizable] 被å¯ç”¨æ—¶å¯è§ã€‚"
#: doc/classes/GraphNode.xml
msgid ""
"The background used when [member overlay] is set to [constant "
"OVERLAY_BREAKPOINT]."
-msgstr "当[member overlay]被设置为[constant OVERLAY_BREAKPOINT]时使用的背景。"
+msgstr ""
+"当 [member overlay] 被设置为 [constant OVERLAY_BREAKPOINT] 时使用的背景。"
#: doc/classes/GraphNode.xml
msgid "The [StyleBox] used when [member comment] is enabled."
-msgstr "当å¯ç”¨[member comment]时使用的[StyleBox]。"
+msgstr "当å¯ç”¨ [member comment] 时使用的 [StyleBox]。"
#: doc/classes/GraphNode.xml
msgid ""
"The [StyleBox] used when [member comment] is enabled and the [GraphNode] is "
"focused."
-msgstr "当[member comment]被å¯ç”¨ï¼Œä¸”[GraphNode]获得焦点时使用的[StyleBox]。"
+msgstr ""
+"当 [member comment] 被å¯ç”¨ï¼Œä¸” [GraphNode] 获得焦点时使用的 [StyleBox]。"
#: doc/classes/GraphNode.xml
msgid "The default background for [GraphNode]."
@@ -33882,7 +33952,7 @@ msgid ""
"This does not affect the size of the meshes. See [member cell_scale]."
msgstr ""
"网格å•元的尺寸。\n"
-"这并ä¸å½±å“网格的尺寸大å°ã€‚å‚阅 [member cell_scale]。"
+"这并ä¸å½±å“网格的尺寸大å°ã€‚è§ [member cell_scale]。"
#: modules/gridmap/doc_classes/GridMap.xml
msgid ""
@@ -34031,7 +34101,7 @@ msgid ""
"HASH_SHA256] to start computation of a SHA-256)."
msgstr ""
"开始对给定的 [code]type[/code] (例如 [constant HASH_SHA256] 进行新的哈希计"
-"算, 以开始计算 SHA-256) 。"
+"算,以开始计算 SHA-256) 。"
#: doc/classes/HashingContext.xml
msgid "Updates the computation with the given [code]chunk[/code] of data."
@@ -34055,7 +34125,7 @@ msgstr "水平盒å¼å®¹å™¨ã€‚"
#: doc/classes/HBoxContainer.xml
msgid "Horizontal box container. See [BoxContainer]."
-msgstr "水平盒å¼å®¹å™¨ã€‚请å‚阅 [BoxContainer]。"
+msgstr "水平盒å¼å®¹å™¨ã€‚è§ [BoxContainer]。"
#: doc/classes/HBoxContainer.xml
msgid "The horizontal space between the [HBoxContainer]'s elements."
@@ -34108,7 +34178,7 @@ msgid ""
"[Generic6DOFJoint]."
msgstr ""
"HingeJoint(铰链关节)通常使用物体 A çš„ Z 轴作为铰链轴,但手动添加时å¯ä»¥æŒ‡å®š"
-"å¦ä¸€ä¸ªè½´ã€‚请å‚阅 [Generic6DOFJoint]。"
+"å¦ä¸€ä¸ªè½´ã€‚å¦è¯·å‚阅 [Generic6DOFJoint]。"
#: doc/classes/HingeJoint.xml doc/classes/Label3D.xml
#: doc/classes/SpriteBase3D.xml
@@ -34702,12 +34772,12 @@ msgid ""
"Sends the body data raw, as a byte array and does not encode it in any way."
msgstr ""
"å‘连接的主机å‘é€åŽŸå§‹è¯·æ±‚ã€‚\n"
-"URL傿•°é€šå¸¸åªæ˜¯ä¸»æœºåŽé¢çš„部分,所以对于[code]http://somehost.com/index.php[/"
-"code],它是[code]/index.php[/code]。当å‘HTTPä»£ç†æœåС噍å‘é€è¯·æ±‚时,它应该是一"
-"个ç»å¯¹çš„URL。对于[constant HTTPClient.METHOD_OPTIONS]请求,å…许[code]*[/"
-"code]。对于[constant HTTPClient.METHOD_CONNECT]请求,应该是标准组件,"
-"[code]host:port[/code]。\n"
-"å¤´ä¿¡æ¯æ˜¯HTTP请求头信æ¯ã€‚关于å¯ç”¨çš„HTTP方法,å‚阅[enum Method]。\n"
+"URL 傿•°é€šå¸¸åªæ˜¯ä¸»æœºåŽé¢çš„部分,所以对于 [code]http://somehost.com/index."
+"php[/code],它是 [code]/index.php[/code]ã€‚å½“å‘ HTTP ä»£ç†æœåС噍å‘é€è¯·æ±‚时,它"
+"应该是一个ç»å¯¹çš„ URL。对于[constant HTTPClient.METHOD_OPTIONS] 请求,å…许 "
+"[code]*[/code]。对于 [constant HTTPClient.METHOD_CONNECT] 请求,应该是标准组"
+"件,[code]host:port[/code]。\n"
+"å¤´ä¿¡æ¯æ˜¯ HTTP 请求头信æ¯ã€‚å¯ç”¨çš„ HTTP æ–¹æ³•è§ [enum Method]。\n"
"以字节数组的形å¼å‘é€åŽŸå§‹æ­£æ–‡æ•°æ®ï¼Œä¸ä»¥ä»»ä½•æ–¹å¼è¿›è¡Œç¼–ç ã€‚"
#: doc/classes/HTTPClient.xml doc/classes/HTTPRequest.xml
@@ -35474,7 +35544,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -35542,7 +35612,7 @@ msgstr ""
" # 执行 POST 请求。截止到文档编写时,下é¢çš„ URL 会返回 JSON。\n"
" # 注æ„:请勿使用å•个 HTTPRequest 节点进行连续请求。\n"
" # 下é¢çš„ä»£ç æ®µä»…ä¾›å‚考。\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -35634,7 +35704,7 @@ msgstr ""
"在底层的 [HTTPClient] 上创建请求。如果没有é…置错误,它会å°è¯•使用 [method "
"HTTPClient.connect_to_host] è¿žæŽ¥å¹¶å°†å‚æ•°ä¼ é€’ç»™ [method HTTPClient."
"request]。\n"
-"如果请求创建æˆåŠŸï¼Œåˆ™è¿”å›ž [constant OK]。 ï¼ˆå¹¶ä¸æ„å‘³ç€æœåС噍已å“应),"
+"如果请求创建æˆåŠŸï¼Œåˆ™è¿”å›ž [constant OK]ã€‚ï¼ˆå¹¶ä¸æ„å‘³ç€æœåС噍已å“应),"
"[constant ERR_UNCONFIGURED] 如果ä¸åœ¨æ ‘中,[constant ERR_BUSY] 如果ä»åœ¨å¤„ç†å…ˆ"
"å‰çš„请求,[constant ERR_INVALID_PARAMETER] å¦‚æžœç»™å®šçš„å­—ç¬¦ä¸²ä¸æ˜¯æœ‰æ•ˆçš„ URL æ ¼"
"å¼ï¼Œæˆ– [constant ERR_CANT_CONNECT]如果ä¸ä½¿ç”¨çº¿ç¨‹å¹¶ä¸” [HTTPClient] 无法连接到"
@@ -35662,7 +35732,7 @@ msgstr ""
"在底层的[HTTPClient]上创建请求,使用一个原始字节数组作为请求主体。如果没有é…"
"置错误,它会å°è¯•使用 [method HTTPClient.connect_to_host] è¿žæŽ¥å¹¶å°†å‚æ•°ä¼ é€’ç»™ "
"[method HTTPClient.request]。\n"
-"如果请求创建æˆåŠŸï¼Œåˆ™è¿”å›ž [constant OK]。 ï¼ˆå¹¶ä¸æ„å‘³ç€æœåС噍已å“应),"
+"如果请求创建æˆåŠŸï¼Œåˆ™è¿”å›ž [constant OK]ã€‚ï¼ˆå¹¶ä¸æ„å‘³ç€æœåС噍已å“应),"
"[constant ERR_UNCONFIGURED] 如果ä¸åœ¨æ ‘中,[constant ERR_BUSY] 如果ä»åœ¨å¤„ç†å…ˆ"
"å‰çš„请求,[constant ERR_INVALID_PARAMETER] å¦‚æžœç»™å®šçš„å­—ç¬¦ä¸²ä¸æ˜¯æœ‰æ•ˆçš„ URL æ ¼"
"å¼ï¼Œæˆ– [constant ERR_CANT_CONNECT]如果ä¸ä½¿ç”¨çº¿ç¨‹å¹¶ä¸” [HTTPClient] 无法连接到"
@@ -35714,14 +35784,16 @@ msgid ""
msgstr "å…许的最大é‡å®šå‘数。用于防止无é™é‡å®šå‘循环。"
#: doc/classes/HTTPRequest.xml
+#, fuzzy
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
"如果设为大于 [code]0.0[/code] 的值,在ç»è¿‡ [code]timeout[/code] ç§’ä»æœª[i]完æˆ"
"[/i]请求时,该 HTTP 请求就会超时。对于 REST API 等较å°çš„ HTTP 请求,将 "
@@ -35798,7 +35870,7 @@ msgid ""
"hardware limitations. Larger images may fail to import."
msgstr ""
"æœ¬åœ°å›¾åƒæ•°æ®ç±»åž‹ã€‚包å«å¯è½¬æ¢ä¸º [ImageTexture] çš„å›¾åƒæ•°æ®ï¼Œå¹¶æä¾›å¸¸ç”¨çš„[i]图åƒ"
-"处ç†[/i]方法。 [Image] 的最大宽度和高度是 [constant MAX_WIDTH] å’Œ [constant "
+"处ç†[/i]方法。[Image] 的最大宽度和高度是 [constant MAX_WIDTH] å’Œ [constant "
"MAX_HEIGHT]。\n"
"[Image] ä¸èƒ½ç›´æŽ¥åˆ†é…给对象的 [code]texture[/code] 属性,例如 [Sprite],必须先"
"手动转æ¢ä¸º [ImageTexture]。\n"
@@ -35954,7 +36026,7 @@ msgstr ""
msgid ""
"Stretches the image and enlarges it by a factor of 2. No interpolation is "
"done."
-msgstr "拉伸图åƒå¹¶å°†å…¶æ”¾å¤§2å€ï¼Œä¸è¿›è¡Œæ’值。"
+msgstr "拉伸图åƒå¹¶å°†å…¶æ”¾å¤§ 2 å€ï¼Œä¸è¿›è¡Œæ’值。"
#: doc/classes/Image.xml
msgid "Fills the image with [code]color[/code]."
@@ -35994,7 +36066,7 @@ msgstr ""
"错误。\n"
"[b]注æ„:[/b]多级æ¸è¿œçº¹ç†çš„ç”Ÿæˆæ˜¯åœ¨ CPU 上完æˆçš„,是å•线程的,并且[i]总是[/i]"
"在主线程上完æˆã€‚è¿™æ„味ç€åœ¨æ¸¸æˆè¿‡ç¨‹ä¸­ç”Ÿæˆå¤šçº§æ¸è¿œçº¹ç†ä¼šå¯¼è‡´æ˜Žæ˜¾çš„å¡é¡¿ï¼Œå³ä½¿ä»Ž "
-"[Thread] 调用[method generate_mipmaps]。"
+"[Thread] 调用 [method generate_mipmaps]。"
#: doc/classes/Image.xml
msgid "Returns a copy of the image's raw data."
@@ -36208,14 +36280,14 @@ msgid ""
"img.set_pixel(x, y, color) # Does not have an effect\n"
"[/codeblock]"
msgstr ""
-"如果图åƒè¢«é”定,设置[code](x, y)[/code]处åƒç´ çš„[Color]。例å­:\n"
+"如果图åƒè¢«é”定,设置 [code](x, y)[/code] 处åƒç´ çš„ [Color]。例å­:\n"
"[codeblock]\n"
"var img = Image.new()\n"
"img.create(img_width, img_height, false, Image.FORMAT_RGBA8)\n"
"img.lock()\n"
-"img.set_pixel(x, y, color) # Works\n"
+"img.set_pixel(x, y, color) # 有效\n"
"img.unlock()\n"
-"img.set_pixel(x, y, color) # Does not have an effect\n"
+"img.set_pixel(x, y, color) # 无效\n"
"[/codeblock]"
#: doc/classes/Image.xml
@@ -36231,20 +36303,20 @@ msgid ""
"img.set_pixelv(Vector2(x, y), color) # Does not have an effect\n"
"[/codeblock]"
msgstr ""
-"如果图åƒè¢«é”定,设置[code](dst.x, dst.y)[/code]处的åƒç´ çš„[Color]。注æ„,"
-"[code]dst[/code]值必须是整数。例:\n"
+"如果图åƒè¢«é”定,设置 [code](dst.x, dst.y)[/code] 处的åƒç´ çš„ [Color]。注æ„,"
+"[code]dst[/code] 值必须是整数。示例:\n"
"[codeblock]\n"
"var img = Image.new()\n"
"img.create(img_width, img_height, false, Image.FORMAT_RGBA8)\n"
"img.lock()\n"
-"img.set_pixelv(Vector2(x, y), color) # Works\n"
+"img.set_pixelv(Vector2(x, y), color) # 有效\n"
"img.unlock()\n"
-"img.set_pixelv(Vector2(x, y), color) # Does not have an effect\n"
+"img.set_pixelv(Vector2(x, y), color) # 无效\n"
"[/codeblock]"
#: doc/classes/Image.xml
msgid "Shrinks the image by a factor of 2."
-msgstr "将图åƒç¼©å°2å€ã€‚"
+msgstr "将图åƒç¼©å° 2 å€ã€‚"
#: doc/classes/Image.xml
msgid "Converts the raw data from the sRGB colorspace to a linear scale."
@@ -36270,7 +36342,7 @@ msgstr "[Image] 资æºå…许的最大高度。"
#: doc/classes/Image.xml
msgid "Texture format with a single 8-bit depth representing luminance."
-msgstr "çº¹ç†æ ¼å¼ï¼Œå…·æœ‰ä»£è¡¨äº®åº¦çš„å•一8使·±åº¦ã€‚"
+msgstr "çº¹ç†æ ¼å¼ï¼Œå…·æœ‰ä»£è¡¨äº®åº¦çš„å•一 8 使·±åº¦ã€‚"
#: doc/classes/Image.xml
msgid ""
@@ -36348,16 +36420,16 @@ msgid ""
"OpenGL texture format [code]GL_RGB32F[/code] where there are three "
"components, each a 32-bit floating-point values."
msgstr ""
-"OpenGLçº¹ç†æ ¼å¼[code]GL_RGB32F[/code],其中有三个部分,æ¯ä¸ªéƒ¨åˆ†éƒ½æ˜¯32使µ®ç‚¹"
-"值。"
+"OpenGL çº¹ç†æ ¼å¼ [code]GL_RGB32F[/code],其中有三个部分,æ¯ä¸ªéƒ¨åˆ†éƒ½æ˜¯ 32 使µ®"
+"点值。"
#: doc/classes/Image.xml
msgid ""
"OpenGL texture format [code]GL_RGBA32F[/code] where there are four "
"components, each a 32-bit floating-point values."
msgstr ""
-"OpenGLçº¹ç†æ ¼å¼[code]GL_RGBA32F[/code],其中有四个部分,æ¯ä¸ªéƒ¨åˆ†éƒ½æ˜¯32使µ®ç‚¹"
-"值。"
+"OpenGL çº¹ç†æ ¼å¼ [code]GL_RGBA32F[/code],其中有四个部分,æ¯ä¸ªéƒ¨åˆ†éƒ½æ˜¯ 32 使µ®"
+"点值。"
#: doc/classes/Image.xml
msgid ""
@@ -36645,7 +36717,7 @@ msgstr "表示 [enum Format] 枚举的大å°ã€‚"
msgid ""
"Performs nearest-neighbor interpolation. If the image is resized, it will be "
"pixelated."
-msgstr "执行最近邻æ’值.如果调整图åƒå¤§å°,它将被åƒç´ åŒ–."
+msgstr "执行最近邻æ’值。如果调整图åƒå¤§å°ï¼Œå®ƒå°†è¢«åƒç´ åŒ–。"
#: doc/classes/Image.xml
msgid ""
@@ -36662,8 +36734,8 @@ msgid ""
"This mode often gives better results compared to [constant "
"INTERPOLATE_BILINEAR], at the cost of being slower."
msgstr ""
-"执行三次æ’值.如果调整图åƒå¤§å°,则图åƒå°†æ¨¡ç³Š.与[constant INTERPOLATE_BILINEAR]"
-"相比,此模å¼é€šå¸¸ä¼šäº§ç”Ÿæ›´å¥½çš„结果,但代价是速度较慢."
+"执行三次æ’值。如果调整图åƒå¤§å°ï¼Œåˆ™å›¾åƒå°†æ¨¡ç³Šã€‚与 [constant "
+"INTERPOLATE_BILINEAR] 相比,此模å¼é€šå¸¸ä¼šäº§ç”Ÿæ›´å¥½çš„结果,但代价是速度较慢。"
#: doc/classes/Image.xml
msgid ""
@@ -36695,36 +36767,36 @@ msgid ""
"Performs Lanczos interpolation. This is the slowest image resizing mode, but "
"it typically gives the best results, especially when downscalng images."
msgstr ""
-"执行Lanczosæ’值.这是最慢的图åƒè°ƒæ•´å¤§å°æ¨¡å¼,但通常å¯ä»¥æä¾›æœ€ä½³æ•ˆæžœ,尤其是在缩"
-"å°å›¾åƒæ—¶."
+"执行 Lanczos æ’值。这是最慢的图åƒè°ƒæ•´å¤§å°æ¨¡å¼ï¼Œä½†é€šå¸¸å¯ä»¥æä¾›æœ€ä½³æ•ˆæžœï¼Œå°¤å…¶æ˜¯"
+"在缩å°å›¾åƒæ—¶ã€‚"
#: doc/classes/Image.xml
msgid "Image does not have alpha."
-msgstr "图片没有Alpha通é“."
+msgstr "图片没有 Alpha 通é“。"
#: doc/classes/Image.xml
msgid "Image stores alpha in a single bit."
-msgstr "图åƒå°†Alpha存储在å•个bit中."
+msgstr "图åƒå°† Alpha 存储在å•个 bit 中。"
#: doc/classes/Image.xml
msgid "Image uses alpha."
-msgstr "图åƒä½¿ç”¨é˜¿å°”法。"
+msgstr "图åƒä½¿ç”¨ Alpha。"
#: doc/classes/Image.xml
msgid "Use S3TC compression."
-msgstr "使用S3TC压缩。"
+msgstr "使用 S3TC 压缩。"
#: doc/classes/Image.xml
msgid "Use PVRTC2 compression."
-msgstr "使用PVRTC2压缩。"
+msgstr "使用 PVRTC2 压缩。"
#: doc/classes/Image.xml
msgid "Use PVRTC4 compression."
-msgstr "使用PVRTC4压缩。"
+msgstr "使用 PVRTC4 压缩。"
#: doc/classes/Image.xml
msgid "Use ETC compression."
-msgstr "使用ETC压缩。"
+msgstr "使用 ETC 压缩。"
#: doc/classes/Image.xml
msgid "Use ETC2 compression."
@@ -36796,7 +36868,7 @@ msgid ""
"hardware limitations."
msgstr ""
"基于图片的纹ç†ï¼Œè¦æ˜¾ç¤ºä¸€ä¸ªå›¾ç‰‡ï¼Œå¿…须使用 [method create_from_image] 方法æ¥åˆ›"
-"建一个 [ImageTexture] å›¾ç‰‡çº¹ç†æ•°æ®:\n"
+"建一个 [ImageTexture] å›¾ç‰‡çº¹ç†æ•°æ®ï¼š\n"
"[codeblock]\n"
"var texture = ImageTexture.new()\n"
"var image = Image.new()\n"
@@ -36901,7 +36973,7 @@ msgid ""
"[Image] data is compressed with a lossy algorithm. You can set the storage "
"quality with [member lossy_quality]."
msgstr ""
-"[Image] æ•°æ®æ˜¯ç”¨æœ‰æŸç®—法压缩的。 ä½ å¯ä»¥ç”¨ [member lossy_quality] 设置存储质"
+"[Image] æ•°æ®æ˜¯ç”¨æœ‰æŸç®—法压缩的。你å¯ä»¥ç”¨ [member lossy_quality] 设置存储质"
"é‡ã€‚"
#: doc/classes/ImageTexture.xml
@@ -36943,7 +37015,7 @@ msgstr ""
#: doc/classes/ImmediateGeometry.xml
msgid ""
"Simple helper to draw an UV sphere with given latitude, longitude and radius."
-msgstr "用于绘制给定ç»çº¬åº¦å’ŒåŠå¾„çš„UVçƒä½“的简å•辅助工具。"
+msgstr "用于绘制给定ç»çº¬åº¦å’ŒåŠå¾„çš„ UV çƒä½“的简å•辅助工具。"
#: doc/classes/ImmediateGeometry.xml
msgid ""
@@ -36963,11 +37035,11 @@ msgstr ""
#: doc/classes/ImmediateGeometry.xml
msgid "Clears everything that was drawn using begin/end."
-msgstr "清除使用begin/end绘制的一切内容。"
+msgstr "清除使用 begin/end 绘制的一切内容。"
#: doc/classes/ImmediateGeometry.xml
msgid "Ends a drawing context and displays the results."
-msgstr "ç»“æŸæ­£åœ¨ç»˜åˆ¶çš„context并显示其结果。"
+msgstr "ç»“æŸæ­£åœ¨ç»˜åˆ¶çš„上下文并显示其结果。"
#: doc/classes/ImmediateGeometry.xml
msgid "The current drawing color."
@@ -37019,10 +37091,10 @@ msgid ""
"[method parse_input_event] instead."
msgstr ""
"这将模拟按下指定的按键动作。\n"
-"强度å¯ä»¥ç”¨äºŽéžå¸ƒå°”è¿ç®—的动作,它的范围在0到1之间,代表给定动作的力度。\n"
-"[b]注æ„:[/b]这个方法ä¸ä¼šå¼•起任何[method Node._input]调用。它旨在与[method "
-"is_action_pressed]和[method is_action_just_pressed]一起使用。如果你想模拟"
-"[code]_input[/code],请使用[method parse_input_event]代替。"
+"强度å¯ä»¥ç”¨äºŽéžå¸ƒå°”è¿ç®—的动作,它的范围在 0 到 1 之间,代表给定动作的力度。\n"
+"[b]注æ„:[/b]这个方法ä¸ä¼šå¼•起任何 [method Node._input] 调用。它旨在与 "
+"[method is_action_pressed] 和 [method is_action_just_pressed] 一起使用。如果"
+"你想模拟 [code]_input[/code],请使用 [method parse_input_event] 代替。"
#: doc/classes/Input.xml
msgid "If the specified action is already pressed, this will release it."
@@ -37111,8 +37183,8 @@ msgid ""
"get_action_strength(\"negative_action\")[/code]."
msgstr ""
"通过指定两个动作æ¥èŽ·å–轴的输入,一个是负的,一个是正的。\n"
-"这是写[code]Input.get_action_strength(\"positive_action\")-Input."
-"get_action_strength(\"negative_action\")[/code]的简写。"
+"这是 [code]Input.get_action_strength(\"positive_action\")-Input."
+"get_action_strength(\"negative_action\")[/code] 的简写。"
#: doc/classes/Input.xml
msgid ""
@@ -37122,7 +37194,7 @@ msgstr "返回一个 [Array],包å«å½“剿‰€æœ‰è¿žæŽ¥æ‰‹æŸ„的设备 ID。"
#: doc/classes/Input.xml
msgid "Returns the currently assigned cursor shape (see [enum CursorShape])."
-msgstr "è¿”å›žå½“å‰æŒ‡å®šçš„光标形状(å‚阅 [enum CursorShape])。"
+msgstr "è¿”å›žå½“å‰æŒ‡å®šçš„å…‰æ ‡å½¢çŠ¶ï¼ˆè§ [enum CursorShape])。"
#: doc/classes/Input.xml
msgid ""
@@ -37133,11 +37205,11 @@ msgid ""
"measurement for each axis is m/s² while on iOS it's a multiple of the "
"Earth's gravitational acceleration [code]g[/code] (~9.81 m/s²)."
msgstr ""
-"如果设备有加速度传感器,则返回设备的é‡åŠ›ã€‚å¦åˆ™ï¼Œè¯¥æ–¹æ³•返回[constant Vector3."
+"如果设备有加速度传感器,则返回设备的é‡åŠ›ã€‚å¦åˆ™ï¼Œè¯¥æ–¹æ³•返回 [constant Vector3."
"ZERO]。\n"
-"[b]注æ„:[/b]这个方法åªåœ¨Androidå’ŒiOS上工作。在其他平å°ä¸Šï¼Œå®ƒæ€»æ˜¯è¿”回"
-"[constant Vector3.ZERO]。在Android上,æ¯ä¸ªè½´çš„æµ‹é‡å•使˜¯m/s²,而在iOS上,它是"
-"地çƒé‡åŠ›åŠ é€Ÿåº¦çš„å€æ•°[code]g[/code](~9.81 m/s²)。"
+"[b]注æ„:[/b]这个方法åªåœ¨ Android å’Œ iOS 上工作。在其他平å°ä¸Šï¼Œå®ƒæ€»æ˜¯è¿”回 "
+"[constant Vector3.ZERO]。在 Android 上,æ¯ä¸ªè½´çš„æµ‹é‡å•使˜¯ m/s²,而在 iOS "
+"上,它是地çƒé‡åŠ›åŠ é€Ÿåº¦çš„å€æ•° [code]g[/code](~9.81 m/s²)。"
#: doc/classes/Input.xml
msgid ""
@@ -37147,16 +37219,16 @@ msgid ""
"[b]Note:[/b] This method only works on Android and iOS. On other platforms, "
"it always returns [constant Vector3.ZERO]."
msgstr ""
-"如果设备有陀螺仪传感器,则返回围绕设备Xã€Yã€Z轴的旋转速率,å•ä½ä¸ºrad/s。å¦"
-"则,该方法返回[constant Vector3.ZERO]。\n"
-"[b]注æ„:[/b]这个方法åªåœ¨Androidå’ŒiOS上工作。在其他平å°ä¸Šï¼Œæ€»æ˜¯è¿”回[constant "
-"Vector3.ZERO]。"
+"如果设备有陀螺仪传感器,则返回围绕设备 Xã€Yã€Z 轴的旋转速率,å•ä½ä¸º rad/s。å¦"
+"则,该方法返回 [constant Vector3.ZERO]。\n"
+"[b]注æ„:[/b]这个方法åªåœ¨ Android å’Œ iOS 上工作。在其他平å°ä¸Šï¼Œæ€»æ˜¯è¿”回 "
+"[constant Vector3.ZERO]。"
#: doc/classes/Input.xml
msgid ""
"Returns the current value of the joypad axis at given index (see [enum "
"JoystickList])."
-msgstr "è¿”å›žç»™å®šç´¢å¼•çš„æ¸¸æˆæ‰‹æŸ„轴的当å‰å€¼ï¼Œå‚阅[enum JoystickList]。"
+msgstr "è¿”å›žç»™å®šç´¢å¼•çš„æ¸¸æˆæ‰‹æŸ„轴的当å‰å€¼ï¼ˆè§ [enum JoystickList])。"
#: doc/classes/Input.xml
msgid "Returns the index of the provided axis name."
@@ -37177,15 +37249,16 @@ msgid ""
"Receives a gamepad button from [enum JoystickList] and returns its "
"equivalent name as a string."
msgstr ""
-"从[enum JoystickList]ä¸­æŽ¥æ”¶æ¸¸æˆæ‰‹æŸ„按钮,并将其对应的å称作为一个字符串返回。"
+"从 [enum JoystickList] ä¸­æŽ¥æ”¶æ¸¸æˆæ‰‹æŸ„按钮,并将其对应的å称作为一个字符串返"
+"回。"
#: doc/classes/Input.xml
msgid ""
"Returns a SDL2-compatible device GUID on platforms that use gamepad "
"remapping. Returns [code]\"Default Gamepad\"[/code] otherwise."
msgstr ""
-"åœ¨ä½¿ç”¨æ¸¸æˆæ‰‹æŸ„釿˜ å°„的平å°ä¸Šè¿”回一个SDL2兼容的设备GUID。å¦åˆ™è¿”回 "
-"[code]\"Default Gamepad\"[/code]é»˜è®¤æ¸¸æˆæ‰‹æŸ„。"
+"åœ¨ä½¿ç”¨æ¸¸æˆæ‰‹æŸ„釿˜ å°„的平å°ä¸Šè¿”回一个 SDL2 兼容的设备 GUID。å¦åˆ™è¿”回 "
+"[code]\"Default Gamepad\"[/code] é»˜è®¤æ¸¸æˆæ‰‹æŸ„。"
#: doc/classes/Input.xml
msgid "Returns the name of the joypad at the specified device index."
@@ -37426,7 +37499,7 @@ msgstr ""
#: doc/classes/Input.xml
msgid ""
"Removes all mappings from the internal database that match the given GUID."
-msgstr "从内部数æ®åº“中删除与给定GUID匹é…的所有映射."
+msgstr "从内部数æ®åº“中删除与给定 GUID 匹é…的所有映射。"
#: doc/classes/Input.xml
msgid ""
@@ -37436,9 +37509,9 @@ msgid ""
"[b]Note:[/b] This value can be immediately overwritten by the hardware "
"sensor value on Android and iOS."
msgstr ""
-"设置加速度传感器的加速度值。å¯ä»¥ç”¨äºŽåœ¨æ²¡æœ‰ç¡¬ä»¶ä¼ æ„Ÿå™¨çš„设备上进行调试,例如在"
-"PC上的编辑器中。\n"
-"[b]注æ„:[/b]这个值在Androidå’ŒiOS上å¯ç«‹å³è¢«ç¡¬ä»¶ä¼ æ„Ÿå™¨çš„值所覆盖。"
+"设置加速度传感器的加速度值。å¯ä»¥ç”¨äºŽåœ¨æ²¡æœ‰ç¡¬ä»¶ä¼ æ„Ÿå™¨çš„设备上进行调试,例如在 "
+"PC 上的编辑器中。\n"
+"[b]注æ„:[/b]这个值在 Android å’Œ iOS 上å¯ç«‹å³è¢«ç¡¬ä»¶ä¼ æ„Ÿå™¨çš„值所覆盖。"
#: doc/classes/Input.xml
msgid ""
@@ -37454,15 +37527,15 @@ msgid ""
"[b]Uncompressed[/b] compression modes are supported. The [b]Video RAM[/b] "
"compression mode can't be used for custom cursors."
msgstr ""
-"设置一个自定义鼠标光标图åƒï¼Œè¯¥å›¾åƒä»…当游æˆçª—å£å†…å¯è§ã€‚还å¯ä»¥æŒ‡å®šçƒ­ç‚¹ã€‚å°†"
-"[code]null[/code]传递给image傿•°å°†é‡ç½®ä¸ºç³»ç»Ÿå…‰æ ‡ã€‚有关详细信æ¯ï¼Œè¯·å‚阅 [enum "
-"CursorShape] 形状列表。\n"
-"[code]image[/code]的大å°å¿…é¡»å°äºŽ256×256。\n"
-"[code]hotspot[/code]的大å°å¿…须在[code]image[/code]的范围内。\n"
-"[b]注æ„:[/b]䏿”¯æŒAnimatedTexture作为自定义鼠标光标。如果使用"
+"设置一个自定义鼠标光标图åƒï¼Œè¯¥å›¾åƒä»…当游æˆçª—å£å†…å¯è§ã€‚还å¯ä»¥æŒ‡å®šçƒ­ç‚¹ã€‚å°† "
+"[code]null[/code] 传递给 image 傿•°å°†é‡ç½®ä¸ºç³»ç»Ÿå…‰æ ‡ã€‚有关详细信æ¯ï¼Œè¯·å‚阅 "
+"[enum CursorShape] 形状列表。\n"
+"[code]image[/code] 的大å°å¿…é¡»å°äºŽ 256×256。\n"
+"[code]hotspot[/code] 的大å°å¿…须在 [code]image[/code] 的范围内。\n"
+"[b]注æ„:[/b]䏿”¯æŒ AnimatedTexture 作为自定义鼠标光标。如果使用 "
"[AnimatedTexture],将仅显示第一帧。\n"
"[b]注æ„:[/b]仅支æŒä»¥[b]æ— æŸ[/b],[b]有æŸ[/b]或[b]未压缩[/b]压缩模å¼å¯¼å…¥çš„图"
-"åƒã€‚[b]Video RAM[/b]压缩模å¼ä¸èƒ½ç”¨äºŽè‡ªå®šä¹‰å…‰æ ‡ã€‚"
+"åƒã€‚[b]Video RAM[/b] 压缩模å¼ä¸èƒ½ç”¨äºŽè‡ªå®šä¹‰å…‰æ ‡ã€‚"
#: doc/classes/Input.xml
msgid ""
@@ -37473,7 +37546,7 @@ msgid ""
"[b]Note:[/b] This method generates an [InputEventMouseMotion] to update "
"cursor immediately."
msgstr ""
-"è®¾ç½®è§†çª—ä¸­ä½¿ç”¨çš„é»˜è®¤å…‰æ ‡å½¢çŠ¶ï¼Œè€Œä¸æ˜¯ [constant CURSOR_ARROW]。\n"
+"è®¾ç½®è¯¥è§†åŒºä¸­ä½¿ç”¨çš„é»˜è®¤å…‰æ ‡å½¢çŠ¶ï¼Œè€Œä¸æ˜¯ [constant CURSOR_ARROW]。\n"
"[b]注æ„:[/b]å¦‚æžœè¦æ›´æ”¹ [Control] 节点的默认光标形状,请改用 [member Control."
"mouse_default_cursor_shape]。\n"
"[b]注æ„:[/b]这个方法会生æˆä¸€ä¸ª [InputEventMouseMotion] ä»¥ç«‹å³æ›´æ–°å…‰æ ‡ã€‚"
@@ -37526,9 +37599,9 @@ msgid ""
"is recommended to restart an effect if it has to be played for more than a "
"few seconds."
msgstr ""
-"å¼€å§‹æŒ¯åŠ¨æ¸¸æˆæ‰‹æŸ„。手柄通常带有两个隆隆声电机,一强一弱。 "
+"å¼€å§‹æŒ¯åŠ¨æ¸¸æˆæ‰‹æŸ„。手柄通常带有两个隆隆声电机,一强一弱。"
"[code]weak_magnitude[/code] 弱震级是弱电机的强度(0 到 1 之间),"
-"[code]strong_magnitude[/code] 强震级是强电机的强度(0 到 1 之间)。 "
+"[code]strong_magnitude[/code] 强震级是强电机的强度(0 到 1 之间)。"
"[code]duration[/code] 是效果的æŒç»­æ—¶é—´ï¼ˆä»¥ç§’为å•ä½ï¼‰ï¼ˆæŒç»­æ—¶é—´ä¸º 0 å°†å°è¯•æ— é™"
"期地播放振动)。\n"
"[b]注æ„:[/b]å¹¶éžæ‰€æœ‰ç¡¬ä»¶éƒ½å…¼å®¹é•¿æ•ˆæžœæŒç»­æ—¶é—´ï¼›å¦‚果必须播放超过几秒钟的效果,"
@@ -37547,8 +37620,8 @@ msgid ""
"later."
msgstr ""
"振动 Android 和 iOS 设备。\n"
-"[b]注æ„:[/b]Android 需è¦å¯¼å‡ºè®¾ç½®ä¸­çš„ [code]VIBRATE[/code] æƒé™ã€‚ iOS 䏿”¯æŒ"
-"æŒç»­æ—¶é—´ã€‚\n"
+"[b]注æ„:[/b]Android 需è¦å¯¼å‡ºè®¾ç½®ä¸­çš„ [code]VIBRATE[/code] æƒé™ã€‚iOS 䏿”¯æŒæŒ"
+"续时间。\n"
"[b]注æ„:[/b]在 iOS å¹³å°ä¸Šï¼ŒiOS 13 åŠä¹‹åŽçš„ç‰ˆæœ¬æ‰æ”¯æŒæŒ‡å®šæŒç»­æ—¶é—´ã€‚"
#: doc/classes/Input.xml
@@ -37568,6 +37641,7 @@ msgid "Controls the mouse mode. See [enum MouseMode] for more information."
msgstr "控制鼠标模å¼ã€‚详情请å‚阅 [enum MouseMode]。"
#: doc/classes/Input.xml
+#, fuzzy
msgid ""
"If [code]true[/code], similar input events sent by the operating system are "
"accumulated. When input accumulation is enabled, all input events generated "
@@ -37578,14 +37652,19 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
"如果为 [code]true[/code],会对æ“作系统å‘é€çš„类似输入事件进行累积。当å¯ç”¨è¾“å…¥"
"累积时,在一帧中产生的所有输入事件将被åˆå¹¶ï¼Œå¹¶åœ¨è¯¥å¸§å®Œæˆæ¸²æŸ“æ—¶å‘出。因此,这"
"é™åˆ¶äº†æ¯ç§’的输入方法调用次数,使之与渲染FPS相一致。\n"
-"输入累加在默认情况下是å¯ç”¨çš„。它å¯ä»¥è¢«ç¦ç”¨ï¼Œå°†ä»¥å¢žåŠ CPU使用率为代价,获得ç¨å¾®"
+"输入累积在默认情况下是å¯ç”¨çš„。它å¯ä»¥è¢«ç¦ç”¨ï¼Œå°†ä»¥å¢žåŠ CPU使用率为代价,获得ç¨å¾®"
"æ›´ç²¾ç¡®åŠæ›´çµæ•的输入。在需è¦è‡ªç”±ç»˜åˆ¶çº¿æ¡çš„åº”ç”¨ä¸­ï¼Œä¸€èˆ¬åº”ç”¨åœ¨ç”¨æˆ·ç»˜åˆ¶çº¿æ¡æ—¶ç¦"
-"用输入累加,以获得紧跟实际输入的结果。"
+"用输入累加,以获得紧跟实际输入的结果。\n"
+"[b]注æ„:[/b]默认[i]ç¦ç”¨[/i]输入累积是出于å‘åŽå…¼å®¹çš„缘故。然而我们推è那些ä¸"
+"需è¦éžå¸¸æ´»è·ƒè¾“入的游æˆå°†å…¶å¯ç”¨ï¼Œèƒ½å¤Ÿé™ä½Ž CPU å ç”¨ã€‚"
#: doc/classes/Input.xml
msgid "Emitted when a joypad device has been connected or disconnected."
@@ -37705,9 +37784,9 @@ msgid ""
"CURSOR_BDIAGSIZE]. It tells the user they can resize the window or the panel "
"both horizontally and vertically."
msgstr ""
-"窗å£è°ƒæ•´å¤§å°çš„光标。是一个åŒå¤´çš„箭头,从左上角到å³ä¸‹è§’,与[constant "
-"CURSOR_BDIAGSIZE]相å。它告诉用户他们å¯ä»¥åœ¨æ°´å¹³å’Œåž‚ç›´æ–¹å‘ä¸Šè°ƒæ•´çª—å£æˆ–颿¿çš„大"
-"å°ã€‚"
+"窗å£è°ƒæ•´å¤§å°çš„光标。是一个åŒå¤´çš„箭头,从左上角到å³ä¸‹è§’,与 [constant "
+"CURSOR_BDIAGSIZE] 相å。它告诉用户他们å¯ä»¥åœ¨æ°´å¹³å’Œåž‚ç›´æ–¹å‘ä¸Šè°ƒæ•´çª—å£æˆ–颿¿çš„"
+"大å°ã€‚"
#: doc/classes/Input.xml
msgid "Move cursor. Indicates that something can be moved."
@@ -37723,7 +37802,7 @@ msgstr "垂直拆分鼠标光标。在 Windows 上,它与 [constant CURSOR_VSI
msgid ""
"Horizontal split mouse cursor. On Windows, it's the same as [constant "
"CURSOR_HSIZE]."
-msgstr "水平分割的鼠标光标。在Windows上,它与[constant CURSOR_HSIZE]相åŒã€‚"
+msgstr "水平分割的鼠标光标。在 Windows 上,它与 [constant CURSOR_HSIZE] 相åŒã€‚"
#: doc/classes/Input.xml
msgid "Help cursor. Usually a question mark."
@@ -37735,7 +37814,7 @@ msgstr "通用输入事件。"
#: doc/classes/InputEvent.xml
msgid "Base class of all sort of input event. See [method Node._input]."
-msgstr "å„ç§è¾“入事件的基类。请å‚阅 [method Node._input]。"
+msgstr "å„ç§è¾“å…¥äº‹ä»¶çš„åŸºç±»ã€‚è§ [method Node._input]。"
#: doc/classes/InputEvent.xml
msgid "InputEvent"
@@ -37963,18 +38042,17 @@ msgstr ""
#: doc/classes/InputEventJoypadButton.xml
msgid "Button identifier. One of the [enum JoystickList] button constants."
-msgstr "按钮标识符。 [enum JoystickList] 按钮常é‡ä¹‹ä¸€ã€‚"
+msgstr "按钮标识符。[enum JoystickList] 按钮常é‡ä¹‹ä¸€ã€‚"
#: doc/classes/InputEventJoypadButton.xml
msgid ""
"If [code]true[/code], the button's state is pressed. If [code]false[/code], "
"the button's state is released."
msgstr ""
-"如果 [code]true[/code],按钮的状æ€è¢«æŒ‰ä¸‹ã€‚如果[code]false[/code],按钮的状æ€"
-"被释放。"
+"如果为 [code]true[/code],按钮的状æ€è¢«æŒ‰ä¸‹ã€‚如果为 [code]false[/code],按钮的"
+"状æ€è¢«é‡Šæ”¾ã€‚"
#: doc/classes/InputEventJoypadButton.xml
-#, fuzzy
msgid ""
"Represents the pressure the user puts on the button with their finger, if "
"the controller supports it. Ranges from [code]0[/code] to [code]1[/code]."
@@ -37994,7 +38072,8 @@ msgstr ""
msgid ""
"Stores information about joystick motions. One [InputEventJoypadMotion] "
"represents one axis at a time."
-msgstr "存储关于æ“纵æ†è¿åŠ¨çš„ä¿¡æ¯ã€‚一个[InputEventJoypadMotion]一次代表一个轴。"
+msgstr ""
+"存储关于æ“纵æ†è¿åŠ¨çš„ä¿¡æ¯ã€‚一个 [InputEventJoypadMotion] 一次代表一个轴。"
#: doc/classes/InputEventJoypadMotion.xml
msgid "Axis identifier. Use one of the [enum JoystickList] axis constants."
@@ -38006,8 +38085,8 @@ msgid ""
"[code]-1.0[/code] to [code]1.0[/code]. A value of [code]0[/code] means the "
"axis is in its resting position."
msgstr ""
-"æ“纵æ†åœ¨ç»™å®šè½´ä¸Šçš„当å‰ä½ç½®ã€‚该值范围从[code]-1.0[/code]到[code]1.0[/code]。值"
-"为[code]0[/code]æ„味ç€è½´å¤„äºŽé™æ­¢ä½ç½®ã€‚"
+"æ“纵æ†åœ¨ç»™å®šè½´ä¸Šçš„当å‰ä½ç½®ã€‚该值范围从 [code]-1.0[/code] 到 [code]1.0[/"
+"code]。值为 [code]0[/code] æ„味ç€è½´å¤„äºŽé™æ­¢ä½ç½®ã€‚"
#: doc/classes/InputEventKey.xml
msgid "Input event type for keyboard events."
@@ -38028,8 +38107,8 @@ msgid ""
"get_physical_scancode_with_modifiers())[/code] where [code]event[/code] is "
"the [InputEventKey]."
msgstr ""
-"返回与修改键组åˆçš„ç‰©ç†æ‰«æç ï¼Œä¾‹å¦‚ [code]Shift[/code] 或 [code]Alt[/code]。请"
-"å‚阅 [InputEventWithModifiers]。\n"
+"返回与修改键组åˆçš„ç‰©ç†æ‰«æç ï¼Œä¾‹å¦‚ [code]Shift[/code] 或 [code]Alt[/code]。å¦"
+"请å‚阅 [InputEventWithModifiers]。\n"
"è¦èŽ·å¾—å¸¦æœ‰ä¿®é¥°ç¬¦çš„ [InputEventKey] 的人类å¯è¯»è¡¨ç¤ºï¼Œè¯·ä½¿ç”¨ [code]OS."
"get_scancode_string(event.get_physical_scancode_with_modifiers())[/code] å…¶"
"中 [code]event[/code] 是 [InputEventKey]。"
@@ -38043,7 +38122,7 @@ msgid ""
"get_scancode_with_modifiers())[/code] where [code]event[/code] is the "
"[InputEventKey]."
msgstr ""
-"返回与 [code]Shift[/code] 或 [code]Alt[/code] 等修饰键组åˆçš„æ‰«æç ã€‚请å‚阅 "
+"返回与 [code]Shift[/code] 或 [code]Alt[/code] 等修饰键组åˆçš„æ‰«æç ã€‚å¦è¯·å‚阅 "
"[InputEventWithModifiers]。\n"
"è¦èŽ·å¾—å¸¦æœ‰ä¿®é¥°ç¬¦çš„ [InputEventKey] 的人类å¯è¯»è¡¨ç¤ºï¼Œè¯·ä½¿ç”¨ [code]OS."
"get_scancode_string(event.get_scancode_with_modifiers())[/code] 其中 "
@@ -38054,7 +38133,7 @@ msgid ""
"If [code]true[/code], the key was already pressed before this event. It "
"means the user is holding the key down."
msgstr ""
-"如果 [code]true[/code],则该键在此事件之å‰å·²è¢«æŒ‰ä¸‹ã€‚è¿™æ„味ç€ç”¨æˆ·æ­£åœ¨æŒ‰ä½è¯¥"
+"如果为 [code]true[/code],则该键在此事件之å‰å·²è¢«æŒ‰ä¸‹ã€‚è¿™æ„味ç€ç”¨æˆ·æ­£åœ¨æŒ‰ä½è¯¥"
"键。"
#: doc/classes/InputEventKey.xml
@@ -38077,8 +38156,8 @@ msgid ""
"If [code]true[/code], the key's state is pressed. If [code]false[/code], the "
"key's state is released."
msgstr ""
-"如果[code]true[/code]ï¼ŒæŒ‰é”®çš„çŠ¶æ€æ˜¯è¢«æŒ‰ä¸‹ã€‚如果[code]false[/code],该键的状æ€"
-"被释放。"
+"如果为 [code]true[/code]ï¼ŒæŒ‰é”®çš„çŠ¶æ€æ˜¯è¢«æŒ‰ä¸‹ã€‚如果为 [code]false[/code],该键"
+"的状æ€è¢«é‡Šæ”¾ã€‚"
#: doc/classes/InputEventKey.xml
msgid ""
@@ -38275,17 +38354,17 @@ msgstr "鼠标按钮事件的输入事件类型。"
#: doc/classes/InputEventMouseButton.xml
msgid "Contains mouse click information. See [method Node._input]."
-msgstr "包å«é¼ æ ‡ç‚¹å‡»ä¿¡æ¯ã€‚è§[method Node._input]。"
+msgstr "包å«é¼ æ ‡ç‚¹å‡»ä¿¡æ¯ã€‚è§ [method Node._input]。"
#: doc/classes/InputEventMouseButton.xml
msgid ""
"The mouse button identifier, one of the [enum ButtonList] button or button "
"wheel constants."
-msgstr "鼠标按钮标识符,是[enum ButtonList] 按钮或按钮滚轮常é‡ä¹‹ä¸€ã€‚"
+msgstr "鼠标按钮标识符,是 [enum ButtonList] 按钮或按钮滚轮常é‡ä¹‹ä¸€ã€‚"
#: doc/classes/InputEventMouseButton.xml
msgid "If [code]true[/code], the mouse button's state is a double-click."
-msgstr "如果[code]true[/code]ï¼Œé¼ æ ‡æŒ‰é’®çš„çŠ¶æ€æ˜¯åŒå‡»ã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œé¼ æ ‡æŒ‰é’®çš„çŠ¶æ€æ˜¯åŒå‡»ã€‚"
#: doc/classes/InputEventMouseButton.xml
msgid ""
@@ -38294,8 +38373,8 @@ msgid ""
"only supported on some platforms; the reported sensitivity varies depending "
"on the platform. May be [code]0[/code] if not supported."
msgstr ""
-"事件的数é‡ï¼ˆæˆ–delta)。当用于高精度滚动事件时,这表示滚动é‡ï¼ˆåž‚直或水平)。这"
-"åªåœ¨ä¸€äº›å¹³å°ä¸Šè¢«æ”¯æŒï¼›æŠ¥å‘Šçš„çµæ•度因平å°ä¸åŒè€Œä¸åŒã€‚å¦‚æžœä¸æ”¯æŒï¼Œå¯èƒ½æ˜¯"
+"事件的数é‡ï¼ˆæˆ– delta)。当用于高精度滚动事件时,这表示滚动é‡ï¼ˆåž‚直或水平)。"
+"è¿™åªåœ¨ä¸€äº›å¹³å°ä¸Šè¢«æ”¯æŒï¼›æŠ¥å‘Šçš„çµæ•度因平å°ä¸åŒè€Œä¸åŒã€‚å¦‚æžœä¸æ”¯æŒï¼Œå¯èƒ½æ˜¯"
"[code]0[/code]。"
#: doc/classes/InputEventMouseButton.xml
@@ -38303,39 +38382,53 @@ msgid ""
"If [code]true[/code], the mouse button's state is pressed. If [code]false[/"
"code], the mouse button's state is released."
msgstr ""
-"如果[code]true[/code],鼠标按键的状æ€ä¸ºæŒ‰ä¸‹ã€‚如果[code]false[/code],鼠标按钮"
-"的状æ€è¢«é‡Šæ”¾ã€‚"
+"如果为 [code]true[/code],鼠标按键的状æ€ä¸ºæŒ‰ä¸‹ã€‚如果为 [code]false[/code],鼠"
+"标按钮的状æ€è¢«é‡Šæ”¾ã€‚"
#: doc/classes/InputEventMouseMotion.xml
msgid "Input event type for mouse motion events."
msgstr "鼠标移动事件的输入事件类型。"
#: doc/classes/InputEventMouseMotion.xml
+#, fuzzy
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
msgstr ""
-"包å«é¼ æ ‡å’Œç¬”çš„è¿åŠ¨ä¿¡æ¯ã€‚支æŒç›¸å¯¹ã€ç»å¯¹ä½ç½®å’Œé€Ÿåº¦ã€‚请å‚阅 [method Node."
-"_input]。\n"
-"[b]注æ„:[/b]默认情况下,这个事件最多åªèƒ½åœ¨æ¯ä¸€å¸§æ¸²æŸ“中å‘å‡ºä¸€æ¬¡ã€‚å¦‚æžœä½ éœ€è¦æ›´"
-"精确的输入报告,请将 [member Input.use_accumulated_input] 设为 [code]false[/"
-"code],让事件尽å¯èƒ½é¢‘ç¹åœ°å‘射。如果你使用 InputEventMouseMotion æ¥ç”»çº¿ï¼Œè¯·è€ƒ"
-"è™‘åŒæ—¶å®žçް [url=https://en.wikipedia.org/wiki/"
-"Bresenham%27s_line_algorithm]Bresenham 的线æ¡ç®—法[/url],以é¿å…在用户快速移动"
-"鼠标时出现å¯è§çš„线æ¡ç©ºéš™ã€‚"
+"包å«é¼ æ ‡å’Œç¬”çš„è¿åŠ¨ä¿¡æ¯ã€‚支æŒç›¸å¯¹ã€ç»å¯¹ä½ç½®å’Œé€Ÿåº¦ã€‚è§ [method Node._input]。\n"
+"[b]注æ„:[/b]默认情况下,这个事件能够æ¯å¸§å‘出多次,æä¾›æ›´ç²¾ç¡®çš„输入报告,但代"
+"价是更高的 CPU å ç”¨ã€‚ä½ å¯ä»¥å°† [member Input.use_accumulated_input] 设为 "
+"[code]true[/code],将æ¯å¸§ä¸­çš„多个事件åˆå¹¶ä¸ºå•个事件进行å‘é€ã€‚\n"
+"[b]注æ„:[/b]如果你使用 InputEventMouseMotion æ¥ç”»çº¿ï¼Œè¯·è€ƒè™‘åŒæ—¶å®žçް"
+"[url=https://zh.wikipedia.org/zh-cn/"
+"%E5%B8%83%E9%9B%B7%E6%A3%AE%E6%BC%A2%E5%A7%86%E7%9B%B4%E7%B7%9A%E6%BC%94%E7%AE%97%E6%B3%95]"
+"布雷森汉姆直线算法[/url],以é¿å…在用户快速移动鼠标时出现å¯è§çš„线æ¡ç©ºéš™ã€‚"
#: doc/classes/InputEventMouseMotion.xml
msgid "Mouse and input coordinates"
msgstr "é¼ æ ‡å’Œè¾“å…¥åæ ‡"
#: doc/classes/InputEventMouseMotion.xml
+#, fuzzy
+msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+"返回键盘布局的数é‡ã€‚\n"
+"[b]注æ„:[/b]本方法在Linuxã€macOSå’ŒWindows上实现。"
+
+#: doc/classes/InputEventMouseMotion.xml
msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
@@ -38350,8 +38443,8 @@ msgid ""
"code] when the user stops moving the mouse."
msgstr ""
"鼠标相对于å‰ä¸€ä¸ªä½ç½®çš„ä½ç½®ï¼ˆä¸Šä¸€å¸§çš„ä½ç½®ï¼‰ã€‚\n"
-"[b]注æ„:[/b]因为[InputEventMouseMotion]åªåœ¨é¼ æ ‡ç§»åŠ¨æ—¶å‘å‡ºï¼Œå½“ç”¨æˆ·åœæ­¢ç§»åЍ鼠"
-"标时,最åŽä¸€ä¸ªäº‹ä»¶çš„相对ä½ç½®ä¸ä¼šæ˜¯[code]Vector2(0, 0)[/code]。"
+"[b]注æ„:[/b]因为 [InputEventMouseMotion] åªåœ¨é¼ æ ‡ç§»åŠ¨æ—¶å‘å‡ºï¼Œå½“ç”¨æˆ·åœæ­¢ç§»åЍ"
+"鼠标时,最åŽä¸€ä¸ªäº‹ä»¶çš„相对ä½ç½®ä¸ä¼šæ˜¯ [code]Vector2(0, 0)[/code]。"
#: doc/classes/InputEventMouseMotion.xml
msgid "The mouse speed in pixels per second."
@@ -38364,8 +38457,8 @@ msgid ""
"toward the user. Ranges from [code]-1.0[/code] to [code]1.0[/code] for both "
"axes."
msgstr ""
-"代表笔的倾斜角度。正的Xåæ ‡å€¼è¡¨ç¤ºå‘å³å€¾æ–œã€‚正的Yåæ ‡å€¼è¡¨ç¤ºå‘用户自身倾斜。两"
-"个轴的范围是[code]-1.0[/code]到[code]1.0[/code]。"
+"代表笔的倾斜角度。正的 X åæ ‡å€¼è¡¨ç¤ºå‘å³å€¾æ–œã€‚正的Yåæ ‡å€¼è¡¨ç¤ºå‘用户自身倾斜。"
+"两个轴的范围是 [code]-1.0[/code] 到 [code]1.0[/code]。"
#: doc/classes/InputEventScreenDrag.xml
msgid ""
@@ -38374,7 +38467,7 @@ msgstr "å±å¹•拖动事件的输入事件类型。仅适用于移动设备。"
#: doc/classes/InputEventScreenDrag.xml
msgid "Contains screen drag information. See [method Node._input]."
-msgstr "包å«å±å¹•拖动信æ¯ã€‚è§[method Node._input]。"
+msgstr "包å«å±å¹•拖动信æ¯ã€‚è§ [method Node._input]。"
#: doc/classes/InputEventScreenDrag.xml
msgid "The drag event index in the case of a multi-drag event."
@@ -38407,13 +38500,13 @@ msgid ""
"Stores multi-touch press/release information. Supports touch press, touch "
"release and [member index] for multi-touch count and order."
msgstr ""
-"存储多点触摸的按压/释放信æ¯ã€‚支æŒè§¦æ‘¸æŒ‰åŽ‹ã€è§¦æ‘¸é‡Šæ”¾å’Œ[member index]的多点触摸"
-"计数和顺åºã€‚"
+"存储多点触摸的按压/释放信æ¯ã€‚支æŒè§¦æ‘¸æŒ‰åŽ‹ã€è§¦æ‘¸é‡Šæ”¾å’Œ [member index] 的多点触"
+"摸计数和顺åºã€‚"
#: doc/classes/InputEventScreenTouch.xml
msgid ""
"The touch index in the case of a multi-touch event. One index = one finger."
-msgstr "在多点触摸事件中的触摸指数。一个索引=一个手指。"
+msgstr "在多点触摸事件中的触摸指数。一个索引 = 一个手指。"
#: doc/classes/InputEventScreenTouch.xml
msgid "The touch position."
@@ -38424,8 +38517,8 @@ msgid ""
"If [code]true[/code], the touch's state is pressed. If [code]false[/code], "
"the touch's state is released."
msgstr ""
-"如果[code]true[/code],触摸的状æ€ä¸ºæŒ‰ä¸‹ã€‚如果[code]false[/code],触摸的状æ€è¢«"
-"释放。"
+"如果为 [code]true[/code],触摸的状æ€ä¸ºæŒ‰ä¸‹ã€‚如果为 [code]false[/code],触摸的"
+"状æ€è¢«é‡Šæ”¾ã€‚"
#: doc/classes/InputEventWithModifiers.xml
msgid "Base class for keys events with modifiers."
@@ -38477,15 +38570,15 @@ msgstr ""
#: doc/classes/InputMap.xml
msgid ""
"Adds an [InputEvent] to an action. This [InputEvent] will trigger the action."
-msgstr "给一个动作添加一个[InputEvent]。这个[InputEvent]将触å‘这个动作。"
+msgstr "ç»™æŸä¸ªåŠ¨ä½œæ·»åŠ ä¸€ä¸ª [InputEvent]。这个 [InputEvent] 将触å‘这个动作。"
#: doc/classes/InputMap.xml
msgid "Removes an [InputEvent] from an action."
-msgstr "从一个动作中删除一个[InputEvent]。"
+msgstr "从æŸä¸ªåŠ¨ä½œä¸­åˆ é™¤ä¸€ä¸ª [InputEvent]。"
#: doc/classes/InputMap.xml
msgid "Removes all events from an action."
-msgstr "从动作中删除所有事件。"
+msgstr "从æŸä¸ªåŠ¨ä½œä¸­åˆ é™¤æ‰€æœ‰äº‹ä»¶ã€‚"
#: doc/classes/InputMap.xml
msgid "Returns a deadzone value for the action."
@@ -38495,7 +38588,7 @@ msgstr "返回该æ“作的死区值。"
msgid ""
"Returns [code]true[/code] if the action has the given [InputEvent] "
"associated with it."
-msgstr "如果该动作有给定的[InputEvent]与之相关,则返回 [code]true[/code]。"
+msgstr "如果该动作有给定的 [InputEvent] 与之相关,则返回 [code]true[/code]。"
#: doc/classes/InputMap.xml
msgid "Sets a deadzone value for the action."
@@ -38508,12 +38601,13 @@ msgid ""
"An [InputEvent] can then be added to this action with [method "
"action_add_event]."
msgstr ""
-"在[InputMap]上添加一个空的动作,有一个å¯é…置的死区[code]deadzone[/code]。\n"
-"ç„¶åŽå¯ä»¥ç”¨[method action_add_event]给这个动作添加一个[InputEvent]。"
+"在 [InputMap] 上添加一个空的动作,有一个å¯é…置的死区 [code]deadzone[/"
+"code]。\n"
+"ç„¶åŽå¯ä»¥ç”¨ [method action_add_event] 给这个动作添加一个 [InputEvent]。"
#: doc/classes/InputMap.xml
msgid "Removes an action from the [InputMap]."
-msgstr "从[InputMap]中删除一个动作。"
+msgstr "从 [InputMap] 中删除一个动作。"
#: doc/classes/InputMap.xml
msgid ""
@@ -38547,21 +38641,21 @@ msgstr ""
#: doc/classes/InputMap.xml
msgid "Returns an array of all actions in the [InputMap]."
-msgstr "返回[InputMap]中所有动作的数组。"
+msgstr "返回 [InputMap] 中所有动作的数组。"
#: doc/classes/InputMap.xml
msgid ""
"Returns [code]true[/code] if the [InputMap] has a registered action with the "
"given name."
-msgstr "如果[InputMap]有一个给定å称的注册动作,返回 [code]true[/code]。"
+msgstr "如果 [InputMap] 有一个给定å称的注册动作,返回 [code]true[/code]。"
#: doc/classes/InputMap.xml
msgid ""
"Clears all [InputEventAction] in the [InputMap] and load it anew from "
"[ProjectSettings]."
msgstr ""
-"清除[InputMap]中的所有[InputEventAction],并从[ProjectSettings]é¡¹ç›®è®¾ç½®ä¸­é‡æ–°"
-"加载它。"
+"清除 [InputMap] 中的所有 [InputEventAction],并从 [ProjectSettings] 项目设置"
+"䏭釿–°åŠ è½½å®ƒã€‚"
#: doc/classes/InstancePlaceholder.xml
msgid "Placeholder for the root [Node] of a [PackedScene]."
@@ -38600,7 +38694,7 @@ msgid ""
"Object.call_deferred] if calling from a thread."
msgstr ""
"获å–调用 [method replace_by_instance] 时默认加载的 [PackedScene] èµ„æºæ–‡ä»¶çš„è·¯"
-"å¾„ã€‚ä¸æ˜¯çº¿ç¨‹å®‰å…¨çš„。如果从线程调用,请使用[method Object.call_deferred]。"
+"å¾„ã€‚ä¸æ˜¯çº¿ç¨‹å®‰å…¨çš„。如果从线程调用,请使用 [method Object.call_deferred]。"
#: doc/classes/InstancePlaceholder.xml
msgid ""
@@ -38687,14 +38781,14 @@ msgid ""
"method will ignore all non-number characters, so calling [code]int('1e3')[/"
"code] will return 13."
msgstr ""
-"将一个[String]å­—ç¬¦ä¸²å€¼è½¬æ¢æˆä¸€ä¸ªæ•´æ•°å€¼ï¼Œè¿™ä¸ªæ–¹æ³•是一个æ¥è‡ªå­—符串的整数解æž"
-"器,所以用一个无效的整数字符串调用这个方法将返回0,一个有效的字符串将是åƒ"
-"[code]'1.7'[/code]è¿™æ ·ã€‚è¿™ä¸ªæ–¹æ³•å°†å¿½ç•¥æ‰€æœ‰éžæ•°å­—字符,所以调用"
-"[code]int('1e3')[/code]将返回13。"
+"å°† [String] å­—ç¬¦ä¸²å€¼è½¬æ¢æˆæ•´æ•°å€¼ï¼Œè¿™ä¸ªæ–¹æ³•是字符串的整数解æžå™¨ï¼Œæ‰€ä»¥ç”¨æ— æ•ˆçš„"
+"整数字符串调用这个方法将返回 0ï¼Œæœ‰æ•ˆçš„å­—ç¬¦ä¸²å°†æ˜¯åƒ [code]'1.7'[/code] 这样"
+"çš„ã€‚è¿™ä¸ªæ–¹æ³•ä¼šå¿½ç•¥æ‰€æœ‰éžæ•°å­—字符,所以调用 [code]int('1e3')[/code] 会返回 "
+"13。"
#: doc/classes/InterpolatedCamera.xml
msgid "[i]Deprecated.[/i] Camera which moves toward another node."
-msgstr "[i] 已弃用。 [/i] å‘å¦ä¸€ä¸ªèŠ‚ç‚¹ç§»åŠ¨çš„ç›¸æœºã€‚"
+msgstr "[i] 已弃用。[/i]å‘å¦ä¸€ä¸ªèŠ‚ç‚¹ç§»åŠ¨çš„ç›¸æœºã€‚"
#: doc/classes/InterpolatedCamera.xml
msgid ""
@@ -38704,10 +38798,10 @@ msgid ""
"If it is not [member enabled] or does not have a valid target set, "
"InterpolatedCamera acts like a normal Camera."
msgstr ""
-"[i]å·²ç»å¼ƒç”¨ï¼ˆå°†åœ¨Godot 4.0 中删除)。[/i]æ’值相机是一ç§[Camera],å¯ä»¥å¹³ç¨³åœ°ç§»"
+"[i]已弃用(将在Godot 4.0 中删除)。[/i]æ’å€¼ç›¸æœºæ˜¯ä¸€ç§ [Camera],å¯ä»¥å¹³ç¨³åœ°ç§»"
"动,以匹é…目标节点的ä½ç½®å’Œæ—‹è½¬ã€‚\n"
-"å¦‚æžœå®ƒä¸æ˜¯[member enabled]或没有有效的目标集,InterpolatedCamera 的行为就åƒä¸€"
-"个正常的相机。"
+"å¦‚æžœå®ƒä¸æ˜¯ [member enabled] 或没有有效的目标集,InterpolatedCamera 的行为就åƒ"
+"一个正常的相机。"
#: doc/classes/InterpolatedCamera.xml
msgid "Sets the node to move toward and orient with."
@@ -38717,7 +38811,12 @@ msgstr "设置è¦ç§»åŠ¨å’Œå®šå‘的节点。"
msgid ""
"If [code]true[/code], and a target is set, the camera will move "
"automatically."
-msgstr "如果[code]true[/code],并且设置了目标,相机将自动移动。"
+msgstr "如果为 [code]true[/code],并且设置了目标,相机将自动移动。"
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr "该相机的处ç†å›žè°ƒã€‚è§ [enum InterpolatedCameraProcessMode]。"
#: doc/classes/InterpolatedCamera.xml
msgid ""
@@ -38727,7 +38826,7 @@ msgstr "相机å‘其目标移动的速度。较高的值将导致相机的è¿åЍ
#: doc/classes/InterpolatedCamera.xml
msgid "The target's [NodePath]."
-msgstr "目标的[NodePath]。"
+msgstr "目标的 [NodePath]。"
#: doc/classes/IntervalTweener.xml
msgid "Creates an idle interval in a [SceneTreeTween] animation."
@@ -38778,7 +38877,7 @@ msgstr ""
#: doc/classes/IP.xml
msgid "Returns all the user's current IPv4 and IPv6 addresses as an array."
-msgstr "以数组形å¼è¿”回所有用户的当å‰IPv4å’ŒIPv6地å€ã€‚"
+msgstr "以数组形å¼è¿”å›žæ‰€æœ‰ç”¨æˆ·çš„å½“å‰ IPv4 å’Œ IPv6 地å€ã€‚"
#: doc/classes/IP.xml
msgid ""
@@ -38794,14 +38893,14 @@ msgid ""
"}\n"
"[/codeblock]"
msgstr ""
-"以数组形å¼è¿”回所有网络适é…器(network adapters)。\n"
-"æ¯ä¸ªé€‚é…器是一个形å¼çš„字典。\n"
+"以数组形å¼è¿”回所有网络适é…器。\n"
+"æ¯ä¸ªé€‚é…器都是一个以下形å¼çš„字典:\n"
"[codeblock]\n"
"{\n"
" \"index\":\"1\", # 接å£ç´¢å¼•。\n"
" \"name\":\"eth0\", # 接å£å称。\n"
-" \"friendly\":\"Ethernet One\", # 一个å‹å¥½çš„å字(å¯èƒ½æ˜¯ç©ºçš„)。\n"
-" \"address\":[\"192.168.1.101\"], # 一个与此接å£ç›¸å…³çš„IPåœ°å€æ•°ç»„。\n"
+" \"friendly\":\"Ethernet One\", # å‹å¥½çš„å字(å¯èƒ½æ˜¯ç©ºçš„)。\n"
+" \"address\":[\"192.168.1.101\"], # 与此接å£ç›¸å…³çš„ IP åœ°å€æ•°ç»„。\n"
"}\n"
"[/codeblock]"
@@ -38836,8 +38935,8 @@ msgid ""
"method). The address type returned depends on the [enum Type] constant given "
"as [code]ip_type[/code]."
msgstr ""
-"åœ¨è§£æžæ—¶è¿”回一个给定的主机åçš„IPv4或IPv6地å€ï¼ˆé˜»å¡žç±»åž‹æ–¹æ³•)。返回的地å€ç±»åž‹"
-"å–决于作为[code]ip_type[/code]çš„[enum Type]常é‡ã€‚"
+"åœ¨è§£æžæ—¶è¿”回一个给定的主机åçš„ IPv4 或 IPv6 地å€ï¼ˆé˜»å¡žç±»åž‹æ–¹æ³•)。返回的地å€"
+"类型å–决于作为 [code]ip_type[/code] çš„ [enum Type] 常é‡ã€‚"
#: doc/classes/IP.xml
msgid ""
@@ -38878,7 +38977,7 @@ msgid ""
"Maximum number of concurrent DNS resolver queries allowed, [constant "
"RESOLVER_INVALID_ID] is returned if exceeded."
msgstr ""
-"å…许的最大并å‘DNSè§£æžå™¨æŸ¥è¯¢æ•°é‡ï¼Œå¦‚果超过,则返回[constant "
+"å…è®¸çš„æœ€å¤§å¹¶å‘ DNS è§£æžå™¨æŸ¥è¯¢æ•°é‡ï¼Œå¦‚果超过,则返回 [constant "
"RESOLVER_INVALID_ID]。"
#: doc/classes/IP.xml
@@ -38921,18 +39020,36 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
"此控件æä¾›äº†ä¸€ä¸ªå¯é€‰æ‹©çš„项目列表,该列表å¯ä»¥æ˜¯å•列(或多列),å¯ä»¥å•独选择文"
"本ã€å›¾æ ‡æˆ–åŒæ—¶é€‰æ‹©æ–‡æœ¬å’Œå›¾æ ‡ã€‚支æŒå·¥å…·æç¤ºï¼Œåˆ—表中的æ¯ä¸ªé¡¹ç›®éƒ½å¯ä»¥æ˜¯ä¸åŒ"
"的。\n"
"列表中å¯é€‰æ‹©çš„项目å¯ä»¥è¢«é€‰æ‹©æˆ–å–æ¶ˆé€‰æ‹©ï¼Œå¹¶ä¸”å¯ä»¥å¯ç”¨å¤šé‡é€‰æ‹©ã€‚用鼠标å³é”®é€‰æ‹©"
-"也å¯ä»¥è¢«å¯ç”¨ï¼Œä»¥å…许使用弹出å¼ä¸Šä¸‹æ–‡èœå•。项目也å¯ä»¥é€šè¿‡åŒå‡»å®ƒä»¬æˆ–按Enter回车"
-"é”®æ¥ \"激活\"。\n"
-"é¡¹ç›®æ–‡æœ¬åªæ”¯æŒå•行字符串,字符串中的æ¢è¡Œå­—符(例如[code]\\n[/code])ä¸ä¼šäº§ç”Ÿ"
-"æ¢è¡Œã€‚在[constant ICON_MODE_TOP]模å¼ä¸‹ï¼Œæ–‡æœ¬è‡ªé€‚应(warp)是å¯ç”¨çš„,但默认情况"
-"下会调整列的宽度以完全适åˆå…¶å†…容。你需è¦è®¾ç½®[member fixed_column_width]大于0"
-"æ¥åŒ…使–‡æœ¬ã€‚"
+"也å¯ä»¥è¢«å¯ç”¨ï¼Œä»¥å…许使用弹出å¼ä¸Šä¸‹æ–‡èœå•。项目也å¯ä»¥é€šè¿‡åŒå‡»å®ƒä»¬æˆ–按回车键"
+"æ¥â€œæ¿€æ´»â€ã€‚\n"
+"é¡¹ç›®æ–‡æœ¬åªæ”¯æŒå•行字符串,字符串中的æ¢è¡Œå­—符(例如 [code]\\n[/code])ä¸ä¼šäº§ç”Ÿ"
+"æ¢è¡Œã€‚文本æ¢è¡Œä¼šåœ¨ [constant ICON_MODE_TOP] 模å¼ä¸‹å¯ç”¨ï¼Œä½†é»˜è®¤æƒ…况下会调整列"
+"的宽度以完全适åˆå…¶å†…容。你需è¦å°† [member fixed_column_width] 设为大于 0 的值"
+"æ‰èƒ½è®©æ–‡æœ¬æ¢è¡Œã€‚\n"
+"[b]å¢žé‡æœç´¢ï¼š[/b]与 [PopupMenu] å’Œ [Tree] 类似,[ItemList] 也支æŒåœ¨èšç„¦æŽ§ä»¶æ—¶"
+"在列表中进行æœç´¢ã€‚按下与æŸä¸ªæ¡ç›®å称首字æ¯ä¸€è‡´çš„æŒ‰é”®ï¼Œå°±ä¼šé€‰ä¸­ä»¥è¯¥å­—æ¯å¼€å¤´çš„"
+"第一个æ¡ç›®ã€‚在此之åŽï¼Œè¿›è¡Œå¢žé‡æœç´¢çš„办法有两ç§ï¼š1)在超时å‰å†æ¬¡æŒ‰ä¸‹åŒä¸€ä¸ªæŒ‰"
+"键,选中以该字æ¯å¼€å¤´çš„下一个æ¡ç›®ã€‚2ï¼‰åœ¨è¶…æ—¶å‰æŒ‰ä¸‹å‰©ä½™å­—æ¯å¯¹åº”的按键,直接匹é…"
+"并选中所需的æ¡ç›®ã€‚这两个动作都会在最åŽä¸€æ¬¡æŒ‰é”®è¶…æ—¶åŽé‡ç½®å›žåˆ—表顶端。你å¯ä»¥é€š"
+"过 [member ProjectSettings.gui/timers/incremental_search_max_interval_msec] "
+"修改超时时长。"
#: doc/classes/ItemList.xml
msgid "Adds an item to the item list with no text, only an icon."
@@ -38945,9 +39062,9 @@ msgid ""
"with no icon.\n"
"If selectable is [code]true[/code], the list item will be selectable."
msgstr ""
-"将一个项目添加到项目列表中,并指定文本。指定一个图标[code]icon[/code],或者图"
-"标[code]icon[/code]使用空[code]null[/code]作为没有图标的列表项。\n"
-"如果å¯é€‰æ‹©å¡«[code]true[/code],列表项将是å¯é€‰æ‹©çš„。"
+"将一个项目添加到项目列表中,并指定文本。指定一个图标 [code]icon[/code],或者"
+"图标 [code]icon[/code] 使用空 [code]null[/code] 作为没有图标的列表项。\n"
+"如果å¯é€‰æ‹©å¡« [code]true[/code],列表项将是å¯é€‰æ‹©çš„。"
#: doc/classes/ItemList.xml
msgid "Removes all items from the list."
@@ -38978,13 +39095,13 @@ msgstr "返回当å‰åˆ—表中的项目数。"
msgid ""
"Returns the custom background color of the item specified by [code]idx[/"
"code] index."
-msgstr "返回由[code]idx[/code]索引指定的项目的自定义背景颜色。"
+msgstr "返回由 [code]idx[/code] 索引指定的项目的自定义背景颜色。"
#: doc/classes/ItemList.xml
msgid ""
"Returns the custom foreground color of the item specified by [code]idx[/"
"code] index."
-msgstr "返回由[code]idx[/code]ç´¢å¼•æŒ‡å®šé¡¹ç›®çš„è‡ªå®šä¹‰å‰æ™¯é¢œè‰²ã€‚"
+msgstr "返回由 [code]idx[/code] ç´¢å¼•æŒ‡å®šé¡¹ç›®çš„è‡ªå®šä¹‰å‰æ™¯é¢œè‰²ã€‚"
#: doc/classes/ItemList.xml
msgid "Returns the icon associated with the specified index."
@@ -38992,13 +39109,13 @@ msgstr "返回与指定索引相关的图标。"
#: doc/classes/ItemList.xml
msgid "Returns a [Color] modulating item's icon at the specified index."
-msgstr "返回指定索引处的[Color]颜色调制(modulating) 项的图标。"
+msgstr "返回指定索引处的 [Color] 颜色调制项的图标。"
#: doc/classes/ItemList.xml
msgid ""
"Returns the region of item's icon used. The whole icon will be used if the "
"region has no area."
-msgstr "返回项目图标的使用区域。如果该区域大å°ä¸º0,整个图标将被使用。"
+msgstr "返回项目图标的使用区域。如果该区域大å°ä¸º 0,整个图标将被使用。"
#: doc/classes/ItemList.xml
msgid "Returns the metadata value of the specified index."
@@ -39078,13 +39195,13 @@ msgstr ""
msgid ""
"Sets the background color of the item specified by [code]idx[/code] index to "
"the specified [Color]."
-msgstr "将[code]idx[/code]索引指定的项目的背景色设置为指定的颜色[Color]。"
+msgstr "将 [code]idx[/code] 索引指定的项目的背景色设置为指定的颜色 [Color]。"
#: doc/classes/ItemList.xml
msgid ""
"Sets the foreground color of the item specified by [code]idx[/code] index to "
"the specified [Color]."
-msgstr "å°†[code]idx[/code]ç´¢å¼•æŒ‡å®šé¡¹ç›®çš„å‰æ™¯é¢œè‰²è®¾ç½®ä¸ºæŒ‡å®šçš„颜色[Color]。"
+msgstr "å°† [code]idx[/code] ç´¢å¼•æŒ‡å®šé¡¹ç›®çš„å‰æ™¯é¢œè‰²è®¾ç½®ä¸ºæŒ‡å®šçš„颜色 [Color]。"
#: doc/classes/ItemList.xml
msgid ""
@@ -39093,23 +39210,23 @@ msgid ""
"(when double-clicking or pressing Enter)."
msgstr ""
"ç¦ç”¨ï¼ˆæˆ–å¯ç”¨ï¼‰æŒ‡å®šç´¢å¼•上的项目。\n"
-"ç¦ç”¨çš„项目ä¸èƒ½è¢«é€‰ä¸­ï¼Œä¹Ÿä¸ä¼šè§¦å‘激活信å·ï¼ˆå½“åŒå‡»æˆ–按Enter回车键)。"
+"ç¦ç”¨çš„项目ä¸èƒ½è¢«é€‰ä¸­ï¼Œä¹Ÿä¸ä¼šè§¦å‘激活信å·ï¼ˆå½“åŒå‡»æˆ–按回车键)。"
#: doc/classes/ItemList.xml
msgid ""
"Sets (or replaces) the icon's [Texture] associated with the specified index."
-msgstr "设置(或替æ¢ï¼‰ä¸ŽæŒ‡å®šç´¢å¼•相关的图标的纹ç†[Texture]。"
+msgstr "设置(或替æ¢ï¼‰ä¸ŽæŒ‡å®šç´¢å¼•ç›¸å…³çš„å›¾æ ‡çš„çº¹ç† [Texture]。"
#: doc/classes/ItemList.xml
msgid ""
"Sets a modulating [Color] of the item associated with the specified index."
-msgstr "设置与指定索引相关的项目的调制颜色[Color]。"
+msgstr "设置与指定索引相关的项目的调制颜色 [Color]。"
#: doc/classes/ItemList.xml
msgid ""
"Sets the region of item's icon used. The whole icon will be used if the "
"region has no area."
-msgstr "设置项目图标的使用区域。如果该区域大å°ä¸º 0, 将使用整个图标。"
+msgstr "设置项目图标的使用区域。如果该区域大å°ä¸º 0,将使用整个图标。"
#: doc/classes/ItemList.xml
msgid "Sets whether the item icon will be drawn transposed."
@@ -39182,19 +39299,20 @@ msgid ""
"affected."
msgstr ""
"所有图标将被调整到的尺寸。\n"
-"如果X或Y分é‡ä¸å¤§äºŽ0,图标的大å°å°†ä¸ä¼šå—到影å“。"
+"如果 X 或 Y 分é‡ä¸å¤§äºŽ 0,图标的大å°å°†ä¸ä¼šå—到影å“。"
#: doc/classes/ItemList.xml
msgid ""
"The icon position, whether above or to the left of the text. See the [enum "
"IconMode] constants."
-msgstr "图标的ä½ç½®ï¼Œæ˜¯åœ¨æ–‡æœ¬çš„上方还是在文本的左边。å‚阅[enum IconMode]常é‡ã€‚"
+msgstr ""
+"图标的ä½ç½®ï¼Œæ˜¯åœ¨æ–‡æœ¬çš„上方还是在文本的左边。å‚阅 [enum IconMode] 常é‡ã€‚"
#: doc/classes/ItemList.xml
msgid ""
"The scale of icon applied after [member fixed_icon_size] and transposing "
"takes effect."
-msgstr "在[member fixed_icon_size]和转置生效åŽåº”用的图标比例。"
+msgstr "在 [member fixed_icon_size] 和转置生效åŽåº”用的图标比例。"
#: doc/classes/ItemList.xml
msgid ""
@@ -39239,7 +39357,7 @@ msgstr "å…许å•选或多选。å‚阅[enum SelectMode]常é‡ã€‚"
msgid ""
"Triggered when specified list item is activated via double-clicking or by "
"pressing Enter."
-msgstr "当指定的列表项目通过åŒå‡»æˆ–按Enter激活时触å‘。"
+msgstr "当指定的列表项目通过åŒå‡»æˆ–按回车键激活时触å‘。"
#: doc/classes/ItemList.xml
msgid ""
@@ -39271,7 +39389,7 @@ msgstr "在å…许多选的列表上更改多选时触å‘。"
msgid ""
"Triggered when a left mouse click is issued within the rect of the list but "
"on empty space."
-msgstr "当鼠标左键在列表的矩形(rect)范围内但在空白处å•击时,会被触å‘。"
+msgstr "当鼠标左键在列表的矩形范围内但在空白处å•击时,会被触å‘。"
#: doc/classes/ItemList.xml
msgid ""
@@ -39279,8 +39397,8 @@ msgid ""
"on empty space.\n"
"[member allow_rmb_select] must be enabled."
msgstr ""
-"当在列表的矩形(rect)范围内但在空白处å•击鼠标å³é”®æ—¶è¢«è§¦å‘。\n"
-"[member allow_rmb_select]必须被å¯ç”¨ã€‚"
+"当在列表的矩形范围内但在空白处å•击鼠标å³é”®æ—¶è¢«è§¦å‘。\n"
+"[member allow_rmb_select] 必须被å¯ç”¨ã€‚"
#: doc/classes/ItemList.xml
msgid "Icon is drawn above the text."
@@ -39296,7 +39414,7 @@ msgstr "ä»…å…许选择å•个项目。"
#: doc/classes/ItemList.xml
msgid "Allows selecting multiple items by holding Ctrl or Shift."
-msgstr "å…许通过按ä½Ctrl或Shift选择多个项目。"
+msgstr "å…è®¸é€šè¿‡æŒ‰ä½ Ctrl 或 Shift 选择多个项目。"
#: doc/classes/ItemList.xml doc/classes/Tree.xml
msgid "Default text [Color] of the item."
@@ -39304,7 +39422,7 @@ msgstr "项目的默认文本颜色 [Color]。"
#: doc/classes/ItemList.xml doc/classes/Tree.xml
msgid "Text [Color] used when the item is selected."
-msgstr "选择项目时使用的文本颜色[Color]。"
+msgstr "选择项目时使用的文本颜色 [Color]。"
#: doc/classes/ItemList.xml
msgid ""
@@ -39340,27 +39458,27 @@ msgstr "[ItemList] 的默认样å¼ç›’ [StyleBox],å³åœ¨æŽ§ä»¶æœªèŽ·å¾—ç„¦ç‚¹æ—
#: doc/classes/ItemList.xml
msgid "[StyleBox] used when the [ItemList] is being focused."
-msgstr "当[ItemList]被èšç„¦æ—¶ä½¿ç”¨çš„æ ·å¼ç›’[StyleBox]。"
+msgstr "当 [ItemList] 被èšç„¦æ—¶ä½¿ç”¨çš„æ ·å¼ç›’ [StyleBox]。"
#: doc/classes/ItemList.xml
msgid "[StyleBox] used for the cursor, when the [ItemList] is being focused."
-msgstr "当[ItemList]被èšç„¦æ—¶ï¼Œç”¨äºŽå…‰æ ‡çš„æ ·å¼ç›’[StyleBox]。"
+msgstr "当 [ItemList] 被èšç„¦æ—¶ï¼Œç”¨äºŽå…‰æ ‡çš„æ ·å¼ç›’ [StyleBox]。"
#: doc/classes/ItemList.xml
msgid ""
"[StyleBox] used for the cursor, when the [ItemList] is not being focused."
-msgstr "当[ItemList]没有被èšç„¦æ—¶ï¼Œç”¨äºŽå…‰æ ‡çš„æ ·å¼ç›’[StyleBox]。"
+msgstr "当 [ItemList] 没有被èšç„¦æ—¶ï¼Œç”¨äºŽå…‰æ ‡çš„æ ·å¼ç›’ [StyleBox]。"
#: doc/classes/ItemList.xml
msgid ""
"[StyleBox] for the selected items, used when the [ItemList] is not being "
"focused."
-msgstr "所选项的样å¼ç›’[StyleBox],当[ItemList]没有获得焦点时使用。"
+msgstr "所选项的样å¼ç›’ [StyleBox],当 [ItemList] 没有获得焦点时使用。"
#: doc/classes/ItemList.xml
msgid ""
"[StyleBox] for the selected items, used when the [ItemList] is being focused."
-msgstr "所选项的样å¼ç›’[StyleBox],当[ItemList]没有获得焦点时使用。"
+msgstr "所选项的样å¼ç›’ [StyleBox],当 [ItemList] 没有获得焦点时使用。"
#: doc/classes/JavaScript.xml
msgid ""
@@ -39526,41 +39644,41 @@ msgid ""
"[/codeblock]\n"
"[b]Note:[/b] Only available in the HTML5 platform."
msgstr ""
-"JavaScriptObject用于与通过[method JavaScript.get_interface]ã€[method "
-"JavaScript.create_object]或[method JavaScript.create_callback]检索或创建的"
-"JavaScript对象交互。\n"
+"JavaScriptObject 用于与通过 [method JavaScript.get_interface]ã€[method "
+"JavaScript.create_object] 或 [method JavaScript.create_callback] 检索或创建"
+"的 JavaScript 对象交互。\n"
"例:\n"
"[codeblock]\n"
"extends Node\n"
"\n"
-"var _my_js_callback = JavaScript.create_callback(self, \"myCallback\") # "
-"This reference must be kept\n"
+"var _my_js_callback = JavaScript.create_callback(self, \"myCallback\") # å¿…é¡»"
+"ä¿ç•™è¿™ä¸ªå¼•用\n"
"var console = JavaScript.get_interface(\"console\")\n"
"\n"
"func _init():\n"
" var buf = JavaScript.create_object(\"ArrayBuffer\", 10) # new "
"ArrayBuffer(10)\n"
-" print(buf) # prints [JavaScriptObject:OBJECT_ID]\n"
+" print(buf) # 输出 [JavaScriptObject:OBJECT_ID]\n"
" var uint8arr = JavaScript.create_object(\"Uint8Array\", buf) # new "
"Uint8Array(buf)\n"
" uint8arr[1] = 255\n"
-" prints(uint8arr[1], uint8arr.byteLength) # prints 255 10\n"
+" prints(uint8arr[1], uint8arr.byteLength) # 输出 255 10\n"
" console.log(uint8arr) # prints in browser console \"Uint8Array(10) [ 0, "
"255, 0, 0, 0, 0, 0, 0, 0, 0 ]\"\n"
"\n"
-" # Equivalent of JavaScript: Array.from(uint8arr).forEach(myCallback)\n"
+" # 相当于 JavaScript: Array.from(uint8arr).forEach(myCallback)\n"
" JavaScript.get_interface(\"Array\").from(uint8arr)."
"forEach(_my_js_callback)\n"
"\n"
"func myCallback(args):\n"
-" # Will be called with the parameters passed to the \"forEach\" callback\n"
+" # 会使用传给“forEachâ€å›žè°ƒçš„傿•°æ¥è°ƒç”¨\n"
" # [0, 0, [JavaScriptObject:1173]]\n"
" # [255, 1, [JavaScriptObject:1173]]\n"
" # ...\n"
" # [0, 9, [JavaScriptObject:1180]]\n"
" print(args)\n"
"[/codeblock]\n"
-"[b]注æ„:[/b]åªåœ¨HTML5å¹³å°ä¸Šå¯ç”¨ã€‚"
+"[b]注æ„:[/b]åªåœ¨ HTML5 å¹³å°ä¸Šå¯ç”¨ã€‚"
#: doc/classes/JNISingleton.xml
msgid ""
@@ -39589,7 +39707,7 @@ msgstr "创建 Android æ’ä»¶"
#: doc/classes/Joint.xml
msgid "Base class for all 3D joints."
-msgstr "所有3D关节的基类。"
+msgstr "所有 3D 关节的基类。"
#: doc/classes/Joint.xml
msgid ""
@@ -39609,15 +39727,15 @@ msgstr "3D 货车镇演示"
msgid ""
"If [code]true[/code], the two bodies of the nodes are not able to collide "
"with each other."
-msgstr "如果 [code]true[/code],则节点的两个主体无法相互碰撞。"
+msgstr "如果为 [code]true[/code],则节点的两个主体无法相互碰撞。"
#: doc/classes/Joint.xml
msgid "The node attached to the first side (A) of the joint."
-msgstr "连接到关节第一侧(A)的节点。"
+msgstr "连接到关节第一侧(A)的节点。"
#: doc/classes/Joint.xml
msgid "The node attached to the second side (B) of the joint."
-msgstr "连接到关节第二侧(B)的节点。"
+msgstr "连接到关节第二侧(B)的节点。"
#: doc/classes/Joint.xml
msgid ""
@@ -39644,7 +39762,7 @@ msgid ""
"can pull on the joint."
msgstr ""
"当 [member node_a] å’Œ [member node_b] å‘ä¸åŒæ–¹å‘移动时,[code]bias[/code] 控"
-"制关节将它们拉回原始ä½ç½®çš„æ‰€éœ€æ—¶é—´ã€‚ [code]bias[/code] 越低,两个物体在关节上"
+"制关节将它们拉回原始ä½ç½®çš„æ‰€éœ€æ—¶é—´ã€‚[code]bias[/code] 越低,两个物体在关节上"
"å—到的拉力越大。"
#: doc/classes/Joint2D.xml
@@ -39876,9 +39994,9 @@ msgid ""
"- [code]params[/code]: An array or dictionary of parameters being passed to "
"the method."
msgstr ""
-"返回JSON-RPC通知形å¼çš„字典。通知是一次性的信æ¯ï¼Œä¸éœ€è¦æœ‰å“应。\n"
-"- [code]method[/code]:被调用的方法的å称。\n"
-"- [code]params[/code]:ä¼ é€’ç»™è¯¥æ–¹æ³•çš„å‚æ•°çš„æ•°ç»„或字典。"
+"返回 JSON-RPC 通知形å¼çš„字典。通知是一次性的信æ¯ï¼Œä¸éœ€è¦æœ‰å“应。\n"
+"- [code]method[/code]:被调用的方法的å称。\n"
+"- [code]params[/code]ï¼šä¼ é€’ç»™è¯¥æ–¹æ³•çš„å‚æ•°çš„æ•°ç»„或字典。"
#: doc/classes/JSONRPC.xml
msgid ""
@@ -39891,11 +40009,11 @@ msgid ""
"- [code]id[/code]: Uniquely identifies this request. The server is expected "
"to send a response with the same ID."
msgstr ""
-"以JSON-RPC请求的形å¼è¿”回字典。请求被å‘é€åˆ°æœåŠ¡å™¨ï¼Œå¹¶æœŸæœ›å¾—åˆ°å“应。ID 字段用于"
-"æœåŠ¡å™¨æŒ‡å®šå®ƒæ­£åœ¨å“应的确切请求。\n"
-"- [code]method[/code]:被调用的方法的å称。\n"
-"- [code]params[/code]:ä¼ é€’ç»™è¯¥æ–¹æ³•çš„å‚æ•°çš„æ•°ç»„或字典。\n"
-"- [code]id[/code]:唯一标识此请求。æœåŠ¡å™¨åº”å‘é€å…·æœ‰ç›¸åŒ ID çš„å“应。"
+"以 JSON-RPC 请求的形å¼è¿”回字典。请求被å‘é€åˆ°æœåŠ¡å™¨ï¼Œå¹¶æœŸæœ›å¾—åˆ°å“应。ID 字段用"
+"于æœåŠ¡å™¨æŒ‡å®šå®ƒæ­£åœ¨å“应的确切请求。\n"
+"- [code]method[/code]:被调用的方法的å称。\n"
+"- [code]params[/code]ï¼šä¼ é€’ç»™è¯¥æ–¹æ³•çš„å‚æ•°çš„æ•°ç»„或字典。\n"
+"- [code]id[/code]:唯一标识此请求。æœåŠ¡å™¨åº”å‘é€å…·æœ‰ç›¸åŒ ID çš„å“应。"
#: doc/classes/JSONRPC.xml
msgid ""
@@ -39935,9 +40053,8 @@ msgid ""
"[code]action[/code]: The action to be run, as a Dictionary in the form of a "
"JSON-RPC request or notification."
msgstr ""
-"给定采用 JSON-RPC 请求形å¼çš„字典:解压请求并è¿è¡Œå®ƒã€‚通过查看å为 \"method\" "
-"的字段并在 JSONRPC 对象中查找等效命å的函数æ¥è§£æžæ–¹æ³•。如果找到,则调用该方"
-"法。\n"
+"给定采用 JSON-RPC 请求形å¼çš„字典:解压请求并è¿è¡Œå®ƒã€‚通过查看å为“methodâ€çš„å­—"
+"段并在 JSONRPC 对象中查找等效命å的函数æ¥è§£æžæ–¹æ³•。如果找到,则调用该方法。\n"
"è¦æ·»åŠ æ–°çš„å—æ”¯æŒæ–¹æ³•,请扩展 JSONRPC 类并在你的å­ç±»ä¸Šè°ƒç”¨ [method "
"process_action]。\n"
"[code]action[/code]:è¦è¿è¡Œçš„动作,作为 JSON-RPC 请求或通知形å¼çš„字典。"
@@ -40136,8 +40253,8 @@ msgid ""
"platform's motion, it will always be first in the slide collisions."
msgstr ""
"沿ç€å‘é‡ç§»åŠ¨ç‰©ä½“ã€‚å¦‚æžœè¿™ä¸ªç‰©ä½“ä¸Žå¦ä¸€ä¸ªç‰©ä½“相撞,它将沿ç€å¦ä¸€ä¸ªç‰©ä½“滑动,而ä¸"
-"是立å³åœæ­¢ã€‚如果å¦ä¸€ä¸ªç‰©ä½“是[KinematicBody]或[RigidBody],它也会被å¦ä¸€ä¸ªç‰©ä½“"
-"çš„è¿åŠ¨æ‰€å½±å“。你å¯ä»¥ç”¨å®ƒæ¥åˆ¶ä½œç§»åŠ¨å’Œæ—‹è½¬çš„å¹³å°ï¼Œæˆ–者让节点推动其他节点。\n"
+"是立å³åœæ­¢ã€‚如果å¦ä¸€ä¸ªç‰©ä½“是 [KinematicBody] 或 [RigidBody],它也会被å¦ä¸€ä¸ªç‰©"
+"体的è¿åŠ¨æ‰€å½±å“。你å¯ä»¥ç”¨å®ƒæ¥åˆ¶ä½œç§»åŠ¨å’Œæ—‹è½¬çš„å¹³å°ï¼Œæˆ–者让节点推动其他节点。\n"
"这个方法应该在 [method Node._physics_process] 中使用,或者在被 [method Node."
"_physics_process] è°ƒç”¨çš„æ–¹æ³•ä¸­ä½¿ç”¨ï¼Œå› ä¸ºå®ƒåœ¨è®¡ç®—æ—¶ï¼Œè‡ªåŠ¨ä½¿ç”¨ç‰©ç†æ­¥éª¤çš„ "
"[code]delta[/code] 值。å¦åˆ™ï¼Œæ¨¡æ‹Ÿå°†ä»¥ä¸æ­£ç¡®çš„速度è¿è¡Œã€‚\n"
@@ -40200,15 +40317,15 @@ msgstr ""
#: doc/classes/KinematicBody.xml
msgid "Lock the body's X axis movement."
-msgstr "é”定物体的Xè½´è¿åŠ¨ã€‚"
+msgstr "é”定物体的 X è½´è¿åŠ¨ã€‚"
#: doc/classes/KinematicBody.xml
msgid "Lock the body's Y axis movement."
-msgstr "é”定物体的Yè½´è¿åŠ¨ã€‚"
+msgstr "é”定物体的 Y è½´è¿åŠ¨ã€‚"
#: doc/classes/KinematicBody.xml
msgid "Lock the body's Z axis movement."
-msgstr "é”定物体的Zè½´è¿åŠ¨ã€‚"
+msgstr "é”定物体的 Z è½´è¿åŠ¨ã€‚"
#: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml
msgid ""
@@ -40247,19 +40364,19 @@ msgstr ""
msgid ""
"Lock the body's X axis movement. Deprecated alias for [member "
"axis_lock_motion_x]."
-msgstr "é”定物体的Xè½´è¿åŠ¨ã€‚å·²è¢«åºŸå¼ƒçš„[member axis_lock_motion_x]的别å。"
+msgstr "é”定物体的 X è½´è¿åŠ¨ã€‚å·²è¢«åºŸå¼ƒçš„ [member axis_lock_motion_x] 的别å。"
#: doc/classes/KinematicBody.xml
msgid ""
"Lock the body's Y axis movement. Deprecated alias for [member "
"axis_lock_motion_y]."
-msgstr "é”定物体的Yè½´è¿åŠ¨ã€‚å·²è¢«åºŸå¼ƒçš„[member axis_lock_motion_y]的别å。"
+msgstr "é”定物体的 Y è½´è¿åŠ¨ã€‚å·²è¢«åºŸå¼ƒçš„ [member axis_lock_motion_y] 的别å。"
#: doc/classes/KinematicBody.xml
msgid ""
"Lock the body's Z axis movement. Deprecated alias for [member "
"axis_lock_motion_z]."
-msgstr "é”定物体的Zè½´è¿åŠ¨ã€‚å·²è¢«åºŸå¼ƒçš„[member axis_lock_motion_z]的别å。"
+msgstr "é”定物体的 Z è½´è¿åŠ¨ã€‚å·²è¢«åºŸå¼ƒçš„ [member axis_lock_motion_z] 的别å。"
#: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml
msgid ""
@@ -40330,7 +40447,7 @@ msgid ""
"value is always positive and only valid after calling [method "
"move_and_slide] and when [method is_on_floor] returns [code]true[/code]."
msgstr ""
-"æ ¹æ®[code]up_direction[/code]返回最åŽä¸€ä¸ªç¢°æ’žç‚¹çš„地æ¿ç¢°æ’žè§’度,默认为"
+"æ ¹æ® [code]up_direction[/code] 返回最åŽä¸€ä¸ªç¢°æ’žç‚¹çš„地æ¿ç¢°æ’žè§’度,默认为 "
"[code]Vector2.UP[/code]。此值始终为正值,并且仅在调用 [method "
"move_and_slide] åŽä¸”当 [method is_on_floor] 返回 [code]true[/code] 时有效。"
@@ -40340,8 +40457,8 @@ msgid ""
"latest collision that occurred during the last call to [method "
"move_and_slide]."
msgstr ""
-"返回[KinematicCollision2D],它包å«åœ¨æœ€åŽä¸€æ¬¡è°ƒç”¨[method move_and_slide]æ—¶å‘生"
-"的最新碰撞信æ¯ã€‚"
+"返回 [KinematicCollision2D],它包å«åœ¨æœ€åŽä¸€æ¬¡è°ƒç”¨ [method move_and_slide] æ—¶"
+"å‘生的最新碰撞信æ¯ã€‚"
#: doc/classes/KinematicBody2D.xml
msgid ""
@@ -40489,9 +40606,9 @@ msgid ""
"colliding object, the remaining motion, and the collision position. This "
"information can be used to calculate a collision response."
msgstr ""
-"包å«[KinematicBody]碰撞的碰撞数æ®ã€‚当[KinematicBody]使用[method "
-"KinematicBody.move_and_collide]移动时,如果它检测到与å¦ä¸€ä¸ªç‰©ä½“的碰撞就会åœ"
-"止。如果检测到碰撞,将返回一个KinematicCollision对象。\n"
+"åŒ…å« [KinematicBody] 碰撞的碰撞数æ®ã€‚当 [KinematicBody] 使用 [method "
+"KinematicBody.move_and_collide] 移动时,如果它检测到与å¦ä¸€ä¸ªç‰©ä½“的碰撞就会åœ"
+"止。如果检测到碰撞,将返回一个 KinematicCollision 对象。\n"
"这个对象包å«å…³äºŽç¢°æ’žçš„ä¿¡æ¯ï¼ŒåŒ…括碰撞的物体ã€å‰©ä½™çš„è¿åŠ¨å’Œç¢°æ’žçš„ä½ç½®ã€‚这些信æ¯"
"å¯ä»¥ç”¨æ¥è®¡ç®—碰撞å“应。"
@@ -40500,8 +40617,8 @@ msgid ""
"The collision angle according to [code]up_direction[/code], which is "
"[code]Vector3.UP[/code] by default. This value is always positive."
msgstr ""
-"æ ¹æ®[code]up_direction[/code]的碰撞角度,默认为[code]Vector3.UP[/code]。这个"
-"值总是为正。"
+"æ ¹æ® [code]up_direction[/code] 的碰撞角度,默认为 [code]Vector3.UP[/code]。这"
+"个值总是为正。"
#: doc/classes/KinematicCollision.xml doc/classes/KinematicCollision2D.xml
msgid "The colliding body."
@@ -40510,11 +40627,11 @@ msgstr "碰撞体。"
#: doc/classes/KinematicCollision.xml doc/classes/KinematicCollision2D.xml
msgid ""
"The colliding body's unique instance ID. See [method Object.get_instance_id]."
-msgstr "碰撞体的唯一实例ID。å‚阅[method Object.get_instance_id]。"
+msgstr "碰撞体的唯一实例 IDã€‚è§ [method Object.get_instance_id]。"
#: doc/classes/KinematicCollision.xml doc/classes/KinematicCollision2D.xml
msgid "The colliding body's metadata. See [Object]."
-msgstr "碰撞体的元数æ®ã€‚å‚阅[Object]。"
+msgstr "碰撞体的元数æ®ã€‚è§ [Object]。"
#: doc/classes/KinematicCollision.xml
msgid "The colliding body's [RID] used by the [PhysicsServer]."
@@ -40526,7 +40643,7 @@ msgstr "碰撞体的形状。"
#: doc/classes/KinematicCollision.xml
msgid "The colliding shape's index. See [CollisionObject]."
-msgstr "碰撞形状的索引。å‚阅[CollisionObject]。"
+msgstr "ç¢°æ’žå½¢çŠ¶çš„ç´¢å¼•ã€‚è§ [CollisionObject]。"
#: doc/classes/KinematicCollision.xml doc/classes/KinematicCollision2D.xml
msgid "The colliding object's velocity."
@@ -40566,9 +40683,9 @@ msgid ""
"colliding object, the remaining motion, and the collision position. This "
"information can be used to calculate a collision response."
msgstr ""
-"包å«[KinematicBody2D]碰撞的碰撞数æ®ã€‚当使用 [method KinematicBody2D."
-"move_and_collide] 移动[KinematicBody2D]时,如果检测到与å¦ä¸€ä¸ªç‰©ä½“的碰撞,它将"
-"åœæ­¢ã€‚如果检测到碰撞,则返回KinematicCollision2D对象。\n"
+"åŒ…å« [KinematicBody2D] 碰撞的碰撞数æ®ã€‚当使用 [method KinematicBody2D."
+"move_and_collide] 移动 [KinematicBody2D] 时,如果检测到与å¦ä¸€ä¸ªç‰©ä½“的碰撞,它"
+"å°†åœæ­¢ã€‚如果检测到碰撞,则返回 KinematicCollision2D 对象。\n"
"è¯¥å¯¹è±¡åŒ…å«æœ‰å…³ç¢°æ’žçš„ä¿¡æ¯ï¼ŒåŒ…括碰撞对象,剩余è¿åŠ¨å’Œç¢°æ’žåæ ‡ã€‚该信æ¯å¯ç”¨äºŽè®¡ç®—"
"碰撞å“应。"
@@ -40593,7 +40710,7 @@ msgid ""
"Displays plain text in a line or wrapped inside a rectangle. For formatted "
"text, use [RichTextLabel]."
msgstr ""
-"在一行中显示纯文本,或在一个矩形内包裹。对于格å¼åŒ–的文本,使用"
+"在一行中显示纯文本,或在一个矩形内包裹。对于格å¼åŒ–的文本,使用 "
"[RichTextLabel]。"
#: doc/classes/Label.xml
@@ -40738,25 +40855,26 @@ msgstr "通过展开行æ¥å¯¹é½æ•´ä¸ªæ–‡æœ¬ã€‚"
#: doc/classes/Label.xml
msgid "Default text [Color] of the [Label]."
-msgstr "[Label]标签的默认文本颜色[Color]。"
+msgstr "[Label] 标签的默认文本颜色 [Color]。"
#: doc/classes/Label.xml
msgid "[Color] of the text's shadow effect."
-msgstr "文本阴影效果的颜色[Color]。"
+msgstr "文本阴影效果的颜色 [Color]。"
#: doc/classes/Label.xml
msgid "The tint of [Font]'s outline. See [member DynamicFont.outline_color]."
-msgstr "[Font]轮廓的色调。å‚阅[member DynamicFont.outline_color]。"
+msgstr "[Font] è½®å»“çš„è‰²è°ƒã€‚è§ [member DynamicFont.outline_color]。"
#: doc/classes/Label.xml
msgid "Vertical space between lines in multiline [Label]."
-msgstr "多行[Label]中å„行之间的垂直空间。"
+msgstr "多行 [Label] 中å„行之间的垂直空间。"
#: doc/classes/Label.xml
msgid ""
"Boolean value. If set to 1 ([code]true[/code]), the shadow will be displayed "
"around the whole text as an outline."
-msgstr "布尔值。如果设置为1,å³[code]true[/code],整个文本周围显示阴影轮廓。"
+msgstr ""
+"布尔值。如果设置为 1([code]true[/code]),则整个文本周围显示阴影轮廓。"
#: doc/classes/Label.xml
msgid "The horizontal offset of the text's shadow."
@@ -40768,11 +40886,11 @@ msgstr "文本阴影的垂直å移。"
#: doc/classes/Label.xml
msgid "[Font] used for the [Label]'s text."
-msgstr "用于标签[Label]文本的字体[Font]。"
+msgstr "用于标签 [Label] 文本的字体 [Font]。"
#: doc/classes/Label.xml
msgid "Background [StyleBox] for the [Label]."
-msgstr "为[Label]设置背景样å¼[StyleBox]。"
+msgstr "为 [Label] 设置背景样å¼ç›’ [StyleBox]。"
#: doc/classes/Label3D.xml
msgid "Displays plain text in a 3D world."
@@ -40804,11 +40922,11 @@ msgstr ""
msgid ""
"The alpha cutting mode to use for the sprite. See [enum AlphaCutMode] for "
"possible values."
-msgstr "该精çµçš„ Alpha è£å‰ªæ¨¡å¼ã€‚å¯èƒ½çš„å–值请å‚阅 [enum AlphaCutMode]。"
+msgstr "该精çµçš„ Alpha è£å‰ªæ¨¡å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum AlphaCutMode]。"
#: doc/classes/Label3D.xml doc/classes/SpatialMaterial.xml
msgid "Threshold at which the alpha scissor will discard values."
-msgstr "alpha scissor 会丢弃数值的阈值。"
+msgstr "Alpha è£å‰ªä¸¢å¼ƒæ•°å€¼çš„阈值。"
#: doc/classes/Label3D.xml
msgid "If [code]true[/code], wraps the text to the [member width]."
@@ -40819,8 +40937,7 @@ msgid ""
"The billboard mode to use for the label. See [enum SpatialMaterial."
"BillboardMode] for possible values."
msgstr ""
-"è¯¥æ ‡ç­¾æ‰€ä½¿ç”¨çš„å…¬å‘Šæ¿æ¨¡å¼ã€‚å¯èƒ½çš„å–值请å‚阅 [enum SpatialMaterial."
-"BillboardMode]。"
+"è¯¥æ ‡ç­¾æ‰€ä½¿ç”¨çš„å…¬å‘Šæ¿æ¨¡å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum SpatialMaterial.BillboardMode]。"
#: doc/classes/Label3D.xml
msgid ""
@@ -40861,7 +40978,7 @@ msgstr "该 [Label3D] 的文本颜色 [Color]。"
msgid ""
"If [code]true[/code], depth testing is disabled and the object will be drawn "
"in render order."
-msgstr "如果[code]true[/code],深度测试被ç¦ç”¨ï¼Œå¯¹è±¡å°†æŒ‰æ¸²æŸ“顺åºç»˜åˆ¶ã€‚"
+msgstr "如果为 [code]true[/code],深度测试被ç¦ç”¨ï¼Œå¯¹è±¡å°†æŒ‰æ¸²æŸ“顺åºç»˜åˆ¶ã€‚"
#: doc/classes/Label3D.xml
msgid "The text drawing offset (in pixels)."
@@ -40976,7 +41093,7 @@ msgstr ""
"这个模å¼åªå…è®¸å®Œå…¨é€æ˜Žæˆ–者完全ä¸é€æ˜Žçš„åƒç´ ã€‚这个模å¼ä¹Ÿå« [i]Alpha 测试[/i]或"
"者[i]1ä½é€æ˜Žåº¦[/i]。\n"
"[b]注æ„:[/b]使用抗锯齿字体和轮廓时,这个模å¼å¯èƒ½ä¼šå‡ºçŽ°é—®é¢˜ï¼Œè¯·å°è¯•调整 "
-"[member alpha_scissor_threshold] 或使用 SDF 字体。 \n"
+"[member alpha_scissor_threshold] 或使用 SDF 字体。\n"
"[b]注æ„:[/b]文本中存在é‡å çš„字形时(例如手写体),这个模å¼å¯èƒ½ä¼šé€ æˆä¸»æ–‡æœ¬å’Œ"
"è½®å»“çš„é€æ˜Žåº¦æŽ’åºé—®é¢˜ã€‚"
@@ -41009,29 +41126,29 @@ msgid ""
"You can dynamically add pieces ([Texture]s) to this [LargeTexture] using "
"different offsets."
msgstr ""
-"[i] 已弃用(将在 Godot 4.0 中移除)。 [/i] 一ç§èƒ½å¤Ÿå­˜å‚¨è®¸å¤šå…·æœ‰åç§»é‡çš„较å°çº¹"
-"ç†çš„ [Texture]。\n"
-"ä½ å¯ä»¥ä½¿ç”¨ä¸åŒçš„åç§»é‡å‘æ­¤ [LargeTexture] åŠ¨æ€æ·»åŠ [Texture]片段。"
+"[i]已弃用(将在 Godot 4.0 中移除)。[/i] 一ç§èƒ½å¤Ÿå­˜å‚¨è®¸å¤šå…·æœ‰åç§»é‡çš„较å°çº¹ç†"
+"的 [Texture]。\n"
+"ä½ å¯ä»¥ä½¿ç”¨ä¸åŒçš„åç§»é‡å‘æ­¤ [LargeTexture] åŠ¨æ€æ·»åŠ  [Texture] 片段。"
#: doc/classes/LargeTexture.xml
msgid ""
"Adds [code]texture[/code] to this [LargeTexture], starting on offset "
"[code]ofs[/code]."
msgstr ""
-"å°†[code]texture[/code]添加到这个[LargeTexture],从åç§»é‡[code]ofs[/code]å¼€"
-"始。"
+"å°† [code]texture[/code] 添加到这个 [LargeTexture],从åç§»é‡ [code]ofs[/code] "
+"开始。"
#: doc/classes/LargeTexture.xml
msgid "Clears the [LargeTexture]."
-msgstr "清除[LargeTexture]。"
+msgstr "清除 [LargeTexture]。"
#: doc/classes/LargeTexture.xml
msgid "Returns the number of pieces currently in this [LargeTexture]."
-msgstr "返回此[LargeTexture]中的片段数。"
+msgstr "返回这个 [LargeTexture] 中的片段数。"
#: doc/classes/LargeTexture.xml
msgid "Returns the offset of the piece with the index [code]idx[/code]."
-msgstr "返回索引为[code]idx[/code]的片段的åç§»é‡ã€‚"
+msgstr "返回索引为 [code]idx[/code] 的片段的åç§»é‡ã€‚"
#: doc/classes/LargeTexture.xml
msgid "Returns the [Texture] of the piece with the index [code]idx[/code]."
@@ -41041,7 +41158,7 @@ msgstr "返回索引为 [code]idx[/code] 的片段的 [Texture]。"
msgid ""
"Sets the offset of the piece with the index [code]idx[/code] to [code]ofs[/"
"code]."
-msgstr "将索引为[code]idx[/code]的片段的åç§»é‡è®¾ç½®ä¸º[code]ofs[/code]。"
+msgstr "将索引为 [code]idx[/code] 的片段的åç§»é‡è®¾ç½®ä¸º [code]ofs[/code]。"
#: doc/classes/LargeTexture.xml
msgid ""
@@ -41052,7 +41169,7 @@ msgstr ""
#: doc/classes/LargeTexture.xml
msgid "Sets the size of this [LargeTexture]."
-msgstr "设置此[LargeTexture]的大å°ã€‚"
+msgstr "设置此 [LargeTexture] 的大å°ã€‚"
#: doc/classes/Light.xml
msgid "Provides a base class for different kinds of light nodes."
@@ -41084,19 +41201,19 @@ msgstr "设置指定的 [enum Light.Param] 傿•°çš„值。"
msgid ""
"If [code]true[/code], the light only appears in the editor and will not be "
"visible at runtime."
-msgstr "如果 [code]true[/code],ç¯å…‰åªåœ¨ç¼–辑器中出现,在è¿è¡Œæ—¶å°†ä¸å¯è§ã€‚"
+msgstr "如果为 [code]true[/code],ç¯å…‰åªåœ¨ç¼–辑器中出现,在è¿è¡Œæ—¶å°†ä¸å¯è§ã€‚"
#: doc/classes/Light.xml
msgid "The light's bake mode. See [enum BakeMode]."
-msgstr "ç¯å…‰çš„烘焙模å¼ã€‚å‚阅[enum BakeMode]。"
+msgstr "ç¯å…‰çš„烘焙模å¼ã€‚è§ [enum BakeMode]。"
#: doc/classes/Light.xml
msgid ""
"The light's color. An [i]overbright[/i] color can be used to achieve a "
"result equivalent to increasing the light's [member light_energy]."
msgstr ""
-"光的颜色。一个过亮[i]overbright[/i]颜色å¯ç”¨äºŽå®žçŽ°ç­‰æ•ˆäºŽå¢žåŠ å…‰çš„èƒ½é‡ [member "
-"light_energy] 的结果。"
+"光的颜色。[i]过亮[/i]的颜色å¯ç”¨äºŽå®žçŽ°ä¸Žå¢žåŠ å…‰çš„ [member light_energy] 相等价"
+"的结果。"
#: doc/classes/Light.xml
msgid "The light will affect objects in the selected layers."
@@ -41108,8 +41225,8 @@ msgid ""
"[OmniLight] and [SpotLight], changing this value will only change the light "
"color's intensity, not the light's radius."
msgstr ""
-"å…‰çš„å¼ºåº¦ä¹˜æ•°ï¼Œæ³¨ï¼Œè¿™ä¸æ˜¯ç‰©ç†å•ä½ã€‚对于 [OmniLight] å’Œ [SpotLight],更改此值åª"
-"会更改ç¯å…‰é¢œè‰²çš„强度,而ä¸ä¼šæ›´æ”¹ç¯å…‰çš„åŠå¾„。"
+"å…‰çš„å¼ºåº¦ä¹˜æ•°ï¼ˆè¿™ä¸æ˜¯ç‰©ç†å•ä½ï¼‰ã€‚对于 [OmniLight] å’Œ [SpotLight],更改此值åªä¼š"
+"更改ç¯å…‰é¢œè‰²çš„强度,而ä¸ä¼šæ›´æ”¹ç¯å…‰çš„åŠå¾„。"
#: doc/classes/Light.xml
msgid ""
@@ -41153,8 +41270,8 @@ msgid ""
"shadowing (\"shadow acne\"), while too large a value causes shadows to "
"separate from casters (\"peter-panning\"). Adjust as needed."
msgstr ""
-"用于调整阴影表现。值太å°ä¼šå¯¼è‡´è‡ªé˜´å½±ï¼ˆâ€œé˜´å½±æš—ç–®â€ï¼‰ï¼Œè€Œå€¼å¤ªå¤§ä¼šå¯¼è‡´é˜´å½±ä¸Žä¹‹åˆ†"
-"离(“彼得平移â€ï¼‰ã€‚æ ¹æ®éœ€è¦è¿›è¡Œè°ƒæ•´ã€‚"
+"用于调整阴影表现。值太å°ä¼šå¯¼è‡´è‡ªé˜´å½±ï¼ˆâ€œé˜´å½±å¤±çœŸâ€ï¼‰ï¼Œè€Œå€¼å¤ªå¤§ä¼šå¯¼è‡´é˜´å½±ä¸Žä¹‹åˆ†"
+"离(“阴影悬浮â€ï¼‰ã€‚æ ¹æ®éœ€è¦è¿›è¡Œè°ƒæ•´ã€‚"
#: doc/classes/Light.xml
msgid "The color of shadows cast by this light."
@@ -41184,7 +41301,7 @@ msgid ""
"cast a shadow on both sides of the mesh, set the mesh to use double-sided "
"shadows with [constant GeometryInstance.SHADOW_CASTING_SETTING_DOUBLE_SIDED]."
msgstr ""
-"如果 [code]true[/code],则å转网格的背é¢å‰”除。当你有一个åŽé¢æœ‰ç¯çš„å¹³é¢ç½‘æ ¼"
+"如果为 [code]true[/code],则å转网格的背é¢å‰”除。当你有一个åŽé¢æœ‰ç¯çš„å¹³é¢ç½‘æ ¼"
"时,这会很有用。如果需è¦åœ¨ç½‘格的两侧投射阴影,请使用 [constant "
"GeometryInstance.SHADOW_CASTING_SETTING_DOUBLE_SIDED] 将网格设置为使用åŒé¢é˜´"
"影。"
@@ -41312,20 +41429,20 @@ msgstr ""
#: doc/classes/Light2D.xml
msgid "The Light2D's [Color]."
-msgstr "Light2D光的颜色 [Color]。"
+msgstr "该 Light2D 的颜色 [Color]。"
#: doc/classes/Light2D.xml
msgid "If [code]true[/code], Light2D will only appear when editing the scene."
-msgstr "如果[code]true[/code],Light2Då°†åªåœ¨ç¼–辑场景时出现。"
+msgstr "如果为 [code]true[/code],Light2D å°†åªåœ¨ç¼–辑场景时出现。"
#: doc/classes/Light2D.xml
msgid "If [code]true[/code], Light2D will emit light."
-msgstr "如果 [code]true[/code],Light2D 会å‘光。"
+msgstr "如果为 [code]true[/code],Light2D 会å‘光。"
#: doc/classes/Light2D.xml
msgid ""
"The Light2D's energy value. The larger the value, the stronger the light."
-msgstr "Light2D的能é‡å€¼ã€‚该值越大,光线就越强。"
+msgstr "Light2D 的能é‡å€¼ã€‚该值越大,光线就越强。"
#: doc/classes/Light2D.xml
msgid "The Light2D's mode. See [enum Mode] constants for values."
@@ -41337,7 +41454,7 @@ msgstr "Light2D çš„ [code]texture[/code] çš„åç§»é‡ã€‚"
#: doc/classes/Light2D.xml
msgid "The height of the Light2D. Used with 2D normal mapping."
-msgstr "Light2D的高度。与2D法线贴图(normal mapping)一起使用。"
+msgstr "Light2D 的高度。与 2D 法线贴图一起使用。"
#: doc/classes/Light2D.xml
msgid ""
@@ -41347,7 +41464,7 @@ msgstr "图层é®ç½©ã€‚åªæœ‰å…·æœ‰åŒ¹é…é®ç½©çš„对象æ‰ä¼šå—到Light2Dçš„å½
#: doc/classes/Light2D.xml
msgid "Maximum layer value of objects that are affected by the Light2D."
-msgstr "å—Light2Då½±å“的对象的最大层数值。"
+msgstr "å— Light2D å½±å“的对象的最大层数值。"
#: doc/classes/Light2D.xml
msgid "Minimum layer value of objects that are affected by the Light2D."
@@ -41356,12 +41473,12 @@ msgstr "å— Light2D å½±å“的对象的最å°å±‚数值。"
#: doc/classes/Light2D.xml
msgid ""
"Maximum [code]z[/code] value of objects that are affected by the Light2D."
-msgstr "å—Light2Då½±å“的物体的最大[code]z[/code]值。"
+msgstr "å— Light2D å½±å“的物体的最大 [code]z[/code] 值。"
#: doc/classes/Light2D.xml
msgid ""
"Minimum [code]z[/code] value of objects that are affected by the Light2D."
-msgstr "å—Light2Då½±å“的物体的最å°[code]z[/code]值。"
+msgstr "å— Light2D å½±å“çš„ç‰©ä½“çš„æœ€å° [code]z[/code] 值。"
#: doc/classes/Light2D.xml
msgid "Shadow buffer size."
@@ -41369,15 +41486,15 @@ msgstr "阴影缓冲区大å°ã€‚"
#: doc/classes/Light2D.xml
msgid "[Color] of shadows cast by the Light2D."
-msgstr "Light2D投下的影å­çš„颜色[Color]。"
+msgstr "该 Light2D 投下的影å­çš„颜色 [Color]。"
#: doc/classes/Light2D.xml
msgid "If [code]true[/code], the Light2D will cast shadows."
-msgstr "如果[code]true[/code],Light2D将投下阴影。"
+msgstr "如果为 [code]true[/code],则该 Light2D 将投下阴影。"
#: doc/classes/Light2D.xml
msgid "Shadow filter type. See [enum ShadowFilter] for possible values."
-msgstr "阴影过滤器类型。相关å¯èƒ½çš„值,å‚阅[enum ShadowFilter] 阴影过滤器。"
+msgstr "阴影过滤器类型。å¯èƒ½çš„å–å€¼è§ [enum ShadowFilter]。"
#: doc/classes/Light2D.xml
msgid "Smoothing value for shadows."
@@ -41392,12 +41509,12 @@ msgid ""
"The shadow mask. Used with [LightOccluder2D] to cast shadows. Only occluders "
"with a matching light mask will cast shadows."
msgstr ""
-"阴影é®ç½©ã€‚与[LightOccluder2D]ä¸€èµ·ä½¿ç”¨æ¥æŠ•å°„é˜´å½±ã€‚åªæœ‰å…·æœ‰åŒ¹é…的光线é®ç½©çš„鮿Œ¡"
-"物æ‰ä¼šæŠ•射阴影。"
+"阴影é®ç½©ã€‚与 [LightOccluder2D] ä¸€èµ·ä½¿ç”¨æ¥æŠ•å°„é˜´å½±ã€‚åªæœ‰å…·æœ‰åŒ¹é…的光线é®ç½©çš„é®"
+"挡物æ‰ä¼šæŠ•射阴影。"
#: doc/classes/Light2D.xml
msgid "[Texture] used for the Light2D's appearance."
-msgstr "用于Light2D外观的[Texture]。"
+msgstr "用于 Light2D 外观的 [Texture]。"
#: doc/classes/Light2D.xml
msgid "The [code]texture[/code]'s scale factor."
@@ -41413,13 +41530,13 @@ msgstr "å°† Light2D 对应的åƒç´ å€¼ä¸Žå…¶ä¸‹æ–¹çš„åƒç´ å€¼ç›¸åŠ ã€‚è¿™æ˜¯ç¯
msgid ""
"Subtracts the value of pixels corresponding to the Light2D to the values of "
"pixels under it, resulting in inversed light effect."
-msgstr "å°†Light2D对应的åƒç´ å€¼å‡åŽ»å…¶ä¸‹æ–¹çš„åƒç´ å€¼ï¼Œäº§ç”Ÿå光效果。"
+msgstr "å°† Light2D 对应的åƒç´ å€¼å‡åŽ»å…¶ä¸‹æ–¹çš„åƒç´ å€¼ï¼Œäº§ç”Ÿå光效果。"
#: doc/classes/Light2D.xml
msgid ""
"Mix the value of pixels corresponding to the Light2D to the values of pixels "
"under it by linear interpolation."
-msgstr "通过线性æ’值将Light2D对应的åƒç´ å€¼ä¸Žå…¶ä¸‹æ–¹çš„åƒç´ å€¼æ··åˆã€‚"
+msgstr "通过线性æ’值将 Light2D 对应的åƒç´ å€¼ä¸Žå…¶ä¸‹æ–¹çš„åƒç´ å€¼æ··åˆã€‚"
#: doc/classes/Light2D.xml
msgid ""
@@ -41427,46 +41544,46 @@ msgid ""
"parts of the screen underneath depending on the value of each pixel of the "
"light (mask) texture."
msgstr ""
-"Light2D的光线纹ç†è¢«ç”¨ä½œé®ç½©ï¼Œæ ¹æ®å…‰çº¿é®ç½©çº¹ç†çš„æ¯ä¸ªåƒç´ çš„值,éšè—或显示å±å¹•下"
-"方的部分。"
+"Light2D 的光线纹ç†è¢«ç”¨ä½œé®ç½©ï¼Œæ ¹æ®å…‰çº¿é®ç½©çº¹ç†çš„æ¯ä¸ªåƒç´ çš„值,éšè—或显示å±å¹•"
+"下方的部分。"
#: doc/classes/Light2D.xml
msgid "No filter applies to the shadow map. See [member shadow_filter]."
-msgstr "没有过滤器适用于阴影贴图。å‚阅[member shadow_filter]。"
+msgstr "æ²¡æœ‰è¿‡æ»¤å™¨é€‚ç”¨äºŽé˜´å½±è´´å›¾ã€‚è§ [member shadow_filter]。"
#: doc/classes/Light2D.xml
msgid ""
"Percentage closer filtering (3 samples) applies to the shadow map. See "
"[member shadow_filter]."
-msgstr "百分比接近过滤(3个样本)适用于阴影贴图。å‚阅[member shadow_filter]。"
+msgstr "百分比接近过滤(3 ä¸ªæ ·æœ¬ï¼‰é€‚ç”¨äºŽé˜´å½±è´´å›¾ã€‚è§ [member shadow_filter]。"
#: doc/classes/Light2D.xml
msgid ""
"Percentage closer filtering (5 samples) applies to the shadow map. See "
"[member shadow_filter]."
-msgstr "百分比接近过滤(5个样本)适用于阴影贴图。å‚阅[member shadow_filter]。"
+msgstr "百分比接近过滤(5 ä¸ªæ ·æœ¬ï¼‰é€‚ç”¨äºŽé˜´å½±è´´å›¾ã€‚è§ [member shadow_filter]。"
#: doc/classes/Light2D.xml
msgid ""
"Percentage closer filtering (7 samples) applies to the shadow map. See "
"[member shadow_filter]."
-msgstr "百分比接近过滤(7个样本)适用于阴影贴图。å‚阅[member shadow_filter]。"
+msgstr "百分比接近过滤(7 ä¸ªæ ·æœ¬ï¼‰é€‚ç”¨äºŽé˜´å½±è´´å›¾ã€‚è§ [member shadow_filter]。"
#: doc/classes/Light2D.xml
msgid ""
"Percentage closer filtering (9 samples) applies to the shadow map. See "
"[member shadow_filter]."
-msgstr "百分比接近过滤(9个样本)适用于阴影贴图。å‚阅[member shadow_filter]。"
+msgstr "百分比接近过滤(9 ä¸ªæ ·æœ¬ï¼‰é€‚ç”¨äºŽé˜´å½±è´´å›¾ã€‚è§ [member shadow_filter]。"
#: doc/classes/Light2D.xml
msgid ""
"Percentage closer filtering (13 samples) applies to the shadow map. See "
"[member shadow_filter]."
-msgstr "百分比接近过滤(13个样本)适用于阴影贴图。å‚阅[member shadow_filter]。"
+msgstr "百分比接近过滤(13 ä¸ªæ ·æœ¬ï¼‰é€‚ç”¨äºŽé˜´å½±è´´å›¾ã€‚è§ [member shadow_filter]。"
#: doc/classes/LightOccluder2D.xml
msgid "Occludes light cast by a Light2D, casting shadows."
-msgstr "鮿Œ¡ç”±Light2D投射的光线,投射阴影。"
+msgstr "鮿Œ¡ç”± Light2D 投射的光线,投射阴影。"
#: doc/classes/LightOccluder2D.xml
msgid ""
@@ -41474,7 +41591,7 @@ msgid ""
"be provided with an [OccluderPolygon2D] in order for the shadow to be "
"computed."
msgstr ""
-"鮿Œ¡Light2D投射的ç¯å…‰ï¼ŒæŠ•射阴影。为了计算阴影,必须为LightOccluder2Dæä¾›"
+"鮿Œ¡ Light2D 投射的ç¯å…‰ï¼ŒæŠ•射阴影。为了计算阴影,必须为 LightOccluder2D æä¾› "
"[OccluderPolygon2D]。"
#: doc/classes/LightOccluder2D.xml
@@ -41482,12 +41599,12 @@ msgid ""
"The LightOccluder2D's light mask. The LightOccluder2D will cast shadows only "
"from Light2D(s) that have the same light mask(s)."
msgstr ""
-"LightOccluder2Dçš„ç¯å…‰é®ç½©ã€‚LightOccluder2D将仅从具有相åŒç¯å…‰é®ç½©çš„Light2D投射"
-"阴影。"
+"LightOccluder2D çš„ç¯å…‰é®ç½©ã€‚LightOccluder2D 将仅从具有相åŒç¯å…‰é®ç½©çš„ Light2D "
+"投射阴影。"
#: doc/classes/LightOccluder2D.xml
msgid "The [OccluderPolygon2D] used to compute the shadow."
-msgstr "用于计算阴影的[OccluderPolygon2D]。"
+msgstr "用于计算阴影的 [OccluderPolygon2D]。"
#: doc/classes/Line2D.xml
msgid "A 2D line."
@@ -41538,17 +41655,18 @@ msgstr "返回该 Line2D 上点的数é‡ã€‚"
#: doc/classes/Line2D.xml
msgid "Returns point [code]i[/code]'s position."
-msgstr "返回点[code]i[/code]çš„ä½ç½®ã€‚"
+msgstr "返回点 [code]i[/code] çš„ä½ç½®ã€‚"
#: doc/classes/Line2D.xml
msgid "Removes the point at index [code]i[/code] from the line."
-msgstr "将索引[code]i[/code]处的点从直线中移除。"
+msgstr "将索引 [code]i[/code] 处的点从直线中移除。"
#: doc/classes/Line2D.xml
msgid ""
"Overwrites the position in point [code]i[/code] with the supplied "
"[code]position[/code]."
-msgstr "用æä¾›çš„[code]position[/code]ä½ç½®è¦†ç›–索引[code]i[/code]处点的ä½ç½®ã€‚"
+msgstr ""
+"用æä¾›çš„ [code]position[/code] ä½ç½®è¦†ç›–索引 [code]i[/code] 处点的ä½ç½®ã€‚"
#: doc/classes/Line2D.xml
msgid ""
@@ -41632,7 +41750,7 @@ msgstr ""
msgid ""
"The texture used for the line's texture. Uses [code]texture_mode[/code] for "
"drawing style."
-msgstr "用于线æ¡çº¹ç†çš„纹ç†ã€‚使用[code]texture_mode[/code]作为绘图样å¼ã€‚"
+msgstr "用于线æ¡çº¹ç†çš„纹ç†ã€‚使用 [code]texture_mode[/code] 作为绘图样å¼ã€‚"
#: doc/classes/Line2D.xml
msgid ""
@@ -42087,7 +42205,7 @@ msgstr "按下清除按钮时使用的颜色。"
#: doc/classes/LineEdit.xml
msgid "Color of the [LineEdit]'s visual cursor (caret)."
-msgstr "[LineEdit]å¯è§†å…‰æ ‡(æ’入符å·)的颜色。"
+msgstr "[LineEdit] å¯è§†å…‰æ ‡ï¼ˆæ’入符å·ï¼‰çš„颜色。"
#: doc/classes/LineEdit.xml
msgid "Default font color."
@@ -42095,7 +42213,7 @@ msgstr "默认字体颜色。"
#: doc/classes/LineEdit.xml
msgid "Font color for selected text (inside the selection rectangle)."
-msgstr "选定文本的字体颜色(在选择矩形内)。"
+msgstr "选定文本的字体颜色(在选择矩形内)。"
#: doc/classes/LineEdit.xml
msgid "Font color when editing is disabled."
@@ -42111,8 +42229,8 @@ msgid ""
"content margins). This value is measured in count of space characters (i.e. "
"this amount of space characters can be displayed without scrolling)."
msgstr ""
-"æ–‡æœ¬çš„æœ€å°æ°´å¹³ç©ºé—´(ä¸åŒ…括清除按钮和内容边è·)。该值以空格字符的计数æ¥è¡¡é‡(峿— "
-"需滚动å³å¯æ˜¾ç¤ºç©ºæ ¼å­—符的数é‡)。"
+"æ–‡æœ¬çš„æœ€å°æ°´å¹³ç©ºé—´ï¼ˆä¸åŒ…括清除按钮和内容边è·ï¼‰ã€‚该值以空格字符的计数æ¥è¡¡é‡"
+"ï¼ˆå³æ— éœ€æ»šåЍå³å¯æ˜¾ç¤ºç©ºæ ¼å­—符的数é‡ï¼‰ã€‚"
#: doc/classes/LineEdit.xml
msgid "Font used for the text."
@@ -42120,7 +42238,7 @@ msgstr "文本使用的字体。"
#: doc/classes/LineEdit.xml
msgid "Texture for the clear button. See [member clear_button_enabled]."
-msgstr "â€œæ¸…é™¤â€æŒ‰é’®çš„纹ç†ã€‚请å‚阅 [member clear_button_enabled]。"
+msgstr "â€œæ¸…é™¤â€æŒ‰é’®çš„纹ç†ã€‚è§ [member clear_button_enabled]。"
#: doc/classes/LineEdit.xml
msgid "Background used when [LineEdit] has GUI focus."
@@ -42413,7 +42531,7 @@ msgstr "在程åºé€€å‡ºå‰è°ƒç”¨ã€‚"
msgid ""
"Called when the user performs an action in the system global menu (e.g. the "
"Mac OS menu bar)."
-msgstr "当用户在系统全局èœå•(如 Mac OSçš„èœå•æ ï¼‰ä¸­æ‰§è¡ŒåŠ¨ä½œæ—¶è¢«è°ƒç”¨ã€‚"
+msgstr "当用户在系统全局èœå•(如 Mac OS çš„èœå•æ ï¼‰ä¸­æ‰§è¡ŒåŠ¨ä½œæ—¶è¢«è°ƒç”¨ã€‚"
#: doc/classes/MainLoop.xml
msgid ""
@@ -42723,8 +42841,9 @@ msgid ""
"Do not use this option if the serialized object comes from untrusted sources "
"to avoid potential security threats such as remote code execution."
msgstr ""
-"返回一个对应于Base64ç¼–ç çš„字符串[code]base64_str[/code]的解ç [Variant]。如果"
-"[code]allow_objects[/code]是[code]true[/code],则å…许对对象进行解ç ã€‚\n"
+"返回一个对应于 Base64 ç¼–ç çš„字符串 [code]base64_str[/code] çš„è§£ç  [Variant]。"
+"如果 [code]allow_objects[/code] 是 [code]true[/code],则å…许对对象进行解"
+"ç ã€‚\n"
"[b]警告:[/b]ååºåˆ—化的对象å¯èƒ½åŒ…å«ä¼šè¢«æ‰§è¡Œçš„代ç ã€‚如果åºåˆ—化的对象æ¥è‡ªä¸å—ä¿¡"
"ä»»çš„æ¥æºï¼Œè¯·ä¸è¦ä½¿ç”¨è¿™ä¸ªé€‰é¡¹ï¼Œä»¥é¿å…潜在的安全å¨èƒï¼Œå¦‚è¿œç¨‹ä»£ç æ‰§è¡Œã€‚"
@@ -42899,11 +43018,11 @@ msgstr "当鼠标在 [MenuButton] ä¸Šæ‚¬åœæ—¶ä½¿ç”¨çš„ [StyleBox] æ ·å¼ç›’。"
#: doc/classes/MenuButton.xml
msgid "Default [StyleBox] for the [MenuButton]."
-msgstr "[MenuButton]的默认[StyleBox]æ ·å¼ç›’。"
+msgstr "[MenuButton] 的默认 [StyleBox] æ ·å¼ç›’。"
#: doc/classes/MenuButton.xml
msgid "[StyleBox] used when the [MenuButton] is being pressed."
-msgstr "[MenuButton]被按下时的[StyleBox]æ ·å¼ç›’。"
+msgstr "[MenuButton] 被按下时的 [StyleBox] æ ·å¼ç›’。"
#: doc/classes/Mesh.xml
msgid "A [Resource] that contains vertex array-based geometry."
@@ -42934,8 +43053,8 @@ msgstr ""
"如果 [code]clean[/code] 是 [code]true[/code] (默认),é‡å¤çš„和内部的顶点会被"
"自动移除。你å¯ä»¥æŠŠå®ƒè®¾ä¸º [code]false[/code] æ¥ä½¿è¿™ä¸ªè¿‡ç¨‹æ›´å¿«ï¼Œå¦‚æžœä¸éœ€è¦çš„"
"è¯ã€‚\n"
-"如果[code]simplify[/code]是[code]true[/code],å¯ä»¥è¿›ä¸€æ­¥ç®€åŒ–几何体以å‡å°‘顶点"
-"的数é‡ã€‚默认情况下是ç¦ç”¨çš„。"
+"如果 [code]simplify[/code] 是 [code]true[/code],å¯ä»¥è¿›ä¸€æ­¥ç®€åŒ–几何体以å‡å°‘é¡¶"
+"点的数é‡ã€‚默认情况下是ç¦ç”¨çš„。"
#: doc/classes/Mesh.xml
msgid ""
@@ -42949,11 +43068,11 @@ msgstr ""
#: doc/classes/Mesh.xml
msgid "Calculate a [ConcavePolygonShape] from the mesh."
-msgstr "从网格中计算出[ConcavePolygonShape]。"
+msgstr "从网格中计算出 [ConcavePolygonShape]。"
#: doc/classes/Mesh.xml
msgid "Generate a [TriangleMesh] from the mesh."
-msgstr "从网格生æˆ[TriangleMesh]。"
+msgstr "ä»Žç½‘æ ¼ç”Ÿæˆ [TriangleMesh]。"
#: doc/classes/Mesh.xml
msgid ""
@@ -42992,21 +43111,21 @@ msgstr "返回所需é¢çš„æ··åˆå½¢çŠ¶æ•°ç»„ã€‚"
msgid ""
"Returns a [Material] in a given surface. Surface is rendered using this "
"material."
-msgstr "返回给定é¢çš„[Material]æè´¨ã€‚é¢å°†ç”±è¯¥æè´¨æ¥æ¸²æŸ“。"
+msgstr "返回给定é¢çš„ [Material] æè´¨ã€‚é¢å°†ç”±è¯¥æè´¨æ¥æ¸²æŸ“。"
#: doc/classes/Mesh.xml
msgid ""
"Sets a [Material] for a given surface. Surface will be rendered using this "
"material."
-msgstr "设置给定é¢çš„[Material]æè´¨ã€‚该é¢å°†ä¼šä½¿ç”¨æ­¤æè´¨æ¸²æŸ“。"
+msgstr "设置给定é¢çš„ [Material] æè´¨ã€‚该é¢å°†ä¼šä½¿ç”¨æ­¤æè´¨æ¸²æŸ“。"
#: doc/classes/Mesh.xml
msgid ""
"Sets a hint to be used for lightmap resolution in [BakedLightmap]. Overrides "
"[member BakedLightmap.default_texels_per_unit]."
msgstr ""
-"设置æç¤ºï¼Œç”¨äºŽ[BakedLightmap]中的光照贴图分辨率。é‡å†™[member BakedLightmap."
-"default_texels_per_unit]。"
+"设置æç¤ºï¼Œç”¨äºŽ [BakedLightmap] 中的光照贴图分辨率。é‡å†™ [member "
+"BakedLightmap.default_texels_per_unit]。"
#: doc/classes/Mesh.xml
msgid "Render array as points (one vertex equals one point)."
@@ -43065,11 +43184,11 @@ msgstr "网格组包å«é¢œè‰²ã€‚"
#: doc/classes/Mesh.xml
msgid "Mesh array contains UVs."
-msgstr "网格组包å«UV。"
+msgstr "ç½‘æ ¼ç»„åŒ…å« UV。"
#: doc/classes/Mesh.xml
msgid "Mesh array contains second UV."
-msgstr "网格组包å«ç¬¬äºŒå¥—UV。"
+msgstr "网格组包å«ç¬¬äºŒå¥— UV。"
#: doc/classes/Mesh.xml
msgid "Mesh array contains bones."
@@ -43087,7 +43206,7 @@ msgstr "网格组使用索引。"
msgid ""
"Used internally to calculate other [code]ARRAY_COMPRESS_*[/code] enum "
"values. Do not use."
-msgstr "内部用于计算其他[code]ARRAY_COMPRESS_*[/code]枚举值。ä¸è¦ä½¿ç”¨ã€‚"
+msgstr "内部用于计算其他 [code]ARRAY_COMPRESS_*[/code] 枚举值。ä¸è¦ä½¿ç”¨ã€‚"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Flag used to mark a compressed (half float) vertex array."
@@ -43095,25 +43214,25 @@ msgstr "用于标记压缩(åŠç²¾åº¦æµ®ç‚¹ï¼‰é¡¶ç‚¹æ•°ç»„的标志。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Flag used to mark a compressed (half float) normal array."
-msgstr "曾ç»ç”¨äºŽæ ‡è®°åŽ‹ç¼©ï¼ˆåŠç²¾åº¦æµ®ç‚¹ï¼‰æ³•呿•°ç»„çš„ Flag。"
+msgstr "曾ç»ç”¨äºŽæ ‡è®°åŽ‹ç¼©ï¼ˆåŠç²¾åº¦æµ®ç‚¹ï¼‰æ³•呿•°ç»„的标志。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Flag used to mark a compressed (half float) tangent array."
-msgstr "曾ç»ç”¨äºŽæ ‡è®°åŽ‹ç¼©ï¼ˆåŠç²¾åº¦æµ®ç‚¹ï¼‰åˆ‡å‘数组的Flag。"
+msgstr "曾ç»ç”¨äºŽæ ‡è®°åŽ‹ç¼©ï¼ˆåŠç²¾åº¦æµ®ç‚¹ï¼‰åˆ‡å‘数组的标志。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Flag used to mark a compressed (half float) color array."
-msgstr "曾用于标记压缩(åŠç²¾åº¦æµ®ç‚¹ï¼‰é¢œè‰²æ•°ç»„çš„Flag。"
+msgstr "曾用于标记压缩(åŠç²¾åº¦æµ®ç‚¹ï¼‰é¢œè‰²æ•°ç»„的标志。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Flag used to mark a compressed (half float) UV coordinates array."
-msgstr "曾用于标记压缩(åŠç²¾åº¦æµ®ç‚¹ï¼‰UV åæ ‡æ•°ç»„çš„ Flag。"
+msgstr "曾用于标记压缩(åŠç²¾åº¦æµ®ç‚¹ï¼‰UV åæ ‡æ•°ç»„的标志。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid ""
"Flag used to mark a compressed (half float) UV coordinates array for the "
"second UV coordinates."
-msgstr "曾用于标记第二套UVåæ ‡çš„压缩(åŠç²¾åº¦æµ®ç‚¹ï¼‰UVåæ ‡æ•°ç»„çš„Flag。"
+msgstr "曾用于标记第二套 UV åæ ‡çš„压缩(åŠç²¾åº¦æµ®ç‚¹ï¼‰UV åæ ‡æ•°ç»„的标志。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Flag used to mark a compressed bone array."
@@ -43125,15 +43244,15 @@ msgstr "用于标记压缩(åŠç²¾åº¦æµ®ç‚¹ï¼‰æƒé‡æ•°ç»„的标志。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Flag used to mark a compressed index array."
-msgstr "曾用于标记压缩索引数组的Flag。"
+msgstr "曾用于标记压缩索引数组的标志。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Flag used to mark that the array contains 2D vertices."
-msgstr "曾用于标记包å«2D顶点的数组的Flag。"
+msgstr "æ›¾ç”¨äºŽæ ‡è®°åŒ…å« 2D 顶点的数组的标志。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid "Flag used to mark that the array uses 16-bit bones instead of 8-bit."
-msgstr "用于标记数组使用16ä½éª¨éª¼è€Œä¸æ˜¯8ä½çš„æ ‡å¿—。"
+msgstr "用于标记数组使用 16 ä½éª¨éª¼è€Œä¸æ˜¯ 8 ä½çš„æ ‡å¿—。"
#: doc/classes/Mesh.xml doc/classes/VisualServer.xml
msgid ""
@@ -43149,10 +43268,10 @@ msgid ""
"ARRAY_COMPRESS_TEX_UV2], [constant ARRAY_COMPRESS_WEIGHTS], and [constant "
"ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION] quickly."
msgstr ""
-"用于快速设置标志[constant ARRAY_COMPRESS_VERTEX], [constant "
-"ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant "
-"ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV], [constant "
-"ARRAY_COMPRESS_TEX_UV2] , [constant ARRAY_COMPRESS_WEIGHTS], 和[constant "
+"用于快速设置标志 [constant ARRAY_COMPRESS_VERTEX]ã€[constant "
+"ARRAY_COMPRESS_NORMAL]ã€[constant ARRAY_COMPRESS_TANGENT]ã€[constant "
+"ARRAY_COMPRESS_COLOR]ã€[constant ARRAY_COMPRESS_TEX_UV]ã€[constant "
+"ARRAY_COMPRESS_TEX_UV2]ã€[constant ARRAY_COMPRESS_WEIGHTS]ã€[constant "
"ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION] 。"
#: doc/classes/Mesh.xml
@@ -43165,7 +43284,7 @@ msgstr "法线数组。"
#: doc/classes/Mesh.xml
msgid "Array of tangents as an array of floats, 4 floats per tangent."
-msgstr "åˆ‡å‘æ•°ç»„。æ¯ä¸€ä¸ªåˆ‡å‘æ•°æ®ç”±å››ä¸ªfloatå˜é‡æè¿°ã€‚"
+msgstr "åˆ‡å‘æ•°ç»„。æ¯ä¸€ä¸ªåˆ‡å‘æ•°æ®ç”±å››ä¸ª float å˜é‡æè¿°ã€‚"
#: doc/classes/Mesh.xml
msgid "Array of colors."
@@ -43177,7 +43296,7 @@ msgstr "UV åæ ‡æ•°ç»„。"
#: doc/classes/Mesh.xml
msgid "Array of second set of UV coordinates."
-msgstr "第二套UVåæ ‡æ•°ç»„。"
+msgstr "第二套 UV åæ ‡æ•°ç»„。"
#: doc/classes/Mesh.xml
msgid "Array of bone data."
@@ -43259,7 +43378,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid "Clears all data currently in MeshDataTool."
-msgstr "将当å‰MeshDataTool中所有的数æ®å…¨éƒ¨æ¸…除。"
+msgstr "å°†å½“å‰ MeshDataTool 中所有的数æ®å…¨éƒ¨æ¸…除。"
#: doc/classes/MeshDataTool.xml
msgid "Adds a new surface to specified [Mesh] with edited data."
@@ -43292,11 +43411,11 @@ msgid ""
"vertices."
msgstr ""
"返回连接到给定边的指定顶点的索引。\n"
-"é¡¶ç‚¹å‚æ•°åªèƒ½æ˜¯0或1,因为边是由两个顶点组æˆçš„。"
+"é¡¶ç‚¹å‚æ•°åªèƒ½æ˜¯ 0 或 1,因为边是由两个顶点组æˆçš„。"
#: doc/classes/MeshDataTool.xml
msgid "Returns the number of faces in this [Mesh]."
-msgstr "返回这个[Mesh]ä¸­çš„é¢æ•°ã€‚"
+msgstr "返回这个 [Mesh] ä¸­çš„é¢æ•°ã€‚"
#: doc/classes/MeshDataTool.xml
msgid ""
@@ -43340,7 +43459,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid "Returns the material assigned to the [Mesh]."
-msgstr "返回分é…ç»™[Mesh]çš„æè´¨ã€‚"
+msgstr "返回分é…ç»™ [Mesh] çš„æè´¨ã€‚"
#: doc/classes/MeshDataTool.xml
msgid "Returns the vertex at given index."
@@ -43356,7 +43475,7 @@ msgstr "返回给定顶点的颜色。"
#: doc/classes/MeshDataTool.xml
msgid "Returns the total number of vertices in [Mesh]."
-msgstr "返回[Mesh]中顶点的总数。"
+msgstr "返回 [Mesh] 中顶点的总数。"
#: doc/classes/MeshDataTool.xml
msgid "Returns an array of edges that share the given vertex."
@@ -43380,11 +43499,11 @@ msgstr "返回给定顶点的正切值。"
#: doc/classes/MeshDataTool.xml
msgid "Returns the UV of the given vertex."
-msgstr "返回给定顶点的UV。"
+msgstr "返回给定顶点的 UV。"
#: doc/classes/MeshDataTool.xml
msgid "Returns the UV2 of the given vertex."
-msgstr "返回给定顶点的UV2。"
+msgstr "返回给定顶点的 UV2。"
#: doc/classes/MeshDataTool.xml
msgid "Returns bone weights of the given vertex."
@@ -43400,7 +43519,7 @@ msgstr "设置给定é¢çš„元数æ®ã€‚"
#: doc/classes/MeshDataTool.xml
msgid "Sets the material to be used by newly-constructed [Mesh]."
-msgstr "设置新构建的[Mesh]使用的æè´¨ã€‚"
+msgstr "设置新构建的 [Mesh] 使用的æè´¨ã€‚"
#: doc/classes/MeshDataTool.xml
msgid "Sets the position of the given vertex."
@@ -43428,11 +43547,11 @@ msgstr "设置给定顶点的切线。"
#: doc/classes/MeshDataTool.xml
msgid "Sets the UV of the given vertex."
-msgstr "设置给定顶点的UV。"
+msgstr "设置给定顶点的 UV。"
#: doc/classes/MeshDataTool.xml
msgid "Sets the UV2 of the given vertex."
-msgstr "设置给定顶点的UV2。"
+msgstr "设置给定顶点的 UV2。"
#: doc/classes/MeshDataTool.xml
msgid "Sets the bone weights of the given vertex."
@@ -43451,10 +43570,10 @@ msgid ""
"[Mesh] has to be instanced more than thousands of times at close proximity, "
"consider using a [MultiMesh] in a [MultiMeshInstance] instead."
msgstr ""
-"MeshInstance是一个节点,它获å–[Mesh]资æºå¹¶åˆ›å»ºä¸€ä¸ªå®žä¾‹ï¼Œå°†å…¶æ·»åŠ åˆ°å½“å‰åœºæ™¯"
-"ä¸­ã€‚è¿™æ˜¯æœ€å¸¸è¢«ç”¨æ¥æ¸²æŸ“3D几何体的类,这å¯ä»¥åœ¨å¾ˆå¤šåœ°æ–¹ä½¿ç”¨[Mesh]实例,它å…许é‡"
-"å¤ä½¿ç”¨å‡ ä½•体并节çœèµ„æºã€‚当[Mesh]å¿…é¡»åœ¨å¾ˆè¿‘çš„åœ°æ–¹è¢«å®žä¾‹åŒ–è¶…è¿‡æ•°åƒæ¬¡æ—¶ï¼Œå¯ä»¥è€ƒ"
-"虑在[MultiMeshInstance]中使用[MultiMesh]æ¥ä»£æ›¿ã€‚"
+"MeshInstance æ˜¯ä¸€ä¸ªèŠ‚ç‚¹ï¼Œå®ƒèŽ·å– [Mesh] 资æºå¹¶åˆ›å»ºä¸€ä¸ªå®žä¾‹ï¼Œå°†å…¶æ·»åŠ åˆ°å½“å‰åœºæ™¯"
+"ä¸­ã€‚è¿™æ˜¯æœ€å¸¸è¢«ç”¨æ¥æ¸²æŸ“ 3D 几何体的类,这å¯ä»¥åœ¨å¾ˆå¤šåœ°æ–¹ä½¿ç”¨ [Mesh] 实例,它å…"
+"许é‡å¤ä½¿ç”¨å‡ ä½•体并节çœèµ„æºã€‚当 [Mesh] å¿…é¡»åœ¨å¾ˆè¿‘çš„åœ°æ–¹è¢«å®žä¾‹åŒ–è¶…è¿‡æ•°åƒæ¬¡æ—¶ï¼Œ"
+"å¯ä»¥è€ƒè™‘在 [MultiMeshInstance] 中使用 [MultiMesh] æ¥ä»£æ›¿ã€‚"
#: doc/classes/MeshInstance.xml
msgid ""
@@ -43467,21 +43586,21 @@ msgid ""
"If [code]simplify[/code] is [code]true[/code], the geometry can be further "
"simplified to reduce the amount of vertices. Disabled by default."
msgstr ""
-"这个助手创建[StaticBody]å­èŠ‚ç‚¹ï¼Œè¯¥èŠ‚ç‚¹å…·æœ‰ä»Žç½‘æ ¼å‡ ä½•å½¢çŠ¶è®¡ç®—çš„"
-"[ConvexPolygonShape]碰撞形状。其主è¦ç”¨äºŽæµ‹è¯•。\n"
-"如果[code]clean[/code]是[code]true[/code](默认),é‡å¤çš„顶点和内部顶点会被自"
-"动移除。å¯ä»¥æŠŠå®ƒè®¾ç½®ä¸º [code]false[/code],以便在ä¸éœ€è¦çš„æƒ…况下使这个过程更"
-"快。\n"
-"如果[code]simplify[/code]是[code]true[/code],å¯ä»¥è¿›ä¸€æ­¥ç®€åŒ–几何体以å‡å°‘顶点"
-"的数é‡ã€‚默认情况下是ç¦ç”¨çš„。"
+"这个辅助工具创建 [StaticBody] å­èŠ‚ç‚¹ï¼Œè¯¥èŠ‚ç‚¹å…·æœ‰ä»Žç½‘æ ¼å‡ ä½•å½¢çŠ¶è®¡ç®—çš„ "
+"[ConvexPolygonShape] 碰撞形状。其主è¦ç”¨äºŽæµ‹è¯•。\n"
+"如果 [code]clean[/code] 是 [code]true[/code](默认),é‡å¤çš„顶点和内部顶点会"
+"被自动移除。å¯ä»¥æŠŠå®ƒè®¾ç½®ä¸º [code]false[/code],以便在ä¸éœ€è¦çš„æƒ…况下使这个过程"
+"更快。\n"
+"如果 [code]simplify[/code] 是 [code]true[/code],å¯ä»¥è¿›ä¸€æ­¥ç®€åŒ–几何体以å‡å°‘é¡¶"
+"点的数é‡ã€‚默认情况下是ç¦ç”¨çš„。"
#: doc/classes/MeshInstance.xml
msgid ""
"This helper creates a [MeshInstance] child node with gizmos at every vertex "
"calculated from the mesh geometry. It's mainly used for testing."
msgstr ""
-"这个辅助工具创建[MeshInstance]å­èŠ‚ç‚¹ï¼Œåœ¨æ¯ä¸ªé¡¶ç‚¹éƒ½æœ‰æ ¹æ®ç½‘格几何形状计算的辅"
-"助线框。其主è¦ç”¨äºŽæµ‹è¯•。"
+"这个辅助工具创建 [MeshInstance] å­èŠ‚ç‚¹ï¼Œåœ¨æ¯ä¸ªé¡¶ç‚¹éƒ½æœ‰æ ¹æ®ç½‘格几何形状计算的"
+"辅助线框。其主è¦ç”¨äºŽæµ‹è¯•。"
#: doc/classes/MeshInstance.xml
msgid ""
@@ -43489,8 +43608,8 @@ msgid ""
"[ConvexPolygonShape] collision shapes calculated from the mesh geometry via "
"convex decomposition. It's mainly used for testing."
msgstr ""
-"这个助手创建[StaticBody]å­èŠ‚ç‚¹ï¼Œè¯¥èŠ‚ç‚¹å…·æœ‰å¤šä¸ª[ConvexPolygonShape]碰撞形状,"
-"这些碰撞形状是通过凸é¢åˆ†è§£ä»Žç½‘格几何形状计算出æ¥çš„。其主è¦ç”¨äºŽæµ‹è¯•。"
+"这个辅助工具创建 [StaticBody] å­èŠ‚ç‚¹ï¼Œè¯¥èŠ‚ç‚¹å…·æœ‰å¤šä¸ª [ConvexPolygonShape] 碰"
+"撞形状,这些碰撞形状是通过凸é¢åˆ†è§£ä»Žç½‘格几何形状计算出æ¥çš„。其主è¦ç”¨äºŽæµ‹è¯•。"
#: doc/classes/MeshInstance.xml
msgid ""
@@ -43498,7 +43617,7 @@ msgid ""
"collision shape calculated from the mesh geometry. It's mainly used for "
"testing."
msgstr ""
-"这个助手创建[StaticBody]å­èŠ‚ç‚¹ï¼Œå…¶ç¢°æ’žå½¢çŠ¶æ˜¯ç”±ç½‘æ ¼çš„å‡ ä½•å½¢çŠ¶è®¡ç®—å‡ºæ¥çš„"
+"这个辅助工具创建 [StaticBody] å­èŠ‚ç‚¹ï¼Œå…¶ç¢°æ’žå½¢çŠ¶æ˜¯ç”±ç½‘æ ¼çš„å‡ ä½•å½¢çŠ¶è®¡ç®—å‡ºæ¥çš„ "
"[ConcavePolygonShape],其主è¦ç”¨äºŽæµ‹è¯•。"
#: doc/classes/MeshInstance.xml
@@ -43509,18 +43628,27 @@ msgid ""
"[Material] defined in the [Mesh]. For example, if [member GeometryInstance."
"material_override] is used, all surfaces will return the override material."
msgstr ""
-"返回[Mesh]绘制时使用的[Material]。这å¯ä»¥è¿”回[member GeometryInstance."
-"material_override],这个[MeshInstance]中定义的表é¢è¦†ç›–[Material],或者[Mesh]"
-"中定义的表é¢[Material]。例如,如果使用[member GeometryInstance."
+"返回 [Mesh] 绘制时使用的 [Material]。这å¯ä»¥è¿”回 [member GeometryInstance."
+"material_override],这个 [MeshInstance] 中定义的表é¢è¦†ç›– [Material],或者 "
+"[Mesh] ä¸­å®šä¹‰çš„è¡¨é¢ [Material]。例如,如果使用 [member GeometryInstance."
"material_override],所有的表é¢éƒ½ä¼šè¿”回覆盖的æè´¨ã€‚"
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
-msgstr "返回[Mesh]资æºè¡¨é¢çš„[Material]。"
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
+msgstr ""
+"返回该 [Mesh] 资æºä¸ŠæŸä¸ªè¡¨é¢çš„ [Material] 覆盖项。\n"
+"[b]注æ„:[/b]这个函数åªä¼šè¿”回与这个 [MeshInstance] 相关è”çš„[i]覆盖[/i]æè´¨ã€‚"
+"è¦èŽ·å–与该 [Mesh] 相关è”çš„æè´¨ï¼Œè¯·è€ƒè™‘使用 [method get_active_material] 或 "
+"[method Mesh.surface_get_material]。"
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr "è¿”å›žè¡¨é¢æè´¨çš„æ•°é‡ã€‚"
+msgid "Returns the number of surface override materials."
+msgstr "è¿”å›žè¡¨é¢æè´¨è¦†ç›–é¡¹çš„æ•°é‡ã€‚"
#: doc/classes/MeshInstance.xml
msgid ""
@@ -43570,12 +43698,17 @@ msgstr ""
"å¦å¤–请注æ„,目标 [MeshInstance] 中的任何åˆå§‹æ•°æ®éƒ½ä¼šè¢«ä¸¢å¼ƒã€‚"
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
-msgstr "为[Mesh]资æºçš„表é¢è®¾ç½®[Material]。"
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
+msgstr ""
+"设置该 [Mesh] 资æºçš„æŒ‡å®šè¡¨é¢çš„ [Material] 覆盖项。这个æè´¨ä¼šä¸Žè¿™ä¸ª "
+"[MeshInstance] å…³è”ï¼Œè€Œä¸æ˜¯ä¸Ž [Mesh] 资æºå…³è”。"
#: doc/classes/MeshInstance.xml
msgid "The [Mesh] resource for the instance."
-msgstr "该实例的[Mesh]资æºã€‚"
+msgstr "该实例的 [Mesh] 资æºã€‚"
#: doc/classes/MeshInstance.xml
msgid "[NodePath] to the [Skeleton] associated with the instance."
@@ -43601,7 +43734,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml
msgid "Node used for displaying a [Mesh] in 2D."
-msgstr "用于在2D中显示[Mesh]的节点。"
+msgstr "用于在 2D 中显示 [Mesh] 的节点。"
#: doc/classes/MeshInstance2D.xml
msgid ""
@@ -43616,7 +43749,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml
msgid "The [Mesh] that will be drawn by the [MeshInstance2D]."
-msgstr "[Mesh]将由[MeshInstance2D]绘制。"
+msgstr "[Mesh] 将由 [MeshInstance2D] 绘制。"
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
@@ -43642,7 +43775,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid "Emitted when the [member texture] is changed."
-msgstr "当[member texture]è¢«æ”¹å˜æ—¶è§¦å‘。"
+msgstr "当 [member texture] è¢«æ”¹å˜æ—¶è§¦å‘。"
#: doc/classes/MeshLibrary.xml
msgid "Library of meshes."
@@ -43654,8 +43787,8 @@ msgid ""
"and ID. Each item can also include collision and navigation shapes. This "
"resource is used in [GridMap]."
msgstr ""
-"网格库包å«ä¸€ä¸ª[Mesh]资æºåˆ—表,æ¯ä¸ªèµ„æºéƒ½æœ‰ä¸€ä¸ªåç§°å’ŒID。æ¯ä¸ªé¡¹ç›®è¿˜å¯ä»¥åŒ…括碰"
-"撞和导航形状。这个资æºåœ¨[GridMap]中使用。"
+"网格库包å«ä¸€ä¸ª [Mesh] 资æºåˆ—表,æ¯ä¸ªèµ„æºéƒ½æœ‰ä¸€ä¸ªåç§°å’Œ ID。æ¯ä¸ªé¡¹ç›®è¿˜å¯ä»¥åŒ…括"
+"碰撞和导航形状。这个资æºåœ¨ [GridMap] 中使用。"
#: doc/classes/MeshLibrary.xml
msgid "Clears the library."
@@ -43666,8 +43799,8 @@ msgid ""
"Creates a new item in the library with the given ID.\n"
"You can get an unused ID from [method get_last_unused_item_id]."
msgstr ""
-"使用给定的ID在库中创建一个新项。\n"
-"ä½ å¯ä»¥ä»Ž[method get_last_unused_item_id]获å–一个未使用的ID。"
+"使用给定的 ID 在库中创建一个新项。\n"
+"ä½ å¯ä»¥ä»Ž [method get_last_unused_item_id] 获å–一个未使用的 ID。"
#: doc/classes/MeshLibrary.xml
msgid "Returns the first item with the given name."
@@ -43675,7 +43808,7 @@ msgstr "返回第一个指定åç§°çš„ item。"
#: doc/classes/MeshLibrary.xml
msgid "Returns the list of item IDs in use."
-msgstr "返回正在使用的 item id列表。"
+msgstr "返回正在使用的 item id 列表。"
#: doc/classes/MeshLibrary.xml
msgid "Returns the item's mesh."
@@ -43715,11 +43848,11 @@ msgid ""
"The array consists of each [Shape] followed by its [Transform]."
msgstr ""
"返回项目的碰撞形状。\n"
-"这个数组由æ¯ä¸ª[Shape]和它的[Transform]组æˆã€‚"
+"这个数组由æ¯ä¸ª [Shape] 和它的 [Transform] 组æˆã€‚"
#: doc/classes/MeshLibrary.xml
msgid "Gets an unused ID for a new item."
-msgstr "èŽ·å–æ–°é¡¹æœªä½¿ç”¨çš„ID。"
+msgstr "èŽ·å–æ–°é¡¹æœªä½¿ç”¨çš„ ID。"
#: doc/classes/MeshLibrary.xml
msgid "Removes the item."
@@ -43740,7 +43873,7 @@ msgid ""
"later using [method find_item_by_name]."
msgstr ""
"设置项的å称。\n"
-"该å称显示在编辑器中。ç¨åŽè¿˜å¯ä»¥ä½¿ç”¨[method find_item_by_name]æ¥æŸ¥æ‰¾è¯¥é¡¹ã€‚"
+"该å称显示在编辑器中。ç¨åŽè¿˜å¯ä»¥ä½¿ç”¨ [method find_item_by_name] æ¥æŸ¥æ‰¾è¯¥é¡¹ã€‚"
#: doc/classes/MeshLibrary.xml
msgid "Sets the item's navigation mesh."
@@ -43774,8 +43907,8 @@ msgid ""
"Simple texture that uses a mesh to draw itself. It's limited because flags "
"can't be changed and region drawing is not supported."
msgstr ""
-"简å•的纹ç†ï¼Œä½¿ç”¨ä¸€ä¸ªç½‘æ ¼æ¥ç»˜åˆ¶è‡ªå·±ã€‚它的应用场景有é™ï¼Œå› ä¸ºFlagä¸èƒ½æ›´æ”¹ï¼Œè€Œä¸”"
-"䏿”¯æŒåŒºåŸŸç»˜åˆ¶ã€‚"
+"简å•的纹ç†ï¼Œä½¿ç”¨ä¸€ä¸ªç½‘æ ¼æ¥ç»˜åˆ¶è‡ªå·±ã€‚它的应用场景有é™ï¼Œå› ä¸º Flag ä¸èƒ½æ›´æ”¹ï¼Œè€Œ"
+"䏔䏿”¯æŒåŒºåŸŸç»˜åˆ¶ã€‚"
#: doc/classes/MeshTexture.xml
msgid "Sets the base texture that the Mesh will use to draw."
@@ -43787,7 +43920,7 @@ msgstr "设置图åƒçš„大å°ï¼Œéœ€è¦å‚考。"
#: doc/classes/MeshTexture.xml
msgid "Sets the mesh used to draw. It must be a mesh using 2D vertices."
-msgstr "设置用于绘制的网格,该网格必须使用2D顶点。"
+msgstr "设置用于绘制的网格,该网格必须使用 2D 顶点。"
#: doc/classes/MethodTweener.xml
msgid ""
@@ -43835,7 +43968,7 @@ msgstr ""
#: modules/mobile_vr/doc_classes/MobileVRInterface.xml
msgid "Generic mobile VR implementation."
-msgstr "通用移动VR实现。"
+msgstr "通用移动 VR 实现。"
#: modules/mobile_vr/doc_classes/MobileVRInterface.xml
msgid ""
@@ -43879,7 +44012,7 @@ msgstr "显示器的宽度,以厘米为å•ä½ã€‚"
msgid ""
"The height at which the camera is placed in relation to the ground (i.e. "
"[ARVROrigin] node)."
-msgstr "æ‘„åƒæœºç›¸å¯¹äºŽåœ°é¢æ‰€å¤„的高度,å³[ARVROrigin]节点。"
+msgstr "æ‘„åƒæœºç›¸å¯¹äºŽåœ°é¢æ‰€å¤„çš„é«˜åº¦ï¼Œå³ [ARVROrigin] 节点。"
#: modules/mobile_vr/doc_classes/MobileVRInterface.xml
msgid ""
@@ -43891,11 +44024,12 @@ msgstr "眼间è·ç¦»ï¼Œä¹Ÿç§°ä¸ºçž³å­”é—´è·ç¦»ã€‚左眼和å³çœ¼çž³å­”之间的
msgid ""
"The k1 lens factor is one of the two constants that define the strength of "
"the lens used and directly influences the lens distortion effect."
-msgstr "k1é•œå¤´å› å­æ˜¯å®šä¹‰æ‰€ä½¿ç”¨é•œå¤´å¼ºåº¦çš„两个常é‡ä¹‹ä¸€ï¼Œå¹¶ç›´æŽ¥å½±å“镜头失真效果。"
+msgstr ""
+"k1 é•œå¤´å› å­æ˜¯å®šä¹‰æ‰€ä½¿ç”¨é•œå¤´å¼ºåº¦çš„两个常é‡ä¹‹ä¸€ï¼Œå¹¶ç›´æŽ¥å½±å“镜头失真效果。"
#: modules/mobile_vr/doc_classes/MobileVRInterface.xml
msgid "The k2 lens factor, see k1."
-msgstr "k2镜头因å­ï¼Œè§k1。"
+msgstr "k2 镜头因å­ï¼Œè§ k1。"
#: modules/mobile_vr/doc_classes/MobileVRInterface.xml
msgid ""
@@ -43950,7 +44084,7 @@ msgstr "返回已ç»ä¸ºç‰¹å®šå®žä¾‹è®¾ç½®çš„自定义数æ®ã€‚"
#: doc/classes/MultiMesh.xml
msgid "Returns the [Transform] of a specific instance."
-msgstr "返回一个特定实例的[Transform]。"
+msgstr "返回一个特定实例的 [Transform]。"
#: doc/classes/MultiMesh.xml
msgid "Returns the [Transform2D] of a specific instance."
@@ -44025,8 +44159,8 @@ msgid ""
"just a container for 4 floating point numbers. The format of the number can "
"change depending on the [enum CustomDataFormat] used."
msgstr ""
-"为特定的实例设置自定义数æ®ã€‚虽然使用了[Color]ï¼Œä½†å®ƒåªæ˜¯ä¸€ä¸ªå®¹çº³4个浮点数的容"
-"器。数字的格å¼å¯ä»¥æ ¹æ®ä½¿ç”¨çš„[enum CustomDataFormat]æ¥æ”¹å˜ã€‚"
+"为特定的实例设置自定义数æ®ã€‚虽然使用了 [Color]ï¼Œä½†å®ƒåªæ˜¯ä¸€ä¸ªå®¹çº³ 4 个浮点数的"
+"容器。数字的格å¼å¯ä»¥æ ¹æ®ä½¿ç”¨çš„ [enum CustomDataFormat] æ¥æ”¹å˜ã€‚"
#: doc/classes/MultiMesh.xml
msgid "Sets the [Transform] for a specific instance."
@@ -44074,7 +44208,7 @@ msgstr ""
#: doc/classes/MultiMesh.xml
msgid "Format of transform used to transform mesh, either 2D or 3D."
-msgstr "ç”¨äºŽå˜æ¢ç½‘æ ¼çš„å˜æ¢æ ¼å¼ï¼Œå¯ä»¥æ˜¯2D或3D。"
+msgstr "ç”¨äºŽå˜æ¢ç½‘æ ¼çš„å˜æ¢æ ¼å¼ï¼Œå¯ä»¥æ˜¯ 2D 或 3D。"
#: doc/classes/MultiMesh.xml
msgid ""
@@ -44123,7 +44257,7 @@ msgid ""
"will be clamped."
msgstr ""
"传递给ç€è‰²å™¨æ—¶å°† custom_data 压缩为 8 ä½ã€‚这使用更少的内存并且å¯ä»¥æ›´å¿«ï¼Œä½†ä¼š"
-"失去精度和范围。 8 使µ®ç‚¹æ•°åªèƒ½è¡¨ç¤º 0 到 1 之间的值,超出该范围的数字将被é™"
+"失去精度和范围。8 使µ®ç‚¹æ•°åªèƒ½è¡¨ç¤º 0 到 1 之间的值,超出该范围的数字将被é™"
"制。"
#: doc/classes/MultiMesh.xml
@@ -44157,15 +44291,15 @@ msgid ""
"This is useful to optimize the rendering of a high amount of instances of a "
"given mesh (for example trees in a forest or grass strands)."
msgstr ""
-"[MultiMeshInstance]是特有的节点,用于基于[MultiMesh]资æºçš„[GeometryInstance]"
-"的实例。\n"
+"[MultiMeshInstance] 是特有的节点,用于基于 [MultiMesh] 资æºçš„ "
+"[GeometryInstance] 的实例。\n"
"这对于优化给定网格的大é‡å®žä¾‹çš„æ¸²æŸ“是éžå¸¸æœ‰ç”¨çš„(例如,森林中的树木或è‰ä¸›ï¼‰ã€‚"
#: doc/classes/MultiMeshInstance.xml
msgid ""
"The [MultiMesh] resource that will be used and shared among all instances of "
"the [MultiMeshInstance]."
-msgstr "在[MultiMeshInstance]的所有实例中使用和共享的[MultiMesh]资æºã€‚"
+msgstr "在 [MultiMeshInstance] 的所有实例中使用和共享的 [MultiMesh] 资æºã€‚"
#: doc/classes/MultiMeshInstance2D.xml
msgid "Node that instances a [MultiMesh] in 2D."
@@ -44177,16 +44311,16 @@ msgid ""
"resource in 2D.\n"
"Usage is the same as [MultiMeshInstance]."
msgstr ""
-"[MultiMeshInstance2D]是特有的节点,用于实例化2Dçš„[MultiMesh]资æºã€‚\n"
-"使用方法与[MultiMeshInstance]相åŒã€‚"
+"[MultiMeshInstance2D] 是特有的节点,用于实例化 2D çš„ [MultiMesh] 资æºã€‚\n"
+"使用方法与 [MultiMeshInstance] 相åŒã€‚"
#: doc/classes/MultiMeshInstance2D.xml
msgid "The [MultiMesh] that will be drawn by the [MultiMeshInstance2D]."
-msgstr "将由[MultiMeshInstance2D]绘制的[MultiMesh]。"
+msgstr "将由 [MultiMeshInstance2D] 绘制的 [MultiMesh]。"
#: doc/classes/MultiplayerAPI.xml
msgid "High-level multiplayer API."
-msgstr "高级多人游æˆAPI。"
+msgstr "é«˜çº§å¤šäººæ¸¸æˆ API。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
@@ -44201,40 +44335,42 @@ msgid ""
"detail and isn't meant to be used by non-Godot servers. It may change "
"without notice."
msgstr ""
-"该类实现了高阶多人游æˆAPI背åŽçš„大部分逻辑。å‚阅[NetworkedMultiplayerPeer]。\n"
-"默认情况下,[SceneTree]有对该类的引用,用于在整个场景中æä¾›å¤šäººæ¸¸æˆåŠŸèƒ½ï¼ˆå³"
+"è¯¥ç±»å®žçŽ°äº†é«˜é˜¶å¤šäººæ¸¸æˆ API 背åŽçš„大部分逻辑。å¦è¯·å‚阅 "
+"[NetworkedMultiplayerPeer]。\n"
+"默认情况下,[SceneTree] 有对该类的引用,用于在整个场景中æä¾›å¤šäººæ¸¸æˆåŠŸèƒ½ï¼ˆå³ "
"RPC/RSET)。\n"
-"通过设置[member Node.custom_multiplayer]属性,å¯ä»¥é‡å†™ç‰¹å®šèŠ‚ç‚¹ä½¿ç”¨çš„å¤šäººæ¸¸æˆ"
-"API实例,从而有效地å…许在åŒä¸€åœºæ™¯ä¸­åŒæ—¶è¿è¡Œå®¢æˆ·ç«¯å’ŒæœåŠ¡å™¨ã€‚\n"
-"[b]注æ„:[/b]高阶的多人游æˆAPIåè®®å®žçŽ°ç»†èŠ‚ï¼Œå¹¶ä¸æ„味ç€å¯ä»¥è¢«éžGodotæœåŠ¡å™¨ä½¿"
-"用。它å¯èƒ½ä¼šæ”¹å˜ï¼Œä¸åšå¦è¡Œé€šçŸ¥ã€‚"
+"通过设置 [member Node.custom_multiplayer] 属性,å¯ä»¥é‡å†™ç‰¹å®šèŠ‚ç‚¹ä½¿ç”¨çš„ "
+"MultiplayerAPI 实例,从而有效地å…许在åŒä¸€åœºæ™¯ä¸­åŒæ—¶è¿è¡Œå®¢æˆ·ç«¯å’ŒæœåŠ¡å™¨ã€‚\n"
+"[b]注æ„:[/b]é«˜é˜¶çš„å¤šäººæ¸¸æˆ API åè®®å®žçŽ°ç»†èŠ‚ï¼Œå¹¶ä¸æ„味ç€å¯ä»¥è¢«éž Godot æœåС噍"
+"使用。它å¯èƒ½ä¼šæ”¹å˜ï¼Œä¸åšå¦è¡Œé€šçŸ¥ã€‚"
#: doc/classes/MultiplayerAPI.xml
msgid ""
"Clears the current MultiplayerAPI network state (you shouldn't call this "
"unless you know what you are doing)."
msgstr ""
-"清除当å‰çš„MultiplayerAPI网络状æ€ï¼ˆé™¤éžä½ çŸ¥é“自己在åšä»€ä¹ˆï¼Œå¦åˆ™ä¸åº”该调用这"
+"清除当å‰çš„ MultiplayerAPI 网络状æ€ï¼ˆé™¤éžä½ çŸ¥é“自己在åšä»€ä¹ˆï¼Œå¦åˆ™ä¸åº”该调用这"
"个)。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
"Returns the peer IDs of all connected peers of this MultiplayerAPI's [member "
"network_peer]."
-msgstr "返回此MultiplayerAPI的[member network_peer]的所有连接的对等体的ID。"
+msgstr ""
+"返回这个 MultiplayerAPI 的 [member network_peer] 的所有连接的对等体的 ID。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
"Returns the unique peer ID of this MultiplayerAPI's [member network_peer]."
-msgstr "返回该多人游æˆAPIçš„[member network_peer]的唯一对等体ID。"
+msgstr "返回这个 MultiplayerAPI 的 [member network_peer] 的唯一对等体 ID。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
"Returns the sender's peer ID for the RPC currently being executed.\n"
"[b]Note:[/b] If not inside an RPC this method will return 0."
msgstr ""
-"è¿”å›žå½“å‰æ­£åœ¨æ‰§è¡Œçš„RPCçš„å‘逿–¹çš„对等体ID。\n"
-"[b]注æ„:[/b]如果ä¸åœ¨RPC内,这个方法将返回0。"
+"è¿”å›žå½“å‰æ­£åœ¨æ‰§è¡Œçš„ RPC çš„å‘逿–¹çš„对等体 ID。\n"
+"[b]注æ„:[/b]如果ä¸åœ¨ RPC 内,这个方法将返回 0。"
#: doc/classes/MultiplayerAPI.xml doc/classes/SceneTree.xml
msgid "Returns [code]true[/code] if there is a [member network_peer] set."
@@ -44245,8 +44381,8 @@ msgid ""
"Returns [code]true[/code] if this MultiplayerAPI's [member network_peer] is "
"in server mode (listening for connections)."
msgstr ""
-"如果这个MultiplayerAPIçš„[member network_peer]处于æœåŠ¡å™¨æ¨¡å¼ï¼ˆç›‘å¬è¿žæŽ¥ï¼‰ï¼Œè¿”"
-"回 [code]true[/code]。"
+"如果这个 MultiplayerAPI çš„ [member network_peer] 处于æœåŠ¡å™¨æ¨¡å¼ï¼ˆç›‘å¬è¿žæŽ¥ï¼‰ï¼Œ"
+"返回 [code]true[/code]。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
@@ -44258,9 +44394,10 @@ msgid ""
"will be executed in the same context of this function (e.g. [code]_process[/"
"code], [code]physics[/code], [Thread])."
msgstr ""
-"ç”¨äºŽè½®è¯¢å¤šäººæ¸¸æˆ API çš„æ–¹æ³•ã€‚åªæœ‰å½“你使用 [member Node.custom_multiplayer] 覆"
-"盖或者你将 [member SceneTree.multiplayer_poll] 设置为 [code]false[/code] 时,"
-"ä½ æ‰éœ€è¦æ‹…心这个问题。默认情况下,[SceneTree] å°†ä¸ºä½ è½®è¯¢å…¶å¤šäººæ¸¸æˆ API。\n"
+"用于轮询 MultiplayerAPI çš„æ–¹æ³•ã€‚åªæœ‰å½“你使用 [member Node."
+"custom_multiplayer] 覆盖或者你将 [member SceneTree.multiplayer_poll] 设置为 "
+"[code]false[/code] 时,你æ‰éœ€è¦æ‹…心这个问题。默认情况下,[SceneTree] 将为你轮"
+"询其 MultiplayerAPI。\n"
"[b]注æ„:[/b]这个方法导致 RPC å’Œ RSET 被调用,所以它们将在这个函数的åŒä¸€ä¸Šä¸‹"
"文中执行(例如 [code]_process[/code]ã€[code]physics[/code]ã€[Thread])。"
@@ -44284,8 +44421,8 @@ msgid ""
"to avoid potential security threats such as remote code execution."
msgstr ""
"如果为 [code]true[/code](或者如果 [member network_peer] 的 [member "
-"PacketPeer.allow_object_decoding] 被设置为 [code]true[/code]ï¼‰ï¼Œå¤šäººæ¸¸æˆ API "
-"å°†å…许在 RPC/RSET 期间的对象进行编ç å’Œè§£ç ã€‚\n"
+"PacketPeer.allow_object_decoding] 被设置为 [code]true[/code]),"
+"MultiplayerAPI å°†å…许在 RPC/RSET 期间的对象进行编ç å’Œè§£ç ã€‚\n"
"[b]警告:[/b]ååºåˆ—化的对象å¯èƒ½åŒ…å«ä¼šè¢«æ‰§è¡Œçš„代ç ã€‚如果åºåˆ—化的对象æ¥è‡ªä¸å—ä¿¡"
"ä»»çš„æ¥æºï¼Œè¯·ä¸è¦ä½¿ç”¨è¿™ä¸ªé€‰é¡¹ï¼Œä»¥é¿å…潜在的安全å¨èƒï¼Œå¦‚è¿œç¨‹ä»£ç æ‰§è¡Œã€‚"
@@ -44310,8 +44447,8 @@ msgid ""
"If [code]true[/code], the MultiplayerAPI's [member network_peer] refuses new "
"incoming connections."
msgstr ""
-"如果[code]true[/code],则MultiplayerAPIçš„[member network_peer]ä¼šæ‹’ç»æ–°çš„ä¼ å…¥"
-"连接。"
+"如果为 [code]true[/code],则MultiplayerAPIçš„[member network_peer]ä¼šæ‹’ç»æ–°çš„ä¼ "
+"入连接。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
@@ -44321,25 +44458,26 @@ msgid ""
"managed by different MultiplayerAPI, allowing for example to run both client "
"and server in the same scene."
msgstr ""
-"用于RPC的根节点。ä¸ä½¿ç”¨ç»å¯¹è·¯å¾„,而是使用相对路径æ¥å¯»æ‰¾åº”该执行RPC的节点。\n"
-"这有效地å…许场景树的ä¸åŒåˆ†æ”¯ç”±ä¸åŒçš„MultiplayerAPI管ç†ï¼Œä¾‹å¦‚å…许在åŒä¸€ä¸ªåœºæ™¯"
-"ä¸­åŒæ—¶è¿è¡Œå®¢æˆ·ç«¯å’ŒæœåŠ¡å™¨ã€‚"
+"用于 RPC 的根节点。ä¸ä½¿ç”¨ç»å¯¹è·¯å¾„,而是使用相对路径æ¥å¯»æ‰¾åº”该执行 RPC 的节"
+"点。\n"
+"这有效地å…许场景树的ä¸åŒåˆ†æ”¯ç”±ä¸åŒçš„ MultiplayerAPI 管ç†ï¼Œä¾‹å¦‚å…许在åŒä¸€ä¸ªåœº"
+"æ™¯ä¸­åŒæ—¶è¿è¡Œå®¢æˆ·ç«¯å’ŒæœåŠ¡å™¨ã€‚"
#: doc/classes/MultiplayerAPI.xml
msgid ""
"Emitted when this MultiplayerAPI's [member network_peer] successfully "
"connected to a server. Only emitted on clients."
msgstr ""
-"当这个MultiplayerAPIçš„[member network_peer]æˆåŠŸè¿žæŽ¥åˆ°ä¸€ä¸ªæœåŠ¡å™¨æ—¶è§¦å‘该信å·ã€‚"
-"è¿™åªåœ¨å®¢æˆ·ç«¯è§¦å‘。"
+"当这个 MultiplayerAPI çš„ [member network_peer] æˆåŠŸè¿žæŽ¥åˆ°ä¸€ä¸ªæœåŠ¡å™¨æ—¶è§¦å‘该信"
+"å·ã€‚è¿™åªåœ¨å®¢æˆ·ç«¯è§¦å‘。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
"Emitted when this MultiplayerAPI's [member network_peer] fails to establish "
"a connection to a server. Only emitted on clients."
msgstr ""
-"当这个MultiplayerAPIçš„[member network_peer]无法与æœåŠ¡å™¨å»ºç«‹è¿žæŽ¥æ—¶è§¦å‘。åªåœ¨å®¢"
-"户端触å‘。"
+"当这个 MultiplayerAPI çš„ [member network_peer] 无法与æœåŠ¡å™¨å»ºç«‹è¿žæŽ¥æ—¶è§¦å‘。åª"
+"在客户端触å‘。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
@@ -44348,9 +44486,9 @@ msgid ""
"clients connect to the same server. Upon connecting to a server, a client "
"also receives this signal for the server (with ID being 1)."
msgstr ""
-"当此多人播放器的 [member network_peer] 与新对等连接时触å‘该信å·ã€‚ID 是新peer"
-"çš„ peer ID。当其他客户端连接到åŒä¸€æœåŠ¡å™¨æ—¶ï¼Œå®¢æˆ·ç«¯ä¼šæ”¶åˆ°é€šçŸ¥ã€‚è¿žæŽ¥åˆ°æœåС噍"
-"åŽï¼Œå®¢æˆ·ç«¯è¿˜ä¼šæ”¶åˆ°æœåŠ¡å™¨çš„æ­¤ä¿¡å·ï¼ˆID 为 1)。"
+"当这个 MultiplayerAPI çš„ [member network_peer] 与新对等连接时触å‘该信å·ã€‚ID "
+"是新 peer çš„ peer ID。当其他客户端连接到åŒä¸€æœåŠ¡å™¨æ—¶ï¼Œå®¢æˆ·ç«¯ä¼šæ”¶åˆ°é€šçŸ¥ã€‚è¿žæŽ¥"
+"到æœåС噍åŽï¼Œå®¢æˆ·ç«¯è¿˜ä¼šæ”¶åˆ°æœåŠ¡å™¨çš„æ­¤ä¿¡å·ï¼ˆID 为 1)。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
@@ -44358,8 +44496,8 @@ msgid ""
"peer. Clients get notified when other clients disconnect from the same "
"server."
msgstr ""
-"当这个MultiplayerAPIçš„[member network_peer]与一个åŒä¼´æ–­å¼€è¿žæŽ¥æ—¶è§¦å‘该信å·ã€‚当"
-"其他客户端与åŒä¸€æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥æ—¶ï¼Œå®¢æˆ·ç«¯ä¼šå¾—åˆ°é€šçŸ¥ã€‚"
+"当这个 MultiplayerAPI çš„ [member network_peer] 与一个åŒä¼´æ–­å¼€è¿žæŽ¥æ—¶è§¦å‘该信"
+"å·ã€‚当其他客户端与åŒä¸€æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥æ—¶ï¼Œå®¢æˆ·ç«¯ä¼šå¾—åˆ°é€šçŸ¥ã€‚"
#: doc/classes/MultiplayerAPI.xml
msgid ""
@@ -44367,16 +44505,17 @@ msgid ""
"[code]packet[/code] with custom data (see [method send_bytes]). ID is the "
"peer ID of the peer that sent the packet."
msgstr ""
-"当这个MultiplayerAPIçš„[member network_peer]收到一个带有自定义数æ®çš„[code]æ•°æ®"
-"包[/code](è§[method send_bytes])时触å‘。ID是å‘é€è¯¥æ•°æ®åŒ…的对等体的ID。"
+"当这个 MultiplayerAPI çš„ [member network_peer] 收到一个带有自定义数æ®çš„æ•°æ®"
+"包 [code]packet[/code]ï¼ˆè§ [method send_bytes])时触å‘。ID 是å‘é€è¯¥æ•°æ®åŒ…的对"
+"等体的ID。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
"Emitted when this MultiplayerAPI's [member network_peer] disconnects from "
"server. Only emitted on clients."
msgstr ""
-"当这个MultiplayerAPIçš„[member network_peer]与æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥æ—¶è§¦å‘。åªåœ¨å®¢æˆ·ç«¯"
-"触å‘。"
+"当这个 MultiplayerAPI çš„ [member network_peer] 与æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥æ—¶è§¦å‘。åªåœ¨å®¢"
+"户端触å‘。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
@@ -44430,8 +44569,8 @@ msgid ""
"[i]Deprecated.[/i] Use [constant RPC_MODE_PUPPET] instead. Analogous to the "
"[code]slave[/code] keyword."
msgstr ""
-"[i]已废弃。[/i] 使用[constant RPC_MODE_PUPPET]代替。类似于[code]slave[/code]"
-"关键字。"
+"[i]已废弃。[/i]使用 [constant RPC_MODE_PUPPET] 代替。类似于 [code]slave[/"
+"code] 关键字。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
@@ -44446,15 +44585,15 @@ msgid ""
"[i]Deprecated.[/i] Use [constant RPC_MODE_REMOTESYNC] instead. Analogous to "
"the [code]sync[/code] keyword."
msgstr ""
-"[i]已废弃。[/i] 使用[constant RPC_MODE_REMOTESYNC]代替。类似于[code]sync[/"
-"code]关键字。"
+"[i]已废弃。[/i]使用 [constant RPC_MODE_REMOTESYNC] 代替。类似于 [code]sync[/"
+"code] 关键字。"
#: doc/classes/MultiplayerAPI.xml
msgid ""
"Behave like [constant RPC_MODE_MASTER] but also make the call or property "
"change locally. Analogous to the [code]mastersync[/code] keyword."
msgstr ""
-"类似于[constant RPC_MODE_MASTER]ï¼Œä½†ä¹Ÿä½¿æ–¹æ³•è°ƒç”¨æˆ–å±žæ€§æ”¹å˜æœ¬åœ°ã€‚类似于 "
+"类似于 [constant RPC_MODE_MASTER]ï¼Œä½†ä¹Ÿä½¿æ–¹æ³•è°ƒç”¨æˆ–å±žæ€§æ”¹å˜æœ¬åœ°ã€‚类似于 "
"[code]mastersync[/code] 关键字。"
#: doc/classes/MultiplayerAPI.xml
@@ -44467,7 +44606,7 @@ msgstr ""
#: doc/classes/Mutex.xml
msgid "A synchronization mutex (mutual exclusion)."
-msgstr "ä¸€ä¸ªåŒæ­¥äº’æ–¥é”(相互排斥)。"
+msgstr "åŒæ­¥äº’æ–¥é”(相互排斥)。"
#: doc/classes/Mutex.xml
msgid ""
@@ -44476,9 +44615,9 @@ msgid ""
"that only one thread can ever acquire the lock at a time. A mutex can be "
"used to protect a critical section; however, be careful to avoid deadlocks."
msgstr ""
-"ä¸€ä¸ªåŒæ­¥äº’æ–¥é”(mutexï¼‰ã€‚å®ƒç”¨äºŽåŒæ­¥å¤šä¸ª[Thread],相当于一个二进制"
-"[Semaphore]。它ä¿è¯æ¯æ¬¡åªæœ‰ä¸€ä¸ªçº¿ç¨‹å¯ä»¥èŽ·å¾—é”。互斥é”å¯ä»¥ç”¨æ¥ä¿æŠ¤ä¸´ç•ŒåŒºï¼›ä½†"
-"æ˜¯ï¼Œè¦æ³¨æ„é¿å…æ­»é”。"
+"åŒæ­¥äº’æ–¥é”ï¼ˆç›¸äº’æŽ’æ–¥ï¼‰ã€‚å®ƒç”¨äºŽåŒæ­¥å¤šä¸ª [Thread],相当于二元 [Semaphore]。它ä¿"
+"è¯æ¯æ¬¡åªæœ‰ä¸€ä¸ªçº¿ç¨‹å¯ä»¥èŽ·å¾—é”。互斥é”å¯ä»¥ç”¨æ¥ä¿æŠ¤ä¸´ç•ŒåŒºï¼›ä½†æ˜¯ï¼Œè¦æ³¨æ„é¿å…æ­»"
+"é”。"
#: doc/classes/Mutex.xml
msgid ""
@@ -44508,40 +44647,40 @@ msgid ""
"unlock] the same number of times in order to unlock it correctly."
msgstr ""
"è§£é”这个 [Mutex],把它留给其他线程。\n"
-"[b]注æ„:[/b]å¦‚æžœä¸€ä¸ªçº¿ç¨‹åœ¨å·²ç»æ‹¥æœ‰äº’æ–¥é”的情况下多次调用[method lock]或"
-"[method try_lock]ï¼Œå®ƒä¹Ÿå¿…é¡»è°ƒç”¨ç›¸åŒæ¬¡æ•°çš„[method unlock]æ‰èƒ½æ­£ç¡®è§£é”."
+"[b]注æ„:[/b]å¦‚æžœä¸€ä¸ªçº¿ç¨‹åœ¨å·²ç»æ‹¥æœ‰äº’æ–¥é”的情况下多次调用 [method lock] 或 "
+"[method try_lock]ï¼Œå®ƒä¹Ÿå¿…é¡»è°ƒç”¨ç›¸åŒæ¬¡æ•°çš„ [method unlock] æ‰èƒ½æ­£ç¡®è§£é”."
#: modules/gdnative/doc_classes/NativeScript.xml
msgid ""
"Returns the documentation string that was previously set with "
"[code]godot_nativescript_set_class_documentation[/code]."
msgstr ""
-"返回之å‰ç”¨[code]godot_nativescript_set_class_documentation[/code]设置的文档字"
-"符串。"
+"返回之å‰ç”¨ [code]godot_nativescript_set_class_documentation[/code] 设置的文档"
+"字符串。"
#: modules/gdnative/doc_classes/NativeScript.xml
msgid ""
"Returns the documentation string that was previously set with "
"[code]godot_nativescript_set_method_documentation[/code]."
msgstr ""
-"返回之å‰ç”¨[code]godot_nativescript_set_method_documentation[/code]设置的文档"
-"字符串。"
+"返回之å‰ç”¨ [code]godot_nativescript_set_method_documentation[/code] 设置的文"
+"档字符串。"
#: modules/gdnative/doc_classes/NativeScript.xml
msgid ""
"Returns the documentation string that was previously set with "
"[code]godot_nativescript_set_property_documentation[/code]."
msgstr ""
-"返回之å‰ç”¨[code]godot_nativescript_set_property_documentation[/code]设置的文"
-"档字符串。"
+"返回之å‰ç”¨ [code]godot_nativescript_set_property_documentation[/code] 设置的"
+"文档字符串。"
#: modules/gdnative/doc_classes/NativeScript.xml
msgid ""
"Returns the documentation string that was previously set with "
"[code]godot_nativescript_set_signal_documentation[/code]."
msgstr ""
-"返回之å‰ç”¨[code]godot_nativescript_set_signal_documentation[/code]设置的文档"
-"字符串。"
+"返回之å‰ç”¨ [code]godot_nativescript_set_signal_documentation[/code] 设置的文"
+"档字符串。"
#: modules/gdnative/doc_classes/NativeScript.xml
msgid ""
@@ -44561,12 +44700,17 @@ msgstr "基于网格的导航和寻路节点。"
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
"class also assists with aligning navigation agents with the meshes they are "
"navigating on."
msgstr ""
+"[i]已弃用。[/i][Navigation] 节点和 [method get_simple_path] 已弃用,会在将æ¥"
+"的版本中移除。请用 [method NavigationServer.map_get_path] 替代。\n"
"在 [NavigationMesh] 的集åˆä¸­æä¾›å¯¼èˆªå’Œå¯»è·¯åŠŸèƒ½ã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œè¿™äº›å°†è‡ªåŠ¨ä»Žå­ "
"[NavigationMeshInstance] 节点中收集。除了基本的寻路之外,这个类还能帮助导航代"
"ç†ä¸Žå…¶æ‰€å¯¼èˆªçš„网格对é½ã€‚"
@@ -44615,11 +44759,16 @@ msgstr "返回这个导航地图在 [NavigationServer] 上的 [RID]。"
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
"etc.) are considered in the path calculation, otherwise they are ignored."
msgstr ""
+"[i]已弃用。[/i][Navigation] 节点和 [method get_simple_path] 已弃用,会在将æ¥"
+"的版本中移除。请用 [method NavigationServer.map_get_path] 替代。\n"
"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹éƒ½æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸­çš„。如果 [code]optimize[/"
"code] 为 [code]true[/code](默认),则计算路径时会考虑æ¯ä¸ª [NavigationMesh] "
"所关è”的代ç†çš„属性(åŠå¾„ã€é«˜åº¦ç­‰ï¼‰ï¼Œå¦åˆ™ä¼šè¢«å¿½ç•¥ã€‚"
@@ -44650,7 +44799,7 @@ msgid ""
"Defines which direction is up. By default, this is [code](0, 1, 0)[/code], "
"which is the world's \"up\" direction."
msgstr ""
-"定义了å‘上的方å‘。默认情况下,这是[code](0,1,0)[/code],这是世界的“å‘ä¸Šâ€æ–¹"
+"定义了å‘上的方å‘。默认情况下,这是 [code](0,1,0)[/code],这是世界的“å‘ä¸Šâ€æ–¹"
"å‘。"
#: doc/classes/Navigation.xml doc/classes/Navigation2DServer.xml
@@ -44665,10 +44814,15 @@ msgstr "2D 导航和寻路节点。"
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
msgstr ""
+"[i]已弃用。[/i][Navigation2D] 节点和 [method get_simple_path] 已弃用,会在将"
+"æ¥çš„版本中移除。请用 [method Navigation2DServer.map_get_path] 替代。\n"
"Navigation2D 在 2D 区域内æä¾›å¯¼èˆªå’Œå¯»è·¯ï¼Œè¯¥åŒºåŸŸä»¥ [NavigationPolygon] 资æºåˆ"
"é›†çš„å½¢å¼æŒ‡å®šã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œè¿™äº›èµ„æºæ˜¯è‡ªåŠ¨ä»Žå­é¡¹ [NavigationPolygonInstance] 节"
"点中收集的。"
@@ -44689,10 +44843,15 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
msgstr ""
+"[i]已弃用。[/i][Navigation2D] 节点和 [method get_simple_path] 已弃用,会在将"
+"æ¥çš„版本中移除。请用 [method Navigation2DServer.map_get_path] 替代。\n"
"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸­çš„。如果 [code]optimize[/code] "
"为 [code]true[/code](默认值),路径将尽å¯èƒ½åœ°åˆå¹¶è·¯å¾„段,从而平滑。"
@@ -44854,11 +45013,64 @@ msgid "Destroys the given RID."
msgstr "销æ¯ç»™å®šçš„ RID。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+"返回该 NavigationServer 上所有已创建的导航地图的 [RID]ã€‚ä¼šåŒæ—¶è¿”回已创建的 "
+"2D å’Œ 3D 导航地图,因为ç†è®ºä¸Šå®ƒä»¬ä¹‹é—´æ˜¯æ²¡æœ‰åŒºåˆ«çš„。"
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr "创建一张新地图。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+"这个函数会立å³å¼ºåˆ¶è¿›è¡ŒæŒ‡å®šå¯¼èˆªåœ°å›¾çš„åŒæ­¥ï¼Œå‚æ•° [code]map[/code] 为 [RID] ç±»"
+"型。默认情况下,导航地图仅会在æ¯ä¸ªç‰©ç†å¸§çš„æœ«å°¾è¿›è¡ŒåŒæ­¥ã€‚这个函数å¯ç”¨äºŽç«‹å³"
+"ï¼ˆé‡æ–°ï¼‰è®¡ç®—该导航地图的所有导航网格和地区连接。这样就能够在修改地图åŽï¼Œåœ¨åŒ"
+"一帧中立å³å¯¹å¯¼èˆªè·¯å¾„è¿›è¡ŒæŸ¥è¯¢ï¼ˆéœ€è¦æ—¶å¯ä»¥è¿›è¡Œå¤šæ¬¡åŒæ­¥ï¼‰ã€‚\n"
+"由于技术上的é™åˆ¶ï¼Œå½“å‰çš„ NavigationServer 命令队列会被清空。这æ„å‘³ç€æ‰€æœ‰å·²åœ¨"
+"当å‰ç‰©ç†å¸§ä¸­å…¥é˜Ÿçš„命令都会被执行,å³ä¾¿è¿™äº›å‘½ä»¤ä¸ŽæŒ‡å®šçš„地图无关,针对的是其他"
+"地图ã€åœ°åŒºã€ä»£ç†ã€‚消耗较大的导航网格以åŠåœ°åŒºè¿žæŽ¥çš„计算åªä¼šå¯¹æŒ‡å®šçš„地图进行。"
+"其他地图会在该物ç†å¸§çš„æœ«å°¾è¿›è¡Œå¸¸è§„çš„åŒæ­¥ã€‚如果指定的地图在进行强制更新åŽåˆæ”¶"
+"到了修改,那么它也会在其他地图更新时å—到更新。\n"
+"这个函数ä¸ä¼šè§¦åŠé¿éšœå¤„ç†ä»¥åŠ [code]safe_velocity[/code] ä¿¡å·çš„分å‘,这些还是"
+"会在该物ç†å¸§çš„æœ«å°¾é’ˆå¯¹æ‰€æœ‰åœ°å›¾çš„代ç†è¿›è¡Œå¤„ç†ã€‚\n"
+"[b]注æ„:[/b]èƒ½åŠ›è¶Šå¤§ï¼Œè´£ä»»è¶Šå¤§ã€‚åªæœ‰çœŸæ­£æ˜Žç™½è‡ªå·±åœ¨å¹²ä»€ä¹ˆçš„用户æ‰åº”该在真正有"
+"éœ€è¦æ—¶ä½¿ç”¨è¿™ä¸ªå‡½æ•°ã€‚å¼ºåˆ¶è¿›è¡Œå¯¼èˆªåœ°å›¾çš„ç«‹å³æ›´æ–°éœ€è¦å¯¹ NavigationServer 加é”å¹¶"
+"清空整个 NavigationServer 的命令队列。这样åšä¸ä»…ä¼šå¤§å¹…å½±å“æ¸¸æˆçš„æ€§èƒ½ï¼Œå¦‚果使"
+"用ä¸å½“ã€ç¼ºä¹è¿œè§ï¼Œè¿˜å¯èƒ½å¼•å…¥ bug。"
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr "返回所有与请求的导航地图 [code]map[/code] å…³è”的导航代ç†çš„ [RID]。"
@@ -44974,6 +45186,32 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "返回 [code]region[/code] 地区的移动消耗 [code]travel_cost[/code]。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+"å¦‚æžœç»™å‡ºçš„ä¸–ç•Œç©ºé—´åæ ‡ç‚¹ [code]point[/code] ç›®å‰ç”±ç»™å‡ºçš„导航地区 "
+"[code]region[/code] 拥有,则返回 [code]true[/code]ã€‚è¿™é‡Œçš„â€œæ‹¥æœ‰â€æŒ‡çš„æ˜¯è¯¥åœ°åŒº"
+"的导航网格多边形é¢ä¸­åŒ…å«è¿™ä¸ªå¯èƒ½çš„ä½ç½®ï¼Œå¹¶ä¸”与给出的地区的导航地区上所有其他"
+"导航地区的导航网格相比,它与这个点的è·ç¦»æ˜¯æœ€è¿‘的。\n"
+"如果有多个导航网格包å«è¿™ä¸ªç‚¹å¹¶ä¸”è·ç¦»ç›¸ç­‰ï¼Œå“ªä¸ªå¯¼èˆªåœ°åŒºçš„多边形先被处ç†ï¼Œé‚£ä¸ª"
+"å¯¼èˆªåœ°åŒºå°±èŽ·å–æ‰€æœ‰æƒã€‚多边形的处ç†é¡ºåºä¸Žå¯¼èˆªåœ°åŒºåœ¨ NavigationServer 上的注册"
+"顺åºä¸€è‡´ã€‚\n"
+"[b]注æ„:[/b]如果ä¸åŒå¯¼èˆªåœ°åŒºçš„导航网格存在é‡å ï¼ˆé€šå¸¸åº”当é¿å…),å¯èƒ½å¾—到预料"
+"之外的结果。"
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "设置 [code]region[/code] 地区的进入消耗 [code]enter_cost[/code]。"
@@ -45230,6 +45468,21 @@ msgstr "æœç´¢å…¶ä»–代ç†çš„è·ç¦»ã€‚"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+"è·ç¦»é˜ˆå€¼ï¼Œç”¨äºŽç¡®å®šæ˜¯å¦å·²åˆ°è¾¾æŸä¸ªè·¯å¾„点。使用这个值,代ç†å°±ä¸å¿…精确地到达æŸä¸ª"
+"路径点,到达æŸä¸ªåŒºåŸŸå†…å³å¯ã€‚如果这个值设得太大,该 NavigationAgent 将跳过路径"
+"上的点,å¯èƒ½å¯¼è‡´å…¶ç¦»å¼€è¯¥å¯¼èˆªç½‘格。如果这个值设得太å°ï¼Œè¯¥ NavigationAgent 将陷"
+"入釿–°å¯»è·¯çš„æ­»å¾ªçŽ¯ï¼Œå› ä¸ºå®ƒåœ¨æ¯æ¬¡ç‰©ç†å¸§æ›´æ–°åŽéƒ½ä¼šè¶…过或者到ä¸äº†ä¸‹ä¸€ä¸ªç‚¹ã€‚"
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
@@ -45237,18 +45490,33 @@ msgstr ""
"å…许代ç†åç¦»ç†æƒ³è·¯å¾„的最大è·ç¦»ã€‚å¯èƒ½ä¸ºäº†é˜²æ’žè€Œäº§ç”Ÿå离。超出最大è·ç¦»æ—¶ï¼Œä¼šé‡"
"æ–°è®¡ç®—ç†æƒ³è·¯å¾„。"
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
-msgstr "代ç†çš„åŠå¾„。"
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
+msgstr ""
+"该é¿éšœä»£ç†çš„åŠå¾„。这是该é¿éšœä»£ç†çš„“身体â€ï¼Œä¸æ˜¯é¿éšœæœºåˆ¶çš„èµ·å§‹åŠå¾„(由 [member "
+"neighbor_dist] 控制)。\n"
+"ä¸ä¼šå½±å“正常的寻路。è¦ä¿®æ”¹è§’色的寻路åŠå¾„,请在烘焙 [NavigationMesh] èµ„æºæ—¶ä½¿"
+"用ä¸åŒçš„ [member NavigationMesh.agent_radius] 属性,针对ä¸åŒçš„角色大å°ä½¿ç”¨ä¸"
+"åŒçš„导航地图。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
-"认为到达目标的è·ç¦»é˜ˆå€¼ã€‚å¯ä»¥è®©ä»£ç†æ— éœ€ç²¾å‡†åˆ°è¾¾è·¯å¾„上的æŸä¸ªç‚¹ï¼Œåˆ°è¾¾æŸä¸ªåŒºåŸŸå³"
-"å¯ã€‚"
+"è·ç¦»é˜ˆå€¼ï¼Œç”¨äºŽç¡®å®šæ˜¯å¦å·²åˆ°è¾¾æœ€ç»ˆçš„目标点。使用这个值,代ç†å°±ä¸å¿…精确地到达最"
+"终的目标,到达该区域内å³å¯ã€‚如果这个值设得太å°ï¼Œè¯¥ NavigationAgent 将陷入釿–°"
+"å¯»è·¯çš„æ­»å¾ªçŽ¯ï¼Œå› ä¸ºå®ƒåœ¨æ¯æ¬¡ç‰©ç†å¸§æ›´æ–°åŽéƒ½ä¼šè¶…过或者到ä¸äº†æœ€ç»ˆçš„目标点。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
@@ -45363,6 +45631,17 @@ msgstr ""
"ä½åŸŸï¼Œç”¨äºŽå†³å®šè¯¥ [NavigationAgent2D] 所属的导航地图层。请求路径时,代ç†ä¼šå¿½ç•¥"
"没有任何匹é…层的导航网格。"
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+"该é¿éšœä»£ç†çš„åŠå¾„。这是该é¿éšœä»£ç†çš„“身体â€ï¼Œä¸æ˜¯é¿éšœæœºåˆ¶çš„èµ·å§‹åŠå¾„(由 [member "
+"neighbor_dist] 控制)。\n"
+"ä¸ä¼šå½±å“正常的寻路。"
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr "ç”¨äºŽæ¨¡æ‹Ÿå¯æ­¥è¡ŒåŒºåŸŸå’Œéšœç¢ç‰©çš„网格。"
@@ -45469,7 +45748,7 @@ msgstr ""
#: doc/classes/NavigationMesh.xml
msgid "The Y axis cell size to use for fields."
-msgstr "用于字段Yè½´å•元的尺寸。"
+msgstr "用于字段 Y è½´å•元的尺寸。"
#: doc/classes/NavigationMesh.xml
msgid ""
@@ -45498,6 +45777,16 @@ msgstr ""
"[b]注æ„:[/b]烘焙时,这个值会å‘ä¸Šå–æ•´åˆ°æœ€æŽ¥è¿‘çš„[member cell_size]çš„å€æ•°ã€‚"
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr "如果烘焙 [AABB] 存在体积,对该导航网格的烘焙会被é™åˆ¶åœ¨å…¶å†…部区域中。"
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr "应用于 [member filter_baking_aabb] [AABB] çš„ä½ç½®åç§»é‡ã€‚"
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr "如果为 [code]true[/code],则标记边缘间的跨度为ä¸å¯è¡Œèµ°ã€‚"
@@ -45532,13 +45821,14 @@ msgstr ""
msgid ""
"Determines which type of nodes will be parsed as geometry. See [enum "
"ParsedGeometryType] for possible values."
-msgstr "决定哪ç§ç±»åž‹çš„节点å¯è§£æžä¸ºå‡ ä½•图形。å‚阅 [enum ParsedGeometryType]。"
+msgstr ""
+"决定哪ç§ç±»åž‹çš„节点å¯è§£æžä¸ºå‡ ä½•图形。å¯èƒ½çš„å–å€¼è§ [enum ParsedGeometryType]。"
#: doc/classes/NavigationMesh.xml
msgid ""
"The source of the geometry used when baking. See [enum SourceGeometryMode] "
"for possible values."
-msgstr "烘焙时使用的几何体的æºã€‚å‚阅 [enum SourceGeometryMode]。"
+msgstr "烘焙时使用的几何体的æºã€‚å¯èƒ½çš„å–å€¼è§ [enum SourceGeometryMode]。"
#: doc/classes/NavigationMesh.xml
msgid ""
@@ -45576,15 +45866,16 @@ msgid ""
"cells allowed to form isolated island areas. For example, a value of 8 will "
"set the number of cells to 64."
msgstr ""
-"一个区域被创建的最å°å°ºå¯¸ã€‚\n"
-"[b]注æ„:[/b]该值将被平方,以计算出å…许形æˆå­¤å²›åŒºåŸŸçš„æœ€å°å•元数。例如,8的值"
-"将把å•元格的数é‡è®¾ä¸º64。"
+"区域被创建所需的最å°å°ºå¯¸ã€‚\n"
+"[b]注æ„:[/b]该值将被平方,以计算出å…许形æˆå­¤å²›åŒºåŸŸçš„æœ€å°å•元数。例如,值为 "
+"8 时将把å•元格的数é‡è®¾ä¸º 64。"
#: doc/classes/NavigationMesh.xml
msgid ""
"Partitioning algorithm for creating the navigation mesh polys. See [enum "
"SamplePartitionType] for possible values."
-msgstr "创建导航网格多边形å•元的分割算法。å‚阅 [enum SamplePartitionType]。"
+msgstr ""
+"创建导航网格多边形å•元的分割算法。å¯èƒ½çš„å–å€¼è§ [enum SamplePartitionType]。"
#: doc/classes/NavigationMesh.xml
msgid ""
@@ -45603,7 +45894,7 @@ msgstr "å•调分区。如果您想è¦å¿«é€Ÿç”Ÿæˆå¯¼èˆªç½‘格,请使用此选
msgid ""
"Layer partitioning. Good choice to use for tiled navigation mesh with medium "
"and small sized tiles."
-msgstr "层分区。用于具有中å°åž‹ç“·ç –的平铺导航网格的ä¸é”™é€‰æ‹©ã€‚"
+msgstr "层分区。用于具有中å°åž‹å›¾å—的平铺导航网格的ä¸é”™é€‰æ‹©ã€‚"
#: doc/classes/NavigationMesh.xml
msgid "Represents the size of the [enum SamplePartitionType] enum."
@@ -45696,7 +45987,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
"这个类负责 3D 导航网格的创建和清ç†ï¼Œå¯¼èˆªç½‘æ ¼ [NavigationMesh] 是 "
"[NavigationMeshInstance] 中的资æºã€‚[NavigationMeshGenerator] 在 2D 中的用处微"
@@ -45717,7 +46016,11 @@ msgstr ""
"è±¡ï¼Œé€šè¿‡åœ¨ç½‘æ ¼çš„åŒ…å›´åŒºåŸŸå‘¨è¾¹åˆ›å»ºä½“ç´ ä¸–ç•Œï¼Œæ¥æ£€æŸ¥åŽŸå§‹å‡ ä½•ä½“ä¸­é€‚åˆ "
"[NavigationMesh] 代ç†è¡Œèµ°çš„地形。\n"
"ç„¶åŽå°±ä¼šè¿”回最终的导航网格,ä¿å­˜åœ¨ [NavigationMesh] 中,å³å¯äº¤ä»˜ "
-"[NavigationMeshInstance] 使用。"
+"[NavigationMeshInstance] 使用。\n"
+"[b]注æ„:[/b]使用网格æ¥å®šä¹‰å¯è¡Œèµ°åŒºåŸŸå¹¶é®æŒ¡å¯¼èˆªçƒ˜ç„™å¹¶ä¸æ€»èƒ½æˆåŠŸã€‚çƒ˜ç„™å¯¼èˆªå¤„ç†"
+"网格原始几何体时,并没有几何体“ä½äºŽå†…部â€çš„æ¦‚念,这是有æ„而为之的。根æ®å½“å‰çƒ˜"
+"ç„™å‚æ•°çš„ä¸åŒï¼Œåªè¦é®æŒ¡ç½‘格足够大,大到能够将导航网格区域包å«åœ¨å…¶å†…部,烘焙时"
+"就会生æˆä¸€ä¸ªå¯¼èˆªç½‘格区域,ä½äºŽé®æŒ¡çš„原始几何体网格内部。"
#: doc/classes/NavigationMeshGenerator.xml
msgid ""
@@ -45811,7 +46114,6 @@ msgstr "决定该 [NavigationMeshInstance] å·²å¯ç”¨è¿˜æ˜¯å·²ç¦ç”¨ã€‚"
#: doc/classes/NavigationMeshInstance.xml
#: doc/classes/NavigationPolygonInstance.xml
-#, fuzzy
msgid ""
"When pathfinding enters this region's navmesh from another regions navmesh "
"the [code]enter_cost[/code] value is added to the path distance for "
@@ -45837,7 +46139,6 @@ msgstr "使用的 [NavigationMesh] 资æºã€‚"
#: doc/classes/NavigationMeshInstance.xml
#: doc/classes/NavigationPolygonInstance.xml
-#, fuzzy
msgid ""
"When pathfinding moves inside this region's navmesh the traveled distances "
"are multiplied with [code]travel_cost[/code] for determining the shortest "
@@ -46000,8 +46301,8 @@ msgid ""
"make_polygons_from_outlines] in order for this array to be converted to "
"polygons that the engine will use."
msgstr ""
-"将包å«è½®å»“顶点的[PoolVector2Array]æ·»åŠ åˆ°åŒ…å«æ‰€æœ‰è½®å»“的内部数组中。你必须调用"
-"[method make_polygons_from_outlines],将数组转æ¢ä¸ºå¼•擎å¯ä½¿ç”¨çš„多边形。"
+"将包å«è½®å»“顶点的 [PoolVector2Array] æ·»åŠ åˆ°åŒ…å«æ‰€æœ‰è½®å»“的内部数组中。你必须调"
+"用 [method make_polygons_from_outlines],将数组转æ¢ä¸ºå¼•擎å¯ä½¿ç”¨çš„多边形。"
#: doc/classes/NavigationPolygon.xml
msgid ""
@@ -46010,9 +46311,9 @@ msgid ""
"to call [method make_polygons_from_outlines] in order for this array to be "
"converted to polygons that the engine will use."
msgstr ""
-"将包å«è½®å»“顶点的[PoolVector2Array]æ·»åŠ åˆ°å†…éƒ¨æ•°ç»„ä¸­ï¼Œè¯¥æ•°ç»„åŒ…å«æ‰€æœ‰å›ºå®šä½ç½®çš„"
-"轮廓。你必须调用[method make_polygons_from_outlines],将数组转æ¢ä¸ºå¼•擎å¯ä½¿ç”¨"
-"的多边形。"
+"将包å«è½®å»“顶点的 [PoolVector2Array] æ·»åŠ åˆ°å†…éƒ¨æ•°ç»„ä¸­ï¼Œè¯¥æ•°ç»„åŒ…å«æ‰€æœ‰å›ºå®šä½ç½®"
+"的轮廓。你必须调用 [method make_polygons_from_outlines],将数组转æ¢ä¸ºå¼•擎å¯ä½¿"
+"用的多边形。"
#: doc/classes/NavigationPolygon.xml
msgid ""
@@ -46056,7 +46357,7 @@ msgstr "返回多边形的数é‡ã€‚"
msgid ""
"Returns a [PoolVector2Array] containing all the vertices being used to "
"create the polygons."
-msgstr "返回包å«ç”¨äºŽåˆ›å»ºå¤šè¾¹å½¢çš„æ‰€æœ‰é¡¶ç‚¹çš„[PoolVector2Array]。"
+msgstr "返回包å«ç”¨äºŽåˆ›å»ºå¤šè¾¹å½¢çš„æ‰€æœ‰é¡¶ç‚¹çš„ [PoolVector2Array]。"
#: doc/classes/NavigationPolygon.xml
msgid "Creates polygons from the outlines added in the editor or by script."
@@ -46269,13 +46570,13 @@ msgid ""
"the server port in UDP. You can use the [UPNP] class to try to forward the "
"server port automatically when starting the server."
msgstr ""
-"一个 PacketPeer 实现,应该在åˆå§‹åŒ–为客户端或æœåС噍åŽä¼ é€’ç»™ [member SceneTree."
+"PacketPeer 的实现,应该在åˆå§‹åŒ–为客户端或æœåС噍åŽä¼ é€’ç»™ [member SceneTree."
"network_peer]。然åŽå¯ä»¥é€šè¿‡è¿žæŽ¥åˆ° [SceneTree] ä¿¡å·æ¥å¤„ç†äº‹ä»¶ã€‚\n"
"ENet 的目的是在 UDPï¼ˆç”¨æˆ·æ•°æ®æŠ¥å议)之上æä¾›ä¸€ä¸ªç›¸å¯¹ç®€å•而å¥å…¨çš„网络通信"
"层。\n"
-"[b]注æ„:[/b]ENet åªä½¿ç”¨UDP,ä¸ä½¿ç”¨TCPã€‚è½¬å‘æœåŠ¡å™¨ç«¯å£ä½¿æ‚¨çš„æœåŠ¡å™¨å¯ä»¥åœ¨å…¬ç½‘"
-"上访问时,åªéœ€è¦å°†æœåŠ¡å™¨ç«¯å£è½¬å‘为UDPå³å¯ã€‚您å¯ä»¥ä½¿ç”¨ [UPNP] ç±»å°è¯•在å¯åЍæœåŠ¡"
-"å™¨æ—¶è‡ªåŠ¨è½¬å‘æœåŠ¡å™¨ç«¯å£ã€‚"
+"[b]注æ„:[/b]ENet åªä½¿ç”¨ UDP,ä¸ä½¿ç”¨ TCPã€‚è½¬å‘æœåŠ¡å™¨ç«¯å£ä½¿æ‚¨çš„æœåŠ¡å™¨å¯ä»¥åœ¨å…¬"
+"网上访问时,åªéœ€è¦å°†æœåŠ¡å™¨ç«¯å£è½¬å‘为 UDP å³å¯ã€‚您å¯ä»¥ä½¿ç”¨ [UPNP] ç±»å°è¯•在å¯åЍ"
+"æœåŠ¡å™¨æ—¶è‡ªåŠ¨è½¬å‘æœåŠ¡å™¨ç«¯å£ã€‚"
#: modules/enet/doc_classes/NetworkedMultiplayerENet.xml
msgid ""
@@ -46355,25 +46656,25 @@ msgid ""
"Disconnect the given peer. If \"now\" is set to [code]true[/code], the "
"connection will be closed immediately without flushing queued messages."
msgstr ""
-"断开给定对等体的连接。如果 \"now \"被设置为 [code]true[/code],连接将被立å³å…³"
-"闭而ä¸å†²åˆ·é˜Ÿåˆ—中的消æ¯ã€‚"
+"断开给定对等体的连接。如果“nowâ€è¢«è®¾ç½®ä¸º [code]true[/code],连接将被立å³å…³é—­è€Œ"
+"ä¸å†²åˆ·é˜Ÿåˆ—中的消æ¯ã€‚"
#: modules/enet/doc_classes/NetworkedMultiplayerENet.xml
msgid ""
"Returns the channel of the last packet fetched via [method PacketPeer."
"get_packet]."
-msgstr "返回通过[method PacketPeer.get_packet]获å–的最åŽä¸€ä¸ªåŒ…çš„Channel。"
+msgstr "返回通过 [method PacketPeer.get_packet] 获å–的上一个数æ®åŒ…çš„ Channel。"
#: modules/enet/doc_classes/NetworkedMultiplayerENet.xml
msgid ""
"Returns the channel of the next packet that will be retrieved via [method "
"PacketPeer.get_packet]."
-msgstr "返回将通过[method PacketPeer.get_packet]获å–的下一个数æ®åŒ…çš„Channel。"
+msgstr "返回通过 [method PacketPeer.get_packet] 获å–的下一个数æ®åŒ…çš„ Channel。"
#: modules/enet/doc_classes/NetworkedMultiplayerENet.xml
#: modules/websocket/doc_classes/WebSocketServer.xml
msgid "Returns the IP address of the given peer."
-msgstr "返回给定对等体的IP地å€ã€‚"
+msgstr "返回给定对等体的 IP 地å€ã€‚"
#: modules/enet/doc_classes/NetworkedMultiplayerENet.xml
#: modules/websocket/doc_classes/WebSocketServer.xml
@@ -46396,8 +46697,8 @@ msgid ""
"code]. For servers, you must also setup the [CryptoKey] via [method "
"set_dtls_key]."
msgstr ""
-"当[member use_dtls]为 [code]true[/code] 时,é…ç½®[X509Certificate]使用。对于æœ"
-"务器,您还必须通过[method set_dtls_key]设置[CryptoKey]。"
+"当 [member use_dtls] 为 [code]true[/code] 时,é…ç½® [X509Certificate] 使用。对"
+"于æœåŠ¡å™¨ï¼Œæ‚¨è¿˜å¿…é¡»é€šè¿‡ [method set_dtls_key] 设置 [CryptoKey]。"
#: modules/enet/doc_classes/NetworkedMultiplayerENet.xml
msgid ""
@@ -46405,8 +46706,8 @@ msgid ""
"code]. Remember to also call [method set_dtls_certificate] to setup your "
"[X509Certificate]."
msgstr ""
-"当[member use_dtls]为 [code]true[/code] 时,é…ç½®[CryptoKey]æ¥ä½¿ç”¨ã€‚è®°ä½ä¹Ÿè¦è°ƒ"
-"用[method set_dtls_certificate]æ¥è®¾ç½®[X509Certificate]。"
+"当 [member use_dtls] 为 [code]true[/code] 时,é…ç½® [CryptoKey] æ¥ä½¿ç”¨ã€‚è®°ä½ä¹Ÿ"
+"è¦è°ƒç”¨ [method set_dtls_certificate] æ¥è®¾ç½® [X509Certificate]。"
#: modules/enet/doc_classes/NetworkedMultiplayerENet.xml
msgid ""
@@ -46449,7 +46750,7 @@ msgid ""
"status of a packet in one channel won't stall the delivery of other packets "
"in another channel."
msgstr ""
-"ENetè¦ä½¿ç”¨çš„ä¿¡é“æ•°é‡ã€‚通é“用于分离ä¸åŒç±»åž‹çš„æ•°æ®ã€‚例如,在å¯é æˆ–æœ‰åºæ¨¡å¼ä¸‹ï¼Œ"
+"ENet è¦ä½¿ç”¨çš„ä¿¡é“æ•°é‡ã€‚通é“用于分离ä¸åŒç±»åž‹çš„æ•°æ®ã€‚例如,在å¯é æˆ–æœ‰åºæ¨¡å¼ä¸‹ï¼Œ"
"åŒ…äº¤ä»˜é¡ºåºæ˜¯åœ¨æ¯ä¸ªé€šé“的基础上ä¿è¯çš„ã€‚è¿™æ ·åšæ˜¯ä¸ºäº†æ¶ˆé™¤å»¶è¿Ÿå¹¶å‡å°‘对数æ®åŒ…的排"
"åºé™åˆ¶ã€‚在一个通é“中的包的交付状æ€ä¸ä¼šåœæ­¢åœ¨å¦ä¸€ä¸ªé€šé“中的其他包的交付。"
@@ -46470,8 +46771,8 @@ msgid ""
msgstr ""
"用于网络数æ®åŒ…的压缩方法。这些在压缩速度与带宽之间有ä¸åŒçš„æƒè¡¡ï¼Œå¦‚æžœæ‚¨å®Œå…¨ä½¿"
"用压缩,您å¯èƒ½éœ€è¦æµ‹è¯•å“ªä¸€ç§æœ€é€‚åˆæ‚¨çš„用例。\n"
-"[b]注:[/b]大多数游æˆçš„网络设计都涉åŠé¢‘ç¹å‘é€è®¸å¤šå°æ•°æ®åŒ…(æ¯ä¸ªå°äºŽ4 KB)。如"
-"果有疑问,建议ä¿ç•™é»˜è®¤åŽ‹ç¼©ç®—æ³•ï¼Œå› ä¸ºå®ƒå¯¹è¿™äº›å°æ•°æ®åŒ…效果最好。\n"
+"[b]注æ„:[/b]大多数游æˆçš„网络设计都涉åŠé¢‘ç¹å‘é€è®¸å¤šå°æ•°æ®åŒ…(æ¯ä¸ªå°äºŽ 4 "
+"KB)。如果有疑问,建议ä¿ç•™é»˜è®¤åŽ‹ç¼©ç®—æ³•ï¼Œå› ä¸ºå®ƒå¯¹è¿™äº›å°æ•°æ®åŒ…效果最好。\n"
"[b]注æ„:[/b][member compression_mode] 必须在æœåС噍åŠå…¶æ‰€æœ‰å®¢æˆ·ç«¯ä¸Šè®¾ç½®ä¸ºç›¸åŒ"
"的值。如果客户端上设置的 [member compression_mode] 与æœåŠ¡å™¨ä¸Šè®¾ç½®çš„ä¸åŒï¼Œåˆ™å®¢"
"户端将无法连接。在 Godot 3.4 之å‰ï¼Œé»˜è®¤çš„ [member compression_mode] 是 "
@@ -46611,7 +46912,7 @@ msgstr "WebRTC ä¿¡å·æ¼”示"
#: doc/classes/NetworkedMultiplayerPeer.xml
msgid ""
"Returns the current state of the connection. See [enum ConnectionStatus]."
-msgstr "返回连接的当å‰çжæ€ã€‚请å‚阅 [enum ConnectionStatus]。"
+msgstr "返回连接的当å‰çжæ€ã€‚è§ [enum ConnectionStatus]。"
#: doc/classes/NetworkedMultiplayerPeer.xml
msgid ""
@@ -46653,7 +46954,7 @@ msgstr ""
msgid ""
"The manner in which to send packets to the [code]target_peer[/code]. See "
"[enum TransferMode]."
-msgstr "å‘[code]target_peer[/code]å‘逿•°æ®åŒ…的方å¼ã€‚å‚阅[enum TransferMode]。"
+msgstr "å‘ [code]target_peer[/code] å‘逿•°æ®åŒ…的方å¼ã€‚è§ [enum TransferMode]。"
#: doc/classes/NetworkedMultiplayerPeer.xml
msgid "Emitted when a connection attempt fails."
@@ -46718,7 +47019,7 @@ msgstr "正在进行的连接断开了。"
#: doc/classes/NetworkedMultiplayerPeer.xml
msgid "A connection attempt is ongoing."
-msgstr "一个连接å°è¯•正在进行中。"
+msgstr "正在å°è¯•进行连接。"
#: doc/classes/NetworkedMultiplayerPeer.xml
msgid "The connection attempt succeeded."
@@ -46747,43 +47048,45 @@ msgid ""
"grid. When you scale the node, it tiles the texture's sides horizontally or "
"vertically, the center on both axes but it doesn't scale or tile the corners."
msgstr ""
-"NinePatchRect也被称为9片å¼é¢æ¿ï¼Œå®ƒåŸºäºŽä¸€ä¸ªå°çš„纹ç†ï¼Œäº§ç”Ÿä»»ä½•å°ºå¯¸çš„å¹²å‡€é¢æ¿ã€‚"
-"为了åšåˆ°è¿™ä¸€ç‚¹ï¼Œå®ƒå°†çº¹ç†åˆ†å‰²æˆ3×3的网格。当你缩放节点时,它在水平或垂直方å‘上"
-"平铺纹ç†çš„两侧,在两个轴上平铺中心,但它ä¸ä¼šç¼©æ”¾æˆ–平铺角部。"
+"NinePatchRect 也被称为 9 片å¼é¢æ¿ï¼Œå®ƒåŸºäºŽä¸€ä¸ªå°çš„纹ç†ï¼Œäº§ç”Ÿä»»ä½•尺寸的干净é¢"
+"æ¿ã€‚为了åšåˆ°è¿™ä¸€ç‚¹ï¼Œå®ƒå°†çº¹ç†åˆ†å‰²æˆ 3×3 的网格。当你缩放节点时,它在水平或垂直"
+"æ–¹å‘上平铺纹ç†çš„两侧,在两个轴上平铺中心,但它ä¸ä¼šç¼©æ”¾æˆ–平铺角部。"
#: doc/classes/NinePatchRect.xml
msgid ""
"Returns the size of the margin identified by the given [enum Margin] "
"constant."
-msgstr "返回由给定的[enum Margin]叏釿 ‡è¯†çš„è¾¹è·å¤§å°ã€‚"
+msgstr "返回由给定的 [enum Margin] 叏釿 ‡è¯†çš„è¾¹è·å¤§å°ã€‚"
#: doc/classes/NinePatchRect.xml
msgid ""
"Sets the size of the margin identified by the given [enum Margin] constant "
"to [code]value[/code] in pixels."
msgstr ""
-"将由给定的[enum Margin]叏釿 ‡è¯†çš„è¾¹è·å¤§å°è®¾ç½®ä¸º[code]value[/code],å•ä½ä¸ºåƒ"
-"素。"
+"将由给定的 [enum Margin] 叏釿 ‡è¯†çš„è¾¹è·å¤§å°è®¾ç½®ä¸º [code]value[/code],å•ä½ä¸º"
+"åƒç´ ã€‚"
#: doc/classes/NinePatchRect.xml
msgid ""
"The stretch mode to use for horizontal stretching/tiling. See [enum "
"NinePatchRect.AxisStretchMode] for possible values."
msgstr ""
-"水平拉伸/平铺时使用的拉伸模å¼ã€‚å‚阅[enum NinePatchRect.AxisStretchMode]。"
+"水平拉伸/平铺时使用的拉伸模å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum NinePatchRect."
+"AxisStretchMode]。"
#: doc/classes/NinePatchRect.xml
msgid ""
"The stretch mode to use for vertical stretching/tiling. See [enum "
"NinePatchRect.AxisStretchMode] for possible values."
msgstr ""
-"用于垂直拉伸/平铺的拉伸模å¼ã€‚å‚阅[enum NinePatchRect.AxisStretchMode]。"
+"用于垂直拉伸/平铺的拉伸模å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum NinePatchRect."
+"AxisStretchMode]。"
#: doc/classes/NinePatchRect.xml
msgid ""
"If [code]true[/code], draw the panel's center. Else, only draw the 9-slice's "
"borders."
-msgstr "如果[code]true[/code]ï¼Œåˆ™ç»˜åˆ¶é¢æ¿çš„中心。å¦åˆ™ï¼Œåªç”»9-slice的边框。"
+msgstr "如果为 [code]true[/code]ï¼Œåˆ™ç»˜åˆ¶é¢æ¿çš„中心。å¦åˆ™ï¼Œåªç”»9-slice的边框。"
#: doc/classes/NinePatchRect.xml
msgid ""
@@ -46791,8 +47094,8 @@ msgid ""
"bottom corners and side will have a height of 16 pixels. You can set all 4 "
"margin values individually to create panels with non-uniform borders."
msgstr ""
-"9-slice的底层行的高度。边è·ä¸º16æ„味ç€9片的底角和侧é¢å°†æœ‰16åƒç´ çš„高度。你å¯ä»¥"
-"å•独设置所有4个边è·å€¼æ¥åˆ›å»ºå…·æœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
+"9-切片底行的高度。边è·ä¸º 16 æ„å‘³ç€ 9-切片的底角和侧é¢å°†æœ‰ 16 åƒç´ çš„高度。你å¯"
+"以å•独设置所有 4 个边è·å€¼ï¼Œæ¥åˆ›å»ºæœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
#: doc/classes/NinePatchRect.xml
msgid ""
@@ -46800,8 +47103,8 @@ msgid ""
"left corners and side will have a width of 16 pixels. You can set all 4 "
"margin values individually to create panels with non-uniform borders."
msgstr ""
-"9-切片的左列宽度。边è·ä¸º16æ„味ç€9切片的左角和侧é¢å°†æœ‰16åƒç´ çš„宽度。你å¯ä»¥å•独"
-"设置所有4个边è·å€¼ï¼Œæ¥åˆ›å»ºæœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
+"9-切片左列的宽度。边è·ä¸º 16 æ„å‘³ç€ 9-切片的左角和侧é¢å°†æœ‰ 16 åƒç´ çš„宽度。你å¯"
+"以å•独设置所有 4 个边è·å€¼ï¼Œæ¥åˆ›å»ºæœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
#: doc/classes/NinePatchRect.xml
msgid ""
@@ -46809,8 +47112,8 @@ msgid ""
"right corners and side will have a width of 16 pixels. You can set all 4 "
"margin values individually to create panels with non-uniform borders."
msgstr ""
-"9-切片的å³åˆ—宽度。边è·ä¸º16æ„味ç€9切片的å³è§’和侧é¢å°†æœ‰16åƒç´ çš„宽度。你å¯ä»¥å•独"
-"设置所有4个边è·å€¼ï¼Œä»¥åˆ›å»ºæœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
+"9-切片å³åˆ—的宽度。边è·ä¸º 16 æ„å‘³ç€ 9-切片的å³è§’和侧é¢å°†æœ‰ 16 åƒç´ çš„宽度。你å¯"
+"以å•独设置所有 4 个边è·å€¼ï¼Œæ¥åˆ›å»ºæœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
#: doc/classes/NinePatchRect.xml
msgid ""
@@ -46818,8 +47121,8 @@ msgid ""
"corners and side will have a height of 16 pixels. You can set all 4 margin "
"values individually to create panels with non-uniform borders."
msgstr ""
-"9切片的顶行的高度。边è·ä¸º16æ„味ç€9切片的顶角和侧é¢å°†æœ‰16åƒç´ çš„高度。你å¯ä»¥å•"
-"独设置所有4个边è·å€¼ï¼Œæ¥åˆ›å»ºæœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
+"9-切片顶行的高度。边è·ä¸º 16 æ„å‘³ç€ 9-切片的顶角和侧é¢å°†æœ‰ 16 åƒç´ çš„高度。你å¯"
+"以å•独设置所有 4 个边è·å€¼ï¼Œæ¥åˆ›å»ºæœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
#: doc/classes/NinePatchRect.xml
msgid ""
@@ -46828,9 +47131,9 @@ msgid ""
"other properties are relative to this one. If the rect is empty, "
"NinePatchRect will use the whole texture."
msgstr ""
-"è¦å–样的纹ç†çš„矩形区域。如果你正在使用一个图集,使用这个属性æ¥å®šä¹‰9-slice应该"
-"使用的区域。所有其他属性都是相对于这个属性而言的。如果矩形为空,NinePatchRect"
-"将使用整个纹ç†ã€‚"
+"è¦å–样的纹ç†çš„矩形区域。如果你正在使用一个图集,使用这个属性æ¥å®šä¹‰ 9-切片应该"
+"使用的区域。所有其他属性都是相对于这个属性而言的。如果矩形为空,"
+"NinePatchRect 将使用整个纹ç†ã€‚"
#: doc/classes/NinePatchRect.xml
msgid "The node's texture resource."
@@ -46844,7 +47147,7 @@ msgstr "当节点的纹ç†å‘生å˜åŒ–时触å‘。"
msgid ""
"Stretches the center texture across the NinePatchRect. This may cause the "
"texture to be distorted."
-msgstr "å°†ä¸­é—´çº¹ç†æ‹‰ä¼¸åˆ°9切片矩形。这å¯èƒ½ä¼šå¯¼è‡´çº¹ç†å¤±çœŸã€‚"
+msgstr "在 NinePatchRect 上拉伸中心纹ç†ã€‚è¿™å¯èƒ½ä¼šå¯¼è‡´çº¹ç†å¤±çœŸã€‚"
#: doc/classes/NinePatchRect.xml
msgid ""
@@ -46856,7 +47159,7 @@ msgid ""
msgstr ""
"在 NinePatchRect 上é‡å¤ä¸­å¿ƒçº¹ç†ã€‚è¿™ä¸ä¼šå¯¼è‡´ä»»ä½•å¯è§çš„失真。纹ç†å¿…须是无ç¼çš„,"
"这样æ‰èƒ½åœ¨è¾¹ç¼˜ä¹‹é—´ä¸æ˜¾ç¤ºä¼ªå½±çš„æƒ…况下工作。\n"
-"[b]注:[/b] 仅在使用 GLES3 渲染器时支æŒã€‚使用 GLES2 渲染器时,这将类似于 "
+"[b]注æ„:[/b]仅在使用 GLES3 渲染器时支æŒã€‚使用 GLES2 渲染器时,这将类似于 "
"[constant AXIS_STRETCH_MODE_STRETCH]。"
#: doc/classes/NinePatchRect.xml
@@ -46872,7 +47175,7 @@ msgstr ""
"在 NinePatchRect 上é‡å¤ä¸­å¿ƒçº¹ç†ï¼Œä½†ä¹Ÿä¼šæ‹‰ä¼¸çº¹ç†ä»¥ç¡®ä¿æ¯ä¸ªå›¾å—都完整å¯è§ã€‚è¿™å¯"
"èƒ½ä¼šå¯¼è‡´çº¹ç†æ‰­æ›²ï¼Œä½†å°äºŽ [constant AXIS_STRETCH_MODE_STRETCH]。纹ç†å¿…须是无ç¼"
"的,这样æ‰èƒ½åœ¨è¾¹ç¼˜ä¹‹é—´ä¸æ˜¾ç¤ºä¼ªå½±çš„æƒ…况下工作。\n"
-"[b]注:[/b] 仅在使用 GLES3 渲染器时支æŒã€‚使用 GLES2 渲染器时,这将类似于 "
+"[b]注æ„:[/b]仅在使用 GLES3 渲染器时支æŒã€‚使用 GLES2 渲染器时,这将类似于 "
"[constant AXIS_STRETCH_MODE_STRETCH]。"
#: doc/classes/Node.xml
@@ -46944,8 +47247,8 @@ msgstr ""
"节点的直接å­èŠ‚ç‚¹ï¼‰çš„å字唯一。\n"
"节点树被称为[i]场景[/i]。场景å¯ä»¥è¢«ä¿å­˜åˆ°ç£ç›˜ä¸Šï¼Œç„¶åŽè¢«å®žä¾‹åŒ–到其他场景中。这"
"使得 Godot é¡¹ç›®çš„æž¶æž„å’Œæ•°æ®æ¨¡åž‹å…·æœ‰éžå¸¸é«˜çš„çµæ´»æ€§ã€‚\n"
-"[b]场景树:[/b] [SceneTree] åŒ…å«æ´»åŠ¨çš„èŠ‚ç‚¹æ ‘ã€‚å½“ä¸€ä¸ªèŠ‚ç‚¹è¢«æ·»åŠ åˆ°åœºæ™¯æ ‘ä¸­æ—¶ï¼Œ"
-"它将收到 [constant NOTIFICATION_ENTER_TREE] 通知,并触å‘å…¶ [method "
+"[b]场景树:[/b][SceneTree] åŒ…å«æ´»åŠ¨çš„èŠ‚ç‚¹æ ‘ã€‚å½“ä¸€ä¸ªèŠ‚ç‚¹è¢«æ·»åŠ åˆ°åœºæ™¯æ ‘ä¸­æ—¶ï¼Œå®ƒ"
+"将收到 [constant NOTIFICATION_ENTER_TREE] 通知,并触å‘å…¶ [method "
"_enter_tree] 回调。å­èŠ‚ç‚¹æ€»æ˜¯åœ¨å…¶çˆ¶èŠ‚ç‚¹[i]之åŽ[/i]被添加,å³çˆ¶èŠ‚ç‚¹çš„ [method "
"_enter_tree] 回调将在其å­èŠ‚ç‚¹çš„ä¹‹å‰è¢«è§¦å‘。\n"
"一旦所有的节点被添加到场景树中,它们就会收到 [constant NOTIFICATION_READY] 通"
@@ -46954,8 +47257,8 @@ msgstr ""
"è¿™æ„味ç€ï¼Œå½“把一个节点添加到场景树中时,将使用下é¢çš„顺åºè¿›è¡Œå›žè°ƒï¼šçˆ¶èŠ‚ç‚¹çš„ "
"[method _enter_tree]ã€å­èŠ‚ç‚¹çš„ [method _enter_tree]ã€å­èŠ‚ç‚¹çš„ [method "
"_ready]ï¼Œæœ€åŽæ˜¯çˆ¶èŠ‚ç‚¹çš„ [method _ready](对整个场景树进行递归)。\n"
-"[b]处ç†ï¼š[/b] 节点å¯ä»¥è¦†ç›–“处ç†â€çжæ€ï¼Œä»¥ä¾¿å®ƒä»¬åœ¨æ¯ä¸€å¸§ä¸Šéƒ½æ”¶åˆ°å›žè°ƒï¼Œè¦æ±‚它们"
-"进行处ç†ï¼ˆåšä¸€äº›äº‹æƒ…)。普通处ç†ï¼ˆå›žè°ƒ [method _process],å¯ä»¥ä½¿ç”¨ [method "
+"[b]处ç†ï¼š[/b]节点å¯ä»¥è¦†ç›–“处ç†â€çжæ€ï¼Œä»¥ä¾¿å®ƒä»¬åœ¨æ¯ä¸€å¸§ä¸Šéƒ½æ”¶åˆ°å›žè°ƒï¼Œè¦æ±‚它们进"
+"行处ç†ï¼ˆåšä¸€äº›äº‹æƒ…)。普通处ç†ï¼ˆå›žè°ƒ [method _process],å¯ä»¥ä½¿ç”¨ [method "
"set_process] 开关)会尽å¯èƒ½å¿«åœ°å‘生,并且å–å†³äºŽå¸§çŽ‡ï¼Œæ‰€ä»¥å¤„ç†æ—¶é—´ [i]delta[/"
"i](å•ä½ä¸ºç§’ï¼‰ä¼šä½œä¸ºå‚æ•°ä¼ å…¥ã€‚物ç†å¤„ç†ï¼ˆå›žè°ƒ [method _physics_process],å¯ä»¥"
"使用 [method set_physics_process] 开关)æ¯ç§’å‘生固定次数(默认为 60),对物ç†"
@@ -46970,11 +47273,11 @@ msgstr ""
"工具时éžå¸¸æœ‰ç”¨ã€‚\n"
"最åŽï¼Œå½“一个节点被 [method Object.free] 或 [method queue_free] 释放时,它也将"
"释放它的所有å­èŠ‚ç‚¹ã€‚\n"
-"[b]分组:[/b] 节点å¯ä»¥è¢«æ·»åŠ åˆ°å¾ˆå¤šçš„ç»„ä¸­ï¼Œä»¥æ–¹ä¾¿ç®¡ç†ï¼Œä½ å¯ä»¥æ ¹æ®è‡ªå·±æ¸¸æˆçš„需"
-"è¦æ¥åˆ›å»ºç±»ä¼¼â€œæ•Œäººâ€æˆ–“收集å“â€è¿™æ ·çš„组。å‚阅 [method add_to_group]ã€[method "
+"[b]分组:[/b]节点å¯ä»¥è¢«æ·»åŠ åˆ°å¾ˆå¤šçš„ç»„ä¸­ï¼Œä»¥æ–¹ä¾¿ç®¡ç†ï¼Œä½ å¯ä»¥æ ¹æ®è‡ªå·±æ¸¸æˆçš„需è¦"
+"æ¥åˆ›å»ºç±»ä¼¼â€œæ•Œäººâ€æˆ–“收集å“â€è¿™æ ·çš„组。å‚阅 [method add_to_group]ã€[method "
"is_in_group] å’Œ [method remove_from_group]。加入组åŽï¼Œä½ å¯ä»¥æ£€ç´¢è¿™äº›ç»„中的所"
"有节点,对它们进行迭代,甚至通过 [SceneTree] 中的方法调用组内方法。\n"
-"[b]节点的网络编程:[/b] 在连接到æœåŠ¡å™¨ï¼ˆæˆ–åˆ¶ä½œæœåŠ¡å™¨ï¼Œå‚阅 "
+"[b]节点的网络编程:[/b]在连接到æœåŠ¡å™¨ï¼ˆæˆ–åˆ¶ä½œæœåŠ¡å™¨ï¼Œå‚阅 "
"[NetworkedMultiplayerENet])之åŽï¼Œå¯ä»¥ä½¿ç”¨å†…置的 RPC(远程过程调用)系统在网"
"络上进行通信。在调用 [method rpc] 时传入方法å,将在本地和所有已连接的对等体"
"中调用对应的方法(对等体=客户端和接å—连接的æœåŠ¡å™¨ï¼‰ã€‚ä¸ºäº†è¯†åˆ«å“ªä¸ªèŠ‚ç‚¹æ”¶åˆ° "
@@ -46998,11 +47301,11 @@ msgid ""
"Corresponds to the [constant NOTIFICATION_ENTER_TREE] notification in "
"[method Object._notification]."
msgstr ""
-"当节点进入[SceneTree]时调用(ä¾‹å¦‚å®žä¾‹åŒ–æ—¶ï¼Œåœºæ™¯æ”¹å˜æ—¶ï¼Œæˆ–者在脚本中调用"
-"[method add_child]åŽ)。如果节点有å­èŠ‚ç‚¹ï¼Œåˆ™é¦–å…ˆè°ƒç”¨å®ƒçš„[method _enter_tree]回"
-"调函数,然åŽå†è°ƒç”¨å­èŠ‚ç‚¹çš„å›žè°ƒå‡½æ•°ã€‚\n"
-"对应于[method Object._notification]中的[constant NOTIFICATION_ENTER_TREE]通"
-"知。"
+"当节点进入 [SceneTree] æ—¶è°ƒç”¨ï¼ˆä¾‹å¦‚å®žä¾‹åŒ–æ—¶ï¼Œåœºæ™¯æ”¹å˜æ—¶ï¼Œæˆ–者在脚本中调用 "
+"[method add_child] åŽï¼‰ã€‚如果节点有å­èŠ‚ç‚¹ï¼Œåˆ™é¦–å…ˆè°ƒç”¨å®ƒçš„ [method "
+"_enter_tree] 回调函数,然åŽå†è°ƒç”¨å­èŠ‚ç‚¹çš„å›žè°ƒå‡½æ•°ã€‚\n"
+"对应于 [method Object._notification] 中的 [constant NOTIFICATION_ENTER_TREE] "
+"通知。"
#: doc/classes/Node.xml
msgid ""
@@ -47015,12 +47318,12 @@ msgid ""
"the node has already left the active tree, connect to the [signal "
"tree_exited]."
msgstr ""
-"当节点å³å°†ç¦»å¼€[SceneTree]时被调用(例如,在释放ã€åœºæ™¯æ”¹å˜æˆ–在脚本中调用"
-"[method remove_child]åŽï¼‰ã€‚如果该节点有å­èŠ‚ç‚¹ï¼Œå®ƒçš„[method _exit_tree]回调将"
-"在所有å­èŠ‚ç‚¹ç¦»å¼€æ ‘åŽè¢«æœ€åŽè°ƒç”¨ã€‚\n"
+"当节点å³å°†ç¦»å¼€ [SceneTree] 时被调用(例如,在释放ã€åœºæ™¯æ”¹å˜æˆ–在脚本中调用 "
+"[method remove_child] åŽï¼‰ã€‚如果该节点有å­èŠ‚ç‚¹ï¼Œå®ƒçš„ [method _exit_tree] 回调"
+"将在所有å­èŠ‚ç‚¹ç¦»å¼€æ ‘åŽè¢«æœ€åŽè°ƒç”¨ã€‚\n"
"对应于 [method Object._notification] 中的 [constant NOTIFICATION_EXIT_TREE] "
"通知和 [signal tree_exiting] ä¿¡å·ã€‚è¦åœ¨èŠ‚ç‚¹å·²ç»ç¦»å¼€æ´»åŠ¨æ ‘æ—¶å¾—åˆ°é€šçŸ¥ï¼Œè¯·è¿žæŽ¥"
-"到 [signal tree_exited] 。"
+"到 [signal tree_exited]。"
#: doc/classes/Node.xml
msgid ""
@@ -47030,10 +47333,10 @@ msgid ""
"Call [method update_configuration_warning] when the warning needs to be "
"updated for this node."
msgstr ""
-"如果覆盖该方法的脚本是一个[code]tool[/code]脚本,那么从该方法返回的字符串将在"
-"Scene Dock中显示为一个警告。\n"
+"如果覆盖该方法的脚本是一个 [code]tool[/code] 脚本,那么从该方法返回的字符串将"
+"åœ¨åœºæ™¯é¢æ¿ä¸­æ˜¾ç¤ºä¸ºä¸€ä¸ªè­¦å‘Šã€‚\n"
"返回一个空字符串ä¸ä¼šäº§ç”Ÿè­¦å‘Šã€‚\n"
-"å½“éœ€è¦æ›´æ–°è¿™ä¸ªèŠ‚ç‚¹çš„è­¦å‘Šæ—¶ï¼Œè°ƒç”¨[method update_configuration_warning]。"
+"å½“éœ€è¦æ›´æ–°è¿™ä¸ªèŠ‚ç‚¹çš„è­¦å‘Šæ—¶ï¼Œè°ƒç”¨ [method update_configuration_warning]。"
#: doc/classes/Node.xml
msgid ""
@@ -47272,7 +47575,7 @@ msgid ""
"scene tree is not paused, and [code]false[/code] if the node is not in the "
"tree."
msgstr ""
-"如果节点å¯ä»¥åœ¨åœºæ™¯æ ‘æš‚åœæ—¶è¿›è¡Œå¤„ç†ï¼Œè¿”回 [code]true[/code](è§[member "
+"如果节点å¯ä»¥åœ¨åœºæ™¯æ ‘æš‚åœæ—¶è¿›è¡Œå¤„ç†ï¼Œè¿”回 [code]true[/code]ï¼ˆè§ [member "
"pause_mode])。如果场景树没有暂åœï¼Œæ€»æ˜¯è¿”回 [code]true[/code],如果节点ä¸åœ¨æ ‘"
"中,则返回 [code]false[/code]。"
@@ -47345,13 +47648,13 @@ msgid ""
"[method get_node] instead. To avoid using [method find_parent] too often, "
"consider caching the node reference into a variable."
msgstr ""
-"查找当å‰èŠ‚ç‚¹çš„ç¬¬ä¸€ä¸ªçˆ¶èŠ‚ç‚¹ï¼Œå…¶å称与[method String.match]中的[code]mask[/"
-"code]相匹é…,区分大å°å†™ï¼Œå…¶[code]\"*\"[/code]匹é…零或多个字符,[code]\"?\"[/"
-"code]匹é…任何å•个字符,除了[code]\".\"[/code]。\n"
+"查找当å‰èŠ‚ç‚¹çš„ç¬¬ä¸€ä¸ªçˆ¶èŠ‚ç‚¹ï¼Œå…¶å称与 [method String.match] 中的 [code]mask[/"
+"code] 相匹é…,区分大å°å†™ï¼Œå…¶ [code]\"*\"[/code] 匹é…零或多个字符,[code]\"?"
+"\"[/code] 匹é…任何å•个字符,除了 [code]\".\"[/code]。\n"
"[b]注æ„:[/b]å®ƒä¸æ˜¯å…¨è·¯å¾„匹é…,åªä¸Žå•个节点å称匹é…。\n"
"[b]注æ„:[/b]由于这个方法在场景树中å‘ä¸Šè¡Œèµ°ï¼Œåœ¨å¤§åž‹çš„ã€æ·±åº¦åµŒå¥—的场景树中å¯èƒ½"
-"会很慢。åªè¦æœ‰å¯èƒ½ï¼Œè¯·è€ƒè™‘使用[method get_node]代替。为了é¿å…过于频ç¹åœ°ä½¿ç”¨"
-"[method find_parent],考虑将节点引用缓存到一个å˜é‡ä¸­ã€‚"
+"会很慢。åªè¦æœ‰å¯èƒ½ï¼Œè¯·è€ƒè™‘使用 [method get_node] 代替。为了é¿å…过于频ç¹åœ°ä½¿"
+"用 [method find_parent],考虑将节点引用缓存到一个å˜é‡ä¸­ã€‚"
#: doc/classes/Node.xml
msgid ""
@@ -47412,7 +47715,7 @@ msgstr "返回节点的索引,å³å®ƒåœ¨å…¶çˆ¶èŠ‚ç‚¹çš„å…„å¼ŸèŠ‚ç‚¹ä¸­çš„ä½ç½®
msgid ""
"Returns the peer ID of the network master for this node. See [method "
"set_network_master]."
-msgstr "返回此节点的网络主节点的对等 ID。请å‚阅 [method set_network_master]。"
+msgstr "返回此节点的网络主节点的对等 IDã€‚è§ [method set_network_master]。"
#: doc/classes/Node.xml
msgid ""
@@ -47488,13 +47791,15 @@ msgid ""
"[[CollisionShape2D:1161], [RectangleShape2D:1156], :extents]\n"
"[/codeblock]"
msgstr ""
-"获å–一个节点åŠå…¶ç”±[NodePath]å­å称指定的资æº(例如[code]Area2D/"
-"CollisionShape2D:shape[/code])。如果在[NodePath]中指定了多个嵌套资æºï¼Œåˆ™å°†èŽ·"
-"å–æœ€åŽä¸€ä¸ªã€‚\n"
-"返回值是一个大å°ä¸º3的数组:第一个索引指å‘[Node](或[code]null[/code]),第二个索"
-"引指å‘[Resource](或[code]null[/code]),第三个索引是剩余的[NodePath]。\n"
-"例如,å‡è®¾[code]Area2D/CollisionShape2D[/code]是一个有效的节点,并且它的"
-"[code]shape[/code]属性被分é…了一个[RectangleShape2D]资æºï¼Œå¯ä»¥æœ‰è¿™æ ·çš„输出:\n"
+"获å–一个节点åŠå…¶ç”± [NodePath] å­å称指定的资æºï¼ˆä¾‹å¦‚[code]Area2D/"
+"CollisionShape2D:shape[/code])。如果在 [NodePath] 中指定了多个嵌套资æºï¼Œåˆ™å°†"
+"èŽ·å–æœ€åŽä¸€ä¸ªã€‚\n"
+"返回值是一个大å°ä¸º 3 的数组:ç¬¬ä¸€ä¸ªç´¢å¼•æŒ‡å‘ [Node](或 [code]null[/code]),第"
+"äºŒä¸ªç´¢å¼•æŒ‡å‘ [Resource](或 [code]null[/code]),第三个索引是剩余的 "
+"[NodePath]。\n"
+"例如,å‡è®¾ [code]Area2D/CollisionShape2D[/code] 是一个有效的节点,并且它的 "
+"[code]shape[/code] 属性被分é…了一个 [RectangleShape2D] 资æºï¼Œå¯ä»¥æœ‰è¿™æ ·çš„输"
+"出:\n"
"[codeblock]\n"
"print(get_node_and_resource(\"Area2D/CollisionShape2D\")) # "
"[[CollisionShape2D:1161], Null, ]\n"
@@ -47531,8 +47836,8 @@ msgid ""
"Returns the relative [NodePath] from this node to the specified [code]node[/"
"code]. Both nodes must be in the same scene or the function will fail."
msgstr ""
-"从这个节点返回到指定的[code]node[/code]的相对[NodePath]。两个节点必须在åŒä¸€ä¸ª"
-"场景中,å¦åˆ™å‡½æ•°å°†å¤±è´¥ã€‚"
+"从这个节点返回到指定的 [code]node[/code] 的相对 [NodePath]。两个节点必须在åŒ"
+"一个场景中,å¦åˆ™å‡½æ•°å°†å¤±è´¥ã€‚"
#: doc/classes/Node.xml
msgid ""
@@ -47541,17 +47846,17 @@ msgid ""
"processing unless the frames per second is changed via [member Engine."
"iterations_per_second]."
msgstr ""
-"返回自上次物ç†ç»‘å®šå¸§ä»¥æ¥æ‰€ç»è¿‡çš„秒数(请å‚阅 [method _physics_process])。在"
-"物ç†å¤„ç†ä¸­ï¼Œé™¤éžé€šè¿‡ [member Engine.iterations_per_second] æ¥æ”¹å˜æ¯ç§’的帧数,"
-"å¦åˆ™å§‹ç»ˆä¸ºå¸¸é‡ã€‚"
+"返回自上次物ç†ç»‘å®šå¸§ä»¥æ¥æ‰€ç»è¿‡çš„ç§’æ•°ï¼ˆè§ [method _physics_process])。在物ç†"
+"处ç†ä¸­ï¼Œé™¤éžé€šè¿‡ [member Engine.iterations_per_second] æ¥æ”¹å˜æ¯ç§’的帧数,å¦åˆ™"
+"始终为常é‡ã€‚"
#: doc/classes/Node.xml
msgid ""
"Returns the node's order in the scene tree branch. For example, if called on "
"the first child node the position is [code]0[/code]."
msgstr ""
-"返回场景树分支中节点的顺åºã€‚例如,如果在第一个å­èŠ‚ç‚¹ä¸Šè°ƒç”¨ï¼Œåˆ™ä½ç½®ä¸º[code]0[/"
-"code]。"
+"返回场景树分支中节点的顺åºã€‚例如,如果在第一个å­èŠ‚ç‚¹ä¸Šè°ƒç”¨ï¼Œåˆ™ä½ç½®ä¸º "
+"[code]0[/code]。"
#: doc/classes/Node.xml
msgid ""
@@ -47564,21 +47869,21 @@ msgid ""
"Returns [code]true[/code] if this is an instance load placeholder. See "
"[InstancePlaceholder]."
msgstr ""
-"如果这是一个实例加载å ä½ç¬¦ï¼Œåˆ™è¿”回 [code]true[/code]。看到"
+"如果这是一个实例加载å ä½ç¬¦ï¼Œåˆ™è¿”回 [code]true[/code]ã€‚è§ "
"[InstancePlaceholder]。"
#: doc/classes/Node.xml
msgid "Returns the [SceneTree] that contains this node."
-msgstr "返回包å«è¯¥èŠ‚ç‚¹çš„[SceneTree]。"
+msgstr "返回包å«è¯¥èŠ‚ç‚¹çš„ [SceneTree]。"
#: doc/classes/Node.xml
msgid "Returns the node's [Viewport]."
-msgstr "返回节点的[Viewport]。"
+msgstr "返回节点的 [Viewport]。"
#: doc/classes/Node.xml
msgid ""
"Returns [code]true[/code] if the node that the [NodePath] points to exists."
-msgstr "如果[NodePath]指å‘的节点存在,则返回 [code]true[/code]。"
+msgstr "如果 [NodePath] 指å‘的节点存在,则返回 [code]true[/code]。"
#: doc/classes/Node.xml
msgid ""
@@ -47616,13 +47921,13 @@ msgid ""
"Returns [code]true[/code] if this node is in the specified group. See notes "
"in the description, and the group methods in [SceneTree]."
msgstr ""
-"如果该节点在指定的组中,则返回 [code]true[/code]。å‚阅æè¿°ä¸­çš„æ³¨é‡Šå’Œ"
-"[SceneTree]中的组方法。"
+"如果该节点在指定的组中,则返回 [code]true[/code]。å‚阅æè¿°ä¸­çš„æ³¨é‡Šå’Œ "
+"[SceneTree] 中的组方法。"
#: doc/classes/Node.xml
msgid ""
"Returns [code]true[/code] if this node is currently inside a [SceneTree]."
-msgstr "如果该节点当å‰åœ¨[SceneTree]中,返回 [code]true[/code]。"
+msgstr "如果该节点当å‰åœ¨ [SceneTree] 中,返回 [code]true[/code]。"
#: doc/classes/Node.xml
msgid ""
@@ -47664,54 +47969,54 @@ msgid ""
"Returns [code]true[/code] if physics processing is enabled (see [method "
"set_physics_process])."
msgstr ""
-"如果å¯ç”¨äº†ç‰©ç†å¤„ç†ï¼Œè¿”回 [code]true[/code](å‚阅[method "
-"set_physics_process])。"
+"如果å¯ç”¨äº†ç‰©ç†å¤„ç†ï¼Œè¿”回 [code]true[/code]ï¼ˆè§ [method "
+"set_physics_process])。"
#: doc/classes/Node.xml
msgid ""
"Returns [code]true[/code] if internal physics processing is enabled (see "
"[method set_physics_process_internal])."
msgstr ""
-"如果内部物ç†å¤„ç†è¢«å¯ç”¨ï¼Œè¿”回 [code]true[/code](è§[method "
-"set_physics_process_internal])。"
+"如果内部物ç†å¤„ç†è¢«å¯ç”¨ï¼Œè¿”回 [code]true[/code]ï¼ˆè§ [method "
+"set_physics_process_internal])。"
#: doc/classes/Node.xml
msgid ""
"Returns [code]true[/code] if processing is enabled (see [method "
"set_process])."
-msgstr "如果开å¯äº†å¤„ç†ï¼Œè¿”回 [code]true[/code](å‚阅[method set_process])。"
+msgstr "如果开å¯äº†å¤„ç†ï¼Œè¿”回 [code]true[/code]ï¼ˆè§ [method set_process])。"
#: doc/classes/Node.xml
msgid ""
"Returns [code]true[/code] if the node is processing input (see [method "
"set_process_input])."
msgstr ""
-"如果节点正在处ç†è¾“入(请å‚阅 [method set_process_input]),则返回 "
-"[code]true[/code]。"
+"如果节点正在处ç†è¾“入,则返回 [code]true[/code]ï¼ˆè§ [method "
+"set_process_input])。"
#: doc/classes/Node.xml
msgid ""
"Returns [code]true[/code] if internal processing is enabled (see [method "
"set_process_internal])."
msgstr ""
-"如果å¯ç”¨äº†å†…部处ç†ï¼Œè¿”回 [code]true[/code](å‚阅[method "
-"set_process_internal])。"
+"如果å¯ç”¨äº†å†…部处ç†ï¼Œåˆ™è¿”回 [code]true[/code]ï¼ˆè§ [method "
+"set_process_internal])。"
#: doc/classes/Node.xml
msgid ""
"Returns [code]true[/code] if the node is processing unhandled input (see "
"[method set_process_unhandled_input])."
msgstr ""
-"å¦‚æžœèŠ‚ç‚¹æ­£åœ¨å¤„ç†æœªè¢«å¤„ç†çš„输入(å‚阅[method set_process_unhandled_input]),则"
-"返回 [code]true[/code]。"
+"å¦‚æžœèŠ‚ç‚¹æ­£åœ¨å¤„ç†æœªè¢«å¤„ç†çš„输入,则返回 [code]true[/code]ï¼ˆè§ [method "
+"set_process_unhandled_input])。"
#: doc/classes/Node.xml
msgid ""
"Returns [code]true[/code] if the node is processing unhandled key input (see "
"[method set_process_unhandled_key_input])."
msgstr ""
-"å¦‚æžœèŠ‚ç‚¹æ­£åœ¨å¤„ç†æœªè¢«å¤„ç†çš„键输入(å‚阅[method "
-"set_process_unhandled_key_input]),则返回 [code]true[/code]。"
+"å¦‚æžœèŠ‚ç‚¹æ­£åœ¨å¤„ç†æœªè¢«å¤„ç†çš„键输入,则返回 [code]true[/code]ï¼ˆè§ [method "
+"set_process_unhandled_key_input])。"
#: doc/classes/Node.xml
msgid ""
@@ -47719,8 +48024,8 @@ msgid ""
"Since calls, signals, etc are performed by tree order, changing the order of "
"children nodes may be useful."
msgstr ""
-"在其他å­èŠ‚ç‚¹ä¸­å°†å­èŠ‚ç‚¹ç§»åŠ¨åˆ°ä¸åŒçš„ä½ç½®(顺åº)。由于调用ã€ä¿¡å·ç­‰æ˜¯æŒ‰æ ‘é¡ºåºæ‰§è¡Œ"
-"的,因此更改å­èŠ‚ç‚¹çš„é¡ºåºå¯èƒ½ä¼šå¾ˆæœ‰ç”¨ã€‚"
+"在其他å­èŠ‚ç‚¹ä¸­å°†å­èŠ‚ç‚¹ç§»åŠ¨åˆ°ä¸åŒçš„ä½ç½®ï¼ˆé¡ºåºï¼‰ã€‚由于调用ã€ä¿¡å·ç­‰æ˜¯æŒ‰æ ‘é¡ºåºæ‰§"
+"行的,因此更改å­èŠ‚ç‚¹çš„é¡ºåºå¯èƒ½ä¼šå¾ˆæœ‰ç”¨ã€‚"
#: doc/classes/Node.xml
msgid ""
@@ -47792,10 +48097,11 @@ msgid ""
"[code]parent_first[/code] is [code]false[/code], the children will be called "
"first."
msgstr ""
-"在这个节点上使用[code]args[/code]ä¸­ç»™å‡ºçš„å‚æ•°è°ƒç”¨ç»™å®šçš„æ–¹æ³•(如果存在),并递归"
-"地在其所有å­èŠ‚ç‚¹èº«ä¸Šè°ƒç”¨ã€‚å¦‚æžœ[code]parent_first[/code]傿•°ä¸º [code]true[/"
-"code],该方法将首先在当å‰èŠ‚ç‚¹ä¸Šè°ƒç”¨ï¼Œç„¶åŽåœ¨å…¶æ‰€æœ‰å­èŠ‚ç‚¹ä¸Šè°ƒç”¨ã€‚å¦‚æžœ"
-"[code]parent_first[/code]为 [code]false[/code],å­èŠ‚ç‚¹çš„æ–¹æ³•å°†é¦–å…ˆè¢«è°ƒç”¨ã€‚"
+"在这个节点上使用 [code]args[/code] ä¸­ç»™å‡ºçš„å‚æ•°è°ƒç”¨ç»™å®šçš„æ–¹æ³•(如果存在),并递"
+"归地在其所有å­èŠ‚ç‚¹èº«ä¸Šè°ƒç”¨ã€‚å¦‚æžœ [code]parent_first[/code] 傿•°ä¸º "
+"[code]true[/code],该方法将首先在当å‰èŠ‚ç‚¹ä¸Šè°ƒç”¨ï¼Œç„¶åŽåœ¨å…¶æ‰€æœ‰å­èŠ‚ç‚¹ä¸Šè°ƒç”¨ã€‚å¦‚"
+"æžœ [code]parent_first[/code] 为 [code]false[/code],å­èŠ‚ç‚¹çš„æ–¹æ³•å°†é¦–å…ˆè¢«è°ƒ"
+"用。"
#: doc/classes/Node.xml
msgid ""
@@ -47857,8 +48163,8 @@ msgid ""
"longer a parent or ancestor."
msgstr ""
"删除一个å­èŠ‚ç‚¹ã€‚è¯¥èŠ‚ç‚¹ä¸ä¼šè¢«åˆ é™¤ï¼Œå¿…须手动删除。\n"
-"[b]注:[/b]如果该[member owner]ä¸å†æ˜¯çˆ¶èŠ‚ç‚¹æˆ–ç¥–å…ˆï¼Œåˆ™è¯¥å‡½æ•°å¯ä»¥å°†è¢«ç§»é™¤èŠ‚ç‚¹"
-"(或其åŽä»£ï¼‰çš„[member owner]设置为[code]null[/code]。"
+"[b]注æ„:[/b]如果该 [member owner] ä¸å†æ˜¯çˆ¶èŠ‚ç‚¹æˆ–ç¥–å…ˆï¼Œåˆ™è¯¥å‡½æ•°å¯ä»¥å°†è¢«ç§»é™¤èŠ‚"
+"点(或其åŽä»£ï¼‰çš„ [member owner] 设置为 [code]null[/code]。"
#: doc/classes/Node.xml
msgid ""
@@ -47892,10 +48198,11 @@ msgid ""
"which case, [code]_ready[/code] will be called in the same order as it would "
"normally)."
msgstr ""
-"è¯·æ±‚å†æ¬¡è°ƒç”¨[code]_ready[/code]。注æ„,该方法ä¸ä¼šè¢«ç«‹å³è°ƒç”¨ï¼Œè€Œæ˜¯è¢«å®‰æŽ’在该节"
-"ç‚¹å†æ¬¡è¢«æ·»åŠ åˆ°åœºæ™¯æ ‘æ—¶ï¼ˆè§[method _ready])。[code]_ready[/code]åªä¸ºè¯·æ±‚它的"
-"节点调用,这æ„味ç€å¦‚果你想让æ¯ä¸ªå­èŠ‚ç‚¹ä¹Ÿè°ƒç”¨[code]_ready[/code],你需è¦ä¸ºå®ƒä»¬"
-"请求readyï¼ˆåœ¨è¿™ç§æƒ…况下,[code]_ready[/code]的调用顺åºä¸Žæ­£å¸¸æƒ…况下相åŒï¼‰ã€‚"
+"è¯·æ±‚å†æ¬¡è°ƒç”¨ [code]_ready[/code]。注æ„,该方法ä¸ä¼šè¢«ç«‹å³è°ƒç”¨ï¼Œè€Œæ˜¯è¢«å®‰æŽ’在该"
+"èŠ‚ç‚¹å†æ¬¡è¢«æ·»åŠ åˆ°åœºæ™¯æ ‘æ—¶ï¼ˆè§ [method _ready])。[code]_ready[/code] åªä¸ºè¯·æ±‚"
+"它的节点调用,这æ„味ç€å¦‚果你想让æ¯ä¸ªå­èŠ‚ç‚¹ä¹Ÿè°ƒç”¨ [code]_ready[/code],你需è¦"
+"为它们请求 readyï¼ˆåœ¨è¿™ç§æƒ…况下,[code]_ready[/code] 的调用顺åºä¸Žæ­£å¸¸æƒ…况下相"
+"åŒï¼‰ã€‚"
#: doc/classes/Node.xml
msgid ""
@@ -47955,8 +48262,8 @@ msgid ""
"By default, methods are not exposed to networking (and RPCs). See also "
"[method rset] and [method rset_config] for properties."
msgstr ""
-"å°† [code]method[/code] 方法的 RPC æ¨¡å¼æ”¹ä¸º [code]mode[/code] 模å¼ã€‚请å‚阅 "
-"[enum MultiplayerAPI.RPCMode]。å¦ä¸€ç§æ–¹æ³•是在方法和属性上加入相应的关键字注解"
+"å°† [code]method[/code] 方法的 RPC æ¨¡å¼æ”¹ä¸º [code]mode[/code] 模å¼ã€‚è§ [enum "
+"MultiplayerAPI.RPCMode]。å¦ä¸€ç§æ–¹æ³•是在方法和属性上加入相应的关键字注解"
"([code]remote[/code]ã€[code]master[/code]ã€[code]puppet[/code]ã€"
"[code]remoteesync[/code]ã€[code]masterync[/code]ã€[code]puppetsync[/code])。"
"é»˜è®¤æƒ…å†µä¸‹ï¼Œæ–¹æ³•ä¸æš´éœ²äºŽç½‘络(和 RPC)。请å‚阅 [method rset] å’Œ [method "
@@ -47994,8 +48301,8 @@ msgid ""
"applies to this method as well."
msgstr ""
"在其他对等体上远程改å˜ä¸€ä¸ªå±žæ€§çš„值(和本地)。行为å–决于给定属性的RPCé…置,"
-"è§ [method rset_config]。关于方法的RPC,也请å‚阅 [method rpc],大多数信æ¯ä¹Ÿé€‚"
-"用于这个方法。"
+"è§ [method rset_config]。关于方法的 RPC,也请å‚阅 [method rpc],大多数信æ¯ä¹Ÿ"
+"适用于这个方法。"
#: doc/classes/Node.xml
msgid ""
@@ -48019,14 +48326,14 @@ msgid ""
"Remotely changes the property's value on a specific peer identified by "
"[code]peer_id[/code] (see [method NetworkedMultiplayerPeer.set_target_peer])."
msgstr ""
-"远程改å˜å±žæ€§çš„值在一个指定的peer上[code]peer_id[/code](å‚阅[method "
-"NetworkedMultiplayerPeer.set_target_peer])。"
+"远程改å˜å±žæ€§çš„值在一个指定的 peer 上 [code]peer_id[/code]ï¼ˆè§ [method "
+"NetworkedMultiplayerPeer.set_target_peer])。"
#: doc/classes/Node.xml
msgid ""
"Remotely changes the property's value on other peers (and locally) using an "
"unreliable protocol."
-msgstr "使用ä¸å¯é çš„å议远程更改其他对等点(和本地)上的属性值。"
+msgstr "使用ä¸å¯é çš„å议远程更改其他对等点(和本地)上的属性值。"
#: doc/classes/Node.xml
msgid ""
@@ -48034,12 +48341,12 @@ msgid ""
"[code]peer_id[/code] using an unreliable protocol (see [method "
"NetworkedMultiplayerPeer.set_target_peer])."
msgstr ""
-"使用ä¸å¯é çš„åè®®(å‚阅[method NetworkedMultiplayerPeer.set_target_peer])远程更"
-"改指定对等体[code]peer_id[/code]上的属性值。"
+"使用ä¸å¯é çš„åè®®ï¼ˆè§ [method NetworkedMultiplayerPeer.set_target_peer])远程"
+"更改指定对等体 [code]peer_id[/code] 上的属性值。"
#: doc/classes/Node.xml
msgid "Sets the folded state of the node in the Scene dock."
-msgstr "设置场景dock中节点的折å çжæ€ã€‚"
+msgstr "è®¾ç½®åœºæ™¯é¢æ¿ä¸­èŠ‚ç‚¹çš„æŠ˜å çжæ€ã€‚"
#: doc/classes/Node.xml
msgid ""
@@ -48050,9 +48357,9 @@ msgid ""
"defaults to peer ID 1 (the server). If [code]recursive[/code], the given "
"peer is recursively set as the master for all children of this node."
msgstr ""
-"将节点的网络主节点设置为具有给定ID的对等体。网络主节点是对网络上的节点具有æƒ"
-"å¨çš„对等体。与[code]master[/code]å’Œ[code]puppet[/code]关键字一起使用很有用。"
-"默认情况下从父节点继承,父节点最终默认为peer ID 1(æœåС噍)。如果"
+"将节点的网络主节点设置为具有给定 ID 的对等体。网络主节点是对网络上的节点具有"
+"æƒå¨çš„对等体。与 [code]master[/code] å’Œ [code]puppet[/code] 关键字一起使用很"
+"有用。默认情况下从父节点继承,父节点最终默认为 peer ID 1(æœåŠ¡å™¨ï¼‰ã€‚å¦‚æžœ "
"[code]recursive[/code],则递归地将给定的对等节点设置为该节点所有å­èŠ‚ç‚¹çš„ä¸»èŠ‚"
"点。"
@@ -48067,10 +48374,10 @@ msgid ""
"_ready] will be ignored."
msgstr ""
"å¯ç”¨æˆ–ç¦ç”¨ç‰©ç†å¤„ç†ï¼ˆå³å›ºå®šå¸§çŽ‡ï¼‰ã€‚å½“ä¸€ä¸ªèŠ‚ç‚¹è¢«å¤„ç†æ—¶ï¼Œå®ƒå°†ä»¥ä¸€ä¸ªå›ºå®šçš„(通常"
-"是60FPS,å‚阅[member Engine.iterations_per_second]æ¥æ›´æ”¹è¯¥å€¼ï¼‰æ—¶é—´é—´é𔿔¶åˆ°ä¸€"
-"个[constant NOTIFICATION_PHYSICS_PROCESS](如果存在,[method "
-"_physics_process]回调将被调用)。如果[method _physics_process]被é‡å†™ï¼Œåˆ™è‡ªåЍ"
-"å¯ç”¨ã€‚在[method _ready]之å‰å¯¹å®ƒçš„任何调用都将被忽略。"
+"是 60 FPS,å‚阅 [member Engine.iterations_per_second] æ¥æ›´æ”¹è¯¥å€¼ï¼‰æ—¶é—´é—´é𔿔¶"
+"到一个 [constant NOTIFICATION_PHYSICS_PROCESS](如果存在,[method "
+"_physics_process] 回调将被调用)。如果 [method _physics_process] 被é‡å†™ï¼Œåˆ™è‡ª"
+"动å¯ç”¨ã€‚在 [method _ready] 之å‰å¯¹å®ƒçš„任何调用都将被忽略。"
#: doc/classes/Node.xml
msgid ""
@@ -48112,8 +48419,8 @@ msgid ""
"Enabled automatically if [method _input] is overridden. Any calls to this "
"before [method _ready] will be ignored."
msgstr ""
-"å¯ç”¨æˆ–ç¦ç”¨è¾“入处ç†ã€‚对于GUI控件æ¥è¯´ï¼Œè¿™ä¸æ˜¯å¿…需的。如果[method _input]被é‡"
-"写,则自动å¯ç”¨ã€‚任何在[method _ready]之å‰å¯¹å®ƒçš„调用都将被忽略。"
+"å¯ç”¨æˆ–ç¦ç”¨è¾“入处ç†ã€‚对于 GUI 控件æ¥è¯´ä¸æ˜¯å¿…需的。如果 [method _input] 被覆"
+"盖,则自动å¯ç”¨ã€‚任何在 [method _ready] 之å‰å¯¹å®ƒçš„调用都将被忽略。"
#: doc/classes/Node.xml
msgid ""
@@ -48151,13 +48458,13 @@ msgid ""
"_unhandled_key_input] is overridden. Any calls to this before [method "
"_ready] will be ignored."
msgstr ""
-"å¯ç”¨æœªå¤„ç†çš„æŒ‰é”®è¾“入处ç†ã€‚如果[method _unhandled_key_input]被é‡å†™ï¼Œåˆ™è‡ªåЍå¯"
-"用。任何在[method _ready]之å‰å¯¹å®ƒçš„调用都将被忽略。"
+"å¯ç”¨æœªå¤„ç†çš„æŒ‰é”®è¾“入处ç†ã€‚如果 [method _unhandled_key_input] 被é‡å†™ï¼Œåˆ™è‡ªåЍå¯"
+"用。任何在 [method _ready] 之å‰å¯¹å®ƒçš„调用都将被忽略。"
#: doc/classes/Node.xml
msgid ""
"Sets whether this is an instance load placeholder. See [InstancePlaceholder]."
-msgstr "è®¾ç½®è¿™æ˜¯å¦æ˜¯ä¸€ä¸ªå®žä¾‹åŠ è½½å ä½ç¬¦ã€‚å‚阅[InstancePlaceholder]。"
+msgstr "è®¾ç½®è¿™æ˜¯å¦æ˜¯å®žä¾‹åŠ è½½å ä½ç¬¦ã€‚è§ [InstancePlaceholder]。"
#: doc/classes/Node.xml
msgid ""
@@ -48173,7 +48480,7 @@ msgid ""
"The override to the default [MultiplayerAPI]. Set to [code]null[/code] to "
"use the default [SceneTree] one."
msgstr ""
-"对默认的[MultiplayerAPI]çš„é‡å†™ã€‚设置为[code]null[/code]å¯ä»¥ä½¿ç”¨é»˜è®¤çš„"
+"对默认的 [MultiplayerAPI] çš„é‡å†™ã€‚设置为 [code]null[/code] å¯ä»¥ä½¿ç”¨é»˜è®¤çš„ "
"[SceneTree]。"
#: doc/classes/Node.xml
@@ -48192,8 +48499,8 @@ msgid ""
"The [MultiplayerAPI] instance associated with this node. Either the [member "
"custom_multiplayer], or the default SceneTree one (if inside tree)."
msgstr ""
-"与该节点相关的[MultiplayerAPI]实例。è¦ä¹ˆæ˜¯[member custom_multiplayer],è¦ä¹ˆæ˜¯"
-"默认的SceneTree(如果在树内)。"
+"与该节点相关的 [MultiplayerAPI] 实例。è¦ä¹ˆæ˜¯ [member custom_multiplayer],è¦"
+"么是默认的 SceneTree(如果在树内)。"
#: doc/classes/Node.xml
msgid ""
@@ -48279,50 +48586,77 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
"在å­èŠ‚ç‚¹è¿›å…¥åœºæ™¯æ ‘æ—¶è§¦å‘,å¯ä»¥æ˜¯å› ä¸ºè¯¥å­èŠ‚ç‚¹è‡ªè¡Œè¿›å…¥ï¼Œä¹Ÿå¯ä»¥æ˜¯å› ä¸ºæœ¬èŠ‚ç‚¹å¸¦ç€"
-"该å­èŠ‚ç‚¹ä¸€èµ·è¿›å…¥ã€‚"
+"该å­èŠ‚ç‚¹ä¸€èµ·è¿›å…¥ã€‚\n"
+"这个信å·ä¼šåœ¨è¯¥å­èŠ‚ç‚¹è‡ªèº«çš„ [constant NOTIFICATION_ENTER_TREE] å’Œ [signal "
+"tree_entered] [i]之åŽ[/i]触å‘。"
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
-"在å­èŠ‚ç‚¹ç¦»å¼€åœºæ™¯æ ‘æ—¶è§¦å‘,å¯ä»¥æ˜¯å› ä¸ºè¯¥å­èŠ‚ç‚¹è‡ªè¡Œç¦»å¼€ï¼Œä¹Ÿå¯ä»¥æ˜¯å› ä¸ºæœ¬èŠ‚ç‚¹ç¦»"
-"开。"
+"在å­èŠ‚ç‚¹å³å°†é€€å‡ºåœºæ™¯æ ‘时触å‘,å¯ä»¥æ˜¯å› ä¸ºè¯¥å­èŠ‚ç‚¹è‡ªè¡Œé€€å‡ºï¼Œä¹Ÿå¯ä»¥æ˜¯å› ä¸ºæœ¬èŠ‚ç‚¹"
+"带ç€è¯¥å­èŠ‚ç‚¹ä¸€èµ·é€€å‡ºã€‚\n"
+"æ”¶åˆ°è¿™ä¸ªä¿¡å·æ—¶ï¼Œè¯¥å­èŠ‚ [code]node[/code] ä»åœ¨æ ‘中并且有效。这个信å·ä¼šåœ¨è¯¥å­èŠ‚"
+"点自身的 [signal tree_exiting] å’Œ [constant NOTIFICATION_EXIT_TREE] [i]之åŽ[/"
+"i]触å‘。"
#: doc/classes/Node.xml
msgid "Emitted when the node is ready."
-msgstr "当节点准备好时触å‘。"
+msgstr "当该节点准备好时触å‘。"
#: doc/classes/Node.xml
msgid "Emitted when the node is renamed."
-msgstr "在é‡å‘½å节点时触å‘。"
+msgstr "当该节点被é‡å‘½å时触å‘。"
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
-msgstr "当节点进入树时触å‘。"
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
+msgstr ""
+"当该节点进入树时触å‘。\n"
+"这个信å·ä¼šåœ¨ç›¸å…³çš„ [constant NOTIFICATION_ENTER_TREE] 通知[i]之åŽ[/i]触å‘。"
#: doc/classes/Node.xml
msgid "Emitted after the node exits the tree and is no longer active."
-msgstr "在节点退出树之åŽè§¦å‘,并且ä¸å†å¤„于活动状æ€ã€‚"
+msgstr "当该节点退出树之åŽè§¦å‘,并且ä¸å†å¤„于活动状æ€ã€‚"
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
-"当节点ä»å¤„于活动状æ€ä½†å³å°†é€€å‡ºæ ‘æ—¶å‘出。这是ååˆå§‹åŒ–的正确ä½ç½®ï¼ˆå¦‚果愿æ„,也"
-"å¯ä»¥ç§°ä¹‹ä¸ºâ€œæžæž„函数â€ï¼‰ã€‚"
+"当该节点ä»å¤„于活动状æ€ä½†å³å°†é€€å‡ºæ ‘æ—¶å‘出。这是ååˆå§‹åŒ–的正确ä½ç½®ï¼ˆå¦‚果愿æ„,"
+"也å¯ä»¥ç§°ä¹‹ä¸ºâ€œæžæž„函数â€ï¼‰ã€‚\n"
+"这个信å·ä¼šåœ¨ç›¸å…³çš„ [constant NOTIFICATION_EXIT_TREE] 通知[i]之å‰[/i]触å‘。"
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
-msgstr "当该节点进入 [SceneTree] 时收到的通知。"
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
+msgstr ""
+"当该节点进入 [SceneTree] 时收到的通知。\n"
+"这个通知会在相关的 [signal tree_entered] [i]之å‰[/i]å‘出。"
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
-msgstr "当该节点å³å°†é€€å‡º [SceneTree] 时收到的通知。"
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
+msgstr ""
+"当该节点å³å°†é€€å‡º [SceneTree] 时收到的通知。\n"
+"这个通知会在相关的 [signal tree_exiting] [i]之åŽ[/i]å‘出。"
#: doc/classes/Node.xml
msgid "Notification received when the node is moved in the parent."
@@ -48330,7 +48664,7 @@ msgstr "当该节点在其父节点中移动时收到的通知。"
#: doc/classes/Node.xml
msgid "Notification received when the node is ready. See [method _ready]."
-msgstr "当该节点就绪时接收到通知。请å‚阅 [method _ready]。"
+msgstr "å½“è¯¥èŠ‚ç‚¹å°±ç»ªæ—¶æŽ¥æ”¶åˆ°é€šçŸ¥ã€‚è§ [method _ready]。"
#: doc/classes/Node.xml
msgid "Notification received when the node is paused."
@@ -48361,7 +48695,7 @@ msgid ""
"[b]Note:[/b] This doesn't mean that a node entered the [SceneTree]."
msgstr ""
"当一个节点被设置为å¦ä¸€ä¸ªèŠ‚ç‚¹çš„å­èŠ‚ç‚¹æ—¶æ”¶åˆ°è¯¥é€šçŸ¥ã€‚\n"
-"[b]注æ„:[/b]è¿™å¹¶ä¸æ„味ç€ä¸€ä¸ªèŠ‚ç‚¹è¿›å…¥äº†[SceneTree]。"
+"[b]注æ„:[/b]è¿™å¹¶ä¸æ„味ç€ä¸€ä¸ªèŠ‚ç‚¹è¿›å…¥äº† [SceneTree]。"
#: doc/classes/Node.xml
msgid ""
@@ -48548,8 +48882,8 @@ msgid ""
"_process]'s [code]delta[/code]. If [code]scaled[/code] is [code]false[/"
"code], normalizes the movement."
msgstr ""
-"基于[method Node._process]的[code]delta[/code],在节点的X轴上应用一个局部平"
-"移。如果[code]scaled[/code]是[code]false[/code],则对è¿åŠ¨è¿›è¡Œæ ‡å‡†åŒ–ã€‚"
+"基于 [method Node._process] 的 [code]delta[/code],在节点的 X 轴上应用一个局"
+"部平移。如果 [code]scaled[/code] 是 [code]false[/code],则对è¿åŠ¨è¿›è¡Œæ ‡å‡†åŒ–ã€‚"
#: doc/classes/Node2D.xml
msgid ""
@@ -48557,8 +48891,8 @@ msgid ""
"_process]'s [code]delta[/code]. If [code]scaled[/code] is [code]false[/"
"code], normalizes the movement."
msgstr ""
-"基于[method Node._process]的[code]delta[/code],在节点的Y轴上应用一个局部平"
-"移。如果[code]scaled[/code]是[code]false[/code],则对è¿åŠ¨è¿›è¡Œæ ‡å‡†åŒ–ã€‚"
+"基于 [method Node._process] 的 [code]delta[/code],在节点的 Y 轴上应用一个局"
+"部平移。如果 [code]scaled[/code] 是 [code]false[/code],则对è¿åŠ¨è¿›è¡Œæ ‡å‡†åŒ–ã€‚"
#: doc/classes/Node2D.xml
msgid ""
@@ -48650,9 +48984,9 @@ msgid ""
"index. If this node's Z index is 2 and its parent's effective Z index is 3, "
"then this node's effective Z index will be 2 + 3 = 5."
msgstr ""
-"如果 [code]true[/code],节点的 Z 索引是相对于它的父节点的 Z 索引而言的。如果"
-"这个节点的 Z 索引是 2,它的父节点的实际 Z 索引是 3,那么这个节点的实际 Z 索引"
-"将是 2 + 3 = 5。"
+"如果为 [code]true[/code],节点的 Z 索引是相对于它的父节点的 Z 索引而言的。如"
+"果这个节点的 Z 索引是 2,它的父节点的实际 Z 索引是 3,那么这个节点的实际 Z 索"
+"引将是 2 + 3 = 5。"
#: doc/classes/Node2D.xml
msgid ""
@@ -48723,7 +49057,7 @@ msgstr ""
"@\"..\" # 父节点。\n"
"@\"../C\" # 兄弟节点 C.\n"
"# å‰å¯¼æ–œæ è¡¨ç¤ºå®ƒæ˜¯æ¥è‡ªåœºæ™¯æ ‘çš„ç»å¯¹è·¯å¾„。\n"
-"@\"/root\" # 等价于 get_tree().get_root()。\n"
+"@\"/root\" # 相当于 get_tree().get_root()。\n"
"@\"/root/Main\" # 如果你的主场景的根节点被命å为“Mainâ€ã€‚\n"
"@\"/root/MyAutoload\" # 如果你有一个自动加载的节点或场景。\n"
"[/codeblock]\n"
@@ -48770,17 +49104,17 @@ msgstr ""
"目标节点路径åŽåŠ ä¸Šå¯é€‰çš„“å­åç§°â€å¯ä»¥æŒ‡å‘èµ„æºæˆ–属性,也å¯ä»¥åµŒå¥—。\n"
"有效 NodePath 的示例(å‡è®¾è¿™äº›èŠ‚ç‚¹å­˜åœ¨å¹¶å…·æœ‰å¼•ç”¨çš„èµ„æºæˆ–属性):\n"
"[codeblock]\n"
-"# 指å‘ç²¾çµèŠ‚ç‚¹\n"
+"# æŒ‡å‘ Sprite 节点\n"
"“Path2D/PathFollow2D/Spriteâ€\n"
"# æŒ‡å‘ Sprite 节点åŠå…¶â€œçº¹ç†â€èµ„æºã€‚\n"
-"# get_node() 将检索“Spriteâ€ï¼Œè€Œ get_node_and_resource()\n"
-"# å°†åŒæ—¶æ£€ç´¢ Sprite 节点和“纹ç†â€èµ„æºã€‚\n"
+"# get_node() 将获å–“Spriteâ€ï¼Œè€Œ get_node_and_resource()\n"
+"# å°†åŒæ—¶èŽ·å– Sprite 节点åŠå…¶â€œtextureâ€èµ„æºã€‚\n"
"“Path2D/PathFollow2D/Sprite:textureâ€\n"
-"# æŒ‡å‘ Sprite 节点åŠå…¶â€œä½ç½®â€å±žæ€§ã€‚\n"
+"# æŒ‡å‘ Sprite 节点åŠå…¶â€œpositionâ€å±žæ€§ã€‚\n"
"\"Path2D/PathFollow2D/Sprite:position\"\n"
"# æŒ‡å‘ Sprite 节点åŠå…¶â€œpositionâ€å±žæ€§çš„“xâ€ç»„件。\n"
"\"Path2D/PathFollow2D/Sprite:position:x\"\n"
-"# ç»å¯¹è·¯å¾„(æ¥è‡ªâ€œrootâ€ï¼‰\n"
+"# ç»å¯¹è·¯å¾„(以“rootâ€å¼€å¤´ï¼‰\n"
"“/root/Level/Path2Dâ€\n"
"[/codeblock]"
@@ -48939,8 +49273,8 @@ msgid ""
"If [code]true[/code], the resulting texture contains a normal map created "
"from the original noise interpreted as a bump map."
msgstr ""
-"如果 [code]true[/code],产生的纹ç†åŒ…å«ä¸€ä¸ªç”±åŽŸå§‹å™ªå£°åˆ›å»ºçš„æ³•çº¿è´´å›¾ï¼Œè§£é‡Šä¸ºå‡¹"
-"凸贴图。"
+"如果为 [code]true[/code],产生的纹ç†åŒ…å«ä¸€ä¸ªç”±åŽŸå§‹å™ªå£°åˆ›å»ºçš„æ³•çº¿è´´å›¾ï¼Œè§£é‡Šä¸º"
+"凹凸贴图。"
#: modules/opensimplex/doc_classes/NoiseTexture.xml
msgid ""
@@ -48976,7 +49310,7 @@ msgid ""
"seamless noise."
msgstr ""
"çº¹ç†æ˜¯å¦å¯ä»¥å¹³é“ºè€Œæ²¡æœ‰å¯è§çš„æŽ¥ç¼ã€‚ç”Ÿæˆæ— ç¼çº¹ç†éœ€è¦æ›´é•¿çš„æ—¶é—´ã€‚\n"
-"[b]注:[/b] ä¸Žéžæ— ç¼å™ªå£°ç›¸æ¯”,无ç¼å™ªå£°å…·æœ‰è¾ƒä½Žçš„对比度。这是由于噪声使用更高"
+"[b]注æ„:[/b]ä¸Žéžæ— ç¼å™ªå£°ç›¸æ¯”,无ç¼å™ªå£°å…·æœ‰è¾ƒä½Žçš„对比度。这是由于噪声使用更高"
"维度æ¥ç”Ÿæˆæ— ç¼å™ªå£°çš„æ–¹å¼ã€‚"
#: modules/opensimplex/doc_classes/NoiseTexture.xml
@@ -49029,9 +49363,9 @@ msgstr ""
"çš„ [code]new Object[/code] 或 VisualScript 中的“构造对象â€èŠ‚ç‚¹ã€‚\n"
"对象ä¸ç®¡ç†å†…存。如果类继承自 Object,则必须手动删除它的实例。为此,请从您的脚"
"本中调用 [method free] 方法或从 C++ 中删除该实例。\n"
-"一些继承 Object 的类添加了内存管ç†ã€‚ [Reference] å°±æ˜¯è¿™ç§æƒ…况,它对引用进行计"
-"数,并在ä¸å†è¢«å¼•用时自动删除自己。 [Node] 是å¦ä¸€ç§åŸºæœ¬ç±»åž‹ï¼Œåœ¨ä»Žå†…存中释放时"
-"删除其所有å­èŠ‚ç‚¹ã€‚\n"
+"一些继承 Object 的类添加了内存管ç†ã€‚[Reference] å°±æ˜¯è¿™ç§æƒ…况,它对引用进行计"
+"数,并在ä¸å†è¢«å¼•用时自动删除自己。[Node] 是å¦ä¸€ç§åŸºæœ¬ç±»åž‹ï¼Œåœ¨ä»Žå†…存中释放时删"
+"除其所有å­èŠ‚ç‚¹ã€‚\n"
"对象导出属性,这些属性主è¦ç”¨äºŽå­˜å‚¨å’Œç¼–è¾‘ï¼Œä½†åœ¨ç¼–ç¨‹ä¸­å¹¶ä¸æ˜¯é‚£ä¹ˆæœ‰ç”¨ã€‚属性在 "
"[method _get_property_list] 中导出并在 [method _get] 和 [method _set] 中处"
"ç†ã€‚然而,脚本语言和 C++ 有更简å•的方法æ¥å¯¼å‡ºå®ƒä»¬ã€‚\n"
@@ -49186,14 +49520,14 @@ msgid ""
"where you should use the same convention as in the C# source (typically "
"PascalCase)."
msgstr ""
-"在空闲时间调用对象上的[code]method[/code]。这个方法支æŒå¯å˜æ•°é‡çš„傿•°ï¼Œæ‰€ä»¥å‚"
-"数是以逗å·åˆ†éš”的列表形å¼ä¼ é€’ã€‚ä¸‹é¢æ˜¯ä¸ªä¾‹å­ï¼š\n"
+"在空闲时间调用对象上的 [code]method[/code]。这个方法支æŒå¯å˜æ•°é‡çš„傿•°ï¼Œæ‰€ä»¥"
+"傿•°æ˜¯ä»¥é€—å·åˆ†éš”的列表形å¼ä¼ é€’ã€‚ä¸‹é¢æ˜¯ä¸ªä¾‹å­ï¼š\n"
"[codeblock]\n"
"call_deferred(\"set\", \"position\", Vector2(42.0, 0.0))\n"
"[/codeblock]\n"
-"[b]注æ„:[/b]在C#中,如果方法å称是由内置的Godot节点定义的,必须指定为"
-"snake_case。这ä¸é€‚用于用户定义的方法,在那里你应该使用与C#æºä»£ç ä¸­ç›¸åŒçš„约定"
-"(通常是PascalCase)。"
+"[b]注æ„:[/b]在 C# 中,如果方法å称是由内置的 Godot 节点定义的,必须指定为 "
+"snake_case。这ä¸é€‚用于用户定义的方法,在那里你应该使用与 C# æºä»£ç ä¸­ç›¸åŒçš„约"
+"定(通常是 PascalCase)。"
#: doc/classes/Object.xml
msgid ""
@@ -49204,8 +49538,8 @@ msgid ""
"callv(\"set\", [ \"position\", Vector2(42.0, 0.0) ])\n"
"[/codeblock]"
msgstr ""
-"在对象上调用[code]method[/code]并返回结果。与[method call]相åï¼Œè¿™ä¸ªæ–¹æ³•ä¸æ”¯"
-"æŒå¯å˜æ•°é‡çš„傿•°ï¼Œè€Œæ˜¯æœŸæœ›æ‰€æœ‰çš„傿•°éƒ½é€šè¿‡ä¸€ä¸ª[Array]。\n"
+"在对象上调用 [code]method[/code] 并返回结果。与 [method call] 相å,这个方法"
+"䏿”¯æŒå¯å˜æ•°é‡çš„傿•°ï¼Œè€Œæ˜¯æœŸæœ›æ‰€æœ‰çš„傿•°éƒ½é€šè¿‡ä¸€ä¸ª [Array]。\n"
"[codeblock]\n"
"callv(\"set\", [ \"position\", Vector2(42.0, 0.0) ])\n"
"[/codeblock]"
@@ -49215,8 +49549,8 @@ msgid ""
"Returns [code]true[/code] if the object can translate strings. See [method "
"set_message_translation] and [method tr]."
msgstr ""
-"如果该对象å¯ä»¥ç¿»è¯‘字符串,则返回 [code]true[/code]。å‚阅[method "
-"set_message_translation]和[method tr]。"
+"如果该对象å¯ä»¥ç¿»è¯‘字符串,则返回 [code]true[/code]ã€‚è§ [method "
+"set_message_translation] 和 [method tr]。"
#: doc/classes/Object.xml
msgid ""
@@ -49429,8 +49763,8 @@ msgstr ""
"将该对象的属性列表作为 [Array] 返回,元素为字典。\n"
"æ¯ä¸ªå±žæ€§çš„ [Dictionary] è‡³å°‘åŒ…å« [code]name: String[/code] å’Œ [code]type: "
"int[/code]ï¼ˆè§ [enum Variant.Type])æ¡ç›®ã€‚å¦å¤–,它还å¯ä»¥åŒ…括 [code]hint: "
-"int[/code](è§[enum PropertyHint])ã€[code]hint_string: String[/code],以åŠ"
-"[code]usage: int[/code](è§[enum PropertyUsageFlags])。"
+"int[/code]ï¼ˆè§ [enum PropertyHint])ã€[code]hint_string: String[/code]ï¼Œä»¥åŠ "
+"[code]usage: int[/code]ï¼ˆè§ [enum PropertyUsageFlags])。"
#: doc/classes/Object.xml
msgid ""
@@ -49487,9 +49821,9 @@ msgid ""
msgstr ""
"如果对象从给定的 [code]class[/code] 中继承,则返回 [code]true[/code]。å¦è¯·å‚"
"阅 [method get_class]。\n"
-"[b]注:[/b] [method is_class] 没有考虑 [code]class_name[/code] 声明。如果对象"
-"有 [code]class_name[/code] 定义,[method is_class] 将为该å称返回 "
-"[code]false[/code] 。"
+"[b]注æ„:[/b][method is_class] 没有考虑 [code]class_name[/code] 声明。如果对"
+"象有 [code]class_name[/code] 定义,[method is_class] 将为该å称返回 "
+"[code]false[/code]。"
#: doc/classes/Object.xml
msgid ""
@@ -49535,7 +49869,7 @@ msgstr ""
#: doc/classes/Object.xml
msgid ""
"Removes a given entry from the object's metadata. See also [method set_meta]."
-msgstr "从对象的元数æ®ä¸­åˆ é™¤ç»™å®šæ¡ç›®ã€‚å¦è§ [method set_meta]。"
+msgstr "从对象的元数æ®ä¸­åˆ é™¤ç»™å®šæ¡ç›®ã€‚å¦è¯·å‚阅 [method set_meta]。"
#: doc/classes/Object.xml
msgid ""
@@ -49596,7 +49930,7 @@ msgstr ""
msgid ""
"Defines whether the object can translate strings (with calls to [method "
"tr]). Enabled by default."
-msgstr "定义对象是å¦å¯ä»¥è½¬æ¢å­—符串(通过调用[method tr])。默认å¯ç”¨ã€‚"
+msgstr "定义对象是å¦å¯ä»¥è½¬æ¢å­—符串(通过调用 [method tr])。默认å¯ç”¨ã€‚"
#: doc/classes/Object.xml
msgid ""
@@ -49686,7 +50020,7 @@ msgstr ""
#: doc/classes/Occluder.xml
msgid "Allows [OccluderShape]s to be used for occlusion culling."
-msgstr "å…许使用[OccluderShape]æ¥è¿›è¡Œé®æŒ¡å‰”除。"
+msgstr "å…许使用 [OccluderShape] æ¥è¿›è¡Œé®æŒ¡å‰”除。"
#: doc/classes/Occluder.xml
msgid ""
@@ -49727,13 +50061,13 @@ msgstr ""
#: doc/classes/OccluderPolygon2D.xml
msgid "Defines a 2D polygon for LightOccluder2D."
-msgstr "为LightOccluder2D定义一个2D多边形。"
+msgstr "为 LightOccluder2D 定义一个 2D 多边形。"
#: doc/classes/OccluderPolygon2D.xml
msgid ""
"Editor facility that helps you draw a 2D polygon used as resource for "
"[LightOccluder2D]."
-msgstr "编辑工具,帮助你绘制一个2D多边形用作资æº[LightOccluder2D]。"
+msgstr "编辑工具,帮助你绘制一个 2D å¤šè¾¹å½¢ç”¨ä½œèµ„æº [LightOccluder2D]。"
#: doc/classes/OccluderPolygon2D.xml
msgid ""
@@ -49741,7 +50075,7 @@ msgid ""
"occludes the light coming from any direction. An opened OccluderPolygon2D "
"occludes the light only at its outline's direction."
msgstr ""
-"如果[code]true[/code],å°é—­è¯¥å¤šè¾¹å½¢ã€‚一个å°é—­çš„polygon2då°é—­æ¥è‡ªä»»ä½•æ–¹å‘çš„"
+"如果为 [code]true[/code],å°é—­è¯¥å¤šè¾¹å½¢ã€‚一个å°é—­çš„polygon2då°é—­æ¥è‡ªä»»ä½•æ–¹å‘çš„"
"光。一个开放的OccluderPolygon2Dåªåœ¨å…¶è½®å»“æ–¹å‘ä¸Šé®æŒ¡å…‰ã€‚"
#: doc/classes/OccluderPolygon2D.xml
@@ -49754,28 +50088,28 @@ msgid ""
"[b]Note:[/b] The returned value is a copy of the underlying array, rather "
"than a reference."
msgstr ""
-"带有多边形顶点ä½ç½®ç´¢å¼•çš„[Vector2]数组。\n"
+"带有多边形顶点ä½ç½®ç´¢å¼•çš„ [Vector2] 数组。\n"
"[b]注æ„:[/b]è¿”å›žå€¼æ˜¯åŸºç¡€æ•°ç»„çš„å‰¯æœ¬ï¼Œè€Œä¸æ˜¯å¼•用。"
#: doc/classes/OccluderPolygon2D.xml
msgid "Culling is disabled. See [member cull_mode]."
-msgstr "ç¦ç”¨å‰”除。å‚阅[member cull_mode]。"
+msgstr "ç¦ç”¨å‰”é™¤ã€‚è§ [member cull_mode]。"
#: doc/classes/OccluderPolygon2D.xml
msgid ""
"Culling is performed in the clockwise direction. See [member cull_mode]."
-msgstr "按顺时针方å‘进行剔除。è§[member cull_mode]。"
+msgstr "按顺时针方å‘è¿›è¡Œå‰”é™¤ã€‚è§ [member cull_mode]。"
#: doc/classes/OccluderPolygon2D.xml
msgid ""
"Culling is performed in the counterclockwise direction. See [member "
"cull_mode]."
-msgstr "按逆时针方å‘进行剔除。å‚阅[member cull_mode]。"
+msgstr "按逆时针方å‘è¿›è¡Œå‰”é™¤ã€‚è§ [member cull_mode]。"
#: doc/classes/OccluderShape.xml
msgid ""
"Base class for shapes used for occlusion culling by the [Occluder] node."
-msgstr "用于[Occluder]èŠ‚ç‚¹è¿›è¡Œé®æŒ¡å‰”除的形状的基类。"
+msgstr "用于 [Occluder] èŠ‚ç‚¹è¿›è¡Œé®æŒ¡å‰”除的形状的基类。"
#: doc/classes/OccluderShape.xml
msgid "[Occluder]s can use any primitive shape derived from [OccluderShape]."
@@ -49905,31 +50239,32 @@ msgid ""
"[member omni_attenuation] in use, the light will never reach anything "
"outside this radius."
msgstr ""
-"光的åŠå¾„。请注æ„,有效的照明区域å¯èƒ½çœ‹èµ·æ¥æ›´å°ï¼Œè¿™å–决于使用的[member "
-"omni_attenuation]。无论使用何ç§[member omni_attenuation],光线都ä¸ä¼šåˆ°è¾¾è¿™ä¸ª"
+"光的åŠå¾„。请注æ„,有效的照明区域å¯èƒ½çœ‹èµ·æ¥æ›´å°ï¼Œè¿™å–决于使用的 [member "
+"omni_attenuation]ã€‚æ— è®ºä½¿ç”¨ä½•ç§ [member omni_attenuation],光线都ä¸ä¼šåˆ°è¾¾è¿™ä¸ª"
"åŠå¾„以外的地方。"
#: doc/classes/OmniLight.xml
msgid "See [enum ShadowDetail]."
-msgstr "å‚阅[enum ShadowDetail]。"
+msgstr "è§ [enum ShadowDetail]。"
#: doc/classes/OmniLight.xml
msgid "See [enum ShadowMode]."
-msgstr "å‚阅[enum ShadowMode]。"
+msgstr "è§ [enum ShadowMode]。"
#: doc/classes/OmniLight.xml
msgid ""
"Shadows are rendered to a dual-paraboloid texture. Faster than [constant "
"SHADOW_CUBE], but lower-quality."
msgstr ""
-"é˜´å½±è¢«æ¸²æŸ“åˆ°ä¸€ä¸ªåŒæŠ›ç‰©é¢çº¹ç†ã€‚比[constant SHADOW_CUBE]更快,但质é‡è¾ƒå·®ã€‚"
+"é˜´å½±è¢«æ¸²æŸ“åˆ°ä¸€ä¸ªåŒæŠ›ç‰©é¢çº¹ç†ã€‚比 [constant SHADOW_CUBE] 更快,但质é‡è¾ƒå·®ã€‚"
#: doc/classes/OmniLight.xml
msgid ""
"Shadows are rendered to a cubemap. Slower than [constant "
"SHADOW_DUAL_PARABOLOID], but higher-quality."
msgstr ""
-"阴影被渲染æˆä¸€ä¸ªcubemap。比[constant SHADOW_DUAL_PARABOLOID]æ…¢ï¼Œä½†è´¨é‡æ›´é«˜ã€‚"
+"阴影被渲染æˆä¸€ä¸ªç«‹æ–¹ä½“贴图。比 [constant SHADOW_DUAL_PARABOLOID] æ…¢ï¼Œä½†è´¨é‡æ›´"
+"高。"
#: doc/classes/OmniLight.xml
msgid "Use more detail vertically when computing the shadow."
@@ -49941,7 +50276,7 @@ msgstr "在计算阴影时,在水平方å‘上使用更多的细节。"
#: modules/opensimplex/doc_classes/OpenSimplexNoise.xml
msgid "Noise generator based on Open Simplex."
-msgstr "基于Open Simplex的噪声å‘生器。"
+msgstr "基于 Open Simplex 的噪声å‘生器。"
#: modules/opensimplex/doc_classes/OpenSimplexNoise.xml
msgid ""
@@ -49965,17 +50300,17 @@ msgid ""
"[/codeblock]"
msgstr ""
"这个资æºå…许你é…ç½®å’Œé‡‡æ ·ä¸€ä¸ªåˆ†å½¢å™ªå£°ç©ºé—´ã€‚ä¸‹é¢æ˜¯ä¸€ä¸ªç®€çŸ­çš„使用例å­ï¼Œå®ƒé…置了"
-"一个OpenSimplexNoise,并在ä¸åŒçš„ä½ç½®å’Œç»´åº¦ä¸Šå¾—到采样。\n"
+"一个 OpenSimplexNoise,并在ä¸åŒçš„ä½ç½®å’Œç»´åº¦ä¸Šå¾—到采样。\n"
"[codeblock]\n"
"var noise = OpenSimplexNoise.new()\n"
"\n"
-"# Configure\n"
+"# é…ç½®\n"
"noise.seed = randi()\n"
"noise.octaves = 4\n"
"noise.period = 20.0\n"
"noise.persistence = 0.8\n"
"\n"
-"# Sample\n"
+"# 采样\n"
"print(\"Values:\")\n"
"print(noise.get_noise_2d(1.0, 1.0))\n"
"print(noise.get_noise_3d(0.5, 3.0, 15.0))\n"
@@ -49990,9 +50325,9 @@ msgid ""
"value is used as the coordinates of the top-left corner of the generated "
"noise."
msgstr ""
-"æ ¹æ®å½“å‰çš„å™ªå£°å‚æ•°ï¼Œç”Ÿæˆä¸€ä¸ª[constant Image.FORMAT_L8]æ ¼å¼çš„噪声图åƒï¼Œéœ€è¦æŒ‡"
-"定其[code]width[/code] 和 [code]height[/code]。如果指定了[code]noise_offset[/"
-"code],那么å移值将作为生æˆçš„å™ªå£°å·¦ä¸Šè§’çš„åæ ‡ã€‚"
+"æ ¹æ®å½“å‰çš„å™ªå£°å‚æ•°ï¼Œç”Ÿæˆä¸€ä¸ª [constant Image.FORMAT_L8] æ ¼å¼çš„噪声图åƒï¼Œéœ€è¦"
+"指定其 [code]width[/code] 和 [code]height[/code]。如果指定了 "
+"[code]noise_offset[/code],那么å移值将作为生æˆçš„å™ªå£°å·¦ä¸Šè§’çš„åæ ‡ã€‚"
#: modules/opensimplex/doc_classes/OpenSimplexNoise.xml
msgid ""
@@ -50000,21 +50335,21 @@ msgid ""
"[b]Note:[/b] This method actually returns the 2D noise value [code][-1,1][/"
"code] with fixed y-coordinate value 0.0."
msgstr ""
-"返回给定xåæ ‡å¤„的一维噪声值[code][-1,1][/code]。\n"
-"[b]注æ„:[/b]这个方法实际上返回的是固定Yåæ ‡å€¼ä¸º0.0的二维噪声值[code][-1,1][/"
-"code]。"
+"返回给定 x åæ ‡å¤„çš„ 1D 噪声值 [code][-1,1][/code]。\n"
+"[b]注æ„:[/b]这个方法实际上返回的是固定 Y åæ ‡å€¼ä¸º 0.0 çš„ 2D 噪声值 [code]"
+"[-1,1][/code]。"
#: modules/opensimplex/doc_classes/OpenSimplexNoise.xml
msgid "Returns the 2D noise value [code][-1,1][/code] at the given position."
-msgstr "返回给定ä½ç½®çš„2D噪声值[code][-1,1][/code]。"
+msgstr "返回在给定ä½ç½®çš„ 2D 噪声值 [code][-1,1][/code]。"
#: modules/opensimplex/doc_classes/OpenSimplexNoise.xml
msgid "Returns the 3D noise value [code][-1,1][/code] at the given position."
-msgstr "返回在给定ä½ç½®çš„3D噪声值[code][-1,1][/code]。"
+msgstr "返回在给定ä½ç½®çš„ 3D 噪声值 [code][-1,1][/code]。"
#: modules/opensimplex/doc_classes/OpenSimplexNoise.xml
msgid "Returns the 4D noise value [code][-1,1][/code] at the given position."
-msgstr "返回指定ä½ç½®çš„4D噪声值[code][-1,1][/code]。"
+msgstr "返回在给定ä½ç½®çš„ 4D 噪声值 [code][-1,1][/code]。"
#: modules/opensimplex/doc_classes/OpenSimplexNoise.xml
msgid ""
@@ -50041,16 +50376,16 @@ msgid ""
"generate.\n"
"[b]Note:[/b] The maximum allowed value is 9."
msgstr ""
-"采样得到分形噪声的OpenSimplexå™ªå£°å±‚æ•°ã€‚æ›´é«˜çš„å€¼å¯¼è‡´æ›´è¯¦ç»†çš„å™ªå£°ï¼Œä½†éœ€è¦æ›´å¤šçš„"
-"æ—¶é—´æ¥ç”Ÿæˆã€‚\n"
-"[b]备注:[/b]最大值为9。"
+"采样得到分形噪声的 OpenSimplex å™ªå£°å±‚æ•°ã€‚æ›´é«˜çš„å€¼å¯¼è‡´æ›´è¯¦ç»†çš„å™ªå£°ï¼Œä½†éœ€è¦æ›´å¤š"
+"的时间æ¥ç”Ÿæˆã€‚\n"
+"[b]备注:[/b]最大值为 9。"
#: modules/opensimplex/doc_classes/OpenSimplexNoise.xml
msgid ""
"Period of the base octave. A lower period results in a higher-frequency "
"noise (more value changes across the same distance)."
msgstr ""
-"基本八度的周期。较低的周期会导致更高频率的噪声(在相åŒè·ç¦»ä¸Šçš„值å˜åŒ–更多)。"
+"基本八度的周期。较低的周期会导致更高频率的噪声(在相åŒè·ç¦»ä¸Šçš„值å˜åŒ–更多)。"
#: modules/opensimplex/doc_classes/OpenSimplexNoise.xml
msgid ""
@@ -50116,15 +50451,15 @@ msgstr "清除[OptionButton]中的所有项目。"
#: doc/classes/OptionButton.xml
msgid "Returns the amount of items in the OptionButton, including separators."
-msgstr "返回OptionButton中的项目数é‡ï¼ŒåŒ…括分隔符。"
+msgstr "返回 OptionButton 中的项目数é‡ï¼ŒåŒ…括分隔符。"
#: doc/classes/OptionButton.xml doc/classes/PopupMenu.xml
msgid "Returns the icon of the item at index [code]idx[/code]."
-msgstr "返回索引[code]idx[/code]处项目的图标。"
+msgstr "返回索引 [code]idx[/code] 处项目的图标。"
#: doc/classes/OptionButton.xml
msgid "Returns the ID of the item at index [code]idx[/code]."
-msgstr "返回索引[code]idx[/code]处项目的ID。"
+msgstr "返回索引 [code]idx[/code] 处项目的 ID。"
#: doc/classes/OptionButton.xml
msgid "Returns the index of the item with the given [code]id[/code]."
@@ -50156,16 +50491,17 @@ msgstr "返回所选项目的 ID,如果没有选择项目,则返回 [code]-1
msgid ""
"Gets the metadata of the selected item. Metadata for items can be set using "
"[method set_item_metadata]."
-msgstr "获å–选定项的元数æ®ã€‚å¯ä»¥ä½¿ç”¨[method set_item_metadata]设置项的元数æ®ã€‚"
+msgstr ""
+"获å–选定项的元数æ®ã€‚å¯ä»¥ä½¿ç”¨ [method set_item_metadata] 设置项的元数æ®ã€‚"
#: doc/classes/OptionButton.xml
msgid ""
"Returns [code]true[/code] if the item at index [code]idx[/code] is disabled."
-msgstr "如果索引[code]idx[/code]项被ç¦ç”¨ï¼Œè¿”回 [code]true[/code]。"
+msgstr "如果索引 [code]idx[/code] 项被ç¦ç”¨ï¼Œè¿”回 [code]true[/code]。"
#: doc/classes/OptionButton.xml
msgid "Removes the item at index [code]idx[/code]."
-msgstr "移除索引[code]idx[/code]处的项目。"
+msgstr "移除索引 [code]idx[/code] 处的项目。"
#: doc/classes/OptionButton.xml
msgid ""
@@ -50234,11 +50570,11 @@ msgstr "当用户更改当å‰é¡¹æ—¶è§¦å‘ã€‚æ‰€é€‰é¡¹ç›®çš„ç´¢å¼•ä½œä¸ºå‚æ•°ä¼ 
#: doc/classes/OptionButton.xml
msgid "Default text [Color] of the [OptionButton]."
-msgstr "[OptionButton]的默认文本[Color]。"
+msgstr "[OptionButton] 的默认文本 [Color]。"
#: doc/classes/OptionButton.xml
msgid "Text [Color] used when the [OptionButton] is disabled."
-msgstr "当[OptionButton]被ç¦ç”¨æ—¶ä½¿ç”¨çš„æ–‡æœ¬[Color]。"
+msgstr "当 [OptionButton] 被ç¦ç”¨æ—¶ä½¿ç”¨çš„æ–‡æœ¬ [Color]。"
#: doc/classes/OptionButton.xml
msgid ""
@@ -50246,16 +50582,16 @@ msgid ""
"normal text color of the button. Disabled, hovered, and pressed states take "
"precedence over this color."
msgstr ""
-"当[OptionButton]获得焦点时使用的文本[Color]ã€‚åªæ›¿æ¢æŒ‰é’®çš„æ­£å¸¸æ–‡æœ¬é¢œè‰²ã€‚ç¦ç”¨ã€"
-"悬åœå’ŒæŒ‰ä¸‹çжæ€ä¼˜å…ˆäºŽè¿™ä¸ªé¢œè‰²ã€‚"
+"当 [OptionButton] 获得焦点时使用的文本 [Color]ã€‚åªæ›¿æ¢æŒ‰é’®çš„æ­£å¸¸æ–‡æœ¬é¢œè‰²ã€‚ç¦"
+"ç”¨ã€æ‚¬åœå’ŒæŒ‰ä¸‹çжæ€ä¼˜å…ˆäºŽè¿™ä¸ªé¢œè‰²ã€‚"
#: doc/classes/OptionButton.xml
msgid "Text [Color] used when the [OptionButton] is being hovered."
-msgstr "当鼠标悬åœ[OptionButton]时使用的文本[Color]。"
+msgstr "å½“é¼ æ ‡æ‚¬åœ [OptionButton] 时使用的文本 [Color]。"
#: doc/classes/OptionButton.xml
msgid "Text [Color] used when the [OptionButton] is being pressed."
-msgstr "当[OptionButton]被按下时使用的文本[Color]。"
+msgstr "当 [OptionButton] 被按下时使用的文本 [Color]。"
#: doc/classes/OptionButton.xml
msgid ""
@@ -50264,11 +50600,11 @@ msgstr "箭头图标和按钮的å³è¾¹ç¼˜ä¹‹é—´çš„æ°´å¹³ç©ºé—´ã€‚"
#: doc/classes/OptionButton.xml
msgid "The horizontal space between [OptionButton]'s icon and text."
-msgstr "[OptionButton]图标与文本之间的水平间è·ã€‚"
+msgstr "[OptionButton] 图标与文本之间的水平间è·ã€‚"
#: doc/classes/OptionButton.xml
msgid "[Font] of the [OptionButton]'s text."
-msgstr "[OptionButton]的文本的[Font]。"
+msgstr "[OptionButton] 的文本的 [Font]。"
#: doc/classes/OptionButton.xml
msgid "The arrow icon to be drawn on the right end of the button."
@@ -50276,7 +50612,7 @@ msgstr "è¦ç»˜åˆ¶åœ¨æŒ‰é’®å³ä¾§çš„箭头图标。"
#: doc/classes/OptionButton.xml
msgid "[StyleBox] used when the [OptionButton] is disabled."
-msgstr "当[OptionButton]被ç¦ç”¨æ—¶ä½¿ç”¨çš„[StyleBox]。"
+msgstr "当 [OptionButton] 被ç¦ç”¨æ—¶ä½¿ç”¨çš„ [StyleBox]。"
#: doc/classes/OptionButton.xml
msgid ""
@@ -50284,20 +50620,20 @@ msgid ""
"current [StyleBox], so using [StyleBoxEmpty] will just disable the focus "
"visual effect."
msgstr ""
-"当[OptionButton]被èšç„¦æ—¶ä½¿ç”¨çš„[StyleBox]。它显示在当å‰çš„[StyleBox]上,所以使"
-"用[StyleBoxEmpty]å°†åªæ˜¯ç¦ç”¨ç„¦ç‚¹çš„视觉效果。"
+"当 [OptionButton] 被èšç„¦æ—¶ä½¿ç”¨çš„ [StyleBox]。它显示在当å‰çš„ [StyleBox] 上,所"
+"以使用 [StyleBoxEmpty] å°†åªæ˜¯ç¦ç”¨ç„¦ç‚¹çš„视觉效果。"
#: doc/classes/OptionButton.xml
msgid "[StyleBox] used when the [OptionButton] is being hovered."
-msgstr "当[OptionButton]è¢«é¼ æ ‡æ‚¬åœæ—¶ä½¿ç”¨çš„[StyleBox]。"
+msgstr "当 [OptionButton] è¢«é¼ æ ‡æ‚¬åœæ—¶ä½¿ç”¨çš„ [StyleBox]。"
#: doc/classes/OptionButton.xml
msgid "Default [StyleBox] for the [OptionButton]."
-msgstr "[OptionButton]的默认[StyleBox]。"
+msgstr "[OptionButton] 的默认 [StyleBox]。"
#: doc/classes/OptionButton.xml
msgid "[StyleBox] used when the [OptionButton] is being pressed."
-msgstr "当按下[OptionButton]时使用的[StyleBox]。"
+msgstr "当按下 [OptionButton] 时使用的 [StyleBox]。"
#: doc/classes/OS.xml
msgid "Operating System functions."
@@ -50310,8 +50646,8 @@ msgid ""
"driver, date and time, timers, environment variables, execution of binaries, "
"command line, etc."
msgstr ""
-"æ“作系统的功能。OS 包装了与主机æ“作系统通信的最常è§åŠŸèƒ½ï¼Œå¦‚å‰ªè´´æ¿ã€è§†é¢‘驱动程"
-"åºã€æ—¥æœŸå’Œæ—¶é—´ã€è®¡æ—¶å™¨ã€çŽ¯å¢ƒå˜é‡ã€äºŒè¿›åˆ¶æ–‡ä»¶çš„æ‰§è¡Œã€å‘½ä»¤è¡Œç­‰ã€‚"
+"æ“作系统的功能。OS å°è£…了与主机æ“作系统通信的最常è§åŠŸèƒ½ï¼Œå¦‚å‰ªè´´æ¿ã€è§†é¢‘驱动ã€"
+"日期和时间ã€è®¡æ—¶å™¨ã€çŽ¯å¢ƒå˜é‡ã€äºŒè¿›åˆ¶æ–‡ä»¶çš„æ‰§è¡Œã€å‘½ä»¤è¡Œç­‰ã€‚"
#: doc/classes/OS.xml
msgid ""
@@ -50339,8 +50675,8 @@ msgid ""
"Shuts down system MIDI driver.\n"
"[b]Note:[/b] This method is implemented on Linux, macOS and Windows."
msgstr ""
-"关闭系统MIDI驱动程åºã€‚\n"
-"[b]注æ„:[/b]该方法åªåœ¨Linux, macOSå’ŒWindows上实现。"
+"关闭系统 MIDI 驱动程åºã€‚\n"
+"[b]注æ„:[/b]该方法åªåœ¨ Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -50374,18 +50710,18 @@ msgid ""
"the project if it is currently running (since the project is an independent "
"child process)."
msgstr ""
-"将当å‰çº¿ç¨‹çš„æ‰§è¡Œå»¶è¿Ÿ [code]msec[/code] 毫秒。 [code]msec[/code] 必须大于或等"
-"于 [code]0[/code]。å¦åˆ™ï¼Œ [method delay_msec] 将䏿‰§è¡Œä»»ä½•æ“作并打å°é”™è¯¯æ¶ˆ"
+"将当å‰çº¿ç¨‹çš„æ‰§è¡Œå»¶è¿Ÿ [code]msec[/code] 毫秒。[code]msec[/code] 必须大于或等"
+"于 [code]0[/code]。å¦åˆ™ï¼Œ[method delay_msec] 将䏿‰§è¡Œä»»ä½•æ“作并打å°é”™è¯¯æ¶ˆ"
"æ¯ã€‚\n"
-"[b]注:[/b] [method delay_msec]是一ç§[i]阻塞[/i]å»¶è¿Ÿä»£ç æ‰§è¡Œçš„æ–¹å¼ã€‚è¦ä»¥éžé˜»"
-"塞方å¼å»¶è¿Ÿä»£ç æ‰§è¡Œï¼Œè¯·å‚阅 [method SceneTree.create_timer]。使用 [method "
+"[b]注æ„:[/b][method delay_msec] 是一ç§[i]阻塞[/i]å»¶è¿Ÿä»£ç æ‰§è¡Œçš„æ–¹å¼ã€‚è¦ä»¥éž"
+"阻塞方å¼å»¶è¿Ÿä»£ç æ‰§è¡Œï¼Œè¯·å‚阅 [method SceneTree.create_timer]。使用 [method "
"SceneTree.create_timer] 生æˆå°†å»¶è¿Ÿä½äºŽ [code]yield[/code] 下方的代ç çš„æ‰§è¡Œï¼Œ"
"而ä¸ä¼šå½±å“项目的其余部分(或编辑器,例如 [EditorPlugin] å’Œ "
"[EditorScript])。\n"
-"[b]注æ„:[/b]当在主线程上调用[method delay_msec]æ—¶ï¼Œå®ƒä¼šå†»ç»“é¡¹ç›®å¹¶é˜»æ­¢å®ƒé‡æ–°"
-"绘制和注册输入,直到延迟结æŸã€‚当使用 [method delay_msec] 作为 [EditorPlugin] "
-"或 [EditorScript] 的一部分时,它会冻结编辑器但ä¸ä¼šå†»ç»“当剿­£åœ¨è¿è¡Œçš„项目(因"
-"为项目是一个独立的å­è¿›ç¨‹ï¼‰ã€‚"
+"[b]注æ„:[/b]当在主线程上调用 [method delay_msec] 时,它会冻结项目并阻止它é‡"
+"新绘制和注册输入,直到延迟结æŸã€‚当使用 [method delay_msec] 作为 "
+"[EditorPlugin] 或 [EditorScript] 的一部分时,它会冻结编辑器但ä¸ä¼šå†»ç»“当剿­£åœ¨"
+"è¿è¡Œçš„项目(因为项目是一个独立的å­è¿›ç¨‹ï¼‰ã€‚"
#: doc/classes/OS.xml
msgid ""
@@ -50406,26 +50742,26 @@ msgid ""
"the project if it is currently running (since the project is an independent "
"child process)."
msgstr ""
-"将当å‰çº¿ç¨‹çš„æ‰§è¡Œå»¶è¿Ÿ [code]usec[/code] 微秒。 [code]usec[/code] 必须大于或等"
-"于 [code]0[/code]。å¦åˆ™ï¼Œ [method delay_usec] 将什么也ä¸åšï¼Œå¹¶ä¼šæ‰“å°é”™è¯¯æ¶ˆ"
+"将当å‰çº¿ç¨‹çš„æ‰§è¡Œå»¶è¿Ÿ [code]usec[/code] 微秒。[code]usec[/code] 必须大于或等"
+"于 [code]0[/code]。å¦åˆ™ï¼Œ[method delay_usec] 将什么也ä¸åšï¼Œå¹¶ä¼šæ‰“å°é”™è¯¯æ¶ˆ"
"æ¯ã€‚\n"
-"[b]注:[/b] [method delay_usec]是一ç§[i]阻塞[/i]å»¶è¿Ÿä»£ç æ‰§è¡Œçš„æ–¹å¼ã€‚è¦ä»¥éžé˜»"
-"塞方å¼å»¶è¿Ÿä»£ç æ‰§è¡Œï¼Œè¯·å‚阅 [method SceneTree.create_timer]。使用 [method "
+"[b]注æ„:[/b][method delay_usec] 是一ç§[i]阻塞[/i]å»¶è¿Ÿä»£ç æ‰§è¡Œçš„æ–¹å¼ã€‚è¦ä»¥éž"
+"阻塞方å¼å»¶è¿Ÿä»£ç æ‰§è¡Œï¼Œè¯·å‚阅 [method SceneTree.create_timer]。使用 [method "
"SceneTree.create_timer] 生æˆå°†å»¶è¿Ÿä½äºŽ [code]yield[/code] 下方的代ç çš„æ‰§è¡Œï¼Œ"
"而ä¸ä¼šå½±å“项目的其余部分(或编辑器,例如 [EditorPlugin] å’Œ "
"[EditorScript])。\n"
-"[b]注æ„:[/b]当在主线程上调用[method delay_usec]时,它会冻结项目并阻止它é‡ç»˜"
-"和注册输入,直到延迟结æŸã€‚当使用 [method delay_usec] 作为 [EditorPlugin] 或 "
-"[EditorScript] 的一部分时,它会冻结编辑器但ä¸ä¼šå†»ç»“当剿­£åœ¨è¿è¡Œçš„项目(因为项"
-"目是一个独立的å­è¿›ç¨‹ï¼‰ã€‚"
+"[b]注æ„:[/b]当在主线程上调用 [method delay_usec] 时,它会冻结项目并阻止它é‡"
+"绘和注册输入,直到延迟结æŸã€‚当使用 [method delay_usec] 作为 [EditorPlugin] "
+"或 [EditorScript] 的一部分时,它会冻结编辑器但ä¸ä¼šå†»ç»“当剿­£åœ¨è¿è¡Œçš„项目(因"
+"为项目是一个独立的å­è¿›ç¨‹ï¼‰ã€‚"
#: doc/classes/OS.xml
msgid ""
"Dumps the memory allocation ringlist to a file (only works in debug).\n"
"Entry format per line: \"Address - Size - Description\"."
msgstr ""
-"将内存分é…ringlist转储到一个文件(仅在调试中工作)。\n"
-"æ¯è¡Œè¾“入格å¼:“地å€-大å°-æè¿°â€ã€‚"
+"å°†å†…å­˜åˆ†é… ringlist 转储到一个文件(仅在调试时å¯ç”¨ï¼‰ã€‚\n"
+"æ¯è¡Œæ¡ç›®æ ¼å¼ï¼šâ€œåœ°å€ - å¤§å° - æè¿°â€ã€‚"
#: doc/classes/OS.xml
msgid ""
@@ -50433,8 +50769,8 @@ msgid ""
"Entry format per line: \"Resource Type : Resource Location\".\n"
"At the end of the file is a statistic of all used Resource Types."
msgstr ""
-"将所有使用的资æºè½¬å‚¨åˆ°æ–‡ä»¶ä¸­(仅在调试中有效)。\n"
-"æ¯è¡Œè¾“入格å¼:“资æºç±»åž‹:资æºä½ç½®â€ã€‚\n"
+"将所有使用的资æºè½¬å‚¨åˆ°æ–‡ä»¶ä¸­ï¼ˆä»…在调试中有效)。\n"
+"æ¯è¡Œè¾“入格å¼ï¼šâ€œèµ„æºç±»åž‹:资æºä½ç½®â€ã€‚\n"
"在文件的末尾是所有已使用资æºç±»åž‹çš„统计数æ®ã€‚"
#: doc/classes/OS.xml
@@ -50584,6 +50920,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
"è¿”å›žä¼ é€’ç»™å¼•æ“Žçš„å‘½ä»¤è¡Œå‚æ•°ã€‚\n"
@@ -50601,6 +50941,10 @@ msgstr ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # å°†ä¸å¸¦å‚数的选项加入该字典,\n"
+" # å–值为空字符串。\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
#: doc/classes/OS.xml
@@ -50733,8 +51077,8 @@ msgid ""
"been granted to the Android application.\n"
"[b]Note:[/b] This method is implemented on Android."
msgstr ""
-"通过这个函数,你å¯ä»¥èŽ·å¾—å·²ç»æŽˆäºˆAndroid应用程åºçš„å±é™©æƒé™åˆ—表。\n"
-"[b]注æ„:[/b]这个方法在Android上实现。"
+"通过这个函数,你å¯ä»¥èŽ·å¾—å·²ç»æŽˆäºˆ Android 应用程åºçš„å±é™©æƒé™åˆ—表。\n"
+"[b]注æ„:[/b]这个方法在 Android 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -50747,7 +51091,7 @@ msgstr ""
"返回相对于组åˆå­—符串中的字符的 IME 光标ä½ç½®ï¼ˆå­—符串的当å‰ç¼–辑部分)。\n"
"[constant MainLoop.NOTIFICATION_OS_IME_UPDATE] 被å‘é€åˆ°åº”用程åºä»¥é€šçŸ¥å®ƒ IME "
"光标ä½ç½®çš„å˜åŒ–。\n"
-"[b]注:[/b]此方法在macOS上实现。"
+"[b]注æ„:[/b]此方法在 macOS 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -50759,7 +51103,7 @@ msgstr ""
"返回 IME 中间组åˆå­—符串。\n"
"[constant MainLoop.NOTIFICATION_OS_IME_UPDATE] 被å‘é€åˆ°åº”用程åºä»¥é€šçŸ¥å®ƒå¯¹ "
"IME 组åˆå­—符串的更改。\n"
-"[b]注:[/b]此方法在macOS上实现。"
+"[b]注æ„:[/b]此方法在 macOS 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -50771,7 +51115,7 @@ msgid ""
"[code]\"QWERTY\"[/code] on unsupported platforms."
msgstr ""
"将当剿‹‰ä¸é”®ç›˜å˜ä½“作为字符串返回。\n"
-"å¯èƒ½çš„返回值是: [code]\"QWERTY\"[/code], [code]\"AZERTY\"[/code], "
+"å¯èƒ½çš„返回值是:[code]\"QWERTY\"[/code],[code]\"AZERTY\"[/code],"
"[code]\"QZERTY\"[/code],[code]\"DVORAK\"[/code],[code]\"NEO\"[/code],"
"[code]\"COLEMAK\"[/code]或[code]\"错误ERROR\"[/code]。\n"
"[b]注æ„:[/b]此方法在 Linuxã€macOS å’Œ Windows 上实现。在ä¸å—支æŒçš„å¹³å°ä¸Šè¿”回 "
@@ -50803,8 +51147,8 @@ msgstr ""
"ISO_15924]æ–‡å­—ä»£ç  [/url],首字æ¯å¤§å†™ã€‚\n"
"[code]COUNTRY[/code] - å¯é€‰ï¼Œ2 个或 3 ä¸ªå­—æ¯ [url=https://en.wikipedia.org/"
"wiki/ISO_3166-1]国家地区代ç [/url],大写。\n"
-"[code]VARIANT[/code] - å¯é€‰ï¼Œè¯­è¨€å˜ä½“,地区和排åºé¡ºåºã€‚ å˜ä½“å¯ä»¥æœ‰ä»»æ„æ•°é‡çš„"
-"带下划线的关键字。\n"
+"[code]VARIANT[/code] - å¯é€‰ï¼Œè¯­è¨€å˜ä½“,地区和排åºé¡ºåºã€‚å˜ä½“å¯ä»¥æœ‰ä»»æ„æ•°é‡çš„带"
+"下划线的关键字。\n"
"[code]extra[/code] - å¯é€‰ï¼Œåˆ†å·åˆ†éš”的附加关键字列表。货å¸ã€æ—¥åŽ†ã€æŽ’åºé¡ºåºå’Œç¼–"
"å·ç³»ç»Ÿä¿¡æ¯ã€‚"
@@ -50819,8 +51163,8 @@ msgid ""
"about country code or variants. For example, for a French Canadian user with "
"[code]fr_CA[/code] locale, this would return [code]fr[/code]."
msgstr ""
-"将主机æ“作系统区域设置的 2 或 3 ä¸ªå­—æ¯ [url=https://en.wikipedia.org/wiki/"
-"List_of_ISO_639-1_codes]语言代ç [/url] 作为字符串返回,该字符串应在所有平å°ä¸Š"
+"将主机æ“作系统区域设置的 2 或 3 个字æ¯çš„[url=https://en.wikipedia.org/wiki/"
+"List_of_ISO_639-1_codes]语言代ç [/url]作为字符串返回,该字符串应在所有平å°ä¸Š"
"ä¿æŒä¸€è‡´ã€‚这相当于æå– [method get_locale] 字符串的 [code]language[/code] 部"
"分。\n"
"当您ä¸éœ€è¦æœ‰å…³å›½å®¶/åœ°åŒºä»£ç æˆ–å˜ä½“çš„é™„åŠ ä¿¡æ¯æ—¶ï¼Œè¿™å¯ç”¨äºŽå°†å®Œå…¨æŒ‡å®šçš„区域设置字"
@@ -50853,10 +51197,9 @@ msgid ""
"[code]\"Server\"[/code], [code]\"Windows\"[/code], [code]\"UWP\"[/code], "
"[code]\"X11\"[/code]."
msgstr ""
-"返回主机æ“作系统的å称。å¯èƒ½çš„值有: [code]\"Android\"[/code], "
-"[code]\"iOS\"[/code], [code]\"HTML5\"[/code], [code]\"OSX\"[/code], "
-"[code]\"Server\"[/code], [code]\"Windows\"[/code], [code]\"UWP\"[/code], "
-"[code]\"X11\"[/code]."
+"返回主机æ“作系统的å称。å¯èƒ½çš„值有:[code]\"Android\"[/code], [code]\"iOS\"[/"
+"code], [code]\"HTML5\"[/code], [code]\"OSX\"[/code], [code]\"Server\"[/"
+"code], [code]\"Windows\"[/code], [code]\"UWP\"[/code], [code]\"X11\"[/code]."
#: doc/classes/OS.xml
msgid ""
@@ -50864,8 +51207,8 @@ msgid ""
"[b]Note:[/b] This method is implemented on Linux and Windows (other OSs will "
"soon be supported)."
msgstr ""
-"返回内部结构指针,以便在GDNativeæ’件中使用。\n"
-"[b]注æ„:[/b]此方法在Linuxå’ŒWindows上实现(其他æ“作系统将很快被支æŒï¼‰ã€‚"
+"返回内部结构指针,以便在 GDNative æ’件中使用。\n"
+"[b]注æ„:[/b]这个方法在 Linux å’Œ Windows 上实现(其他æ“作系统将很快被支æŒï¼‰ã€‚"
#: doc/classes/OS.xml
msgid ""
@@ -50875,7 +51218,7 @@ msgid ""
msgstr ""
"以百分比形å¼è¿”回设备中剩余的电池电é‡ã€‚如果电æºçŠ¶æ€æœªçŸ¥ï¼Œåˆ™è¿”回 [code]-1[/"
"code]。\n"
-"[b]注æ„:[/b]该方法在Linuxã€macOSå’ŒWindows上实现。"
+"[b]注æ„:[/b]这个方法在 Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -50885,7 +51228,7 @@ msgid ""
msgstr ""
"返回设备耗尽电池å‰å‡ ç§’钟内剩余时间的估计值。如果电æºçŠ¶æ€æœªçŸ¥ï¼Œåˆ™è¿”回 "
"[code]-1[/code]。\n"
-"[b]注æ„:[/b]此方法在 Linuxã€macOS å’Œ Windows 上实现。"
+"[b]注æ„:[/b]这个方法在 Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -50893,8 +51236,8 @@ msgid ""
"[enum PowerState] constants.\n"
"[b]Note:[/b] This method is implemented on Linux, macOS and Windows."
msgstr ""
-"返回设备关于电池和电æºçš„当å‰çжæ€ã€‚请å‚阅 [enum PowerState] 常é‡ã€‚\n"
-"[b]注æ„:[/b]该方法在Linuxã€macOSå’ŒWindows上实现。"
+"返回设备关于电池和电æºçš„当å‰çжæ€ã€‚è§ [enum PowerState] 常é‡ã€‚\n"
+"[b]注æ„:[/b]这个方法在 Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -50903,7 +51246,7 @@ msgid ""
"Windows."
msgstr ""
"返回项目的进程 ID。\n"
-"[b]注æ„:[/b]此方法在Androidã€iOSã€Linuxã€macOSå’ŒWindows上实现。"
+"[b]注æ„:[/b]这个方法在 Androidã€iOSã€Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -50990,8 +51333,8 @@ msgid ""
"[b]Note:[/b] This method is implemented on macOS."
msgstr ""
"返回最大的å±å¹•的缩放。\n"
-"[b]注:[/b] 在macOS上,如果系统中至少有一个hiDPI(Retina)å±å¹•,则返回值为"
-"[code]2.0[/code],其他情况为[code]1.0[/code]。\n"
+"[b]注æ„:[/b]在 macOS 上,如果系统中至少有一个 hiDPI(Retina)å±å¹•,则返回值"
+"为 [code]2.0[/code],其他情况为 [code]1.0[/code]。\n"
"[b]注æ„:[/b]此方法仅在macOS上实现。"
#: doc/classes/OS.xml
@@ -51118,7 +51461,7 @@ msgid ""
"application restarts."
msgstr ""
"返回当å‰çº¿ç¨‹çš„ ID。这å¯ç”¨äºŽæ—¥å¿—,以简化多线程应用程åºçš„调试。\n"
-"[b]注:[/b] 线程 ID 䏿˜¯ç¡®å®šçš„,也许会在应用程åºé‡æ–°å¯åŠ¨æ—¶è¢«é‡å¤ä½¿ç”¨ã€‚"
+"[b]注æ„:[/b] 线程 ID 䏿˜¯ç¡®å®šçš„,也许会在应用程åºé‡æ–°å¯åŠ¨æ—¶è¢«é‡å¤ä½¿ç”¨ã€‚"
#: doc/classes/OS.xml
msgid ""
@@ -51147,7 +51490,7 @@ msgstr ""
#: doc/classes/OS.xml
msgid ""
"Returns the current time zone as a dictionary with the keys: bias and name."
-msgstr "以字典形å¼è¿”å›žå½“å‰æ—¶åŒºï¼Œé”®ä¸ºï¼šbiaså’Œname。"
+msgstr "以字典形å¼è¿”å›žå½“å‰æ—¶åŒºï¼Œé”®ä¸ºï¼šbias å’Œ name。"
#: doc/classes/OS.xml
msgid ""
@@ -51179,8 +51522,8 @@ msgid ""
"decrease)."
msgstr ""
"以秒为å•ä½è¿”回当å‰çš„ UNIX 纪元时间戳。\n"
-"[b]é‡è¦ï¼š[/b] 这是用户å¯ä»¥æ‰‹åŠ¨è®¾ç½®çš„ç³»ç»Ÿæ—¶é’Ÿã€‚ [b]永远ä¸è¦ä½¿ç”¨[/b]è¿™ç§æ–¹æ³•è¿›"
-"行精确的时间计算,因为它的结果也会å—到æ“作系统的自动调整。 [b]始终使用[/b] "
+"[b]é‡è¦ï¼š[/b]这是用户å¯ä»¥æ‰‹åŠ¨è®¾ç½®çš„ç³»ç»Ÿæ—¶é’Ÿã€‚[b]永远ä¸è¦ä½¿ç”¨[/b]è¿™ç§æ–¹æ³•进行"
+"精确的时间计算,因为它的结果也会å—到æ“作系统的自动调整。[b]始终使用[/b] "
"[method get_ticks_usec] 或 [method get_ticks_msec] 进行精确时间计算,因为它们"
"ä¿è¯æ˜¯å•è°ƒçš„ï¼ˆå³æ°¸ä¸å‡å°‘)。"
@@ -51275,7 +51618,7 @@ msgid ""
msgstr ""
"将带有文本“标签â€çš„æ–°é¡¹ç›®æ·»åŠ åˆ°å…¨å±€èœå•。使用“_dockâ€èœå•将项目添加到 macOS åœ"
"é æ å›¾æ ‡èœå•。\n"
-"[b]注:[/b]此方法在macOS上实现。"
+"[b]注æ„:[/b]此方法在 macOS 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51478,7 +51821,7 @@ msgid ""
"[b]Note:[/b] This method is implemented on Linux, macOS and Windows."
msgstr ""
"设置活动键盘布局。\n"
-"[b]注:[/b]此方法å¯åœ¨Linuxã€macOSå’ŒWindows上实现。"
+"[b]注æ„:[/b]此方法在 Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51533,7 +51876,7 @@ msgid ""
"[b]Note:[/b] This method is only implemented on iOS."
msgstr ""
"如果本地视频正在播放,返回 [code]true[/code]。\n"
-"[b]注æ„:[/b]这个方法åªåœ¨iOS上实现。"
+"[b]注æ„:[/b]这个方法åªåœ¨ iOS 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51541,7 +51884,7 @@ msgid ""
"[b]Note:[/b] This method is only implemented on iOS."
msgstr ""
"æš‚åœæœ¬åœ°è§†é¢‘播放。\n"
-"[b]注æ„:[/b]这个方法åªåœ¨iOS上实现。"
+"[b]注æ„:[/b]这个方法åªåœ¨ iOS 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51550,7 +51893,7 @@ msgid ""
"[b]Note:[/b] This method is only implemented on iOS."
msgstr ""
"以给定的音é‡ã€éŸ³é¢‘å’Œå­—å¹•è½¨é“æ’­æ”¾æ¥è‡ªæŒ‡å®šè·¯å¾„的本地视频。\n"
-"[b]注æ„:[/b]这个方法åªåœ¨iOS上实现。"
+"[b]注æ„:[/b]这个方法åªåœ¨ iOS 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51558,7 +51901,7 @@ msgid ""
"[b]Note:[/b] This method is implemented on iOS."
msgstr ""
"åœæ­¢æœ¬åœ°è§†é¢‘播放。\n"
-"[b]注æ„:[/b]这个方法在iOS上实现。"
+"[b]注æ„:[/b]这个方法在 iOS 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51566,7 +51909,7 @@ msgid ""
"[b]Note:[/b] This method is implemented on iOS."
msgstr ""
"æ¢å¤æœ¬åœ°è§†é¢‘播放。\n"
-"[b]注æ„:[/b]这个方法在iOS上实现。"
+"[b]注æ„:[/b]这个方法在 iOS 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51581,8 +51924,8 @@ msgid ""
"Shows all resources in the game. Optionally, the list can be written to a "
"file by specifying a file path in [code]tofile[/code]."
msgstr ""
-"显示游æˆä¸­çš„æ‰€æœ‰èµ„æºã€‚也å¯ä»¥é€šè¿‡åœ¨[code]tofile[/code]中指定文件路径将该列表写"
-"入文件。"
+"显示游æˆä¸­çš„æ‰€æœ‰èµ„æºã€‚也å¯ä»¥é€šè¿‡åœ¨ [code]tofile[/code] 中指定文件路径将该列表"
+"写入文件。"
#: doc/classes/OS.xml
msgid "Shows the list of loaded textures sorted by size in memory."
@@ -51602,16 +51945,17 @@ msgid ""
"Windows or bounce the dock icon on OSX.\n"
"[b]Note:[/b] This method is implemented on Linux, macOS and Windows."
msgstr ""
-"è¦æ±‚用户注æ„该窗å£ã€‚它会在Windows上闪çƒä»»åŠ¡æ æŒ‰é’®ï¼Œæˆ–在OSX上弹出Dock图标。\n"
-"[b]注æ„:[/b]这个方法在Linuxã€macOSå’ŒWindows上实现。"
+"è¦æ±‚用户注æ„该窗å£ã€‚它会在 Windows 上闪çƒä»»åŠ¡æ æŒ‰é’®ï¼Œæˆ–在 OSX 上让 Dock 图标"
+"弹跳。\n"
+"[b]注æ„:[/b]这个方法在 Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
"At the moment this function is only used by [code]AudioDriverOpenSL[/code] "
"to request permission for [code]RECORD_AUDIO[/code] on Android."
msgstr ""
-"ç›®å‰ï¼Œè¿™ä¸ªå‡½æ•°åªè¢«[code]AudioDriverOpenSL[/code]用æ¥è¯·æ±‚Android上"
-"[code]RECORD_AUDIO[/code]çš„æƒé™ã€‚"
+"ç›®å‰ï¼Œè¿™ä¸ªå‡½æ•°åªè¢« [code]AudioDriverOpenSL[/code] 用æ¥è¯·æ±‚ Android 上 "
+"[code]RECORD_AUDIO[/code] çš„æƒé™ã€‚"
#: doc/classes/OS.xml
msgid ""
@@ -51620,9 +51964,9 @@ msgid ""
"applications.\n"
"[b]Note:[/b] This method is implemented on Android."
msgstr ""
-"通过这个功能,你å¯ä»¥ç”³è¯·å±é™©çš„æƒé™ï¼Œå› ä¸ºåœ¨Android应用程åºä¸­ï¼Œæ­£å¸¸çš„æƒé™ä¼šåœ¨å®‰"
+"ä½ å¯ä»¥é€šè¿‡è¿™ä¸ªå‡½æ•°ç”³è¯·å±é™©çš„æƒé™ï¼Œå› ä¸ºåœ¨ Android 应用程åºä¸­ï¼Œæ­£å¸¸çš„æƒé™ä¼šåœ¨å®‰"
"装时自动授予。\n"
-"[b]注æ„:[/b]此方法在Android上实现。"
+"[b]注æ„:[/b]这个方法在 Android 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51669,15 +52013,15 @@ msgstr ""
"应用程åºå¯ä»¥é€šè¿‡ä½¿ç”¨ [method get_ime_selection] å’Œ [method get_ime_text] 函数"
"æ¥æ£€ç´¢ç»„åˆçжæ€ã€‚\n"
"è¾“å…¥å®Œæˆæ—¶æäº¤å®Œæˆçš„组åˆå­—符串。\n"
-"[b]注æ„:[/b]该方法在 Linuxã€macOS å’Œ Windows 上实现。"
+"[b]注æ„:[/b]这个方法在 Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
"Sets position of IME suggestion list popup (in window coordinates).\n"
"[b]Note:[/b] This method is implemented on Linux, macOS and Windows."
msgstr ""
-"设置 IME 建议列表弹出窗å£çš„ä½ç½®ï¼ˆåœ¨çª—å£å标中)。\n"
-"[b]注æ„:[/b]此方法在 Linuxã€macOS å’Œ Windows 上实现。"
+"设置 IME 建议列表弹出窗å£çš„ä½ç½®ï¼ˆä½¿ç”¨çª—å£å标)。\n"
+"[b]注æ„:[/b]这个方法在 Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51690,7 +52034,7 @@ msgstr ""
"使用多尺寸平å°ç‰¹å®šå›¾æ ‡æ–‡ä»¶è®¾ç½®æ¸¸æˆçš„图标(在 Windows 上是 [code]*.ico[/"
"code],在 macOS 上是 [code]*.icns[/code])。\n"
"适当的大å°å­å›¾æ ‡ç”¨äºŽçª—壿 ‡é¢˜ã€ä»»åŠ¡æ /程åºåžå’Œçª—å£é€‰æ‹©å¯¹è¯æ¡†ã€‚\n"
-"[b]注æ„:[/b]此方法在 macOS å’Œ Windows 上实现。"
+"[b]注æ„:[/b]这个方法在 macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid "Sets the name of the current thread."
@@ -51698,7 +52042,7 @@ msgstr "设置当å‰çº¿ç¨‹çš„å称。"
#: doc/classes/OS.xml
msgid "Enables backup saves if [code]enabled[/code] is [code]true[/code]."
-msgstr "如果[code]enabled[/code]为 [code]true[/code],则å¯ç”¨å¤‡ä»½ä¿å­˜ã€‚"
+msgstr "如果 [code]enabled[/code] 为 [code]true[/code],则å¯ç”¨å¤‡ä»½ä¿å­˜ã€‚"
#: doc/classes/OS.xml
msgid ""
@@ -51706,7 +52050,7 @@ msgid ""
"[b]Note:[/b] This method is implemented on Linux, macOS and Windows."
msgstr ""
"è®¾ç½®çª—å£æ˜¯å¦åº”始终ä½äºŽé¡¶éƒ¨ã€‚\n"
-"[b]注æ„:[/b]该方法在 Linuxã€macOS å’Œ Windows 上实现。"
+"[b]注æ„:[/b]这个方法在 Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51731,18 +52075,18 @@ msgstr ""
"设置窗å£çš„一个接å—鼠标事件的多边形区域。该区域外的鼠标事件将被传递出去。\n"
"传递一个空数组将ç¦ç”¨ç©¿é€æ”¯æŒï¼ˆæ‰€æœ‰é¼ æ ‡äº‹ä»¶å°†è¢«çª—壿‹¦æˆªï¼Œè¿™æ˜¯é»˜è®¤è¡Œä¸ºï¼‰ã€‚\n"
"[codeblock]\n"
-"# 设置区域,使用Path2D节点。\n"
-"OS.set_window_mouse_passthrough($Path2D.curve.get_baked_points() )\n"
+"# 设置区域,使用 Path2D 节点。\n"
+"OS.set_window_mouse_passthrough($Path2D.curve.get_baked_points())\n"
"\n"
-"# 设置区域,使用Polygon2D节点。\n"
+"# 设置区域,使用 Polygon2D 节点。\n"
"OS.set_window_mouse_passthrough($Polygon2D.polygon)\n"
"\n"
"# é‡ç½®åŒºåŸŸä¸ºé»˜è®¤å€¼ã€‚\n"
-"OS.set_window_mouse_passthrough([] )\n"
+"OS.set_window_mouse_passthrough([])\n"
"[/codeblock]\n"
-"[b]注æ„:[/b]在Windows上,ä½äºŽåŒºåŸŸå¤–的窗å£éƒ¨åˆ†ä¸ä¼šè¢«ç»˜åˆ¶ï¼Œè€Œåœ¨Linuxå’ŒmacOS上"
-"则会。\n"
-"[b]注æ„:[/b]这个方法在Linuxã€macOSå’ŒWindows上实现。"
+"[b]注æ„:[/b]在 Windows 上,ä½äºŽåŒºåŸŸå¤–的窗å£éƒ¨åˆ†ä¸ä¼šè¢«ç»˜åˆ¶ï¼Œè€Œåœ¨ Linux å’Œ "
+"macOS 上则会。\n"
+"[b]注æ„:[/b]这个方法在 Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51754,7 +52098,7 @@ msgstr ""
"å°†çª—å£æ ‡é¢˜è®¾ç½®ä¸ºæŒ‡å®šçš„字符串。\n"
"[b]注æ„:[/b]应该å¶å°”使用,ä¸è¦æ¯å¸§éƒ½è®¾ç½®ï¼Œå› ä¸ºè¿™ä¼šå¯¹æŸäº›çª—å£ç®¡ç†å™¨çš„æ€§èƒ½äº§ç”Ÿ"
"è´Ÿé¢å½±å“。\n"
-"[b]注æ„:[/b]该方法在 HTML5ã€Linuxã€macOS å’Œ Windows 上实现。"
+"[b]注æ„:[/b]这个方法在 HTML5ã€Linuxã€macOS å’Œ Windows 上实现。"
#: doc/classes/OS.xml
msgid ""
@@ -51785,7 +52129,7 @@ msgstr ""
"[code]mailto[/code] URL 方案[/url]。\n"
"å¯ä»¥ä½¿ç”¨ [method ProjectSettings.globalize_path] å°† [code]res://[/code] å’Œ "
"[code]user://[/code] 路径转æ¢ä¸ºæœ¬æ–¹æ³•所使用的系统路径。\n"
-"[b]注æ„:[/b]本方法在 Androidã€iOSã€HTML5ã€Linuxã€macOSã€ä»¥åŠ Windows 上实"
+"[b]注æ„:[/b]这个方法在 Androidã€iOSã€HTML5ã€Linuxã€macOSã€ä»¥åŠ Windows 上实"
"现。"
#: doc/classes/OS.xml
@@ -51805,7 +52149,7 @@ msgstr ""
"测)。\n"
"éœ€è¦æŠŠ [code]multiline[/code] 傿•°è®¾ç½®ä¸º [code]true[/code] æ‰èƒ½è¾“入多行文本,"
"如在 [TextEdit] 中。\n"
-"[b]注æ„:[/b]此方法在 Androidã€iOS å’Œ UWP 上实现。"
+"[b]注æ„:[/b]这个方法在 Androidã€iOS å’Œ UWP 上实现。"
#: doc/classes/OS.xml
msgid "The clipboard from the host OS. Might be unavailable on some platforms."
@@ -51821,7 +52165,7 @@ msgid ""
"each frame, and attempts to compensate for random variation. This will only "
"operate on systems where V-Sync is active."
msgstr ""
-"如果 [code]true[/code],引擎会过滤æ¯å¸§ä¹‹é—´æµ‹é‡çš„æ—¶é—´å¢žé‡ï¼Œå¹¶å°è¯•è¡¥å¿éšæœºå˜"
+"如果为 [code]true[/code],引擎会过滤æ¯å¸§ä¹‹é—´æµ‹é‡çš„æ—¶é—´å¢žé‡ï¼Œå¹¶å°è¯•è¡¥å¿éšæœºå˜"
"化。这åªä¼šåœ¨åž‚ç›´åŒæ­¥å¤„于活动状æ€çš„系统上è¿è¡Œã€‚"
#: doc/classes/OS.xml
@@ -51908,8 +52252,8 @@ msgid ""
"framerate halving (e.g. from 60 FPS to 30 FPS) when using it.\n"
"[b]Note:[/b] This property is only implemented on Windows."
msgstr ""
-"为 [code]true[/code] 时,如果 [code]vsync_enabled[/code] 为真,当æ“作系统的窗"
-"å£åˆæˆå™¨è¢«å¯ç”¨å¹¶ä¸”游æˆå¤„äºŽçª—å£æ¨¡å¼æ—¶ï¼Œå°†ä½¿ç”¨è¯¥åˆæˆå™¨è¿›è¡Œåž‚ç›´åŒæ­¥ã€‚\n"
+"如果为 [code]true[/code] 且 [code]vsync_enabled[/code] 为真,当æ“作系统的窗å£"
+"åˆæˆå™¨è¢«å¯ç”¨å¹¶ä¸”游æˆå¤„äºŽçª—å£æ¨¡å¼æ—¶ï¼Œå°†ä½¿ç”¨è¯¥åˆæˆå™¨è¿›è¡Œåž‚ç›´åŒæ­¥ã€‚\n"
"[b]注æ„:[/b]此选项是实验性的,旨在缓解æŸäº›ç”¨æˆ·é‡åˆ°çš„å¡é¡¿ã€‚但是,一些用户在使"
"用时é‡åˆ°äº† Vsync 帧率å‡åŠï¼Œä¾‹å¦‚从 60 FPS 到 30 FPS。\n"
"[b]注æ„:[/b]此属性仅在 Windows 上实现。"
@@ -52117,34 +52461,34 @@ msgid ""
"- Linux: [code]X11::GLXContext[/code]\n"
"- MacOS: [code]NSOpenGLContext*[/code] (not yet implemented)"
msgstr ""
-"OpenGL上下文:\n"
+"OpenGL 上下文:\n"
"- Windows:[code]HGLRC[/code]\n"
"- Linux:[code]X11::GLXContext[/code]\n"
-"- MacOS:[code]NSOpenGLContext*[/code] (尚未实现)"
+"- MacOS:[code]NSOpenGLContext*[/code](尚未实现)"
#: doc/classes/OS.xml
msgid "Landscape screen orientation."
-msgstr "横å‘å±å¹•æ–¹å‘。"
+msgstr "æ¨ªå±æ–¹å‘。"
#: doc/classes/OS.xml
msgid "Portrait screen orientation."
-msgstr "纵å‘å±å¹•æ–¹å‘。"
+msgstr "ç«–å±æ–¹å‘。"
#: doc/classes/OS.xml
msgid "Reverse landscape screen orientation."
-msgstr "å转横å‘å±å¹•æ–¹å‘。"
+msgstr "å€’æ¨ªå±æ–¹å‘。"
#: doc/classes/OS.xml
msgid "Reverse portrait screen orientation."
-msgstr "å转纵å‘å±å¹•æ–¹å‘。"
+msgstr "å€’ç«–å±æ–¹å‘。"
#: doc/classes/OS.xml
msgid "Uses landscape or reverse landscape based on the hardware sensor."
-msgstr "æ ¹æ®ç¡¬ä»¶ä¼ æ„Ÿå™¨ä½¿ç”¨æ¨ªå‘或å呿¨ªå‘。"
+msgstr "æ ¹æ®ç¡¬ä»¶ä¼ æ„Ÿå™¨ä½¿ç”¨æ¨ªå±æˆ–å€’æ¨ªå±æ–¹å‘。"
#: doc/classes/OS.xml
msgid "Uses portrait or reverse portrait based on the hardware sensor."
-msgstr "æ ¹æ®ç¡¬ä»¶ä¼ æ„Ÿå™¨ä½¿ç”¨çºµå‘或åå‘纵å‘。"
+msgstr "æ ¹æ®ç¡¬ä»¶ä¼ æ„Ÿå™¨ä½¿ç”¨ç«–屿ˆ–倒竖å±ã€‚"
#: doc/classes/OS.xml
msgid "Uses most suitable orientation based on the hardware sensor."
@@ -52208,7 +52552,7 @@ msgstr "[PackedDataContainer] 的引用版本。"
#: doc/classes/PackedScene.xml
msgid "An abstraction of a serialized scene."
-msgstr "一个åºåˆ—化场景的抽象。"
+msgstr "对åºåˆ—化场景的抽象。"
#: doc/classes/PackedScene.xml
msgid ""
@@ -52336,7 +52680,7 @@ msgstr ""
#: doc/classes/PackedScene.xml
msgid "If passed to [method instance], blocks edits to the scene state."
-msgstr "如果传递给[method instance],则阻止对场景状æ€çš„编辑。"
+msgstr "如果传递给 [method instance],则阻止对场景状æ€çš„编辑。"
#: doc/classes/PackedScene.xml
msgid ""
@@ -52355,7 +52699,7 @@ msgid ""
msgstr ""
"如果传递给 [method instance]ï¼Œå‘æœ¬åœ°åœºæ™¯æä¾›æœ¬åœ°åœºæ™¯èµ„æºã€‚åªæœ‰ä¸»åœºæ™¯åº”该接收"
"主编辑状æ€ã€‚\n"
-"[b]注æ„:[/b]åªåœ¨ç¼–辑器构建中å¯ç”¨ã€‚"
+"[b]注æ„:[/b]仅在编辑器构建中å¯ç”¨ã€‚"
#: doc/classes/PackedScene.xml
msgid ""
@@ -52390,9 +52734,9 @@ msgid ""
"without having to encode data as low-level bytes or having to worry about "
"network ordering."
msgstr ""
-"PacketPeer是基于数æ®åŒ…çš„å议(如UDP)的抽象和基类。它æä¾›äº†ä¸€ä¸ªAPI,用于å‘é€"
-"å’ŒæŽ¥æ”¶ä½œä¸ºåŽŸå§‹æ•°æ®æˆ–å˜é‡çš„æ•°æ®åŒ…。这使得通过å议传输数æ®å˜å¾—很容易,而ä¸å¿…å°†"
-"æ•°æ®ç¼–ç ä¸ºä½Žçº§å­—节或担心网络顺åºã€‚"
+"PacketPeer 是基于数æ®åŒ…çš„å议(如 UDP)的抽象和基类。它æä¾›äº†ä¸€ä¸ª API,用于å‘"
+"é€å’ŒæŽ¥æ”¶ä½œä¸ºåŽŸå§‹æ•°æ®æˆ–å˜é‡çš„æ•°æ®åŒ…。这使得通过å议传输数æ®å˜å¾—很容易,而ä¸å¿…"
+"将数æ®ç¼–ç ä¸ºä½Žçº§å­—节或担心网络顺åºã€‚"
#: doc/classes/PacketPeer.xml
msgid "Returns the number of packets currently available in the ring-buffer."
@@ -52407,7 +52751,8 @@ msgid ""
"Returns the error state of the last packet received (via [method get_packet] "
"and [method get_var])."
msgstr ""
-"è¿”å›žæœ€åŽæŽ¥æ”¶çš„æ•°æ®åŒ…的错误状æ€ï¼ˆé€šè¿‡[method get_packet]å’Œ[method get_var])。"
+"è¿”å›žæœ€åŽæŽ¥æ”¶çš„æ•°æ®åŒ…的错误状æ€ï¼ˆé€šè¿‡ [method get_packet] å’Œ [method "
+"get_var])。"
#: doc/classes/PacketPeer.xml
msgid ""
@@ -52417,8 +52762,8 @@ msgid ""
"Do not use this option if the serialized object comes from untrusted sources "
"to avoid potential security threats such as remote code execution."
msgstr ""
-"获å–一个å˜é‡ã€‚如果[code]allow_objects[/code] 或 [member "
-"allow_object_decoding]为 [code]true[/code],则å…许对对象进行解ç ã€‚\n"
+"获å–一个å˜é‡ã€‚如果 [code]allow_objects[/code] 或 [member "
+"allow_object_decoding] 为 [code]true[/code],则å…许对对象进行解ç ã€‚\n"
"[b]警告:[/b]ååºåˆ—化对象å¯èƒ½åŒ…嫿‰§è¡Œçš„代ç ã€‚如果åºåˆ—化对象æ¥è‡ªä¸å—信任的æºï¼Œ"
"请ä¸è¦ä½¿ç”¨æ­¤é€‰é¡¹ï¼Œä»¥é¿å…潜在的安全å¨èƒï¼Œå¦‚è¿œç¨‹ä»£ç æ‰§è¡Œã€‚"
@@ -52432,8 +52777,8 @@ msgid ""
"allow_object_decoding]) is [code]true[/code], encoding objects is allowed "
"(and can potentially include code)."
msgstr ""
-"å°†[Variant]作为数æ®åŒ…å‘é€ã€‚如果[code]full_objects[/code] 或 [member "
-"allow_object_decoding]为 [code]true[/code],则å…许对对象进行编ç ï¼ˆå¹¶ä¸”å¯èƒ½åŒ…"
+"å°† [Variant] 作为数æ®åŒ…å‘é€ã€‚如果 [code]full_objects[/code] 或 [member "
+"allow_object_decoding] 为 [code]true[/code],则å…许对对象进行编ç ï¼ˆå¹¶ä¸”å¯èƒ½åŒ…"
"å«ä»£ç ï¼‰ã€‚"
#: doc/classes/PacketPeer.xml
@@ -52446,10 +52791,10 @@ msgid ""
"Do not use this option if the serialized object comes from untrusted sources "
"to avoid potential security threats such as remote code execution."
msgstr ""
-"[i]已废弃。[/i] 你应该使用 [code]get_var[/code] å’Œ [code]put_var[/code] 傿•°"
-"æ¥ä»£æ›¿å®ƒã€‚\n"
-"如果[code]true[/code],多人游æˆAPIå°†å…许在RPC/RSETs期间对对象进行编ç å’Œè§£"
-"ç ã€‚\n"
+"[i]已废弃。[/i]你应该使用 [code]get_var[/code] å’Œ [code]put_var[/code] 傿•°æ¥"
+"代替它。\n"
+"如果为 [code]true[/code]ï¼Œå¤šäººæ¸¸æˆ API å°†å…许在 RPC/RSET 期间对对象进行编ç å’Œ"
+"è§£ç ã€‚\n"
"[b]警告:[/b]ååºåˆ—化的对象å¯èƒ½åŒ…å«ä¼šè¢«æ‰§è¡Œçš„代ç ã€‚如果åºåˆ—化的对象æ¥è‡ªä¸å—ä¿¡"
"ä»»çš„æ¥æºï¼Œè¯·ä¸è¦ä½¿ç”¨è¿™ä¸ªé€‰é¡¹ï¼Œä»¥é¿å…潜在的安全å¨èƒï¼Œå¦‚è¿œç¨‹ä»£ç æ‰§è¡Œã€‚"
@@ -52463,14 +52808,15 @@ msgid ""
"[code]encode_buffer_max_size[/code], the method will error out with "
"[constant ERR_OUT_OF_MEMORY]."
msgstr ""
-"ç¼–ç [Variant]æ—¶å…许的最大缓冲区大å°ã€‚æé«˜æ­¤å€¼ä»¥æ”¯æŒæ›´å¤§çš„内存分é…。\n"
-"[method put_var]方法在堆栈上分é…内存,使用的缓冲区将自动增长到最接近的二次"
-"方,以匹é…[Variant]的大å°ã€‚如果[Variant]大于 [code]encode_buffer_max_size[/"
-"code],则该方法将以[constant ERR_OUT_OF_MEMORY]出错。"
+"ç¼–ç  [Variant] æ—¶å…许的最大缓冲区大å°ã€‚æé«˜æ­¤å€¼ä»¥æ”¯æŒæ›´å¤§çš„内存分é…。\n"
+"[method put_var] 方法在堆栈上分é…内存,使用的缓冲区将自动增长到最接近的二次"
+"æ–¹ï¼Œä»¥åŒ¹é… [Variant] 的大å°ã€‚如果 [Variant] 大于 "
+"[code]encode_buffer_max_size[/code],则该方法将以 [constant "
+"ERR_OUT_OF_MEMORY] 出错。"
#: doc/classes/PacketPeerDTLS.xml
msgid "DTLS packet peer."
-msgstr "DTLSæ•°æ®åŒ…客户端。"
+msgstr "DTLS æ•°æ®åŒ…客户端。"
#: doc/classes/PacketPeerDTLS.xml
msgid ""
@@ -52497,19 +52843,19 @@ msgid ""
"argument. You can specify a custom [X509Certificate] to use for validation "
"via the [code]valid_certificate[/code] argument."
msgstr ""
-"使用必须连接的底层[PacketPeerUDP](è§[method PacketPeerUDP.connect_to_host])"
-"连接一个[code]peer[/code],开始DTLSæ¡æ‰‹è¿‡ç¨‹ã€‚如果[code]validate_certs[/code]"
-"是[code]true[/code],[PacketPeerDTLS]将验è¯è¿œç¨‹å¯¹ç­‰ä½“æäº¤çš„è¯ä¹¦å¹¶ä¸Ž"
-"[code]for_hostname[/code]傿•°åŒ¹é…。你å¯ä»¥é€šè¿‡[code]valid_certificate[/code]å‚"
-"数指定一个自定义的[X509Certificate]æ¥è¿›è¡ŒéªŒè¯ã€‚"
+"使用必须连接的底层 [PacketPeerUDP]ï¼ˆè§ [method PacketPeerUDP."
+"connect_to_host])连接一个 [code]peer[/code],开始 DTLS æ¡æ‰‹è¿‡ç¨‹ã€‚如果 "
+"[code]validate_certs[/code] 为 [code]true[/code],[PacketPeerDTLS] 将验è¯è¿œç¨‹"
+"对等体æäº¤çš„è¯ä¹¦å¹¶ä¸Ž [code]for_hostname[/code] 傿•°åŒ¹é…。你å¯ä»¥é€šè¿‡ "
+"[code]valid_certificate[/code] 傿•°æŒ‡å®šç”¨äºŽéªŒè¯çš„自定义 [X509Certificate]。"
#: doc/classes/PacketPeerDTLS.xml
msgid "Disconnects this peer, terminating the DTLS session."
-msgstr "断开此对等体的连接,终止DTLS会è¯ã€‚"
+msgstr "断开此对等体的连接,终止 DTLS 会è¯ã€‚"
#: doc/classes/PacketPeerDTLS.xml doc/classes/StreamPeerSSL.xml
msgid "Returns the status of the connection. See [enum Status] for values."
-msgstr "返回连接的状æ€ã€‚有关值,请å‚阅[enum Status]。"
+msgstr "返回连接的状æ€ã€‚å–å€¼è§ [enum Status]。"
#: doc/classes/PacketPeerDTLS.xml
msgid ""
@@ -52520,32 +52866,32 @@ msgstr ""
#: doc/classes/PacketPeerDTLS.xml
msgid "A status representing a [PacketPeerDTLS] that is disconnected."
-msgstr "表示已断开连接的[PacketPeerDTLS]的状æ€ã€‚"
+msgstr "表示已断开连接的 [PacketPeerDTLS] 的状æ€ã€‚"
#: doc/classes/PacketPeerDTLS.xml
msgid ""
"A status representing a [PacketPeerDTLS] that is currently performing the "
"handshake with a remote peer."
-msgstr "è¡¨ç¤ºå½“å‰æ­£åœ¨ä¸Žè¿œç¨‹å¯¹ç­‰æ–¹è¿›è¡Œæ¡æ‰‹çš„[PacketPeerDTLS]的状æ€ã€‚"
+msgstr "è¡¨ç¤ºå½“å‰æ­£åœ¨ä¸Žè¿œç¨‹å¯¹ç­‰æ–¹è¿›è¡Œæ¡æ‰‹çš„ [PacketPeerDTLS] 的状æ€ã€‚"
#: doc/classes/PacketPeerDTLS.xml
msgid ""
"A status representing a [PacketPeerDTLS] that is connected to a remote peer."
-msgstr "表示连接到远程对等方的[PacketPeerDTLS]的状æ€ã€‚"
+msgstr "表示连接到远程对等方的 [PacketPeerDTLS] 的状æ€ã€‚"
#: doc/classes/PacketPeerDTLS.xml
msgid "A status representing a [PacketPeerDTLS] in a generic error state."
-msgstr "表示处于一般错误状æ€çš„[PacketPeerDTLS]的状æ€ã€‚"
+msgstr "表示处于一般错误状æ€çš„ [PacketPeerDTLS] 的状æ€ã€‚"
#: doc/classes/PacketPeerDTLS.xml
msgid ""
"An error status that shows a mismatch in the DTLS certificate domain "
"presented by the host and the domain requested for validation."
-msgstr "显示主机æä¾›çš„DTLSè¯ä¹¦åŸŸä¸Žè¯·æ±‚验è¯çš„域ä¸åŒ¹é…的错误状æ€ã€‚"
+msgstr "显示主机æä¾›çš„ DTLS è¯ä¹¦åŸŸä¸Žè¯·æ±‚验è¯çš„域ä¸åŒ¹é…的错误状æ€ã€‚"
#: doc/classes/PacketPeerStream.xml
msgid "Wrapper to use a PacketPeer over a StreamPeer."
-msgstr "在StreamPeer上使用PacketPeer的包装器。"
+msgstr "在 StreamPeer 上使用 PacketPeer 的包装器。"
#: doc/classes/PacketPeerStream.xml
msgid ""
@@ -52554,26 +52900,26 @@ msgid ""
"implements a custom protocol over the StreamPeer, so the user should not "
"read or write to the wrapped StreamPeer directly."
msgstr ""
-"PacketStreamPeeræä¾›äº†ä¸€ä¸ªåŒ…装器,用于在æµä¸Šä½¿ç”¨æ•°æ®åŒ…工作。这å…许在"
-"StreamPeer上使用基于数æ®åŒ…的代ç ã€‚PacketPeerStream在StreamPeer上实现了一个自"
-"定义的å议,所以用户ä¸åº”该直接读或写到被包装的StreamPeer上。"
+"PacketStreamPeer æä¾›äº†ä¸€ä¸ªåŒ…装器,用于在æµä¸Šä½¿ç”¨æ•°æ®åŒ…工作。这å…许在 "
+"StreamPeer 上使用基于数æ®åŒ…的代ç ã€‚PacketPeerStream 在 StreamPeer 上实现了一"
+"个自定义的å议,所以用户ä¸åº”该直接读或写到被包装的 StreamPeer 上。"
#: doc/classes/PacketPeerStream.xml
msgid "The wrapped [StreamPeer] object."
-msgstr "被·包装的[StreamPeer]对象。"
+msgstr "被包装的 [StreamPeer] 对象。"
#: doc/classes/PacketPeerUDP.xml
msgid "UDP packet peer."
-msgstr "UDPæ•°æ®åŒ…客户端。"
+msgstr "UDP æ•°æ®åŒ…客户端。"
#: doc/classes/PacketPeerUDP.xml
msgid ""
"UDP packet peer. Can be used to send raw UDP packets as well as [Variant]s."
-msgstr "UDPæ•°æ®åŒ…对等体。å¯ä»¥ç”¨æ¥å‘é€åŽŸå§‹çš„UDPæ•°æ®åŒ…以åŠ[Variant]。"
+msgstr "UDP æ•°æ®åŒ…对等体。å¯ä»¥ç”¨æ¥å‘é€åŽŸå§‹çš„ UDP æ•°æ®åŒ…ä»¥åŠ [Variant]。"
#: doc/classes/PacketPeerUDP.xml
msgid "Closes the UDP socket the [PacketPeerUDP] is currently listening on."
-msgstr "关闭[PacketPeerUDP]当剿­£åœ¨ä¾¦å¬çš„UDP套接字。"
+msgstr "关闭 [PacketPeerUDP] 当剿­£åœ¨ä¾¦å¬çš„ UDP 套接字。"
#: doc/classes/PacketPeerUDP.xml
msgid ""
@@ -52590,41 +52936,41 @@ msgid ""
"technique like SSL or DTLS if you feel like your application is transferring "
"sensitive information."
msgstr ""
-"调用此方法将UDP对等体连接到给定的[code]host[/code]/[code]port[/code]对。UDP实"
-"é™…ä¸Šæ˜¯æ— è¿žæŽ¥çš„ï¼Œæ‰€ä»¥è¿™ä¸ªé€‰é¡¹åªæ„å‘³ç€æ¥è‡ªä¸åŒåœ°å€çš„入包被自动丢弃,而出包总是"
-"被å‘é€åˆ°è¿žæŽ¥çš„地å€(ä¸å…许将æ¥è°ƒç”¨[method set_dest_address])。该方法ä¸å‘远程对"
-"等体å‘é€ä»»ä½•æ•°æ®ï¼Œè¦å‘逿•°æ®ï¼Œè¯·ä½¿ç”¨[method PacketPeer.put_var]或[method "
-"PacketPeer.put_packet]。å‚è§[UDPServer]。\n"
-"[b]注æ„:[/b]连接到远程对等体并ä¸èƒ½é˜²æ­¢IPæ¬ºéª—ç­‰æ¶æ„攻击。如果您觉得您的应用程"
-"åºæ­£åœ¨ä¼ è¾“æ•æ„Ÿä¿¡æ¯ï¼Œå¯ä»¥è€ƒè™‘使用SSL或DTLS等加密技术。"
+"调用此方法将 UDP 对等体连接到给定的 [code]host[/code]/[code]port[/code] 对。"
+"UDP å®žé™…ä¸Šæ˜¯æ— è¿žæŽ¥çš„ï¼Œæ‰€ä»¥è¿™ä¸ªé€‰é¡¹åªæ„å‘³ç€æ¥è‡ªä¸åŒåœ°å€çš„入包被自动丢弃,而出"
+"包总是被å‘é€åˆ°è¿žæŽ¥çš„地å€ï¼ˆä¸å…许将æ¥è°ƒç”¨ [method set_dest_address])。该方法"
+"ä¸å‘远程对等体å‘é€ä»»ä½•æ•°æ®ï¼Œè¦å‘逿•°æ®ï¼Œè¯·ä½¿ç”¨ [method PacketPeer.put_var] "
+"或 [method PacketPeer.put_packet]。å¦è¯·å‚阅 [UDPServer]。\n"
+"[b]注æ„:[/b]连接到远程对等体并ä¸èƒ½é˜²æ­¢ IP æ¬ºéª—ç­‰æ¶æ„攻击。如果您觉得您的应用"
+"ç¨‹åºæ­£åœ¨ä¼ è¾“æ•æ„Ÿä¿¡æ¯ï¼Œå¯ä»¥è€ƒè™‘使用 SSL 或 DTL S等加密技术。"
#: doc/classes/PacketPeerUDP.xml
msgid ""
"Returns the IP of the remote peer that sent the last packet(that was "
"received with [method PacketPeer.get_packet] or [method PacketPeer.get_var])."
msgstr ""
-"返回å‘逿œ€åŽä¸€ä¸ªæ•°æ®åŒ…(通过[method PacketPeer.get_packet]或[method "
-"PacketPeer.get_var]接收)的远程对等体的IP。"
+"返回å‘逿œ€åŽä¸€ä¸ªæ•°æ®åŒ…(通过 [method PacketPeer.get_packet] 或 [method "
+"PacketPeer.get_var] 接收)的远程对等体的 IP。"
#: doc/classes/PacketPeerUDP.xml
msgid ""
"Returns the port of the remote peer that sent the last packet(that was "
"received with [method PacketPeer.get_packet] or [method PacketPeer.get_var])."
msgstr ""
-"返回å‘逿œ€åŽä¸€ä¸ªæ•°æ®åŒ…(通过[method PacketPeer.get_packet]或[method "
-"PacketPeer.get_var]接收)的远程对等方的端å£ã€‚"
+"返回å‘逿œ€åŽä¸€ä¸ªæ•°æ®åŒ…(通过 [method PacketPeer.get_packet] 或 [method "
+"PacketPeer.get_var] 接收)的远程对等方的端å£ã€‚"
#: doc/classes/PacketPeerUDP.xml
msgid ""
"Returns [code]true[/code] if the UDP socket is open and has been connected "
"to a remote address. See [method connect_to_host]."
msgstr ""
-"如果UDP套接字已打开并已连接到远程地å€ï¼Œåˆ™è¿”回 [code]true[/code]。请å‚阅"
+"如果 UDP 套接字已打开并已连接到远程地å€ï¼Œåˆ™è¿”回 [code]true[/code]ã€‚è§ "
"[method connect_to_host]。"
#: doc/classes/PacketPeerUDP.xml
msgid "Returns whether this [PacketPeerUDP] is listening."
-msgstr "返回这个[PacketPeerUDP]æ˜¯å¦æ­£åœ¨ç›‘å¬ã€‚"
+msgstr "返回这个 [PacketPeerUDP] æ˜¯å¦æ­£åœ¨ç›‘å¬ã€‚"
#: doc/classes/PacketPeerUDP.xml
msgid ""
@@ -52647,8 +52993,8 @@ msgid ""
"Removes the interface identified by [code]interface_name[/code] from the "
"multicast group specified by [code]multicast_address[/code]."
msgstr ""
-"从[code]multicast_address[/code]指定的组播组中移除[code]interface_name[/code]"
-"标识的接å£ã€‚"
+"从 [code]multicast_address[/code] 指定的组播组中移除 [code]interface_name[/"
+"code] 标识的接å£ã€‚"
#: doc/classes/PacketPeerUDP.xml
msgid ""
@@ -52664,15 +53010,16 @@ msgid ""
"only listen on the interface with that addresses (or fail if no interface "
"with the given address exists)."
msgstr ""
-"使这个[PacketPeerUDP]在与[code]bind_address[/code]绑定的[code]端å£[/code]上监"
-"å¬ï¼Œç¼“冲区大å°ä¸º[code]recv_buf_size[/code]。\n"
-"如果[code]bind_address[/code]被设置为[code]\"*\"[/code](默认),对等体将监å¬"
-"所有å¯ç”¨åœ°å€ï¼ˆåŒ…括IPv4å’ŒIPv6)。\n"
-"如果[code]bind_address[/code]被设置为[code]\"0.0.0.0\"[/code](对于IPv4)或"
-"[code]\":\"[/code](对于IPv6ï¼‰ï¼Œå¯¹ç­‰ä½“å°†ç›‘å¬æ‰€æœ‰ç¬¦åˆè¯¥IP类型的å¯ç”¨åœ°å€ã€‚\n"
-"如果[code]bind_address[/code]被设置为任何有效的地å€ï¼ˆä¾‹å¦‚"
-"[code]\"192.168.1.101\"[/code],[code]\":1\"[/code]等),对等体将åªç›‘å¬å…·æœ‰è¯¥"
-"地å€çš„æŽ¥å£ï¼ˆå¦‚æžœä¸å­˜åœ¨å…·æœ‰è¯¥åœ°å€çš„æŽ¥å£ï¼Œåˆ™å¤±è´¥ï¼‰ã€‚"
+"使这个 [PacketPeerUDP] 在与 [code]bind_address[/code] ç»‘å®šçš„ç«¯å£ [code]port[/"
+"code] 上监å¬ï¼Œç¼“冲区大å°ä¸º [code]recv_buf_size[/code]。\n"
+"如果 [code]bind_address[/code] 被设置为 [code]\"*\"[/code](默认),对等体将"
+"ç›‘å¬æ‰€æœ‰å¯ç”¨åœ°å€ï¼ˆåŒ…括 IPv4 å’Œ IPv6)。\n"
+"如果 [code]bind_address[/code] 被设置为 [code]\"0.0.0.0\"[/code](对于 IPv4)"
+"或 [code]\":\"[/code](对于 IPv6ï¼‰ï¼Œå¯¹ç­‰ä½“å°†ç›‘å¬æ‰€æœ‰ç¬¦åˆè¯¥ IP 类型的å¯ç”¨åœ°"
+"å€ã€‚\n"
+"如果 [code]bind_address[/code] 被设置为任何有效的地å€ï¼ˆä¾‹å¦‚ "
+"[code]\"192.168.1.101\"[/code]ã€[code]\":1\"[/code] 等),对等体将åªç›‘å¬å…·æœ‰"
+"该地å€çš„æŽ¥å£ï¼ˆå¦‚æžœä¸å­˜åœ¨å…·æœ‰è¯¥åœ°å€çš„æŽ¥å£ï¼Œåˆ™å¤±è´¥ï¼‰ã€‚"
#: doc/classes/PacketPeerUDP.xml
msgid ""
@@ -52696,9 +53043,9 @@ msgid ""
"[b]Note:[/b] [method set_broadcast_enabled] must be enabled before sending "
"packets to a broadcast address (e.g. [code]255.255.255.255[/code])."
msgstr ""
-"设置å‘逿•°æ®åŒ…å’Œå˜é‡çš„目标地å€å’Œç«¯å£ã€‚如果需è¦ï¼Œå°†ä½¿ç”¨DNSè§£æžä¸€ä¸ªä¸»æœºå。\n"
+"设置å‘逿•°æ®åŒ…å’Œå˜é‡çš„目标地å€å’Œç«¯å£ã€‚如果需è¦ï¼Œå°†ä½¿ç”¨ DNS è§£æžä¸»æœºå。\n"
"[b]注æ„:[/b]在å‘广播地å€ï¼ˆä¾‹å¦‚:[code]255.255.255.255[/code])å‘逿•°æ®åŒ…之"
-"å‰ï¼Œå¿…é¡»å¯ç”¨[method set_broadcast_enabled]。"
+"å‰ï¼Œå¿…é¡»å¯ç”¨ [method set_broadcast_enabled]。"
#: doc/classes/PacketPeerUDP.xml
msgid ""
@@ -52718,15 +53065,15 @@ msgid ""
" return\n"
"[/codeblock]"
msgstr ""
-"等待数æ®åŒ…到达侦å¬ç«¯å£ã€‚å‚è§[method listen]。\n"
-"[b]注æ„:[/b][method wait]一旦被调用就ä¸èƒ½è¢«ä¸­æ–­ã€‚è¿™å¯ä»¥é€šè¿‡å…许å¦ä¸€æ–¹å‘é€ä¸€"
+"等待数æ®åŒ…到达侦å¬ç«¯å£ã€‚è§ [method listen]。\n"
+"[b]注æ„:[/b][method wait] 一旦被调用就ä¸èƒ½è¢«ä¸­æ–­ã€‚è¿™å¯ä»¥é€šè¿‡å…许å¦ä¸€æ–¹å‘é€ä¸€"
"个特定的“death pillâ€åŒ…æ¥è§£å†³ï¼Œå¦‚下所示:\n"
"[codeblock]\n"
-"# Server\n"
+"# æœåС噍\n"
"socket.set_dest_address(\"127.0.0.1\", 789)\n"
"socket.put_packet(\"Time to stop\".to_ascii())\n"
"\n"
-"# Client\n"
+"# 客户的\n"
"while socket.wait() == OK:\n"
" var data = socket.get_packet().get_string_from_ascii()\n"
" if data == \"Time to stop\":\n"
@@ -52735,15 +53082,15 @@ msgstr ""
#: doc/classes/Panel.xml
msgid "Provides an opaque background for [Control] children."
-msgstr "为[Control]孿ާ件æä¾›ä¸é€æ˜Žçš„背景。"
+msgstr "为 [Control] 孿ާ件æä¾›ä¸é€æ˜Žçš„背景。"
#: doc/classes/Panel.xml
msgid ""
"Panel is a [Control] that displays an opaque background. It's commonly used "
"as a parent and container for other types of [Control] nodes."
msgstr ""
-"颿¿æ˜¯ä¸€ä¸ªæ˜¾ç¤ºä¸é€æ˜ŽèƒŒæ™¯çš„[Control]。它通常用作其他类型的[Control]节点的父节"
-"点和容器。"
+"颿¿æ˜¯ä¸€ä¸ªæ˜¾ç¤ºä¸é€æ˜ŽèƒŒæ™¯çš„ [Control]。它通常用作其他类型的 [Control] 节点的父"
+"节点和容器。"
#: doc/classes/Panel.xml
msgid "2D Finite State Machine Demo"
@@ -52838,8 +53185,8 @@ msgid ""
"limit, the background will stop scrolling. Must be lower than [member "
"scroll_limit_end] to work."
msgstr ""
-"开始滚动的左上角é™åˆ¶ã€‚如果相机超出这个é™åˆ¶ï¼ŒèƒŒæ™¯å°†åœæ­¢æ»šåŠ¨ã€‚å¿…é¡»ä½ŽäºŽ[member "
-"scroll_limit_end]æ‰èƒ½å·¥ä½œã€‚"
+"开始滚动的左上角é™åˆ¶ã€‚如果相机超出这个é™åˆ¶ï¼ŒèƒŒæ™¯å°†åœæ­¢æ»šåŠ¨ã€‚å¿…é¡»ä½ŽäºŽ [member "
+"scroll_limit_end] æ‰èƒ½å·¥ä½œã€‚"
#: doc/classes/ParallaxBackground.xml
msgid ""
@@ -52847,8 +53194,8 @@ msgid ""
"limit, the background will stop scrolling. Must be higher than [member "
"scroll_limit_begin] to work."
msgstr ""
-"å³ä¸‹è§’é™åˆ¶æ»šåŠ¨ç»“æŸã€‚如果相机超出这个é™åˆ¶ï¼ŒèƒŒæ™¯å°†åœæ­¢æ»šåŠ¨ã€‚å¿…é¡»é«˜äºŽ[member "
-"scroll_limit_begin]æ‰èƒ½å·¥ä½œã€‚"
+"å³ä¸‹è§’é™åˆ¶æ»šåŠ¨ç»“æŸã€‚如果相机超出这个é™åˆ¶ï¼ŒèƒŒæ™¯å°†åœæ­¢æ»šåŠ¨ã€‚å¿…é¡»é«˜äºŽ [member "
+"scroll_limit_begin] æ‰èƒ½å·¥ä½œã€‚"
#: doc/classes/ParallaxBackground.xml
msgid ""
@@ -52856,8 +53203,8 @@ msgid ""
"[Camera2D], but can be used to manually manage scrolling when no camera is "
"present."
msgstr ""
-"视差背景的滚动值。使用[Camera2D]时自动计算,但å¯ç”¨äºŽæ‰‹åŠ¨ç®¡ç†æ— æ‘„åƒå¤´æ—¶çš„æ»š"
-"动。"
+"视差背景的滚动值。使用 [Camera2D] 时会自动计算,但也å¯ç”¨äºŽæ‰‹åŠ¨ç®¡ç†æ— æ‘„åƒæœºæ—¶"
+"的滚动。"
#: doc/classes/ParallaxLayer.xml
msgid "A parallax scrolling layer to be used with [ParallaxBackground]."
@@ -52883,26 +53230,26 @@ msgid ""
"scrolling background. If an axis is set to [code]0[/code], the [Texture] "
"will not be mirrored."
msgstr ""
-"视差图层的[Texture]镜åƒã€‚ç”¨äºŽåˆ›å»ºæ— é™æ»šåŠ¨çš„èƒŒæ™¯ã€‚å¦‚æžœä¸€ä¸ªè½´è¢«è®¾ç½®ä¸º[code]0[/"
-"code], [Texture]å°†ä¸ä¼šè¢«é•œåƒã€‚"
+"视差图层的 [Texture] 镜åƒã€‚ç”¨äºŽåˆ›å»ºæ— é™æ»šåŠ¨çš„èƒŒæ™¯ã€‚å¦‚æžœæŸä¸ªè½´è¢«è®¾ç½®ä¸º "
+"[code]0[/code],[Texture] å°†ä¸ä¼šè¢«é•œåƒã€‚"
#: doc/classes/ParallaxLayer.xml
msgid ""
"The ParallaxLayer's offset relative to the parent ParallaxBackground's "
"[member ParallaxBackground.scroll_offset]."
msgstr ""
-"ParallaxLayer相对于父ParallaxBackgroundçš„åç§»é‡[member ParallaxBackground."
-"scroll_offset]。"
+"该 ParallaxLayer çš„åç§»é‡ï¼Œç›¸å¯¹äºŽçˆ¶ ParallaxBackground çš„ [member "
+"ParallaxBackground.scroll_offset]。"
#: doc/classes/ParallaxLayer.xml
msgid ""
"Multiplies the ParallaxLayer's motion. If an axis is set to [code]0[/code], "
"it will not scroll."
-msgstr "å¤åˆ¶è§†å·®å›¾å±‚çš„è¿åŠ¨ã€‚å¦‚æžœä¸€ä¸ªè½´è¢«è®¾ç½®ä¸º[code]0[/code],它将ä¸ä¼šæ»šåŠ¨ã€‚"
+msgstr "å¤åˆ¶è§†å·®å›¾å±‚çš„è¿åŠ¨ã€‚å¦‚æžœä¸€ä¸ªè½´è¢«è®¾ç½®ä¸º [code]0[/code],它将ä¸ä¼šæ»šåŠ¨ã€‚"
#: doc/classes/Particles.xml
msgid "GPU-based 3D particle emitter."
-msgstr "基于GPUçš„3Dç²’å­å‘射器。"
+msgstr "基于 GPU çš„ 3D ç²’å­å‘射器。"
#: doc/classes/Particles.xml
msgid ""
@@ -53034,8 +53381,8 @@ msgid ""
"when particles are off-screen."
msgstr ""
"[AABB] 确定节点的区域,该区域需è¦åœ¨å±å¹•上å¯è§æ‰èƒ½ä½¿ç²’å­ç³»ç»Ÿå¤„于活动状æ€ã€‚\n"
-"如果在节点进入/退出å±å¹•æ—¶ç²’å­çªç„¶å‡ºçް/消失,则增大框。 [AABB] å¯ä»¥é€šè¿‡ä»£ç æˆ–"
-"使用 [b]Particles → Generate AABB[/b] 编辑器工具生æˆã€‚\n"
+"如果在节点进入/退出å±å¹•æ—¶ç²’å­çªç„¶å‡ºçް/消失,则增大框。[AABB] å¯ä»¥é€šè¿‡ä»£ç æˆ–使"
+"用 [b]Particles → Generate AABB[/b] 编辑器工具生æˆã€‚\n"
"[b]注æ„:[/b]如果使用中的 [ParticlesMaterial] é…置为投射阴影,您å¯èƒ½éœ€è¦æ”¾å¤§"
"æ­¤ AABB 以确ä¿åœ¨ç²’å­ç¦»å±æ—¶æ›´æ–°é˜´å½±ã€‚"
@@ -53072,7 +53419,7 @@ msgid ""
"[b]Note:[/b] Unlike [CPUParticles2D], [Particles2D] currently ignore the "
"texture region defined in [AtlasTexture]s."
msgstr ""
-"用于创建å„ç§ç²’å­ç³»ç»Ÿå’Œæ•ˆæžœçš„ 2D ç²’å­èŠ‚ç‚¹ã€‚ [Particles2D] 具有一个å‘射器,å¯ä»¥"
+"用于创建å„ç§ç²’å­ç³»ç»Ÿå’Œæ•ˆæžœçš„ 2D ç²’å­èŠ‚ç‚¹ã€‚[Particles2D] 具有一个å‘射器,å¯ä»¥"
"以给定的速率生æˆä¸€å®šæ•°é‡çš„ç²’å­ã€‚\n"
"使用 [code]process_material[/code] 属性添加 [ParticlesMaterial] 以é…置粒å­å¤–"
"观和行为。或者,您å¯ä»¥æ·»åŠ å°†åº”ç”¨äºŽæ‰€æœ‰ç²’å­çš„ [ShaderMaterial]。\n"
@@ -53110,7 +53457,7 @@ msgid ""
"→ Generate Visibility Rect[/b] editor tool."
msgstr ""
"[Rect2] 确定节点的区域,该区域需è¦åœ¨å±å¹•上å¯è§æ‰èƒ½ä½¿ç²’å­ç³»ç»Ÿå¤„于活动状æ€ã€‚\n"
-"如果当节点进入/退出å±å¹•æ—¶ç²’å­çªç„¶å‡ºçް/消失,则增长矩形。 [Rect2] å¯ä»¥é€šè¿‡ä»£ç "
+"如果当节点进入/退出å±å¹•æ—¶ç²’å­çªç„¶å‡ºçް/消失,则增长矩形。[Rect2] å¯ä»¥é€šè¿‡ä»£ç "
"或使用 [b]Particles → Generate Visibility Rect[/b] 编辑器工具生æˆã€‚"
#: doc/classes/ParticlesMaterial.xml
@@ -53132,14 +53479,14 @@ msgid ""
"ratio of [code]0.4[/code] would scale the original property between "
"[code]0.4-1.0[/code] of its original value."
msgstr ""
-"ParticlesMaterial定义了粒å­çš„属性和行为。它å¯ç”¨äºŽ[Particles]å’Œ[Particles2D]å‘"
-"射器节点的[code]process_material[/code]中。\n"
-"这个æè´¨çš„一些属性在å‘射时被应用到æ¯ä¸ªç²’å­ä¸Šï¼Œè€Œå…¶ä»–属性å¯ä»¥åº”用"
-"[CurveTexture]æ¥åœ¨ç²’å­çš„ç”Ÿå‘½å‘¨æœŸä¸­æ”¹å˜æ•°å€¼ã€‚\n"
-"å½“éšæœºæ€§æ¯”率被应用到一个属性时,用æ¥ä»¥ä¸€ä¸ªéšæœºé‡æ¥æ‰©å±•è¯¥å±žæ€§ã€‚éšæœºçŽ‡ç”¨æ¥åœ¨"
-"[code]1.0[/code]和一个å°äºŽ1çš„éšæœºæ•°ä¹‹é—´æ’å€¼ï¼Œç»“æžœä¹˜ä»¥å±žæ€§ï¼Œå¾—åˆ°éšæœºçš„属性。例"
-"如,一个[code]0.4[/code]çš„éšæœºæ¯”率将在[code]0.4-1.0[/code]之间缩放原始属性的"
-"原值。"
+"ParticlesMaterial 定义了粒å­çš„属性和行为。它å¯ç”¨äºŽ [Particles] å’Œ "
+"[Particles2D] å‘射器节点的 [code]process_material[/code]中。\n"
+"这个æè´¨çš„一些属性在å‘射时被应用到æ¯ä¸ªç²’å­ä¸Šï¼Œè€Œå…¶ä»–属性å¯ä»¥åº”用 "
+"[CurveTexture] æ¥åœ¨ç²’å­çš„ç”Ÿå‘½å‘¨æœŸä¸­æ”¹å˜æ•°å€¼ã€‚\n"
+"å½“éšæœºæ€§æ¯”率被应用到一个属性时,用æ¥ä»¥ä¸€ä¸ªéšæœºé‡æ¥æ‰©å±•è¯¥å±žæ€§ã€‚éšæœºçŽ‡ç”¨æ¥åœ¨ "
+"[code]1.0[/code] 和一个å°äºŽ 1 çš„éšæœºæ•°ä¹‹é—´æ’å€¼ï¼Œç»“æžœä¹˜ä»¥å±žæ€§ï¼Œå¾—åˆ°éšæœºçš„属"
+"性。例如,一个 [code]0.4[/code] çš„éšæœºæ¯”率将在 [code]0.4-1.0[/code] 之间缩放"
+"原始属性的原值。"
#: doc/classes/ParticlesMaterial.xml
msgid "Returns [code]true[/code] if the specified flag is enabled."
@@ -53157,7 +53504,7 @@ msgstr "è¿”å›žæŒ‡å®šå‚æ•°ä½¿ç”¨çš„ [Texture]。"
msgid ""
"If [code]true[/code], enables the specified flag. See [enum Flags] for "
"options."
-msgstr "如果[code]true[/code],å¯ç”¨æŒ‡å®šçš„Flag。选项请å‚阅[enum Flags]。"
+msgstr "如果为 [code]true[/code],å¯ç”¨æŒ‡å®šçš„æ ‡å¿—。选项请å‚阅 [enum Flags]。"
#: doc/classes/ParticlesMaterial.xml
msgid "Sets the specified [enum Parameter]."
@@ -53202,15 +53549,15 @@ msgstr ""
#: doc/classes/ParticlesMaterial.xml
msgid "Each particle's angular velocity will vary along this [CurveTexture]."
-msgstr "æ¯ä¸ªç²’å­çš„角速度将沿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„角速度将沿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid "Each particle's animation offset will vary along this [CurveTexture]."
-msgstr "æ¯ä¸ªç²’å­çš„动画å移将沿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„动画å移将沿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid "Each particle's animation speed will vary along this [CurveTexture]."
-msgstr "æ¯ä¸ªç²’å­çš„动画速度将沿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„动画速度将沿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid ""
@@ -53318,12 +53665,12 @@ msgstr "沿 Y è½´çš„ [member spread] é‡ã€‚"
#: doc/classes/ParticlesMaterial.xml
msgid "Each particle's hue will vary along this [CurveTexture]."
-msgstr "æ¯ä¸ªç²’å­çš„色调将沿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„色调将沿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid ""
"Each particle's linear acceleration will vary along this [CurveTexture]."
-msgstr "æ¯ä¸ªç²’å­çš„线性加速度将沿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„线性加速度将沿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid ""
@@ -53337,37 +53684,37 @@ msgstr ""
#: doc/classes/ParticlesMaterial.xml
msgid "Each particle's orbital velocity will vary along this [CurveTexture]."
-msgstr "æ¯ä¸ªç²’å­çš„轨é“速度将沿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„轨é“速度将沿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid ""
"Each particle's radial acceleration will vary along this [CurveTexture]."
-msgstr "æ¯ä¸ªç²’å­çš„径å‘加速度将沿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„径å‘加速度将沿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid "Each particle's scale will vary along this [CurveTexture]."
-msgstr "æ¯ä¸ªç²’å­çš„æ¯”例将沿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„æ¯”例将沿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid ""
"Each particle's tangential acceleration will vary along this [CurveTexture]."
-msgstr "æ¯ä¸ªç²’å­çš„切å‘加速度将沿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "æ¯ä¸ªç²’å­çš„切å‘加速度将沿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid "Trail particles' color will vary along this [GradientTexture]."
-msgstr "轨迹粒å­çš„颜色将沿ç€è¿™ä¸ª[GradientTexture]å˜åŒ–。"
+msgstr "轨迹粒å­çš„颜色将沿ç€è¿™ä¸ª [GradientTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid ""
"Emitter will emit [code]amount[/code] divided by [code]trail_divisor[/code] "
"particles. The remaining particles will be used as trail(s)."
msgstr ""
-"å‘射器将å‘å°„[code]amount[/code]除以[code]trail_visor[/code]的粒å­ã€‚剩下的粒å­"
-"将作为轨迹使用。"
+"å‘射器将å‘å°„ [code]amount[/code] 除以 [code]trail_visor[/code] 的粒å­ã€‚剩下的"
+"ç²’å­å°†ä½œä¸ºè½¨è¿¹ä½¿ç”¨ã€‚"
#: doc/classes/ParticlesMaterial.xml
msgid "Trail particles' size will vary along this [CurveTexture]."
-msgstr "轨迹粒å­çš„大å°å°†æ²¿ç€è¿™ä¸ª[CurveTexture]å˜åŒ–。"
+msgstr "轨迹粒å­çš„大å°å°†æ²¿ç€è¿™ä¸ª [CurveTexture] å˜åŒ–。"
#: doc/classes/ParticlesMaterial.xml
msgid ""
@@ -53483,8 +53830,8 @@ msgid ""
"point on the [member emission_point_texture]. Particle color will be "
"modulated by [member emission_color_texture]."
msgstr ""
-"ç²’å­å°†åœ¨[member emission_point_texture]ä¸Šéšæœºé‡‡æ ·ç‚¹æ‰€å†³å®šçš„ä½ç½®å‘射。粒å­é¢œè‰²"
-"将由[member emission_color_texture]调节。"
+"ç²’å­å°†åœ¨ [member emission_point_texture] ä¸Šéšæœºé‡‡æ ·ç‚¹æ‰€å†³å®šçš„ä½ç½®å‘射。粒å­é¢œ"
+"色将由 [member emission_color_texture] 调节。"
#: doc/classes/ParticlesMaterial.xml
msgid ""
@@ -53493,9 +53840,9 @@ msgid ""
"will be set based on [member emission_normal_texture]. Particle color will "
"be modulated by [member emission_color_texture]."
msgstr ""
-"ç²’å­å°†åœ¨[member emission_point_texture]ä¸Šéšæœºé‡‡æ ·ç‚¹æ‰€å†³å®šçš„ä½ç½®å‘射。粒å­é€Ÿåº¦"
-"和旋转将基于[member emission_normal_texture]进行设置。粒å­é¢œè‰²å°†ç”±[member "
-"emission_color_texture]调节。"
+"ç²’å­å°†åœ¨ [member emission_point_texture] ä¸Šéšæœºé‡‡æ ·ç‚¹æ‰€å†³å®šçš„ä½ç½®å‘射。粒å­é€Ÿ"
+"度和旋转将基于 [member emission_normal_texture] 进行设置。粒å­é¢œè‰²å°†ç”± "
+"[member emission_color_texture] 调节。"
#: doc/classes/Path.xml
msgid "Contains a [Curve3D] path for [PathFollow] nodes to follow."
@@ -53516,15 +53863,15 @@ msgstr ""
#: doc/classes/Path.xml
msgid "A [Curve3D] describing the path."
-msgstr "A [Curve3D]æè¿°è·¯å¾„。"
+msgstr "æè¿°è·¯å¾„çš„ [Curve3D]。"
#: doc/classes/Path.xml
msgid "Emitted when the [member curve] changes."
-msgstr "当[member curve]æ”¹å˜æ—¶è§¦å‘。"
+msgstr "当 [member curve] æ”¹å˜æ—¶è§¦å‘。"
#: doc/classes/Path2D.xml
msgid "Contains a [Curve2D] path for [PathFollow2D] nodes to follow."
-msgstr "包å«ä¸€ä¸ª[Curve2D]路径,供[PathFollow2D]节点éµå¾ªã€‚"
+msgstr "包å«ä¸€ä¸ª [Curve2D] 路径,供 [PathFollow2D] 节点éµå¾ªã€‚"
#: doc/classes/Path2D.xml
msgid ""
@@ -53534,14 +53881,14 @@ msgid ""
"of [PathFollow2D]). As such, the curve should usually start with a zero "
"vector ([code](0, 0)[/code])."
msgstr ""
-"å¯ä»¥è®©[PathFollow2D]å­èŠ‚ç‚¹æ²¿ç€[Curve2D]移动。有关用法的更多信æ¯ï¼Œè¯·å‚阅"
+"å¯ä»¥è®© [PathFollow2D] å­èŠ‚ç‚¹æ²¿ç€ [Curve2D] 移动。有关用法的更多信æ¯ï¼Œè¯·å‚阅 "
"[PathFollow2D]。\n"
-"[b]注:[/b]该路径被认为是相对于移动的节点([PathFollow2D]çš„å­èŠ‚ç‚¹)。因此,曲线"
-"通常以零å‘é‡([code](0,0)[/code])开始。"
+"[b]注æ„:[/b]该路径被认为是相对于移动的节点([PathFollow2D] çš„å­èŠ‚ç‚¹ï¼‰ã€‚å› "
+"此,曲线通常以零å‘é‡ï¼ˆ[code](0,0)[/code])开始。"
#: doc/classes/Path2D.xml
msgid "A [Curve2D] describing the path."
-msgstr "A [Curve2D]æè¿°è·¯å¾„。"
+msgstr "æè¿°è·¯å¾„çš„ [Curve2D]。"
#: doc/classes/PathFollow.xml
msgid "Point sampler for a [Path]."
@@ -53574,10 +53921,11 @@ msgid ""
"points and increase memory consumption, or make a cubic interpolation "
"between two points at the cost of (slightly) slower calculations."
msgstr ""
-"如果[code]true[/code],两个缓存的点之间的ä½ç½®æ˜¯ç«‹æ–¹æ’值,å¦åˆ™æ˜¯çº¿æ€§æ’值。\n"
-"沿ç€[Path]çš„[Curve3D]的点在使用å‰è¢«é¢„计算,以加快计算。而åŽï¼Œåœ¨ç¡®å®šåç§»é‡ä¸Šçš„"
-"点会在两个相邻的缓存点之间进行æ’值计算。如果曲线有急转弯,这å¯èƒ½ä¼šäº§ç”Ÿä¸€ä¸ªé—®"
-"题,因为缓存的点å¯èƒ½ä¸ä¼šè¶³å¤Ÿç´§è·Ÿæ›²çº¿ã€‚\n"
+"如果为 [code]true[/code],两个缓存的点之间的ä½ç½®æ˜¯ç«‹æ–¹æ’值,å¦åˆ™æ˜¯çº¿æ€§æ’"
+"值。\n"
+"æ²¿ç€ [Path] çš„ [Curve3D] 的点在使用å‰è¢«é¢„计算,以加快计算。而åŽï¼Œåœ¨ç¡®å®šåç§»é‡"
+"上的点会在两个相邻的缓存点之间进行æ’值计算。如果曲线有急转弯,这å¯èƒ½ä¼šäº§ç”Ÿä¸€"
+"个问题,因为缓存的点å¯èƒ½ä¸ä¼šè¶³å¤Ÿç´§è·Ÿæ›²çº¿ã€‚\n"
"这个问题有两个答案:è¦ä¹ˆå¢žåŠ ç¼“å­˜ç‚¹çš„æ•°é‡ï¼Œä»£ä»·æ˜¯å¢žåŠ å†…å­˜æ¶ˆè€—ï¼›è¦ä¹ˆåœ¨ä¸¤ä¸ªç‚¹ä¹‹"
"间进行立方æ’å€¼ï¼Œä»£ä»·æ˜¯è®¡ç®—é€Ÿåº¦ç¨æ…¢ã€‚"
@@ -53590,8 +53938,8 @@ msgid ""
"If [code]true[/code], any offset outside the path's length will wrap around, "
"instead of stopping at the ends. Use it for cyclic paths."
msgstr ""
-"如果[code]true[/code],路径长度以外的任何åç§»éƒ½å°†çŽ¯ç»•ï¼Œè€Œä¸æ˜¯åœ¨ç»“æŸæ—¶åœæ­¢ã€‚对"
-"于循环路径使用它。"
+"如果为 [code]true[/code],路径长度以外的任何åç§»éƒ½å°†çŽ¯ç»•ï¼Œè€Œä¸æ˜¯åœ¨ç»“æŸæ—¶åœ"
+"止。对于循环路径使用它。"
#: doc/classes/PathFollow.xml
msgid ""
@@ -53606,7 +53954,7 @@ msgid ""
"Allows or forbids rotation on one or more axes, depending on the [enum "
"RotationMode] constants being used."
msgstr ""
-"å…è®¸æˆ–ç¦æ­¢åœ¨ä¸€ä¸ªæˆ–多个轴上旋转,这å–决于使用的[enum RotationMode]常é‡ã€‚"
+"å…è®¸æˆ–ç¦æ­¢åœ¨ä¸€ä¸ªæˆ–多个轴上旋转,这å–决于使用的 [enum RotationMode] 常é‡ã€‚"
#: doc/classes/PathFollow.xml
msgid ""
@@ -53615,8 +53963,8 @@ msgid ""
"the path, as the offset supplied is multiplied internally by the path's "
"length."
msgstr ""
-"到第一个顶点的è·ç¦»ï¼Œå°†0.0作为第一个顶点,1.0作为最åŽä¸€ä¸ªé¡¶ç‚¹ã€‚è¿™åªæ˜¯è¡¨ç¤ºè·¯å¾„"
-"内åç§»é‡çš„å¦ä¸€ç§æ–¹å¼ï¼Œå› ä¸ºæä¾›çš„åç§»é‡åœ¨å†…部乘以路径的长度。"
+"到第一个顶点的è·ç¦»ï¼Œå°† 0.0 作为第一个顶点,1.0 作为最åŽä¸€ä¸ªé¡¶ç‚¹ã€‚è¿™åªæ˜¯è¡¨ç¤ºè·¯"
+"径内åç§»é‡çš„å¦ä¸€ç§æ–¹å¼ï¼Œå› ä¸ºæä¾›çš„åç§»é‡åœ¨å†…部乘以路径的长度。"
#: doc/classes/PathFollow.xml doc/classes/PathFollow2D.xml
msgid "The node's offset perpendicular to the curve."
@@ -53649,7 +53997,7 @@ msgstr ""
#: doc/classes/PathFollow2D.xml
msgid "Point sampler for a [Path2D]."
-msgstr "对[Path2D]çš„ç‚¹å–æ ·çš„å–æ ·å™¨ã€‚"
+msgstr "对 [Path2D] çš„ç‚¹å–æ ·çš„å–æ ·å™¨ã€‚"
#: doc/classes/PathFollow2D.xml
msgid ""
@@ -53660,8 +54008,8 @@ msgid ""
"descendant nodes will then move accordingly when setting an offset in this "
"node."
msgstr ""
-"这个节点接å—它的父节点[Path2D]ï¼Œå¹¶è¿”å›žå…¶ä¸­ä¸€ä¸ªç‚¹çš„åæ ‡(给定到第一个顶点的è·"
-"离)。\n"
+"这个节点接å—它的父节点 [Path2D] å¹¶è¿”å›žå…¶ä¸­ä¸€ä¸ªç‚¹çš„åæ ‡ï¼Œéœ€è¦ç»™å®šåˆ°ç¬¬ä¸€ä¸ªé¡¶ç‚¹"
+"çš„è·ç¦»ã€‚\n"
"在ä¸ç¼–ç ç§»åŠ¨æ¨¡å¼çš„æƒ…况下,它å¯ä»¥ä½¿å…¶ä»–节点éµå¾ªä¸€æ¡è·¯å¾„。因此,节点必须是这个"
"节点的å­èŠ‚ç‚¹ã€‚å½“åœ¨è¯¥èŠ‚ç‚¹ä¸­è®¾ç½®åç§»é‡æ—¶ï¼ŒåŽä»£èŠ‚ç‚¹å°†ç›¸åº”åœ°ç§»åŠ¨ã€‚"
@@ -53711,8 +54059,9 @@ msgid ""
"offset within the path, as the offset supplied is multiplied internally by "
"the path's length."
msgstr ""
-"在0.0(第一个顶点)到1.0(最åŽä¸€ä¸ªé¡¶ç‚¹)的范围内,沿ç€è·¯å¾„çš„è·ç¦»ä¸ºä¸€ä¸ªæ•°å­—。这åª"
-"是表示路径内åç§»é‡çš„å¦ä¸€ç§æ–¹å¼ï¼Œå› ä¸ºæä¾›çš„åç§»é‡åœ¨å†…部乘以路径的长度。"
+"在 0.0(第一个顶点)到 1.0(最åŽä¸€ä¸ªé¡¶ç‚¹ï¼‰çš„范围内,沿ç€è·¯å¾„çš„è·ç¦»ä¸ºä¸€ä¸ªæ•°"
+"å­—ã€‚è¿™åªæ˜¯è¡¨ç¤ºè·¯å¾„内åç§»é‡çš„å¦ä¸€ç§æ–¹å¼ï¼Œå› ä¸ºæä¾›çš„åç§»é‡åœ¨å†…部乘以路径的长"
+"度。"
#: doc/classes/PCKPacker.xml
msgid "Creates packages that can be loaded into a running project."
@@ -53731,24 +54080,24 @@ msgid ""
"The above [PCKPacker] creates package [code]test.pck[/code], then adds a "
"file named [code]text.txt[/code] at the root of the package."
msgstr ""
-"[PCKPacker]用于创建å¯ä»¥é€šè¿‡[method ProjectSettings.load_resource_pack]加载到"
-"正在è¿è¡Œçš„项目中的包。\n"
+"[PCKPacker] 用于创建å¯ä»¥é€šè¿‡ [method ProjectSettings.load_resource_pack] 加载"
+"到正在è¿è¡Œçš„项目中的包。\n"
"[codeblock]\n"
"var packer = PCKPacker.new()\n"
"packer.pck_start(\"test.pck\")\n"
"packer.add_file(\"res://text.txt\", \"text.txt\")\n"
"packer.flush()\n"
"[/codeblock]\n"
-"上é¢çš„[PCKPacker]创建包[code]test.pck[/code],然åŽåœ¨åŒ…的根目录中添加一个å为"
-"[code]text.txt[/code]的文件。"
+"上é¢çš„ [PCKPacker] 创建包 [code]test.pck[/code],然åŽåœ¨åŒ…的根目录中添加一个å"
+"为 [code]text.txt[/code] 的文件。"
#: doc/classes/PCKPacker.xml
msgid ""
"Adds the [code]source_path[/code] file to the current PCK package at the "
"[code]pck_path[/code] internal path (should start with [code]res://[/code])."
msgstr ""
-"å°†[code]source_path[/code]文件添加到当å‰PCK包的[code]pck_path[/code]内部路径"
-"(应该以[code]res://[/code]开始)。"
+"å°† [code]source_path[/code] æ–‡ä»¶æ·»åŠ åˆ°å½“å‰ PCK 包的 [code]pck_path[/code] 内"
+"部路径(应该以 [code]res://[/code] 开头)。"
#: doc/classes/PCKPacker.xml
msgid ""
@@ -53756,8 +54105,8 @@ msgid ""
"flush. If [code]verbose[/code] is [code]true[/code], a list of files added "
"will be printed to the console for easier debugging."
msgstr ""
-"自上次刷新以æ¥ï¼Œä½¿ç”¨æ‰€æœ‰[method add_file]调用写入指定的文件。如果"
-"[code]verbose[/code]为 [code]true[/code],添加的文件列表将被打å°åˆ°æŽ§åˆ¶å°ï¼Œä»¥"
+"自上次刷新以æ¥ï¼Œä½¿ç”¨æ‰€æœ‰ [method add_file] 调用写入指定的文件。如果 "
+"[code]verbose[/code] 为 [code]true[/code],添加的文件列表将被打å°åˆ°æŽ§åˆ¶å°ï¼Œä»¥"
"便于调试。"
#: doc/classes/PCKPacker.xml
@@ -53766,8 +54115,9 @@ msgid ""
"code] file extension isn't added automatically, so it should be part of "
"[code]pck_name[/code] (even though it's not required)."
msgstr ""
-"创建一个å为[code]pck_name[/code]的新PCK文件。[code].Pck[/code]文件扩展åä¸ä¼š"
-"自动添加,所以它应该是[code]pck_name[/code]的一部分(å³ä½¿å®ƒä¸æ˜¯å¿…需的)。"
+"创建一个å为 [code]pck_name[/code] 的新 PCK 文件。ä¸ä¼šè‡ªåŠ¨æ·»åŠ  [code].pck[/"
+"code] 文件扩展å,所以它应该是 [code]pck_name[/code] 的一部分(å³ä½¿å®ƒä¸æ˜¯å¿…需"
+"的)。"
#: doc/classes/Performance.xml
msgid "Exposes performance-related data."
@@ -53785,11 +54135,11 @@ msgid ""
"[b]Note:[/b] Many of these monitors are not updated in real-time, so there "
"may be a short delay between changes."
msgstr ""
-"这个类æä¾›äº†å¯¹ä¸€äº›ä¸Žæ€§èƒ½æœ‰å…³çš„ä¸åŒç›‘控的访问,比如内存使用é‡ã€ç»˜åˆ¶è°ƒç”¨å’ŒFPS。"
-"这些与编辑器的[b]Monitor[/b]标签中的[b]Debugger[/b]颿¿æ‰€æ˜¾ç¤ºçš„æ•°å€¼ç›¸åŒã€‚通过"
-"使用这个类的[method get_monitor]方法,å¯ä»¥ä»Žä½ çš„代ç ä¸­è®¿é—®è¿™äº›æ•°æ®ã€‚\n"
+"这个类æä¾›äº†å¯¹ä¸€äº›ä¸Žæ€§èƒ½æœ‰å…³çš„ä¸åŒç›‘控的访问,比如内存使用é‡ã€ç»˜åˆ¶è°ƒç”¨å’Œ "
+"FPS。这些与编辑器[b]调试器[/b]颿¿çš„[b]监视[/b]标签中的所显示的数值相åŒã€‚通过"
+"使用这个类的 [method get_monitor] 方法,å¯ä»¥ä»Žä½ çš„代ç ä¸­è®¿é—®è¿™äº›æ•°æ®ã€‚\n"
"[b]注æ„:[/b]这些监视器中有几个åªåœ¨è°ƒè¯•模å¼ä¸‹å¯ç”¨ï¼Œå½“在å‘布版构建中使用时,将"
-"总是返回0。\n"
+"总是返回 0。\n"
"[b]注æ„:[/b]è¿™äº›ç›‘æŽ§å™¨ä¸­çš„è®¸å¤šä¸æ˜¯å®žæ—¶æ›´æ–°çš„,所以在å˜åŒ–之间å¯èƒ½ä¼šæœ‰çŸ­æš‚的延"
"迟。"
@@ -53802,10 +54152,9 @@ msgid ""
"console\n"
"[/codeblock]"
msgstr ""
-"返回一个å¯ç”¨ç›‘视器的值。你应该æä¾›ä¸€ä¸ª[enum Monitor]常é‡ä½œä¸ºå‚数,åƒè¿™æ ·:\n"
+"返回一个å¯ç”¨ç›‘视器的值。你应该æä¾›ä¸€ä¸ª [enum Monitor] 常é‡ä½œä¸ºå‚数,åƒè¿™æ ·:\n"
"[codeblock]\n"
-"print(Performance.get_monitor(Performance.TIME_FPS)) # Prints the FPS to the "
-"console\n"
+"print(Performance.get_monitor(Performance.TIME_FPS)) # 在终端中输出 FPS\n"
"[/codeblock]"
#: doc/classes/Performance.xml
@@ -53843,12 +54192,12 @@ msgid ""
"Largest amount of memory the message queue buffer has used, in bytes. The "
"message queue is used for deferred functions calls and notifications."
msgstr ""
-"消æ¯é˜Ÿåˆ—缓冲区使用的最大内存数é‡(以字节为å•ä½)。消æ¯é˜Ÿåˆ—用于延迟函数调用和通"
-"知。"
+"消æ¯é˜Ÿåˆ—缓冲区使用的最大内存数é‡ï¼ˆä»¥å­—节为å•ä½ï¼‰ã€‚消æ¯é˜Ÿåˆ—用于延迟函数调用和"
+"通知。"
#: doc/classes/Performance.xml
msgid "Number of objects currently instanced (including nodes)."
-msgstr "当å‰å®žä¾‹åŒ–的对象数é‡(包括节点)。"
+msgstr "当å‰å®žä¾‹åŒ–的对象数é‡ï¼ˆåŒ…括节点)。"
#: doc/classes/Performance.xml
msgid "Number of resources currently used."
@@ -53868,27 +54217,27 @@ msgstr "孤儿节点的数é‡ï¼Œå­¤å„¿èŠ‚ç‚¹å³æ— æ³•被按父级追溯到根节
#: doc/classes/Performance.xml
msgid "3D objects drawn per frame."
-msgstr "æ¯å¸§ç»˜åˆ¶3D对象的数é‡ã€‚"
+msgstr "æ¯å¸§ç»˜åˆ¶ 3D 对象的数é‡ã€‚"
#: doc/classes/Performance.xml
msgid "Vertices drawn per frame. 3D only."
-msgstr "æ¯å¸§ç»˜åˆ¶çš„顶点数。åªåœ¨3D中有效。"
+msgstr "æ¯å¸§ç»˜åˆ¶çš„顶点数。åªåœ¨ 3D 中有效。"
#: doc/classes/Performance.xml
msgid "Material changes per frame. 3D only."
-msgstr "æ¯ä¸€å¸§çš„æè´¨å˜åŒ–。仅é™3D。"
+msgstr "æ¯ä¸€å¸§çš„æè´¨å˜åŒ–ã€‚ä»…é™ 3D。"
#: doc/classes/Performance.xml
msgid "Shader changes per frame. 3D only."
-msgstr "æ¯ä¸€å¸§çš„ç€è‰²å™¨å˜åŒ–。仅é™3D。"
+msgstr "æ¯ä¸€å¸§çš„ç€è‰²å™¨å˜åŒ–ã€‚ä»…é™ 3D。"
#: doc/classes/Performance.xml
msgid "Render surface changes per frame. 3D only."
-msgstr "æ¯å¸§æ¸²æŸ“é¢çš„å˜åŒ–。仅3D中有效。"
+msgstr "æ¯å¸§æ¸²æŸ“é¢çš„å˜åŒ–。仅 3D 中有效。"
#: doc/classes/Performance.xml
msgid "Draw calls per frame. 3D only."
-msgstr "æ¯ä¸€å¸§çš„绘图调用。仅é™3D。"
+msgstr "æ¯ä¸€å¸§çš„ç»˜å›¾è°ƒç”¨ã€‚ä»…é™ 3D。"
#: doc/classes/Performance.xml
msgid "Items or joined items drawn per frame."
@@ -53918,15 +54267,15 @@ msgstr "在 GLES2 å’Œ GLES3 渲染åŽç«¯ä¸­æœªå®žçŽ°ï¼Œå§‹ç»ˆè¿”å›ž 0。"
#: doc/classes/Performance.xml
msgid "Number of active [RigidBody2D] nodes in the game."
-msgstr "游æˆä¸­æ´»è·ƒçš„[RigidBody2D]节点数é‡ã€‚"
+msgstr "游æˆä¸­æ´»è·ƒçš„ [RigidBody2D] 节点数é‡ã€‚"
#: doc/classes/Performance.xml
msgid "Number of collision pairs in the 2D physics engine."
-msgstr "2D物ç†å¼•擎中的碰撞对数é‡ã€‚"
+msgstr "2D 物ç†å¼•擎中的碰撞对数é‡ã€‚"
#: doc/classes/Performance.xml
msgid "Number of islands in the 2D physics engine."
-msgstr "2D物ç†å¼•擎中的岛屿数é‡ã€‚"
+msgstr "2D 物ç†å¼•擎中的岛屿数é‡ã€‚"
#: doc/classes/Performance.xml
msgid "Number of active [RigidBody] and [VehicleBody] nodes in the game."
@@ -53934,19 +54283,19 @@ msgstr "游æˆä¸­æ´»åŠ¨çš„ [RigidBody] å’Œ [VehicleBody] 节点的数é‡ã€‚"
#: doc/classes/Performance.xml
msgid "Number of collision pairs in the 3D physics engine."
-msgstr "3D物ç†å¼•擎中的碰撞对数é‡ã€‚"
+msgstr "3D 物ç†å¼•擎中的碰撞对数é‡ã€‚"
#: doc/classes/Performance.xml
msgid "Number of islands in the 3D physics engine."
-msgstr "3D物ç†å¼•擎中的岛屿数é‡ã€‚"
+msgstr "3D 物ç†å¼•擎中的岛屿数é‡ã€‚"
#: doc/classes/Performance.xml
msgid "Output latency of the [AudioServer]."
-msgstr "[AudioServer]的输出延迟。"
+msgstr "[AudioServer] 的输出延迟。"
#: doc/classes/Performance.xml
msgid "Represents the size of the [enum Monitor] enum."
-msgstr "表示[enum Monitor] enum的大å°ã€‚"
+msgstr "表示 [enum Monitor] 枚举的大å°ã€‚"
#: doc/classes/PHashTranslation.xml
msgid "Optimized translation."
@@ -53956,13 +54305,13 @@ msgstr "优化的翻译。"
msgid ""
"Optimized translation. Uses real-time compressed translations, which results "
"in very small dictionaries."
-msgstr "优化翻译。使用实时压缩翻译,从而生æˆéžå¸¸å°çš„è¯å…¸ã€‚"
+msgstr "优化的翻译。使用实时压缩翻译,从而生æˆéžå¸¸å°çš„è¯å…¸ã€‚"
#: doc/classes/PHashTranslation.xml
msgid ""
"Generates and sets an optimized translation from the given [Translation] "
"resource."
-msgstr "从给定的[Translation]资æºç”Ÿæˆå¹¶è®¾ç½®ä¼˜åŒ–的翻译。"
+msgstr "从给定的 [Translation] 资æºç”Ÿæˆå¹¶è®¾ç½®ä¼˜åŒ–的翻译。"
#: doc/classes/Physics2DDirectBodyState.xml
msgid "Direct access object to a physics body in the [Physics2DServer]."
@@ -54024,30 +54373,30 @@ msgstr "对物体施加旋转冲é‡ã€‚"
#: doc/classes/Physics2DDirectBodyState.xml
#: doc/classes/PhysicsDirectBodyState.xml
msgid "Returns the collider's [RID]."
-msgstr "返回碰撞体的[RID]。"
+msgstr "返回该碰撞体的 [RID]。"
#: doc/classes/Physics2DDirectBodyState.xml
#: doc/classes/PhysicsDirectBodyState.xml
msgid "Returns the collider's object id."
-msgstr "返回碰撞体的对象id。"
+msgstr "返回该碰撞体的对象 id。"
#: doc/classes/Physics2DDirectBodyState.xml
msgid ""
"Returns the collider object. This depends on how it was created (will return "
"a scene node if such was used to create it)."
msgstr ""
-"返回碰撞体对象。这å–决于它是如何创建的(如果是被作为场景节点创建的,那么将返"
-"回场景节点)。"
+"返回该碰撞体对象。这å–决于它是如何创建的(如果是被作为场景节点创建的,那么将"
+"返回场景节点)。"
#: doc/classes/Physics2DDirectBodyState.xml
#: doc/classes/PhysicsDirectBodyState.xml
msgid "Returns the contact position in the collider."
-msgstr "返回碰撞体中的接触ä½ç½®ã€‚"
+msgstr "返回该碰撞体中的接触ä½ç½®ã€‚"
#: doc/classes/Physics2DDirectBodyState.xml
#: doc/classes/PhysicsDirectBodyState.xml
msgid "Returns the collider's shape index."
-msgstr "返回碰撞体的形状索引。"
+msgstr "返回该碰撞体的形状索引。"
#: doc/classes/Physics2DDirectBodyState.xml
msgid ""
@@ -54055,13 +54404,13 @@ msgid ""
"[method Object.get_meta], and is set with [method Physics2DServer."
"shape_set_data]."
msgstr ""
-"返回碰撞形状的元数æ®ã€‚这个元数æ®ä¸åŒäºŽ[method Object.get_meta],是用[method "
-"Physics2DServer.shape_set_data]设置的。"
+"返回该碰撞形状的元数æ®ã€‚这个元数æ®ä¸åŒäºŽ [method Object.get_meta],是用 "
+"[method Physics2DServer.shape_set_data] 设置的。"
#: doc/classes/Physics2DDirectBodyState.xml
#: doc/classes/PhysicsDirectBodyState.xml
msgid "Returns the linear velocity vector at the collider's contact point."
-msgstr "返回碰撞体接触点处的线速度å‘é‡ã€‚"
+msgstr "返回该碰撞体接触点处的线速度å‘é‡ã€‚"
#: doc/classes/Physics2DDirectBodyState.xml
msgid ""
@@ -54069,8 +54418,8 @@ msgid ""
"[b]Note:[/b] By default, this returns 0 unless bodies are configured to "
"monitor contacts. See [member RigidBody2D.contact_monitor]."
msgstr ""
-"返回此物体与其他物体的接触次数。\n"
-"[b]注æ„:[/b]默认情况下,除éžç‰©ä½“被设为监视接触者,å¦åˆ™è¿”回0。å‚阅 [member "
+"返回这个物体与其他物体的接触次数。\n"
+"[b]注æ„:[/b]默认情况下,除éžç‰©ä½“被设为监视接触者,å¦åˆ™è¿”回 0ã€‚è§ [member "
"RigidBody2D.contact_monitor]。"
#: doc/classes/Physics2DDirectBodyState.xml
@@ -54126,12 +54475,12 @@ msgstr "物体的线性速度,å•ä½ä¸ºåƒç´ æ¯ç§’。"
#: doc/classes/Physics2DDirectBodyState.xml
#: doc/classes/PhysicsDirectBodyState.xml
msgid "If [code]true[/code], this body is currently sleeping (not active)."
-msgstr "如果[code]true[/code],则该物体当å‰å¤„于ç¡çœ çжæ€(䏿´»åЍ)。"
+msgstr "如果为 [code]true[/code],则该物体当å‰å¤„于ç¡çœ çжæ€ï¼ˆä¸æ´»åŠ¨ï¼‰ã€‚"
#: doc/classes/Physics2DDirectBodyState.xml
#: doc/classes/PhysicsDirectBodyState.xml
msgid "The timestep (delta) used for the simulation."
-msgstr "用于模拟的时间步长(delta)。"
+msgstr "用于模拟的时间步长(delta)。"
#: doc/classes/Physics2DDirectBodyState.xml
#: doc/classes/PhysicsDirectBodyState.xml
@@ -54159,15 +54508,15 @@ msgstr "ç‰©ä½“çš„å˜æ¢çŸ©é˜µã€‚"
#: doc/classes/Physics2DDirectSpaceState.xml
msgid "Direct access object to a space in the [Physics2DServer]."
-msgstr "直接访问[Physics2DServer]中的空间的对象。"
+msgstr "直接访问 [Physics2DServer] 中的空间的对象。"
#: doc/classes/Physics2DDirectSpaceState.xml
msgid ""
"Direct access object to a space in the [Physics2DServer]. It's used mainly "
"to do queries against objects and areas residing in a given space."
msgstr ""
-"直接访问[Physics2DServer]中的空间的对象。它主è¦ç”¨äºŽå¯¹ä½äºŽç»™å®šç©ºé—´ä¸­çš„对象和区"
-"域进行查询。"
+"直接访问 [Physics2DServer] 中的空间的对象。它主è¦ç”¨äºŽå¯¹ä½äºŽç»™å®šç©ºé—´ä¸­çš„对象和"
+"区域进行查询。"
#: doc/classes/Physics2DDirectSpaceState.xml
msgid ""
@@ -54370,7 +54719,7 @@ msgstr ""
"通过 [Physics2DShapeQueryParameters] 对象检查给出的形状与空间的交点。返回的相"
"交形状是一个字典数组,包å«ä»¥ä¸‹å­—段:\n"
"[code]collider[/code]:碰撞的对象。\n"
-"[code]collider_id[/code]:碰撞对象的ID。\n"
+"[code]collider_id[/code]:碰撞对象的 ID。\n"
"[code]metadata[/code]:相交形状的元数æ®ã€‚这个元数æ®ä¸Ž [method Object."
"get_meta] ä¸åŒï¼Œæ˜¯ç”¨ [method Physics2DServer.shape_set_data] 设置的。\n"
"[code]rid[/code]:相交对象的 [RID]。\n"
@@ -54379,7 +54728,7 @@ msgstr ""
#: doc/classes/Physics2DServer.xml
msgid "Server interface for low-level 2D physics access."
-msgstr "用于底层2D物ç†è®¿é—®æœåŠ¡çš„æŽ¥å£ã€‚"
+msgstr "用于底层 2D 物ç†è®¿é—®æœåŠ¡çš„æŽ¥å£ã€‚"
#: doc/classes/Physics2DServer.xml
msgid ""
@@ -54420,17 +54769,17 @@ msgstr ""
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Gets the instance ID of the object the area is assigned to."
-msgstr "获å–区域分é…给的对象的实例ID。"
+msgstr "获å–区域分é…给的对象的实例 ID。"
#: doc/classes/Physics2DServer.xml
msgid ""
"Returns an area parameter value. See [enum AreaParameter] for a list of "
"available parameters."
-msgstr "è¿”å›žåŒºåŸŸå‚æ•°å€¼ã€‚有关å¯ç”¨å‚数的列表,请å‚阅[enum AreaParameter]。"
+msgstr "è¿”å›žåŒºåŸŸå‚æ•°å€¼ã€‚有关å¯ç”¨å‚数的列表,请å‚阅 [enum AreaParameter]。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Returns the [RID] of the nth shape of an area."
-msgstr "返回区域的第n个形状的[RID]。"
+msgstr "返回区域的第 n 个形状的 [RID]。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Returns the number of shapes assigned to an area."
@@ -54479,13 +54828,13 @@ msgid ""
"5: The shape index of the area where the object entered/exited."
msgstr ""
"设置当任何主体/区域进入或退出该区域时调用的函数。这个回调函数将被任何与区域交"
-"互的对象调用,并接å—5ä¸ªå‚æ•°:\n"
-"1: [constant AREA_BODY_ADDED]或[constant AREA_BODY_REMOVED],å–决于对象是å¦è¿›"
-"入或退出该区域。\n"
-"2:进入/退出该区域对象的[RID]。\n"
-"3:进入/退出该区域对象的实例ID。\n"
-"4:进入/离开该区域的物体的形状指数。\n"
-"5:物体进入/离开区域的形状指数。"
+"äº’çš„å¯¹è±¡è°ƒç”¨ï¼Œå¹¶æŽ¥å— 5 ä¸ªå‚æ•°ï¼š\n"
+"1:[constant AREA_BODY_ADDED] 或 [constant AREA_BODY_REMOVED],å–决于对象是å¦"
+"进入或退出该区域。\n"
+"2:进入/退出该区域对象的 [RID]。\n"
+"3:进入/退出该区域对象的实例 ID。\n"
+"4:进入/离开该区域的物体的形状指数。\n"
+"5:物体进入/离开区域的形状指数。"
#: doc/classes/Physics2DServer.xml
msgid ""
@@ -54517,8 +54866,8 @@ msgid ""
"Sets the space override mode for the area. See [enum AreaSpaceOverrideMode] "
"for a list of available modes."
msgstr ""
-"为该区域设置空间覆盖模å¼ã€‚请å‚阅[enum AreaSpaceOverrideMode]获å–å¯ç”¨æ¨¡å¼çš„列"
-"表。"
+"为该区域设置空间覆盖模å¼ã€‚请å‚阅 [enum AreaSpaceOverrideMode] 获å–å¯ç”¨æ¨¡å¼çš„"
+"列表。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Sets the transform matrix for an area."
@@ -54535,9 +54884,9 @@ msgid ""
"in global coordinates. A force differs from an impulse in that, while the "
"two are forces, the impulse clears itself after being applied."
msgstr ""
-"在施加的力和扭矩上添加一个有作用点的力。与[method body_apply_impulse]一样,力"
-"和物体原点的åç§»é‡éƒ½åœ¨å…¨å±€å标中。力与冲é‡çš„ä¸åŒä¹‹å¤„在于,虽然两者都是力,但"
-"冲é‡åœ¨è¢«æ–½åŠ åŽä¼šè‡ªåŠ¨æ¸…é™¤ã€‚"
+"在施加的力和扭矩上添加一个有作用点的力。与 [method body_apply_impulse] 一样,"
+"力和物体原点的åç§»é‡éƒ½åœ¨å…¨å±€å标中。力与冲é‡çš„ä¸åŒä¹‹å¤„在于,虽然两者都是力,"
+"但冲é‡åœ¨è¢«æ–½åŠ åŽä¼šè‡ªåŠ¨æ¸…é™¤ã€‚"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid ""
@@ -54587,7 +54936,7 @@ msgstr ""
msgid ""
"Returns the maximum contacts that can be reported. See [method "
"body_set_max_contacts_reported]."
-msgstr "è¿”å›žå¯æŠ¥å‘Šçš„æœ€å¤§æŽ¥è§¦æ•°ã€‚å‚阅[method body_set_max_contacts_reported]。"
+msgstr "è¿”å›žå¯æŠ¥å‘Šçš„æœ€å¤§æŽ¥è§¦æ•°ã€‚è§ [method body_set_max_contacts_reported]。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Returns the body mode."
@@ -54597,11 +54946,11 @@ msgstr "返回物体模å¼ã€‚"
msgid ""
"Returns the value of a body parameter. See [enum BodyParameter] for a list "
"of available parameters."
-msgstr "è¿”å›žç‰©ä½“å‚æ•°çš„值。请å‚阅[enum BodyParameter]获å–å¯ç”¨å‚数列表。"
+msgstr "è¿”å›žç‰©ä½“å‚æ•°çš„值。请å‚阅 [enum BodyParameter] 获å–å¯ç”¨å‚数列表。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Returns the [RID] of the nth shape of a body."
-msgstr "返回body的第n个碰撞形状的[RID]。"
+msgstr "返回物体的第 n 个碰撞形状的 [RID]。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Returns the number of shapes assigned to a body."
@@ -54617,7 +54966,7 @@ msgstr "è¿”å›žç‰©ä½“ç¢°æ’žå½¢çŠ¶çš„å˜æ¢çŸ©é˜µã€‚"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Returns the [RID] of the space assigned to a body."
-msgstr "返回分é…给物体的空间的[RID]。"
+msgstr "返回分é…给物体的空间的 [RID]。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Returns a body state."
@@ -54628,8 +54977,8 @@ msgid ""
"Returns whether a body uses a callback function to calculate its own physics "
"(see [method body_set_force_integration_callback])."
msgstr ""
-"返回一个body是å¦ä½¿ç”¨å›žè°ƒå‡½æ•°æ¥è®¡ç®—它自己的物ç†å€¼(å‚阅"
-"body_set_force_integration_callback方法)。"
+"返回一个物体是å¦ä½¿ç”¨å›žè°ƒå‡½æ•°æ¥è®¡ç®—它自己的物ç†å€¼ï¼ˆè§ [method "
+"body_set_force_integration_callback])。"
#: doc/classes/Physics2DServer.xml
msgid "Removes a body from the list of bodies exempt from collisions."
@@ -54666,7 +55015,7 @@ msgid ""
"Continuous collision detection tries to predict where a moving body will "
"collide, instead of moving it and correcting its movement if it collided."
msgstr ""
-"设置使用[enum CCDMode]常é‡ä¹‹ä¸€çš„连续碰撞检测模å¼ã€‚\n"
+"设置使用 [enum CCDMode] 常é‡ä¹‹ä¸€çš„连续碰撞检测模å¼ã€‚\n"
"连续碰撞检测试图预测一个è¿åŠ¨ä½“å°†åœ¨å“ªé‡Œå‘ç”Ÿç¢°æ’žï¼Œè€Œä¸æ˜¯ç§»åŠ¨å®ƒå¹¶åœ¨å®ƒå‘生碰撞时"
"纠正其è¿åŠ¨ã€‚"
@@ -54689,14 +55038,14 @@ msgstr ""
#: doc/classes/Physics2DServer.xml
msgid "Sets the body mode using one of the [enum BodyMode] constants."
-msgstr "使用[enum BodyMode]常é‡ä¹‹ä¸€è®¾ç½®body模å¼ã€‚"
+msgstr "使用 [enum BodyMode] 常é‡ä¹‹ä¸€è®¾ç½® body 模å¼ã€‚"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid ""
"Sets whether a body uses a callback function to calculate its own physics "
"(see [method body_set_force_integration_callback])."
msgstr ""
-"设置一个物体是å¦ä½¿ç”¨å›žè°ƒå‡½æ•°æ¥è®¡ç®—它自己的物ç†ï¼ˆå‚阅 [method "
+"设置一个物体是å¦ä½¿ç”¨å›žè°ƒå‡½æ•°æ¥è®¡ç®—它自己的物ç†ï¼ˆè§ [method "
"body_set_force_integration_callback])。"
#: doc/classes/Physics2DServer.xml
@@ -54710,26 +55059,27 @@ msgid ""
"Substitutes a given body shape by another. The old shape is selected by its "
"index, the new one by its [RID]."
msgstr ""
-"用一个给定的物体形状代替å¦ä¸€ä¸ªã€‚旧的形状是通过其索引选择的,新的是通过其[RID]"
-"选择的。"
+"用一个给定的物体形状代替å¦ä¸€ä¸ªã€‚旧的形状是通过其索引选择的,新的是通过其 "
+"[RID] 选择的。"
#: doc/classes/Physics2DServer.xml
msgid ""
"Enables one way collision on body if [code]enable[/code] is [code]true[/"
"code]."
-msgstr "如果[code]enable[/code]为 [code]true[/code],则在body上å¯ç”¨å•å‘碰撞。"
+msgstr ""
+"如果 [code]enable[/code] 为 [code]true[/code],则在 body 上å¯ç”¨å•å‘碰撞。"
#: doc/classes/Physics2DServer.xml
msgid "Disables shape in body if [code]disable[/code] is [code]true[/code]."
-msgstr "如果[code]disable[/code]为 [code]true[/code],则在body中ç¦ç”¨å½¢çŠ¶ã€‚"
+msgstr "如果 [code]disable[/code] 为 [code]true[/code],则在 body 中ç¦ç”¨å½¢çŠ¶ã€‚"
#: doc/classes/Physics2DServer.xml
msgid ""
"Sets metadata of a shape within a body. This metadata is different from "
"[method Object.set_meta], and can be retrieved on shape queries."
msgstr ""
-"设置一个体中的形状的元数æ®ã€‚这个元数æ®ä¸Ž[method Object.set_meta]ä¸åŒï¼Œå¯ä»¥åœ¨"
-"形状查询中检索。"
+"设置一个体中的形状的元数æ®ã€‚这个元数æ®ä¸Ž [method Object.set_meta] ä¸åŒï¼Œå¯ä»¥"
+"在形状查询中检索。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Sets the transform matrix for a body shape."
@@ -54737,7 +55087,7 @@ msgstr "è®¾ç½®ç‰©ä½“å½¢çŠ¶çš„å˜æ¢çŸ©é˜µã€‚"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Assigns a space to the body (see [method space_create])."
-msgstr "给物体分é…一个空间(å‚阅 [method space_create])。"
+msgstr "给物体分é…ä¸€ä¸ªç©ºé—´ï¼ˆè§ [method space_create])。"
#: doc/classes/Physics2DServer.xml
msgid ""
@@ -54756,7 +55106,7 @@ msgid ""
"can be passed to return additional information in."
msgstr ""
"如果从空间中的给定点沿给定方å‘移动会导致碰撞,则返回 [code]true[/code]。边è·"
-"增加了碰撞检测中涉åŠçš„形状的大å°ã€‚ 通过返回[Physics2DTestMotionResult] å¯ä»¥é™„"
+"增加了碰撞检测中涉åŠçš„形状的大å°ã€‚通过返回[Physics2DTestMotionResult] å¯ä»¥é™„"
"加信æ¯ã€‚"
#: doc/classes/Physics2DServer.xml
@@ -54774,7 +55124,8 @@ msgstr "è¿”å›žé˜»å°¼å¼¹ç°§å…³èŠ‚å‚æ•°å€¼ã€‚"
msgid ""
"Sets a damped spring joint parameter. See [enum DampedStringParam] for a "
"list of available parameters."
-msgstr "è®¾ç½®é˜»å°¼å¼¹ç°§å…³èŠ‚å‚æ•°ã€‚å‚阅[enum DampedStringParam]获å–å¯ç”¨å‚数的列表。"
+msgstr ""
+"è®¾ç½®é˜»å°¼å¼¹ç°§å…³èŠ‚å‚æ•°ã€‚å‚阅 [enum DampedStringParam] 获å–å¯ç”¨å‚数的列表。"
#: doc/classes/Physics2DServer.xml
msgid ""
@@ -54790,7 +55141,7 @@ msgid ""
"Returns information about the current state of the 2D physics engine. See "
"[enum ProcessInfo] for a list of available states."
msgstr ""
-"返回关于2D物ç†å¼•擎当å‰çжæ€çš„ä¿¡æ¯ã€‚有关å¯ç”¨çжæ€åˆ—表,请å‚阅[enum "
+"返回关于 2D 物ç†å¼•擎当å‰çжæ€çš„ä¿¡æ¯ã€‚有关å¯ç”¨çжæ€åˆ—表,请å‚阅 [enum "
"ProcessInfo]。"
#: doc/classes/Physics2DServer.xml
@@ -54805,13 +55156,13 @@ msgstr "è¿”å›žå…³èŠ‚å‚æ•°çš„值。"
#: doc/classes/Physics2DServer.xml
msgid "Returns a joint's type (see [enum JointType])."
-msgstr "返回一个关节的类型(è§[enum JointType])。"
+msgstr "è¿”å›žä¸€ä¸ªå…³èŠ‚çš„ç±»åž‹ï¼ˆè§ [enum JointType])。"
#: doc/classes/Physics2DServer.xml
msgid ""
"Sets a joint parameter. See [enum JointParam] for a list of available "
"parameters."
-msgstr "è®¾ç½®å…³èŠ‚å‚æ•°ã€‚有关å¯ç”¨å‚数的列表,请å‚阅[enum JointParam]。"
+msgstr "è®¾ç½®å…³èŠ‚å‚æ•°ã€‚有关å¯ç”¨å‚数的列表,请å‚阅 [enum JointParam]。"
#: doc/classes/Physics2DServer.xml
msgid ""
@@ -54841,14 +55192,14 @@ msgstr "返回形状数æ®ã€‚"
#: doc/classes/Physics2DServer.xml
msgid "Returns a shape's type (see [enum ShapeType])."
-msgstr "返回一个形状的类型(å‚阅[enum ShapeType])。"
+msgstr "è¿”å›žä¸€ä¸ªå½¢çŠ¶çš„ç±»åž‹ï¼ˆè§ [enum ShapeType])。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid ""
"Sets the shape data that defines its shape and size. The data to be passed "
"depends on the kind of shape created [method shape_get_type]."
msgstr ""
-"设置定义形状和大å°çš„形状数æ®ã€‚è¦ä¼ é€’的数æ®å–决于创建的形状的类型[method "
+"设置定义形状和大å°çš„形状数æ®ã€‚è¦ä¼ é€’的数æ®å–决于创建的形状的类型 [method "
"shape_get_type]。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
@@ -54857,9 +55208,9 @@ msgid ""
"engine that can be assigned to an area or a body. It can be assigned to an "
"area with [method area_set_space], or to a body with [method body_set_space]."
msgstr ""
-"创建一个空间。空间是物ç†å¼•æ“Žçš„å‚æ•°é›†åˆï¼Œå¯ä»¥åˆ†é…给区域或主体。它å¯ä»¥é€šè¿‡"
-"[method area_set_space]分é…给一个区域,或者通过[method body_set_space]分é…ç»™"
-"一个主体。"
+"创建一个空间。空间是物ç†å¼•æ“Žçš„å‚æ•°é›†åˆï¼Œå¯ä»¥åˆ†é…给区域或主体。它å¯ä»¥é€šè¿‡ "
+"[method area_set_space] 分é…给一个区域,或者通过 [method body_set_space] 分é…"
+"给一个主体。"
#: doc/classes/Physics2DServer.xml
msgid ""
@@ -54886,7 +55237,7 @@ msgstr "将空间标记为活动空间。它ä¸ä¼šæœ‰æ•ˆæžœï¼Œé™¤éžå®ƒè¢«åˆ†é…
msgid ""
"Sets the value for a space parameter. See [enum SpaceParameter] for a list "
"of available parameters."
-msgstr "è®¾ç½®ç©ºé—´å‚æ•°çš„值。å‚阅[enum SpaceParameter]获å–å¯ç”¨å‚数列表。"
+msgstr "è®¾ç½®ç©ºé—´å‚æ•°çš„值。å‚阅 [enum SpaceParameter] 获å–å¯ç”¨å‚数列表。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid ""
@@ -54940,8 +55291,8 @@ msgid ""
"violating a constraint, to avoid leaving them in that state because of "
"numerical imprecision."
msgstr ""
-"常é‡ï¼Œç”¨äºŽè®¾ç½®/èŽ·å–æ‰€æœ‰ç‰©ç†çº¦æŸçš„默认求解器å置。解算器å差是一个控制两个物体"
-"在è¿å约æŸåŽ \"åå¼¹ \"程度的因素,以é¿å…由于数值ä¸ç²¾ç¡®è€Œä½¿å®ƒä»¬å¤„于这ç§çжæ€ã€‚"
+"常é‡ï¼Œç”¨äºŽè®¾ç½®/èŽ·å–æ‰€æœ‰ç‰©ç†çº¦æŸçš„默认求解器å置。解算器å置是一个控制两个物体"
+"在è¿å约æŸåŽâ€œåå¼¹â€ç¨‹åº¦çš„因素,以é¿å…由于数值ä¸ç²¾ç¡®è€Œä½¿å®ƒä»¬å¤„于这ç§çжæ€ã€‚"
#: doc/classes/Physics2DServer.xml
msgid ""
@@ -54993,8 +55344,8 @@ msgid ""
"supplied form is a convex polygon."
msgstr ""
"这是用于创建凸多边形的常é‡ã€‚一个多边形是由一个点的列表定义的。它å¯ä»¥ç”¨äºŽäº¤ç‚¹"
-"和内/外侧检查。与[member CollisionPolygon2D.polygon]属性ä¸åŒï¼Œç”¨[method "
-"shape_set_data]修改的多边形并ä¸éªŒè¯æ‰€æä¾›çš„ç‚¹çš„å½¢å¼æ˜¯ä¸€ä¸ªå‡¸å½¢å¤šè¾¹å½¢ã€‚"
+"和内/外侧检查。与 [member CollisionPolygon2D.polygon] 属性ä¸åŒï¼Œç”¨ [method "
+"shape_set_data] 修改的多边形并ä¸éªŒè¯æ‰€æä¾›çš„ç‚¹çš„å½¢å¼æ˜¯ä¸€ä¸ªå‡¸å½¢å¤šè¾¹å½¢ã€‚"
#: doc/classes/Physics2DServer.xml
msgid ""
@@ -55096,15 +55447,15 @@ msgstr ""
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Constant for static bodies."
-msgstr "StaticBody 的常é‡ã€‚"
+msgstr "陿€ç‰©ä½“的常é‡ã€‚"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Constant for kinematic bodies."
-msgstr "KinematicBody 的常é‡ã€‚"
+msgstr "è¿åŠ¨å­¦ç‰©ä½“çš„å¸¸é‡ã€‚"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Constant for rigid bodies."
-msgstr "RigidBody 的常é‡ã€‚"
+msgstr "刚体的常é‡ã€‚"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid ""
@@ -55144,7 +55495,7 @@ msgstr "常é‡ï¼Œç”¨äºŽè®¾ç½®/获å–物体的角度阻尼系数。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Represents the size of the [enum BodyParameter] enum."
-msgstr "表示[enum BodyParameter]枚举的大å°ã€‚"
+msgstr "表示 [enum BodyParameter] 枚举的大å°ã€‚"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Constant to set/get the current transform matrix of the body."
@@ -55196,8 +55547,8 @@ msgid ""
"undamped spring, while 1 causes the system to reach equilibrium as fast as "
"possible (critical damping)."
msgstr ""
-"设置弹簧接头的阻尼比率。值为0表示无阻尼弹簧,而1导致系统尽å¯èƒ½å¿«åœ°è¾¾åˆ°å¹³è¡¡"
-"(临界阻尼)。"
+"设置弹簧接头的阻尼比率。值为 0 表示无阻尼弹簧,而 1 导致系统尽å¯èƒ½å¿«åœ°è¾¾åˆ°å¹³"
+"衡(临界阻尼)。"
#: doc/classes/Physics2DServer.xml
msgid ""
@@ -55211,13 +55562,13 @@ msgstr ""
msgid ""
"Enables continuous collision detection by raycasting. It is faster than "
"shapecasting, but less precise."
-msgstr "通过射线投射实现连续的碰撞检测。它比shapecasting更快,但ä¸å¤Ÿç²¾ç¡®ã€‚"
+msgstr "通过射线投射实现连续的碰撞检测。它比形状投射更快,但ä¸å¤Ÿç²¾ç¡®ã€‚"
#: doc/classes/Physics2DServer.xml
msgid ""
"Enables continuous collision detection by shapecasting. It is the slowest "
"CCD method, and the most precise."
-msgstr "通过形å˜å®žçŽ°è¿žç»­çš„ç¢°æ’žæ£€æµ‹ã€‚å®ƒæ˜¯æœ€æ…¢çš„CCD方法,也是最精确的。"
+msgstr "通过形å˜å®žçŽ°è¿žç»­çš„ç¢°æ’žæ£€æµ‹ã€‚å®ƒæ˜¯æœ€æ…¢çš„ CCD 方法,也是最精确的。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid ""
@@ -55261,12 +55612,12 @@ msgstr "设置用于碰撞/相交查询的 [Shape2D]。"
#: doc/classes/Physics2DShapeQueryParameters.xml
msgid "If [code]true[/code], the query will take [Area2D]s into account."
-msgstr "如果[code]true[/code],查询将考虑[Area2D]。"
+msgstr "如果为 [code]true[/code],查询将考虑 [Area2D]。"
#: doc/classes/Physics2DShapeQueryParameters.xml
msgid ""
"If [code]true[/code], the query will take [PhysicsBody2D]s into account."
-msgstr "如果[code]true[/code],查询将考虑[PhysicsBody2D]。"
+msgstr "如果为 [code]true[/code],查询将考虑 [PhysicsBody2D]。"
#: doc/classes/Physics2DShapeQueryParameters.xml
#: doc/classes/PhysicsShapeQueryParameters.xml
@@ -55298,7 +55649,7 @@ msgstr "正在查询的形状的è¿åŠ¨ã€‚"
#: doc/classes/Physics2DShapeQueryParameters.xml
#: doc/classes/PhysicsShapeQueryParameters.xml
msgid "The queried shape's [RID]. See also [method set_shape]."
-msgstr "查询形状的 [RID]。å¦è§[method set_shape]。"
+msgstr "查询形状的 [RID]。å¦è¯·å‚阅 [method set_shape]。"
#: doc/classes/Physics2DShapeQueryParameters.xml
#: doc/classes/PhysicsShapeQueryParameters.xml
@@ -55307,7 +55658,7 @@ msgstr "è¢«æŸ¥è¯¢å½¢çŠ¶çš„å˜æ¢çŸ©é˜µã€‚"
#: doc/classes/PhysicsBody.xml
msgid "Base class for all objects affected by physics in 3D space."
-msgstr "在3D空间中å—物ç†å½±å“的所有对象的基类。"
+msgstr "在 3D 空间中å—物ç†å½±å“的所有对象的基类。"
#: doc/classes/PhysicsBody.xml
msgid ""
@@ -55371,7 +55722,7 @@ msgid ""
"This is equivalent to [code]add_force(force, Vector3(0,0,0))[/code]."
msgstr ""
"增加一个æ’定的方å‘力,而ä¸å½±å“旋转。\n"
-"这相当于[code]add_force(force, Vector3(0,0,0))[/code]。"
+"相当于 [code]add_force(force, Vector3(0,0,0))[/code]。"
#: doc/classes/PhysicsDirectBodyState.xml
msgid "Adds a constant rotational force without affecting position."
@@ -55383,7 +55734,7 @@ msgid ""
"This is equivalent to [code]apply_impulse(Vector3(0, 0, 0), impulse)[/code]."
msgstr ""
"施加å•一方å‘的冲é‡è€Œä¸å½±å“旋转。\n"
-"这等价于 [code]apply_impulse(Vector3(0, 0, 0), impulse)[/code]。"
+"相当于 [code]apply_impulse(Vector3(0, 0, 0), impulse)[/code]。"
#: doc/classes/PhysicsDirectBodyState.xml
msgid ""
@@ -55417,7 +55768,7 @@ msgid ""
"monitor contacts. See [member RigidBody.contact_monitor]."
msgstr ""
"返回此物体与其他物体的接触次数。\n"
-"[b]注æ„:[/b]默认情况下,除éžç‰©ä½“被设为监视接触者,å¦åˆ™è¿”回0。å‚阅 [member "
+"[b]注æ„:[/b]默认情况下,除éžç‰©ä½“被设为监视接触者,å¦åˆ™è¿”回 0ã€‚è§ [member "
"RigidBody2D.contact_monitor]。"
#: doc/classes/PhysicsDirectBodyState.xml
@@ -55497,15 +55848,15 @@ msgid ""
"If the shape did not intersect anything, then an empty dictionary is "
"returned instead."
msgstr ""
-"检查通过[PhysicsShapeQueryParameters]对象给出的形状与空间的交点。如果它与一个"
-"以上的形状å‘生碰撞,则选择最近的。返回的对象是包å«ä»¥ä¸‹å­—段的字典:\n"
-"[code]collider_id[/code]:碰撞对象的ID。\n"
-"[code]linear_velocity[/code]:碰撞对象的速度[Vector3]。如果对象是一个[Area],"
-"结果是[code](0, 0, 0)[/code]。\n"
-"[code]normal[/code]:ç‰©ä½“åœ¨äº¤ç‚¹å¤„çš„è¡¨é¢æ³•线。\n"
-"[code]点[/code]:相交点。\n"
-"[code]rid[/code]:相交物体的[RID]。\n"
-"[code]shape[/code]:碰撞形状的形状索引。\n"
+"检查通过 [PhysicsShapeQueryParameters] 对象给出的形状与空间的交点。如果它与一"
+"个以上的形状å‘生碰撞,则选择最近的。返回的对象是包å«ä»¥ä¸‹å­—段的字典:\n"
+"[code]collider_id[/code]:碰撞对象的 ID。\n"
+"[code]linear_velocity[/code]:碰撞对象的速度 [Vector3]。如果对象是一个 "
+"[Area],结果是 [code](0, 0, 0)[/code]。\n"
+"[code]normal[/code]ï¼šç‰©ä½“åœ¨äº¤ç‚¹å¤„çš„è¡¨é¢æ³•线。\n"
+"[code]point[/code]:相交点。\n"
+"[code]rid[/code]:相交物体的 [RID]。\n"
+"[code]shape[/code]:碰撞形状的形状索引。\n"
"如果该形状没有与任何物体相交,那么将返回空的字典。"
#: doc/classes/PhysicsDirectSpaceState.xml
@@ -55554,17 +55905,17 @@ msgid ""
"determine if the ray should collide with [PhysicsBody]s or [Area]s, "
"respectively."
msgstr ""
-"在给定的空间中与一æ¡å°„线相交。返回的对象是具有下列字段的字典:\n"
-"[code]collider[/code]:碰撞的对象。\n"
-"[code]collider_id[/code]:碰撞对象的ID。\n"
-"[code]normal[/code]:ç‰©ä½“åœ¨ç›¸äº¤ç‚¹çš„è¡¨é¢æ³•线。\n"
-"[code]position[/code]:交å‰ç‚¹ã€‚\n"
-"[code]rid[/code]:相交物体的[RID]。\n"
-"[code]形状[/code]:碰撞形状的形状索引。\n"
+"在给定的空间中与一æ¡å°„线相交。返回的对象是具有下列字段的字典:\n"
+"[code]collider[/code]:碰撞的对象。\n"
+"[code]collider_id[/code]:碰撞对象的 ID。\n"
+"[code]normal[/code]ï¼šç‰©ä½“åœ¨ç›¸äº¤ç‚¹çš„è¡¨é¢æ³•线。\n"
+"[code]position[/code]:交å‰ç‚¹ã€‚\n"
+"[code]rid[/code]:相交物体的 [RID]。\n"
+"[code]shape[/code]:碰撞形状的形状索引。\n"
"如果射线没有与任何物体相交,那么将返回空的字典。\n"
-"此外,该方法å¯ä»¥æŽ¥å—一个[code]exclude[/code]对象或[RID]数组,该数组将被排除在"
-"碰撞之外,[code]collision_mask[/code]使ީç è¡¨ç¤ºè¦æ£€æŸ¥çš„物ç†å±‚,或者布尔值æ¥ç¡®"
-"定射线是å¦åº”该分别与[PhysicsBody]或[Area]å‘生碰撞。"
+"此外,该方法å¯ä»¥æŽ¥å—一个 [code]exclude[/code] 对象或 [RID] 数组,该数组将被排"
+"除在碰撞之外,[code]collision_mask[/code] 使ީç è¡¨ç¤ºè¦æ£€æŸ¥çš„物ç†å±‚,或者布尔"
+"值æ¥ç¡®å®šå°„线是å¦åº”该分别与 [PhysicsBody] 或 [Area] å‘生碰撞。"
#: doc/classes/PhysicsDirectSpaceState.xml
msgid ""
@@ -55579,13 +55930,13 @@ msgid ""
"The number of intersections can be limited with the [code]max_results[/code] "
"parameter, to reduce the processing time."
msgstr ""
-"通过[PhysicsShapeQueryParameters]对象给出的形状与空间检查交点。相交的形状会以"
-"数组的形å¼è¿”å›žï¼Œè¯¥æ•°ç»„åŒ…å«æœ‰ä»¥ä¸‹å­—段的字典:\n"
-"[code]collider[/code]:碰撞的对象。\n"
-"[code]collider_id[/code]:碰撞对象的ID。\n"
-"[code]rid[/code]:相交物体的[RID]。\n"
-"[code]shape[/code]:碰撞形状的形状索引。\n"
-"å¯ä»¥ç”¨[code]max_results[/code]傿•°é™åˆ¶ç›¸äº¤çš„æ•°é‡ï¼Œä»¥å‡å°‘å¤„ç†æ—¶é—´ã€‚"
+"通过 [PhysicsShapeQueryParameters] 对象给出的形状与空间检查交点。相交的形状会"
+"以数组的形å¼è¿”å›žï¼Œè¯¥æ•°ç»„åŒ…å«æœ‰ä»¥ä¸‹å­—段的字典:\n"
+"[code]collider[/code]:碰撞的对象。\n"
+"[code]collider_id[/code]:碰撞对象的 ID。\n"
+"[code]rid[/code]:相交物体的 [RID]。\n"
+"[code]shape[/code]:碰撞形状的形状索引。\n"
+"å¯ä»¥ç”¨ [code]max_results[/code] 傿•°é™åˆ¶ç›¸äº¤çš„æ•°é‡ï¼Œä»¥å‡å°‘å¤„ç†æ—¶é—´ã€‚"
#: doc/classes/PhysicsMaterial.xml
msgid "A material for physics properties."
@@ -55594,27 +55945,30 @@ msgstr "具有物ç†å±žæ€§çš„æè´¨ã€‚"
#: doc/classes/PhysicsMaterial.xml
msgid ""
"Provides a means of modifying the collision properties of a [PhysicsBody]."
-msgstr "æä¾›äº†ä¸€ç§ä¿®æ”¹[PhysicsBody]的碰撞属性的方法。"
+msgstr "æä¾›äº†ä¸€ç§ä¿®æ”¹ [PhysicsBody] 的碰撞属性的方法。"
#: doc/classes/PhysicsMaterial.xml
msgid ""
"If [code]true[/code], subtracts the bounciness from the colliding object's "
"bounciness instead of adding it."
-msgstr "如果[code]true[/code],则从碰撞对象的弹跳性中å‡åŽ»å¼¹æ€§ï¼Œè€Œä¸æ˜¯æ·»åŠ å®ƒã€‚"
+msgstr ""
+"如果为 [code]true[/code],则从碰撞对象的弹跳性中å‡åŽ»å¼¹æ€§ï¼Œè€Œä¸æ˜¯æ·»åŠ å®ƒã€‚"
#: doc/classes/PhysicsMaterial.xml
msgid ""
"The body's bounciness. Values range from [code]0[/code] (no bounce) to "
"[code]1[/code] (full bounciness)."
msgstr ""
-"实体的弹性。值的范围从[code]0[/code](无å弹)到[code]1[/code](完全å弹)。"
+"实体的弹性。值的范围从 [code]0[/code](无å弹)到 [code]1[/code](完全å"
+"弹)。"
#: doc/classes/PhysicsMaterial.xml
msgid ""
"The body's friction. Values range from [code]0[/code] (frictionless) to "
"[code]1[/code] (maximum friction)."
msgstr ""
-"物体的摩擦。å–值范围从[code]0[/code](无摩擦)到[code]1[/code](最大摩擦)。"
+"物体的摩擦。å–值范围从 [code]0[/code](无摩擦)到 [code]1[/code](最大摩"
+"擦)。"
#: doc/classes/PhysicsMaterial.xml
msgid ""
@@ -55624,9 +55978,9 @@ msgid ""
"instead. If [code]true[/code] for both colliding objects, the physics engine "
"will use the highest friction."
msgstr ""
-"如果 [code]true[/code],当两个物体碰撞时,物ç†å¼•擎将使用标记为“粗糙â€çš„物体的"
-"摩擦。如果 [code]false[/code],物ç†å¼•擎将使用所有碰撞物体的最低摩擦力æ¥ä»£æ›¿ã€‚"
-"如果两个碰撞的对象都为 [code]true[/code],物ç†å¼•擎将使用最高的摩擦力。"
+"如果为 [code]true[/code],当两个物体碰撞时,物ç†å¼•擎将使用标记为“粗糙â€çš„物体"
+"的摩擦。如果 [code]false[/code],物ç†å¼•擎将使用所有碰撞物体的最低摩擦力æ¥ä»£"
+"替。如果两个碰撞的对象都为 [code]true[/code],物ç†å¼•擎将使用最高的摩擦力。"
#: doc/classes/PhysicsServer.xml
msgid "Server interface for low-level physics access."
@@ -55642,23 +55996,23 @@ msgstr ""
#: doc/classes/PhysicsServer.xml
msgid "Creates an [Area]."
-msgstr "创建一个[Area]区域。"
+msgstr "创建一个 [Area] 区域。"
#: doc/classes/PhysicsServer.xml
msgid ""
"Returns an area parameter value. A list of available parameters is on the "
"[enum AreaParameter] constants."
-msgstr "è¿”å›žåŒºåŸŸå‚æ•°å€¼ã€‚å¯ç”¨å‚数列表ä½äºŽ[enum AreaParameter]常é‡ä¸Šã€‚"
+msgstr "è¿”å›žåŒºåŸŸå‚æ•°å€¼ã€‚å¯ç”¨å‚数列表ä½äºŽ [enum AreaParameter] 常é‡ä¸Šã€‚"
#: doc/classes/PhysicsServer.xml
msgid "If [code]true[/code], area collides with rays."
-msgstr "如果[code]true[/code],则区域与光线碰撞。"
+msgstr "如果为 [code]true[/code],则区域与光线碰撞。"
#: doc/classes/PhysicsServer.xml
msgid ""
"Sets the value for an area parameter. A list of available parameters is on "
"the [enum AreaParameter] constants."
-msgstr "设置é¢ç§¯å‚数的值。å¯ç”¨å‚数列表ä½äºŽ[enum AreaParameter]常é‡ä¸Šã€‚"
+msgstr "设置é¢ç§¯å‚数的值。å¯ç”¨å‚数列表ä½äºŽ [enum AreaParameter] 常é‡ä¸Šã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Sets object pickable with rays."
@@ -55669,7 +56023,7 @@ msgid ""
"Sets the space override mode for the area. The modes are described in the "
"[enum AreaSpaceOverrideMode] constants."
msgstr ""
-"设置区域的空间替代模å¼ã€‚[enum AreaSpaceOverrideMode]常é‡ä¸­æè¿°äº†è¿™äº›æ¨¡å¼ã€‚"
+"设置区域的空间替代模å¼ã€‚[enum AreaSpaceOverrideMode] 常é‡ä¸­æè¿°äº†è¿™äº›æ¨¡å¼ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
@@ -55687,7 +56041,7 @@ msgid ""
"BodyMode] constants, for the type of body created. Additionally, the body "
"can be created in sleeping state to save processing time."
msgstr ""
-"创建物ç†ä½“ã€‚å¯¹äºŽåˆ›å»ºçš„ç‰©ä½“ç±»åž‹ï¼Œç¬¬ä¸€ä¸ªå‚æ•°å¯ä»¥æ˜¯[enum BodyMode]常é‡ä¸­çš„任何"
+"创建物ç†ä½“ã€‚å¯¹äºŽåˆ›å»ºçš„ç‰©ä½“ç±»åž‹ï¼Œç¬¬ä¸€ä¸ªå‚æ•°å¯ä»¥æ˜¯ [enum BodyMode] 常é‡ä¸­çš„任何"
"值。此外,物体å¯ä»¥åœ¨ä¼‘眠状æ€ä¸‹åˆ›å»ºï¼Œä»¥èŠ‚çœå¤„ç†æ—¶é—´ã€‚"
#: doc/classes/PhysicsServer.xml
@@ -55702,7 +56056,7 @@ msgstr ""
msgid ""
"Returns the value of a body parameter. A list of available parameters is on "
"the [enum BodyParameter] constants."
-msgstr "è¿”å›žç‰©ä½“å‚æ•°çš„值。å¯ç”¨å‚数列表ä½äºŽ[enum BodyParameter]常é‡ä¸Šã€‚"
+msgstr "è¿”å›žç‰©ä½“å‚æ•°çš„值。å¯ç”¨å‚数列表ä½äºŽ [enum BodyParameter] 常é‡ä¸Šã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
@@ -55728,26 +56082,26 @@ msgid ""
"Continuous collision detection tries to predict where a moving body will "
"collide, instead of moving it and correcting its movement if it collided."
msgstr ""
-"如果[code]true[/code],则å¯ç”¨è¿žç»­ç¢°æ’žæ£€æµ‹æ¨¡å¼ã€‚\n"
+"如果为 [code]true[/code],则å¯ç”¨è¿žç»­ç¢°æ’žæ£€æµ‹æ¨¡å¼ã€‚\n"
"连续碰撞检测å°è¯•预测è¿åŠ¨ç‰©ä½“ç¢°æ’žçš„ä½ç½®ï¼Œè€Œä¸æ˜¯åœ¨ç¢°æ’žæ—¶ç§»åŠ¨ç‰©ä½“å¹¶çº æ­£å…¶è¿åŠ¨ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Sets the body mode, from one of the [enum BodyMode] constants."
-msgstr "从[enum BodyMode]常é‡ä¹‹ä¸€è®¾ç½®ä¸»ä½“模å¼ã€‚"
+msgstr "从 [enum BodyMode] 常é‡ä¹‹ä¸€è®¾ç½®ä¸»ä½“模å¼ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
"Sets a body parameter. A list of available parameters is on the [enum "
"BodyParameter] constants."
-msgstr "è®¾ç½®ç‰©ä½“å‚æ•°ã€‚å¯ç”¨å‚数列表ä½äºŽ[enum BodyParameter]常é‡ä¸Šã€‚"
+msgstr "è®¾ç½®ç‰©ä½“å‚æ•°ã€‚å¯ç”¨å‚数列表ä½äºŽ [enum BodyParameter] 常é‡ä¸Šã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Sets the body pickable with rays if [code]enabled[/code] is set."
-msgstr "如果设置了[code]enabled[/code],则设置å¯ä½¿ç”¨å…‰çº¿æ‹¾å–的物体。"
+msgstr "如果设置了 [code]enabled[/code],则设置å¯ä½¿ç”¨å…‰çº¿æ‹¾å–的物体。"
#: doc/classes/PhysicsServer.xml
msgid "Sets a body state (see [enum BodyState] constants)."
-msgstr "设置主体状æ€ï¼ˆè¯·å‚阅[enum BodyState]常é‡ï¼‰ã€‚"
+msgstr "设置主体状æ€ï¼ˆè§ [enum BodyState] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
@@ -55761,12 +56115,12 @@ msgstr ""
#: doc/classes/PhysicsServer.xml
msgid ""
"Gets a cone_twist_joint parameter (see [enum ConeTwistJointParam] constants)."
-msgstr "获å–åœ†é”¥ä½“æ‰­æ›²å…³èŠ‚å‚æ•°ï¼ˆè¯·å‚阅[enum ConeTwistJointParam]常é‡ï¼‰ã€‚"
+msgstr "获å–åœ†é”¥ä½“æ‰­æ›²å…³èŠ‚å‚æ•°ï¼ˆè§ [enum ConeTwistJointParam] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
"Sets a cone_twist_joint parameter (see [enum ConeTwistJointParam] constants)."
-msgstr "è®¾ç½®åœ†é”¥ä½“æ‰­æ›²å…³èŠ‚å‚æ•°ï¼ˆè¯·å‚阅[enum ConeTwistJointParam]常é‡ï¼‰ã€‚"
+msgstr "è®¾ç½®åœ†é”¥ä½“æ‰­æ›²å…³èŠ‚å‚æ•°ï¼ˆè§ [enum ConeTwistJointParam] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
@@ -55780,25 +56134,24 @@ msgstr ""
#: doc/classes/PhysicsServer.xml
msgid ""
"Gets a generic_6_DOF_joint flag (see [enum G6DOFJointAxisFlag] constants)."
-msgstr "获å–generic_6_DOF_joit flag(请å‚阅[enum G6DOFJointAxisFlag]常é‡ï¼‰ã€‚"
+msgstr "èŽ·å– generic_6_DOF_joit æ ‡å¿—ï¼ˆè§ [enum G6DOFJointAxisFlag] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
"Gets a generic_6_DOF_joint parameter (see [enum G6DOFJointAxisParam] "
"constants)."
-msgstr ""
-"èŽ·å– generic_6_DOF_joint 傿•°ï¼ˆè¯·å‚阅[enum G6DOFJointAxisParam]常é‡ï¼‰ã€‚"
+msgstr "èŽ·å– generic_6_DOF_joint 傿•°ï¼ˆè§ [enum G6DOFJointAxisParam] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
"Sets a generic_6_DOF_joint flag (see [enum G6DOFJointAxisFlag] constants)."
-msgstr "设置generic_6_DOF_joint flag(请å‚阅[enum G6DOFJointAxisFlag]常é‡ï¼‰ã€‚"
+msgstr "设置 generic_6_DOF_joint æ ‡å¿—ï¼ˆè§ [enum G6DOFJointAxisFlag] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
"Sets a generic_6_DOF_joint parameter (see [enum G6DOFJointAxisParam] "
"constants)."
-msgstr "设置 generic_6_DOF_joint傿•°ï¼ˆè¯·å‚阅[enum G6DOFJointAxisParam]常é‡ï¼‰ã€‚"
+msgstr "设置 generic_6_DOF_joint 傿•°ï¼ˆè§ [enum G6DOFJointAxisParam] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
@@ -55811,39 +56164,39 @@ msgstr ""
#: doc/classes/PhysicsServer.xml
msgid "Gets a hinge_joint flag (see [enum HingeJointFlag] constants)."
-msgstr "获å–铰链关节标志(请å‚阅[enum HingeJointFlag]常é‡ï¼‰ã€‚"
+msgstr "èŽ·å– hinge_joint æ ‡å¿—ï¼ˆè§ [enum HingeJointFlag] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Gets a hinge_joint parameter (see [enum HingeJointParam])."
-msgstr "获å–é“°é“¾å…³èŠ‚å‚æ•°ï¼ˆè¯·å‚阅[enum HingeJointParam])。"
+msgstr "èŽ·å– hinge_joint 傿•°ï¼ˆè§ [enum HingeJointParam])。"
#: doc/classes/PhysicsServer.xml
msgid "Sets a hinge_joint flag (see [enum HingeJointFlag] constants)."
-msgstr "设置铰链关节标志(请å‚阅[enum HingeJointFlag]常é‡ï¼‰ã€‚"
+msgstr "设置 hinge_joint æ ‡å¿—ï¼ˆè§ [enum HingeJointFlag] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Sets a hinge_joint parameter (see [enum HingeJointParam] constants)."
-msgstr "è®¾ç½®é“°é“¾å…³èŠ‚å‚æ•°ï¼ˆè¯·å‚阅[enum HingeJointParam]常é‡ï¼‰ã€‚"
+msgstr "设置 hinge_joint 傿•°ï¼ˆè§ [enum HingeJointParam] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Creates a [ConeTwistJoint]."
-msgstr "创建一个[ConeTwistJoint]。"
+msgstr "创建一个 [ConeTwistJoint]。"
#: doc/classes/PhysicsServer.xml
msgid "Creates a [Generic6DOFJoint]."
-msgstr "创建一个 [Generic6DOFJoint]通用6å‘关节。"
+msgstr "创建一个 [Generic6DOFJoint] 通用 6 å‘关节。"
#: doc/classes/PhysicsServer.xml
msgid "Creates a [HingeJoint]."
-msgstr "创建一个 [HingeJoint]关节。"
+msgstr "创建一个 [HingeJoint] 铰链关节。"
#: doc/classes/PhysicsServer.xml
msgid "Creates a [PinJoint]."
-msgstr "创建一个 [PinJoint]图钉关节。"
+msgstr "创建一个 [PinJoint] 图钉关节。"
#: doc/classes/PhysicsServer.xml
msgid "Creates a [SliderJoint]."
-msgstr "创建一个 [SliderJoint]关节。"
+msgstr "创建一个 [SliderJoint] 关节。"
#: doc/classes/PhysicsServer.xml
msgid "Gets the priority value of the Joint."
@@ -55860,32 +56213,32 @@ msgstr "设置关节的优先级值。"
#: doc/classes/PhysicsServer.xml
msgid ""
"Returns position of the joint in the local space of body a of the joint."
-msgstr "返回关节在关节物体A的局部空间中的ä½ç½®ã€‚"
+msgstr "返回关节在关节物体 A 的局部空间中的ä½ç½®ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
"Returns position of the joint in the local space of body b of the joint."
-msgstr "返回关节在关节物体B的局部空间中的ä½ç½®ã€‚"
+msgstr "返回关节在关节物体 B 的局部空间中的ä½ç½®ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Gets a pin_joint parameter (see [enum PinJointParam] constants)."
-msgstr "获å–pin_joint傿•°ï¼ˆè¯·å‚阅[enum PinJointParam]常é‡ï¼‰ã€‚"
+msgstr "èŽ·å– pin_joint 傿•°ï¼ˆè§ [enum PinJointParam] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Sets position of the joint in the local space of body a of the joint."
-msgstr "设置关节在关节物体A的局部空间中的ä½ç½®ã€‚"
+msgstr "设置关节在关节物体 A 的局部空间中的ä½ç½®ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Sets position of the joint in the local space of body b of the joint."
-msgstr "设置关节在关节物体B的局部空间中的ä½ç½®ã€‚"
+msgstr "设置关节在关节物体 B 的局部空间中的ä½ç½®ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Sets a pin_joint parameter (see [enum PinJointParam] constants)."
-msgstr "设置pin_joint傿•°ï¼ˆè¯·å‚阅[enum PinJointParam]常é‡ï¼‰ã€‚"
+msgstr "设置 pin_joint 傿•°ï¼ˆè§ [enum PinJointParam] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Activates or deactivates the 3D physics engine."
-msgstr "激活或åœç”¨3D物ç†å¼•擎。"
+msgstr "激活或åœç”¨ 3D 物ç†å¼•擎。"
#: doc/classes/PhysicsServer.xml
msgid ""
@@ -55907,16 +56260,16 @@ msgid ""
"body or an area. To do so, you must use [method area_set_shape] or [method "
"body_set_shape]."
msgstr ""
-"创建一个[enum ShapeType]ç±»åž‹çš„å½¢çŠ¶ã€‚ä¸æŠŠå®ƒåˆ†é…给一个体或一个区域。è¦åšåˆ°è¿™ä¸€"
-"点,你必须使用[method area_set_shape]或[method body_set_shape]。"
+"创建一个 [enum ShapeType] ç±»åž‹çš„å½¢çŠ¶ã€‚ä¸æŠŠå®ƒåˆ†é…给一个体或一个区域。è¦åšåˆ°è¿™"
+"一点,你必须使用 [method area_set_shape] 或 [method body_set_shape]。"
#: doc/classes/PhysicsServer.xml
msgid "Returns the type of shape (see [enum ShapeType] constants)."
-msgstr "返回形状的类型(请å‚阅[enum ShapeType]常é‡ï¼‰ã€‚"
+msgstr "è¿”å›žå½¢çŠ¶çš„ç±»åž‹ï¼ˆè§ [enum ShapeType] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "Gets a slider_joint parameter (see [enum SliderJointParam] constants)."
-msgstr "获å–slider_joint傿•°ï¼ˆè¯·å‚阅[enum SliderJointParam]常é‡ï¼‰ã€‚"
+msgstr "èŽ·å– slider_joint 傿•°ï¼ˆè§ [enum SliderJointParam] 常é‡ï¼‰ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
@@ -55929,11 +56282,11 @@ msgstr ""
msgid ""
"Sets the value for a space parameter. A list of available parameters is on "
"the [enum SpaceParameter] constants."
-msgstr "è®¾ç½®ç©ºé—´å‚æ•°çš„值。å¯ç”¨å‚数列表ä½äºŽ[enum SpaceParameter]常é‡ä¸Šã€‚"
+msgstr "è®¾ç½®ç©ºé—´å‚æ•°çš„值。å¯ç”¨å‚数列表ä½äºŽ [enum SpaceParameter] 常é‡ä¸Šã€‚"
#: doc/classes/PhysicsServer.xml
msgid "The [Joint] is a [PinJoint]."
-msgstr "该[Joint] 是 [PinJoint]。"
+msgstr "该 [Joint] 是 [PinJoint]。"
#: doc/classes/PhysicsServer.xml
msgid "The [Joint] is a [HingeJoint]."
@@ -55973,7 +56326,7 @@ msgstr ""
msgid ""
"If above 0, this value is the maximum value for an impulse that this Joint "
"puts on its ends."
-msgstr "如果大于0,这个值就是这个关节对其两端施加的冲é‡çš„æœ€å¤§å€¼ã€‚"
+msgstr "如果大于 0,这个值就是这个关节对其两端施加的冲é‡çš„æœ€å¤§å€¼ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "The maximum rotation across the Hinge."
@@ -55985,7 +56338,7 @@ msgstr "é“°é“¾ä¸Šçš„æœ€å°æ—‹è½¬ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "If [code]true[/code], the Hinge has a maximum and a minimum rotation."
-msgstr "如果[code]true[/code]ï¼Œé“°é“¾å…·æœ‰æœ€å¤§å’Œæœ€å°æ—‹è½¬ã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œé“°é“¾å…·æœ‰æœ€å¤§å’Œæœ€å°æ—‹è½¬ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "If [code]true[/code], a motor turns the Hinge."
@@ -56131,7 +56484,7 @@ msgstr "线性马达在试图达到目标速度时å¯ä»¥æ–½åŠ çš„æœ€å¤§åŠ›ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "A factor that gets multiplied onto all rotations across the axes."
-msgstr "一个乘以所有轴旋转的因å­ã€‚"
+msgstr "乘以所有轴旋转的因å­ã€‚"
#: doc/classes/PhysicsServer.xml
msgid ""
@@ -56161,7 +56514,7 @@ msgstr "设置时,存在跨这些轴的线性马达,以指定的速度为目
#: doc/classes/PhysicsServer.xml
msgid "The [Shape] is a [PlaneShape]."
-msgstr "该[Shape] 是 [PlaneShape]。"
+msgstr "该 [Shape] 是 [PlaneShape]。"
#: doc/classes/PhysicsServer.xml
msgid "The [Shape] is a [RayShape]."
@@ -56211,11 +56564,11 @@ msgstr "设置将用于碰撞/相交查询的 [Shape]。"
#: doc/classes/PhysicsShapeQueryParameters.xml
msgid "If [code]true[/code], the query will take [Area]s into account."
-msgstr "如果[code]true[/code],查询将考虑 [Area]。"
+msgstr "如果为 [code]true[/code],查询将考虑 [Area]。"
#: doc/classes/PhysicsShapeQueryParameters.xml
msgid "If [code]true[/code], the query will take [PhysicsBody]s into account."
-msgstr "如果 [code]true[/code],则查询将考虑 [PhysicsBody]。"
+msgstr "如果为 [code]true[/code],则查询将考虑 [PhysicsBody]。"
#: doc/classes/PinJoint.xml
msgid "Pin joint for 3D PhysicsBodies."
@@ -56226,7 +56579,7 @@ msgid ""
"Pin joint for 3D rigid bodies. It pins 2 bodies (rigid or static) together. "
"See also [Generic6DOFJoint]."
msgstr ""
-"3Dåˆšä½“çš„é’‰å…³èŠ‚ã€‚å®ƒå°†ä¸¤ä¸ªç‰©ä½“ï¼ˆåˆšä½“æˆ–é™æ€ä½“)钉在一起。å‚阅"
+"3D åˆšä½“çš„é’‰å…³èŠ‚ã€‚å®ƒå°†ä¸¤ä¸ªç‰©ä½“ï¼ˆåˆšä½“æˆ–é™æ€ä½“)钉在一起。å¦è¯·å‚阅 "
"[Generic6DOFJoint]。"
#: doc/classes/PinJoint.xml
@@ -56245,7 +56598,7 @@ msgstr "è¢«é’‰åœ¨ä¸€èµ·çš„ç‰©ä½“ä¹‹é—´ä¿æŒå…±é€Ÿçš„力。越高,力越大。
msgid ""
"If above 0, this value is the maximum value for an impulse that this Joint "
"produces."
-msgstr "如果大于0,这个值就是此关节产生的冲é‡çš„æœ€å¤§å€¼ã€‚"
+msgstr "如果大于 0,这个值就是此关节产生的冲é‡çš„æœ€å¤§å€¼ã€‚"
#: doc/classes/PinJoint2D.xml
msgid "Pin Joint for 2D shapes."
@@ -56273,9 +56626,9 @@ msgid ""
"the plane is considered the side of the plane towards where the normal is "
"pointing."
msgstr ""
-"å¹³é¢è¡¨ç¤ºæ ‡å‡†åŒ–çš„å¹³é¢æ–¹ç¨‹ã€‚åŸºæœ¬ä¸Šï¼Œâ€œæ³•çº¿â€æ˜¯å¹³é¢çš„æ³•线(aã€bã€c归一化),而“dâ€æ˜¯"
-"原点到平é¢çš„è·ç¦»(åœ¨â€œæ³•çº¿â€æ–¹å‘)ã€‚â€œä¸Šæ–¹â€æˆ–“上方â€å¹³é¢è¢«è®¤ä¸ºæ˜¯æ³•线指å‘的平é¢ä¸€"
-"侧。"
+"å¹³é¢è¡¨ç¤ºæ ‡å‡†åŒ–çš„å¹³é¢æ–¹ç¨‹ã€‚åŸºæœ¬ä¸Šï¼Œâ€œæ³•çº¿â€æ˜¯å¹³é¢çš„æ³•线(归一化的 aã€bã€c),"
+"而“dâ€æ˜¯åŽŸç‚¹åˆ°å¹³é¢çš„è·ç¦»ï¼ˆåœ¨â€œæ³•çº¿â€æ–¹å‘ï¼‰ã€‚â€œä¸Šæ–¹â€æˆ–“上方â€å¹³é¢è¢«è®¤ä¸ºæ˜¯æ³•线指å‘çš„"
+"å¹³é¢ä¸€ä¾§ã€‚"
#: doc/classes/Plane.xml
msgid ""
@@ -56303,7 +56656,7 @@ msgstr "返回平é¢çš„中心。"
msgid ""
"Returns the shortest distance from the plane to the position [code]point[/"
"code]."
-msgstr "返回从平é¢åˆ°ä½ç½®[code]point[/code]的最短è·ç¦»ã€‚"
+msgstr "返回从平é¢åˆ°ä½ç½® [code]point[/code] 的最短è·ç¦»ã€‚"
#: doc/classes/Plane.xml
msgid ""
@@ -56360,7 +56713,7 @@ msgstr ""
#: doc/classes/Plane.xml
msgid ""
"Returns [code]true[/code] if [code]point[/code] is located above the plane."
-msgstr "如果[code]point[/code]ä½äºŽå¹³é¢ä¸Šæ–¹ï¼Œåˆ™è¿”回 [code]true[/code]。"
+msgstr "如果 [code]point[/code] ä½äºŽå¹³é¢ä¸Šæ–¹ï¼Œåˆ™è¿”回 [code]true[/code]。"
#: doc/classes/Plane.xml
msgid "Returns a copy of the plane, normalized."
@@ -56370,7 +56723,7 @@ msgstr "返回平é¢çš„一个标准化副本。"
msgid ""
"Returns the orthogonal projection of [code]point[/code] into a point in the "
"plane."
-msgstr "返回 [code]点[/code]在平é¢ä¸Šçš„æ­£äº¤æŠ•影。"
+msgstr "返回 [code]point[/code] 在平é¢ä¸Šçš„æ­£äº¤æŠ•影。"
#: doc/classes/Plane.xml
msgid ""
@@ -56380,9 +56733,9 @@ msgid ""
"[code]d[/code], while the [code](a, b, c)[/code] coordinates are represented "
"by the [member normal] property."
msgstr ""
-"从原点到平é¢çš„è·ç¦»ï¼Œæ²¿[member normal]æ–¹å‘。这个值通常是éžè´Ÿçš„。\n"
-"在平é¢[code]ax + by + cz = d[/code]çš„æ ‡é‡æ–¹ç¨‹ä¸­ï¼Œè¿™æ˜¯[code]d[/code],而[code]"
-"(a, b, c)[/code]åæ ‡ç”±[member normal]属性表示。"
+"从原点到平é¢çš„è·ç¦»ï¼Œæ²¿ [member normal] æ–¹å‘。这个值通常是éžè´Ÿçš„。\n"
+"åœ¨å¹³é¢ [code]ax + by + cz = d[/code] çš„æ ‡é‡æ–¹ç¨‹ä¸­ï¼Œè¿™æ˜¯ [code]d[/code],而 "
+"[code](a, b, c)[/code] åæ ‡ç”± [member normal] 属性表示。"
#: doc/classes/Plane.xml
msgid ""
@@ -56392,20 +56745,20 @@ msgid ""
"property."
msgstr ""
"å¹³é¢çš„æ³•线,必须归一化。\n"
-"在平é¢[code]ax + by + cz = d[/code]çš„æ ‡é‡æ–¹ç¨‹ä¸­ï¼Œè¿™æ˜¯å‘é‡[code](a, b, c)[/"
-"code],其中[code]d[/code]是[member d]属性。"
+"åœ¨å¹³é¢ [code]ax + by + cz = d[/code] çš„æ ‡é‡æ–¹ç¨‹ä¸­ï¼Œè¿™æ˜¯å‘é‡ [code](a, b, c)[/"
+"code],其中 [code]d[/code] 是 [member d] 属性。"
#: doc/classes/Plane.xml
msgid "The X component of the plane's [member normal] vector."
-msgstr "å¹³é¢çš„[member normal]å‘é‡çš„X分é‡ã€‚"
+msgstr "平颿³•å‘é‡ [member normal] çš„ X 分é‡ã€‚"
#: doc/classes/Plane.xml
msgid "The Y component of the plane's [member normal] vector."
-msgstr "å¹³é¢çš„[member normal]å‘é‡çš„Y分é‡ã€‚"
+msgstr "平颿³•å‘é‡ [member normal] çš„ Y 分é‡ã€‚"
#: doc/classes/Plane.xml
msgid "The Z component of the plane's [member normal] vector."
-msgstr "å¹³é¢çš„[member normal]å‘é‡çš„Z分é‡ã€‚"
+msgstr "平颿³•å‘é‡ [member normal] çš„ Z 分é‡ã€‚"
#: doc/classes/Plane.xml
msgid "A plane that extends in the Y and Z axes (normal vector points +X)."
@@ -56521,7 +56874,7 @@ msgid ""
"canvas_polygon_index_buffer_size_kb]."
msgstr ""
"Polygon2D 由一组点定义。æ¯ä¸ªç‚¹éƒ½è¿žæŽ¥åˆ°ä¸‹ä¸€ä¸ªç‚¹ï¼Œæœ€åŽä¸€ä¸ªç‚¹è¿žæŽ¥åˆ°ç¬¬ä¸€ä¸ªç‚¹ï¼Œä»Ž"
-"而形æˆå°é—­çš„多边形。 Polygon2D å¯ä»¥å¡«å……颜色(纯色或æ¸å˜è‰²ï¼‰æˆ–填充给定的纹"
+"而形æˆå°é—­çš„多边形。Polygon2D å¯ä»¥å¡«å……颜色(纯色或æ¸å˜è‰²ï¼‰æˆ–填充给定的纹"
"ç†ã€‚\n"
"[b]注æ„:[/b]默认情况下,Godot 一次最多åªèƒ½ç»˜åˆ¶ 4096 个多边形点。è¦å¢žåŠ æ­¤é™"
"制,请打开项目设置并增加 [member ProjectSettings.rendering/limits/buffers/"
@@ -56531,35 +56884,35 @@ msgstr ""
#: doc/classes/Polygon2D.xml
msgid ""
"Adds a bone with the specified [code]path[/code] and [code]weights[/code]."
-msgstr "添加指定[code]path[/code]和[code]weights[/code]的骨骼."
+msgstr "添加指定 [code]path[/code] 和 [code]weights[/code] 的骨骼。"
#: doc/classes/Polygon2D.xml
msgid "Removes all bones from this [Polygon2D]."
-msgstr "删除这个[Polygon2D]的所有骨骼."
+msgstr "删除这个 [Polygon2D] 的所有骨骼。"
#: doc/classes/Polygon2D.xml
msgid "Removes the specified bone from this [Polygon2D]."
-msgstr "从这个[Polygon2D]中删除指定的骨骼."
+msgstr "从这个 [Polygon2D] 中删除指定的骨骼。"
#: doc/classes/Polygon2D.xml
msgid "Returns the number of bones in this [Polygon2D]."
-msgstr "返回这个[Polygon2D]中骨骼的数é‡."
+msgstr "返回这个 [Polygon2D] 中骨骼的数é‡ã€‚"
#: doc/classes/Polygon2D.xml
msgid "Returns the path to the node associated with the specified bone."
-msgstr "返回与指定骨骼相关è”的节点的路径."
+msgstr "返回与指定骨骼相关è”的节点的路径。"
#: doc/classes/Polygon2D.xml
msgid "Returns the height values of the specified bone."
-msgstr "返回指定骨骼的高度值."
+msgstr "返回指定骨骼的高度值。"
#: doc/classes/Polygon2D.xml
msgid "Sets the path to the node associated with the specified bone."
-msgstr "设置与指定骨骼相关è”的节点的路径."
+msgstr "设置与指定骨骼相关è”的节点的路径。"
#: doc/classes/Polygon2D.xml
msgid "Sets the weight values for the specified bone."
-msgstr "设置指定骨骼的æƒé‡å€¼."
+msgstr "设置指定骨骼的æƒé‡å€¼ã€‚"
#: doc/classes/Polygon2D.xml
msgid ""
@@ -56602,12 +56955,12 @@ msgid ""
"If [code]true[/code], polygon will be inverted, containing the area outside "
"the defined points and extending to the [code]invert_border[/code]."
msgstr ""
-"如果为 [code]true[/code],则多边形将å转,包å«å®šä¹‰ç‚¹ä¹‹å¤–的区域,并扩展到"
-"[code]invert_border[/code](å转边界)."
+"如果为 [code]true[/code],则多边形将å转,包å«å®šä¹‰ç‚¹ä¹‹å¤–的区域,并扩展到 "
+"[code]invert_border[/code](å转边界)。"
#: doc/classes/Polygon2D.xml
msgid "The offset applied to each vertex."
-msgstr "应用于æ¯ä¸ªé¡¶ç‚¹çš„ä½ç½®åç§»é‡."
+msgstr "应用于æ¯ä¸ªé¡¶ç‚¹çš„ä½ç½®åç§»é‡ã€‚"
#: doc/classes/Polygon2D.xml
msgid ""
@@ -56717,11 +57070,12 @@ msgstr ""
msgid ""
"Constructs a new [PoolByteArray]. Optionally, you can pass in a generic "
"[Array] that will be converted."
-msgstr "构建新的[PoolByteArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„[Array],它将被转æ¢ã€‚"
+msgstr ""
+"构建新的 [PoolByteArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„ [Array],它将被转æ¢ã€‚"
#: doc/classes/PoolByteArray.xml
msgid "Appends a [PoolByteArray] at the end of this array."
-msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ [PoolByteArray]。"
+msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ  [PoolByteArray]。"
#: doc/classes/PoolByteArray.xml
msgid ""
@@ -56737,7 +57091,7 @@ msgid ""
"[code]buffer_size[/code] to the size of the uncompressed data. Set the "
"compression mode using one of [enum File.CompressionMode]'s constants."
msgstr ""
-"返回新的 [PoolByteArray] 解压数æ®ã€‚ [code]buffer_size[/code] 设置未压缩数æ®çš„"
+"返回新的 [PoolByteArray] 解压数æ®ã€‚[code]buffer_size[/code] 设置未压缩数æ®çš„"
"大å°ã€‚使用 [enum File.CompressionMode] 常é‡ä¹‹ä¸€è®¾ç½®åŽ‹ç¼©æ¨¡å¼ã€‚"
#: doc/classes/PoolByteArray.xml
@@ -56812,7 +57166,7 @@ msgid ""
"[b]Note:[/b] This is equivalent to using the [code]in[/code] operator."
msgstr ""
"如果该数组包å«ç»™å®šçš„值,则返回 [code]true[/code]。\n"
-"[b]注æ„:[/b]与使用 [code]in[/code] æ“作符等价。"
+"[b]注æ„:[/b]相当于使用 [code]in[/code] æ“作符。"
#: doc/classes/PoolByteArray.xml
msgid ""
@@ -56866,6 +57220,14 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr "改å˜ç»™å®šç´¢å¼•处的字节。"
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+#, fuzzy
+msgid "Sorts the elements of the array in ascending order."
+msgstr "从数组中删除ä½äºŽç´¢å¼•的元素。"
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -56928,11 +57290,11 @@ msgid ""
"Constructs a new [PoolColorArray]. Optionally, you can pass in a generic "
"[Array] that will be converted."
msgstr ""
-"构建新的[PoolColorArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„[Array],它将被转æ¢ã€‚"
+"构建新的 [PoolColorArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„ [Array],它将被转æ¢ã€‚"
#: doc/classes/PoolColorArray.xml
msgid "Appends a [PoolColorArray] at the end of this array."
-msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ ä¸€ä¸ª[PoolColorArray]。"
+msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ ä¸€ä¸ª [PoolColorArray]。"
#: doc/classes/PoolColorArray.xml doc/classes/PoolIntArray.xml
msgid "Appends a value to the array."
@@ -56950,7 +57312,7 @@ msgstr ""
#: doc/classes/PoolColorArray.xml
msgid "Changes the [Color] at the given index."
-msgstr "更改给定索引处的[Color]。"
+msgstr "更改给定索引处的 [Color]。"
#: doc/classes/PoolIntArray.xml
msgid "A pooled array of integers ([int])."
@@ -57012,18 +57374,19 @@ msgstr ""
msgid ""
"Constructs a new [PoolIntArray]. Optionally, you can pass in a generic "
"[Array] that will be converted."
-msgstr "构建新的[PoolIntArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„[Array],它将被转æ¢ã€‚"
+msgstr ""
+"构建新的 [PoolIntArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„ [Array],它将被转æ¢ã€‚"
#: doc/classes/PoolIntArray.xml
msgid "Appends a [PoolIntArray] at the end of this array."
-msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ [PoolIntArray]。"
+msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ  [PoolIntArray]。"
#: doc/classes/PoolIntArray.xml
msgid ""
"Inserts a new int at a given position in the array. The position must be "
"valid, or at the end of the array ([code]idx == size()[/code])."
msgstr ""
-"在数组中的指定ä½ç½®æ’入一个新的int。这个ä½ç½®å¿…须是有效的,或者在数组的末端"
+"在数组中的指定ä½ç½®æ’入一个新的 int。这个ä½ç½®å¿…须是有效的,或者在数组的末端"
"([code]idx == size()[/code])。"
#: doc/classes/PoolIntArray.xml
@@ -57092,11 +57455,12 @@ msgstr ""
msgid ""
"Constructs a new [PoolRealArray]. Optionally, you can pass in a generic "
"[Array] that will be converted."
-msgstr "构建新的[PoolRealArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„[Array],它将被转æ¢ã€‚"
+msgstr ""
+"构建新的 [PoolRealArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„ [Array],它将被转æ¢ã€‚"
#: doc/classes/PoolRealArray.xml
msgid "Appends a [PoolRealArray] at the end of this array."
-msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ [PoolRealArray]。"
+msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ  [PoolRealArray]。"
#: doc/classes/PoolRealArray.xml
msgid "Changes the float at the given index."
@@ -57153,11 +57517,11 @@ msgid ""
"Constructs a new [PoolStringArray]. Optionally, you can pass in a generic "
"[Array] that will be converted."
msgstr ""
-"构建新的[PoolStringArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„[Array],它将被转æ¢ã€‚"
+"构建新的 [PoolStringArray]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„ [Array],它将被转æ¢ã€‚"
#: doc/classes/PoolStringArray.xml
msgid "Appends a [PoolStringArray] at the end of this array."
-msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ [PoolStringArray]。"
+msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ  [PoolStringArray]。"
#: doc/classes/PoolStringArray.xml
msgid ""
@@ -57172,7 +57536,7 @@ msgstr "在数组的末尾追加字符串元素。"
#: doc/classes/PoolStringArray.xml
msgid "Changes the [String] at the given index."
-msgstr "更改给定索引处的[String]。"
+msgstr "更改给定索引处的 [String]。"
#: doc/classes/PoolVector2Array.xml
msgid "A pooled array of [Vector2]s."
@@ -57232,15 +57596,15 @@ msgid ""
"Constructs a new [PoolVector2Array]. Optionally, you can pass in a generic "
"[Array] that will be converted."
msgstr ""
-"构建新的[PoolVector2Array]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„[Array],它将被转æ¢ã€‚"
+"构建新的 [PoolVector2Array]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„ [Array],它将被转æ¢ã€‚"
#: doc/classes/PoolVector2Array.xml
msgid "Appends a [PoolVector2Array] at the end of this array."
-msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ [PoolVector2Array]。"
+msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ  [PoolVector2Array]。"
#: doc/classes/PoolVector2Array.xml
msgid "Inserts a [Vector2] at the end."
-msgstr "在末尾æ’å…¥[Vector2]。"
+msgstr "在末尾æ’入一个 [Vector2]。"
#: doc/classes/PoolVector2Array.xml
msgid "Changes the [Vector2] at the given index."
@@ -57299,15 +57663,15 @@ msgid ""
"Constructs a new [PoolVector3Array]. Optionally, you can pass in a generic "
"[Array] that will be converted."
msgstr ""
-"构建新的[PoolVector3Array]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„[Array],它将被转æ¢ã€‚"
+"构建新的 [PoolVector3Array]。你å¯ä»¥é€‰æ‹©ä¼ å…¥ä¸€ä¸ªé€šç”¨çš„ [Array],它将被转æ¢ã€‚"
#: doc/classes/PoolVector3Array.xml
msgid "Appends a [PoolVector3Array] at the end of this array."
-msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ [PoolVector3Array]。"
+msgstr "åœ¨è¿™ä¸ªæ•°ç»„çš„æœ€åŽæ·»åŠ  [PoolVector3Array]。"
#: doc/classes/PoolVector3Array.xml
msgid "Inserts a [Vector3] at the end."
-msgstr "在末尾æ’å…¥[Vector3]。"
+msgstr "在末尾æ’入一个 [Vector3]。"
#: doc/classes/PoolVector3Array.xml
msgid "Changes the [Vector3] at the given index."
@@ -57382,8 +57746,8 @@ msgid ""
"ConfirmationDialog.get_cancel] and hide the buttons in question by setting "
"their [member CanvasItem.visible] property to [code]false[/code]."
msgstr ""
-"如果[code]true[/code],当点击事件å‘生在它之外,或者当它收到[code]ui_cancel[/"
-"code]动作事件时,弹出窗å£ä¸ä¼šè¢«éšè—。\n"
+"如果为 [code]true[/code],当点击事件å‘生在它之外,或者当它收到"
+"[code]ui_cancel[/code]动作事件时,弹出窗å£ä¸ä¼šè¢«éšè—。\n"
"[b]注æ„:[/b]å¯ç”¨æ­¤å±žæ€§ä¸ä¼šå½±å“ä»Žæ­¤ç±»ç»§æ‰¿çš„å¯¹è¯æ¡†ä¸­å…³é—­æˆ–å–æ¶ˆæŒ‰é’®çš„行为。作为"
"解决方法,您å¯ä»¥ä½¿ç”¨ [method WindowDialog.get_close_button] 或 [method "
"ConfirmationDialog.get_cancel] 并通过将其 [member CanvasItem.visible] 属性设"
@@ -57421,18 +57785,36 @@ msgstr "PopupDialog æ˜¯å¼¹å‡ºå¯¹è¯æ¡†çš„基类,与 [WindowDialog] 一起。"
#: doc/classes/PopupDialog.xml
msgid "Sets a custom [StyleBox] for the panel of the [PopupDialog]."
-msgstr "为[PopupDialog]çš„é¢æ¿è®¾ç½®è‡ªå®šä¹‰çš„[StyleBox]。"
+msgstr "为 [PopupDialog] çš„é¢æ¿è®¾ç½®è‡ªå®šä¹‰çš„ [StyleBox]。"
#: doc/classes/PopupMenu.xml
msgid "PopupMenu displays a list of options."
-msgstr "PopupMenu(弹出èœå•)显示选项列表."
+msgstr "PopupMenu 会显示一个选项列表。"
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
-msgstr ""
-"[PopupMenu]是一个显示选项列表的[Control].å®ƒä»¬åœ¨å·¥å…·æ æˆ–上下文èœå•中很常用."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
+msgstr ""
+"[PopupMenu] 是会显示一个选项列表的 [Control]。常è§äºŽå·¥å…·æ å’Œä¸Šä¸‹æ–‡èœå•中。\n"
+"[b]å¢žé‡æœç´¢ï¼š[/b]与 [ItemList] å’Œ [Tree] 类似,[PopupMenu] 也支æŒåœ¨èšç„¦æŽ§ä»¶æ—¶"
+"在列表中进行æœç´¢ã€‚按下与æŸä¸ªæ¡ç›®å称首字æ¯ä¸€è‡´çš„æŒ‰é”®ï¼Œå°±ä¼šé€‰ä¸­ä»¥è¯¥å­—æ¯å¼€å¤´çš„"
+"第一个æ¡ç›®ã€‚在此之åŽï¼Œè¿›è¡Œå¢žé‡æœç´¢çš„办法有两ç§ï¼š1)在超时å‰å†æ¬¡æŒ‰ä¸‹åŒä¸€ä¸ªæŒ‰"
+"键,选中以该字æ¯å¼€å¤´çš„下一个æ¡ç›®ã€‚2ï¼‰åœ¨è¶…æ—¶å‰æŒ‰ä¸‹å‰©ä½™å­—æ¯å¯¹åº”的按键,直接匹é…"
+"并选中所需的æ¡ç›®ã€‚这两个动作都会在最åŽä¸€æ¬¡æŒ‰é”®è¶…æ—¶åŽé‡ç½®å›žåˆ—表顶端。你å¯ä»¥é€š"
+"过 [member ProjectSettings.gui/timers/incremental_search_max_interval_msec] "
+"修改超时时长。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57446,13 +57828,14 @@ msgid ""
"built-in checking behavior and must be checked/unchecked manually. See "
"[method set_item_checked] for more info on how to control it."
msgstr ""
-"添加一个新的带有[code]label[/code]æ–‡æœ¬çš„å¯æ£€æŸ¥é¡¹ç›®.\n"
-"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª[code]id[/code]以åŠä¸€ä¸ªå¿«æ·é”®([code]accel[/code])加速.如果没"
-"有æä¾›[code]id[/code],将从索引中创建一个.如果没有æä¾›[code]accel[/code],那么"
-"将为其分é…默认的[code]0[/code].å‚阅 [method get_item_accelerator]了解更多关于"
-"å¿«æ·é”®çš„ä¿¡æ¯.\n"
-"[b]注æ„:[/b]坿£€æŸ¥é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªæ£€æŸ¥æ ‡è®°,但没有任何内置的检查行为,必须手动"
-"æ£€æŸ¥æˆ–å–æ¶ˆæ£€æŸ¥.å‚阅[method set_item_checked]了解更多关于如何控制它的信æ¯."
+"添加一个新的带有 [code]label[/code] 文本的å¯å‹¾é€‰é¡¹ç›®ã€‚\n"
+"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª [code]id[/code] 以åŠä¸€ä¸ªå¿«æ·é”®ï¼ˆ[code]accel[/code])。如果没"
+"有æä¾› [code]id[/code],将从索引中创建一个。如果没有æä¾› [code]accel[/code],"
+"那么将为其分é…默认的 [code]0[/code]。å‚阅 [method get_item_accelerator] 了解"
+"更多关于快æ·é”®çš„ä¿¡æ¯.\n"
+"[b]注æ„:[/b]å¯å‹¾é€‰é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå‹¾é€‰æ ‡è®°ï¼Œä½†æ²¡æœ‰ä»»ä½•内置的检查行为,必须手"
+"åŠ¨å‹¾é€‰æˆ–å–æ¶ˆå‹¾é€‰ã€‚å‚阅 [method set_item_checked] 了解更多关于如何控制它的信"
+"æ¯ã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57464,12 +57847,13 @@ msgid ""
"built-in checking behavior and must be checked/unchecked manually. See "
"[method set_item_checked] for more info on how to control it."
msgstr ""
-"æ·»åŠ ä¸€ä¸ªæ–°çš„å¯æ£€æŸ¥é¡¹ç›®,并将指定的[ShortCut]分é…给它.å°†å¤é€‰æ¡†çš„æ ‡ç­¾è®¾ç½®ä¸º"
-"ShortCutçš„åç§°.\n"
-"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª[code]id[/code].如果没有æä¾›[code]id[/code],将从索引中创建一"
-"个.\n"
-"[b]注æ„:[/b]坿£€æŸ¥é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªæ£€æŸ¥æ ‡è®°,但没有任何内置的检查行为,必须手动"
-"æ£€æŸ¥æˆ–å–æ¶ˆæ£€æŸ¥. å‚阅 [method set_item_checked]了解更多关于如何控制它的信æ¯."
+"æ·»åŠ ä¸€ä¸ªæ–°çš„å¯æ£€æŸ¥é¡¹ç›®,并将指定的 [ShortCut] 分é…给它。将å¤é€‰æ¡†çš„æ ‡ç­¾è®¾ç½®ä¸º "
+"ShortCut çš„å称。\n"
+"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª [code]id[/code]。如果没有æä¾› [code]id[/code],将从索引中创"
+"建一个。\n"
+"[b]注æ„:[/b]坿£€æŸ¥é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªæ£€æŸ¥æ ‡è®°ï¼Œä½†æ²¡æœ‰ä»»ä½•内置的检查行为,必须手"
+"åŠ¨æ£€æŸ¥æˆ–å–æ¶ˆæ£€æŸ¥ã€‚å‚阅 [method set_item_checked] 了解更多关于如何控制它的信"
+"æ¯ã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57484,14 +57868,14 @@ msgid ""
"built-in checking behavior and must be checked/unchecked manually. See "
"[method set_item_checked] for more info on how to control it."
msgstr ""
-"æ·»åŠ ä¸€ä¸ªæ–°çš„å¯æ£€æŸ¥é¡¹ç›®ï¼Œå¸¦æœ‰æ–‡æœ¬[code]label[/code]和图标[code]texture[/"
+"æ·»åŠ ä¸€ä¸ªæ–°çš„å¯æ£€æŸ¥é¡¹ç›®ï¼Œå¸¦æœ‰æ–‡æœ¬ [code]label[/code] 和图标 [code]texture[/"
"code]。\n"
-"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª[code]id[/code],以åŠä¸€ä¸ªåŠ é€Ÿå™¨ï¼ˆ[code]accel[/code])。如果没"
-"有æä¾›[code]id[/code],将从索引中创建一个。如果没有æä¾›[code]accel[/code],那"
-"么默认的[code]0[/code]将被分é…给它。å‚阅[method get_item_accelerator]èŽ·å–æ›´å¤š"
-"关于加速器的信æ¯ã€‚\n"
+"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª [code]id[/code],以åŠä¸€ä¸ªåŠ é€Ÿå™¨ï¼ˆ[code]accel[/code])。如果"
+"没有æä¾› [code]id[/code],将从索引中创建一个。如果没有æä¾› [code]accel[/"
+"code],那么默认的 [code]0[/code] 将被分é…给它。å‚阅 [method "
+"get_item_accelerator] èŽ·å–æ›´å¤šå…³äºŽåŠ é€Ÿå™¨çš„ä¿¡æ¯ã€‚\n"
"[b]注æ„:[/b]å¯é€‰é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå¤é€‰æ ‡è®°ï¼Œä½†æ²¡æœ‰ä»»ä½•内置的检查行为,必须手动"
-"检查/å–æ¶ˆæ£€æŸ¥ã€‚å‚阅[method set_item_checked]èŽ·å–æ›´å¤šå…³äºŽå¦‚何控制它的信æ¯ã€‚"
+"检查/å–æ¶ˆæ£€æŸ¥ã€‚å‚阅 [method set_item_checked] èŽ·å–æ›´å¤šå…³äºŽå¦‚何控制它的信æ¯ã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57504,12 +57888,12 @@ msgid ""
"built-in checking behavior and must be checked/unchecked manually. See "
"[method set_item_checked] for more info on how to control it."
msgstr ""
-"添加一个新的å¯é€‰é¡¹ç›®ï¼Œå¹¶ä¸ºå…¶åˆ†é…指定的[ShortCut]和图标[code]texture[/code]。"
-"å°†å¤é€‰æ¡†çš„æ ‡ç­¾è®¾ç½®ä¸º[ShortCut]çš„å称。\n"
-"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª[code]id[/code]。如果没有æä¾›[code]id[/code],将从索引中创建"
-"一个。\n"
+"添加一个新的å¯é€‰é¡¹ç›®ï¼Œå¹¶ä¸ºå…¶åˆ†é…指定的 [ShortCut] 和图标 [code]texture[/"
+"code]。将å¤é€‰æ¡†çš„æ ‡ç­¾è®¾ç½®ä¸º [ShortCut] çš„å称。\n"
+"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª [code]id[/code]。如果没有æä¾› [code]id[/code],将从索引中创"
+"建一个。\n"
"[b]注æ„:[/b]å¯é€‰é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå¤é€‰æ ‡è®°ï¼Œä½†æ²¡æœ‰ä»»ä½•内置的检查行为,必须手动"
-"检查/å–æ¶ˆæ£€æŸ¥ã€‚å‚阅[method set_item_checked]èŽ·å–æ›´å¤šå…³äºŽå¦‚何控制它的信æ¯ã€‚"
+"检查/å–æ¶ˆæ£€æŸ¥ã€‚å‚阅 [method set_item_checked] èŽ·å–æ›´å¤šå…³äºŽå¦‚何控制它的信æ¯ã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57520,20 +57904,20 @@ msgid ""
"[code]0[/code] will be assigned to it. See [method get_item_accelerator] for "
"more info on accelerators."
msgstr ""
-"添加带有文本[code]lable[/code]和图标[code]texture[/code]的新项目。\n"
-"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª[code]id[/code],以åŠä¸€ä¸ªåŠ é€Ÿå™¨([code]accel[/code])。如果没有"
-"æä¾›[code]id[/code],将从索引中创建一个。如果没有æä¾›[code]accel[/code],则将"
-"为其分é…默认的[code]0[/code]。有关加速器的更多信æ¯ï¼Œè¯·å‚阅[method "
-"get_item_accelerator]。"
+"添加带有文本 [code]lable[/code] 和图标 [code]texture[/code] 的新项目。\n"
+"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ª [code]id[/code],以åŠä¸€ä¸ªå¿«æ·é”®ï¼ˆ[code]accel[/code])。如果"
+"没有æä¾› [code]id[/code],将从索引中创建一个。如果没有æä¾› [code]accel[/"
+"code],则将为其分é…默认的[code]0[/code]。有关快æ·é”®çš„æ›´å¤šä¿¡æ¯ï¼Œè¯·å‚阅 "
+"[method get_item_accelerator]。"
#: doc/classes/PopupMenu.xml
msgid "Same as [method add_icon_check_item], but uses a radio check button."
-msgstr "与[method add_icon_check_item]相åŒï¼Œä½†ä½¿ç”¨å•选按钮。"
+msgstr "与 [method add_icon_check_item] 相åŒï¼Œä½†ä½¿ç”¨å•选按钮。"
#: doc/classes/PopupMenu.xml
msgid ""
"Same as [method add_icon_check_shortcut], but uses a radio check button."
-msgstr "与[method add_icon_check_shortcut]相åŒï¼Œä½†ä½¿ç”¨ä¸€ä¸ªå•选按钮。"
+msgstr "与 [method add_icon_check_shortcut] 相åŒï¼Œä½†ä½¿ç”¨ä¸€ä¸ªå•选按钮。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57542,9 +57926,9 @@ msgid ""
"An [code]id[/code] can optionally be provided. If no [code]id[/code] is "
"provided, one will be created from the index."
msgstr ""
-"æ·»åŠ ä¸€ä¸ªæ–°é¡¹ï¼Œå¹¶åˆ†é…æŒ‡å®šçš„[ShortCut]和图标[code]texture[/code]给它。将å¤é€‰æ¡†"
-"的标签设置为[ShortCut]çš„å称。\n"
-"å¯ä»¥é€‰æ‹©æä¾›[code]id[/code]。如果没有æä¾›[code]id[/code],将从索引中创建一"
+"æ·»åŠ ä¸€ä¸ªæ–°é¡¹ï¼Œå¹¶åˆ†é…æŒ‡å®šçš„ [ShortCut] 和图标 [code]texture[/code] 给它。将å¤"
+"选框的标签设置为 [ShortCut] çš„å称。\n"
+"å¯ä»¥é€‰æ‹©æä¾› [code]id[/code]。如果没有æä¾› [code]id[/code],将从索引中创建一"
"个。"
#: doc/classes/PopupMenu.xml
@@ -57556,10 +57940,10 @@ msgid ""
"[code]0[/code] will be assigned to it. See [method get_item_accelerator] for "
"more info on accelerators."
msgstr ""
-"添加一个带有文本[code]label[/code]的新项目。\n"
-"å¯ä»¥é€‰æ‹©æä¾›[code]id[/code],以åŠåŠ é€Ÿå™¨([code]accel[/code])。如果没有æä¾›"
-"[code]id[/code],将从索引中创建一个。如果没有æä¾›[code]accel[/code],则默认的"
-"[code]0[/code]将被分é…给它。有关加速器的更多信æ¯ï¼Œè¯·å‚阅[method "
+"添加一个带有文本 [code]label[/code] 的新项目。\n"
+"å¯ä»¥é€‰æ‹©æä¾› [code]id[/code],以åŠåŠ é€Ÿå™¨ï¼ˆ[code]accel[/code])。如果没有æä¾› "
+"[code]id[/code],将从索引中创建一个。如果没有æä¾› [code]accel[/code],则默认"
+"çš„ [code]0[/code] 将被分é…给它。有关加速器的更多信æ¯ï¼Œè¯·å‚阅 [method "
"get_item_accelerator]。"
#: doc/classes/PopupMenu.xml
@@ -57575,13 +57959,13 @@ msgid ""
"[code]0[/code] will be assigned to it. See [method get_item_accelerator] for "
"more info on accelerators."
msgstr ""
-"添加一个带有文本[code]label[/code]的新的多状æ€é¡¹ã€‚\n"
-"与普通的二进制项相å,多状æ€é¡¹å¯ä»¥æœ‰ä¸¤ä¸ªä»¥ä¸Šçš„状æ€ï¼Œå¦‚[code]max_states[/code]"
-"æ‰€å®šä¹‰çš„ã€‚æ¯æ¬¡æŒ‰ä¸‹æˆ–激活物å“将增加一个状æ€ã€‚默认值由[code]default_state[/"
-"code]定义。\n"
-"å¯ä»¥é€‰æ‹©æä¾›[code]id[/code],以åŠåŠ é€Ÿå™¨([code]accel[/code])。如果没有æä¾›"
-"[code]id[/code],将从索引中创建一个。如果没有æä¾›[code]accel[/code],则默认的"
-"[code]0[/code]将被分é…给它。有关加速器的更多信æ¯ï¼Œè¯·å‚阅[method "
+"添加一个带有文本 [code]label[/code] 的新的多状æ€é¡¹ã€‚\n"
+"与普通的二进制项相å,多状æ€é¡¹å¯ä»¥æœ‰ä¸¤ä¸ªä»¥ä¸Šçš„状æ€ï¼Œå¦‚ [code]max_states[/"
+"code] æ‰€å®šä¹‰çš„ã€‚æ¯æ¬¡æŒ‰ä¸‹æˆ–激活物å“将增加一个状æ€ã€‚默认值由 "
+"[code]default_state[/code] 定义。\n"
+"å¯ä»¥é€‰æ‹©æä¾› [code]id[/code],以åŠåŠ é€Ÿå™¨ï¼ˆ[code]accel[/code])。如果没有æä¾›"
+"[code]id[/code],将从索引中创建一个。如果没有æä¾› [code]accel[/code],则默认"
+"çš„ [code]0[/code] 将被分é…给它。有关加速器的更多信æ¯ï¼Œè¯·å‚阅 [method "
"get_item_accelerator]。"
#: doc/classes/PopupMenu.xml
@@ -57596,10 +57980,10 @@ msgid ""
"built-in checking behavior and must be checked/unchecked manually. See "
"[method set_item_checked] for more info on how to control it."
msgstr ""
-"添加一个带有文本[code]label[/code]çš„å•选按钮。\n"
-"å¯ä»¥é€‰æ‹©æä¾›[code]id[/code],以åŠåŠ é€Ÿå™¨([code]accel[/code])。如果没有æä¾›"
-"[code]id[/code],将从索引中创建一个。如果没有æä¾›[code]accel[/code],则默认的"
-"[code]0[/code]将被分é…给它。有关加速器的更多信æ¯ï¼Œè¯·å‚阅[method "
+"添加一个带有文本 [code]label[/code] çš„å•选按钮。\n"
+"å¯ä»¥é€‰æ‹©æä¾› [code]id[/code],以åŠåŠ é€Ÿå™¨ï¼ˆ[code]accel[/code])。如果没有æä¾›"
+"[code]id[/code],将从索引中创建一个。如果没有æä¾› [code]accel[/code],则默认"
+"çš„ [code]0[/code] 将被分é…给它。有关加速器的更多信æ¯ï¼Œè¯·å‚阅 [method "
"get_item_accelerator]。\n"
"[b]注æ„:[/b]Checkable é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå¤é€‰æ ‡è®°ï¼Œä½†æ²¡æœ‰ä»»ä½•内置的检查行为,必"
"须手动检查/䏿£€æŸ¥ã€‚有关如何控制它的更多信æ¯ï¼Œè¯·å‚阅 [method "
@@ -57615,12 +57999,12 @@ msgid ""
"built-in checking behavior and must be checked/unchecked manually. See "
"[method set_item_checked] for more info on how to control it."
msgstr ""
-"添加一个新的å•选å¤é€‰æŒ‰é’®å¹¶ä¸ºå…¶åˆ†é…一个[ShortCut]。将å¤é€‰æ¡†çš„æ ‡ç­¾è®¾ç½®ä¸º"
-"[ShortCut]çš„å称。\n"
-"å¯ä»¥é€‰æ‹©æä¾›[code]id[/code]。如果没有æä¾›[code]id[/code],将从索引中创建一"
+"添加一个新的å•选å¤é€‰æŒ‰é’®å¹¶ä¸ºå…¶åˆ†é…一个 [ShortCut]。将å¤é€‰æ¡†çš„æ ‡ç­¾è®¾ç½®ä¸º "
+"[ShortCut] çš„å称。\n"
+"å¯ä»¥é€‰æ‹©æä¾› [code]id[/code]。如果没有æä¾› [code]id[/code],将从索引中创建一"
"个。\n"
-"[b]注:[/b] Checkableé¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå¤é€‰æ ‡è®°ï¼Œä½†æ²¡æœ‰ä»»ä½•内置的检查行为,必须"
-"手动检查/䏿£€æŸ¥ã€‚有关如何控制它的更多信æ¯ï¼Œè¯·å‚阅[method set_item_checked]。"
+"[b]注æ„:[/b]å¯å‹¾é€‰çš„é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå¤é€‰æ ‡è®°ï¼Œä½†æ²¡æœ‰ä»»ä½•内置的检查行为,必须"
+"手动检查/䏿£€æŸ¥ã€‚有关如何控制它的更多信æ¯ï¼Œè¯·å‚阅 [method set_item_checked]。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57629,9 +58013,9 @@ msgid ""
"A [code]label[/code] can optionally be provided, which will appear at the "
"center of the separator."
msgstr ""
-"在项目之间添加一个分隔符。分隔符也å ç”¨ä¸€ä¸ªç´¢å¼•,你å¯ä»¥é€šè¿‡ä½¿ç”¨[code]id[/code]"
-"傿•°æ¥è®¾ç½®ã€‚\n"
-"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ªæ ‡ç­¾[code]label[/code],它将出现在分隔符的中心。"
+"在项目之间添加一个分隔符。分隔符也å ç”¨ä¸€ä¸ªç´¢å¼•,你å¯ä»¥é€šè¿‡ä½¿ç”¨ [code]id[/"
+"code] 傿•°æ¥è®¾ç½®ã€‚\n"
+"å¯ä»¥é€‰æ‹©æä¾›ä¸€ä¸ªæ ‡ç­¾ [code]label[/code],它将出现在分隔符的中心。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57639,8 +58023,8 @@ msgid ""
"An [code]id[/code] can optionally be provided. If no [code]id[/code] is "
"provided, one will be created from the index."
msgstr ""
-"添加一个[ShortCut]。\n"
-"å¯ä»¥é€‰æ‹©æä¾›[code]id[/code]。如果没有æä¾›[code]id[/code],将从索引中创建一"
+"添加一个 [ShortCut]。\n"
+"å¯ä»¥é€‰æ‹©æä¾› [code]id[/code]。如果没有æä¾› [code]id[/code],将从索引中创建一"
"个。"
#: doc/classes/PopupMenu.xml
@@ -57651,14 +58035,14 @@ msgid ""
"An [code]id[/code] can optionally be provided. If no [code]id[/code] is "
"provided, one will be created from the index."
msgstr ""
-"添加一个项目,当å•击父[PopupMenu]节点时,它将作为å­èœå•。[code]submenu[/code]"
-"傿•°æ˜¯å­èŠ‚ç‚¹[PopupMenu]çš„å称,当点击项目时显示该å­èŠ‚ç‚¹ã€‚\n"
-"å¯ä»¥é€‰æ‹©æä¾›[code]id[/code]。如果没有æä¾›[code]id[/code],将从索引中创建一"
+"添加一个项目,当å•击父 [PopupMenu] 节点时,它将作为å­èœå•。[code]submenu[/"
+"code] 傿•°æ˜¯å­èŠ‚ç‚¹ [PopupMenu] çš„å称,当点击项目时显示该å­èŠ‚ç‚¹ã€‚\n"
+"å¯ä»¥é€‰æ‹©æä¾› [code]id[/code]。如果没有æä¾› [code]id[/code],将从索引中创建一"
"个。"
#: doc/classes/PopupMenu.xml
msgid "Removes all items from the [PopupMenu]."
-msgstr "从[PopupMenu]中移除所有项目。"
+msgstr "从该 [PopupMenu] 中移除所有项目。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57672,19 +58056,20 @@ msgid ""
"are special combinations of keys that activate the item, no matter which "
"control is focused."
msgstr ""
-"返回索引[code]idx[/code]处项目的加速项。加速器是一ç§ç‰¹æ®Šçš„æŒ‰é”®ç»„åˆï¼Œå¯ä»¥æ¿€æ´»"
-"物å“,无论哪个控制键处于焦点状æ€ã€‚"
+"返回索引 [code]idx[/code] 处项目的加速项。加速器是一ç§ç‰¹æ®Šçš„æŒ‰é”®ç»„åˆï¼Œå¯ä»¥æ¿€"
+"活物å“,无论哪个控制键处于焦点状æ€ã€‚"
#: doc/classes/PopupMenu.xml
msgid "Returns the number of items in the [PopupMenu]."
-msgstr "返回[PopupMenu]中的项目数。"
+msgstr "返回该 [PopupMenu] 中的项目数。"
#: doc/classes/PopupMenu.xml
msgid ""
"Returns the id of the item at index [code]idx[/code]. [code]id[/code] can be "
"manually assigned, while index can not."
msgstr ""
-"返回索引[code]idx[/code]处项目的id。[code]id[/code]å¯ä»¥æ‰‹åŠ¨åˆ†é…,而索引ä¸èƒ½ã€‚"
+"返回索引 [code]idx[/code] 处项目的 id。[code]id[/code] å¯ä»¥æ‰‹åŠ¨åˆ†é…,而索引ä¸"
+"能。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57692,8 +58077,8 @@ msgid ""
"Index is automatically assigned to each item by the engine. Index can not be "
"set manually."
msgstr ""
-"è¿”å›žåŒ…å«æŒ‡å®šçš„[code]id[/code]的项的索引。索引由引擎自动分é…ç»™æ¯ä¸ªé¡¹ç›®ã€‚ä¸èƒ½æ‰‹"
-"动设置索引。"
+"è¿”å›žåŒ…å«æŒ‡å®šçš„ [code]id[/code] 的项的索引。索引由引擎自动分é…ç»™æ¯ä¸ªé¡¹ç›®ã€‚ä¸èƒ½"
+"手动设置索引。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57701,26 +58086,26 @@ msgid ""
"can set it with [method set_item_metadata], which provides a simple way of "
"assigning context data to items."
msgstr ""
-"返回指定项的元数æ®ï¼Œè¯¥é¡¹å¯ä»¥æ˜¯ä»»ä½•类型。您å¯ä»¥ä½¿ç”¨[method set_item_metadata]"
-"æ¥è®¾ç½®å®ƒï¼Œå®ƒæä¾›äº†ä¸€ç§å°†ä¸Šä¸‹æ–‡æ•°æ®åˆ†é…ç»™é¡¹çš„ç®€å•æ–¹æ³•。"
+"返回指定项的元数æ®ï¼Œè¯¥é¡¹å¯ä»¥æ˜¯ä»»ä½•类型。您å¯ä»¥ä½¿ç”¨ [method "
+"set_item_metadata] æ¥è®¾ç½®å®ƒï¼Œå®ƒæä¾›äº†ä¸€ç§å°†ä¸Šä¸‹æ–‡æ•°æ®åˆ†é…ç»™é¡¹çš„ç®€å•æ–¹æ³•。"
#: doc/classes/PopupMenu.xml
msgid ""
"Returns the [ShortCut] associated with the specified [code]idx[/code] item."
-msgstr "返回与指定的[code]idx[/code]项关è”çš„[ShortCut]。"
+msgstr "返回与指定的 [code]idx[/code] 项关è”çš„ [ShortCut]。"
#: doc/classes/PopupMenu.xml
msgid ""
"Returns the submenu name of the item at index [code]idx[/code]. See [method "
"add_submenu_item] for more info on how to add a submenu."
msgstr ""
-"返回在索引[code]idx[/code]处的项目的å­èœå•å。更多关于如何添加å­èœå•的信æ¯ï¼Œ"
-"请å‚阅[method add_submenu_item]。"
+"返回在索引 [code]idx[/code] 处的项目的å­èœå•å。更多关于如何添加å­èœå•的信"
+"æ¯ï¼Œè¯·å‚阅 [method add_submenu_item]。"
#: doc/classes/PopupMenu.xml
msgid ""
"Returns the tooltip associated with the specified index [code]idx[/code]."
-msgstr "返回与指定索引 [code]idx[/code]å…³è”的工具æç¤ºã€‚"
+msgstr "返回与指定索引 [code]idx[/code] å…³è”的工具æç¤ºã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57736,10 +58121,10 @@ msgid ""
"don't have any built-in checking behavior and must be checked/unchecked "
"manually."
msgstr ""
-"如果索引[code]idx[/code]的项目以æŸç§æ–¹å¼æ˜¯å¯æ£€æŸ¥çš„,例如,如果它有一个å¤é€‰æ¡†"
-"或å•选按钮,则返回 [code]true[/code]。\n"
-"[b]注:[/b]坿£€æŸ¥é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå¤é€‰æ ‡è®°æˆ–å•选按钮,但没有任何内置的检查行"
-"为,必须手动检查/å–æ¶ˆã€‚"
+"如果索引 [code]idx[/code] 的项目以æŸç§æ–¹å¼æ˜¯å¯æ£€æŸ¥çš„,例如,如果它有一个å¤é€‰"
+"框或å•选按钮,则返回 [code]true[/code]。\n"
+"[b]注æ„:[/b]å¯å‹¾é€‰é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå¤é€‰æ ‡è®°æˆ–å•选按钮,但没有任何内置的检查行"
+"为,必须手动勾选/å–æ¶ˆã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57763,9 +58148,10 @@ msgid ""
"[b]Note:[/b] This is purely cosmetic; you must add the logic for checking/"
"unchecking items in radio groups."
msgstr ""
-"如果index [code]idx[/code]具有å•选按钮样å¼çš„坿£€æŸ¥æ€§ï¼Œåˆ™è¿”回 [code]true[/"
+"å¦‚æžœç´¢å¼•å· [code]idx[/code] 具有å•选按钮样å¼çš„坿£€æŸ¥æ€§ï¼Œåˆ™è¿”回 [code]true[/"
"code]。\n"
-"[b]注:[/b]这纯粹是装饰性的;您必须添加用于在å•选组中检查/å–æ¶ˆæ£€æŸ¥é¡¹ç›®çš„逻辑。"
+"[b]注æ„:[/b]这纯粹是装饰性的;您必须添加用于在å•选组中检查/å–æ¶ˆæ£€æŸ¥é¡¹ç›®çš„逻"
+"辑。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57786,8 +58172,8 @@ msgid ""
"[b]Note:[/b] The indices of items after the removed item will be shifted by "
"one."
msgstr ""
-"从èœå•中移除索引[code]idx[/code]项。\n"
-"[b]注:[/b]被移除项åŽçš„项的索引将被移ä½1。"
+"从èœå•中移除索引 [code]idx[/code] 项。\n"
+"[b]注æ„:[/b]被移除项åŽçš„é¡¹çš„ç´¢å¼•å°†è¢«ç§»ä½ 1。"
#: doc/classes/PopupMenu.xml
msgid "Sets the currently focused item as the given [code]index[/code]."
@@ -57795,7 +58181,7 @@ msgstr "将当å‰èšç„¦é¡¹ç›®è®¾ç½®ä¸ºç»™å®šçš„索引 [code]index[/code]。"
#: doc/classes/PopupMenu.xml
msgid "Hides the [PopupMenu] when the window loses focus."
-msgstr "当窗å£å¤±åŽ»ç„¦ç‚¹æ—¶éšè—[PopupMenu]。"
+msgstr "当窗å£å¤±åŽ»ç„¦ç‚¹æ—¶éšè— [PopupMenu]。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57803,7 +58189,7 @@ msgid ""
"special combinations of keys that activate the item, no matter which control "
"is focused."
msgstr ""
-"设置索引[code]idx[/code]项的加速键。加速器是一ç§ç‰¹æ®Šçš„æŒ‰é”®ç»„åˆï¼Œå¯ä»¥æ¿€æ´»ç‰©"
+"设置索引 [code]idx[/code] 项的加速键。加速器是一ç§ç‰¹æ®Šçš„æŒ‰é”®ç»„åˆï¼Œå¯ä»¥æ¿€æ´»ç‰©"
"å“,无论哪个控制键处于焦点状æ€ã€‚"
#: doc/classes/PopupMenu.xml
@@ -57813,17 +58199,17 @@ msgid ""
"[b]Note:[/b] Checkable items just display a checkmark, but don't have any "
"built-in checking behavior and must be checked/unchecked manually."
msgstr ""
-"设置索引[code]idx[/code]é¡¹æ˜¯å¦æœ‰å¤é€‰æ¡†ã€‚如果[code]false[/code],则将项目类型"
-"设置为纯文本。\n"
-"[b]注:[/b] Checkableé¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå¤é€‰æ ‡è®°ï¼Œä½†æ²¡æœ‰ä»»ä½•内置的检查行为,必须"
-"手动检查/䏿£€æŸ¥ã€‚"
+"设置索引 [code]idx[/code] é¡¹æ˜¯å¦æœ‰å¤é€‰æ¡†ã€‚如果为 [code]false[/code],则将项目"
+"类型设置为纯文本。\n"
+"[b]注æ„:[/b]å¯å‹¾é€‰é¡¹ç›®åªæ˜¯æ˜¾ç¤ºä¸€ä¸ªå¤é€‰æ ‡è®°ï¼Œä½†æ²¡æœ‰ä»»ä½•内置的勾选行为,必须手"
+"动勾选/å–æ¶ˆã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
"Sets the type of the item at the specified index [code]idx[/code] to radio "
"button. If [code]false[/code], sets the type of the item to plain text."
msgstr ""
-"将指定索引[code]idx[/code]处的项目类型设置为å•选按钮。如果[code]false[/"
+"将指定索引[code]idx[/code]处的项目类型设置为å•选按钮。如果为 [code]false[/"
"code],则将项目类型设置为纯文本。"
#: doc/classes/PopupMenu.xml
@@ -57832,24 +58218,24 @@ msgid ""
"would be displayed as a line. If [code]false[/code], sets the type of the "
"item to plain text."
msgstr ""
-"将索引 [code]idx[/code]标记为分隔符,这æ„味ç€å®ƒå°†æ˜¾ç¤ºä¸ºä¸€è¡Œã€‚如果"
+"将索引 [code]idx[/code]标记为分隔符,这æ„味ç€å®ƒå°†æ˜¾ç¤ºä¸ºä¸€è¡Œã€‚如果为 "
"[code]false[/code],则将项目类型设置为纯文本。"
#: doc/classes/PopupMenu.xml
msgid "Sets the checkstate status of the item at index [code]idx[/code]."
-msgstr "设置项目在index [code]idx[/code]处的checkstate状æ€ã€‚"
+msgstr "è®¾ç½®åœ¨ç´¢å¼•å· [code]idx[/code] 处的项目的勾选状æ€ã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
"Enables/disables the item at index [code]idx[/code]. When it is disabled, it "
"can't be selected and its action can't be invoked."
msgstr ""
-"å¯ç”¨/ç¦ç”¨ç´¢å¼•[code]idx[/code]项。当它被ç¦ç”¨æ—¶ï¼Œå°±æ— æ³•选择它,也无法调用它的æ“"
-"作。"
+"å¯ç”¨/ç¦ç”¨ç´¢å¼• [code]idx[/code] 项。当它被ç¦ç”¨æ—¶ï¼Œå°±æ— æ³•选择它,也无法调用它的"
+"æ“作。"
#: doc/classes/PopupMenu.xml
msgid "Replaces the [Texture] icon of the specified [code]idx[/code]."
-msgstr "æ›¿æ¢æŒ‡å®š[code]idx[/code]的纹ç†[Texture]图标。"
+msgstr "æ›¿æ¢æŒ‡å®š [code]idx[/code] çš„çº¹ç† [Texture] 图标。"
#: doc/classes/PopupMenu.xml
msgid "Sets the [code]id[/code] of the item at index [code]idx[/code]."
@@ -57868,15 +58254,15 @@ msgstr ""
msgid ""
"Sets the state of a multistate item. See [method add_multistate_item] for "
"details."
-msgstr "设置一个多æ€é¡¹ç›®çš„状æ€ã€‚详è§[method add_multistate_item]。"
+msgstr "设置一个多æ€é¡¹ç›®çš„状æ€ã€‚详情请å‚阅 [method add_multistate_item]。"
#: doc/classes/PopupMenu.xml
msgid "Sets a [ShortCut] for the specified item [code]idx[/code]."
-msgstr "为指定的项目[code]idx[/code]设置[ShortCut]。"
+msgstr "为指定的项目 [code]idx[/code] 设置 [ShortCut]。"
#: doc/classes/PopupMenu.xml
msgid "Disables the [ShortCut] of the specified index [code]idx[/code]."
-msgstr "ç¦ç”¨æŒ‡å®šç´¢å¼•[code]idx[/code]çš„[ShortCut]。"
+msgstr "ç¦ç”¨æŒ‡å®šç´¢å¼• [code]idx[/code] çš„ [ShortCut]。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57884,44 +58270,45 @@ msgid ""
"name of a child [PopupMenu] node that would be shown when the item is "
"clicked."
msgstr ""
-"将项目的å­èœå•设置为索引[code]idx[/code]。å­èœå•是一个å­[PopupMenu]节点的å"
-"称,在å•击项目时显示该节点。"
+"将项目的å­èœå•设置为索引 [code]idx[/code]。å­èœå•æ˜¯ä¸€ä¸ªå­ [PopupMenu] 节点的"
+"å称,在å•击项目时显示该节点。"
#: doc/classes/PopupMenu.xml
msgid ""
"Sets the [String] tooltip of the item at the specified index [code]idx[/"
"code]."
-msgstr "在指定的索引[code]idx[/code]处设置项目的[String]工具æç¤ºã€‚"
+msgstr "在指定的索引 [code]idx[/code] 处设置项目的 [String] 工具æç¤ºã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
"Toggles the check state of the item of the specified index [code]idx[/code]."
-msgstr "åˆ‡æ¢æŒ‡å®šç´¢å¼•[code]idx[/code]项的检查状æ€ã€‚"
+msgstr "åˆ‡æ¢æŒ‡å®šç´¢å¼• [code]idx[/code] 项的检查状æ€ã€‚"
#: doc/classes/PopupMenu.xml
msgid ""
"Cycle to the next state of a multistate item. See [method "
"add_multistate_item] for details."
-msgstr "循环到一个多æ€é¡¹ç›®çš„下一个状æ€ã€‚详è§[method add_multistate_item]。"
+msgstr ""
+"循环到一个多æ€é¡¹ç›®çš„下一个状æ€ã€‚详情请å‚阅 [method add_multistate_item]。"
#: doc/classes/PopupMenu.xml
msgid "If [code]true[/code], allows navigating [PopupMenu] with letter keys."
-msgstr "如果为 [code]true[/code],å…许用字æ¯é”®å¯¼èˆª[PopupMenu]。"
+msgstr "如果为 [code]true[/code],å…许用字æ¯é”®å¯¼èˆª [PopupMenu]。"
#: doc/classes/PopupMenu.xml
msgid ""
"If [code]true[/code], hides the [PopupMenu] when a checkbox or radio button "
"is selected."
-msgstr "如果[code]true[/code],则在选中å¤é€‰æ¡†æˆ–å•选按钮时éšè—[PopupMenu]。"
+msgstr "如果为 [code]true[/code],则在选中å¤é€‰æ¡†æˆ–å•选按钮时éšè— [PopupMenu]。"
#: doc/classes/PopupMenu.xml
msgid "If [code]true[/code], hides the [PopupMenu] when an item is selected."
-msgstr "如果[code]true[/code],当一个项目被选中时éšè—[PopupMenu]。"
+msgstr "如果为 [code]true[/code],当一个项目被选中时éšè— [PopupMenu]。"
#: doc/classes/PopupMenu.xml
msgid ""
"If [code]true[/code], hides the [PopupMenu] when a state item is selected."
-msgstr "如果[code]true[/code],则在选中状æ€é¡¹æ—¶éšè—[PopupMenu]。"
+msgstr "如果为 [code]true[/code],则在选中状æ€é¡¹æ—¶éšè— [PopupMenu]。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57929,16 +58316,16 @@ msgid ""
"hovering. If the popup menu is added as a child of another (acting as a "
"submenu), it will inherit the delay time of the parent menu item."
msgstr ""
-"è®¾ç½®é¼ æ ‡æ‚¬åœæ—¶å­èœå•项弹出的延迟时间(以秒为å•ä½)。如果弹出èœå•被添加为å¦ä¸€ä¸ª"
-"èœå•çš„å­èœå•(作为å­èœå•),它将继承父èœå•项的延迟时间。"
+"è®¾ç½®é¼ æ ‡æ‚¬åœæ—¶å­èœå•项弹出的延迟时间,以秒为å•ä½ã€‚如果弹出èœå•被添加为å¦ä¸€ä¸ª"
+"èœå•çš„å­èœå•(作为å­èœå•),它将继承父èœå•项的延迟时间。"
#: doc/classes/PopupMenu.xml
msgid ""
"Emitted when user navigated to an item of some [code]id[/code] using "
"[code]ui_up[/code] or [code]ui_down[/code] action."
msgstr ""
-"当用户使用[code]ui_up[/code]或[code]ui_down[/code]æ“作导航到æŸä¸ª[code]id[/"
-"code]项时触å‘。"
+"当用户使用 [code]ui_up[/code] 或 [code]ui_down[/code] æ“作导航到æŸä¸ª "
+"[code]id[/code] 项时触å‘。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57954,7 +58341,7 @@ msgstr "当按下æŸä¸ª[code]index[/code]的项或激活其加速器时触å‘。
#: doc/classes/PopupMenu.xml
msgid "The default text [Color] for menu items' names."
-msgstr "èœå•项å称的默认文本[Color]。"
+msgstr "èœå•项å称的默认文本 [Color]。"
#: doc/classes/PopupMenu.xml
msgid ""
@@ -57962,8 +58349,8 @@ msgid ""
"menu item name when defined. See [method get_item_accelerator] for more info "
"on accelerators."
msgstr ""
-"文本[Color]用于快æ·é”®å’ŒåŠ é€Ÿå™¨ï¼Œå½“å®šä¹‰æ—¶æ˜¾ç¤ºåœ¨èœå•项åç§°æ—边。有关加速器的更多"
-"ä¿¡æ¯ï¼Œè¯·å‚阅[method get_item_accelerator]。"
+"文本 [Color] 用于快æ·é”®å’ŒåŠ é€Ÿå™¨ï¼Œå½“å®šä¹‰æ—¶æ˜¾ç¤ºåœ¨èœå•项åç§°æ—边。有关加速器的更"
+"多信æ¯ï¼Œè¯·å‚阅 [method get_item_accelerator]。"
#: doc/classes/PopupMenu.xml
msgid "[Color] used for disabled menu items' text."
@@ -58147,14 +58534,14 @@ msgid ""
"If you want to override this default, set this value to [code]false[/code], "
"and the local [member portal_margin] will take effect."
msgstr ""
-"在大多数情况下,您会希望在Portal中使用默认的 [Portal] è¾¹è·ï¼ˆè¿™æ˜¯åœ¨ "
+"在大多数情况下,您会希望在 Portal 中使用默认的 [Portal] è¾¹è·ï¼ˆè¿™æ˜¯åœ¨ "
"[RoomManager] 中设置的)。\n"
-"如果è¦è¦†ç›–这个默认值,把这个值设置为 [code]false[/code],本地的[member "
-"portal_margin]就会生效。"
+"如果è¦è¦†ç›–这个默认值,把这个值设置为 [code]false[/code],本地的 [member "
+"portal_margin] 就会生效。"
#: doc/classes/Position2D.xml
msgid "Generic 2D position hint for editing."
-msgstr "用于编辑的通用2Dä½ç½®æç¤ºã€‚"
+msgstr "用于编辑的通用 2D ä½ç½®æç¤ºã€‚"
#: doc/classes/Position2D.xml
msgid ""
@@ -58162,8 +58549,9 @@ msgid ""
"it displays as a cross in the 2D editor at all times. You can set cross' "
"visual size by using the gizmo in the 2D editor while the node is selected."
msgstr ""
-"用于编辑的通用2Dä½ç½®æç¤ºã€‚它就åƒä¸€ä¸ªæ™®é€šçš„[Node2D],但它在2D编辑器中始终显示"
-"为一个å字。选择节点时,å¯ä»¥ä½¿ç”¨2Dç¼–è¾‘å™¨ä¸­çš„å°æŽ§ä»¶æ¥è®¾ç½®å字的视觉大å°ã€‚"
+"用于编辑的通用 2D ä½ç½®æç¤ºã€‚它就åƒä¸€ä¸ªæ™®é€šçš„ [Node2D],但它在 2D 编辑器中始终"
+"显示为一个å字。选择节点时,å¯ä»¥ä½¿ç”¨ 2D ç¼–è¾‘å™¨ä¸­çš„å°æŽ§ä»¶æ¥è®¾ç½®å字的视觉大"
+"å°ã€‚"
#: doc/classes/Position3D.xml
msgid "Generic 3D position hint for editing."
@@ -58755,12 +59143,12 @@ msgid ""
"The [member application/config/use_custom_user_dir] setting must be enabled "
"for this to take effect."
msgstr ""
-"该用户目录用于存储æŒä¹…æ•°æ®([code]user://[/code]文件系统)。如果留空,"
-"[code]user://[/code]将解æžä¸ºGodot自己的é…置文件夹中特定于项目的文件夹(请å‚阅"
-"[method OS.get_user_data_dir])。如果定义了自定义目录å,将使用该å称并将其附"
-"加到系统特定的用户数æ®ç›®å½•(与[method OS.get_user_data_dir]中记录的Godoté…置文"
-"件夹相åŒçš„父文件夹)。\n"
-"å¿…é¡»å¯ç”¨ [member application/config/use_custom_user_dir]设置æ‰èƒ½ä½¿å…¶ç”Ÿæ•ˆã€‚"
+"这个用户目录用于存储æŒä¹…æ•°æ®ï¼ˆ[code]user://[/code]文件系统)。如果留空,"
+"[code]user://[/code] 将解æžä¸º Godot 自己的é…ç½®æ–‡ä»¶å¤¹ä¸­ç‰¹å®šäºŽé¡¹ç›®çš„æ–‡ä»¶å¤¹ï¼ˆè§ "
+"[method OS.get_user_data_dir])。如果定义了自定义目录å,将使用该å称并将其附"
+"加到系统特定的用户数æ®ç›®å½•(与 [method OS.get_user_data_dir] 中记录的 Godot "
+"é…置文件夹相åŒçš„父文件夹)。\n"
+"å¿…é¡»å¯ç”¨ [member application/config/use_custom_user_dir] 设置æ‰èƒ½ä½¿å…¶ç”Ÿæ•ˆã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -58825,11 +59213,11 @@ msgid ""
"effect. If [code]false[/code], the project will save user data to [code](OS "
"user data directory)/Godot/app_userdata/(project name)[/code]."
msgstr ""
-"如果[code]true[/code],项目将把用户数æ®ä¿å­˜åˆ°è‡ªå·±çš„用户目录中(请å‚阅[member "
-"application/config/custom_user_dir_name])。此设置仅在桌é¢å¹³å°ä¸Šæœ‰æ•ˆã€‚必须在"
-"[member application/config/custom_user_dir_name]设置中设置åç§°æ‰èƒ½ç”Ÿæ•ˆã€‚如果"
-"[code]false[/code],项目将把用户数æ®ä¿å­˜åˆ°[code](OS user data directory)/"
-"Godot/app_userdata/(project name)[/code]。"
+"如果为 [code]true[/code],项目将把用户数æ®ä¿å­˜åˆ°è‡ªå·±çš„用户目录中(请å‚阅"
+"[member application/config/custom_user_dir_name])。此设置仅在桌é¢å¹³å°ä¸Šæœ‰"
+"效。必须在[member application/config/custom_user_dir_name]设置中设置åç§°æ‰èƒ½"
+"生效。如果为 [code]false[/code],项目将把用户数æ®ä¿å­˜åˆ°[code](OS user data "
+"directory)/Godot/app_userdata/(project name)[/code]。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -58845,9 +59233,9 @@ msgid ""
"default can impact compatibility with some external tools or plugins which "
"expect the default [code].import[/code] folder."
msgstr ""
-"如果 [code]true[/code],项目将使用一个éšè—目录([code].import[/code])æ¥å­˜å‚¨"
-"项目特定的数æ®ï¼ˆå…ƒæ•°æ®ã€ç€è‰²å™¨ç¼“存等)。\n"
-"如果 [code]false[/code],将使用éžéšè—目录 ([code]import[/code])。\n"
+"如果为 [code]true[/code],项目将使用一个éšè—目录([code].import[/code])æ¥å­˜"
+"储项目特定的数æ®ï¼ˆå…ƒæ•°æ®ã€ç€è‰²å™¨ç¼“存等)。\n"
+"如果为 [code]false[/code],将使用éžéšè—目录([code]import[/code])。\n"
"[b]注æ„:[/b]更改此设置åŽé‡æ–°å¯åŠ¨åº”ç”¨ç¨‹åºã€‚\n"
"[b]注æ„:[/b]更改此值有助于在平å°ä¸Šæˆ–使用ä¸å…许éšè—目录模å¼çš„第三方工具。仅当"
"æ‚¨çŸ¥é“æ‚¨çš„çŽ¯å¢ƒéœ€è¦æ—¶æ‰ä¿®æ”¹æ­¤è®¾ç½®ï¼Œå› ä¸ºæ›´æ”¹é»˜è®¤è®¾ç½®ä¼šå½±å“与æŸäº›éœ€è¦é»˜è®¤ "
@@ -58899,9 +59287,9 @@ msgid ""
"application/run/disable_stdout].\n"
"Changes to this setting will only be applied upon restarting the application."
msgstr ""
-"如果 [code]true[/code],则ç¦ç”¨æ‰“å°åˆ°æ ‡å‡†é”™è¯¯ã€‚如果 [code]true[/code],这也会"
-"éšè—ç”± [method @GDScript.push_error] å’Œ [method @GDScript.push_warning] 打å°"
-"的错误和警告消æ¯ã€‚å¦è§[member application/run/disable_stdout]。\n"
+"如果为 [code]true[/code],则ç¦ç”¨æ‰“å°åˆ°æ ‡å‡†é”™è¯¯ã€‚如果为 [code]true[/code],这"
+"也会éšè—ç”± [method @GDScript.push_error] å’Œ [method @GDScript.push_warning] "
+"打å°çš„错误和警告消æ¯ã€‚å¦è§[member application/run/disable_stdout]。\n"
"对此设置的更改åªä¼šåœ¨é‡æ–°å¯åŠ¨åº”ç”¨ç¨‹åºæ—¶åº”用。"
#: doc/classes/ProjectSettings.xml
@@ -58911,7 +59299,7 @@ msgid ""
"command line argument. See also [member application/run/disable_stderr].\n"
"Changes to this setting will only be applied upon restarting the application."
msgstr ""
-"如果 [code]true[/code],则ç¦ç”¨æ‰“å°åˆ°æ ‡å‡†è¾“出。这相当于使用 [code]--quiet[/"
+"如果为 [code]true[/code],则ç¦ç”¨æ‰“å°åˆ°æ ‡å‡†è¾“出。这相当于使用 [code]--quiet[/"
"code] å‘½ä»¤è¡Œå‚æ•°å¯åŠ¨ç¼–è¾‘å™¨æˆ–é¡¹ç›®ã€‚å¦è§[member application/run/"
"disable_stderr]。\n"
"对此设置的更改åªä¼šåœ¨é‡æ–°å¯åŠ¨åº”ç”¨ç¨‹åºæ—¶åº”用。"
@@ -58931,8 +59319,8 @@ msgid ""
"([code]stderr[/code]) is always flushed when a line is printed to it.\n"
"Changes to this setting will only be applied upon restarting the application."
msgstr ""
-"如果 [code]true[/code]ï¼Œåˆ™æ¯æ¬¡æ‰“å°ä¸€è¡Œæ—¶åˆ·æ–°æ ‡å‡†è¾“出æµã€‚这会影å“终端日志记录"
-"和文件日志记录。\n"
+"如果为 [code]true[/code]ï¼Œåˆ™æ¯æ¬¡æ‰“å°ä¸€è¡Œæ—¶åˆ·æ–°æ ‡å‡†è¾“出æµã€‚这会影å“终端日志记"
+"录和文件日志记录。\n"
"è¿è¡Œé¡¹ç›®æ—¶ï¼Œå¦‚果希望由 systemd/journalctl ç­‰æœåŠ¡ç®¡ç†å™¨æ”¶é›†æ—¥å¿—,则必须å¯ç”¨æ­¤"
"设置。默认情况下,在å‘布版本中ç¦ç”¨æ­¤è®¾ç½®ï¼Œå› ä¸ºå¦‚果快速连续打å°å¤§é‡è¡Œï¼Œåˆ™åœ¨æ¯"
"个打å°è¡Œä¸Šåˆ·æ–°éƒ½ä¼šå¯¹æ€§èƒ½äº§ç”Ÿè´Ÿé¢å½±å“。此外,如果å¯ç”¨æ­¤è®¾ç½®ï¼Œå¦‚果应用程åºå´©æºƒ"
@@ -58966,15 +59354,16 @@ msgid ""
"visually. This is meant for writing applications and editors, but is pretty "
"useless (and can hurt performance) in most games."
msgstr ""
-"如果 [code]true[/code],则å¯ç”¨ä½Žå¤„ç†å™¨ä½¿ç”¨æ¨¡å¼ã€‚此设置仅适用于桌é¢å¹³å°ã€‚如果"
-"视觉上没有任何å˜åŒ–,å±å¹•ä¸ä¼šè¢«é‡ç»˜ã€‚这是为了编写应用程åºå’Œç¼–辑器,但在大多数"
-"游æˆä¸­è¿™æ˜¯éžå¸¸æ— ç”¨çš„(并å¯èƒ½æŸå®³æ€§èƒ½ï¼‰ã€‚"
+"如果为 [code]true[/code],则å¯ç”¨ä½Žå¤„ç†å™¨ä½¿ç”¨æ¨¡å¼ã€‚此设置仅适用于桌é¢å¹³å°ã€‚如"
+"果视觉上没有任何å˜åŒ–,å±å¹•ä¸ä¼šè¢«é‡ç»˜ã€‚这是为了编写应用程åºå’Œç¼–辑器,但在大多"
+"数游æˆä¸­è¿™æ˜¯éžå¸¸æ— ç”¨çš„(并å¯èƒ½æŸå®³æ€§èƒ½ï¼‰ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"Amount of sleeping between frames when the low-processor usage mode is "
"enabled (in microseconds). Higher values will result in lower CPU usage."
-msgstr "å¯ç”¨ä½Žå¤„ç†å™¨ä½¿ç”¨æ¨¡å¼æ—¶å¸§é—´çš„ç¡çœ é‡(以微秒计)。值越高,CPUå ç”¨çŽ‡è¶Šä½Žã€‚"
+msgstr ""
+"å¯ç”¨ä½Žå¤„ç†å™¨ä½¿ç”¨æ¨¡å¼æ—¶å¸§é—´çš„ç¡çœ é‡ï¼ˆä»¥å¾®ç§’计)。值越高,CPUå ç”¨çŽ‡è¶Šä½Žã€‚"
#: doc/classes/ProjectSettings.xml
msgid "Path to the main scene file that will be loaded when the project runs."
@@ -59194,14 +59583,15 @@ msgstr ""
msgid ""
"If [code]true[/code], enables warnings when using a function as if it was a "
"property."
-msgstr "如果[code]true[/code],则在使用函数时å¯ç”¨è­¦å‘Šï¼Œå°±åƒå®ƒæ˜¯å±žæ€§ä¸€æ ·ã€‚"
+msgstr "如果为 [code]true[/code],则在使用函数时å¯ç”¨è­¦å‘Šï¼Œå°±åƒå®ƒæ˜¯å±žæ€§ä¸€æ ·ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when a ternary operator may emit "
"values with incompatible types."
msgstr ""
-"如果[code]true[/code],则当三元è¿ç®—符å¯èƒ½å‘出类型ä¸å…¼å®¹çš„值时,将å¯ç”¨è­¦å‘Šã€‚"
+"如果为 [code]true[/code],则当三元è¿ç®—符å¯èƒ½å‘出类型ä¸å…¼å®¹çš„值时,将å¯ç”¨è­¦"
+"告。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59224,7 +59614,7 @@ msgstr ""
msgid ""
"If [code]true[/code], enables warnings when using a property as if it was a "
"function."
-msgstr "如果[code]true[/code],则在将属性当作函数使用时å¯ç”¨è­¦å‘Šã€‚"
+msgstr "如果为 [code]true[/code],则在将属性当作函数使用时å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59233,9 +59623,9 @@ msgid ""
"argument). Such return values are sometimes used to denote possible errors "
"using the [enum Error] enum."
msgstr ""
-"如果[code]true[/code],则在ä¸ä½¿ç”¨å‡½æ•°è¿”回值(通过将其赋值给å˜é‡æˆ–将其用作函数"
-"傿•°)调用函数时å¯ç”¨è­¦å‘Šã€‚这样的返回值有时使用[enum Error] 枚举æ¥è¡¨ç¤ºå¯èƒ½çš„é”™"
-"误。"
+"如果为 [code]true[/code],则在ä¸ä½¿ç”¨å‡½æ•°è¿”回值(通过将其赋值给å˜é‡æˆ–将其用作函"
+"æ•°å‚æ•°)调用函数时å¯ç”¨è­¦å‘Šã€‚这样的返回值有时使用[enum Error] 枚举æ¥è¡¨ç¤ºå¯èƒ½çš„"
+"错误。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59243,8 +59633,8 @@ msgid ""
"member variable that would shadow a variable at an upper level (such as a "
"member variable)."
msgstr ""
-"如果[code]true[/code],则在定义局部或å­ç±»æˆå‘˜å˜é‡æ—¶å¯ç”¨è­¦å‘Šï¼Œè¯¥å±€éƒ¨æˆ–å­ç±»æˆå‘˜"
-"å˜é‡å°†åœ¨ä¸Šå±‚阴影å˜é‡(如æˆå‘˜å˜é‡)。"
+"如果为 [code]true[/code],则在定义局部或å­ç±»æˆå‘˜å˜é‡æ—¶å¯ç”¨è­¦å‘Šï¼Œè¯¥å±€éƒ¨æˆ–å­ç±»"
+"æˆå‘˜å˜é‡å°†åœ¨ä¸Šå±‚阴影å˜é‡ï¼ˆå¦‚æˆå‘˜å˜é‡ï¼‰ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59252,8 +59642,8 @@ msgid ""
"no effect on the surrounding code, such as writing [code]2 + 2[/code] as a "
"statement."
msgstr ""
-"如果[code]true[/code]ï¼Œåˆ™åœ¨è°ƒç”¨å¯¹å‘¨å›´ä»£ç æ²¡æœ‰å½±å“çš„è¡¨è¾¾å¼æ—¶å¯ç”¨è­¦å‘Šï¼Œä¾‹å¦‚å°†"
-"[code]2 + 2[/code]写æˆè¯­å¥ã€‚"
+"如果为 [code]true[/code]ï¼Œåˆ™åœ¨è°ƒç”¨å¯¹å‘¨å›´ä»£ç æ²¡æœ‰å½±å“çš„è¡¨è¾¾å¼æ—¶å¯ç”¨è­¦å‘Šï¼Œä¾‹å¦‚"
+"å°†[code]2 + 2[/code]写æˆè¯­å¥ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59261,19 +59651,19 @@ msgid ""
"that has no effect on the surrounding code, such as writing [code]42 if "
"active else 0[/code] as a statement."
msgstr ""
-"如果[code]true[/code]ï¼Œåˆ™åœ¨è°ƒç”¨å¯¹å‘¨å›´ä»£ç æ²¡æœ‰å½±å“çš„ä¸‰å…ƒè¡¨è¾¾å¼æ—¶å¯ç”¨è­¦å‘Šï¼Œä¾‹å¦‚"
-"å°†[code]42(如果激活else 0[/code])写入语å¥ã€‚"
+"如果为 [code]true[/code]ï¼Œåˆ™åœ¨è°ƒç”¨å¯¹å‘¨å›´ä»£ç æ²¡æœ‰å½±å“çš„ä¸‰å…ƒè¡¨è¾¾å¼æ—¶å¯ç”¨è­¦å‘Šï¼Œ"
+"例如将[code]42(如果激活else 0[/code])写入语å¥ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], all warnings will be reported as if they were errors."
-msgstr "如果[code]true[/code],所有警告将被报告为错误。"
+msgstr "如果为 [code]true[/code],所有警告将被报告为错误。"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when using a variable that wasn't "
"previously assigned."
-msgstr "如果[code]true[/code]ï¼Œåˆ™åœ¨ä½¿ç”¨ä»¥å‰æ²¡æœ‰èµ‹å€¼çš„å˜é‡æ—¶å¯ç”¨è­¦å‘Šã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œåˆ™åœ¨ä½¿ç”¨ä»¥å‰æ²¡æœ‰èµ‹å€¼çš„å˜é‡æ—¶å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59281,60 +59671,60 @@ msgid ""
"assignment operator like [code]+=[/code] if the variable wasn't previously "
"assigned."
msgstr ""
-"如果[code]true[/code],则在使用赋值æ“作符[code]+=[/code](如果å˜é‡ä¹‹å‰æ²¡æœ‰èµ‹"
-"值)为å˜é‡èµ‹å€¼æ—¶å¯ç”¨è­¦å‘Šã€‚"
+"如果为 [code]true[/code],则在使用赋值æ“作符[code]+=[/code](如果å˜é‡ä¹‹å‰æ²¡æœ‰"
+"赋值)为å˜é‡èµ‹å€¼æ—¶å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when unreachable code is detected "
"(such as after a [code]return[/code] statement that will always be executed)."
msgstr ""
-"如果[code]true[/code],则在检测到ä¸å¯è¾¾çš„ä»£ç æ—¶å¯ç”¨è­¦å‘Š(例如在始终执行的"
-"[code]return[/code]语å¥ä¹‹åŽ)。"
+"如果为 [code]true[/code],则在检测到ä¸å¯è¾¾çš„ä»£ç æ—¶å¯ç”¨è­¦å‘Šï¼ˆä¾‹å¦‚在始终执行的"
+"[code]return[/code]语å¥ä¹‹åŽï¼‰ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when using an expression whose type "
"may not be compatible with the function parameter expected."
msgstr ""
-"如果[code]true[/code],则在使用类型å¯èƒ½ä¸ŽæœŸæœ›çš„å‡½æ•°å‚æ•°ä¸å…¼å®¹çš„è¡¨è¾¾å¼æ—¶å¯ç”¨è­¦"
-"告。"
+"如果为 [code]true[/code],则在使用类型å¯èƒ½ä¸ŽæœŸæœ›çš„å‡½æ•°å‚æ•°ä¸å…¼å®¹çš„è¡¨è¾¾å¼æ—¶å¯"
+"用警告。"
#: doc/classes/ProjectSettings.xml
msgid "If [code]true[/code], enables warnings when performing an unsafe cast."
-msgstr "如果[code]true[/code],则在执行ä¸å®‰å…¨çš„å¼ºåˆ¶è½¬æ¢æ—¶å¯ç”¨è­¦å‘Šã€‚"
+msgstr "如果为 [code]true[/code],则在执行ä¸å®‰å…¨çš„å¼ºåˆ¶è½¬æ¢æ—¶å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when calling a method whose presence "
"is not guaranteed at compile-time in the class."
msgstr ""
-"如果[code]true[/code],则在调用类中ä¸èƒ½ä¿è¯åœ¨ç¼–译时存在的方法时å¯ç”¨è­¦å‘Šã€‚"
+"如果为 [code]true[/code],则在调用类中ä¸èƒ½ä¿è¯åœ¨ç¼–译时存在的方法时å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when accessing a property whose "
"presence is not guaranteed at compile-time in the class."
msgstr ""
-"如果[code]true[/code],则在访问类中ä¸èƒ½ä¿è¯åœ¨ç¼–译时存在的属性时å¯ç”¨è­¦å‘Šã€‚"
+"如果为 [code]true[/code],则在访问类中ä¸èƒ½ä¿è¯åœ¨ç¼–译时存在的属性时å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when a function parameter is unused."
-msgstr "如果[code]true[/code]ï¼Œå½“ä¸€ä¸ªå‡½æ•°å‚æ•°æœªä½¿ç”¨æ—¶ï¼Œå¯ç”¨è­¦å‘Šã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œå½“ä¸€ä¸ªå‡½æ•°å‚æ•°æœªä½¿ç”¨æ—¶ï¼Œå¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when a member variable is unused."
-msgstr "如果[code]true[/code],当一个æˆå‘˜å˜é‡æœªä½¿ç”¨æ—¶ï¼Œå¯ç”¨è­¦å‘Šã€‚"
+msgstr "如果为 [code]true[/code],当一个æˆå‘˜å˜é‡æœªä½¿ç”¨æ—¶ï¼Œå¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid "If [code]true[/code], enables warnings when a signal is unused."
-msgstr "如果[code]true[/code]ï¼Œåˆ™åœ¨ä¿¡å·æœªä½¿ç”¨æ—¶å¯ç”¨è­¦å‘Šã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œåˆ™åœ¨ä¿¡å·æœªä½¿ç”¨æ—¶å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid "If [code]true[/code], enables warnings when a local variable is unused."
-msgstr "如果[code]true[/code],则在局部å˜é‡æœªä½¿ç”¨æ—¶å¯ç”¨è­¦å‘Šã€‚"
+msgstr "如果为 [code]true[/code],则在局部å˜é‡æœªä½¿ç”¨æ—¶å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59342,16 +59732,16 @@ msgid ""
"same name as a function. This will turn into an error in a future version "
"when first-class functions become supported in GDScript."
msgstr ""
-"如果 [code]true[/code],则在声明与函数åŒåçš„å˜é‡æ—¶å¯ç”¨è­¦å‘Šã€‚当 GDScript 支æŒ"
-"一æµå‡½æ•°æ—¶ï¼Œè¿™å°†åœ¨æœªæ¥ç‰ˆæœ¬ä¸­å˜æˆé”™è¯¯ã€‚"
+"如果为 [code]true[/code],则在声明与函数åŒåçš„å˜é‡æ—¶å¯ç”¨è­¦å‘Šã€‚当 GDScript 支"
+"æŒä¸€æµå‡½æ•°æ—¶ï¼Œè¿™å°†åœ¨æœªæ¥ç‰ˆæœ¬ä¸­å˜æˆé”™è¯¯ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when assigning the result of a "
"function that returns [code]void[/code] to a variable."
msgstr ""
-"如果[code]true[/code],则在将返回 [code]void[/code]的函数的结果赋值给å˜é‡æ—¶å¯"
-"用警告。"
+"如果为 [code]true[/code],则在将返回 [code]void[/code]的函数的结果赋值给å˜é‡"
+"æ—¶å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59435,43 +59825,42 @@ msgstr "最大的å¯è§†è„šæœ¬è°ƒç”¨å †æ ˆï¼Œä»¥é¿å…æ— é™é€’归。"
msgid ""
"Color of the contact points between collision shapes, visible when \"Visible "
"Collision Shapes\" is enabled in the Debug menu."
-msgstr "碰撞形状之间接触点的颜色,在调试èœå•中å¯ç”¨â€œå¯è§ç¢°æ’žå½¢çŠ¶â€æ—¶å¯è§ã€‚"
+msgstr "碰撞形状之间接触点的颜色,在调试èœå•中å¯ç”¨â€œæ˜¾ç¤ºç¢°æ’žå½¢çŠ¶â€æ—¶å¯è§ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"Sets whether 2D physics will display collision outlines in game when "
"\"Visible Collision Shapes\" is enabled in the Debug menu."
msgstr ""
-"设置当调试èœå•中的å¯ç”¨ \"å¯è§çš„碰撞形状\" 时,2Dç‰©ç†æ˜¯å¦ä¼šåœ¨æ¸¸æˆä¸­æ˜¾ç¤ºç¢°æ’žè½®"
-"廓。"
+"设置当调试èœå•中的å¯ç”¨â€œæ˜¾ç¤ºç¢°æ’žå½¢çŠ¶â€æ—¶ï¼Œ2D ç‰©ç†æ˜¯å¦ä¼šåœ¨æ¸¸æˆä¸­æ˜¾ç¤ºç¢°æ’žè½®å»“。"
#: doc/classes/ProjectSettings.xml
msgid ""
"Maximum number of contact points between collision shapes to display when "
"\"Visible Collision Shapes\" is enabled in the Debug menu."
-msgstr "当在调试èœå•中å¯ç”¨â€œå¯è§ç¢°æ’žå½¢çŠ¶â€æ—¶ï¼Œç¢°æ’žå½¢çŠ¶ä¹‹é—´æ˜¾ç¤ºçš„æœ€å¤§æŽ¥è§¦ç‚¹æ•°ã€‚"
+msgstr "当在调试èœå•中å¯ç”¨â€œæ˜¾ç¤ºç¢°æ’žå½¢çŠ¶â€æ—¶ï¼Œç¢°æ’žå½¢çŠ¶ä¹‹é—´æ˜¾ç¤ºçš„æœ€å¤§æŽ¥è§¦ç‚¹æ•°ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"Color of the collision shapes, visible when \"Visible Collision Shapes\" is "
"enabled in the Debug menu."
-msgstr "碰撞形状的颜色,当在调试èœå•中å¯ç”¨â€œå¯è§ç¢°æ’žå½¢çŠ¶â€æ—¶å¯è§ã€‚"
+msgstr "碰撞形状的颜色,当在调试èœå•中å¯ç”¨â€œæ˜¾ç¤ºç¢°æ’žå½¢çŠ¶â€æ—¶å¯è§ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"Color of the disabled navigation geometry, visible when \"Visible "
"Navigation\" is enabled in the Debug menu."
-msgstr "被ç¦ç”¨çš„导航几何图形的颜色,在调试èœå•中å¯ç”¨â€œå¯è§å¯¼èˆªâ€æ—¶å¯è§ã€‚"
+msgstr "被ç¦ç”¨çš„导航几何图形的颜色,在调试èœå•中å¯ç”¨â€œæ˜¾ç¤ºå¯¼èˆªâ€æ—¶å¯è§ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
"Color of the navigation geometry, visible when \"Visible Navigation\" is "
"enabled in the Debug menu."
-msgstr "导航几何图形的颜色,在调试èœå•中å¯ç”¨â€œå¯è§å¯¼èˆªâ€æ—¶å¯è§ã€‚"
+msgstr "导航几何图形的颜色,在调试èœå•中å¯ç”¨â€œæ˜¾ç¤ºå¯¼èˆªâ€æ—¶å¯è§ã€‚"
#: doc/classes/ProjectSettings.xml
msgid "Custom image for the mouse cursor (limited to 256×256)."
-msgstr "鼠标光标的自定义图åƒ(最大256×256)。"
+msgstr "鼠标光标的自定义图åƒï¼ˆæœ€å¤§ 256×256)。"
#: doc/classes/ProjectSettings.xml
msgid "Hotspot for the custom mouse cursor image."
@@ -59690,6 +60079,11 @@ msgid ""
"- [code]2[/code] (snake_case): Converts the scene root name to snake_case "
"casing."
msgstr ""
+"场景文件的默认命å风格,从场景根节点推导时使用。å¯èƒ½çš„选项有:\n"
+"- [code]0[/code]ï¼ˆè‡ªåŠ¨ï¼‰ï¼šä¿æŒåœºæ™¯æ ¹èŠ‚ç‚¹å称,ä¸ä¿®æ”¹å¤§å°å†™ã€‚\n"
+"- [code]1[/code](PascalCase):将场景根节点å称转æ¢ä¸º PascalCase 驼峰风"
+"格。\n"
+"- [code]2[/code](snake_case):将场景根节点å称转æ¢ä¸º snake_case 蛇形风格。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59697,7 +60091,7 @@ msgid ""
"script templates both in the editor-specific path and in this project-"
"specific path."
msgstr ""
-"对于项目特定的脚本模æ¿çš„æœç´¢è·¯å¾„ã€‚ Godot 将在编辑器的特定路径和此项目的路径中"
+"对于项目特定的脚本模æ¿çš„æœç´¢è·¯å¾„ã€‚Godot 将在编辑器的特定路径和此项目的路径中"
"æœç´¢ã€‚"
#: doc/classes/ProjectSettings.xml
@@ -59730,8 +60124,8 @@ msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
-"[member ScrollContainer.scroll_deadzone],它将用于所有[ScrollContainer]s,除"
-"éžé‡å†™ã€‚"
+"[member ScrollContainer.scroll_deadzone],它将用于所有 [ScrollContainer],除"
+"éžfug。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59757,8 +60151,8 @@ msgid ""
"If [code]true[/code], swaps OK and Cancel buttons in dialogs on Windows and "
"UWP to follow interface conventions."
msgstr ""
-"如果[code]true[/code],在Windowså’ŒUWPçš„å¯¹è¯æ¡†ä¸­äº¤æ¢ç¡®å®šå’Œå–消按钮,以éµå¾ªç•Œé¢"
-"惯例。"
+"如果为 [code]true[/code],在Windowså’ŒUWPçš„å¯¹è¯æ¡†ä¸­äº¤æ¢ç¡®å®šå’Œå–消按钮,以éµå¾ª"
+"ç•Œé¢æƒ¯ä¾‹ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59776,17 +60170,17 @@ msgstr "自定义 [Font] 资æºçš„路径,用于项目的所有 GUI 元素的é»
#: doc/classes/ProjectSettings.xml
msgid "If [code]true[/code], makes sure the theme used works with HiDPI."
-msgstr "如果[code]true[/code],确ä¿ä½¿ç”¨çš„主题将在HiDPI下工作。"
+msgstr "如果为 [code]true[/code],确ä¿ä½¿ç”¨çš„主题将在 HiDPI 下工作。"
#: doc/classes/ProjectSettings.xml
msgid ""
"Timer setting for incremental search in [Tree], [ItemList], etc. controls "
"(in milliseconds)."
-msgstr "在[Tree], [ItemList]ç­‰æŽ§ä»¶ä¸­ä¸ºå¢žé‡æœç´¢è®¾ç½®è®¡æ—¶å™¨(以毫秒为å•ä½)。"
+msgstr "在 [Tree]ã€[ItemList] ç­‰æŽ§ä»¶ä¸­ä¸ºå¢žé‡æœç´¢è®¾ç½®è®¡æ—¶å™¨ï¼ˆå•ä½ä¸ºæ¯«ç§’)。"
#: doc/classes/ProjectSettings.xml
msgid "Timer for detecting idle in [TextEdit] (in seconds)."
-msgstr "检测[TextEdit]空闲的计时器(å•ä½ä¸ºç§’)。"
+msgstr "检测 [TextEdit] 空闲的计时器(å•ä½ä¸ºç§’)。"
#: doc/classes/ProjectSettings.xml
msgid "Default delay for tooltips (in seconds)."
@@ -59900,10 +60294,11 @@ msgid ""
"necessary for the internal logic of several [Control]s. The events assigned "
"to the action can however be modified."
msgstr ""
-"默认的在[Control](例如[ItemList]或[Tree])中下拉页é¢çš„[InputEventAction],与典"
-"型桌é¢UI系统中[constant KEY_PAGEDOWN]的行为相匹é…。\n"
-"[b]注æ„:[/b]默认的[code]ui_*[/code]动作ä¸èƒ½è¢«åˆ é™¤ï¼Œå› ä¸ºå®ƒä»¬æ˜¯å‡ ä¸ª[Control]çš„"
-"内部逻辑所必需的。但是,å¯ä»¥ä¿®æ”¹åˆ†é…给该æ“作的事件。"
+"默认的在 [Control](例如 [ItemList] 或 [Tree])中å‘下翻页的 "
+"[InputEventAction]ï¼Œä¸Žå…¸åž‹æ¡Œé¢ UI 系统中 [constant KEY_PAGEDOWN] 的行为相匹"
+"é…。\n"
+"[b]注æ„:[/b]默认的 [code]ui_*[/code] 动作ä¸èƒ½è¢«åˆ é™¤ï¼Œå› ä¸ºå®ƒä»¬æ˜¯å‡ ä¸ª "
+"[Control] 的内部逻辑所必需的。但是,å¯ä»¥ä¿®æ”¹åˆ†é…给该æ“作的事件。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59914,10 +60309,11 @@ msgid ""
"necessary for the internal logic of several [Control]s. The events assigned "
"to the action can however be modified."
msgstr ""
-"默认在[Control](例如[ItemList]或[Tree])中上移页é¢çš„[InputEventAction],与典型"
-"桌é¢UI系统中[constant KEY_PAGEUP]的行为相匹é…。\n"
-"[b]注æ„:[/b]默认的[code]ui_*[/code]动作ä¸èƒ½è¢«åˆ é™¤ï¼Œå› ä¸ºå®ƒä»¬æ˜¯å‡ ä¸ª[Control]çš„"
-"内部逻辑所必需的。但是,å¯ä»¥ä¿®æ”¹åˆ†é…给该æ“作的事件。"
+"默认的在 [Control](例如 [ItemList] 或 [Tree])中å‘上翻页的 "
+"[InputEventAction]ï¼Œä¸Žå…¸åž‹æ¡Œé¢ UI 系统中 [constant KEY_PAGEUP] 的行为相匹"
+"é…。\n"
+"[b]注æ„:[/b]默认的 [code]ui_*[/code] 动作ä¸èƒ½è¢«åˆ é™¤ï¼Œå› ä¸ºå®ƒä»¬æ˜¯å‡ ä¸ª "
+"[Control] 的内部逻辑所必需的。但是,å¯ä»¥ä¿®æ”¹åˆ†é…给该æ“作的事件。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59964,12 +60360,12 @@ msgid ""
"because they can't run at the target frame rate.\n"
"[b]Note:[/b] Currently implemented only in Android."
msgstr ""
-"如果 [code]true[/code],按键/触摸/æ“纵æ†äº‹ä»¶å°†åœ¨æ¯ä¸ªç©ºé—²å¸§å’Œç‰©ç†å¸§ä¹‹å‰åˆ·"
+"如果为 [code]true[/code],按键/触摸/æ“纵æ†äº‹ä»¶å°†åœ¨æ¯ä¸ªç©ºé—²å¸§å’Œç‰©ç†å¸§ä¹‹å‰åˆ·"
"新。\n"
-"如果 [code]false[/code],此类事件将在引擎迭代之间æ¯ä¸ªç©ºé—²å¸§ä»…刷新一次。\n"
+"如果为 [code]false[/code],此类事件将在引擎迭代之间æ¯ä¸ªç©ºé—²å¸§ä»…刷新一次。\n"
"å¯ç”¨æ­¤åŠŸèƒ½å¯ä»¥å¤§å¤§æé«˜å¯¹è¾“入的å“åº”èƒ½åŠ›ï¼Œç‰¹åˆ«æ˜¯åœ¨éœ€è¦æ¯ä¸ªå¯è§ï¼ˆç©ºé—²ï¼‰å¸§è¿è¡Œå¤š"
"个物ç†å¸§çš„设备中,因为它们无法以目标帧速率è¿è¡Œã€‚\n"
-"[b]注:[/b] ç›®å‰ä»…在 Android 中实现。"
+"[b]注æ„:[/b]ç›®å‰ä»…在 Android 中实现。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -60838,7 +61234,7 @@ msgid ""
"on threads. If servers get stalled too often when loading resources in a "
"thread, increase this number."
msgstr ""
-"在多线程模å¼ä¸‹ä½¿ç”¨æ—¶ï¼ŒæœåŠ¡å™¨ä¼šä½¿ç”¨å®ƒï¼ˆæœåŠ¡å™¨å’Œå¯è§†åŒ–端)。 RID 是预先分é…的,"
+"在多线程模å¼ä¸‹ä½¿ç”¨æ—¶ï¼ŒæœåŠ¡å™¨ä¼šä½¿ç”¨å®ƒï¼ˆæœåŠ¡å™¨å’Œå¯è§†åŒ–端)。RID 是预先分é…的,"
"以é¿å…åœ¨çº¿ç¨‹ä¸Šåœæ­¢è¯·æ±‚它们的æœåŠ¡å™¨ã€‚å¦‚æžœåœ¨çº¿ç¨‹ä¸­åŠ è½½èµ„æºæ—¶æœåС噍ç»å¸¸å¡é¡¿ï¼Œè¯·"
"增加此数字。"
@@ -60966,11 +61362,11 @@ msgstr "使用TCP的连接å°è¯•的超时(以秒为å•ä½ï¼‰ã€‚"
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebRTCDataChannel] input buffer."
-msgstr "[WebRTCDataChannel] 输入缓冲区的最大尺寸(å•ä½ï¼šåƒå­—节)。"
+msgstr "[WebRTCDataChannel] 输入缓冲区的最大尺寸(å•ä½ä¸º kiB)。"
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebSocketClient] input buffer."
-msgstr "[WebSocketClient] 输入缓冲区的最大尺寸,以 kiB 为å•ä½ã€‚"
+msgstr "[WebSocketClient] 输入缓冲区的最大尺寸(å•ä½ä¸º kiB)。"
#: doc/classes/ProjectSettings.xml
msgid "Maximum number of concurrent input packets for [WebSocketClient]."
@@ -60978,7 +61374,7 @@ msgstr "[WebSocketClient] 的最大并å‘输入数æ®åŒ…数。"
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebSocketClient] output buffer."
-msgstr "[WebSocketClient]输出缓冲区的最大尺寸,以kiB为å•ä½ã€‚"
+msgstr "[WebSocketClient]输出缓冲区的最大尺寸(å•ä½ä¸º kiB)。"
#: doc/classes/ProjectSettings.xml
msgid "Maximum number of concurrent output packets for [WebSocketClient]."
@@ -60986,7 +61382,7 @@ msgstr "[WebSocketClient]的最大并å‘输出数æ®åŒ…æ•°é‡ã€‚"
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebSocketServer] input buffer."
-msgstr "[WebSocketServer]输入缓冲区的最大尺寸,以kiB为å•ä½ã€‚"
+msgstr "[WebSocketServer]输入缓冲区的最大尺寸(å•ä½ä¸º kiB)。"
#: doc/classes/ProjectSettings.xml
msgid "Maximum number of concurrent input packets for [WebSocketServer]."
@@ -60994,7 +61390,7 @@ msgstr "[WebSocketServer] 的最大并å‘输入数æ®åŒ…æ•°é‡ã€‚"
#: doc/classes/ProjectSettings.xml
msgid "Maximum size (in kiB) for the [WebSocketServer] output buffer."
-msgstr "[WebSocketServer] 输出缓冲区的最大尺寸,以 kiB 为å•ä½ã€‚"
+msgstr "[WebSocketServer] 输出缓冲区的最大尺寸(å•ä½ä¸º kiB)。"
#: doc/classes/ProjectSettings.xml
msgid "Maximum number of concurrent output packets for [WebSocketServer]."
@@ -61021,9 +61417,9 @@ msgid ""
"bundle will be used.\n"
"If in doubt, leave this setting empty."
msgstr ""
-"用于SSL连接的CAè¯ä¹¦åŒ…。如果设置为éžç©ºå€¼ï¼Œè¿™å°†[i]覆盖[/i]Godot默认的"
+"用于 SSL 连接的 CA è¯ä¹¦åŒ…。如果设置为éžç©ºå€¼ï¼Œè¿™å°†[i]覆盖[/i] Godot 默认的 "
"[url=https://github.com/godotengine/godot/blob/master/thirdparty/certs/ca-"
-"certificates.crt]Mozillaè¯ä¹¦åŒ…[/url]。如果留空,将使用默认的è¯ä¹¦åŒ…。\n"
+"certificates.crt]Mozilla è¯ä¹¦åŒ…[/url]。如果留空,将使用默认的è¯ä¹¦åŒ…。\n"
"如果有疑问,让这个设置为空。"
#: doc/classes/ProjectSettings.xml
@@ -61559,8 +61955,8 @@ msgid ""
"with hardware skinning, [code]VERTEX[/code] is the position [i]before[/i] "
"skinning."
msgstr ""
-"如果 [code]true[/code],则在 CPU è€Œéž GPU 上执行 2D 蒙皮。这æä¾›äº†ä¸Žå„ç§ç¡¬ä»¶"
-"的更大兼容性,并且在æŸäº›æƒ…况下也å¯èƒ½æ›´å¿«ã€‚\n"
+"如果为 [code]true[/code],则在 CPU è€Œéž GPU 上执行 2D 蒙皮。这æä¾›äº†ä¸Žå„ç§ç¡¬"
+"件的更大兼容性,并且在æŸäº›æƒ…况下也å¯èƒ½æ›´å¿«ã€‚\n"
"当å‰ä»…在 [member rendering/batching/options/use_batching] å¤„äºŽæ´»åŠ¨çŠ¶æ€æ—¶å¯"
"用。\n"
"[b]注æ„:[/b]䏿”¯æŒæŠ—锯齿软件蒙皮多边形,将在没有抗锯齿的情况下渲染。\n"
@@ -61576,8 +61972,8 @@ msgid ""
"Consider using the project setting [member rendering/batching/precision/"
"uv_contract] to prevent artifacts."
msgstr ""
-"如果 [code]true[/code],则在 2D 渲染中强制将顶点对é½åˆ°åƒç´ ã€‚å¯èƒ½æœ‰åŠ©äºŽæŸäº›åƒ"
-"素艺术风格。\n"
+"如果为 [code]true[/code],则在 2D 渲染中强制将顶点对é½åˆ°åƒç´ ã€‚å¯èƒ½æœ‰åŠ©äºŽæŸäº›"
+"åƒç´ è‰ºæœ¯é£Žæ ¼ã€‚\n"
"è¿™ç§æ•æ‰æ˜¯åœ¨é¡¶ç‚¹ç€è‰²å™¨ä¸­çš„ GPU 上执行的。\n"
"考虑使用项目设置[member rendering/batching/precision/uv_contract] æ¥é˜²æ­¢å‡ºçް"
"伪影。"
@@ -61836,9 +62232,8 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
"这是åŒä¸€æ—¶é—´æ‰€èƒ½ç¼–译(或者从缓存中é‡å»ºï¼‰çš„ç€è‰²å™¨çš„æœ€å¤§æ•°é‡ã€‚\n"
"在è¿è¡Œæ—¶ï¼Œå¦‚果已ç»è¾¾åˆ°äº†è¿™ä¸ªæ•°é‡ï¼Œå…¶ä»–能够进行异步编译的ç€è‰²å™¨ä¼šç›´æŽ¥ä½¿ç”¨å®ƒä»¬"
@@ -61847,56 +62242,80 @@ msgstr ""
"èƒ½å¤šçš„å¼‚æ­¥ç¼–è¯‘çš„åŒæ—¶ï¼Œä¸å¯¹æ¸¸æˆçš„å“应性造æˆå½±å“,å¦åˆ™å°±ä¼šè¾œè´Ÿå¼‚步编译所带æ¥çš„"
"好处。æ¢å¥è¯è¯´ï¼Œä½ å¯èƒ½ä¼šç‰ºç‰²ä¸€ç‚¹ç‚¹çš„ FPSï¼Œæ€»æ¯”åŒæ­¥ç¼–译让整个游æˆåœæ»žè¦å¥½ã€‚\n"
"默认值比较ä¿å®ˆï¼Œæ‰€ä»¥å»ºè®®ä½ æ ¹æ®è‡ªå·±çš„目标硬件作出调整。\n"
-"[b]注æ„:[/b]本设置仅在 [code]rendering/gles3/shaders/"
-"shader_compilation_mode[/code] [b]ä¸ä¸º[/b] [code]Synchronous[/code] 时有æ„"
-"义。"
+"[b]注æ„:[/b]本设置仅在 [member rendering/gles3/shaders/"
+"shader_compilation_mode] [b]ä¸ä¸º[/b] [code]Synchronous[/code] 时有æ„义。"
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
-"默认是针对 [code]rendering/gles3/shaders/max_concurrent_compiles[/code] 的覆"
+"默认是针对 [member rendering/gles3/shaders/max_simultaneous_compiles] 的覆"
"盖,å–值éžå¸¸ä¿å®ˆã€‚\n"
"æ ¹æ®ä½ æ‰€è®¾å®šä¸ºç›®æ ‡çš„特定设备,你å¯èƒ½ä¼šæƒ³è¦æé«˜è¿™ä¸ªå€¼ã€‚\n"
-"[b]注æ„:[/b]本设置仅在 [code]rendering/gles3/shaders/"
-"shader_compilation_mode[/code] [b]ä¸ä¸º[/b] [code]Synchronous[/code] 时有æ„"
-"义。"
+"[b]注æ„:[/b]本设置仅在 [member rendering/gles3/shaders/"
+"shader_compilation_mode] [b]ä¸ä¸º[/b] [code]Synchronous[/code] 时有æ„义。"
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+"默认是针对 [member rendering/gles3/shaders/max_simultaneous_compiles] 的覆"
+"盖,å–值éžå¸¸ä¿å®ˆã€‚\n"
+"æ ¹æ®ä½ æ‰€è®¾å®šä¸ºç›®æ ‡çš„特定设备,你å¯èƒ½ä¼šæƒ³è¦æé«˜è¿™ä¸ªå€¼ã€‚\n"
+"[b]注æ„:[/b]本设置仅在 [member rendering/gles3/shaders/"
+"shader_compilation_mode] [b]ä¸ä¸º[/b] [code]Synchronous[/code] 时有æ„义。"
#: doc/classes/ProjectSettings.xml
msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
"超级ç€è‰²å™¨ç¼“存所能增长到的最大大å°ï¼Œå•ä½ä¸ºå…†å­—节。在å¯åŠ¨æ—¶ï¼Œä¼šåˆ é™¤æœ€ä¹…æœªç”¨çš„"
"æ¡ç›®ï¼Œç›´åˆ°æ€»å¤§å°åˆ°è¾¾èŒƒå›´å†…。\n"
-"[b]注æ„:[/b]本设置仅在 [code]rendering/gles3/shaders/"
-"shader_compilation_mode[/code] 为 [code]Asynchronous + Cache[/code] 时有æ„"
-"义。"
+"[b]注æ„:[/b]本设置仅在 [member rendering/gles3/shaders/"
+"shader_compilation_mode] 为 [code]Asynchronous + Cache[/code] 时有æ„义。"
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
-"[code]rendering/gles3/shaders/ubershader_cache_size_mb[/code] 的覆盖项,为针"
-"对移动平å°é…置更å°çš„æœ€å¤§å¤§å°ï¼Œç§»åЍ平å°çš„存储空间更有é™ã€‚\n"
-"[b]注æ„:[/b]本设置仅在 [code]rendering/gles3/shaders/"
-"shader_compilation_mode[/code] 为 [code]Asynchronous + Cache[/code] 时有æ„"
-"义。"
+"[member rendering/gles3/shaders/shader_cache_size_mb] 的覆盖项,为针对移动平"
+"å°é…置更å°çš„æœ€å¤§å¤§å°ï¼Œç§»åЍ平å°çš„存储空间更有é™ã€‚\n"
+"[b]注æ„:[/b]本设置仅在 [member rendering/gles3/shaders/"
+"shader_compilation_mode] 为 [code]Asynchronous + Cache[/code] 时有æ„义。"
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+"[member rendering/gles3/shaders/shader_cache_size_mb] 的覆盖项,为针对移动平"
+"å°é…置更å°çš„æœ€å¤§å¤§å°ï¼Œç§»åЍ平å°çš„存储空间更有é™ã€‚\n"
+"[b]注æ„:[/b]ç›®å‰ Web å¹³å°å°šä¸æ”¯æŒç€è‰²å™¨ç¼“存。\n"
+"[b]注æ„:[/b]本设置仅在 [member rendering/gles3/shaders/"
+"shader_compilation_mode] 为 [code]Asynchronous + Cache[/code] 时有æ„义。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -61943,17 +62362,28 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
-"[code]rendering/gles3/shaders/shader_compilation_mode[/code] 的覆盖项,用于为"
-"移动设备ç¦ç”¨å¼‚步编译。\n"
+"[member rendering/gles3/shaders/shader_compilation_mode] 的覆盖项,用于为移动"
+"设备ç¦ç”¨å¼‚步编译。\n"
"移动 GPU 通常ä¸ä¼šæ”¯æŒè¶…级ç€è‰²å™¨ï¼Œå› ä¸ºå…¶å¤æ‚度较高。"
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+"[member rendering/gles3/shaders/shader_compilation_mode] 的覆盖项,用于为 "
+"Web å¹³å°ç¦ç”¨å¼‚步编译。\n"
+"æŸäº›æµè§ˆå™¨ï¼ˆå°¤å…¶åœ¨ç§»åЍ平å°ä¸Šï¼‰é€šå¸¸ä¸ä¼šæ”¯æŒè¶…级ç€è‰²å™¨ï¼Œå› ä¸ºå…¶å¤æ‚度较高。"
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr "æ··åˆå½¢çŠ¶çš„æœ€å¤§ç¼“å†²åŒºå¤§å°ã€‚任何比这更大的混åˆå½¢çŠ¶éƒ½ä¸èµ·ä½œç”¨ã€‚"
@@ -62270,7 +62700,7 @@ msgid ""
"VRAM-compressed textures will be exported on Android and iOS, increasing the "
"data pack's size."
msgstr ""
-"如果 [code]true[/code]ï¼Œä¸”ä¸æ”¯æŒ GLES3 驱动程åºï¼Œåˆ™å…许回退到 GLES2 驱动程"
+"如果为 [code]true[/code]ï¼Œä¸”ä¸æ”¯æŒ GLES3 驱动程åºï¼Œåˆ™å…许回退到 GLES2 驱动程"
"åºã€‚\n"
"[b]注æ„:[/b]两个显å¡é©±åЍ䏿˜¯äº’相替代的,所以为 GLES3 设计的游æˆåœ¨å›žé€€åˆ° "
"GLES2 æ—¶å¯èƒ½æ— æ³•正常è¿è¡Œã€‚特别是,GLES3 åŽç«¯çš„æŸäº›åŠŸèƒ½åœ¨ GLES2 中ä¸å¯ç”¨ã€‚å¯ç”¨"
@@ -62307,9 +62737,8 @@ msgid ""
"[member rendering/quality/filters/use_fxaa]."
msgstr ""
"如果设置为大于 [code]0.0[/code] 的值,对比度自适应é”化将应用于 3D 视å£ã€‚这具"
-"æœ‰è¾ƒä½Žçš„æ€§èƒ½æˆæœ¬ï¼Œå¯ç”¨äºŽæ¢å¤ä½¿ç”¨ FXAA æ—¶æŸå¤±çš„一些é”度。 [code]0.5[/code] 附"
-"近的值通常会给出最好的结果。å¦è§ [member rendering/quality/filters/"
-"use_fxaa]。"
+"æœ‰è¾ƒä½Žçš„æ€§èƒ½æˆæœ¬ï¼Œå¯ç”¨äºŽæ¢å¤ä½¿ç”¨ FXAA æ—¶æŸå¤±çš„一些é”度。[code]0.5[/code] 附近"
+"的值通常会给出最好的结果。å¦è§ [member rendering/quality/filters/use_fxaa]。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -62327,8 +62756,8 @@ msgstr ""
"如果为 [code]true[/code],则使用快速åŽå¤„ç†è¿‡æ»¤å™¨ä½¿æ¡å¸¦æ˜Žæ˜¾ä¸é‚£ä¹ˆæ˜Žæ˜¾ã€‚在æŸäº›"
"情况下,去带å¯èƒ½ä¼šå¼•å…¥ç¨å¾®æ˜Žæ˜¾çš„æŠ–动模å¼ã€‚å»ºè®®ä»…åœ¨å®žé™…éœ€è¦æ—¶å¯ç”¨åŽ»æ¡å¸¦ï¼Œå› ä¸º"
"抖动模å¼ä¼šä½¿æ— æŸåŽ‹ç¼©çš„å±å¹•截图更大。\n"
-"[b]注æ„:[/b]仅在 GLES3 åŽç«¯å¯ç”¨ã€‚ [member rendering/quality/depth/hdr] 也必"
-"须为 [code]true[/code] æ‰èƒ½ä½¿åŽ»è‰²å¸¦æœ‰æ•ˆã€‚\n"
+"[b]注æ„:[/b]仅在 GLES3 åŽç«¯å¯ç”¨ã€‚[member rendering/quality/depth/hdr] 也必须"
+"为 [code]true[/code] æ‰èƒ½ä½¿åŽ»è‰²å¸¦æœ‰æ•ˆã€‚\n"
"[b]注æ„:[/b]已知在移动平å°ä¸Šçš„åŽ»è‰²å¸¦å­˜åœ¨ç ´åæ¸²æŸ“的问题。因此,建议在用于移动"
"平尿—¶ç¦ç”¨æ­¤é€‰é¡¹ã€‚"
@@ -62354,10 +62783,10 @@ msgid ""
"mobile as less memory bandwidth is used. If [code]false[/code], linear "
"mipmap filtering (also called \"trilinear filtering\") is used."
msgstr ""
-"如果 [code]true[/code],则在使用 mipmap 时使用最近邻 mipmap 过滤(也称为“åŒçº¿"
-"性过滤â€ï¼‰ï¼Œè¿™å°†å¯¼è‡´ mipmap 阶段之间出现å¯è§çš„æŽ¥ç¼ã€‚由于使用较少的内存带宽,这"
-"å¯èƒ½ä¼šæé«˜ç§»åŠ¨è®¾å¤‡çš„æ€§èƒ½ã€‚å¦‚æžœ [code]false[/code],则使用线性 mipmap 过滤(也"
-"称为“三线性过滤â€ï¼‰ã€‚"
+"如果为 [code]true[/code],则在使用 mipmap 时使用最近邻 mipmap 过滤(也称为“åŒ"
+"线性过滤â€ï¼‰ï¼Œè¿™å°†å¯¼è‡´ mipmap 阶段之间出现å¯è§çš„æŽ¥ç¼ã€‚由于使用较少的内存带宽,"
+"è¿™å¯èƒ½ä¼šæé«˜ç§»åŠ¨è®¾å¤‡çš„æ€§èƒ½ã€‚å¦‚æžœ [code]false[/code],则使用线性 mipmap 过滤"
+"(也称为“三线性过滤â€ï¼‰ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -62380,8 +62809,8 @@ msgid ""
"framebuffer_allocation] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-"由于性能或驱动支æŒé—®é¢˜ï¼Œåœ¨ç§»åŠ¨è®¾å¤‡ä¸Šå¯¹[member rendering/quality/"
-"intended_usage/framebuffer_allocation]ä»¥ä½Žé…æ•°å€¼è¦†ç›–。"
+"由于性能或驱动支æŒé—®é¢˜ï¼Œåœ¨ç§»åŠ¨è®¾å¤‡ä¸Šå¯¹ [member rendering/quality/"
+"intended_usage/framebuffer_allocation] ä»¥ä½Žé…æ•°å€¼è¦†ç›–。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -62397,8 +62826,8 @@ msgid ""
"Lower-end override for [member rendering/quality/lightmapping/"
"use_bicubic_sampling] on mobile devices, in order to reduce bandwidth usage."
msgstr ""
-"在移动设备上对[member rendering/quality/lightmapping/use_bicubic_sampling]进"
-"行低端覆盖,以å‡å°‘带宽使用。"
+"在移动设备上对 [member rendering/quality/lightmapping/use_bicubic_sampling] "
+"进行低端覆盖,以å‡å°‘带宽使用。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -62422,8 +62851,8 @@ msgid ""
"variants of reflection probes and panorama backgrounds (sky). Those blurred "
"variants are used by rough materials."
msgstr ""
-"如果 [code]true[/code]ï¼Œåˆ™ä½¿ç”¨å¤§é‡æ ·æœ¬æ¥åˆ›å»ºå射探针和全景背景(天空)的模糊"
-"å˜ä½“。这些模糊的å˜ä½“å¯ä»¥è¢«ç²—糙的æè´¨ä½¿ç”¨ã€‚"
+"如果为 [code]true[/code]ï¼Œåˆ™ä½¿ç”¨å¤§é‡æ ·æœ¬æ¥åˆ›å»ºå射探针和全景背景(天空)的模"
+"糊å˜ä½“。这些模糊的å˜ä½“å¯ä»¥è¢«ç²—糙的æè´¨ä½¿ç”¨ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -62444,7 +62873,7 @@ msgid ""
"[b]Note:[/b] Low and mid range hardware do not support complex irradiance "
"maps well and may crash if this is set too high."
msgstr ""
-"é™åˆ¶è¾ç…§åº¦è´´å›¾çš„大å°ï¼Œé€šå¸¸ç”± [member Sky.radiance_size] 确定。与[member "
+"é™åˆ¶è¾ç…§åº¦è´´å›¾çš„大å°ï¼Œé€šå¸¸ç”± [member Sky.radiance_size] 确定。与 [member "
"rendering/quality/reflections/high_quality_ggx] 类似,更大的尺寸会产生更高质"
"é‡çš„è¾ç…§åº¦è´´å›¾ã€‚使用高频 HDRI 贴图时使用较高的值,å¦åˆ™è¯·å°½å¯èƒ½é™ä½Žè¯¥å€¼ã€‚\n"
"[b]注æ„:[/b]中低档硬件ä¸èƒ½å¾ˆå¥½åœ°æ”¯æŒå¤æ‚çš„è¾ç…§åº¦è´´å›¾ï¼Œå¦‚果设置太高å¯èƒ½ä¼šå´©"
@@ -62571,9 +63000,11 @@ msgstr "阴影贴图的细分象é™å¤§å°ã€‚请å‚阅阴影映射文档。"
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
-msgstr "阴影图集的尺寸(用于 OmniLight å’Œ SpotLightï¼‰ã€‚è§æ–‡æ¡£ã€‚"
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
+msgstr ""
+"设置阴影图集的图åƒå¤§å°ï¼ˆç”¨äºŽå…¨å‘光和èšå…‰ï¼‰ã€‚该值将被四èˆäº”入到最接近的 2 çš„"
+"幂。è§é˜´å½±è´´å›¾æ–‡æ¡£ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -62715,8 +63146,8 @@ msgid ""
"Try enabling this option if you see any visual anomalies in 3D (such as "
"incorrect object visibility)."
msgstr ""
-"如果 [code]true[/code],则将在渲染和 Godot 物ç†ä¸­ä½¿ç”¨çº¿ç¨‹å®‰å…¨ç‰ˆæœ¬çš„ BVH(边界"
-"体积层次结构)。\n"
+"如果为 [code]true[/code],则将在渲染和 Godot 物ç†ä¸­ä½¿ç”¨çº¿ç¨‹å®‰å…¨ç‰ˆæœ¬çš„ BVH(边"
+"界体积层次结构)。\n"
"如果您在 3D ä¸­çœ‹åˆ°ä»»ä½•è§†è§‰å¼‚å¸¸ï¼Œä¾‹å¦‚ä¸æ­£ç¡®çš„å¯è§æ€§å¯¹è±¡ï¼Œè¯·å°è¯•å¯ç”¨æ­¤é€‰é¡¹ã€‚"
#: doc/classes/ProjectSettings.xml
@@ -63135,7 +63566,7 @@ msgid ""
"operations (obtaining axis-angle and performing SLERP, in particular) are "
"more efficient and robust against floating-point errors."
msgstr ""
-"一个用于表示 3D 旋转的å•ä½å››å…ƒæ•°ã€‚四元数需è¦ç»è¿‡å½’一化æ‰èƒ½ç”¨äºŽæ—‹è½¬ã€‚\n"
+"用于表示 3D 旋转的å•ä½å››å…ƒæ•°ã€‚四元数需è¦ç»è¿‡å½’一化æ‰èƒ½ç”¨äºŽæ—‹è½¬ã€‚\n"
"它类似于 Basis,åŽè€…实现了旋转的矩阵表示,并且å¯ä»¥ä½¿ç”¨è½´-è§’å¯¹æˆ–æ¬§æ‹‰è§’è¿›è¡Œå‚æ•°"
"化。Basis å¯ä»¥å­˜å‚¨æ—‹è½¬ã€ç¼©æ”¾å’Œé”™åˆ‡ï¼Œè€Œ Quat åªå­˜å‚¨æ—‹è½¬ã€‚\n"
"由于它的紧凑性和在内存中的存储方å¼ï¼ŒæŸäº›æ“作(特别是获得轴角和执行 SLERP)更"
@@ -63307,12 +63738,12 @@ msgid ""
"[Basis] matrix. If a vector is transformed by an identity quaternion, it "
"will not change."
msgstr ""
-"å•ä½å››å…ƒæ•°ï¼Œä»£è¡¨æ— æ—‹è½¬ã€‚等效于å•ä½ [Basis] 矩阵。如果一个å‘é‡è¢«ä¸€ä¸ªå•ä½å››å…ƒæ•°"
+"å•ä½å››å…ƒæ•°ï¼Œä»£è¡¨æ— æ—‹è½¬ã€‚相当于å•ä½ [Basis] 矩阵。如果一个å‘é‡è¢«ä¸€ä¸ªå•ä½å››å…ƒæ•°"
"å˜æ¢ï¼Œå®ƒä¸ä¼šæ”¹å˜ã€‚"
#: doc/classes/RandomNumberGenerator.xml
msgid "A class for generating pseudo-random numbers."
-msgstr "一个用于生æˆä¼ªéšæœºæ•°çš„ç±»ã€‚"
+msgstr "用于生æˆä¼ªéšæœºæ•°çš„ç±»ã€‚"
#: doc/classes/RandomNumberGenerator.xml
msgid ""
@@ -63336,8 +63767,8 @@ msgid ""
msgstr ""
"RandomNumberGenerator 是一个用于生æˆä¼ªéšæœºæ•°çš„ç±»ã€‚å®ƒç›®å‰ä½¿ç”¨ [url=http://www."
"pcg-random.org/]PCG32[/url]。\n"
-"[b]注:[/b]底层算法是实现细节。因此,跨 Godot 版本的å¯é‡å¤éšæœºæµä¸åº”该ä¾èµ–于"
-"此。\n"
+"[b]注æ„:[/b]底层算法是实现细节。因此,跨 Godot 版本的å¯é‡å¤éšæœºæµä¸åº”该ä¾èµ–"
+"于此。\n"
"è¦æ ¹æ®æ—¶é—´ç›¸å…³ç§å­ç”Ÿæˆéšæœºæµ®ç‚¹æ•°ï¼Œåœ¨ç»™å®šèŒƒå›´å†…ï¼š\n"
"[codeblock]\n"
"var rng = RandomNumberGenerator.new()\n"
@@ -63345,7 +63776,7 @@ msgstr ""
" rng.randomize()\n"
" var my_random_number = rng.randf_range(-10.0, 10.0)\n"
"[/codeblock]\n"
-"[b]注:[/b] [member seed] å’Œ [member state] å±žæ€§çš„é»˜è®¤å€¼æ˜¯ä¼ªéšæœºçš„,在调用"
+"[b]注æ„:[/b][member seed] å’Œ [member state] å±žæ€§çš„é»˜è®¤å€¼æ˜¯ä¼ªéšæœºçš„,在调用 "
"[method randomize] 时会å‘生å˜åŒ–。此处记录的 [code]0[/code] 值是一个å ä½ç¬¦ï¼Œè€Œ"
"䏿˜¯å®žé™…的默认ç§å­ã€‚"
@@ -63453,10 +63884,10 @@ msgstr ""
"[codeblock]\n"
"var rng = RandomNumberGenerator.new()\n"
"print(rng.randf())\n"
-"var saved_state = rng.state # Store current state.\n"
-"print(rng.randf()) # Advance internal state.\n"
-"rng.state = saved_state # Restore the state.\n"
-"print(rng.randf()) # Prints the same value as in previous.\n"
+"var saved_state = rng.state # ä¿å­˜å½“å‰çжæ€ã€‚\n"
+"print(rng.randf()) # 让内部状æ€å‘生步进。\n"
+"rng.state = saved_state # æ¢å¤çжæ€ã€‚\n"
+"print(rng.randf()) # 输出和之å‰ä¸€æ ·çš„值。\n"
"[/codeblock]\n"
"[b]注æ„:[/b]ä¸è¦å°†çжæ€è®¾ç½®ä¸ºä»»æ„å€¼ï¼Œå› ä¸ºéšæœºæ•°ç”Ÿæˆå™¨è¦æ±‚状æ€å…·æœ‰æŸäº›ç‰¹æ€§æ‰èƒ½"
"正常è¿è¡Œã€‚它应该åªè®¾ç½®ä¸ºæ¥è‡ªçжæ€å±žæ€§æœ¬èº«çš„值。è¦ä½¿ç”¨ä»»æ„输入åˆå§‹åŒ–éšæœºæ•°ç”Ÿæˆ"
@@ -63495,20 +63926,20 @@ msgstr "使该 [Range] åœæ­¢ä¸Žä»»ä½•å…¶ä»– Range 共享其æˆå‘˜å˜é‡ã€‚"
#: doc/classes/Range.xml
msgid ""
"If [code]true[/code], [member value] may be greater than [member max_value]."
-msgstr "如果[code]true[/code],[member value]å¯èƒ½å¤§äºŽ[member max_value]。"
+msgstr "如果为 [code]true[/code],[member value]å¯èƒ½å¤§äºŽ[member max_value]。"
#: doc/classes/Range.xml
msgid ""
"If [code]true[/code], [member value] may be less than [member min_value]."
-msgstr "如果[code]true[/code],[member value]å¯èƒ½å°äºŽ[member min_value]。"
+msgstr "如果为 [code]true[/code],[member value]å¯èƒ½å°äºŽ[member min_value]。"
#: doc/classes/Range.xml
msgid ""
"If [code]true[/code], and [code]min_value[/code] is greater than 0, "
"[code]value[/code] will be represented exponentially rather than linearly."
msgstr ""
-"如果[code]true[/code],并且[code]min_value[/code]大于0,[code]value[/code]将"
-"以指数方å¼è€Œä¸æ˜¯çº¿æ€§æ–¹å¼è¡¨ç¤ºã€‚"
+"如果为 [code]true[/code],并且[code]min_value[/code]大于0,[code]value[/code]"
+"将以指数方å¼è€Œä¸æ˜¯çº¿æ€§æ–¹å¼è¡¨ç¤ºã€‚"
#: doc/classes/Range.xml
msgid ""
@@ -63542,7 +63973,7 @@ msgid ""
"If [code]true[/code], [code]value[/code] will always be rounded to the "
"nearest integer."
msgstr ""
-"如果 [code]true[/code],[code]value[/code] 将始终四èˆäº”入到最接近的整数。"
+"如果为 [code]true[/code],[code]value[/code] 将始终四èˆäº”入到最接近的整数。"
#: doc/classes/Range.xml
msgid ""
@@ -63786,8 +64217,8 @@ msgid ""
"queries are required between physics frames (or during the same frame) use "
"[method force_raycast_update] after adjusting the raycast."
msgstr ""
-"RayCast 表示一æ¡ä»ŽåŽŸç‚¹åˆ°ç›®æ ‡ä½ç½® [code]cast_to[/code] çš„ç›´çº¿ã€‚å®ƒè¢«ç”¨æ¥æŸ¥è¯¢2D"
-"空间,以便沿ç€å°„线的路径找到最近的物体。\n"
+"RayCast 表示一æ¡ä»ŽåŽŸç‚¹åˆ°ç›®æ ‡ä½ç½® [code]cast_to[/code] çš„ç›´çº¿ã€‚å®ƒè¢«ç”¨æ¥æŸ¥è¯¢ "
+"2D 空间,以便沿ç€å°„线的路径找到最近的物体。\n"
"RayCast2D å¯ä»¥å¿½ç•¥ä¸€äº›ç‰©ä½“,通过 [code]add_exception[/code] 将它们添加到异常"
"列表中,通过设置碰撞层进行适当的过滤,或者通过类型掩ç è¿‡æ»¤ç‰©ä½“类型。\n"
"RayCast2D å¯ä»¥è¢«é…置为报告 [Area2D]([member collide_with_areas])和 "
@@ -63838,7 +64269,7 @@ msgstr "射线的长度。"
#: doc/classes/RayShape.xml doc/classes/RayShape2D.xml
msgid "If [code]true[/code], allow the shape to return the correct normal."
-msgstr "如果 [code]true[/code],则å…许形状返回正确的法线。"
+msgstr "如果为 [code]true[/code],则å…许形状返回正确的法线。"
#: doc/classes/RayShape2D.xml
msgid "Ray shape for 2D collisions."
@@ -63850,8 +64281,8 @@ msgid ""
"it tries to separate itself from whatever is touching its far endpoint. It's "
"often useful for characters."
msgstr ""
-"äºŒç»´ç¢°æ’žçš„å°„çº¿å½¢çŠ¶ã€‚å°„çº¿å¹¶ä¸æ˜¯çœŸæ­£çš„碰撞体;相å,它试图将自己与接触其远端的"
-"任何东西分开。它通常对角色很有用。"
+"2D ç¢°æ’žçš„å°„çº¿å½¢çŠ¶ã€‚å°„çº¿å¹¶ä¸æ˜¯çœŸæ­£çš„碰撞体;相å,它试图将自己与接触其远端的任"
+"何东西分开。它通常对角色很有用。"
#: doc/classes/Rect2.xml
msgid "2D axis-aligned bounding box."
@@ -63995,13 +64426,13 @@ msgstr "返回一个更大的 [Rect2],其中包å«è¿™ä¸ª [Rect2] å’Œ [code]b[/
#: doc/classes/RectangleShape2D.xml
msgid "Rectangle shape for 2D collisions."
-msgstr "二维碰撞的矩形。"
+msgstr "2D 碰撞的矩形。"
#: doc/classes/RectangleShape2D.xml
msgid ""
"Rectangle shape for 2D collisions. This shape is useful for modeling box-"
"like 2D objects."
-msgstr "二维碰撞的矩形。这个形状对于建模盒状2D对象很有用。"
+msgstr "2D 碰撞的矩形。这个形状对于建模盒状 2D 对象很有用。"
#: doc/classes/RectangleShape2D.xml
msgid ""
@@ -64029,7 +64460,7 @@ msgid ""
"free references that are no longer in use. This means that unused references "
"will linger on for a while before being removed."
msgstr ""
-"ä»»ä½•ä¿æŒå¼•用计数对象的基类。 [Resource] 和许多其他辅助对象继承了这个类。\n"
+"ä»»ä½•ä¿æŒå¼•用计数对象的基类。[Resource] 和许多其他辅助对象继承了这个类。\n"
"与其他 [Object] 类型ä¸åŒï¼ŒReference ä¿ç•™ä¸€ä¸ªå†…部引用计数器,以便在ä¸ä½¿ç”¨ä¸”ä»…"
"在那时自动释放。因此,ä¸éœ€è¦ä½¿ç”¨ [method Object.free] 手动释放引用。\n"
"在ç»å¤§å¤šæ•°ç”¨ä¾‹ä¸­ï¼Œæ‚¨åªéœ€è¦å®žä¾‹åŒ–和使用 [Reference] 派生类型。此类中æä¾›çš„æ–¹æ³•"
@@ -64077,8 +64508,8 @@ msgid ""
"display a rectangle filled with a solid color, consider using [ColorRect] "
"instead."
msgstr ""
-"矩形框,仅在其矩形周围显示 [member border_color] 边框颜色。 [ReferenceRect] "
-"没有填充 [Color]ã€‚å¦‚æžœä½ éœ€è¦æ˜¾ç¤ºå¡«å……纯色的矩形,请考虑使用 [ColorRect] 。"
+"矩形框,仅在其矩形周围显示 [member border_color] 边框颜色。[ReferenceRect] 没"
+"有填充 [Color]ã€‚å¦‚æžœä½ éœ€è¦æ˜¾ç¤ºå¡«å……纯色的矩形,请考虑使用 [ColorRect] 。"
#: doc/classes/ReferenceRect.xml
msgid "Sets the border [Color] of the [ReferenceRect]."
@@ -64178,8 +64609,8 @@ msgid ""
"the reflection probe slower to render; you may want to disable this if using "
"the [constant UPDATE_ALWAYS] [member update_mode]."
msgstr ""
-"如果[code]true[/code],则在å射探测中计算阴影。这使得å射探针渲染更慢;如果想"
-"ç¦ç”¨å®ƒ,å¯ä»¥ä½¿ç”¨ [constant UPDATE_ALWAYS] [member update_mode]。"
+"如果为 [code]true[/code],则在å射探测中计算阴影。这使得å射探针渲染更慢;如果"
+"想ç¦ç”¨å®ƒ,å¯ä»¥ä½¿ç”¨ [constant UPDATE_ALWAYS] [member update_mode]。"
#: doc/classes/ReflectionProbe.xml
msgid ""
@@ -64228,7 +64659,7 @@ msgid ""
"lighting is then controlled by the [code]interior_ambient_*[/code] "
"properties."
msgstr ""
-"如果[code]true[/code],å射将忽略天空的贡献。然åŽçŽ¯å¢ƒç…§æ˜Žç”±"
+"如果为 [code]true[/code],å射将忽略天空的贡献。然åŽçŽ¯å¢ƒç…§æ˜Žç”±"
"[code]internal_ambient_*[/code]属性控制。"
#: doc/classes/ReflectionProbe.xml
@@ -64364,61 +64795,63 @@ msgid ""
"[b]Tip:[/b] You can use [url=https://regexr.com/]Regexr[/url] to test "
"regular expressions online."
msgstr ""
-"正则表达å¼ï¼ˆæˆ–ç§°regex)是一ç§ç´§å‡‘的语言,å¯ç”¨äºŽè¯†åˆ«éµå¾ªç‰¹å®šæ¨¡å¼çš„字符串,如"
-"URLã€ç”µå­é‚®ä»¶åœ°å€ã€å®Œæ•´å¥å­ç­‰ã€‚例如,一个[code]ab[0-9][/code]的正则表达å¼å¯ä»¥"
-"找到[code]ab[/code]åŽé¢è·Ÿç€[code]0[/code]到[code]9[/code]的任何数字的字符串。"
-"è¦æƒ³æ›´æ·±å…¥åœ°äº†è§£ï¼Œä½ å¯ä»¥å¾ˆå®¹æ˜“地在互è”网上找到å„ç§æ•™ç¨‹å’Œè¯¦ç»†è§£é‡Šã€‚\n"
-"首先,在使用RegEx对象之å‰ï¼Œéœ€è¦ç”¨[method compile] 对其进行æœç´¢æ¨¡å¼çš„编译。\n"
+"正则表达å¼ï¼ˆæˆ–ç§° regex)是一ç§ç´§å‡‘的语言,å¯ç”¨äºŽè¯†åˆ«éµå¾ªç‰¹å®šæ¨¡å¼çš„字符串,如 "
+"URLã€ç”µå­é‚®ä»¶åœ°å€ã€å®Œæ•´å¥å­ç­‰ã€‚ä¾‹å¦‚æ­£åˆ™è¡¨è¾¾å¼ [code]ab[0-9][/code] å¯ä»¥æ‰¾åˆ° "
+"[code]ab[/code] åŽé¢è·Ÿç€ [code]0[/code] 到 [code]9[/code] 的任何数字的字符"
+"ä¸²ã€‚è¦æƒ³æ›´æ·±å…¥åœ°äº†è§£ï¼Œä½ å¯ä»¥å¾ˆå®¹æ˜“地在互è”网上找到å„ç§æ•™ç¨‹å’Œè¯¦ç»†è§£é‡Šã€‚\n"
+"首先,在使用 RegEx 对象之å‰ï¼Œéœ€è¦ç”¨ [method compile] 对其进行æœç´¢æ¨¡å¼çš„ç¼–"
+"译。\n"
"[codeblock]\n"
"var regex = RegEx.new()\n"
"regex.compile(\"\\\\w-(\\\\d+)\")\n"
"[/codeblock]\n"
-"在为表达å¼è½¬ä¹‰ä¹‹å‰ï¼Œå¿…须先为GDScript转义æœç´¢æ¨¡å¼ã€‚例如,[code]compile(\"\\"
-"\\d+\")[/code]会被RegEx读æˆ[code]\\d+[/code]ã€‚åŒæ ·ï¼Œ[code]compile(\"\\\"(?:\\"
-"\\\\\\.|[^\\\"])*\\\")[/code]会被读作[code]\"(?:\\.|[^\"])*\"[/code]。\n"
-"使用 [method search] ,你å¯ä»¥åœ¨ç»™å®šçš„æ–‡æœ¬ä¸­åŒ¹é…模å¼ã€‚如果匹é…到一个模å¼ï¼Œå°†è¿”"
-"回[RegExMatch],你å¯ä»¥ä½¿ç”¨[method RegExMatch.get_string]å’Œ[method RegExMatch."
-"get_start]等方法检索结果的细节。\n"
+"在为表达å¼è½¬ä¹‰ä¹‹å‰ï¼Œå¿…须先为 GDScript 转义æœç´¢æ¨¡å¼ã€‚例如,[code]compile(\"\\"
+"\\d+\")[/code] 会被 RegEx è¯»æˆ [code]\\d+[/code]ã€‚åŒæ ·ï¼Œ[code]compile(\"\\"
+"\"(?:\\\\\\\\.|[^\\\"])*\\\")[/code] 会被读作 [code]\"(?:\\.|[^\"])*\"[/"
+"code]。\n"
+"使用 [method search],你å¯ä»¥åœ¨ç»™å®šçš„æ–‡æœ¬ä¸­åŒ¹é…模å¼ã€‚如果匹é…到一个模å¼ï¼Œå°†è¿”"
+"回 [RegExMatch],你å¯ä»¥ä½¿ç”¨ [method RegExMatch.get_string] å’Œ [method "
+"RegExMatch.get_start] 等方法检索结果的细节。\n"
"[codeblock]\n"
"var regex = RegEx.new()\n"
"regex.compile(\"\\\\w-(\\\\d+)\")\n"
"var result = regex.search(\"abc n-0123\")\n"
"if result:\n"
-" print(result.get_string()) # Would print n-0123\n"
+" print(result.get_string()) # 会输出 n-0123\n"
"[/codeblock]\n"
-"æ•获组的结果[code]()[/code]å¯ä»¥é€šè¿‡å‘[RegExMatch]中的å„ç§æ–¹æ³•ä¼ é€’ç»„å·æ¥æ£€ç´¢ã€‚"
-"默认是组0,并且将总是指整个模å¼ã€‚在上é¢çš„例å­ä¸­ï¼Œè°ƒç”¨[code]result."
-"get_string(1)[/code]会得到[code]0123[/code]。\n"
-"这个版本的RegEx也支æŒå‘½åçš„æ•获组,åç§°å¯ä»¥ç”¨æ¥æ£€ç´¢ç»“果。如果两个或更多的组有"
-"相åŒçš„å称,那么这个åç§°å°†åªæŒ‡ç¬¬ä¸€ä¸ªæœ‰åŒ¹é…的组。\n"
+"æ•获组的结果 [code]()[/code] å¯ä»¥é€šè¿‡å‘ [RegExMatch] 中的å„ç§æ–¹æ³•ä¼ é€’ç»„å·æ¥æ£€"
+"索。默认是组 0,并且将总是指整个模å¼ã€‚在上é¢çš„例å­ä¸­ï¼Œè°ƒç”¨ [code]result."
+"get_string(1)[/code] 会得到 [code]0123[/code]。\n"
+"这个版本的 RegEx 也支æŒå‘½åçš„æ•获组,åç§°å¯ä»¥ç”¨æ¥æ£€ç´¢ç»“果。如果两个或更多的组"
+"有相åŒçš„å称,那么这个åç§°å°†åªæŒ‡ç¬¬ä¸€ä¸ªæœ‰åŒ¹é…的组。\n"
"[codeblock]\n"
"var regex = RegEx.new()\n"
"regex.compile(\"d(?<digit>[0-9]+)|x(?<digit>[0-9a-f]+)\")\n"
-"var result = regex.search(\"the number is x2f\")\n"
+"var result = regex.search(\"数字是 x2f\")\n"
"if result:\n"
-" print(result.get_string(\"digit\")) # Would print 2f\n"
+" print(result.get_string(\"digit\")) # 会输出 2f\n"
"[/codeblock]\n"
-"如果你需è¦å¤„ç†å¤šä¸ªç»“果,[method search_all]会生æˆä¸€ä¸ªæ‰€æœ‰ä¸é‡å çš„结果列表。为"
-"了方便起è§ï¼Œè¿™å¯ä»¥å’Œä¸€ä¸ª[code]for[/code]循环结åˆèµ·æ¥ã€‚\n"
+"如果你需è¦å¤„ç†å¤šä¸ªç»“果,[method search_all] 会生æˆä¸€ä¸ªæ‰€æœ‰ä¸é‡å çš„结果列表。"
+"为了方便起è§ï¼Œè¿™å¯ä»¥å’Œä¸€ä¸ª [code]for[/code] 循环结åˆèµ·æ¥ã€‚\n"
"[codeblock]\n"
"for result in regex.search_all(\"d01, d03, d0c, x3f and x42\"):\n"
" print(result.get_string(\"digit\"))\n"
-"# Would print 01 03 0 3f 42\n"
+"# 会输出 01 03 0 3f 42\n"
"[/codeblock]\n"
-"[b]使用RegEx分割字符串的例å­ï¼š[/b]\n"
+"[b]使用 RegEx 分割字符串的例å­ï¼š[/b]\n"
"[codeblock]\n"
"var regex = RegEx.new()\n"
-"regex.compile(\"\\\\S+\") # Negated whitespace character class.\n"
+"regex.compile(\"\\\\S+\") # éžç©ºç™½å­—符类。\n"
"var results = []\n"
"for result in regex.search_all(\"One Two \\n\\tThree\"):\n"
" results.push_back(result.get_string())\n"
-"# The `results` array now contains \"One\", \"Two\", \"Three\".\n"
+"# `results` æ•°ç»„åŒ…å« \"One\"ã€\"Two\"ã€\"Three\"。\n"
"[/codeblock]\n"
-"[b]注æ„:[/b]Godotçš„regex实现是基于[url=https://www.pcre.org/]PCRE2[/url] "
-"库。你å¯ä»¥æŸ¥çœ‹å®Œæ•´çš„æ¨¡å¼å‚考[url=https://www.pcre.org/current/doc/html/"
+"[b]注æ„:[/b]Godot çš„ regex 实现基于的是 [url=https://www.pcre.org/]PCRE2[/"
+"url]。你å¯ä»¥æŸ¥çœ‹å®Œæ•´çš„æ¨¡å¼å‚考[url=https://www.pcre.org/current/doc/html/"
"pcre2pattern.html]这里[/url]。\n"
-"[b]æç¤ºï¼š[/b] ä½ å¯ä»¥ä½¿ç”¨[url=https://regexr.com/]Regexr[/url]æ¥åœ¨çº¿æµ‹è¯•正则表"
-"è¾¾å¼ã€‚"
+"[b]æç¤ºï¼š[/b] ä½ å¯ä»¥ä½¿ç”¨ [url=https://regexr.com/]Regexr[/url] æ¥åœ¨çº¿æµ‹è¯•正则"
+"表达å¼ã€‚"
#: modules/regex/doc_classes/RegEx.xml
msgid ""
@@ -64434,8 +64867,8 @@ msgid ""
"compilation is successful. If an error is encountered, details are printed "
"to standard output and an error is returned."
msgstr ""
-"编译并指定è¦ä½¿ç”¨çš„æœç´¢æ¨¡å¼ã€‚如果编译æˆåŠŸï¼Œè¿”å›ž[constant OK]。如果é‡åˆ°é”™è¯¯ï¼Œç»†"
-"节将被打å°åˆ°æ ‡å‡†è¾“出,并返回一个错误。"
+"编译并指定è¦ä½¿ç”¨çš„æœç´¢æ¨¡å¼ã€‚如果编译æˆåŠŸï¼Œè¿”å›ž [constant OK]。如果é‡åˆ°é”™è¯¯ï¼Œ"
+"细节将被打å°åˆ°æ ‡å‡†è¾“出,并返回一个错误。"
#: modules/regex/doc_classes/RegEx.xml
msgid "Returns the number of capturing groups in compiled pattern."
@@ -64463,9 +64896,9 @@ msgid ""
"region to search within can be specified without modifying where the start "
"and end anchor would be."
msgstr ""
-"在文本中æœç´¢ç¼–译åŽçš„æ¨¡å¼ã€‚如果找到,返回第一个匹é…结果的[RegExMatch]容器,å¦"
-"则返回 [code]null[/code]。å¯ä»¥æŒ‡å®šè¦æœç´¢çš„区域,而ä¸éœ€è¦ä¿®æ”¹å¼€å§‹å’Œç»“æŸé”šç‚¹çš„"
-"ä½ç½®ã€‚"
+"在文本中æœç´¢ç¼–译åŽçš„æ¨¡å¼ã€‚如果找到,返回第一个匹é…结果的 [RegExMatch] 容器,"
+"å¦åˆ™è¿”回 [code]null[/code]。å¯ä»¥æŒ‡å®šè¦æœç´¢çš„区域,而ä¸éœ€è¦ä¿®æ”¹å¼€å§‹å’Œç»“æŸé”šç‚¹"
+"çš„ä½ç½®ã€‚"
#: modules/regex/doc_classes/RegEx.xml
msgid ""
@@ -64474,9 +64907,9 @@ msgid ""
"empty array is returned instead. The region to search within can be "
"specified without modifying where the start and end anchor would be."
msgstr ""
-"在文本中æœç´¢ç¼–译过的模å¼ã€‚为æ¯ä¸ªä¸é‡å çš„结果返回一个[RegExMatch]容器数组。如"
-"果没有å‘现任何结果,则返回一个空数组。å¯ä»¥æŒ‡å®šè¦æœç´¢çš„区域,而ä¸éœ€è¦ä¿®æ”¹å¼€å§‹"
-"和结æŸé”šç‚¹çš„ä½ç½®ã€‚"
+"在文本中æœç´¢ç¼–译过的模å¼ã€‚为æ¯ä¸ªä¸é‡å çš„结果返回一个 [RegExMatch] 容器数组。"
+"如果没有å‘现任何结果,则返回一个空数组。å¯ä»¥æŒ‡å®šè¦æœç´¢çš„区域,而ä¸éœ€è¦ä¿®æ”¹å¼€"
+"始和结æŸé”šç‚¹çš„ä½ç½®ã€‚"
#: modules/regex/doc_classes/RegEx.xml
msgid ""
@@ -64487,14 +64920,14 @@ msgid ""
"replacement). The region to search within can be specified without modifying "
"where the start and end anchor would be."
msgstr ""
-"æœç´¢æ–‡æœ¬ä¸­çš„编译模å¼ï¼Œå¹¶å°†å…¶æ›¿æ¢ä¸ºæŒ‡å®šçš„字符串。诸如[code]$1[/code]å’Œ"
-"[code]$name[/code]等转义和åå‘å¼•ç”¨ä¼šè¢«å±•å¼€å’Œè§£å†³ã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œåªæœ‰ç¬¬ä¸€ä¸ªå®žä¾‹"
+"æœç´¢æ–‡æœ¬ä¸­çš„编译模å¼ï¼Œå¹¶å°†å…¶æ›¿æ¢ä¸ºæŒ‡å®šçš„字符串。诸如 [code]$1[/code] å’Œ "
+"[code]$name[/code] 等转义和åå‘å¼•ç”¨ä¼šè¢«å±•å¼€å’Œè§£å†³ã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œåªæœ‰ç¬¬ä¸€ä¸ªå®žä¾‹"
"被替æ¢ï¼Œä½†å¯ä»¥å¯¹æ‰€æœ‰å®žä¾‹è¿›è¡Œä¿®æ”¹ï¼ˆå…¨å±€æ›¿æ¢ï¼‰ã€‚å¯ä»¥æŒ‡å®šè¦æœç´¢çš„区域,而ä¸éœ€è¦"
"修改开始和结æŸé”šçš„ä½ç½®ã€‚"
#: modules/regex/doc_classes/RegExMatch.xml
msgid "Contains the results of a [RegEx] search."
-msgstr "包å«[RegEx]æœç´¢çš„结果。"
+msgstr "åŒ…å« [RegEx] æœç´¢çš„结果。"
#: modules/regex/doc_classes/RegExMatch.xml
msgid ""
@@ -64503,8 +64936,9 @@ msgid ""
"and range of the match and its capturing groups, and it can extract its "
"substring for you."
msgstr ""
-"包å«ç”±[method RegEx.search]å’Œ[method RegEx.search_all]返回的å•个[RegEx]匹é…结"
-"果。它å¯ä»¥ç”¨æ¥æŸ¥æ‰¾åŒ¹é…çš„ä½ç½®å’ŒèŒƒå›´ä»¥åŠå®ƒçš„æ•èŽ·ç»„ï¼Œå¹¶ä¸”å¯ä»¥æå–å…¶å­å­—符串。"
+"包å«ç”± [method RegEx.search] å’Œ [method RegEx.search_all] 返回的å•个 [RegEx] "
+"匹é…结果。它å¯ä»¥ç”¨æ¥æŸ¥æ‰¾åŒ¹é…çš„ä½ç½®å’ŒèŒƒå›´ä»¥åŠå®ƒçš„æ•èŽ·ç»„ï¼Œå¹¶ä¸”å¯ä»¥æå–å…¶å­å­—符"
+"串。"
#: modules/regex/doc_classes/RegExMatch.xml
msgid ""
@@ -64515,8 +64949,8 @@ msgid ""
"Returns -1 if the group did not match or doesn't exist."
msgstr ""
"返回æºå­—符串中匹é…的结æŸä½ç½®ã€‚æ•获组的结æŸä½ç½®å¯ä»¥é€šè¿‡æä¾›å…¶ç»„å·çš„æ•´æ•°æˆ–å…¶å­—"
-"符串å称(如果它是一个命åç»„ï¼‰æ¥æ£€ç´¢ã€‚默认值为0,指的是整个表达å¼ã€‚\n"
-"å¦‚æžœè¯¥ç»„æ²¡æœ‰åŒ¹é…æˆ–ä¸å­˜åœ¨ï¼Œåˆ™è¿”回-1。"
+"符串å称(如果它是一个命åç»„ï¼‰æ¥æ£€ç´¢ã€‚默认值为 0,指的是整个表达å¼ã€‚\n"
+"å¦‚æžœè¯¥ç»„æ²¡æœ‰åŒ¹é…æˆ–ä¸å­˜åœ¨ï¼Œåˆ™è¿”回 -1。"
#: modules/regex/doc_classes/RegExMatch.xml
msgid "Returns the number of capturing groups."
@@ -64553,8 +64987,8 @@ msgid ""
"that were matched are included. If multiple groups have the same name, that "
"name would refer to the first matching one."
msgstr ""
-"一个命å组的字典和它相应的组å·ã€‚åªæœ‰è¢«åŒ¹é…的组æ‰è¢«åŒ…括在内。如果多个组有相åŒ"
-"çš„å称,该å称将指第一个匹é…的组。"
+"命å组的字典和它相应的组å·ã€‚åªæœ‰è¢«åŒ¹é…的组æ‰è¢«åŒ…括在内。如果多个组有相åŒçš„å"
+"称,该å称将指第一个匹é…的组。"
#: modules/regex/doc_classes/RegExMatch.xml
msgid "An [Array] of the match and its capturing groups."
@@ -64570,7 +65004,7 @@ msgid ""
"RemoteTransform pushes its own [Transform] to another [Spatial] derived Node "
"in the scene."
msgstr ""
-"RemoteTransform将自己的[Transform]推é€åˆ°åœºæ™¯ä¸­å¦ä¸€ä¸ª[Spatial]派生节点。"
+"RemoteTransform 将自己的 [Transform] 推é€åˆ°åœºæ™¯ä¸­å¦ä¸€ä¸ª [Spatial] 派生节点。"
#: doc/classes/RemoteTransform.xml
msgid ""
@@ -64579,8 +65013,8 @@ msgid ""
"It can be set to update another Node's position, rotation and/or scale. It "
"can use either global or local coordinates."
msgstr ""
-"RemoteTransform将自己的[Transform]推é€åˆ°åœºæ™¯ä¸­å¦ä¸€ä¸ª[Spatial]派生节点(称为远"
-"程节点)。\n"
+"RemoteTransform 将自己的 [Transform] 推é€åˆ°åœºæ™¯ä¸­å¦ä¸€ä¸ª [Spatial] 派生节点"
+"(称为远程节点)。\n"
"它å¯ä»¥è¢«è®¾ç½®ä¸ºæ›´æ–°å¦ä¸€ä¸ªèŠ‚ç‚¹çš„ä½ç½®ã€æ—‹è½¬å’Œ/或比例。它å¯ä»¥ä½¿ç”¨å…¨å±€å标或局部å"
"标。"
@@ -64601,31 +65035,31 @@ msgstr "远程节点的节点ä½ç½® [NodePath],相对于 RemoteTransform 在åœ
#: doc/classes/RemoteTransform.xml doc/classes/RemoteTransform2D.xml
msgid "If [code]true[/code], the remote node's position is updated."
-msgstr "如果 [code]true[/code],则更新远程节点的ä½ç½®ã€‚"
+msgstr "如果为 [code]true[/code],则更新远程节点的ä½ç½®ã€‚"
#: doc/classes/RemoteTransform.xml doc/classes/RemoteTransform2D.xml
msgid "If [code]true[/code], the remote node's rotation is updated."
-msgstr "如果 [code]true[/code],则更新远程节点的旋转。"
+msgstr "如果为 [code]true[/code],则更新远程节点的旋转。"
#: doc/classes/RemoteTransform.xml doc/classes/RemoteTransform2D.xml
msgid "If [code]true[/code], the remote node's scale is updated."
-msgstr "如果 [code]true[/code],则更新远程节点的比例。"
+msgstr "如果为 [code]true[/code],则更新远程节点的比例。"
#: doc/classes/RemoteTransform.xml doc/classes/RemoteTransform2D.xml
msgid ""
"If [code]true[/code], global coordinates are used. If [code]false[/code], "
"local coordinates are used."
msgstr ""
-"如果 [code]true[/code]ï¼Œåˆ™ä½¿ç”¨å…¨å±€åæ ‡ã€‚如果 [code]false[/code],则使用本地å"
-"标。"
+"如果为 [code]true[/code]ï¼Œåˆ™ä½¿ç”¨å…¨å±€åæ ‡ã€‚如果 [code]false[/code],则使用本地"
+"åæ ‡ã€‚"
#: doc/classes/RemoteTransform2D.xml
msgid ""
"RemoteTransform2D pushes its own [Transform2D] to another [CanvasItem] "
"derived Node in the scene."
msgstr ""
-"RemoteTransform2D将自己的[Transform2D]推é€åˆ°åœºæ™¯ä¸­å¦ä¸€ä¸ª[CanvasItem]派生节"
-"点。"
+"RemoteTransform2D 将自己的 [Transform2D] 推é€åˆ°åœºæ™¯ä¸­å¦ä¸€ä¸ª [CanvasItem] 派生"
+"节点。"
#: doc/classes/RemoteTransform2D.xml
msgid ""
@@ -64673,12 +65107,12 @@ msgid ""
"free resources that are no longer in use. This means that unused resources "
"will linger on for a while before being removed."
msgstr ""
-"èµ„æºæ˜¯æ‰€æœ‰Godot特定资æºç±»åž‹çš„基类,主è¦ä½œä¸ºæ•°æ®å®¹å™¨ã€‚由于它们继承自"
+"èµ„æºæ˜¯æ‰€æœ‰ Godot 特定资æºç±»åž‹çš„基类,主è¦ä½œä¸ºæ•°æ®å®¹å™¨ã€‚由于它们继承自 "
"[Reference],资æºè¢«å¼•用计数,并在ä¸å†ä½¿ç”¨æ—¶è¢«é‡Šæ”¾ã€‚一旦从ç£ç›˜åŠ è½½ï¼Œå®ƒä»¬ä¹Ÿä¼šè¢«"
-"缓存,因此任何从给定路径加载资æºçš„å°è¯•都会返回相åŒçš„引用(这与[Node]相å,"
-"[Node]没有引用计数,å¯ä»¥æ ¹æ®éœ€è¦ä»Žç£ç›˜å®žä¾‹åŒ–多次)。资æºå¯ä»¥ä»Žå¤–部ä¿å­˜åœ¨ç£ç›˜"
+"缓存,因此任何从给定路径加载资æºçš„å°è¯•都会返回相åŒçš„引用(这与 [Node] 相å,"
+"[Node] 没有引用计数,å¯ä»¥æ ¹æ®éœ€è¦ä»Žç£ç›˜å®žä¾‹åŒ–多次)。资æºå¯ä»¥ä»Žå¤–部ä¿å­˜åœ¨ç£ç›˜"
"上,也å¯ä»¥æ†ç»‘在å¦ä¸€ä¸ªå¯¹è±¡ä¸­ï¼Œå¦‚[Node]或å¦ä¸€ä¸ªèµ„æºã€‚\n"
-"[b]注æ„:[/b]在C#中,资æºä¸å†è¢«ä½¿ç”¨åŽä¸ä¼šç«‹å³è¢«é‡Šæ”¾ã€‚相å,垃圾回收将定期è¿"
+"[b]注æ„:[/b]在 C# 中,资æºä¸å†è¢«ä½¿ç”¨åŽä¸ä¼šç«‹å³è¢«é‡Šæ”¾ã€‚相å,垃圾回收将定期è¿"
"行,并释放ä¸å†ä½¿ç”¨çš„资æºã€‚è¿™æ„å‘³ç€æœªä½¿ç”¨çš„资æºåœ¨è¢«åˆ é™¤ä¹‹å‰ä¼šåœç•™ä¸€æ®µæ—¶é—´ã€‚"
#: doc/classes/Resource.xml
@@ -64728,7 +65162,7 @@ msgid ""
"[/codeblock]\n"
"[b]Note:[/b] This method is called automatically for built-in resources."
msgstr ""
-"å‘出[signal changed]更改信å·ã€‚\n"
+"å‘出 [signal changed] 更改信å·ã€‚\n"
"如果ä¾èµ–该资æºçš„外部对象应该被更新,那么æ¯å½“该资æºçš„状æ€å‘生å˜åŒ–(如属性的修"
"改)时,必须手动调用该方法。\n"
"该方法等åŒäºŽã€‚\n"
@@ -64844,17 +65278,17 @@ msgid ""
"as [code].stex[/code] ([StreamTexture]) first, so they can be loaded with "
"better efficiency on the graphics card."
msgstr ""
-"Godot使用ResourceFormatLoaders在编辑器或导出的游æˆä¸­åŠ è½½èµ„æºã€‚它们通过"
-"[ResourceLoader]å•例自动查询,或者在加载具有内部ä¾èµ–æ€§çš„èµ„æºæ—¶è¢«æŸ¥è¯¢ã€‚æ¯ä¸ªæ–‡"
-"件类型å¯ä»¥ä½œä¸ºä¸åŒçš„资æºç±»åž‹åŠ è½½ï¼Œå› æ­¤åœ¨å¼•æ“Žä¸­æ³¨å†Œäº†å¤šä¸ª"
-"ResourceFormatLoaders。\n"
+"Godot 使用 ResourceFormatLoader 在编辑器或导出的游æˆä¸­åŠ è½½èµ„æºã€‚它们通过 "
+"[ResourceLoader] å•例自动查询,或者在加载具有内部ä¾èµ–æ€§çš„èµ„æºæ—¶è¢«æŸ¥è¯¢ã€‚æ¯ä¸ªæ–‡"
+"件类型å¯ä»¥ä½œä¸ºä¸åŒçš„资æºç±»åž‹åŠ è½½ï¼Œå› æ­¤åœ¨å¼•æ“Žä¸­æ³¨å†Œäº†å¤šä¸ª "
+"ResourceFormatLoader。\n"
"扩展这个类å…许你定义你自己的加载器。请确ä¿å°Šé‡æ–‡æ¡£ä¸­çš„返回类型和值。你应该给"
-"它一个带有[code]class_name[/code]的全局类å,这样它æ‰èƒ½è¢«æ³¨å†Œã€‚åƒå†…置的"
-"ResourceFormatLoaders一样,它将在加载其处ç†çš„ç±»åž‹çš„èµ„æºæ—¶è¢«è‡ªåŠ¨è°ƒç”¨ã€‚ä½ ä¹Ÿå¯ä»¥"
-"实现一个[ResourceFormatSaver]。\n"
-"[b]注æ„:[/b]如果你需è¦çš„资æºç±»åž‹å­˜åœ¨ï¼Œä½†Godot无法加载其格å¼ï¼Œä½ ä¹Ÿå¯ä»¥æ‰©å±•"
+"它一个带有 [code]class_name[/code] 的全局类å,这样它æ‰èƒ½è¢«æ³¨å†Œã€‚åƒå†…置的 "
+"ResourceFormatLoader 一样,它将在加载其处ç†çš„ç±»åž‹çš„èµ„æºæ—¶è¢«è‡ªåŠ¨è°ƒç”¨ã€‚ä½ ä¹Ÿå¯ä»¥"
+"实现一个 [ResourceFormatSaver]。\n"
+"[b]注æ„:[/b]如果你需è¦çš„资æºç±»åž‹å­˜åœ¨ï¼Œä½†Godot无法加载其格å¼ï¼Œä½ ä¹Ÿå¯ä»¥æ‰©å±• "
"[EditorImportPlugin]ã€‚é€‰æ‹©ä¸€ç§æ–¹å¼è€Œä¸æ˜¯å¦ä¸€ç§æ–¹å¼ï¼Œå–å†³äºŽè¯¥æ ¼å¼æ˜¯å¦é€‚åˆäºŽæœ€"
-"终导出的游æˆã€‚例如,最好先把[code].png[/code]纹ç†å¯¼å…¥ä¸º[code].stex[/code]"
+"终导出的游æˆã€‚例如,最好先把 [code].png[/code] 纹ç†å¯¼å…¥ä¸º [code].stex[/code]"
"([StreamTexture]),这样它们在显å¡ä¸Šçš„加载效率会更好。"
#: doc/classes/ResourceFormatLoader.xml
@@ -64906,8 +65340,8 @@ msgid ""
"Error] constant in case of failure."
msgstr ""
"当引擎å‘现这个加载器是兼容的,就会加载一个资æºã€‚å¦‚æžœåŠ è½½çš„èµ„æºæ˜¯å¯¼å…¥çš„结果,"
-"[code]original_path[/code]å°†é’ˆå¯¹æºæ–‡ä»¶ã€‚æˆåŠŸæ—¶è¿”å›žä¸€ä¸ª[Resource]对象,失败时"
-"返回一个[enum Error]常é‡ã€‚"
+"[code]original_path[/code] å°†é’ˆå¯¹æºæ–‡ä»¶ã€‚æˆåŠŸæ—¶è¿”å›žä¸€ä¸ª [Resource] 对象,失败"
+"时返回一个 [enum Error] 常é‡ã€‚"
#: doc/classes/ResourceFormatLoader.xml
msgid ""
@@ -64917,8 +65351,8 @@ msgid ""
"Returns [constant OK] on success, or an [enum Error] constant in case of "
"failure."
msgstr ""
-"如果实现,é‡å‘½å给定资æºä¸­çš„ä¾èµ–项并ä¿å­˜å®ƒã€‚ [code]renames[/code] 是一个将旧"
-"çš„ä¾èµ–路径映射到新的路径的 [code]{ String => String }[/code]的字典 。\n"
+"如果实现,é‡å‘½å给定资æºä¸­çš„ä¾èµ–项并ä¿å­˜å®ƒã€‚[code]renames[/code] 是一个将旧的"
+"ä¾èµ–路径映射到新的路径的 [code]{ String => String }[/code]的字典 。\n"
"æˆåŠŸæ—¶è¿”å›ž [constant OK],失败时返回 [enum Error] 常é‡ã€‚"
#: doc/classes/ResourceFormatSaver.xml
@@ -64944,8 +65378,8 @@ msgstr ""
"默认情况下,Godot 将资æºä¿å­˜ä¸º [code].tres[/code](基于文本)ã€[code].res[/"
"code](二进制)或其他内置格å¼ï¼Œä½†æ‚¨å¯ä»¥é€‰æ‹©é€šè¿‡æ‰©å±•这个类æ¥åˆ›å»ºè‡ªå·±çš„æ ¼å¼ã€‚请"
"务必éµå®ˆè®°å½•的返回类型和值。你应该给它一个全局类å [code]class_name[/code] 以"
-"便它被注册。与内置的 ResourceFormatSavers 一样,它会在ä¿å­˜å…¶è¯†åˆ«ç±»åž‹çš„èµ„æºæ—¶"
-"自动调用。你也å¯ä»¥å®žçŽ°ä¸€ä¸ª [ResourceFormatLoader]。"
+"便它被注册。与内置的 ResourceFormatSaver 一样,它会在ä¿å­˜å…¶è¯†åˆ«ç±»åž‹çš„èµ„æºæ—¶è‡ª"
+"动调用。你也å¯ä»¥å®žçŽ°ä¸€ä¸ª [ResourceFormatLoader]。"
#: doc/classes/ResourceFormatSaver.xml
msgid ""
@@ -64966,9 +65400,9 @@ msgid ""
"Returns [constant OK] on success, or an [enum Error] constant in case of "
"failure."
msgstr ""
-"将给定的资æºå¯¹è±¡ä¿å­˜åˆ°ç›®æ ‡[code]path[/code]处的文件。[code]flags[/code]是一个"
-"ç”±[enum ResourceSaver.SaverFlags]常é‡ç»„æˆçš„使ީç ã€‚\n"
-"æˆåŠŸæ—¶è¿”å›ž[constant OK],失败时返回[enum Error]常é‡ã€‚"
+"将给定的资æºå¯¹è±¡ä¿å­˜åˆ°ç›®æ ‡ [code]path[/code] 处的文件。[code]flags[/code] 是"
+"一个由 [enum ResourceSaver.SaverFlags] 常é‡ç»„æˆçš„使ީç ã€‚\n"
+"æˆåŠŸæ—¶è¿”å›ž [constant OK],失败时返回 [enum Error] 常é‡ã€‚"
#: doc/classes/ResourceImporter.xml
msgid "Base class for the implementation of core resource importers."
@@ -65013,21 +65447,20 @@ msgid ""
"granularity, which makes it mainly useful for displaying loading bars or "
"percentages."
msgstr ""
-"交互å¼èµ„æº[Resource]加载器。这个对象在执行交互å¼åŠ è½½æ—¶ç”±[ResourceLoader]è¿”"
-"回。它å…许以高粒度(high granularity)加载资æºï¼Œè¿™ä½¿å¾—它主è¦ç”¨äºŽæ˜¾ç¤ºåŠ è½½æ¡æˆ–"
-"百分比。"
+"äº¤äº’å¼ [Resource] 加载器。这个对象在执行交互å¼åŠ è½½æ—¶ç”± [ResourceLoader] è¿”"
+"回。它å…许以高粒度加载资æºï¼Œè¿™ä½¿å¾—它主è¦ç”¨äºŽæ˜¾ç¤ºåŠ è½½æ¡æˆ–百分比。"
#: doc/classes/ResourceInteractiveLoader.xml
msgid ""
"Returns the loaded resource if the load operation completed successfully, "
"[code]null[/code] otherwise."
-msgstr "如果加载æ“作æˆåŠŸå®Œæˆï¼Œè¿”回加载的资æºï¼Œå¦åˆ™ä¸ºç©º[code]null[/code]。"
+msgstr "如果加载æ“作æˆåŠŸå®Œæˆï¼Œè¿”回加载的资æºï¼Œå¦åˆ™ä¸º [code]null[/code]。"
#: doc/classes/ResourceInteractiveLoader.xml
msgid ""
"Returns the load stage. The total amount of stages can be queried with "
"[method get_stage_count]."
-msgstr "返回加载阶段。å¯ä»¥ä½¿ç”¨[method get_stage_count]查询阶段总数。"
+msgstr "返回加载阶段。å¯ä»¥ä½¿ç”¨ [method get_stage_count] 查询阶段总数。"
#: doc/classes/ResourceInteractiveLoader.xml
msgid ""
@@ -65090,14 +65523,14 @@ msgid ""
"An optional [code]type_hint[/code] can be used to further specify the "
"[Resource] type that should be handled by the [ResourceFormatLoader]."
msgstr ""
-"返回给定的[code]path[/code]是å¦å­˜åœ¨å·²è¯†åˆ«çš„资æºã€‚\n"
-"一个å¯é€‰çš„[code]type_hint[/code]å¯ä»¥ç”¨æ¥è¿›ä¸€æ­¥æŒ‡å®š[ResourceFormatLoader]应该"
-"处ç†çš„[Resource]类型。"
+"返回给定的路径 [code]path[/code] 处是å¦å­˜åœ¨å·²è¯†åˆ«çš„资æºã€‚\n"
+"一个å¯é€‰çš„ [code]type_hint[/code] å¯ä»¥ç”¨æ¥è¿›ä¸€æ­¥æŒ‡å®š [ResourceFormatLoader] "
+"应该处ç†çš„ [Resource] 类型。"
#: doc/classes/ResourceLoader.xml
msgid ""
"Returns the dependencies for the resource at the given [code]path[/code]."
-msgstr "返回给定[code]path[/code]处资æºçš„ä¾èµ–关系。"
+msgstr "返回给定路径 [code]path[/code] 处资æºçš„ä¾èµ–关系。"
#: doc/classes/ResourceLoader.xml
msgid "Returns the list of recognized extensions for a resource type."
@@ -65106,7 +65539,8 @@ msgstr "返回资æºç±»åž‹çš„已识别扩展å列表。"
#: doc/classes/ResourceLoader.xml
msgid ""
"[i]Deprecated method.[/i] Use [method has_cached] or [method exists] instead."
-msgstr "[i]废弃的方法。[/i]使用[method has_cached]或[method exists]代替。"
+msgstr ""
+"[i]废弃的方法。[/i]请使用 [method has_cached] 或 [method exists] 代替。"
#: doc/classes/ResourceLoader.xml
msgid ""
@@ -65290,7 +65724,7 @@ msgstr "ä¸è¦ä¿å­˜ç¼–辑器特定的元数æ®ï¼ˆç”±å…¶ [code]__editor[/code] å
#: doc/classes/ResourceSaver.xml
msgid "Save as big endian (see [member File.endian_swap])."
-msgstr "ä¿å­˜ä¸ºå¤§ç«¯ï¼ˆå‚阅 [member File.endian_swap])。"
+msgstr "ä¿å­˜ä¸ºå¤§ç«¯ï¼ˆè§ [member File.endian_swap])。"
#: doc/classes/ResourceSaver.xml
msgid ""
@@ -65304,7 +65738,7 @@ msgstr ""
msgid ""
"Take over the paths of the saved subresources (see [method Resource."
"take_over_path])."
-msgstr "接管ä¿å­˜çš„å­èµ„æºçš„路径(è§[method Resource.take_over_path])。"
+msgstr "接管ä¿å­˜çš„å­èµ„æºçš„è·¯å¾„ï¼ˆè§ [method Resource.take_over_path])。"
#: doc/classes/RichTextEffect.xml
msgid "A custom effect for use with [RichTextLabel]."
@@ -65468,7 +65902,7 @@ msgid ""
"Installs a custom effect. [code]effect[/code] should be a valid "
"[RichTextEffect]."
msgstr ""
-"安装自定义效果。 [code]effect[/code] 应该是一个有效的 [RichTextEffect]。"
+"安装自定义效果。[code]effect[/code] 应该是一个有效的 [RichTextEffect]。"
#: doc/classes/RichTextLabel.xml
msgid "Adds a newline tag to the tag stack."
@@ -65502,8 +65936,8 @@ msgid ""
"Adds an [code][align][/code] tag based on the given [code]align[/code] "
"value. See [enum Align] for possible values."
msgstr ""
-"æ ¹æ®ç»™å®šçš„[code][align][/code]值,添加一个[code]align[/code]标签。å¯èƒ½çš„值è§"
-"[enum Align]。"
+"æ ¹æ®ç»™å®šçš„ [code][align][/code] 值,添加一个 [code]align[/code] 标签。å¯èƒ½çš„"
+"å–å€¼è§ [enum Align]。"
#: doc/classes/RichTextLabel.xml
msgid ""
@@ -65629,7 +66063,7 @@ msgid ""
"add_text] will reset this to [code]false[/code]. Use instead [method "
"append_bbcode] to preserve BBCode formatting."
msgstr ""
-"如果 [code]true[/code],标签使用 BBCode æ ¼å¼ã€‚\n"
+"如果为 [code]true[/code],标签使用 BBCode æ ¼å¼ã€‚\n"
"[b]注æ„:[/b]å°è¯•使用 [method add_text] 更改 [RichTextLabel] 的文本会将其é‡ç½®"
"为 [code]false[/code]。改用 [method append_bbcode] æ¥ä¿ç•™ BBCode æ ¼å¼ã€‚"
@@ -65670,7 +66104,7 @@ msgid ""
"[RichTextLabel] in [Container]s, but it's unreliable in some cases and will "
"be removed in future versions."
msgstr ""
-"如果 [code]true[/code],标签的高度将自动更新以适应其内容。\n"
+"如果为 [code]true[/code],标签的高度将自动更新以适应其内容。\n"
"[b]注æ„:[/b]此属性用作解决 [Container] 中 [RichTextLabel] 问题的解决方法,但"
"在æŸäº›æƒ…况下ä¸å¯é ï¼Œå°†åœ¨æœªæ¥ç‰ˆæœ¬ä¸­åˆ é™¤ã€‚"
@@ -65679,12 +66113,12 @@ msgid ""
"If [code]true[/code], the label underlines meta tags such as [code][url]"
"{text}[/url][/code]."
msgstr ""
-"如果 [code]true[/code],则会在元标签下划线,例如 [code][url]{text}[/url][/"
+"如果为 [code]true[/code],则会在元标签下划线,例如 [code][url]{text}[/url][/"
"code]。"
#: doc/classes/RichTextLabel.xml
msgid "If [code]true[/code], the label uses the custom font color."
-msgstr "如果 [code]true[/code],则标签使用自定义字体颜色。"
+msgstr "如果为 [code]true[/code],则标签使用自定义字体颜色。"
#: doc/classes/RichTextLabel.xml
msgid ""
@@ -65703,18 +66137,18 @@ msgid ""
"If [code]true[/code], the scrollbar is visible. Setting this to [code]false[/"
"code] does not block scrolling completely. See [method scroll_to_line]."
msgstr ""
-"如果 [code]true[/code],则滚动æ¡å¯è§ã€‚将此设置为 [code]false[/code] ä¸ä¼šå®Œå…¨"
-"阻止滚动。è§[method scroll_to_line]。"
+"如果为 [code]true[/code],则滚动æ¡å¯è§ã€‚将此设置为 [code]false[/code] ä¸ä¼šå®Œ"
+"全阻止滚动。è§[method scroll_to_line]。"
#: doc/classes/RichTextLabel.xml
msgid ""
"If [code]true[/code], the window scrolls down to display new content "
"automatically."
-msgstr "如果 [code]true[/code],则窗å£å‘下滚动以自动显示新内容。"
+msgstr "如果为 [code]true[/code],则窗å£å‘下滚动以自动显示新内容。"
#: doc/classes/RichTextLabel.xml
msgid "If [code]true[/code], the label allows text selection."
-msgstr "如果 [code]true[/code],标签å…许文本选择。"
+msgstr "如果为 [code]true[/code],标签å…许文本选择。"
#: doc/classes/RichTextLabel.xml
msgid ""
@@ -65818,7 +66252,7 @@ msgid ""
"The color of selected text, used when [member selection_enabled] is "
"[code]true[/code]."
msgstr ""
-"选定文本的颜色(当[member selection_enabled]为 [code]true[/code] 时使用)。"
+"选定文本的颜色(当 [member selection_enabled] 为 [code]true[/code] 时使用)。"
#: doc/classes/RichTextLabel.xml
msgid "The color of the font's shadow."
@@ -65894,16 +66328,16 @@ msgid ""
"themselves. They are used by and with the low-level Server classes such as "
"[VisualServer]."
msgstr ""
-"RID类型用于访问资æºçš„唯一整数ID。它们ä¸é€æ˜Žï¼Œè¿™æ„味ç€å…¶æœ¬èº«å¹¶ä¸æŽˆäºˆå¯¹ç›¸å…³èµ„æº"
-"的访问。它们被低级别的æœåŠ¡ç±»ä½¿ç”¨ï¼Œå¦‚[VisualServer]。"
+"RID 类型用于访问资æºçš„唯一整数 ID。它们ä¸é€æ˜Žï¼Œè¿™æ„味ç€å…¶æœ¬èº«å¹¶ä¸æŽˆäºˆå¯¹ç›¸å…³èµ„"
+"æºçš„访问。它们被低级别的æœåŠ¡ç±»ä½¿ç”¨ï¼Œå¦‚ [VisualServer]。"
#: doc/classes/RID.xml
msgid ""
"Creates a new RID instance with the ID of a given resource. When not handed "
"a valid resource, silently stores the unused ID 0."
msgstr ""
-"用给定资æºçš„ID创建一个新的RIDå®žä¾‹ã€‚å½“æ²¡æœ‰å¾—åˆ°ä¸€ä¸ªæœ‰æ•ˆçš„èµ„æºæ—¶ï¼Œé»˜è®¤å­˜å‚¨æœªä½¿ç”¨"
-"的ID 0。"
+"用给定资æºçš„ ID 创建一个新的 RID å®žä¾‹ã€‚å½“æ²¡æœ‰å¾—åˆ°ä¸€ä¸ªæœ‰æ•ˆçš„èµ„æºæ—¶ï¼Œé»˜è®¤å­˜å‚¨æœª"
+"使用的 ID 0。"
#: doc/classes/RID.xml
msgid "Returns the ID of the referenced resource."
@@ -65956,8 +66390,8 @@ msgid ""
"for a body."
msgstr ""
"在物ç†å¤„ç†è¿‡ç¨‹ä¸­è¢«è°ƒç”¨ï¼Œå…许你读å–并安全地修改对象的模拟状æ€ã€‚默认情况下,它"
-"是在通常的物ç†è¡Œä¸ºä¹‹å¤–工作的,但是[member custom_integrator]属性å…许你ç¦ç”¨é»˜"
-"认行为,为一个物体施加完全自定义的åˆåŠ›ã€‚"
+"会和通常的物ç†è¡Œä¸ºä¸€èµ·ç”Ÿæ•ˆï¼Œä½†æ˜¯ä½ å¯ä»¥é€šè¿‡ [member custom_integrator] 属性ç¦"
+"用默认行为,为物体施加完全自定义的åˆåŠ›ã€‚"
#: doc/classes/RigidBody.xml
msgid ""
@@ -65966,7 +66400,7 @@ msgid ""
"This is equivalent to [code]add_force(force, Vector3(0,0,0))[/code]."
msgstr ""
"在ä¸å½±å“旋转的情况下添加æ’定的方å‘力(å³åŠ é€Ÿåº¦ï¼‰ã€‚\n"
-"这相当于 [code]add_force(force, Vector3(0,0,0))[/code]。"
+"相当于 [code]add_force(force, Vector3(0,0,0))[/code]。"
#: doc/classes/RigidBody.xml
msgid ""
@@ -65988,7 +66422,7 @@ msgid ""
"This is equivalent to [code]apply_impulse(Vector3(0,0,0), impulse)[/code]."
msgstr ""
"施加å•一方å‘的冲é‡è€Œä¸å½±å“旋转。\n"
-"这等价于[code]apply_impulse(Vector3(0,0,0), impulse)[/code]。"
+"相当于 [code]apply_impulse(Vector3(0,0,0), impulse)[/code]。"
#: doc/classes/RigidBody.xml
msgid ""
@@ -65998,7 +66432,7 @@ msgid ""
"position uses the rotation of the global coordinate system, but is centered "
"at the object's origin."
msgstr ""
-"对物体施加一个有å‘的冲é‡ã€‚冲釿˜¯ä¸Žæ—¶é—´æ— å…³çš„! 在æ¯ä¸€å¸§ä¸­æ–½åŠ ä¸€ä¸ªå†²é‡å°†äº§ç”Ÿä¸€"
+"对物体施加一个有å‘的冲é‡ã€‚冲釿˜¯ä¸Žæ—¶é—´æ— å…³çš„ï¼åœ¨æ¯ä¸€å¸§ä¸­æ–½åŠ ä¸€ä¸ªå†²é‡å°†äº§ç”Ÿä¸€"
"个与帧率相关的力。出于这个原因,它应该åªåœ¨æ¨¡æ‹Ÿä¸€æ¬¡æ€§å½±å“时使用。该ä½ç½®ä½¿ç”¨å…¨"
"局忠‡ç³»çš„æ—‹è½¬ï¼Œä½†ä»¥ç‰©ä½“的原点为中心。"
@@ -66025,8 +66459,9 @@ msgid ""
"For performance, list of collisions is updated once per frame and before the "
"physics step. Consider using signals instead."
msgstr ""
-"è¿”å›žä¸€ä¸ªä¸Žæ­¤ç¢°æ’žçš„ç‰©ä½“çš„åˆ—è¡¨ã€‚è¦æ±‚[member contact_monitor]设置为 [code]true[/"
-"code],[member contacts_reported]设置得足够高,以检测所有碰撞。\n"
+"è¿”å›žä¸€ä¸ªä¸Žæ­¤ç¢°æ’žçš„ç‰©ä½“çš„åˆ—è¡¨ã€‚è¦æ±‚ [member contact_monitor] 设置为 "
+"[code]true[/code],[member contacts_reported] 设置得足够高,以检测所有碰"
+"撞。\n"
"[b]注æ„:[/b]在移动物体åŽï¼Œè¿™ä¸ªæµ‹è¯•çš„ç»“æžœä¸æ˜¯ç«‹å³çš„。为了性能,碰撞列表æ¯å¸§åœ¨"
"物ç†è¿ç®—之剿›´æ–°ä¸€æ¬¡ã€‚å¯ä»¥è€ƒè™‘ä½¿ç”¨ä¿¡å·æ¥ä»£æ›¿ã€‚"
@@ -66097,7 +66532,7 @@ msgid ""
"[member mode] is [constant MODE_CHARACTER]. It can still be put to sleep "
"manually by setting its [member sleeping] property to [code]true[/code]."
msgstr ""
-"如果[code]true[/code],实体å¯ä»¥åœ¨æ²¡æœ‰è¿åŠ¨çš„æƒ…å†µä¸‹è¿›å…¥ç¡çœ æ¨¡å¼ã€‚è§[member "
+"如果为 [code]true[/code],实体å¯ä»¥åœ¨æ²¡æœ‰è¿åŠ¨çš„æƒ…å†µä¸‹è¿›å…¥ç¡çœ æ¨¡å¼ã€‚è§[member "
"sleeping]。\n"
"[b]注æ„:[/b]RigidBody3D 的模å¼[member mode] 为常é‡[constant MODE_CHARACTER] "
"æ—¶ä¸ä¼šè‡ªåŠ¨è¿›å…¥ä¼‘çœ æ¨¡å¼ã€‚ä»ç„¶å¯ä»¥é€šè¿‡å°†å…¶ [member sleeping] 属性设置为 "
@@ -66108,7 +66543,7 @@ msgid ""
"If [code]true[/code], the RigidBody will emit signals when it collides with "
"another RigidBody. See also [member contacts_reported]."
msgstr ""
-"如果[code]true[/code],当RigidBody与å¦ä¸€ä¸ªRigidBody碰撞时会å‘出信å·ã€‚å‚阅"
+"如果为 [code]true[/code],当RigidBody与å¦ä¸€ä¸ªRigidBody碰撞时会å‘出信å·ã€‚å‚阅"
"[member contacts_reported]。"
#: doc/classes/RigidBody.xml
@@ -66122,7 +66557,7 @@ msgid ""
msgstr ""
"将被记录的最大接触次数。需è¦å°† [member contact_monitor] 设置为 [code]true[/"
"code]。\n"
-"[b]注:[/b]接触次数与碰撞次数ä¸åŒã€‚平行边之间的碰撞将导致两个接触(æ¯ç«¯ä¸€"
+"[b]注æ„:[/b]接触次数与碰撞次数ä¸åŒã€‚平行边之间的碰撞将导致两个接触(æ¯ç«¯ä¸€"
"个),平行é¢ä¹‹é—´çš„碰撞将导致四个接触(æ¯ä¸ªè§’一个)。"
#: doc/classes/RigidBody.xml
@@ -66134,7 +66569,7 @@ msgid ""
"small, fast-moving objects. Not using continuous collision detection is "
"faster to compute, but can miss small, fast-moving objects."
msgstr ""
-"如果 [code]true[/code],则使用连续碰撞检测。\n"
+"如果为 [code]true[/code],则使用连续碰撞检测。\n"
"连续碰撞检测å°è¯•é¢„æµ‹ä¸€ä¸ªç§»åŠ¨çš„ç‰©ä½“ä¼šåœ¨å“ªé‡Œç¢°æ’žï¼Œè€Œä¸æ˜¯ç§»åŠ¨å®ƒå¹¶åœ¨å®ƒå‘生碰撞时"
"纠正它的è¿åŠ¨ã€‚è¿žç»­ç¢°æ’žæ£€æµ‹æ›´ç²¾ç¡®ï¼Œå¹¶ä¸”é”™è¿‡äº†è¾ƒå°çš„ã€å¿«é€Ÿç§»åŠ¨çš„ç‰©ä½“çš„æ’žå‡»ã€‚ä¸"
"使用连续碰撞检测的计算速度更快,但å¯èƒ½ä¼šé”™è¿‡å°çš„ã€å¿«é€Ÿç§»åŠ¨çš„ç‰©ä½“ã€‚"
@@ -66146,9 +66581,9 @@ msgid ""
"body will only move as determined by the [method _integrate_forces] "
"function, if defined."
msgstr ""
-"如果 [code]true[/code],则该物体的内力积分将被ç¦ç”¨ï¼ˆå¦‚é‡åŠ›æˆ–ç©ºæ°”æ‘©æ“¦ï¼‰ã€‚é™¤äº†"
-"碰撞å“åº”ä¹‹å¤–ï¼Œç‰©ä½“å°†ä»…æ ¹æ® [method _integrate_forces] 函数确定的方å¼ç§»åŠ¨ï¼ˆå¦‚"
-"果已定义)。"
+"如果为 [code]true[/code],则该物体的内力积分将被ç¦ç”¨ï¼ˆå¦‚é‡åŠ›æˆ–ç©ºæ°”æ‘©æ“¦ï¼‰ã€‚é™¤"
+"了碰撞å“åº”ä¹‹å¤–ï¼Œç‰©ä½“å°†ä»…æ ¹æ® [method _integrate_forces] 函数确定的方å¼ç§»åЍ"
+"(如果已定义)。"
#: doc/classes/RigidBody.xml
msgid ""
@@ -66201,7 +66636,7 @@ msgstr "实体的质é‡ã€‚"
#: doc/classes/RigidBody.xml
msgid "The body mode. See [enum Mode] for possible values."
-msgstr "物体的模å¼ã€‚å¯èƒ½çš„值è§[enum Mode]。"
+msgstr "物体的模å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum Mode]。"
#: doc/classes/RigidBody.xml doc/classes/RigidBody2D.xml
#: doc/classes/StaticBody.xml doc/classes/StaticBody2D.xml
@@ -66220,8 +66655,8 @@ msgid ""
"until woken up by another body through, for example, a collision, or by "
"using the [method apply_impulse] or [method add_force] methods."
msgstr ""
-"如果 [code]true[/code],物体ä¸ä¼šç§»åЍ并䏔ä¸ä¼šè®¡ç®—力,直到被å¦ä¸€ä¸ªç‰©ä½“唤醒,例"
-"如碰撞,或使用 [method apply_impulse] 或 [method add_force] 方法。"
+"如果为 [code]true[/code],物体ä¸ä¼šç§»åЍ并䏔ä¸ä¼šè®¡ç®—力,直到被å¦ä¸€ä¸ªç‰©ä½“唤醒,"
+"例如碰撞,或使用 [method apply_impulse] 或 [method add_force] 方法。"
#: doc/classes/RigidBody.xml
msgid ""
@@ -66240,12 +66675,12 @@ msgid ""
"[code]body[/code] the [Node], if it exists in the tree, of the other "
"[PhysicsBody] or [GridMap]."
msgstr ""
-"当与å¦ä¸€ä¸ª[PhysicsBody]或[GridMap]å‘生碰撞时触å‘。需è¦å°†[member "
-"contact_monitor]设置为 [code]true[/code],并且将[member contacts_reported]设"
-"置得足够高以检测所有的碰撞。如果[MeshLibrary]有碰撞[Shape],[GridMap]就会被检"
-"测到。\n"
-"[code]body[/code]的[Node],如果它存在于树中,则是其他[PhysicsBody]或[GridMap]"
-"的节点。"
+"当与å¦ä¸€ä¸ª [PhysicsBody] 或 [GridMap] å‘生碰撞时触å‘。需è¦å°† [member "
+"contact_monitor] 设置为 [code]true[/code],并且将 [member contacts_reported] "
+"设置得足够高以检测所有的碰撞。如果 [MeshLibrary] 有碰撞 [Shape],[GridMap] 就"
+"会被检测到。\n"
+"[code]body[/code] 的 [Node],如果它存在于树中,则是其他 [PhysicsBody] 或 "
+"[GridMap] 的节点。"
#: doc/classes/RigidBody.xml
msgid ""
@@ -66256,12 +66691,12 @@ msgid ""
"[code]body[/code] the [Node], if it exists in the tree, of the other "
"[PhysicsBody] or [GridMap]."
msgstr ""
-"当与å¦ä¸€ä¸ª[PhysicsBody]或[GridMap]çš„ç¢°æ’žç»“æŸæ—¶è§¦å‘。需è¦å°†[member "
-"contact_monitor]设置为 [code]true[/code],并且将[member contacts_reported]设"
-"置得足够高以检测到所有的碰撞。如果[MeshLibrary]有碰撞[Shape],[GridMap]就会被"
-"检测到。\n"
-"[code]body[/code]的[Node],如果它存在于树中,则是其他[PhysicsBody]或[GridMap]"
-"的节点。"
+"当与å¦ä¸€ä¸ª [PhysicsBody]或 [GridMap] çš„ç¢°æ’žç»“æŸæ—¶è§¦å‘。需è¦å°† [member "
+"contact_monitor] 设置为 [code]true[/code],并且将 [member contacts_reported] "
+"设置得足够高以检测到所有的碰撞。如果 [MeshLibrary] 有碰撞 [Shape],[GridMap] "
+"就会被检测到。\n"
+"[code]body[/code]的[Node],如果它存在于树中,则是其他 [PhysicsBody] 或 "
+"[GridMap] 的节点。"
#: doc/classes/RigidBody.xml
msgid ""
@@ -66285,22 +66720,23 @@ msgid ""
"[ConcavePolygonShape]. Don't use multiple [CollisionShape]s when using a "
"[ConcavePolygonShape] with Bullet physics if you need shape indices."
msgstr ""
-"当[PhysicsBody]或[GridMap]的一个形状[Shape]进入这个区域的一个形状[Shape]æ—¶å‘"
-"出的。需è¦å°†ç›‘控[member contact_monitor]设置为 [code]true[/code],且[member "
-"contacts_reported]设置的足够高以检测所有碰撞。如果[MeshLibrary]有碰撞形状"
-"[Shape],就会检测到[GridMap]。\n"
-"[code]body_id[/code]由[PhysicsServer]使用的其他[PhysicsBody]或[MeshLibrary]的"
-"[CollisionObject]的[RID]。\n"
-"[code]body[/code] 其他[PhysicsBody]或[GridMap]的[Node](如果它存在于树中)。\n"
-"[code]body_shape_index[/code] 由[PhysicsServer]使用的其他[PhysicsBody]或"
-"[GridMap]的[Shape]的索引。用 [code]body."
-"shape_owner_get_owner(body_shape_index)[/code]èŽ·å– [CollisionShape] 节点。\n"
-"[code]local_shape[/code] 由[PhysicsServer]使用的这个刚体(RigidBody)的[Shape]"
-"的索引。用[code]self.shape_owner_get_owner(local_shape_index)[/code]获å–"
-"[CollisionShape]节点。\n"
-"[b]注æ„:[/b]当使用[ConcavePolygonShape]时,对于å­å¼¹çš„物ç†è¿ç®—无法识别形状索"
-"引。如果你需è¦å½¢çŠ¶æŒ‡æ•°ï¼Œåœ¨ä½¿ç”¨[ConcavePolygonShape]和对于å­å¼¹çš„物ç†è¿ç®—时,ä¸"
-"è¦ä½¿ç”¨å¤šä¸ª[CollisionShape]。"
+"当 [PhysicsBody] 或 [GridMap] 的一个形状 [Shape] 进入这个区域的一个形状 "
+"[Shape] æ—¶å‘出的。需è¦å°†ç›‘控 [member contact_monitor] 设置为 [code]true[/"
+"code],且 [member contacts_reported] 设置的足够高以检测所有碰撞。如果 "
+"[MeshLibrary] 有碰撞形状 [Shape],就会检测到 [GridMap]。\n"
+"[code]body_id[/code] 由 [PhysicsServer] 使用的其他 [PhysicsBody] 或 "
+"[MeshLibrary] 的 [CollisionObject] 的 [RID]。\n"
+"[code]body[/code] 其他 [PhysicsBody] 或 [GridMap] 的 [Node](如果它存在于树"
+"中)。\n"
+"[code]body_shape_index[/code] 由 [PhysicsServer] 使用的其他 [PhysicsBody] 或 "
+"[GridMap] 的 [Shape] 的索引。用 [code]body."
+"shape_owner_get_owner(body_shape_index)[/code] èŽ·å– [CollisionShape] 节点。\n"
+"[code]local_shape[/code] 由 [PhysicsServer] 使用的这个 RigidBody 的 [Shape] "
+"的索引。用 [code]self.shape_owner_get_owner(local_shape_index)[/code] èŽ·å– "
+"[CollisionShape] 节点。\n"
+"[b]注æ„:[/b]当使用 [ConcavePolygonShape] 时,对于å­å¼¹çš„物ç†è¿ç®—无法识别形状"
+"索引。如果你需è¦å½¢çŠ¶æŒ‡æ•°ï¼Œåœ¨ä½¿ç”¨ [ConcavePolygonShape] 和对于å­å¼¹çš„物ç†è¿ç®—"
+"时,ä¸è¦ä½¿ç”¨å¤šä¸ª[CollisionShape]。"
#: doc/classes/RigidBody.xml
msgid ""
@@ -66353,35 +66789,34 @@ msgid ""
"engine or [code]emit_signal(\"sleeping_state_changed\")[/code] is used."
msgstr ""
"当物ç†å¼•擎改å˜ç‰©ä½“çš„ç¡çœ çŠ¶æ€æ—¶å‘出。\n"
-"[b]注æ„:[/b]改å˜[member sleeping]的值ä¸ä¼šè§¦å‘这个信å·ã€‚åªæœ‰å½“物ç†å¼•擎改å˜äº†"
-"ç¡çœ çŠ¶æ€æˆ–者使用了[code]emit_signal(\"sleeping_state_changed\")[/code]时,它"
-"æ‰ä¼šè¢«å‘出。"
+"[b]注æ„:[/b]æ”¹å˜ [member sleeping] 的值ä¸ä¼šè§¦å‘这个信å·ã€‚åªæœ‰å½“物ç†å¼•擎改å˜"
+"了ç¡çœ çŠ¶æ€æˆ–者使用了 [code]emit_signal(\"sleeping_state_changed\")[/code] "
+"时,它æ‰ä¼šè¢«å‘出。"
#: doc/classes/RigidBody.xml
msgid ""
"Rigid body mode. This is the \"natural\" state of a rigid body. It is "
"affected by forces, and can move, rotate, and be affected by user code."
msgstr ""
-"刚体模å¼ã€‚这是一个刚体的 \"自然 \"状æ€ã€‚它å—到力的影å“,å¯ä»¥ç§»åŠ¨ã€æ—‹è½¬ï¼Œå¹¶å—"
-"到用户代ç çš„å½±å“。"
+"刚体模å¼ã€‚这是一个刚体的“自然â€çжæ€ã€‚它å—到力的影å“,å¯ä»¥ç§»åŠ¨ã€æ—‹è½¬ï¼Œå¹¶å—到用"
+"户代ç çš„å½±å“。"
#: doc/classes/RigidBody.xml
msgid ""
"Static mode. The body behaves like a [StaticBody], and can only move by user "
"code."
-msgstr "陿­¢æ¨¡å¼ã€‚实体的行为就åƒä¸€ä¸ª[StaticBody],åªèƒ½é€šè¿‡ç”¨æˆ·ä»£ç ç§»åŠ¨ã€‚"
+msgstr "陿­¢æ¨¡å¼ã€‚该实体的行为与 [StaticBody] 类似,åªèƒ½è¢«ç”¨æˆ·ä»£ç ç§»åŠ¨ã€‚"
#: doc/classes/RigidBody.xml
msgid ""
"Character body mode. This behaves like a rigid body, but can not rotate."
-msgstr "角色模å¼ã€‚这与刚体的行为类似,但ä¸èƒ½æ—‹è½¬ã€‚"
+msgstr "角色模å¼ã€‚与刚体的行为类似,但ä¸èƒ½æ—‹è½¬ã€‚"
#: doc/classes/RigidBody.xml
msgid ""
"Kinematic body mode. The body behaves like a [KinematicBody], and can only "
"move by user code."
-msgstr ""
-"è¿åŠ¨ä½“æ¨¡å¼ã€‚这个实体的行为就åƒä¸€ä¸ª[KinematicBody],åªèƒ½é€šè¿‡ç”¨æˆ·ä»£ç æ¥ç§»åŠ¨ã€‚"
+msgstr "è¿åŠ¨ä½“æ¨¡å¼ã€‚该实体的行为与 [KinematicBody] 类似,åªèƒ½è¢«ç”¨æˆ·ä»£ç ç§»åŠ¨ã€‚"
#: doc/classes/RigidBody2D.xml
msgid "A body that is controlled by the 2D physics engine."
@@ -66419,7 +66854,7 @@ msgstr ""
"è¦è®°ä½ï¼Œç‰©ç†ç‰©ä½“在自己管ç†å˜æ¢ï¼Œå®ƒä¼šè¦†ç›–ä½ çš„å˜æ¢è®¾ç½®ã€‚所以任何直接或间接的å˜"
"æ¢ï¼ˆåŒ…括节点或其父级的缩放)将åªåœ¨ç¼–辑器中å¯è§ï¼Œå¹¶åœ¨è¿è¡Œæ—¶ç«‹å³é‡ç½®ã€‚\n"
"如果你需è¦è¦†ç›–默认的物ç†è¡Œä¸ºæˆ–者在è¿è¡Œæ—¶æ·»åŠ å˜æ¢ï¼Œä½ å¯ä»¥å†™ä¸€ä¸ªè‡ªå®šä¹‰çš„åˆåŠ›ã€‚"
-"å‚阅 [member custom_integrator]。\n"
+"è§ [member custom_integrator]。\n"
"è´¨é‡ä¸­å¿ƒæ€»æ˜¯ä½äºŽèŠ‚ç‚¹çš„åŽŸç‚¹ï¼Œè€Œä¸è€ƒè™‘ [CollisionShape2D] 中心点的å移。"
#: doc/classes/RigidBody2D.xml
@@ -66439,10 +66874,10 @@ msgid ""
"custom_integrator] allows you to disable the default behavior and write "
"custom force integration for a body."
msgstr ""
-"å…许你读å–并安全地修改对象的模拟状æ€ã€‚如果你需è¦ç›´æŽ¥æ”¹å˜ç‰©ä½“çš„"
-"[code]position[/code]或其他物ç†å±žæ€§ï¼Œè¯·ä½¿ç”¨å®ƒä»£æ›¿[method Node."
-"_physics_process]。默认情况下,它是在通常的物ç†è¡Œä¸ºä¹‹å¤–工作的,但是[member "
-"custom_integrator]å…许你ç¦ç”¨é»˜è®¤è¡Œä¸ºå¹¶ä¸ºä¸€ä¸ªç‰©ä½“编写自定义的åˆåŠ›ã€‚"
+"å…许你读å–并安全地修改对象的模拟状æ€ã€‚如果你需è¦ç›´æŽ¥æ”¹å˜ç‰©ä½“çš„ "
+"[code]position[/code] 或其他物ç†å±žæ€§ï¼Œè¯·ä½¿ç”¨å®ƒä»£æ›¿ [method Node."
+"_physics_process]。默认情况下,它是在通常的物ç†è¡Œä¸ºä¹‹å¤–工作的,但是 [member "
+"custom_integrator] å…许你ç¦ç”¨é»˜è®¤è¡Œä¸ºå¹¶ä¸ºä¸€ä¸ªç‰©ä½“编写自定义的åˆåŠ›ã€‚"
#: doc/classes/RigidBody2D.xml
msgid ""
@@ -66453,8 +66888,8 @@ msgid ""
"global coordinate system, but is centered at the object's origin."
msgstr ""
"对物体施加一个有å‘的冲é‡ã€‚冲釿˜¯ä¸Žæ—¶é—´æ— å…³çš„。æ¯ä¸€å¸§åº”用一个冲é‡ä¼šæœ‰ä¸€ä¸ªä¸Žå¸§"
-"相关的力。由于这个原因,它åªåº”该在模拟一次性冲击时使用(å¦åˆ™å°±ä½¿ç”¨\"_force "
-"\"函数)。ä½ç½®ä½¿ç”¨å…¨å±€å标系的旋转,但以物体的原点为中心。"
+"相关的力。由于这个原因,它åªåº”该在模拟一次性冲击时使用(å¦åˆ™å°±ä½¿ç”¨â€œ_forceâ€å‡½"
+"数)。ä½ç½®ä½¿ç”¨å…¨å±€å标系的旋转,但以物体的原点为中心。"
#: doc/classes/RigidBody2D.xml
msgid ""
@@ -66509,7 +66944,7 @@ msgid ""
"[member mode] is [constant MODE_CHARACTER]. It can still be put to sleep "
"manually by setting its [member sleeping] property to [code]true[/code]."
msgstr ""
-"如果[code]true[/code],身体å¯ä»¥åœ¨æ²¡æœ‰è¿åŠ¨çš„æƒ…å†µä¸‹è¿›å…¥ç¡çœ æ¨¡å¼ã€‚è§[member "
+"如果为 [code]true[/code],身体å¯ä»¥åœ¨æ²¡æœ‰è¿åŠ¨çš„æƒ…å†µä¸‹è¿›å…¥ç¡çœ æ¨¡å¼ã€‚è§[member "
"sleeping]。\n"
"[b]注æ„:[/b]RigidBody2D çš„[member mode] 为[constant MODE_CHARACTER] æ—¶ä¸ä¼šè‡ª"
"动进入休眠模å¼ã€‚ä»ç„¶å¯ä»¥é€šè¿‡å°†å…¶ [member sleeping] 属性设置为 [code]true[/"
@@ -66520,8 +66955,8 @@ msgid ""
"If [code]true[/code], the body will emit signals when it collides with "
"another RigidBody2D. See also [member contacts_reported]."
msgstr ""
-"如果[code]true[/code],则物体在与å¦ä¸€ä¸ªRigidBody2D碰撞时会å‘出信å·ã€‚å‚阅"
-"[member contacts_reported]。"
+"如果为 [code]true[/code],则物体在与å¦ä¸€ä¸ª RigidBody2D 碰撞时会å‘出信å·ã€‚å¦è¯·"
+"å‚阅 [member contacts_reported]。"
#: doc/classes/RigidBody2D.xml
msgid ""
@@ -66556,7 +66991,7 @@ msgid ""
"Aside from collision response, the body will only move as determined by the "
"[method _integrate_forces] function."
msgstr ""
-"如果 [code]true[/code],则ç¦ç”¨è¯¥ç‰©ä½“的内力积分。除了碰撞å“应,物体åªä¼šæŒ‰ç…§ "
+"如果为 [code]true[/code],则ç¦ç”¨è¯¥ç‰©ä½“的内力积分。除了碰撞å“应,物体åªä¼šæŒ‰ç…§ "
"[method _integrate_forces] 函数确定的方å¼ç§»åŠ¨ã€‚"
#: doc/classes/RigidBody2D.xml
@@ -66577,7 +67012,7 @@ msgid ""
"from the [b]Default Gravity[/b] value in [b]Project > Project Settings > "
"Physics > 2d[/b] and/or any additional gravity vector applied by [Area2D]s."
msgstr ""
-"乘以施加在物体上的é‡åŠ›ã€‚ç‰©ä½“çš„é‡åŠ›æ˜¯ç”±[b]项目 > 项目设置 > ç‰©ç† > 2D[/b]中的"
+"乘以施加在物体上的é‡åŠ›ã€‚ç‰©ä½“çš„é‡åŠ›æ˜¯ç”±[b]项目 > 项目设置 > ç‰©ç† > 2D[/b] 中的"
"[b]默认é‡åŠ›[/b]值和/或任何由 [Area2D] 应用的é¢å¤–é‡åŠ›å‘é‡è®¡ç®—出æ¥çš„。"
#: doc/classes/RigidBody2D.xml
@@ -66614,7 +67049,7 @@ msgid ""
"thread and runs at a different granularity. Use [method _integrate_forces] "
"as your process loop for precise control of the body state."
msgstr ""
-"该实体的线速度,å•ä½ä¸ºåƒç´ æ¯ç§’。å¯ä»¥å¶å°”使用,但是[b]ä¸è¦æ¯ä¸€å¸§éƒ½è®¾ç½®å®ƒ[/b],"
+"该实体的线速度,å•ä½ä¸ºåƒç´ æ¯ç§’。å¯ä»¥å¶å°”使用,但是[b]ä¸è¦æ¯ä¸€å¸§éƒ½åŽ»è®¾ç½®[/b],"
"因为物ç†å¯èƒ½åœ¨å¦ä¸€ä¸ªçº¿ç¨‹ä¸­è¿è¡Œï¼Œå¹¶ä¸”以ä¸åŒçš„间隔。使用 [method "
"_integrate_forces] 作为你的进程循环,以精确控制物体状æ€ã€‚"
@@ -66639,11 +67074,12 @@ msgid ""
"[code]body[/code] the [Node], if it exists in the tree, of the other "
"[PhysicsBody2D] or [TileMap]."
msgstr ""
-"当与å¦ä¸€ä¸ª[PhysicsBody2D]或[TileMap]å‘生碰撞时触å‘。需è¦å°†[member "
-"contact_monitor]设置为 [code]true[/code],并且将[member contacts_reported]设"
-"置得足够高以检测所有的碰撞。如果[TileSet]有碰撞[Shape2D],就会检测到[TileMap]"
-"的。\n"
-"[code]body[/code]是其他[PhysicsBody2D]或[TileMap]的[Node],如果它存在于树中。"
+"当与å¦ä¸€ä¸ª [PhysicsBody2D] 或 [TileMap] å‘生碰撞时触å‘。需è¦å°† [member "
+"contact_monitor] 设置为 [code]true[/code],并且将 [member contacts_reported] "
+"设置得足够高以检测所有的碰撞。如果[TileSet] 有碰撞 [Shape2D],就会检测到 "
+"[TileMap] 的。\n"
+"[code]body[/code] 是其他 [PhysicsBody2D] 或 [TileMap] 的 [Node],如果它存在于"
+"树中。"
#: doc/classes/RigidBody2D.xml
msgid ""
@@ -66654,11 +67090,12 @@ msgid ""
"[code]body[/code] the [Node], if it exists in the tree, of the other "
"[PhysicsBody2D] or [TileMap]."
msgstr ""
-"当与å¦ä¸€ä¸ª[PhysicsBody2D]或[TileMap]çš„ç¢°æ’žç»“æŸæ—¶å‘出的。需è¦å°† [member "
+"当与å¦ä¸€ä¸ª [PhysicsBody2D] 或 [TileMap] çš„ç¢°æ’žç»“æŸæ—¶å‘出的。需è¦å°† [member "
"contact_monitor] 设置为 [code]true[/code] 并将 [member contacts_reported] 设"
-"置为足够高以检测所有碰撞。如果[TileSet]有碰撞[Shape2D],就会检测到"
+"置为足够高以检测所有碰撞。如果[TileSet] 有碰撞 [Shape2D],就会检测到 "
"[TileMap]。\n"
-"[code]body[/code] 其他[PhysicsBody2D]或[TileMap]的[Node](如果它存在于树中)。"
+"[code]body[/code] 其他 [PhysicsBody2D] 或 [TileMap] 的 [Node](如果它存在于树"
+"中)。"
#: doc/classes/RigidBody2D.xml
msgid ""
@@ -66713,20 +67150,22 @@ msgid ""
"RigidBody2D used by the [Physics2DServer]. Get the [CollisionShape2D] node "
"with [code]self.shape_owner_get_owner(local_shape_index)[/code]."
msgstr ""
-"当这个RigidBody2D的一个[Shape2D]å’Œå¦ä¸€ä¸ª[PhysicsBody2D]或[TileMap]çš„[Shape2D]"
-"ä¹‹é—´çš„ç¢°æ’žç»“æŸæ—¶è§¦å‘ã€‚è¦æ±‚[member contact_monitor]设置为 [code]true[/code],"
-"[member contacts_reported]设置得足够高以检测所有的碰撞。如果[TileSet]有碰撞"
-"[Shape2D],就会检测到[TileMap]的。\n"
-"[code]body_rid[/code] [Physics2DServer]使用的其他[PhysicsBody2D]或[TileSet]的"
-"[CollisionObject2D]的 [RID]。\n"
-"[code]body[/code] å¦ä¸€ä¸ª[PhysicsBody2D]或[TileMap]çš„[Node],如果它存在于树"
-"中。\n"
-"[code]body_shape_index[/code] 由[Physics2DServer]使用的其他[PhysicsBody2D]或"
-"[TileMap]的[Shape2D]的索引。用[code]body."
-"shape_owner_get_owner(body_shape_index)[/code]获得[CollisionShape2D]节点。\n"
-"[code]local_shape_index[/code]这个RigidBody2D的[Shape2D]的索引,由"
-"[Physics2DServer]使用。用[code]self.shape_owner_get_owner(local_shape_index)"
-"[/code]获å–[CollisionShape2D]节点。"
+"当这个 RigidBody2D 的一个 [Shape2D] å’Œå¦ä¸€ä¸ª [PhysicsBody2D] 或 [TileMap] çš„ "
+"[Shape2D] ä¹‹é—´çš„ç¢°æ’žç»“æŸæ—¶è§¦å‘ã€‚è¦æ±‚ [member contact_monitor] 设置为 "
+"[code]true[/code],[member contacts_reported] 设置得足够高以检测所有的碰撞。"
+"如果 [TileSet] 有碰撞 [Shape2D],就会检测到 [TileMap] 的。\n"
+"[code]body_rid[/code] [Physics2DServer] 使用的其他 [PhysicsBody2D] 或 "
+"[TileSet] 的 [CollisionObject2D] 的 [RID]。\n"
+"[code]body[/code] å¦ä¸€ä¸ª [PhysicsBody2D] 或 [TileMap] çš„ [Node],如果它存在于"
+"树中。\n"
+"[code]body_shape_index[/code] 由 [Physics2DServer] 使用的其他 "
+"[PhysicsBody2D] 或 [TileMap] 的 [Shape2D]的索引。用 [code]body."
+"shape_owner_get_owner(body_shape_index)[/code] 获得 [CollisionShape2D] 节"
+"点。\n"
+"[code]local_shape_index[/code] 这个 RigidBody2D 的 [Shape2D] 的索引,由 "
+"[Physics2DServer] 使用。用 [code]self."
+"shape_owner_get_owner(local_shape_index)[/code] èŽ·å– [CollisionShape2D] 节"
+"点。"
#: doc/classes/RigidBody2D.xml
msgid ""
@@ -66738,20 +67177,20 @@ msgstr ""
#: doc/classes/RigidBody2D.xml
msgid "Static mode. The body behaves like a [StaticBody2D] and does not move."
-msgstr "陿€æ¨¡å¼ã€‚物体的行为就åƒä¸€ä¸ª[StaticBody2D],ä¸ä¼šç§»åŠ¨ã€‚"
+msgstr "陿€æ¨¡å¼ã€‚该物体的行为与 [StaticBody2D] 类似,ä¸ä¼šç§»åŠ¨ã€‚"
#: doc/classes/RigidBody2D.xml
msgid ""
"Character mode. Similar to [constant MODE_RIGID], but the body can not "
"rotate."
-msgstr "角色模å¼ã€‚与[constant MODE_RIGID]类似,但主体ä¸èƒ½æ—‹è½¬ã€‚"
+msgstr "角色模å¼ã€‚与 [constant MODE_RIGID] 类似,但该实体ä¸èƒ½æ—‹è½¬ã€‚"
#: doc/classes/RigidBody2D.xml
msgid ""
"Kinematic mode. The body behaves like a [KinematicBody2D], and must be moved "
"by code."
msgstr ""
-"è¿åŠ¨å­¦æ¨¡å¼ã€‚这个物体的行为就åƒä¸€ä¸ª[KinematicBody2D]ï¼Œå¿…é¡»é€šè¿‡ä»£ç æ¥ç§»åŠ¨ã€‚"
+"è¿åŠ¨å­¦æ¨¡å¼ã€‚该物体的行为就åƒä¸Ž [KinematicBody2D] ç±»ä¼¼ï¼Œå¿…é¡»é€šè¿‡ä»£ç æ¥ç§»åŠ¨ã€‚"
#: doc/classes/RigidBody2D.xml
msgid ""
@@ -66765,18 +67204,17 @@ msgstr ""
msgid ""
"Continuous collision detection enabled using raycasting. This is faster than "
"shapecasting but less precise."
-msgstr "使用射线投射å¯ç”¨è¿žç»­ç¢°æ’žæ£€æµ‹ã€‚这比 shapecasting 快,但精度较低。"
+msgstr "使用射线投射å¯ç”¨è¿žç»­ç¢°æ’žæ£€æµ‹ã€‚这比形状投射快,但精度较低。"
#: doc/classes/RigidBody2D.xml
msgid ""
"Continuous collision detection enabled using shapecasting. This is the "
"slowest CCD method and the most precise."
-msgstr ""
-"使用 shapecasting å¯ç”¨è¿žç»­ç¢°æ’žæ£€æµ‹ã€‚这是最慢的 CCD 方法,也是最精确的。"
+msgstr "使用形状投射å¯ç”¨è¿žç»­ç¢°æ’žæ£€æµ‹ã€‚这是最慢的 CCD 方法,也是最精确的。"
#: doc/classes/Room.xml
msgid "Room node, used to group objects together locally for [Portal] culling."
-msgstr "Room 节点,用于在本地将对象组åˆåœ¨ä¸€èµ·ä»¥è¿›è¡Œ [Portal] 剔除。"
+msgstr "房间节点,用于在本地将对象组åˆåœ¨ä¸€èµ·ä»¥è¿›è¡Œ [Portal] 剔除。"
#: doc/classes/Room.xml
msgid ""
@@ -66908,7 +67346,7 @@ msgid ""
msgstr ""
"为了使用入å£é®æŒ¡å‰”除系统,您必须使用 [Room] å’Œ [Portal] æ¥æž„建您的关å¡ã€‚在这"
"些å¯ä»¥åœ¨è¿è¡Œæ—¶ä½¿ç”¨ä¹‹å‰ï¼Œå®ƒä»¬å¿…é¡»ç»è¿‡ä¸€ä¸ªç®€çŸ­çš„转æ¢è¿‡ç¨‹æ¥æž„建 [code]room "
-"graph[/code],这是入å£å‰”除所需的è¿è¡Œæ—¶æ•°æ®ã€‚ [code]portal graph[/code] ç”± "
+"graph[/code],这是入å£å‰”除所需的è¿è¡Œæ—¶æ•°æ®ã€‚[code]portal graph[/code] ç”± "
"[RoomManager] 节点控制,[RoomManager] è¿˜åŒ…å«æ•´ä¸ªå…¥å£ç³»ç»Ÿé€šç”¨çš„设置。"
#: doc/classes/RoomManager.xml
@@ -66917,7 +67355,7 @@ msgid ""
"before unloading a level, when transitioning from level to level, or "
"returning to a main menu."
msgstr ""
-"该方法会从 [b]portal graph[/b] æ¸…é™¤æ‰€æœ‰è½¬æ¢æ•°æ®ã€‚在å¸è½½å…³å¡ã€ä»Žå…³å¡è½¬æ¢åˆ°å…³å¡"
+"该方法会清除 [b]room graph[/b] ä¸­æ‰€æœ‰çš„è½¬æ¢æ•°æ®ã€‚在å¸è½½å…³å¡ã€ä»Žå…³å¡è½¬æ¢åˆ°å…³å¡"
"或返回主èœå•时使用此选项。"
#: doc/classes/RoomManager.xml
@@ -67015,9 +67453,9 @@ msgstr ""
"请注æ„,已ç»è½¬æ¢ä¸º [Portal] èŠ‚ç‚¹ï¼ˆè€Œä¸æ˜¯ [MeshInstance])的 [Portal] ä»ç„¶éœ€è¦"
"éµå¾ªç›¸åŒçš„命å约定,因为它们在转æ¢è¿‡ç¨‹ä¸­æ¯æ¬¡éƒ½ä¼šé‡æ–°é“¾æŽ¥ã€‚\n"
"建议您仅将对象放置在希望留在这些空间内的空间中 - å³ [code]portal mode[/code]"
-"是 [code]STATIC[/code] 或 [code]DYNAMIC[/code](ä¸ç©¿è¶Š Portal)。 "
+"是 [code]STATIC[/code] 或 [code]DYNAMIC[/code](ä¸ç©¿è¶Š Portal)。"
"[code]GLOBAL[/code] å’Œ [code]ROAMING[/code] 对象最好放置在场景树的å¦ä¸€éƒ¨åˆ†ï¼Œ"
-"以é¿å…混淆。有关portal模å¼çš„完整说明,请å‚阅 [CullInstance]。"
+"以é¿å…混淆。有关 portal 模å¼çš„完整说明,请å‚阅 [CullInstance]。"
#: doc/classes/RoomManager.xml
msgid ""
@@ -67215,7 +67653,7 @@ msgstr ""
#: doc/classes/RoomManager.xml
msgid "Shows the [Portal] margins when the portal gizmo is used in the editor."
-msgstr "当在编辑器中使用portal工具时,显示[Portal]的边界。"
+msgstr "当在编辑器中使用入å£å·¥å…·æ—¶ï¼Œæ˜¾ç¤º [Portal] 的边界。"
#: doc/classes/RoomManager.xml
msgid ""
@@ -67226,8 +67664,8 @@ msgid ""
"Sometimes using the larger gameplay area of the secondary PVS may be "
"preferable."
msgstr ""
-"å½“å¯¹è±¡è¿›å…¥å’Œé€€å‡ºæ¸¸æˆæ—¶æŽ¥æ”¶æ¸¸æˆå›žè°ƒæ—¶ï¼Œ[b]游æˆåŒºåŸŸ[/b]å¯ä»¥ç”±[Room]的主è¦PVS"
-"(潜在å¯è§é›†ï¼‰æˆ–次è¦PVS(主è¦PVSåŠå…¶ç›¸é‚»çš„PVS)定义[Room])。\n"
+"å½“å¯¹è±¡è¿›å…¥å’Œé€€å‡ºæ¸¸æˆæ—¶æŽ¥æ”¶æ¸¸æˆå›žè°ƒæ—¶ï¼Œ[b]游æˆåŒºåŸŸ[/b]å¯ä»¥ç”± [Room] çš„ä¸»è¦ PVS"
+"(潜在å¯è§é›†ï¼‰æˆ–æ¬¡è¦ PVSï¼ˆä¸»è¦ PVS åŠå…¶ç›¸é‚»çš„ PVS)定义 [Room])。\n"
"æœ‰æ—¶ä½¿ç”¨æ¬¡è¦ PVS 的较大游æˆåŒºåŸŸå¯èƒ½æ›´å¯å–。"
#: doc/classes/RoomManager.xml
@@ -67235,8 +67673,8 @@ msgid ""
"Use only [Portal]s at runtime to determine visibility. PVS will not be "
"generated at [Room]s conversion, and gameplay notifications cannot be used."
msgstr ""
-"在è¿è¡Œæ—¶ä»…使用 [Portal] æ¥ç¡®å®šå¯è§æ€§ã€‚ [Room] 的转æ¢ä¸ä¼šäº§ç”Ÿ PVS,无法使用游"
-"æˆé€šçŸ¥ã€‚"
+"在è¿è¡Œæ—¶ä»…使用 [Portal] æ¥ç¡®å®šå¯è§æ€§ã€‚[Room] 的转æ¢ä¸ä¼šäº§ç”Ÿ PVS,无法使用游æˆ"
+"通知。"
#: doc/classes/RoomManager.xml
msgid ""
@@ -67252,7 +67690,7 @@ msgstr "仅使用 [Room] çš„ PVS(潜在å¯è§é›†ï¼‰æ¥ç¡®å®šå¯è§æ€§ã€‚"
#: doc/classes/RootMotionView.xml
msgid "Editor-only helper for setting up root motion in [AnimationTree]."
-msgstr "在[AnimationTree]中设置根è¿åŠ¨çš„ä»…ç¼–è¾‘å™¨å¯ç”¨çš„辅助工具。"
+msgstr "在 [AnimationTree] 中设置根è¿åŠ¨çš„ä»…ç¼–è¾‘å™¨å¯ç”¨çš„辅助工具。"
#: doc/classes/RootMotionView.xml
msgid ""
@@ -67308,8 +67746,8 @@ msgid ""
"([i]local[/i] Y = 0). If [code]false[/code], the points' original Y "
"coordinate is preserved."
msgstr ""
-"如果 [code]true[/code],则网格的点都将ä½äºŽç›¸åŒçš„ Y åæ ‡ä¸Šï¼ˆ[i]local[/i] Y = "
-"0)。如果 [code]false[/code],则ä¿ç•™ç‚¹çš„原始 Y åæ ‡ã€‚"
+"如果为 [code]true[/code],则网格的点都将ä½äºŽç›¸åŒçš„ Y åæ ‡ä¸Šï¼ˆ[i]local[/i] Y "
+"= 0)。如果 [code]false[/code],则ä¿ç•™ç‚¹çš„原始 Y åæ ‡ã€‚"
#: doc/classes/SceneState.xml
msgid "A script interface to a scene file's data."
@@ -67323,8 +67761,8 @@ msgid ""
"scene as the result of [method PackedScene.get_state]."
msgstr ""
"维护一个与场景相关的资æºã€èŠ‚ç‚¹ã€å¯¼å‡ºçš„å’Œé‡å†™çš„属性以åŠå†…置脚本的列表。\n"
-"这个类ä¸èƒ½ç›´æŽ¥å®žä¾‹åŒ–,它是作为[method PackedScene.get_state]的结果为一个给定"
-"的场景检索的。"
+"这个类ä¸èƒ½ç›´æŽ¥å®žä¾‹åŒ–,它是作为 [method PackedScene.get_state] 的结果为一个给"
+"定的场景检索的。"
#: doc/classes/SceneState.xml
msgid ""
@@ -67339,20 +67777,20 @@ msgid ""
"get_connection_count() - 1][/code]."
msgstr ""
"返回场景中的信å·è¿žæŽ¥æ•°ã€‚\n"
-"用于查询其他[code]get_connection_*[/code]方法中的连接元数æ®çš„[code]idx[/code]"
-"傿•°ï¼Œå…¶é—´é𔿗¶é—´ä¸º[code][0, get_connection_count() - 1][/code]。"
+"用于查询其他 [code]get_connection_*[/code] 方法中的连接元数æ®çš„ [code]idx[/"
+"code] 傿•°ï¼ŒèŒƒå›´æ˜¯ [code][0, get_connection_count() - 1][/code]。"
#: doc/classes/SceneState.xml
msgid ""
"Returns the connection flags for the signal at [code]idx[/code]. See [enum "
"Object.ConnectFlags] constants."
msgstr ""
-"返回 [code]idx[/code] 处的信å·çš„连接标志。请å‚阅 [enum Object.ConnectFlags] "
-"常é‡ã€‚"
+"返回 [code]idx[/code] 处的信å·çš„è¿žæŽ¥æ ‡å¿—ã€‚è§ [enum Object.ConnectFlags] 常"
+"é‡ã€‚"
#: doc/classes/SceneState.xml
msgid "Returns the method connected to the signal at [code]idx[/code]."
-msgstr "返回连接到[code]idx[/code]处信å·çš„æ–¹æ³•。"
+msgstr "返回连接到 [code]idx[/code] 处信å·çš„æ–¹æ³•。"
#: doc/classes/SceneState.xml
msgid "Returns the name of the signal at [code]idx[/code]."
@@ -67362,7 +67800,7 @@ msgstr "返回 [code]idx[/code] 处的信å·å称。"
msgid ""
"Returns the path to the node that owns the signal at [code]idx[/code], "
"relative to the root node."
-msgstr "返回拥有[code]idx[/code]处信å·çš„节点的相对于根节点的路径。"
+msgstr "返回拥有 [code]idx[/code] 处信å·çš„节点的相对于根节点的路径。"
#: doc/classes/SceneState.xml
msgid ""
@@ -67379,8 +67817,8 @@ msgid ""
"1][/code]."
msgstr ""
"返回场景中节点的数é‡ã€‚\n"
-"[code]idx[/code]傿•°ç”¨äºŽåœ¨å…¶ä»–[code]get_node_*[/code]方法中查询节点数æ®ï¼Œå…¶é—´"
-"隔为[code][0, get_node_count() - 1][/code]。"
+"[code]idx[/code] 傿•°ç”¨äºŽåœ¨å…¶ä»– [code]get_node_*[/code] 方法中查询节点数æ®ï¼Œ"
+"范围为 [code][0, get_node_count() - 1][/code]。"
#: doc/classes/SceneState.xml
msgid ""
@@ -67432,9 +67870,9 @@ msgid ""
"If [code]for_parent[/code] is [code]true[/code], returns the path of the "
"[code]idx[/code] node's parent instead."
msgstr ""
-"返回 [code]idx[/code]处的节点的路径。\n"
-"如果[code]for_parent[/code]是[code]true[/code],则返回 [code]idx[/code]节点的"
-"父节点的路径。"
+"返回 [code]idx[/code] 处的节点的路径。\n"
+"如果 [code]for_parent[/code] 是 [code]true[/code],则返回 [code]idx[/code] 节"
+"点的父节点的路径。"
#: doc/classes/SceneState.xml
msgid ""
@@ -67469,8 +67907,8 @@ msgid ""
"Returns [code]true[/code] if the node at [code]idx[/code] is an "
"[InstancePlaceholder]."
msgstr ""
-"如果[code]idx[/code]处的节点是一个[InstancePlaceholder],返回 [code]true[/"
-"code]。"
+"如果 [code]idx[/code] 处的节点是一个 [InstancePlaceholder],则返回 "
+"[code]true[/code]。"
#: doc/classes/SceneState.xml
msgid ""
@@ -67550,8 +67988,8 @@ msgstr ""
"对给定组的æ¯ä¸ªæˆå‘˜è°ƒç”¨ [code]method[/code]。您å¯ä»¥é€šè¿‡åœ¨æ–¹æ³•è°ƒç”¨ç»“æŸæ—¶æŒ‡å®šå‚"
"æ•°æ¥å°†å‚数传递给 [code]method[/code]。此方法等效于使用 [constant "
"GROUP_CALL_DEFAULT] 标志调用 [method call_group_flags]。\n"
-"[b]注:[/b] [code]method[/code]最多åªèƒ½æœ‰5ä¸ªå‚æ•°ï¼ˆæ€»å…±7ä¸ªå‚æ•°ä¼ é€’给这个方"
-"法)。\n"
+"[b]注æ„:[/b][code]method[/code] 最多åªèƒ½æœ‰ 5 ä¸ªå‚æ•°ï¼ˆæ€»å…± 7 ä¸ªå‚æ•°ä¼ é€’给这个"
+"方法)。\n"
"[b]注æ„:[/b]由于设计é™åˆ¶ï¼Œå¦‚æžœå‚æ•°ä¹‹ä¸€ä¸º [code]null[/code],[method "
"call_group] å°†é™é»˜å¤±è´¥ã€‚\n"
"[b]注æ„:[/b][method call_group] 将始终调用具有一帧延迟的方法,其方å¼ç±»ä¼¼äºŽ "
@@ -67576,8 +68014,8 @@ msgstr ""
"对给定组的æ¯ä¸ªæˆå‘˜è°ƒç”¨ [code]method[/code],éµä»Žç»™å®šçš„ [enum "
"GroupCallFlags]。您å¯ä»¥é€šè¿‡åœ¨æ–¹æ³•è°ƒç”¨ç»“æŸæ—¶æŒ‡å®šå‚æ•°æ¥å°†å‚数传递给 "
"[code]method[/code]。\n"
-"[b]注:[/b] [code]method[/code]最多åªèƒ½æœ‰5ä¸ªå‚æ•°ï¼ˆæ€»å…±8ä¸ªå‚æ•°ä¼ é€’给这个方"
-"法)。\n"
+"[b]注æ„:[/b][code]method[/code] 最多åªèƒ½æœ‰ 5 ä¸ªå‚æ•°ï¼ˆæ€»å…± 8 ä¸ªå‚æ•°ä¼ é€’给这个"
+"方法)。\n"
"[b]注æ„:[/b]由于设计é™åˆ¶ï¼Œå¦‚æžœå‚æ•°ä¹‹ä¸€ä¸º [code]null[/code],[method "
"call_group_flags] å°†é™é»˜å¤±è´¥ã€‚\n"
"[codeblock]\n"
@@ -67670,7 +68108,7 @@ msgstr "返回此 [SceneTree] 的 [member network_peer] 的唯一对等 ID。"
#: doc/classes/SceneTree.xml
msgid "Returns the number of nodes in this [SceneTree]."
-msgstr "返回此[SceneTree]中的节点数。"
+msgstr "返回此 [SceneTree] 中的节点数。"
#: doc/classes/SceneTree.xml
msgid "Returns a list of all nodes assigned to the given group."
@@ -67686,7 +68124,7 @@ msgstr ""
#: doc/classes/SceneTree.xml
msgid "Returns the sender's peer ID for the most recently received RPC call."
-msgstr "返回最近收到的RPC调用的å‘é€è€…的对等ID。"
+msgstr "返回最近收到的 RPC 调用的å‘é€è€…的对等 ID。"
#: doc/classes/SceneTree.xml
msgid "Returns [code]true[/code] if the given group exists."
@@ -67697,8 +68135,8 @@ msgid ""
"Returns [code]true[/code] if the most recent [InputEvent] was marked as "
"handled with [method set_input_as_handled]."
msgstr ""
-"如果最近的 [InputEvent] 被使用 [method set_input_as_handled] 设置为已处ç†ï¼Œè¿”"
-"回 [code]true[/code]。"
+"如果最近的 [InputEvent] 被使用 [method set_input_as_handled] 设置为已处ç†ï¼Œåˆ™"
+"返回 [code]true[/code]。"
#: doc/classes/SceneTree.xml
msgid ""
@@ -67801,14 +68239,15 @@ msgid ""
"If [code]true[/code], collision shapes will be visible when running the game "
"from the editor for debugging purposes."
msgstr ""
-"如果 [code]true[/code],以调试为目的从编辑器è¿è¡Œæ¸¸æˆæ—¶ï¼Œç¢°æ’žå½¢çŠ¶å°†æ˜¯å¯è§çš„。"
+"如果为 [code]true[/code],以调试为目的从编辑器è¿è¡Œæ¸¸æˆæ—¶ï¼Œç¢°æ’žå½¢çŠ¶å°†æ˜¯å¯è§"
+"的。"
#: doc/classes/SceneTree.xml
msgid ""
"If [code]true[/code], navigation polygons will be visible when running the "
"game from the editor for debugging purposes."
msgstr ""
-"如果 [code]true[/code],以调试为目的从编辑器è¿è¡Œæ¸¸æˆæ—¶ï¼Œå¯¼èˆªå¤šè¾¹å½¢å°†æ˜¯å¯è§"
+"如果为 [code]true[/code],以调试为目的从编辑器è¿è¡Œæ¸¸æˆæ—¶ï¼Œå¯¼èˆªå¤šè¾¹å½¢å°†æ˜¯å¯è§"
"的。"
#: doc/classes/SceneTree.xml
@@ -67829,11 +68268,12 @@ msgid ""
"and for manual [Mutex] protection when accessing the [MultiplayerAPI] from "
"threads."
msgstr ""
-"如果 [code]true[/code](默认值),则在 [signal idle_frame] 期间å¯ç”¨æ­¤ "
+"如果为 [code]true[/code](默认值),则在 [signal idle_frame] 期间å¯ç”¨æ­¤ "
"SceneTree 的 [MultiplayerAPI] 自动轮询。\n"
-"如果[code]false[/code]ï¼Œåˆ™éœ€è¦æ‰‹åŠ¨è°ƒç”¨[method MultiplayerAPI.poll]æ¥å¤„ç†ç½‘络"
-"æ•°æ®åŒ…并投递RPCs/RSETs。这å…许在ä¸åŒçš„循环(例如物ç†ã€çº¿ç¨‹ã€ç‰¹å®šæ—¶é—´æ­¥é•¿ï¼‰ä¸­"
-"è¿è¡Œ RPC/RSET,并在从线程访问 [MultiplayerAPI] 时进行手动 [Mutex] ä¿æŠ¤ã€‚"
+"如果为 [code]false[/code]ï¼Œåˆ™éœ€è¦æ‰‹åŠ¨è°ƒç”¨ [method MultiplayerAPI.poll] æ¥å¤„ç†"
+"网络数æ®åŒ…并投递 RPC/RSET。这样就能够在ä¸åŒçš„循环(例如物ç†ã€çº¿ç¨‹ã€ç‰¹å®šæ—¶é—´æ­¥"
+"长)中è¿è¡Œ RPC/RSET,并在从线程访问 [MultiplayerAPI] 时进行手动 [Mutex] ä¿"
+"护。"
#: doc/classes/SceneTree.xml
msgid ""
@@ -67845,11 +68285,11 @@ msgid ""
"by default. Handling of networking-related events (connection, "
"disconnection, new clients) is done by connecting to [SceneTree]'s signals."
msgstr ""
-"å¤„ç† RPC ç³»ç»Ÿçš„å¯¹ç­‰å¯¹è±¡ï¼ˆè®¾ç½®åŽæœ‰æ•ˆåœ°å¯ç”¨ç½‘络)。根æ®peer本身的ä¸åŒï¼Œ"
-"[SceneTree]å°†æˆä¸ºç½‘络æœåŠ¡å™¨ï¼ˆæ£€æŸ¥[method is_network_server])并将根节点的网络"
-"模å¼è®¾ç½®ä¸ºmaster,或者它将æˆä¸ºæ ¹èŠ‚ç‚¹è¢«è®¾ç½®ä¸ºpuppet的普通对等体。所有å­èŠ‚ç‚¹é»˜"
-"认设置为继承网络模å¼ã€‚ä¸Žç½‘ç»œç›¸å…³çš„äº‹ä»¶ï¼ˆè¿žæŽ¥ã€æ–­å¼€è¿žæŽ¥ã€æ–°å®¢æˆ·ç«¯ï¼‰çš„å¤„ç†æ˜¯é€š"
-"过连接到 [SceneTree] çš„ä¿¡å·æ¥å®Œæˆçš„。"
+"å¤„ç† RPC ç³»ç»Ÿçš„å¯¹ç­‰å¯¹è±¡ï¼ˆè®¾ç½®åŽæœ‰æ•ˆåœ°å¯ç”¨ç½‘络)。根æ®å¯¹ç­‰ä½“本身的ä¸åŒï¼Œ"
+"[SceneTree] å°†æˆä¸ºç½‘络æœåŠ¡å™¨ï¼ˆæ£€æŸ¥ [method is_network_server])并将根节点的网"
+"络模å¼è®¾ç½®ä¸º master,或者它将æˆä¸ºæ ¹èŠ‚ç‚¹è¢«è®¾ç½®ä¸º puppet 的普通对等体。所有å­èŠ‚"
+"点默认设置为继承网络模å¼ã€‚ä¸Žç½‘ç»œç›¸å…³çš„äº‹ä»¶ï¼ˆè¿žæŽ¥ã€æ–­å¼€è¿žæŽ¥ã€æ–°å®¢æˆ·ç«¯ï¼‰çš„处ç†"
+"是通过连接到 [SceneTree] çš„ä¿¡å·æ¥å®Œæˆçš„。"
#: doc/classes/SceneTree.xml
msgid ""
@@ -67860,9 +68300,9 @@ msgid ""
"- [method Node._process], [method Node._physics_process] and [method Node."
"_input] will not be called anymore in nodes."
msgstr ""
-"如果[code]true[/code],[SceneTree]会暂åœã€‚这样åšä¼šæœ‰ä»¥ä¸‹è¡Œä¸º:\n"
-"- 2Då’Œ3D物ç†å°†åœæ­¢ã€‚这包括信å·å’Œç¢°æ’žæ£€æµ‹ã€‚\n"
-"- 节点ä¸å†è°ƒç”¨[method Node._process]ã€[method Node._physics_process]å’Œ"
+"如果为 [code]true[/code],[SceneTree] 会暂åœã€‚这样åšä¼šæœ‰ä»¥ä¸‹è¡Œä¸ºï¼š\n"
+"- 2D å’Œ 3D 物ç†å°†åœæ­¢ï¼ŒåŒ…括信å·å’Œç¢°æ’žæ£€æµ‹ã€‚\n"
+"- 节点ä¸å†è°ƒç”¨ [method Node._process]ã€[method Node._physics_process] å’Œ "
"[method Node._input]。"
#: doc/classes/SceneTree.xml
@@ -67890,8 +68330,8 @@ msgid ""
"If [code]true[/code], the [SceneTree]'s [member network_peer] refuses new "
"incoming connections."
msgstr ""
-"如果 [code]true[/code],则 [SceneTree] çš„ [member network_peer] æ‹’ç»æ–°çš„ä¼ å…¥"
-"连接。"
+"如果为 [code]true[/code],则 [SceneTree] çš„ [member network_peer] æ‹’ç»æ–°çš„ä¼ "
+"入连接。"
#: doc/classes/SceneTree.xml
msgid "The [SceneTree]'s root [Viewport]."
@@ -67927,16 +68367,16 @@ msgid ""
"Emitted whenever this [SceneTree]'s [member network_peer] successfully "
"connected to a server. Only emitted on clients."
msgstr ""
-"当这个[SceneTree]çš„[member network_peer]æˆåŠŸè¿žæŽ¥åˆ°ä¸€ä¸ªæœåŠ¡å™¨æ—¶å‘出。åªåœ¨å®¢æˆ·"
-"端å‘出。"
+"æ¯å½“这个 [SceneTree] çš„ [member network_peer] æˆåŠŸè¿žæŽ¥åˆ°æœåŠ¡å™¨æ—¶å‘出。åªä¼šåœ¨"
+"客户端å‘出。"
#: doc/classes/SceneTree.xml
msgid ""
"Emitted whenever this [SceneTree]'s [member network_peer] fails to establish "
"a connection to a server. Only emitted on clients."
msgstr ""
-"æ¯å½“æ­¤ [SceneTree] çš„ [member network_peer] 无法与æœåŠ¡å™¨å»ºç«‹è¿žæŽ¥æ—¶å‘出。仅在"
-"客户端上å‘出。"
+"æ¯å½“这个 [SceneTree] çš„ [member network_peer] 无法建立与æœåŠ¡å™¨çš„è¿žæŽ¥æ—¶å‘出。"
+"åªä¼šåœ¨å®¢æˆ·ç«¯å‘出。"
#: doc/classes/SceneTree.xml
msgid ""
@@ -67955,7 +68395,8 @@ msgstr "æ¯å½“å•击全局èœå•项时触å‘。"
msgid ""
"Emitted immediately before [method Node._process] is called on every node in "
"the [SceneTree]."
-msgstr "在对[SceneTree]中的æ¯ä¸ªèŠ‚ç‚¹è°ƒç”¨[method Node._process]之å‰ç«‹å³å‘出。"
+msgstr ""
+"在对 [SceneTree] 中的æ¯ä¸ªèŠ‚ç‚¹è°ƒç”¨ [method Node._process] 之å‰ç«‹å³å‘出。"
#: doc/classes/SceneTree.xml
msgid ""
@@ -67964,9 +68405,9 @@ msgid ""
"clients connect to the same server. Upon connecting to a server, a client "
"also receives this signal for the server (with ID being 1)."
msgstr ""
-"当这个[SceneTree]çš„[member network_peer]与一个新的对等体连接时å‘出。ID是新对"
-"等体的对等体ID。当其他客户端连接到åŒä¸€ä¸ªæœåŠ¡å™¨æ—¶ï¼Œå®¢æˆ·ç«¯ä¼šå¾—åˆ°é€šçŸ¥ã€‚å½“è¿žæŽ¥åˆ°"
-"一个æœåŠ¡å™¨æ—¶ï¼Œå®¢æˆ·ç«¯ä¹Ÿä¼šæ”¶åˆ°è¯¥æœåŠ¡å™¨çš„è¿™ä¸ªä¿¡å·ï¼ˆID为1)。"
+"æ¯å½“这个 [SceneTree] çš„ [member network_peer] 连上一个新的对等体时å‘出。ID 是"
+"新对等体的对等体 ID。当有其他客户端连接到åŒä¸€ä¸ªæœåŠ¡å™¨æ—¶ï¼Œå®¢æˆ·ç«¯ä¼šå¾—åˆ°é€šçŸ¥ã€‚å½“"
+"连接到æœåŠ¡å™¨æ—¶ï¼Œå®¢æˆ·ç«¯ä¹Ÿä¼šæ”¶åˆ°é’ˆå¯¹è¯¥æœåŠ¡å™¨çš„è¿™ä¸ªä¿¡å·ï¼ˆID 为 1)。"
#: doc/classes/SceneTree.xml
msgid ""
@@ -67974,8 +68415,8 @@ msgid ""
"peer. Clients get notified when other clients disconnect from the same "
"server."
msgstr ""
-"æ¯å½“æ­¤ [SceneTree] çš„ [member network_peer] 与对等方断开连接时å‘出。当其他客"
-"户端与åŒä¸€æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥æ—¶ï¼Œå®¢æˆ·ç«¯ä¼šæ”¶åˆ°é€šçŸ¥ã€‚"
+"æ¯å½“这个 [SceneTree] çš„ [member network_peer] 断开与对等体的连接时å‘出。当其"
+"他客户端与åŒä¸€æœåŠ¡å™¨æ–­å¼€è¿žæŽ¥æ—¶ï¼Œå®¢æˆ·ç«¯ä¼šæ”¶åˆ°é€šçŸ¥ã€‚"
#: doc/classes/SceneTree.xml
msgid "Emitted whenever a node is added to the [SceneTree]."
@@ -68025,23 +68466,23 @@ msgstr "当 [SceneTree] 层次结构å‘生å˜åŒ–(移动或é‡å‘½åå­é¡¹ç­‰ï¼
#: doc/classes/SceneTree.xml
msgid "Call a group with no flags (default)."
-msgstr "调用没有标志的组(默认)。"
+msgstr "对组进行调用时,ä¸ä½¿ç”¨æ ‡å¿—(默认)。"
#: doc/classes/SceneTree.xml
msgid "Call a group in reverse scene order."
-msgstr "以相å的场景顺åºè°ƒç”¨ç»„。"
+msgstr "对组进行调用时,使用逆场景åºã€‚"
#: doc/classes/SceneTree.xml
msgid "Call a group immediately (calls are normally made on idle)."
-msgstr "ç«‹å³è°ƒç”¨ä¸€ä¸ªç»„(调用通常在空闲时进行)。"
+msgstr "å¯¹ç»„è¿›è¡Œè°ƒç”¨æ—¶ï¼Œç«‹å³æ‰§è¡Œï¼ˆæ­£å¸¸æƒ…况下是在空闲时调用的)。"
#: doc/classes/SceneTree.xml
msgid "Call a group only once even if the call is executed many times."
-msgstr "å³ä½¿è°ƒç”¨å¤šæ¬¡æ‰§è¡Œï¼Œä¹Ÿåªè°ƒç”¨ä¸€æ¬¡ç»„。"
+msgstr "对组进行调用时,å³ä¾¿æ‰§è¡Œäº†å¤šæ¬¡è°ƒç”¨ä¹Ÿåªè°ƒç”¨ä¸€æ¬¡ã€‚"
#: doc/classes/SceneTree.xml
msgid "No stretching."
-msgstr "未拉伸。"
+msgstr "䏿‹‰ä¼¸ã€‚"
#: doc/classes/SceneTree.xml
msgid "Render stretching in higher resolution (interpolated)."
@@ -68051,7 +68492,7 @@ msgstr "以更高的分辨率渲染拉伸(æ’值)。"
msgid ""
"Keep the specified display resolution. No interpolation. Content may appear "
"pixelated."
-msgstr "ä¿æŒæŒ‡å®šçš„æ˜¾ç¤ºåˆ†è¾¨çŽ‡ã€‚æ²¡æœ‰æ’值。内容å¯èƒ½ä¼šå‡ºçްåƒç´ åŒ–。"
+msgstr "ä¿æŒæŒ‡å®šçš„æ˜¾ç¤ºåˆ†è¾¨çŽ‡ã€‚ä¸åšæ’值。内容å¯èƒ½ä¼šå‡ºçްåƒç´ åŒ–。"
#: doc/classes/SceneTree.xml
msgid ""
@@ -68069,13 +68510,13 @@ msgstr "在任æ„轴上用黑æ¡å¡«å……æ¥ä¿æŒç›¸åŒçš„长宽比。这å¯ä»¥é˜²
msgid ""
"Expand vertically. Left/right black bars may appear if the window is too "
"wide."
-msgstr "垂直展开。如果窗å£å¤ªå®½ï¼Œå¯èƒ½ä¼šå‡ºçް左/å³é»‘æ¡ã€‚"
+msgstr "垂直扩展。如果窗å£å¤ªå®½ï¼Œå¯èƒ½ä¼šå‡ºçް左/å³é»‘æ¡ã€‚"
#: doc/classes/SceneTree.xml
msgid ""
"Expand horizontally. Top/bottom black bars may appear if the window is too "
"tall."
-msgstr "水平展开。如果窗å£å¤ªé«˜ï¼Œå¯èƒ½ä¼šå‡ºçŽ°é¡¶éƒ¨/底部黑æ¡ã€‚"
+msgstr "水平扩展。如果窗å£å¤ªé«˜ï¼Œå¯èƒ½ä¼šå‡ºçŽ°é¡¶éƒ¨/底部黑æ¡ã€‚"
#: doc/classes/SceneTree.xml
msgid ""
@@ -68102,9 +68543,9 @@ msgid ""
"The timer will be dereferenced after its time elapses. To preserve the "
"timer, you can keep a reference to it. See [Reference]."
msgstr ""
-"由场景树管ç†çš„ä¸€æ¬¡æ€§å®šæ—¶å™¨ï¼Œå®ƒåœ¨å®Œæˆæ—¶å‘[signal timeout] ä¿¡å·ã€‚请å‚阅 "
+"由场景树管ç†çš„ä¸€æ¬¡æ€§å®šæ—¶å™¨ï¼Œå®ƒåœ¨å®Œæˆæ—¶å‘ [signal timeout] ä¿¡å·ã€‚å¦è¯·å‚阅 "
"[method SceneTree.create_timer]。\n"
-"与 [Timer] 相å,它ä¸éœ€è¦å®žä¾‹åŒ–节点。常用于创建一次性的延迟定时器,如下é¢çš„例"
+"与 [Timer] ä¸åŒï¼Œå®ƒä¸éœ€è¦å®žä¾‹åŒ–节点。常用于创建一次性的延迟定时器,如下é¢çš„例"
"å­ï¼š\n"
"[codeblock]\n"
"func some_function():\n"
@@ -68144,24 +68585,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -68170,8 +68610,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -68179,16 +68620,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -68200,7 +68641,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
"[SceneTreeTween] 是由场景树管ç†çš„补间动画。与 [Tween] 相对,ä¸éœ€è¦å®žä¾‹åŒ–节"
"点。\n"
@@ -68211,21 +68652,21 @@ msgstr ""
"建 [SceneTreeTween]。手动创建的 [SceneTreeTween](å³ä½¿ç”¨ [code]Tween.new()[/"
"code])是无效的,ä¸èƒ½ç”¨äºŽå¯¹å€¼è¿›è¡Œè¡¥é—´ï¼Œä½†ä½ å¯ä»¥ç”¨ [method interpolate_value] "
"æ¥æ‰‹åЍæ’值。\n"
-"[SceneTreeTween] 动画是由 [Tweener] åºåˆ—æž„æˆçš„,默认串行执行。å‘该 "
-"[SceneTreeTween] 追加 [Tweener] å³å¯åˆ›å»ºåºåˆ—。使用 [Tweener] æ¥åšåŠ¨ç”»å°±å«åšè¡¥"
-"间(Tweening)。示例补间åºåˆ—是类似这样的:\n"
+"è¡¥é—´åŠ¨ç”»æ˜¯é€šè¿‡å‘ [SceneTreeTween] 对象中添加 [Tweener] 创建的,添加的方法有 "
+"[method tween_property]ã€[method tween_interval]ã€[method tween_callback]ã€"
+"[method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"这个åºåˆ—会让 [code]$Sprite[/code] å˜çº¢ï¼Œç„¶åŽç¼©å°ï¼Œæœ€åŽè°ƒç”¨ [method Node."
-"queue_free] æ¥ç§»é™¤ç²¾çµã€‚更多用法信æ¯è¯·å‚阅 [method tween_property]ã€[method "
-"tween_interval]ã€[method tween_callback]ã€[method tween_method] 方法。\n"
+"这个åºåˆ—会让 [code]$Sprite[/code] å˜çº¢ï¼Œç„¶åŽç¼©å°ï¼Œæœ€åŽå†è°ƒç”¨ [method Node."
+"queue_free] æ¥é‡Šæ”¾è¯¥ç²¾çµã€‚[Tweener] 默认是一个接一个执行的。这个行为å¯ä»¥é€šè¿‡ "
+"[method parallel] 和 [method set_parallel] 更改。\n"
"使用 [code]tween_*[/code] 方法创建 [Tweener] åŽï¼Œå¯ä»¥ä½¿ç”¨é“¾å¼æ–¹æ³•调用æ¥è°ƒæ•´"
"该 [Tweener] 的属性。例如,如果你想è¦åœ¨ä¸Šé¢çš„例å­ä¸­è®¾ç½®ä¸åŒçš„过渡类型,那么你"
-"å¯ä»¥ï¼š\n"
+"å¯ä»¥ä½¿ç”¨ [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -68234,8 +68675,9 @@ msgstr ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"[SceneTreeTween] 的大部分方法都å¯ä»¥ç”¨è¿™ç§æ–¹æ³•进行链å¼è°ƒç”¨ã€‚在这个示例中,我们"
-"对该 [SceneTreeTween] 进行了绑定,并设置了默认的过渡:\n"
+"[SceneTreeTween] 的大部分方法都å¯ä»¥ç”¨è¿™ç§æ–¹æ³•进行链å¼è°ƒç”¨ã€‚在下é¢çš„示例中,我"
+"们将该 [SceneTreeTween] 绑定到了执行脚本的节点,并为其 [Tweener] 设置了默认的"
+"过渡:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -68247,7 +68689,7 @@ msgstr ""
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"上é¢çš„示例中,该节点的所有å­èŠ‚ç‚¹éƒ½ä¼šä¾æ¬¡è¢«ç§»åŠ¨åˆ° (0, 0)。\n"
"一些 [Tweener] 会用到过渡和缓动。å‰è€…æŽ¥å— [enum Tween.TransitionType] 常é‡ï¼Œ"
@@ -68302,28 +68744,32 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
"使用给定的增é‡ç§’æ•° [code]delta[/code] 处ç†è¯¥ [SceneTreeTween]。最常è§çš„用法是"
"在该 [SceneTreeTween] æš‚åœæ—¶å¯¹å…¶è¿›è¡Œæ‰‹åŠ¨æŽ§åˆ¶ã€‚ä¹Ÿå¯ç”¨äºŽç«‹å³åœæ­¢è¯¥ "
-"[SceneTreeTween] 的动画,使用比完整长度更大的 [code]delta[/code] å³å¯ã€‚\n"
+"[SceneTreeTween] 的动画,将 [code]delta[/code] 设得比完整长度更大å³å¯ã€‚\n"
"如果该 [SceneTreeTween] ä»ç„¶æœ‰æœªå®Œæˆçš„ [Tweener],则返回 [code]true[/"
"code]。\n"
-"[b]注æ„:[/b]该 [SceneTreeTween] 在完æˆåŽä¼šå¤±æ•ˆï¼Œä½†ä½ å¯ä»¥åœ¨ step åŽè°ƒç”¨ "
-"[method stop] 将其ä¿ç•™å¹¶é‡ç½®ã€‚"
+"[b]注æ„:[/b]该 [SceneTreeTween] 完æˆåŠ¨ç”»åŽï¼Œä¼šåœ¨ä¸‹ä¸€ä¸ªå¤„ç†å¸§ä¸­å¤±æ•ˆã€‚ä½ å¯ä»¥åœ¨"
+"执行 [method custom_step] åŽè°ƒç”¨ [method stop] 将该 [SceneTreeTween] ä¿ç•™å¹¶é‡"
+"置。"
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -68372,20 +68818,21 @@ msgid ""
msgstr "返回该 [SceneTreeTween] ç›®å‰æ˜¯å¦æ­£åœ¨æ‰§è¡Œï¼Œå³æœªæš‚åœä¸”未完æˆã€‚"
#: doc/classes/SceneTreeTween.xml
+#, fuzzy
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
"返回该 [SceneTreeTween] æ˜¯å¦æœ‰æ•ˆã€‚有效的 [SceneTreeTween] 是由场景树包å«çš„ "
"[SceneTreeTween]ï¼ˆå³ [method SceneTree.get_processed_tweens] 返回的数组中包å«"
"这个 [SceneTreeTween])。[SceneTreeTween] 失效的情况有:补间完æˆã€è¢«é”€æ¯ã€ä½¿"
-"用 [code]Tween.new()[/code] 创建。无效的 [SceneTreeTween] ä¸èƒ½è¿½åŠ  "
-"[Tweener],因为无法进行动画。ä¸è¿‡ [method interpolate_value] 还是å¯ä»¥ä½¿ç”¨çš„。"
+"用 [code]SceneTreeTween.new()[/code] 创建。无效的 [SceneTreeTween] ä¸èƒ½è¿½åŠ  "
+"[Tweener]。"
#: doc/classes/SceneTreeTween.xml
msgid "Aborts all tweening operations and invalidates the [SceneTreeTween]."
@@ -68432,28 +68879,29 @@ msgstr ""
"的默认缓动类型。"
#: doc/classes/SceneTreeTween.xml
+#, fuzzy
msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
"è¿™åªè¯¥è¡¥é—´åºåˆ—çš„é‡å¤æ¬¡æ•°ï¼Œå³ [code]set_loops(2)[/code] 会让动画执行两次。\n"
"调用这个方法时如果ä¸å¸¦å‚数,那么该 [SceneTreeTween] ä¼šæ— é™æ‰§è¡Œï¼Œç›´åˆ°è¢« "
-"[method kill] 销æ¯ã€ç»‘å®šèŠ‚ç‚¹è¢«é‡Šæ”¾ã€æˆ–者所有进行动画的对象都被释放(无法å†è¿›"
-"行任何动画)。\n"
-"[b]警告:[/b]使用无é™å¾ªçŽ¯æ—¶è¯·ä¸€å®šè¦åŠ å…¥ä¸€äº›æ—¶é•¿/延迟。0 时长的循环动画(例如"
-"å•个ä¸å¸¦å»¶è¿Ÿçš„ [CallbackTweener] 或者节点无效的 [PropertyTweener]ï¼‰å’Œæ— é™ "
-"[code]while[/code] 循环是一样的,会导致游æˆå†»ç»“。如果 [SceneTreeTween] 的生命"
-"期ä¾èµ–于æŸä¸ªèŠ‚ç‚¹ï¼Œè¯·ä¸€å®šä½¿ç”¨ [method bind_node]。"
+"[method kill] 销æ¯ã€è¯¥ [SceneTreeTween] ç»‘å®šçš„èŠ‚ç‚¹è¢«é‡Šæ”¾ã€æˆ–者所有进行动画的"
+"对象都被释放(无法å†è¿›è¡Œä»»ä½•动画)。\n"
+"[b]警告:[/b]使用无é™å¾ªçŽ¯æ—¶è¯·ä¸€å®šè¦åŠ å…¥ä¸€äº›æ—¶é•¿/延迟。为了防止游æˆå†»ç»“,0 æ—¶"
+"长的循环动画(例如å•个ä¸å¸¦å»¶è¿Ÿçš„ [CallbackTweener])会在循环若干次åŽåœæ­¢ï¼Œé€ "
+"æˆå‡ºä¹Žé¢„料的结果。如果 [SceneTreeTween] 的生命期ä¾èµ–于æŸä¸ªèŠ‚ç‚¹ï¼Œè¯·ä¸€å®šä½¿ç”¨ "
+"[method bind_node]。"
#: doc/classes/SceneTreeTween.xml
msgid ""
@@ -68539,10 +68987,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -68637,8 +69085,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -68666,7 +69114,7 @@ msgstr ""
"创建并追加一个 [PropertyTweener]。这个方法会将 [code]object[/code] 对象的 "
"[code]property[/code] 属性在åˆå§‹å€¼å’Œæœ€ç»ˆå€¼ [code]final_val[/code] 之间进行补"
"间,æŒç»­æ—¶é—´ä¸º [code]duration[/code] 秒。åˆå§‹å€¼é»˜è®¤ä¸ºè¯¥ [PropertyTweener] å¯"
-"动时的值。例如:\n"
+"动时该属性的值。例如:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -68692,21 +69140,20 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
"在该 [SceneTreeTween] å®Œæˆæ‰€æœ‰è¡¥é—´æ—¶è§¦å‘。该 [SceneTreeTween] 被设为无é™å¾ªçޝ"
"æ—¶ä¸ä¼šè§¦å‘ï¼ˆè§ [method set_loops])。\n"
-"[b]注æ„:[/b]触å‘这个信å·åŽï¼Œè¯¥ [SceneTreeTween] ä¼šè¢«ç§»é™¤ï¼ˆç½®ä¸ºæ— æ•ˆï¼‰ï¼Œä½†ä¸æ˜¯"
-"ç«‹å³å‘生的,而是在下一个处ç†å¸§ä¸­å‘生。在该信å·çš„回调中调用 [method stop] 会ä¿"
-"留该 [SceneTreeTween]。"
+"[b]注æ„:[/b]触å‘这个信å·åŽï¼Œè¯¥ [SceneTreeTween] 会在下一个处ç†å¸§ä¸­è¢«ç§»é™¤ï¼ˆç½®"
+"为无效)。在该信å·çš„回调中调用 [method stop] å¯ä»¥é˜²æ­¢è¯¥ [SceneTreeTween] 被移"
+"除。"
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
"完æˆä¸€æ¬¡å¾ªçŽ¯æ—¶è§¦å‘ï¼ˆè§ [method set_loops]),会æä¾›è¯¥å¾ªçŽ¯çš„ç´¢å¼•å·ã€‚这个信å·ä¸"
@@ -68716,7 +69163,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
"完æˆè¯¥ [SceneTreeTween] 的一步完æˆåŽè§¦å‘,会æä¾›è¿™ä¸€æ­¥çš„索引å·ã€‚一步指的是å•"
"个 [Tweener] 或一组并行执行的 [Tweener]。"
@@ -68845,9 +69292,9 @@ msgstr ""
"调用 [method Popup.popup] 方法之å‰é…置其字段。\n"
"[codeblock]\n"
"func _ready():\n"
-" dialog.config(\"Node\", \"res://new_node.gd\") # For in-engine types\n"
+" dialog.config(\"Node\", \"res://new_node.gd\") # 引擎内置类型\n"
" dialog.config(\"\\\"res://base_node.gd\\\"\", \"res://derived_node.gd\") "
-"# For script types\n"
+"# 脚本类型\n"
" dialog.popup_centered()\n"
"[/codeblock]"
@@ -68857,19 +69304,19 @@ msgstr "预填必填字段以é…ç½® ScriptCreateDialog 以供使用。"
#: doc/classes/ScriptCreateDialog.xml
msgid "Emitted when the user clicks the OK button."
-msgstr "当用户点击OK按钮时å‘出。"
+msgstr "当用户点击确定按钮时å‘出。"
#: doc/classes/ScriptEditor.xml
msgid "Godot editor's script editor."
-msgstr "Godot编辑器的脚本编辑器。"
+msgstr "Godot 编辑器的脚本编辑器。"
#: doc/classes/ScriptEditor.xml
msgid ""
"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
"the singleton using [method EditorInterface.get_script_editor]."
msgstr ""
-"[b]注æ„:[/b]这个类ä¸åº”该被直接实例化。相å,使用[method EditorInterface."
-"get_script_editor]æ¥è®¿é—®è¿™ä¸ªå•例。"
+"[b]注æ„:[/b]这个类ä¸åº”该被直接实例化。相å,使用 [method EditorInterface."
+"get_script_editor] æ¥è®¿é—®è¿™ä¸ªå•例。"
#: doc/classes/ScriptEditor.xml
msgid "Returns a [Script] that is currently active in editor."
@@ -68891,8 +69338,8 @@ msgid ""
"code]. The file extension can be omitted from [code]base_path[/code]. It "
"will be added based on the selected scripting language."
msgstr ""
-"æ‰“å¼€åˆ›å»ºè„šæœ¬çš„å¯¹è¯æ¡†ã€‚脚本将扩展[code]base_name[/code]。文件扩展åå¯ä»¥ä»Ž"
-"[code]base_path[/code]中çœç•¥ã€‚å®ƒå°†æ ¹æ®æ‰€é€‰æ‹©çš„脚本语言添加。"
+"æ‰“å¼€åˆ›å»ºè„šæœ¬çš„å¯¹è¯æ¡†ã€‚脚本将扩展 [code]base_name[/code]。文件扩展åå¯ä»¥ä»Ž "
+"[code]base_path[/code] 中çœç•¥ã€‚å®ƒå°†æ ¹æ®æ‰€é€‰æ‹©çš„脚本语言添加。"
#: doc/classes/ScriptEditor.xml
msgid ""
@@ -68922,8 +69369,8 @@ msgid ""
"size of the page). Horizontal ([HScrollBar]) and Vertical ([VScrollBar]) "
"versions are available."
msgstr ""
-"æ»šåŠ¨æ¡æ˜¯åŸºäºŽ [Range] çš„ [Control]ï¼Œæ˜¾ç¤ºå¯æ‹–动区域(页é¢å¤§å°ï¼‰ã€‚æä¾›æ°´å¹³ "
-"([HScrollBar]) 和垂直 ([VScrollBar]) 版本。"
+"æ»šåŠ¨æ¡æ˜¯åŸºäºŽ [Range] çš„ [Control]ï¼Œæ˜¾ç¤ºå¯æ‹–动区域(页é¢å¤§å°ï¼‰ã€‚æä¾›æ°´å¹³"
+"([HScrollBar])和垂直([VScrollBar])版本。"
#: doc/classes/ScrollBar.xml
msgid ""
@@ -68954,13 +69401,13 @@ msgid ""
"they will upscale to the ScrollContainer's size if it's larger (scroll is "
"invisible for the chosen dimension)."
msgstr ""
-"æ»šåŠ¨å®¹å™¨èŠ‚ç‚¹ï¼Œç”¨äºŽåŒ…å« [Control] å­èŠ‚ç‚¹ã€‚ æ»šåŠ¨å®¹å™¨å°†åœ¨éœ€è¦æ—¶è‡ªåŠ¨åˆ›å»ºæ»šåŠ¨æ¡å­"
-"项([HScrollBar]ã€[VScrollBar] 或两者),且仅在滚动容器区域内绘制控件。滚动æ¡"
-"将自动绘制在å³ä¾§æˆ–底部,å³åž‚直或水平,并å…许拖动以在滚动容器内移动å¯è§†æŽ§ä»¶åŠ"
-"å…¶å­é¡¹ã€‚滚动æ¡è¿˜å°†æ ¹æ®æŽ§ä»¶ç›¸å¯¹äºŽæ»šåŠ¨å®¹å™¨çš„ [member Control.rect_min_size] 自"
-"动调整抓å–器的大å°ã€‚与 [Panel] 控件é…åˆä½¿ç”¨æ•ˆæžœå¾ˆå¥½ã€‚您å¯ä»¥å°†å­é¡¹çš„大尿 ‡å¿—设"
-"置为 [code]EXPAND[/code]ï¼Œå½“æ»šåŠ¨å®¹å™¨çš„å¤§å°æ›´å¤§ï¼ˆæ»šåŠ¨å¯¹äºŽæ‰€é€‰ç»´åº¦ä¸å¯è§ï¼‰ï¼Œå®ƒ"
-"们将放大到滚动容器的大å°ã€‚"
+"æ»šåŠ¨å®¹å™¨èŠ‚ç‚¹ï¼Œç”¨äºŽåŒ…å« [Control] å­èŠ‚ç‚¹ã€‚æ»šåŠ¨å®¹å™¨å°†åœ¨éœ€è¦æ—¶è‡ªåŠ¨åˆ›å»ºæ»šåŠ¨æ¡å­é¡¹"
+"([HScrollBar]ã€[VScrollBar] 或两者),且仅在滚动容器区域内绘制控件。滚动æ¡å°†"
+"自动绘制在å³ä¾§æˆ–底部,å³åž‚直或水平,并å…许拖动以在滚动容器内移动å¯è§†æŽ§ä»¶åŠå…¶"
+"å­é¡¹ã€‚滚动æ¡è¿˜å°†æ ¹æ®æŽ§ä»¶ç›¸å¯¹äºŽæ»šåŠ¨å®¹å™¨çš„ [member Control.rect_min_size] 自动"
+"调整抓å–器的大å°ã€‚与 [Panel] 控件é…åˆä½¿ç”¨æ•ˆæžœå¾ˆå¥½ã€‚您å¯ä»¥å°†å­é¡¹çš„大尿 ‡å¿—设置"
+"为 [code]EXPAND[/code]ï¼Œå½“æ»šåŠ¨å®¹å™¨çš„å¤§å°æ›´å¤§ï¼ˆæ»šåŠ¨å¯¹äºŽæ‰€é€‰ç»´åº¦ä¸å¯è§ï¼‰ï¼Œå®ƒä»¬"
+"将放大到滚动容器的大å°ã€‚"
#: doc/classes/ScrollContainer.xml
msgid ""
@@ -69017,8 +69464,8 @@ msgid ""
"focused children (including indirect children) to make sure they are fully "
"visible."
msgstr ""
-"如果 [code]true[/code],则 ScrollContainer 将自动滚动到获得焦点的å­é¡¹ï¼ˆåŒ…括间"
-"接å­é¡¹ï¼‰ä»¥ç¡®ä¿å®ƒä»¬å®Œå…¨å¯è§ã€‚"
+"如果为 [code]true[/code],则 ScrollContainer 将自动滚动到获得焦点的å­é¡¹ï¼ˆåŒ…括"
+"间接å­é¡¹ï¼‰ä»¥ç¡®ä¿å®ƒä»¬å®Œå…¨å¯è§ã€‚"
#: doc/classes/ScrollContainer.xml
msgid "The current horizontal scroll value."
@@ -69026,7 +69473,7 @@ msgstr "当剿°´å¹³æ»šåŠ¨å€¼ã€‚"
#: doc/classes/ScrollContainer.xml
msgid "If [code]true[/code], enables horizontal scrolling."
-msgstr "如果 [code]true[/code],å¯ç”¨æ°´å¹³æ»šåŠ¨ã€‚"
+msgstr "如果为 [code]true[/code],å¯ç”¨æ°´å¹³æ»šåŠ¨ã€‚"
#: doc/classes/ScrollContainer.xml
msgid "The current vertical scroll value."
@@ -69034,7 +69481,7 @@ msgstr "当å‰åž‚直滚动值。"
#: doc/classes/ScrollContainer.xml
msgid "If [code]true[/code], enables vertical scrolling."
-msgstr "如果 [code]true[/code],则å¯ç”¨åž‚直滚动。"
+msgstr "如果为 [code]true[/code],则å¯ç”¨åž‚直滚动。"
#: doc/classes/ScrollContainer.xml
msgid "Emitted when scrolling stops."
@@ -69056,7 +69503,7 @@ msgstr "2D 碰撞的分段形状。"
msgid ""
"Segment shape for 2D collisions. Consists of two points, [code]a[/code] and "
"[code]b[/code]."
-msgstr "2D 碰撞的分段形状。由[code]a[/code] å’Œ [code]b[/code]两点组æˆã€‚"
+msgstr "2D 碰撞的分段形状。由 [code]a[/code] å’Œ [code]b[/code] 两点组æˆã€‚"
#: doc/classes/SegmentShape2D.xml
msgid "The segment's first point position."
@@ -69160,8 +69607,8 @@ msgid ""
"[b]Note:[/b] [code]param[/code] must match the name of the uniform in the "
"code exactly."
msgstr ""
-"如果ç€è‰²å™¨åœ¨å…¶ä»£ç ä¸­æŠŠè¿™ä¸ªå‚数定义为uniform,则返回 [code]true[/code]。\n"
-"[b]注æ„:[/b][code]param[/code] 必须与代ç ä¸­çš„uniformå称完全匹é…。"
+"如果ç€è‰²å™¨åœ¨å…¶ä»£ç ä¸­æŠŠè¿™ä¸ªå‚数定义为 uniform,则返回 [code]true[/code]。\n"
+"[b]注æ„:[/b][code]param[/code] 必须与代ç ä¸­çš„ uniform å称完全匹é…。"
#: doc/classes/Shader.xml
msgid ""
@@ -69188,9 +69635,9 @@ msgid ""
"[b]Note:[/b] Custom defines are not validated by the Godot shader parser, so "
"care should be taken when using them."
msgstr ""
-"返回该ç€è‰²å™¨çš„自定义。自定义å¯ä»¥åœ¨Godot中用于添加ç€è‰²å™¨é€»è¾‘所需的GLSLé¢„å¤„ç†æŒ‡"
-"令(例如:扩展)。\n"
-"[b]注æ„:[/b]自定义没有ç»è¿‡Godotç€è‰²å™¨è§£æžå™¨çš„验è¯ï¼Œæ‰€ä»¥ä½¿ç”¨æ—¶è¦æ³¨æ„。"
+"返回该ç€è‰²å™¨çš„自定义。自定义å¯ä»¥åœ¨ Godot 中用于添加ç€è‰²å™¨é€»è¾‘所需的 GLSL 预处"
+"ç†æŒ‡ä»¤ï¼ˆä¾‹å¦‚:扩展)。\n"
+"[b]注æ„:[/b]自定义没有ç»è¿‡ Godot ç€è‰²å™¨è§£æžå™¨çš„验è¯ï¼Œæ‰€ä»¥ä½¿ç”¨æ—¶è¦æ³¨æ„。"
#: doc/classes/Shader.xml
msgid "Mode used to draw all 3D objects."
@@ -69228,14 +69675,15 @@ msgstr ""
#: doc/classes/ShaderMaterial.xml
msgid ""
"Returns the current value set for this material of a uniform in the shader."
-msgstr "返回在ç€è‰²å™¨ä¸­æ­¤uniformæè´¨çš„当å‰å€¼ã€‚"
+msgstr "返回在ç€è‰²å™¨ä¸­æ­¤ uniform æè´¨çš„当å‰å€¼ã€‚"
#: doc/classes/ShaderMaterial.xml
msgid ""
"Returns [code]true[/code] if the property identified by [code]name[/code] "
"can be reverted to a default value."
msgstr ""
-"如果由[code]name[/code]标识的属性å¯ä»¥æ¢å¤åˆ°é»˜è®¤å€¼ï¼Œåˆ™è¿”回 [code]true[/code]。"
+"如果由 [code]name[/code] 标识的属性å¯ä»¥æ¢å¤åˆ°é»˜è®¤å€¼ï¼Œåˆ™è¿”回 [code]true[/"
+"code]。"
#: doc/classes/ShaderMaterial.xml
msgid ""
@@ -69249,8 +69697,8 @@ msgid ""
"[b]Note:[/b] [code]param[/code] must match the name of the uniform in the "
"code exactly."
msgstr ""
-"改å˜ç€è‰²å™¨ä¸­æè´¨çš„uniform值。\n"
-"[b]注æ„:[/b][code]param[/code]必须与代ç ä¸­çš„uniformå称完全匹é…。"
+"改å˜ç€è‰²å™¨ä¸­æè´¨çš„ uniform 值。\n"
+"[b]注æ„:[/b][code]param[/code] 必须与代ç ä¸­çš„ uniform å称完全匹é…。"
#: doc/classes/ShaderMaterial.xml
msgid "The [Shader] program used to render this material."
@@ -69265,7 +69713,8 @@ msgid ""
"Base class for all 3D shape resources. Nodes that inherit from this can be "
"used as shapes for a [PhysicsBody] or [Area] objects."
msgstr ""
-"所有3D形状资æºçš„基类。继承于此的节点å¯ä»¥ä½œä¸º[PhysicsBody]或[Area]对象的形状。"
+"所有3D形状资æºçš„基类。继承于此的节点å¯ä»¥ä½œä¸º [PhysicsBody] 或 [Area] 对象的形"
+"状。"
#: doc/classes/Shape.xml
msgid ""
@@ -69288,11 +69737,11 @@ msgstr ""
#: doc/classes/Shape2D.xml
msgid "Base class for all 2D shapes."
-msgstr "所有2D形状的基类。"
+msgstr "所有 2D 形状的基类。"
#: doc/classes/Shape2D.xml
msgid "Base class for all 2D shapes. All 2D shape types inherit from this."
-msgstr "所有2D形状的基类。所有的2D形状类型都继承于此。"
+msgstr "所有 2D 形状的基类。所有的 2D 形状类型都继承于此。"
#: doc/classes/Shape2D.xml
msgid ""
@@ -69390,7 +69839,7 @@ msgstr ""
#: doc/classes/Shape2D.xml
msgid "The shape's custom solver bias."
-msgstr "形状的自定义求解器å差。"
+msgstr "形状的自定义求解器å置。"
#: doc/classes/ShortCut.xml
msgid "A shortcut for binding input."
@@ -69419,7 +69868,7 @@ msgstr ""
#: doc/classes/ShortCut.xml
msgid "If [code]true[/code], this shortcut is valid."
-msgstr "如果 [code]true[/code]ï¼Œåˆ™æ­¤å¿«æ·æ–¹å¼æœ‰æ•ˆã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œåˆ™æ­¤å¿«æ·æ–¹å¼æœ‰æ•ˆã€‚"
#: doc/classes/ShortCut.xml
msgid ""
@@ -69445,8 +69894,8 @@ msgid ""
"with respect to skeleton, so it not the actual global/world transform of the "
"bone."
msgstr ""
-"骨架为管ç†éª¨éª¼æä¾›äº†åˆ†å±‚的界é¢ï¼ŒåŒ…æ‹¬å§¿åŠ¿ã€æ”¾æ¾å’ŒåŠ¨ç”»ï¼ˆè¯·å‚阅 [Animation])。"
-"它还å¯ä»¥ä½¿ç”¨å¸ƒå¨ƒå¨ƒç‰©ç†ã€‚\n"
+"骨架为管ç†éª¨éª¼æä¾›äº†åˆ†å±‚的界é¢ï¼ŒåŒ…æ‹¬å§¿åŠ¿ã€æ”¾æ¾å’ŒåŠ¨ç”»ï¼ˆè§ [Animation])。它还"
+"å¯ä»¥ä½¿ç”¨å¸ƒå¨ƒå¨ƒç‰©ç†ã€‚\n"
"éª¨éª¼ç›¸å¯¹äºŽéª¨æž¶çš„æ•´ä½“å˜æ¢æ˜¯ç”±ä»¥ä¸‹å±‚次顺åºå†³å®šçš„:放æ¾å§¿åŠ¿ã€è‡ªå®šä¹‰å§¿åŠ¿å’Œå§¿"
"势。\n"
"注æ„,下é¢çš„â€œå…¨å±€å§¿åŠ¿â€æ˜¯æŒ‡éª¨éª¼ç›¸å¯¹äºŽéª¨æž¶çš„æ•´ä½“å˜æ¢ï¼Œæ‰€ä»¥å®ƒä¸æ˜¯éª¨éª¼çš„实际全局"
@@ -69457,7 +69906,7 @@ msgid ""
"Adds a bone, with name [code]name[/code]. [method get_bone_count] will "
"become the bone index."
msgstr ""
-"添加一个骨骼,å称为 [code]name[/code]。 [method get_bone_count] å°†æˆä¸ºéª¨éª¼ç´¢"
+"添加一个骨骼,å称为 [code]name[/code]。[method get_bone_count] å°†æˆä¸ºéª¨éª¼ç´¢"
"引。"
#: doc/classes/Skeleton.xml
@@ -69511,9 +69960,9 @@ msgid ""
"[b]Note:[/b] The parent bone returned will always be less than "
"[code]bone_idx[/code]."
msgstr ""
-"返回在[code]bone_idx[/code]处的骨骼的父级索引。如果是-1,那么骨骼就没有父骨"
-"骼。\n"
-"[b]注æ„:[/b]返回的父骨骼将总是å°äºŽ[code]bone_idx[/code]。"
+"返回在 [code]bone_idx[/code] 处的骨骼的父级索引。如果是 -1,那么骨骼就没有父"
+"骨骼。\n"
+"[b]注æ„:[/b]返回的父骨骼将总是å°äºŽ [code]bone_idx[/code]。"
#: doc/classes/Skeleton.xml
msgid ""
@@ -69543,7 +69992,7 @@ msgstr "设置骨骼 [code]bone_idx[/code] çš„å§¿åŠ¿å˜æ¢ã€‚"
#: doc/classes/Skeleton.xml
msgid "Sets the rest transform for bone [code]bone_idx[/code]."
-msgstr "为骨骼[code]bone_idx[/code]设置休æ¯å˜æ¢ã€‚"
+msgstr "为骨骼 [code]bone_idx[/code] 设置休æ¯å˜æ¢ã€‚"
#: doc/classes/Skeleton2D.xml
msgid "Skeleton for 2D characters and animated objects."
@@ -69696,7 +70145,7 @@ msgid ""
"disable the SkeletonIK. A value at or below [code]0.01[/code] also calls "
"[method Skeleton.clear_bones_global_pose_override]."
msgstr ""
-"IK 效果应用于当å‰éª¨æž¶éª¨éª¼é“¾çš„æ’å€¼ã€‚ [code]1.0[/code] 的值将完全覆盖所有骨架骨"
+"IK 效果应用于当å‰éª¨æž¶éª¨éª¼é“¾çš„æ’å€¼ã€‚[code]1.0[/code] 的值将完全覆盖所有骨架骨"
"éª¼å˜æ¢ï¼Œè€Œ [code]0.0[/code] 的值将在视觉上ç¦ç”¨ SkeletonIK。等于或低于 "
"[code]0.01[/code] 的值也调用 [method Skeleton."
"clear_bones_global_pose_override]。"
@@ -69732,12 +70181,12 @@ msgid ""
"If [code]true[/code] overwrites the rotation of the tip bone with the "
"rotation of the [member target] (or [member target_node] if defined)."
msgstr ""
-"如果[code]true[/code],则用 [member target] (或者如果定义了[member "
+"如果为 [code]true[/code],则用 [member target](或者如果定义了 [member "
"target_node]])的旋转覆盖尖端骨骼的旋转。"
#: doc/classes/SkeletonIK.xml
msgid "The name of the current root bone, the first bone in the IK chain."
-msgstr "当剿 ¹éª¨çš„å称,å³IK链中的第一个骨。"
+msgstr "当å‰çš„æ ¹éª¨éª¼çš„åç§°ï¼Œå³ IK 链中的第一æ¡éª¨éª¼ã€‚"
#: doc/classes/SkeletonIK.xml
msgid ""
@@ -69755,8 +70204,8 @@ msgid ""
"Target node [NodePath] for the IK chain. If available, the node's current "
"[Transform] is used instead of the [member target] property."
msgstr ""
-"IK链的目标节点[NodePath]。如果有的è¯ï¼Œå°†ä½¿ç”¨èŠ‚ç‚¹å½“å‰çš„[Transform]ï¼Œè€Œä¸æ˜¯"
-"[member target]属性。"
+"IK 链的目标节点 [NodePath]。如果有的è¯ï¼Œå°†ä½¿ç”¨èŠ‚ç‚¹å½“å‰çš„ [Transform]ï¼Œè€Œä¸æ˜¯ "
+"[member target] 属性。"
#: doc/classes/SkeletonIK.xml
msgid ""
@@ -69772,8 +70221,8 @@ msgid ""
"magnet target (pole target) when calculating the bone chain. Use the magnet "
"position (pole target) to control the bending of the IK chain."
msgstr ""
-"如果[code]true[/code],指示IK求解器在解算器链时考虑次è¦ç£é“目标(æžç‚¹ç›®æ ‡ï¼‰ã€‚"
-"使用ç£é“ä½ç½®ï¼ˆç£æžç›®æ ‡ï¼‰æ¥æŽ§åˆ¶IK链的弯曲。"
+"如果为 [code]true[/code],指示 IK 求解器在解算器链时考虑次è¦ç£é“目标(æžç‚¹ç›®"
+"标)。使用ç£é“ä½ç½®ï¼ˆç£æžç›®æ ‡ï¼‰æ¥æŽ§åˆ¶ IK 链的弯曲。"
#: doc/classes/Sky.xml
msgid "The base class for [PanoramaSky] and [ProceduralSky]."
@@ -69825,8 +70274,8 @@ msgid ""
"as it is known to cause GPU hangs on certain systems."
msgstr ""
"è¾å°„纹ç†å°ºå¯¸ä¸º1024×1024åƒç´ ã€‚\n"
-"[b]注æ„:[/b][constant RADIANCE_SIZE_1024]在检查器中没有公开,因为它在æŸäº›ç³»"
-"统上会导致GPU挂起。"
+"[b]注æ„:[/b][constant RADIANCE_SIZE_1024] 在检查器中没有公开,因为它在æŸäº›ç³»"
+"统上会导致 GPU 挂起。"
#: doc/classes/Sky.xml
msgid ""
@@ -69835,12 +70284,12 @@ msgid ""
"as it is known to cause GPU hangs on certain systems."
msgstr ""
"è¾å°„纹ç†å°ºå¯¸ä¸º2048×2048åƒç´ ã€‚\n"
-"[b]注æ„:[/b][constant RADIANCE_SIZE_2048]没有在检查器中公开,因为它在æŸäº›ç³»"
-"统上会导致GPU挂起。"
+"[b]注æ„:[/b][constant RADIANCE_SIZE_2048] 没有在检查器中公开,因为它在æŸäº›ç³»"
+"统上会导致 GPU 挂起。"
#: doc/classes/Sky.xml
msgid "Represents the size of the [enum RadianceSize] enum."
-msgstr "代表[enum RadianceSize]枚举的大å°ã€‚"
+msgstr "代表 [enum RadianceSize] 枚举的大å°ã€‚"
#: doc/classes/Slider.xml
msgid "Base class for GUI sliders."
@@ -69899,7 +70348,7 @@ msgstr "3D 中,两个 PhysicsBody 之间的滑动æ¡ã€‚"
#: doc/classes/SliderJoint.xml
msgid ""
"Slides across the X axis of the pivot object. See also [Generic6DOFJoint]."
-msgstr "在轴心对象的 X 轴上滑动。å‚阅 [Generic6DOFJoint]。"
+msgstr "在轴心对象的 X 轴上滑动。å¦è¯·å‚阅 [Generic6DOFJoint]。"
#: doc/classes/SliderJoint.xml
msgid ""
@@ -69941,8 +70390,8 @@ msgid ""
"linear_limit/lower_distance] and [member linear_limit/upper_distance] is "
"surpassed."
msgstr ""
-"一旦超过[member linear_limit/lower_distance]和[member linear_limit/"
-"upper_distance]所定义的æžé™ï¼Œå°±ä¼šäº§ç”Ÿçš„阻尼é‡ã€‚"
+"一旦超过 [member linear_limit/lower_distance] 和 [member linear_limit/"
+"upper_distance] 所定义的æžé™ï¼Œå°±ä¼šäº§ç”Ÿçš„阻尼é‡ã€‚"
#: doc/classes/SliderJoint.xml
msgid ""
@@ -70025,7 +70474,7 @@ msgid ""
"If [code]true[/code], the [SoftBody] is simulated in physics. Can be set to "
"[code]false[/code] to pause the physics simulation."
msgstr ""
-"为 [code]true[/code] æ—¶ [SoftBody] ä¼šè¿›è¡Œç‰©ç†æ¨¡æ‹Ÿã€‚å¯ä»¥é€šè¿‡è®¾ç½®ä¸º "
+"为 [code]true[/code] 时该 [SoftBody] ä¼šè¿›è¡Œç‰©ç†æ¨¡æ‹Ÿã€‚å¯ä»¥é€šè¿‡è®¾ç½®ä¸º "
"[code]false[/code] æ¥æš‚åœç‰©ç†æ¨¡æ‹Ÿã€‚"
#: doc/classes/SoftBody.xml
@@ -70208,15 +70657,15 @@ msgstr ""
msgid ""
"Rotates the local transformation around axis, a unit [Vector3], by specified "
"angle in radians."
-msgstr "围绕轴(一个å•ä½[Vector3]ï¼‰æ—‹è½¬å±€éƒ¨å˜æ¢ï¼ŒæŒ‡å®šè§’度(弧度)。"
+msgstr "围绕轴(å•ä½ [Vector3]ï¼‰æ—‹è½¬å±€éƒ¨å˜æ¢ï¼ŒæŒ‡å®šè§’度(弧度)。"
#: doc/classes/Spatial.xml
msgid ""
"Rotates the local transformation around axis, a unit [Vector3], by specified "
"angle in radians. The rotation axis is in object-local coordinate system."
msgstr ""
-"围绕轴(一个å•ä½[Vector3]ï¼‰æ—‹è½¬æœ¬åœ°å˜æ¢ï¼ŒæŒ‡å®šè§’度(弧度)。旋转轴是在物体的本"
-"åœ°åæ ‡ç³»ä¸­ã€‚"
+"围绕轴(å•ä½ [Vector3]ï¼‰æ—‹è½¬æœ¬åœ°å˜æ¢ï¼ŒæŒ‡å®šè§’度(弧度)。旋转轴是在物体的本地"
+"åæ ‡ç³»ä¸­ã€‚"
#: doc/classes/Spatial.xml
msgid "Rotates the local transformation around the X axis by angle in radians."
@@ -70248,8 +70697,8 @@ msgid ""
"transformation scale. Changes to the local transformation scale are "
"preserved."
msgstr ""
-"设置节点是å¦ä½¿ç”¨[code](1, 1, 1)[/code]çš„æ¯”ä¾‹æˆ–å…¶æœ¬åœ°å˜æ¢æ¯”ä¾‹ã€‚å¯¹æœ¬åœ°å˜æ¢æ¯”例"
-"的改å˜ä¼šè¢«ä¿ç•™ä¸‹æ¥ã€‚"
+"设置节点是å¦ä½¿ç”¨ [code](1, 1, 1)[/code] çš„æ¯”ä¾‹æˆ–å…¶æœ¬åœ°å˜æ¢æ¯”ä¾‹ã€‚å¯¹æœ¬åœ°å˜æ¢æ¯”"
+"例的改å˜ä¼šè¢«ä¿ç•™ä¸‹æ¥ã€‚"
#: doc/classes/Spatial.xml
msgid ""
@@ -70268,7 +70717,7 @@ msgid ""
"Sets whether the node notifies about its local transformation changes. "
"[Spatial] will not propagate this by default."
msgstr ""
-"设置节点是å¦é€šçŸ¥å®ƒçš„å±€éƒ¨å˜æ¢å˜åŒ–。默认情况下,[Spatial]ä¸ä¼šä¼ æ’­è¿™ä¸€ç‚¹ã€‚"
+"设置节点是å¦é€šçŸ¥å®ƒçš„å±€éƒ¨å˜æ¢å˜åŒ–。默认情况下,[Spatial] ä¸ä¼šä¼ æ’­è¿™ä¸€ç‚¹ã€‚"
#: doc/classes/Spatial.xml
msgid ""
@@ -70276,26 +70725,26 @@ msgid ""
"changes. [Spatial] will not propagate this by default, unless it is in the "
"editor context and it has a valid gizmo."
msgstr ""
-"设置节点是å¦é€šçŸ¥å…¶å…¨å±€å’Œå±€éƒ¨å˜æ¢çš„å˜åŒ–。[Spatial]默认情况下ä¸ä¼šä¼ æ’­ï¼Œé™¤éžæ˜¯åœ¨"
-"编辑器上下文中,并且它有一个有效的gizmo。"
+"设置节点是å¦é€šçŸ¥å…¶å…¨å±€å’Œå±€éƒ¨å˜æ¢çš„å˜åŒ–。[Spatial] 默认情况下ä¸ä¼šä¼ æ’­ï¼Œé™¤éžæ˜¯"
+"在编辑器上下文中,并且它有一个有效的控制器。"
#: doc/classes/Spatial.xml
msgid ""
"Enables rendering of this node. Changes [member visible] to [code]true[/"
"code]."
-msgstr "å¯ç”¨æ­¤èŠ‚ç‚¹çš„å‘ˆçŽ°ã€‚å°†[member visible]更改为 [code]true[/code]。"
+msgstr "å¯ç”¨æ­¤èŠ‚ç‚¹çš„å‘ˆçŽ°ã€‚å°† [member visible] 更改为 [code]true[/code]。"
#: doc/classes/Spatial.xml
msgid ""
"Transforms [code]local_point[/code] from this node's local space to world "
"space."
-msgstr "å°†[code]local_point[/code]从该节点的本地空间转æ¢ä¸ºä¸–界空间。"
+msgstr "å°† [code]local_point[/code] 从该节点的本地空间转æ¢ä¸ºä¸–界空间。"
#: doc/classes/Spatial.xml
msgid ""
"Transforms [code]global_point[/code] from world space to this node's local "
"space."
-msgstr "å°†[code]global_point[/code]从世界空间转æ¢åˆ°è¿™ä¸ªèŠ‚ç‚¹çš„æœ¬åœ°ç©ºé—´ã€‚"
+msgstr "å°† [code]global_point[/code] 从世界空间转æ¢åˆ°è¿™ä¸ªèŠ‚ç‚¹çš„æœ¬åœ°ç©ºé—´ã€‚"
#: doc/classes/Spatial.xml
msgid ""
@@ -70305,15 +70754,15 @@ msgid ""
"offset of [code](2, 0, 0)[/code] would actually add 20 ([code]2 * 10[/code]) "
"to the X coordinate."
msgstr ""
-"通过给定的åç§»é‡[Vector3]改å˜èŠ‚ç‚¹çš„ä½ç½®ã€‚\n"
-"注æ„,平移[code]offset[/code]å—节点比例因å­(scale)的影å“,所以如果按例如"
-"[code](10,1,1)[/code]进行缩放,平移[code](2,0,0)[/code]实际上会在Xåæ ‡ä¸Šå¢žåŠ "
+"通过给定的åç§»é‡ [Vector3] 改å˜èŠ‚ç‚¹çš„ä½ç½®ã€‚\n"
+"注æ„,平移 [code]offset[/code] å—节点缩放的影å“,所以如果按例如 [code]"
+"(10,1,1)[/code] 进行缩放,平移 [code](2,0,0)[/code] 实际上会在 X åæ ‡ä¸Šå¢žåŠ  "
"20 ([code]2 * 10[/code])。"
#: doc/classes/Spatial.xml
msgid ""
"Changes the node's position by the given offset [Vector3] in local space."
-msgstr "通过给定的åç§»é‡[Vector3]改å˜èŠ‚ç‚¹åœ¨å±€éƒ¨ç©ºé—´ä¸­çš„ä½ç½®ã€‚"
+msgstr "通过给定的åç§»é‡ [Vector3] 改å˜èŠ‚ç‚¹åœ¨å±€éƒ¨ç©ºé—´ä¸­çš„ä½ç½®ã€‚"
#: doc/classes/Spatial.xml
msgid "Updates the [SpatialGizmo] of this node."
@@ -70328,11 +70777,37 @@ msgstr ""
"视化和编辑手柄。"
#: doc/classes/Spatial.xml
+#, fuzzy
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+"å±€éƒ¨å˜æ¢çš„æ—‹è½¬éƒ¨åˆ†ä»¥å¼§åº¦è¡¨ç¤ºï¼Œä»¥ YXZ-Euler 角的形å¼è¡¨ç¤ºï¼ˆX è§’ã€Y è§’ã€Z "
+"角)。\n"
+"[b]注æ„:[/b]在数学æ„ä¹‰ä¸Šï¼Œæ—‹è½¬æ˜¯ä¸€ä¸ªçŸ©é˜µè€Œä¸æ˜¯ä¸€ä¸ªå‘é‡ã€‚这三个欧拉角是旋转矩"
+"é˜µæ¬§æ‹‰è§’å‚æ•°åŒ–çš„ä¸‰ä¸ªç‹¬ç«‹å‚æ•°ï¼Œå­˜å‚¨åœ¨ [Vector3] æ•°æ®ç»“æž„ä¸­å¹¶ä¸æ˜¯å› ä¸ºæ—‹è½¬æ˜¯ä¸€ä¸ª"
+"矢é‡ï¼Œè€Œæ˜¯å› ä¸º [Vector3] æ˜¯ä¸€ç§æ–¹ä¾¿å­˜å‚¨ 3 个浮点数的数æ®ç»“构。因此,对旋转“å‘"
+"é‡â€åº”用仿射æ“作是没有æ„义的。"
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr "此节点的世界空间(全局)[Transform]。"
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -70343,17 +70818,18 @@ msgid ""
"point numbers. Therefore, applying affine operations on the rotation "
"\"vector\" is not meaningful."
msgstr ""
-"å±€éƒ¨å˜æ¢çš„æ—‹è½¬éƒ¨åˆ†ä»¥å¼§åº¦è¡¨ç¤ºï¼Œä»¥YXZ-Euler角的形å¼è¡¨ç¤º(Xè§’ã€Yè§’ã€Zè§’)。\n"
-"[b]注:[/b]在数学æ„ä¹‰ä¸Šï¼Œæ—‹è½¬æ˜¯ä¸€ä¸ªçŸ©é˜µè€Œä¸æ˜¯ä¸€ä¸ªå‘é‡ã€‚这三个欧拉角是旋转矩阵"
-"æ¬§æ‹‰è§’å‚æ•°åŒ–çš„ä¸‰ä¸ªç‹¬ç«‹å‚æ•°ï¼Œå­˜å‚¨åœ¨[Vector3]æ•°æ®ç»“æž„ä¸­å¹¶ä¸æ˜¯å› ä¸ºæ—‹è½¬æ˜¯ä¸€ä¸ªçŸ¢"
-"é‡ï¼Œè€Œæ˜¯å› ä¸º[Vector3]æ˜¯ä¸€ç§æ–¹ä¾¿å­˜å‚¨3个浮点数的数æ®ç»“构。因此,对旋转“å‘é‡â€åº”"
-"用仿射æ“作是没有æ„义的。"
+"å±€éƒ¨å˜æ¢çš„æ—‹è½¬éƒ¨åˆ†ä»¥å¼§åº¦è¡¨ç¤ºï¼Œä»¥ YXZ-Euler 角的形å¼è¡¨ç¤ºï¼ˆX è§’ã€Y è§’ã€Z "
+"角)。\n"
+"[b]注æ„:[/b]在数学æ„ä¹‰ä¸Šï¼Œæ—‹è½¬æ˜¯ä¸€ä¸ªçŸ©é˜µè€Œä¸æ˜¯ä¸€ä¸ªå‘é‡ã€‚这三个欧拉角是旋转矩"
+"é˜µæ¬§æ‹‰è§’å‚æ•°åŒ–çš„ä¸‰ä¸ªç‹¬ç«‹å‚æ•°ï¼Œå­˜å‚¨åœ¨ [Vector3] æ•°æ®ç»“æž„ä¸­å¹¶ä¸æ˜¯å› ä¸ºæ—‹è½¬æ˜¯ä¸€ä¸ª"
+"矢é‡ï¼Œè€Œæ˜¯å› ä¸º [Vector3] æ˜¯ä¸€ç§æ–¹ä¾¿å­˜å‚¨ 3 个浮点数的数æ®ç»“构。因此,对旋转“å‘"
+"é‡â€åº”用仿射æ“作是没有æ„义的。"
#: doc/classes/Spatial.xml
msgid ""
"Rotation part of the local transformation in degrees, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle)."
-msgstr "æ—‹è½¬éƒ¨åˆ†å±€éƒ¨å˜æ¢ä¸ºåº¦ï¼ŒæŒ‰YXZ-Eulerè§’æ ¼å¼æŒ‡å®š(Xè§’ã€Yè§’ã€Zè§’)。"
+msgstr "æ—‹è½¬éƒ¨åˆ†å±€éƒ¨å˜æ¢ä¸ºåº¦ï¼ŒæŒ‰ YXZ-Euler è§’æ ¼å¼æŒ‡å®šï¼ˆX è§’ã€Y è§’ã€Z 角)。"
#: doc/classes/Spatial.xml
msgid ""
@@ -70369,7 +70845,7 @@ msgstr ""
#: doc/classes/Spatial.xml
msgid "Local space [Transform] of this node, with respect to the parent node."
-msgstr "该节点相对于父节点的局部空间[Transform]。"
+msgstr "该节点相对于父节点的局部空间 [Transform]。"
#: doc/classes/Spatial.xml
msgid "Local translation of this node."
@@ -70381,8 +70857,8 @@ msgid ""
"its antecedents are visible as well (in other words, [method "
"is_visible_in_tree] must return [code]true[/code])."
msgstr ""
-"如果[code]true[/code],这个节点就会被画出æ¥ã€‚åªæœ‰å½“它的所有å‰é¡¹ä¹Ÿæ˜¯å¯è§çš„æ—¶"
-"å€™ï¼Œè¿™ä¸ªèŠ‚ç‚¹æ‰æ˜¯å¯è§çš„(æ¢å¥è¯è¯´ï¼Œ[method is_visible_in_tree]必须返回 "
+"如果为 [code]true[/code],这个节点就会被画出æ¥ã€‚åªæœ‰å½“它的所有å‰é¡¹ä¹Ÿæ˜¯å¯è§çš„"
+"æ—¶å€™ï¼Œè¿™ä¸ªèŠ‚ç‚¹æ‰æ˜¯å¯è§çš„(æ¢å¥è¯è¯´ï¼Œ[method is_visible_in_tree] 必须返回 "
"[code]true[/code])。"
#: doc/classes/Spatial.xml
@@ -70481,7 +70957,7 @@ msgid ""
"way the cost for using the feature is only incurred when specified. Features "
"can also be enabled by setting the corresponding member to [code]true[/code]."
msgstr ""
-"如果 [code]true[/code],则å¯ç”¨æŒ‡å®šçš„ [enum Feature]。 [SpatialMaterial]s 中å¯"
+"如果为 [code]true[/code],则å¯ç”¨æŒ‡å®šçš„ [enum Feature]。[SpatialMaterial] 中å¯"
"用的许多功能需è¦åœ¨ä½¿ç”¨å‰å¯ç”¨ã€‚è¿™æ ·ï¼Œåªæœ‰åœ¨æŒ‡å®šæ—¶æ‰ä¼šäº§ç”Ÿä½¿ç”¨è¯¥åŠŸèƒ½çš„æˆæœ¬ã€‚也"
"å¯ä»¥é€šè¿‡å°†ç›¸åº”çš„æˆå‘˜è®¾ç½®ä¸º [code]true[/code] æ¥å¯ç”¨åŠŸèƒ½ã€‚"
@@ -70573,8 +71049,8 @@ msgid ""
"If [code]true[/code], ambient occlusion is enabled. Ambient occlusion "
"darkens areas based on the [member ao_texture]."
msgstr ""
-"如果 [code]true[/code],å¯ç”¨çŽ¯å¢ƒé®æŒ¡ã€‚çŽ¯å¢ƒé®æŒ¡æ ¹æ® [member ao_texture] 使区域"
-"å˜æš—。"
+"如果为 [code]true[/code],å¯ç”¨çŽ¯å¢ƒé®æŒ¡ã€‚çŽ¯å¢ƒé®æŒ¡æ ¹æ® [member ao_texture] 使区"
+"åŸŸå˜æš—。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70593,8 +71069,8 @@ msgid ""
"If [code]true[/code], use [code]UV2[/code] coordinates to look up from the "
"[member ao_texture]."
msgstr ""
-"如果 [code]true[/code],请使用 [code]UV2[/code] åæ ‡ä»Ž[member ao_texture]中查"
-"找。"
+"如果为 [code]true[/code],请使用 [code]UV2[/code] åæ ‡ä»Ž [member ao_texture] "
+"中查找。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70641,9 +71117,9 @@ msgid ""
"[b]Note:[/b] Clearcoat rendering is not visible if the material has [member "
"flags_unshaded] set to [code]true[/code]."
msgstr ""
-"如果 [code]true[/code],则å¯ç”¨æ¸…æ¼†æ¸²æŸ“ã€‚åœ¨ç…§æ˜Žè®¡ç®—ä¸­æ·»åŠ äºŒçº§é€æ˜Žé€šè·¯ï¼Œä»Žè€Œå¯¼"
-"致添加镜é¢å射斑点。这使得æè´¨çœ‹èµ·æ¥å¥½åƒæœ‰ä¸€å±‚逿˜Žå±‚,å¯ä»¥æ˜¯æœ‰å…‰æ³½çš„也å¯ä»¥æ˜¯"
-"粗糙的。\n"
+"如果为 [code]true[/code],则å¯ç”¨æ¸…æ¼†æ¸²æŸ“ã€‚åœ¨ç…§æ˜Žè®¡ç®—ä¸­æ·»åŠ äºŒçº§é€æ˜Žé€šè·¯ï¼Œä»Žè€Œ"
+"导致添加镜é¢å射斑点。这使得æè´¨çœ‹èµ·æ¥å¥½åƒæœ‰ä¸€å±‚逿˜Žå±‚,å¯ä»¥æ˜¯æœ‰å…‰æ³½çš„也å¯ä»¥"
+"是粗糙的。\n"
"[b]注æ„:[/b]如果æè´¨å°† [member flags_unshaded] 设置为 [code]true[/code],则"
"逿˜Žæ¶‚层渲染ä¸å¯è§ã€‚"
@@ -70670,8 +71146,8 @@ msgid ""
"along the view ray to determine occlusion and parrallax. This can be very "
"performance demanding, but results in more realistic looking depth mapping."
msgstr ""
-"如果 [code]true[/code],ç€è‰²å™¨å°†åœ¨æ²¿è§†å›¾å°„çº¿çš„å¤šä¸ªç‚¹ä¸Šè¯»å–æ·±åº¦çº¹ç†ä»¥ç¡®å®šé®æŒ¡"
-"和视差。这å¯èƒ½å¯¹æ€§èƒ½è¦æ±‚很高,但会产生更逼真的深度映射。"
+"如果为 [code]true[/code],ç€è‰²å™¨å°†åœ¨æ²¿è§†å›¾å°„çº¿çš„å¤šä¸ªç‚¹ä¸Šè¯»å–æ·±åº¦çº¹ç†ä»¥ç¡®å®šé®"
+"挡和视差。这å¯èƒ½å¯¹æ€§èƒ½è¦æ±‚很高,但会产生更逼真的深度映射。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70681,8 +71157,8 @@ msgid ""
"the same material. The value of [member depth_enabled] will be ignored if "
"[member uv1_triplanar] is enabled."
msgstr ""
-"如果 [code]true[/code],则å¯ç”¨æ·±åº¦æ˜ å°„ï¼ˆä¹Ÿç§°ä¸ºâ€œè§†å·®æ˜ å°„â€æˆ–“高度映射â€ï¼‰ã€‚å¦è§ "
-"[member normal_enabled]。\n"
+"如果为 [code]true[/code],则å¯ç”¨æ·±åº¦æ˜ å°„ï¼ˆä¹Ÿç§°ä¸ºâ€œè§†å·®æ˜ å°„â€æˆ–“高度映射â€ï¼‰ã€‚å¦"
+"è§ [member normal_enabled]。\n"
"[b]注æ„:[/b]如果在åŒä¸€æè´¨ä¸Šä½¿ç”¨ä¸‰å¹³é¢è´´å›¾ï¼Œåˆ™ä¸æ”¯æŒæ·±åº¦è´´å›¾ã€‚如果å¯ç”¨ "
"[member uv1_triplanar],则 [member depth_enabled] 的值将被忽略。"
@@ -70692,8 +71168,8 @@ msgid ""
"the depth effect. This may be necessary if you have encoded your binormals "
"in a way that is conflicting with the depth effect."
msgstr ""
-"如果 [code]true[/code],则在深度效果中使用之å‰ä¼šç¿»è½¬å‰¯æ³•线的方å‘。如果你对你"
-"çš„å‰¯æ³•çº¿çš„ç¼–ç æ–¹å¼ä¸Žæ·±åº¦æ•ˆæžœæœ‰å†²çªï¼Œè¿™å¯èƒ½æ˜¯å¿…è¦çš„。"
+"如果为 [code]true[/code],则在深度效果中使用之å‰ä¼šç¿»è½¬å‰¯æ³•线的方å‘。如果你对"
+"ä½ çš„å‰¯æ³•çº¿çš„ç¼–ç æ–¹å¼ä¸Žæ·±åº¦æ•ˆæžœæœ‰å†²çªï¼Œè¿™å¯èƒ½æ˜¯å¿…è¦çš„。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70701,8 +71177,8 @@ msgid ""
"the depth effect. This may be necessary if you have encoded your tangents in "
"a way that is conflicting with the depth effect."
msgstr ""
-"如果 [code]true[/code],切线方å‘在深度效果中使用å‰ä¼šç¿»è½¬ã€‚如果你对切线的编ç "
-"æ–¹å¼ä¸Žæ·±åº¦æ•ˆæžœæœ‰å†²çªï¼Œè¿™å¯èƒ½æ˜¯å¿…è¦çš„。"
+"如果为 [code]true[/code],切线方å‘在深度效果中使用å‰ä¼šç¿»è½¬ã€‚如果你对切线的编"
+"ç æ–¹å¼ä¸Žæ·±åº¦æ•ˆæžœæœ‰å†²çªï¼Œè¿™å¯èƒ½æ˜¯å¿…è¦çš„。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70753,9 +71229,9 @@ msgid ""
"detail_mask]. This can be used to add variation to objects, or to blend "
"between two different albedo/normal textures."
msgstr ""
-"如果[code]true[/code],å¯ç”¨ç»†èŠ‚å åŠ ã€‚Detail是基于[member detail_mask]在对象表"
-"颿··åˆçš„第二个纹ç†ã€‚è¿™å¯ä»¥ç”¨æ¥ç»™ç‰©ä½“增加å˜åŒ–,或者在两ç§ä¸åŒçš„å射率/法线纹ç†"
-"之间进行混åˆã€‚"
+"如果为 [code]true[/code],å¯ç”¨ç»†èŠ‚å åŠ ã€‚Detail是基于[member detail_mask]在对"
+"è±¡è¡¨é¢æ··åˆçš„第二个纹ç†ã€‚è¿™å¯ä»¥ç”¨æ¥ç»™ç‰©ä½“增加å˜åŒ–,或者在两ç§ä¸åŒçš„å射率/法线"
+"纹ç†ä¹‹é—´è¿›è¡Œæ··åˆã€‚"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70782,7 +71258,7 @@ msgid ""
"Specifies whether to use [code]UV[/code] or [code]UV2[/code] for the detail "
"layer. See [enum DetailUV] for options."
msgstr ""
-"指定细节层是使用[code]UV[/code]还是[code]UV2[/code]。选项请å‚阅[enum "
+"指定细节层是使用 [code]UV[/code] 还是 [code]UV2[/code]。选项请å‚阅 [enum "
"DetailUV]。"
#: doc/classes/SpatialMaterial.xml
@@ -70820,11 +71296,11 @@ msgstr ""
msgid ""
"Specifies which type of fade to use. Can be any of the [enum "
"DistanceFadeMode]s."
-msgstr "指定è¦ä½¿ç”¨çš„æ·¡å…¥æ·¡å‡ºç±»åž‹ã€‚å¯ä»¥æ˜¯ä»»ä½•一个[enum DistanceFadeMode]。"
+msgstr "指定è¦ä½¿ç”¨çš„æ·¡å…¥æ·¡å‡ºç±»åž‹ã€‚å¯ä»¥æ˜¯ä»»ä½•一个 [enum DistanceFadeMode]。"
#: doc/classes/SpatialMaterial.xml
msgid "The emitted light's color. See [member emission_enabled]."
-msgstr "å‘出的光的颜色。å‚阅[member emission_enabled]。"
+msgstr "å‘出的光的颜色。å‚阅 [member emission_enabled]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70833,25 +71309,25 @@ msgid ""
"[GIProbe] or [BakedLightmap] is used and this object is used in baked "
"lighting."
msgstr ""
-"如果 [code]true[/code],物体会å‘光。å‘å…‰ä½¿ç‰©ä½“çœ‹èµ·æ¥æ›´äº®ã€‚如果使用 [GIProbe] "
-"或 [BakedLightmap] 并且此对象用于烘焙照明,则该对象还å¯ä»¥å°†å…‰æŠ•射到其他对象"
-"上。"
+"如果为 [code]true[/code],物体会å‘光。å‘å…‰ä½¿ç‰©ä½“çœ‹èµ·æ¥æ›´äº®ã€‚如果使用 "
+"[GIProbe] 或 [BakedLightmap] 并且此对象用于烘焙照明,则该对象还å¯ä»¥å°†å…‰æŠ•射到"
+"其他对象上。"
#: doc/classes/SpatialMaterial.xml
msgid "The emitted light's strength. See [member emission_enabled]."
-msgstr "å‘出的光的强度。å‚阅[member emission_enabled]。"
+msgstr "å‘å‡ºçš„å…‰çš„å¼ºåº¦ã€‚è§ [member emission_enabled]。"
#: doc/classes/SpatialMaterial.xml
msgid "Use [code]UV2[/code] to read from the [member emission_texture]."
-msgstr "使用[code]UV2[/code]从[member emission_texture]中读å–。"
+msgstr "使用 [code]UV2[/code] 从 [member emission_texture] 中读å–。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"Sets how [member emission] interacts with [member emission_texture]. Can "
"either add or multiply. See [enum EmissionOperator] for options."
msgstr ""
-"设置[member emission]与[member emission_texture]的交互方å¼ã€‚å¯ä»¥æ˜¯åŠ æ³•æˆ–ä¹˜"
-"法。选项å‚阅 [enum EmissionOperator] 。"
+"设置 [member emission] 与 [member emission_texture] 的交互方å¼ã€‚å¯ä»¥æ˜¯åŠ æ³•æˆ–"
+"乘法。å¯é€‰å€¼è§ [enum EmissionOperator] 。"
#: doc/classes/SpatialMaterial.xml
msgid "Texture that specifies how much surface emits light at a given point."
@@ -70869,13 +71345,13 @@ msgstr "å¯ç”¨æœ‰ç¬¦å·è·ç¦»åœºæ¸²æŸ“ç€è‰²å™¨ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "If [code]true[/code], the object receives no ambient light."
-msgstr "如果[code]true[/code]ï¼Œåˆ™å¯¹è±¡ä¸æŽ¥æ”¶çŽ¯å¢ƒå…‰ã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œåˆ™å¯¹è±¡ä¸æŽ¥æ”¶çŽ¯å¢ƒå…‰ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid ""
"If [code]true[/code], the object receives no shadow that would otherwise be "
"cast onto it."
-msgstr "如果[code]true[/code],则对象ä¸ä¼šæ”¶åˆ°æŠ•射到其上的阴影。"
+msgstr "如果为 [code]true[/code],则对象ä¸ä¼šæ”¶åˆ°æŠ•射到其上的阴影。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70883,25 +71359,26 @@ msgid ""
"the normal stays correct when using a non-uniform scale. Only enable if "
"using non-uniform scaling."
msgstr ""
-"如果 [code]true[/code],ç€è‰²å™¨å°†è®¡ç®—é¢å¤–çš„æ“作,以确ä¿åœ¨ä½¿ç”¨éžå‡åŒ€æ¯”例时法线"
-"ä¿æŒæ­£ç¡®ã€‚仅在使用éžå‡åŒ€ç¼©æ”¾æ—¶å¯ç”¨ã€‚"
+"如果为 [code]true[/code],ç€è‰²å™¨å°†è®¡ç®—é¢å¤–çš„æ“作,以确ä¿åœ¨ä½¿ç”¨éžå‡åŒ€æ¯”例时法"
+"çº¿ä¿æŒæ­£ç¡®ã€‚仅在使用éžå‡åŒ€ç¼©æ”¾æ—¶å¯ç”¨ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid ""
"If [code]true[/code], the object is rendered at the same size regardless of "
"distance."
-msgstr "如果[code]true[/code],则无论è·ç¦»è¿œè¿‘,对象都以相åŒçš„尺寸呈现。"
+msgstr "如果为 [code]true[/code],则无论è·ç¦»è¿œè¿‘,对象都以相åŒçš„尺寸呈现。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"If [code]true[/code], transparency is enabled on the body. See also [member "
"params_blend_mode]."
msgstr ""
-"如果[code]true[/code],则å¯ç”¨ç‰©ä½“çš„é€æ˜Žåº¦ã€‚å‚阅 [member params_blend_mode]。"
+"如果为 [code]true[/code],则å¯ç”¨ç‰©ä½“çš„é€æ˜Žåº¦ã€‚å‚阅 [member "
+"params_blend_mode]。"
#: doc/classes/SpatialMaterial.xml
msgid "If [code]true[/code], the object is unaffected by lighting."
-msgstr "如果 [code]true[/code],则物体ä¸å—光照影å“。"
+msgstr "如果为 [code]true[/code],则物体ä¸å—光照影å“。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70909,8 +71386,8 @@ msgid ""
"[b]Note:[/b] This is only effective for objects whose geometry is point-"
"based rather than triangle-based. See also [member params_point_size]."
msgstr ""
-"如果[code]true[/code],å¯ä»¥æ”¹å˜æ¸²æŸ“点的大å°ã€‚\n"
-"[b]注æ„:[/b]è¿™åªå¯¹å‡ ä½•ä½“æ˜¯åŸºäºŽç‚¹è€Œä¸æ˜¯åŸºäºŽä¸‰è§’形的对象有效。å‚阅[member "
+"如果为 [code]true[/code],则å¯ä»¥æ”¹å˜æ¸²æŸ“点的大å°ã€‚\n"
+"[b]注æ„:[/b]è¿™åªå¯¹å‡ ä½•ä½“æ˜¯åŸºäºŽç‚¹è€Œä¸æ˜¯åŸºäºŽä¸‰è§’å½¢çš„å¯¹è±¡æœ‰æ•ˆã€‚è§ [member "
"params_point_size]。"
#: doc/classes/SpatialMaterial.xml
@@ -70920,8 +71397,8 @@ msgid ""
"areas are transparent. Useful for overlaying shadows onto a camera feed in "
"AR."
msgstr ""
-"如果 [code]true[/code],å¯ç”¨ \"阴影到ä¸é€æ˜Žåº¦ \"的渲染模å¼ï¼Œåœ¨è¯¥æ¨¡å¼ä¸‹ï¼Œå…‰ç…§"
-"会修改 alpha,使阴影区域ä¸é€æ˜Žï¼Œéžé˜´å½±åŒºåŸŸé€æ˜Žã€‚对于在AR中把阴影å åŠ åˆ°ç›¸æœºç”»"
+"如果为 [code]true[/code],å¯ç”¨â€œé˜´å½±åˆ°ä¸é€æ˜Žåº¦â€çš„æ¸²æŸ“模å¼ï¼Œåœ¨è¯¥æ¨¡å¼ä¸‹ï¼Œå…‰ç…§ä¼š"
+"修改 Alpha,使阴影区域ä¸é€æ˜Žï¼Œéžé˜´å½±åŒºåŸŸé€æ˜Žã€‚对于在 AR 中把阴影å åŠ åˆ°ç›¸æœºç”»"
"é¢ä¸Šå¾ˆæœ‰ç”¨ã€‚"
#: doc/classes/SpatialMaterial.xml
@@ -70960,8 +71437,8 @@ msgid ""
"If [code]true[/code], triplanar mapping is calculated in world space rather "
"than object local space. See also [member uv1_triplanar]."
msgstr ""
-"如果 [code]true[/code]ï¼Œåˆ™åœ¨ä¸–ç•Œç©ºé—´è€Œä¸æ˜¯ç‰©ä½“å±€éƒ¨ç©ºé—´ä¸­è®¡ç®—ä¸‰å¹³é¢æ˜ å°„。å¦è§ "
-"[member uv1_triplanar]。"
+"如果为 [code]true[/code]ï¼Œåˆ™åœ¨ä¸–ç•Œç©ºé—´è€Œä¸æ˜¯ç‰©ä½“å±€éƒ¨ç©ºé—´ä¸­è®¡ç®—ä¸‰å¹³é¢æ˜ å°„。å¦"
+"è§ [member uv1_triplanar]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -70991,13 +71468,13 @@ msgid ""
msgstr ""
"设置镜é¢åå°„å…‰å¶çš„大å°ã€‚镜é¢å射光嶿˜¯å…‰æºå射的亮点。\n"
"[b]注æ„:[/b]这与 [member metallic] ä¸åŒï¼Œèƒ½é‡ä¸å®ˆæ’,所以在大多数情况下,应"
-"该将其ä¿ç•™åœ¨ [code]0.5[/code]。请å‚阅 [member roughness]。"
+"该将其ä¿ç•™åœ¨ [code]0.5[/code]。å¦è¯·å‚阅 [member roughness]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture used to specify metallic for an object. This is multiplied by "
"[member metallic]."
-msgstr "用于指定对象的金属质感。此值乘[member metallic]。"
+msgstr "用于指定对象的金属质感。此值乘 [member metallic]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71013,7 +71490,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid "If [code]true[/code], normal mapping is enabled."
-msgstr "如果[code]true[/code],则å¯ç”¨æ³•线映射。"
+msgstr "如果为 [code]true[/code],则å¯ç”¨æ³•线映射。"
#: doc/classes/SpatialMaterial.xml
msgid "The strength of the normal map's effect."
@@ -71054,9 +71531,9 @@ msgid ""
"Otherwise the scale is lost when billboarding. Only applies when [member "
"params_billboard_mode] is [constant BILLBOARD_ENABLED]."
msgstr ""
-"如果 [code]true[/code],ç€è‰²å™¨å°†ä¿æŒä¸ºç½‘格缩放设置。å¦åˆ™ï¼Œå½“åšå¹¿å‘Šç‰Œæ—¶ï¼Œç¼©æ”¾"
-"会丢失。仅在 [member params_billboard_mode] 为 [constant BILLBOARD_ENABLED] "
-"时适用。"
+"如果为 [code]true[/code],ç€è‰²å™¨å°†ä¿æŒä¸ºç½‘格缩放设置。å¦åˆ™ï¼Œå½“åšå¹¿å‘Šç‰Œæ—¶ï¼Œç¼©"
+"放会丢失。仅在 [member params_billboard_mode] 为 [constant "
+"BILLBOARD_ENABLED] 时适用。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71085,27 +71562,27 @@ msgstr ""
msgid ""
"Which side of the object is not drawn when backfaces are rendered. See [enum "
"CullMode]."
-msgstr "æ¸²æŸ“èƒŒé¢æ—¶ï¼Œä¸ç»˜åˆ¶å¯¹è±¡çš„哪一é¢ã€‚å‚阅 [enum CullMode]。"
+msgstr "æ¸²æŸ“èƒŒé¢æ—¶ï¼Œä¸ç»˜åˆ¶å¯¹è±¡çš„哪一é¢ã€‚è§ [enum CullMode]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"Determines when depth rendering takes place. See [enum DepthDrawMode]. See "
"also [member flags_transparent]."
msgstr ""
-"确定深度渲染å‘生的时间。请å‚é˜…æ·±åº¦ç»˜åˆ¶æ¨¡å¼ [enum DepthDrawMode] 。å¦è§"
+"确定深度渲染å‘生的时间。请å‚é˜…æ·±åº¦ç»˜åˆ¶æ¨¡å¼ [enum DepthDrawMode] 。å¦è¯·å‚阅 "
"[member flags_transparent]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"The algorithm used for diffuse light scattering. See [enum DiffuseMode]."
-msgstr "用于漫å射光散射的算法。å‚è§ [enum DiffuseMode]。"
+msgstr "用于漫åå°„å…‰æ•£å°„çš„ç®—æ³•ã€‚è§ [enum DiffuseMode]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"If [code]true[/code], enables the vertex grow setting. See [member "
"params_grow_amount]."
msgstr ""
-"如果[code]true[/code],å¯ç”¨é¡¶ç‚¹ç”Ÿé•¿è®¾ç½®ã€‚å‚è§[member params_grow_amount]。"
+"如果为 [code]true[/code],å¯ç”¨é¡¶ç‚¹ç”Ÿé•¿è®¾ç½®ã€‚å‚è§[member params_grow_amount]。"
#: doc/classes/SpatialMaterial.xml
msgid "Grows object vertices in the direction of their normals."
@@ -71128,7 +71605,7 @@ msgid ""
"If [code]true[/code], the shader will discard all pixels that have an alpha "
"value less than [member params_alpha_scissor_threshold]."
msgstr ""
-"如果[code]true[/code],ç€è‰²å™¨å°†ä¸¢å¼ƒæ‰€æœ‰alpha值å°äºŽ[member "
+"如果为 [code]true[/code],ç€è‰²å™¨å°†ä¸¢å¼ƒæ‰€æœ‰alpha值å°äºŽ[member "
"params_alpha_scissor_threshold]çš„åƒç´ ã€‚"
#: doc/classes/SpatialMaterial.xml
@@ -71145,7 +71622,7 @@ msgid ""
"If [code]true[/code], particle animations are looped. Only enabled when "
"using [constant BILLBOARD_PARTICLES]. See [member params_billboard_mode]."
msgstr ""
-"如果 [code]true[/code],循环粒å­åŠ¨ç”»ã€‚ä»…åœ¨ä½¿ç”¨ [constant "
+"如果为 [code]true[/code],循环粒å­åŠ¨ç”»ã€‚ä»…åœ¨ä½¿ç”¨ [constant "
"BILLBOARD_PARTICLES] æ—¶å¯ç”¨ã€‚å‚阅[member params_billboard_mode]。"
#: doc/classes/SpatialMaterial.xml
@@ -71168,8 +71645,8 @@ msgid ""
"If [code]true[/code], the proximity fade effect is enabled. The proximity "
"fade effect fades out each pixel based on its distance to another object."
msgstr ""
-"如果[code]true[/code],则å¯ç”¨æŽ¥è¿‘æ·¡å‡ºæ•ˆæžœã€‚é‚»è¿‘æ·¡å‡ºæ•ˆæžœä¼šæ ¹æ®æ¯ä¸ªåƒç´ ä¸Žå¦ä¸€ä¸ª"
-"对象的è·ç¦»æ·¡å‡ºã€‚"
+"如果为 [code]true[/code],则å¯ç”¨æŽ¥è¿‘æ·¡å‡ºæ•ˆæžœã€‚é‚»è¿‘æ·¡å‡ºæ•ˆæžœä¼šæ ¹æ®æ¯ä¸ªåƒç´ ä¸Žå¦"
+"一个对象的è·ç¦»æ·¡å‡ºã€‚"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71178,9 +71655,9 @@ msgid ""
"backend, the material's roughness value will affect the blurriness of the "
"refraction. Higher roughness values will make the refraction look blurrier."
msgstr ""
-"如果[code]true[/code],则å¯ç”¨æŠ˜å°„æ•ˆæžœã€‚æŠ˜å°„æ˜¯æ ¹æ®æ¥è‡ªç‰©ä½“åŽé¢çš„å…‰çº¿æ¥æ‰­æ›²é€æ˜Ž"
-"度的。当使用GLES3åŽç«¯æ—¶ï¼Œæè´¨çš„ç²—ç³™åº¦å€¼ä¼šå½±å“æŠ˜å°„çš„æ¨¡ç³Šåº¦ã€‚è¾ƒé«˜çš„ç²—ç³™åº¦å€¼ä¼šä½¿"
-"æŠ˜å°„çœ‹èµ·æ¥æ›´æ¨¡ç³Šã€‚"
+"如果为 [code]true[/code],则å¯ç”¨æŠ˜å°„æ•ˆæžœã€‚æŠ˜å°„æ˜¯æ ¹æ®æ¥è‡ªç‰©ä½“åŽé¢çš„å…‰çº¿æ¥æ‰­æ›²"
+"逿˜Žåº¦çš„。当使用GLES3åŽç«¯æ—¶ï¼Œæè´¨çš„ç²—ç³™åº¦å€¼ä¼šå½±å“æŠ˜å°„çš„æ¨¡ç³Šåº¦ã€‚è¾ƒé«˜çš„ç²—ç³™åº¦å€¼"
+"ä¼šä½¿æŠ˜å°„çœ‹èµ·æ¥æ›´æ¨¡ç³Šã€‚"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71217,7 +71694,7 @@ msgid ""
"[b]Note:[/b] Rim lighting is not visible if the material has [member "
"flags_unshaded] set to [code]true[/code]."
msgstr ""
-"如果 [code]true[/code],则å¯ç”¨è¾¹ç¼˜æ•ˆæžœã€‚边缘照明增加了物体上掠过角度的亮"
+"如果为 [code]true[/code],则å¯ç”¨è¾¹ç¼˜æ•ˆæžœã€‚边缘照明增加了物体上掠过角度的亮"
"度。\n"
"[b]注æ„:[/b]如果æè´¨å°† [member flags_unshaded] 设置为 [code]true[/code],则"
"边缘光照ä¸å¯è§ã€‚"
@@ -71226,7 +71703,7 @@ msgstr ""
msgid ""
"Texture used to set the strength of the rim lighting effect per-pixel. "
"Multiplied by [member rim]."
-msgstr "纹ç†ç”¨äºŽè®¾ç½®æ¯ä¸ªåƒç´ çš„边缘光照效果的强度。乘以[member rim]。"
+msgstr "纹ç†ç”¨äºŽè®¾ç½®æ¯ä¸ªåƒç´ çš„边缘光照效果的强度。乘以 [member rim]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71234,8 +71711,8 @@ msgid ""
"[code]0[/code] the light color is used, while [code]1[/code] means albedo "
"color is used. An intermediate value generally works best."
msgstr ""
-"渲染边缘效果时,混åˆå…‰ç…§è‰²å’Œå射色的数é‡ã€‚如果[code]0[/code]表示使用光色,"
-"[code]1[/code]表示使用å照色。一般æ¥è¯´ï¼Œä¸­é—´å€¼çš„æ•ˆæžœæœ€å¥½ã€‚"
+"渲染边缘效果时,混åˆå…‰ç…§è‰²å’Œå射色的数é‡ã€‚如果 [code]0[/code] 表示使用光色,"
+"[code]1[/code] 表示使用å照色。一般æ¥è¯´ï¼Œä¸­é—´å€¼çš„æ•ˆæžœæœ€å¥½ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71244,21 +71721,21 @@ msgid ""
"[member metallic]."
msgstr ""
"表é¢å射。[code]0[/code] 值表示一é¢å®Œç¾Žçš„镜åƒï¼Œè€Œ [code]1[/code] 值则完全模糊"
-"了å射。å¦è¯·å‚阅[member metallic]。"
+"了å射。å¦è¯·å‚阅 [member metallic]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture used to control the roughness per-pixel. Multiplied by [member "
"roughness]."
-msgstr "用于控制æ¯ä¸ªåƒç´ ç²—糙度的纹ç†ã€‚乘以[member roughness]。"
+msgstr "用于控制æ¯ä¸ªåƒç´ ç²—糙度的纹ç†ã€‚乘以 [member roughness]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"If [code]true[/code], subsurface scattering is enabled. Emulates light that "
"penetrates an object's surface, is scattered, and then emerges."
msgstr ""
-"如果[code]true[/code],则å¯ç”¨æ¬¡è¡¨é¢æ•£å°„。模拟光线穿é€ç‰©ä½“表é¢ï¼Œè¢«æ•£å°„,然åŽå‡º"
-"现。"
+"如果为 [code]true[/code],则å¯ç”¨æ¬¡è¡¨é¢æ•£å°„。模拟光线穿é€ç‰©ä½“表é¢ï¼Œè¢«æ•£å°„,然"
+"åŽå‡ºçŽ°ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "The strength of the subsurface scattering effect."
@@ -71269,7 +71746,7 @@ msgid ""
"Texture used to control the subsurface scattering strength. Stored in the "
"red texture channel. Multiplied by [member subsurf_scatter_strength]."
msgstr ""
-"ç”¨äºŽæŽ§åˆ¶æ¬¡è¡¨é¢æ•£å°„强度的纹ç†ã€‚存储在红色纹ç†é€šé“中。乘以[member "
+"ç”¨äºŽæŽ§åˆ¶æ¬¡è¡¨é¢æ•£å°„强度的纹ç†ã€‚存储在红色纹ç†é€šé“中。乘以 [member "
"subsurf_scatter_strength]。"
#: doc/classes/SpatialMaterial.xml
@@ -71280,13 +71757,13 @@ msgstr "传输效果使用的颜色。表示穿过物体的光。"
#: doc/classes/SpatialMaterial.xml
msgid "If [code]true[/code], the transmission effect is enabled."
-msgstr "如果 [code]true[/code],则å¯ç”¨ä¼ è¾“效果。"
+msgstr "如果为 [code]true[/code],则å¯ç”¨ä¼ è¾“效果。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture used to control the transmission effect per-pixel. Added to [member "
"transmission]."
-msgstr "纹ç†ç”¨äºŽæŽ§åˆ¶æ¯ä¸ªåƒç´ çš„传输效果。添加到[member transmission]。"
+msgstr "纹ç†ç”¨äºŽæŽ§åˆ¶æ¯ä¸ªåƒç´ çš„传输效果。添加到 [member transmission]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71302,7 +71779,7 @@ msgid ""
"How much to scale the [code]UV[/code] coordinates. This is multiplied by "
"[code]UV[/code] in the vertex function."
msgstr ""
-"缩放 [code]UV[/code] åæ ‡çš„多少。这个值乘以顶点函数中的[code]UV[/code]。"
+"缩放 [code]UV[/code] åæ ‡çš„多少。这个值乘以顶点函数中的 [code]UV[/code]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71317,12 +71794,12 @@ msgid ""
"because it is blending the texture between the three axes, it is unsuitable "
"when you are trying to achieve crisp texturing."
msgstr ""
-"如果 [code]true[/code],纹ç†å°†ä¸ä½¿ç”¨ [code]UV[/code],而是使用三平é¢çº¹ç†æŸ¥æ‰¾"
-"æ¥ç¡®å®šå¦‚何应用纹ç†ã€‚三平é¢çº¹ç†ä½¿ç”¨å¯¹è±¡è¡¨é¢çš„æ–¹å‘æ¥æ··åˆçº¹ç†å标之间。它从æºçº¹"
-"ç†ä¸­è¯»å–3次,æ¯ä¸ªè½´ä¸€æ¬¡ï¼Œç„¶åŽæ ¹æ®åƒç´ ä¸Žæ¯ä¸ªè½´çš„紧密程度在结果之间进行混åˆã€‚è¿™"
-"通常用于自然特å¾ï¼Œä»¥èŽ·å¾—çœŸå®žçš„æè´¨æ··åˆã€‚由于三平é¢çº¹ç†å¤„ç†æ¯ä¸€ä¸ªåƒç´ éœ€è¦æ›´å¤š"
-"的纹ç†è¯»å–,所以它比普通的UV纹ç†å¤„ç†è¦æ…¢å¾—多。此外,由于它是在三个轴之间混åˆ"
-"纹ç†ï¼Œæ‰€ä»¥å½“ä½ è¯•å›¾å®žçŽ°æ¸…æ™°çš„çº¹ç†æ—¶ï¼Œå®ƒæ˜¯ä¸åˆé€‚的。"
+"如果为 [code]true[/code],纹ç†å°†ä¸ä½¿ç”¨ [code]UV[/code],而是使用三平é¢çº¹ç†æŸ¥"
+"找æ¥ç¡®å®šå¦‚何应用纹ç†ã€‚三平é¢çº¹ç†ä½¿ç”¨å¯¹è±¡è¡¨é¢çš„æ–¹å‘æ¥æ··åˆçº¹ç†å标之间。它从æº"
+"纹ç†ä¸­è¯»å–3次,æ¯ä¸ªè½´ä¸€æ¬¡ï¼Œç„¶åŽæ ¹æ®åƒç´ ä¸Žæ¯ä¸ªè½´çš„紧密程度在结果之间进行混åˆã€‚"
+"这通常用于自然特å¾ï¼Œä»¥èŽ·å¾—çœŸå®žçš„æè´¨æ··åˆã€‚由于三平é¢çº¹ç†å¤„ç†æ¯ä¸€ä¸ªåƒç´ éœ€è¦æ›´"
+"多的纹ç†è¯»å–,所以它比普通的UV纹ç†å¤„ç†è¦æ…¢å¾—多。此外,由于它是在三个轴之间混"
+"åˆçº¹ç†ï¼Œæ‰€ä»¥å½“ä½ è¯•å›¾å®žçŽ°æ¸…æ™°çš„çº¹ç†æ—¶ï¼Œå®ƒæ˜¯ä¸åˆé€‚的。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71336,7 +71813,7 @@ msgid ""
"added to [code]UV2[/code] in the vertex function. This can be used to offset "
"a texture."
msgstr ""
-"[code]UV2[/code]åæ ‡çš„åç§»é‡ã€‚这个é‡å°†è¢«æ·»åŠ åˆ°é¡¶ç‚¹å‡½æ•°ä¸­çš„ [code]UV2[/code] "
+"[code]UV2[/code] åæ ‡çš„åç§»é‡ã€‚这个é‡å°†è¢«æ·»åŠ åˆ°é¡¶ç‚¹å‡½æ•°ä¸­çš„ [code]UV2[/code] "
"中。这å¯ä»¥ç”¨æ¥å移纹ç†ã€‚"
#: doc/classes/SpatialMaterial.xml
@@ -71344,7 +71821,7 @@ msgid ""
"How much to scale the [code]UV2[/code] coordinates. This is multiplied by "
"[code]UV2[/code] in the vertex function."
msgstr ""
-"缩放 [code]UV[/code] åæ ‡çš„多少。这个值乘以顶点函数中的[code]UV[/code]。"
+"缩放 [code]UV[/code] åæ ‡çš„多少。这个值乘以顶点函数中的 [code]UV[/code]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71359,21 +71836,21 @@ msgid ""
"because it is blending the texture between the three axes, it is unsuitable "
"when you are trying to achieve crisp texturing."
msgstr ""
-"如果 [code]true[/code],纹ç†å°†ä¸ä½¿ç”¨ [code]UV[/code],而是使用三平é¢çº¹ç†æŸ¥æ‰¾"
-"æ¥ç¡®å®šå¦‚何应用纹ç†ã€‚三平é¢çº¹ç†ä½¿ç”¨å¯¹è±¡è¡¨é¢çš„æ–¹å‘æ¥æ··åˆçº¹ç†å标之间。它从æºçº¹"
-"ç†ä¸­è¯»å– 3 次,æ¯ä¸ªè½´ä¸€æ¬¡ï¼Œç„¶åŽæ ¹æ®åƒç´ ä¸Žæ¯ä¸ªè½´çš„紧密程度在结果之间进行混åˆã€‚"
-"这通常用于自然特å¾ï¼Œä»¥èŽ·å¾—çœŸå®žçš„æè´¨æ··åˆã€‚由于三平é¢çº¹ç†å¤„ç†æ¯ä¸€ä¸ªåƒç´ éœ€è¦æ›´"
-"多的纹ç†è¯»å–,所以它比普通的 UV 纹ç†å¤„ç†è¦æ…¢å¾—多。此外,由于它是在三个轴之间"
-"æ··åˆçº¹ç†ï¼Œæ‰€ä»¥å½“ä½ è¯•å›¾å®žçŽ°æ¸…æ™°çš„çº¹ç†æ—¶ï¼Œå®ƒæ˜¯ä¸åˆé€‚的。"
+"如果为 [code]true[/code],纹ç†å°†ä¸ä½¿ç”¨ [code]UV[/code],而是使用三平é¢çº¹ç†æŸ¥"
+"找æ¥ç¡®å®šå¦‚何应用纹ç†ã€‚三平é¢çº¹ç†ä½¿ç”¨å¯¹è±¡è¡¨é¢çš„æ–¹å‘æ¥æ··åˆçº¹ç†å标之间。它从æº"
+"纹ç†ä¸­è¯»å– 3 次,æ¯ä¸ªè½´ä¸€æ¬¡ï¼Œç„¶åŽæ ¹æ®åƒç´ ä¸Žæ¯ä¸ªè½´çš„紧密程度在结果之间进行混"
+"åˆã€‚这通常用于自然特å¾ï¼Œä»¥èŽ·å¾—çœŸå®žçš„æè´¨æ··åˆã€‚由于三平é¢çº¹ç†å¤„ç†æ¯ä¸€ä¸ªåƒç´ éœ€"
+"è¦æ›´å¤šçš„纹ç†è¯»å–,所以它比普通的 UV 纹ç†å¤„ç†è¦æ…¢å¾—多。此外,由于它是在三个轴"
+"之间混åˆçº¹ç†ï¼Œæ‰€ä»¥å½“ä½ è¯•å›¾å®žçŽ°æ¸…æ™°çš„çº¹ç†æ—¶ï¼Œå®ƒæ˜¯ä¸åˆé€‚的。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"If [code]true[/code], the model's vertex colors are processed as sRGB mode."
-msgstr "如果[code]true[/code],则模型的顶点颜色将作为 sRGB 模å¼å¤„ç†ã€‚"
+msgstr "如果为 [code]true[/code],则模型的顶点颜色将作为 sRGB 模å¼å¤„ç†ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "If [code]true[/code], the vertex color is used as albedo color."
-msgstr "如果[code]true[/code],则使用顶点颜色作为å射率颜色。"
+msgstr "如果为 [code]true[/code],则使用顶点颜色作为å射率颜色。"
#: doc/classes/SpatialMaterial.xml
msgid "Texture specifying per-pixel color."
@@ -71407,7 +71884,7 @@ msgstr "指定æ¯åƒç´ æ¸…漆值的纹ç†ã€‚"
msgid ""
"Texture specifying per-pixel flowmap direction for use with [member "
"anisotropy]."
-msgstr "指定æ¯ä¸ªåƒç´ æµå›¾æ–¹å‘的纹ç†ï¼Œç”¨äºŽ[member anisotropy]。"
+msgstr "指定æ¯ä¸ªåƒç´ æµå›¾æ–¹å‘的纹ç†ï¼Œç”¨äºŽ [member anisotropy]。"
#: doc/classes/SpatialMaterial.xml
msgid "Texture specifying per-pixel ambient occlusion value."
@@ -71443,15 +71920,15 @@ msgstr "指定æ¯ä¸ªåƒç´ ç»†èŠ‚æ³•çº¿çš„çº¹ç†ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Represents the size of the [enum TextureParam] enum."
-msgstr "表示[enum TextureParam]枚举的大å°ã€‚"
+msgstr "表示 [enum TextureParam] 枚举的大å°ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Use [code]UV[/code] with the detail texture."
-msgstr "使用[code]UV[/code]与细节纹ç†ã€‚"
+msgstr "使用 [code]UV[/code] 与细节纹ç†ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Use [code]UV2[/code] with the detail texture."
-msgstr "使用[code]UV2[/code]与细节纹ç†ã€‚"
+msgstr "使用 [code]UV2[/code] 与细节纹ç†ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member flags_transparent]."
@@ -71459,19 +71936,19 @@ msgstr "用于设置 [member flags_transparent] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member emission_enabled]."
-msgstr "用于设置[member emission_enabled]的常é‡ã€‚"
+msgstr "用于设置 [member emission_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member normal_enabled]."
-msgstr "用于设置[member normal_enabled]的常é‡ã€‚"
+msgstr "用于设置 [member normal_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member rim_enabled]."
-msgstr "用于设置[member rim_enabled]的常é‡ã€‚"
+msgstr "用于设置 [member rim_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member clearcoat_enabled]."
-msgstr "用于设置[member clearcoat_enabled]的常é‡ã€‚"
+msgstr "用于设置 [member clearcoat_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member anisotropy_enabled]."
@@ -71479,7 +71956,7 @@ msgstr "用于设置 [member anisotropy_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member ao_enabled]."
-msgstr "用于设置[member ao_enabled]的常é‡ã€‚"
+msgstr "用于设置 [member ao_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member depth_enabled]."
@@ -71487,7 +71964,7 @@ msgstr "用于设置 [member depth_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member subsurf_scatter_enabled]."
-msgstr "用于设置[member subsurf_scatter_enabled]的常é‡ã€‚"
+msgstr "用于设置 [member subsurf_scatter_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member transmission_enabled]."
@@ -71495,11 +71972,11 @@ msgstr "用于设置 [member transmission_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member refraction_enabled]."
-msgstr "用于设置[member refraction_enabled]的常é‡ã€‚"
+msgstr "用于设置 [member refraction_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Constant for setting [member detail_enabled]."
-msgstr "用于设置[member detail_enabled]的常é‡ã€‚"
+msgstr "用于设置 [member detail_enabled] 的常é‡ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71571,7 +72048,7 @@ msgstr "å°† [code]ALBEDO[/code] 设置为网格中指定的æ¯é¡¶ç‚¹é¢œè‰²ã€‚"
msgid ""
"Vertex color is in sRGB space and needs to be converted to linear. Only "
"applies in the GLES3 renderer."
-msgstr "顶点颜色在sRGB空间,需è¦è½¬æˆçº¿æ€§ã€‚仅适用于 GLES3 渲染器。"
+msgstr "顶点颜色在 sRGB 空间,需è¦è½¬æˆçº¿æ€§ã€‚仅适用于 GLES3 渲染器。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71600,28 +72077,28 @@ msgstr ""
msgid ""
"Use triplanar texture lookup for all texture lookups that would normally use "
"[code]UV[/code]."
-msgstr "对所有通常会使用[code]UV[/code]çš„çº¹ç†æŸ¥æ‰¾ä½¿ç”¨ä¸‰å¹³é¢çº¹ç†æŸ¥æ‰¾ã€‚"
+msgstr "对所有通常会使用 [code]UV[/code] çš„çº¹ç†æŸ¥æ‰¾ä½¿ç”¨ä¸‰å¹³é¢çº¹ç†æŸ¥æ‰¾ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid ""
"Use triplanar texture lookup for all texture lookups that would normally use "
"[code]UV2[/code]."
-msgstr "对所有通常会使用[code]UV2[/code]çš„çº¹ç†æŸ¥æ‰¾ä½¿ç”¨ä¸‰å¹³é¢çº¹ç†æŸ¥æ‰¾ã€‚"
+msgstr "对所有通常会使用 [code]UV2[/code] çš„çº¹ç†æŸ¥æ‰¾ä½¿ç”¨ä¸‰å¹³é¢çº¹ç†æŸ¥æ‰¾ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid ""
"Use [code]UV2[/code] coordinates to look up from the [member ao_texture]."
-msgstr "使用[code]UV2[/code]åæ ‡ä»Ž[member ao_texture]中查找。"
+msgstr "使用 [code]UV2[/code] åæ ‡ä»Ž [member ao_texture] 中查找。"
#: doc/classes/SpatialMaterial.xml
msgid ""
"Use [code]UV2[/code] coordinates to look up from the [member "
"emission_texture]."
-msgstr "使用[code]UV2[/code]åæ ‡ï¼Œä»Ž[member emission_texture]中查找。"
+msgstr "使用 [code]UV2[/code] åæ ‡ä»Ž [member emission_texture] 中查找。"
#: doc/classes/SpatialMaterial.xml
msgid "Use alpha scissor. Set by [member params_use_alpha_scissor]."
-msgstr "使用alpha剪刀。由 [member params_use_alpha_scissor] 设置。"
+msgstr "使用 Alpha è£å‰ªã€‚ç”± [member params_use_alpha_scissor] 设置。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -71631,7 +72108,7 @@ msgstr "在三平é¢çº¹ç†æŸ¥æ‰¾ä¸­ä½¿ç”¨ä¸–ç•Œåæ ‡è€Œä¸æ˜¯å±€éƒ¨å标。"
#: doc/classes/SpatialMaterial.xml
msgid "Forces the shader to convert albedo from sRGB space to linear space."
-msgstr "强制ç€è‰²å™¨å°†å射率从sRGB空间转æ¢ä¸ºçº¿æ€§ç©ºé—´ã€‚"
+msgstr "强制ç€è‰²å™¨å°†å射率从 sRGB 空间转æ¢ä¸ºçº¿æ€§ç©ºé—´ã€‚"
#: doc/classes/SpatialMaterial.xml
msgid "Disables receiving shadows from other objects."
@@ -71659,7 +72136,7 @@ msgstr "漫散射忽略了粗糙度。"
#: doc/classes/SpatialMaterial.xml
msgid "Extends Lambert to cover more than 90 degrees when roughness increases."
-msgstr "当粗糙度增加时,将Lambert延伸到90度以上。"
+msgstr "当粗糙度增加时,将 Lambert 延伸到 90 度以上。"
#: doc/classes/SpatialMaterial.xml
msgid "Attempts to use roughness to emulate microsurfacing."
@@ -71704,10 +72181,10 @@ msgid ""
"The [member ParticlesMaterial.anim_speed] or [member CPUParticles."
"anim_speed] should also be set to a positive value for the animation to play."
msgstr ""
-"当分é…ç»™[Particles]å’Œ[CPUParticles]节点时用于粒å­ç³»ç»Ÿã€‚å¯ç”¨"
-"[code]particles_anim_*[/code]属性。\n"
-"为了播放动画,[member ParticlesMaterial.anim_speed]或[member CPUParticles."
-"anim_speed]也应该被设置为正值。"
+"当分é…ç»™ [Particles] å’Œ [CPUParticles] 节点时用于粒å­ç³»ç»Ÿã€‚å¯ç”¨ "
+"[code]particles_anim_*[/code] 属性。\n"
+"为了播放动画,[member ParticlesMaterial.anim_speed] 或 [member CPUParticles."
+"anim_speed] 也应该被设置为正值。"
#: doc/classes/SpatialMaterial.xml
msgid "Used to read from the red channel of a texture."
@@ -71723,7 +72200,7 @@ msgstr "用æ¥è¯»å–纹ç†çš„è“色通é“。"
#: doc/classes/SpatialMaterial.xml
msgid "Used to read from the alpha channel of a texture."
-msgstr "用æ¥è¯»å–纹ç†çš„alpha通é“。"
+msgstr "用æ¥è¯»å–纹ç†çš„ Alpha 通é“。"
#: doc/classes/SpatialMaterial.xml
msgid "Adds the emission color to the color from the emission texture."
@@ -71804,8 +72281,8 @@ msgid ""
"[b]Note:[/b] To get a regular hemisphere, the height and radius of the "
"sphere must be equal."
msgstr ""
-"如果 [code]true[/code],则创建一个åŠçƒè€Œä¸æ˜¯ä¸€ä¸ªå®Œæ•´çš„çƒä½“。\n"
-"[b]注:[/b]è¦å¾—到一个规则的åŠçƒï¼Œçƒä½“的高度和åŠå¾„必须相等。"
+"如果为 [code]true[/code],则创建一个åŠçƒè€Œä¸æ˜¯ä¸€ä¸ªå®Œæ•´çš„çƒä½“。\n"
+"[b]注æ„:[/b]è¦å¾—到一个规则的åŠçƒï¼Œçƒä½“的高度和åŠå¾„必须相等。"
#: doc/classes/SphereMesh.xml
msgid "Number of radial segments on the sphere."
@@ -71902,7 +72379,7 @@ msgid ""
"If [code]true[/code], the [SpinBox] will be editable. Otherwise, it will be "
"read only."
msgstr ""
-"如果 [code]true[/code],则 [SpinBox] 将是å¯ç¼–辑的。å¦åˆ™ï¼Œå®ƒå°†æ˜¯åªè¯»çš„。"
+"如果为 [code]true[/code],则 [SpinBox] 将是å¯ç¼–辑的。å¦åˆ™ï¼Œå®ƒå°†æ˜¯åªè¯»çš„。"
#: doc/classes/SpinBox.xml
msgid ""
@@ -71942,7 +72419,7 @@ msgid ""
"If [code]true[/code], the area of the first [Control] will be collapsed and "
"the dragger will be disabled."
msgstr ""
-"如果 [code]true[/code],第一个 [Control] 的区域将被折å å¹¶ä¸”拖动器将被ç¦ç”¨ã€‚"
+"如果为 [code]true[/code],第一个 [Control] 的区域将被折å å¹¶ä¸”拖动器将被ç¦ç”¨ã€‚"
#: doc/classes/SplitContainer.xml
msgid ""
@@ -72165,7 +72642,7 @@ msgstr ""
#: doc/classes/Sprite.xml
msgid "If [code]true[/code], texture is centered."
-msgstr "如果 [code]true[/code],纹ç†å±…中。"
+msgstr "如果为 [code]true[/code],纹ç†å±…中。"
#: doc/classes/Sprite.xml doc/classes/Sprite3D.xml
msgid ""
@@ -72206,19 +72683,19 @@ msgid ""
"If [code]true[/code], texture is cut from a larger atlas texture. See "
"[member region_rect]."
msgstr ""
-"如果 [code]true[/code],则从较大的图集纹ç†ä¸­å‰ªåˆ‡çº¹ç†ã€‚å‚阅 [member "
+"如果为 [code]true[/code],则从较大的图集纹ç†ä¸­å‰ªåˆ‡çº¹ç†ã€‚è§ [member "
"region_rect]。"
#: doc/classes/Sprite.xml
msgid "If [code]true[/code], the outermost pixels get blurred out."
-msgstr "如果 [code]true[/code],最外é¢çš„åƒç´ ä¼šå˜å¾—模糊。"
+msgstr "如果为 [code]true[/code],最外é¢çš„åƒç´ ä¼šå˜å¾—模糊。"
#: doc/classes/Sprite.xml doc/classes/Sprite3D.xml
msgid ""
"The region of the atlas texture to display. [member region_enabled] must be "
"[code]true[/code]."
msgstr ""
-"è¦æ˜¾ç¤ºçš„图集纹ç†åŒºåŸŸã€‚ [member region_enabled] 必须是 [code]true[/code]。"
+"è¦æ˜¾ç¤ºçš„图集纹ç†åŒºåŸŸã€‚[member region_enabled] 必须是 [code]true[/code]。"
#: doc/classes/Sprite.xml
msgid "[Texture] object to draw."
@@ -72254,7 +72731,7 @@ msgid ""
"If [code]true[/code], texture will be cut from a larger atlas texture. See "
"[member region_rect]."
msgstr ""
-"如果 [code]true[/code],纹ç†å°†ä»Žè¾ƒå¤§çš„图集纹ç†ä¸­å‰ªåˆ‡ã€‚å‚阅 [member "
+"如果为 [code]true[/code],纹ç†å°†ä»Žè¾ƒå¤§çš„图集纹ç†ä¸­å‰ªåˆ‡ã€‚å‚阅 [member "
"region_rect]。"
#: doc/classes/Sprite3D.xml
@@ -72360,14 +72837,14 @@ msgstr ""
msgid ""
"If [code]true[/code], the [Light] in the [Environment] has effects on the "
"sprite."
-msgstr "如果 [code]true[/code],则 [Environment] 中的 [Light] å¯¹ç²¾çµæœ‰å½±å“。"
+msgstr "如果为 [code]true[/code],则 [Environment] 中的 [Light] å¯¹ç²¾çµæœ‰å½±å“。"
#: doc/classes/SpriteBase3D.xml
msgid ""
"If [code]true[/code], the texture's transparency and the opacity are used to "
"make those parts of the sprite invisible."
msgstr ""
-"如果 [code]true[/code],纹ç†çš„逿˜Žåº¦å’Œä¸é€æ˜Žåº¦ç”¨äºŽä½¿ç²¾çµçš„这些部分ä¸å¯è§ã€‚"
+"如果为 [code]true[/code],纹ç†çš„逿˜Žåº¦å’Œä¸é€æ˜Žåº¦ç”¨äºŽä½¿ç²¾çµçš„这些部分ä¸å¯è§ã€‚"
#: doc/classes/SpriteBase3D.xml
msgid ""
@@ -72915,7 +73392,7 @@ msgstr "一ç§é”™è¯¯çжæ€ï¼Œæ˜¾ç¤ºä¸»æœºæäº¤çš„SSLè¯ä¹¦åŸŸä¸Žè¯·æ±‚验è¯çš„
#: doc/classes/StreamPeerTCP.xml
msgid "TCP stream peer."
-msgstr "TCPæµå¯¹ç­‰ä½“。"
+msgstr "TCP æµå¯¹ç­‰ä½“。"
#: doc/classes/StreamPeerTCP.xml
msgid ""
@@ -72989,11 +73466,11 @@ msgstr "表示处于错误状æ€çš„ [StreamPeerTCP] 的状æ€ã€‚"
#: doc/classes/StreamTexture.xml
msgid "A [code].stex[/code] texture."
-msgstr "[code].stex[/code]纹ç†."
+msgstr "[code].stex[/code] 纹ç†ã€‚"
#: doc/classes/StreamTexture.xml
msgid "A texture that is loaded from a [code].stex[/code] file."
-msgstr "从[code].stex[/code]文件加载的纹ç†ã€‚"
+msgstr "从 [code].stex[/code] 文件加载的纹ç†ã€‚"
#: doc/classes/StreamTexture.xml
msgid "Loads the texture from the given path."
@@ -73289,9 +73766,55 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
-"æ ¼å¼åŒ–字符串,将所有的 [code]placeholder[/code] 替æ¢ä¸º [code]values[/code]。"
+"æ ¼å¼åŒ–字符串,将所有的 [code]placeholder[/code] 替æ¢ä¸º [code]values[/code] 中"
+"的元素。\n"
+"[code]values[/code] å¯ä»¥æ˜¯ [Dictionary] 或 [Array]。[code]placeholder[/code] "
+"中的下划线都会事先被替æ¢ä¸ºå¯¹åº”的键。数组元素使用其索引å·ä½œä¸ºé”®ã€‚\n"
+"[codeblock]\n"
+"# 输出:Waiting for Godot 是 Samuel Beckett çš„æˆå‰§ï¼ŒGodot 引擎由此得å。\n"
+"var use_array_values = \"Waiting for {0} 是 {1} çš„æˆå‰§ï¼Œ{0} 引擎由此得"
+"å。\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# 输出:第 42 å·ç”¨æˆ·æ˜¯ Godot。\n"
+"print(\"第 {id} å·ç”¨æˆ·æ˜¯ {name}。\".format({\"id\": 42, \"name\": "
+"\"Godot\"}))\n"
+"[/codeblock]\n"
+"[code]values[/code] 为数组时还会进行一些é¢å¤–的处ç†ã€‚如果 [code]placeholder[/"
+"code] 中ä¸åŒ…å«ä¸‹åˆ’çº¿ï¼Œè¯¥æ•°ç»„ä¸­çš„å…ƒç´ ä¼šä¾æ¬¡å¯¹å‡ºçŽ°çš„å ä½ç¬¦è¿›è¡Œæ›¿æ¢ï¼›å¦‚果数组元"
+"素是一个包å«ä¸¤ä¸ªå…ƒç´ çš„æ•°ç»„,那么它就会被解释为键值对。\n"
+"[codeblock]\n"
+"# 输出:第 42 å·ç”¨æˆ·æ˜¯ Godot。\n"
+"print(\"第 {} å·ç”¨æˆ·æ˜¯ {}。\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"第 {id} å·ç”¨æˆ·æ˜¯ {name}。\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
#: doc/classes/String.xml
msgid "If the string is a valid file path, returns the base directory name."
@@ -73559,20 +74082,20 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
"å¦‚æžœè¯¥å­—ç¬¦ä¸²åŒ…å«æœ‰æ•ˆçš„æ•´æ•°ï¼Œåˆ™è¿”回 [code]true[/code]\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # 输出“Trueâ€\n"
-"print(\"14.6\".is_valid_int()) # 输出“Falseâ€\n"
-"print(\"L\".is_valid_int()) # 输出“Falseâ€\n"
-"print(\"+3\".is_valid_int()) # 输出“Trueâ€\n"
-"print(\"-12\".is_valid_int()) # 输出“Trueâ€\n"
+"print(\"7\".is_valid_integer()) # 输出“Trueâ€\n"
+"print(\"14.6\".is_valid_integer()) # 输出“Falseâ€\n"
+"print(\"L\".is_valid_integer()) # 输出“Falseâ€\n"
+"print(\"+3\".is_valid_integer()) # 输出“Trueâ€\n"
+"print(\"-12\".is_valid_integer()) # 输出“Trueâ€\n"
"[/codeblock]"
#: doc/classes/String.xml
@@ -73752,7 +74275,7 @@ msgstr "æ ¼å¼åŒ–æ•°å­—ï¼Œåœ¨å°æ•°ç‚¹å‰å…·æœ‰ [code]digits[/code] 的确切数
#: doc/classes/String.xml
msgid "Decode a percent-encoded string. See [method percent_encode]."
-msgstr "è§£ç ä¸€ä¸ªç™¾åˆ†æ¯”ç¼–ç çš„字符串。å‚阅[method percent_encode]。"
+msgstr "è§£ç ä¸€ä¸ªç™¾åˆ†æ¯”ç¼–ç çš„å­—ç¬¦ä¸²ã€‚è§ [method percent_encode]。"
#: doc/classes/String.xml
msgid ""
@@ -73768,7 +74291,7 @@ msgid ""
"the string as a subpath. E.g. [code]\"this/is\".plus_file(\"path\") == "
"\"this/is/path\"[/code]."
msgstr ""
-"如果字符串是路径,则在字符串末尾连接 [code]file[/code] 作为å­è·¯å¾„。例如。 "
+"如果字符串是路径,则在字符串末尾连接 [code]file[/code] 作为å­è·¯å¾„。例如。"
"[code]\"this/is\".plus_file(\"path\") == \"this/is/path\"[/code]。"
#: doc/classes/String.xml
@@ -73915,7 +74438,7 @@ msgid ""
"If you need to split strings with more complex rules, use the [RegEx] class "
"instead."
msgstr ""
-"通过 [code]delimiter[/code] 字符串拆分字符串并返回å­å­—符串数组。 "
+"通过 [code]delimiter[/code] 字符串拆分字符串并返回å­å­—符串数组。"
"[code]delimiter[/code] å¯ä»¥æ˜¯ä»»æ„长度。\n"
"如果指定了 [code]maxsplit[/code],它定义了从左边到 [code]maxsplit[/code] 的分"
"割次数。默认值 [code]0[/code] 表示所有项目都被拆分。\n"
@@ -74098,9 +74621,9 @@ msgid ""
"[code]focus[/code] [StyleBox] more reusable across different nodes."
msgstr ""
"æ ·å¼ç›’ StyleBox æ˜¯ä¸€ç§ [Resource],它æä¾›äº†ä¸€ä¸ªæŠ½è±¡åŸºç±»ï¼Œç”¨äºŽä¸º UI 绘制风格化"
-"的框。 StyleBox 被用于绘制按钮的样å¼ã€è¡Œç¼–è¾‘æ¡†çš„èƒŒæ™¯ã€æ ‘的背景等,也被用作测"
-"试指针信å·çš„逿˜ŽæŽ©ç ã€‚å°† StyleBox æŒ‡å®šä¸ºæŽ§ä»¶çš„æŽ©ç æ—¶ï¼Œå¦‚æžœåœ¨æŽ©ç æµ‹è¯•失败,点"
-"击和è¿åŠ¨ä¿¡å·å°†é€è¿‡å®ƒä¼ é€’至下层控件。\n"
+"的框。StyleBox 被用于绘制按钮的样å¼ã€è¡Œç¼–è¾‘æ¡†çš„èƒŒæ™¯ã€æ ‘的背景等,也被用作测试"
+"指针信å·çš„逿˜ŽæŽ©ç ã€‚å°† StyleBox æŒ‡å®šä¸ºæŽ§ä»¶çš„æŽ©ç æ—¶ï¼Œå¦‚æžœåœ¨æŽ©ç æµ‹è¯•失败,点击"
+"å’Œè¿åŠ¨ä¿¡å·å°†é€è¿‡å®ƒä¼ é€’至下层控件。\n"
"[b]注æ„:[/b]对于有 [i]主题属性[/i] çš„ [Control] 控件,å为 [code]focus[/"
"code] çš„ [StyleBox] 会显示在å为 [code]normal[/code]ã€[code]hover[/code]ã€"
"[code]pressed[/code] 的 [StyleBox]之上。这样的行为有助于 [code]focus[/code] "
@@ -74108,13 +74631,16 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
-"使用具有给定 [RID] 的 [CanvasItem] 绘制此StyleBox。\n"
-"您å¯ä»¥åœ¨ [CanvasItem] 派生节点上使用 [method Object.get_instance_id] èŽ·å– "
-"[RID] 值。"
+"使用由给定的 [RID] 标识的画布项绘制这个样å¼ç›’。\n"
+"[RID] 值既å¯ä»¥é€šè¿‡å¯¹çŽ°æœ‰çš„åŸºäºŽ [CanvasItem] 节点调用 [method CanvasItem."
+"get_canvas_item] 获得,也å¯ä»¥é€šè¿‡ [method VisualServer.canvas_item_create] ç›´"
+"接在 [VisualServer] 上创建画布项获得。"
#: doc/classes/StyleBox.xml
msgid "Returns the size of this [StyleBox] without the margins."
@@ -74273,8 +74799,7 @@ msgid ""
"Returns the given [code]margin[/code]'s border width. See [enum Margin] for "
"possible values."
msgstr ""
-"返回给定的 [code]margin[/code] 的边框宽度。有关å¯èƒ½çš„值,请å‚阅 [enum "
-"Margin]。"
+"返回给定的 [code]margin[/code] 的边框宽度。å¯èƒ½çš„å–å€¼è§ [enum Margin]。"
#: doc/classes/StyleBoxFlat.xml
msgid "Returns the smallest border width out of all four borders."
@@ -74284,23 +74809,22 @@ msgstr "返回所有四个边界中最å°çš„边框宽度。"
msgid ""
"Returns the given [code]corner[/code]'s radius. See [enum Corner] for "
"possible values."
-msgstr ""
-"返回给定的 [code]corner[/code] çš„åŠå¾„。有关å¯èƒ½çš„值,请å‚阅 [enum Corner]。"
+msgstr "返回给定的 [code]corner[/code] çš„åŠå¾„。å¯èƒ½çš„å–å€¼è§ [enum Corner]。"
#: doc/classes/StyleBoxFlat.xml doc/classes/StyleBoxTexture.xml
msgid ""
"Returns the size of the given [code]margin[/code]'s expand margin. See [enum "
"Margin] for possible values."
msgstr ""
-"返回给定的[code]margin[/code]的扩展边è·çš„大å°ã€‚å¯èƒ½çš„值è§[enum Margin]。"
+"返回给定的 [code]margin[/code] 的扩展边è·çš„大å°ã€‚å¯èƒ½çš„å–å€¼è§ [enum Margin]。"
#: doc/classes/StyleBoxFlat.xml
msgid ""
"Sets the border width to [code]width[/code] pixels for the given "
"[code]margin[/code]. See [enum Margin] for possible values."
msgstr ""
-"用给定的[code]margin[/code]设置边界宽度为[code]width[/code]åƒç´ ã€‚å¯èƒ½çš„值è§"
-"[enum Margin]。"
+"用给定的 [code]margin[/code] 设置边界宽度为 [code]width[/code] åƒç´ ã€‚å¯èƒ½çš„å–"
+"å€¼è§ [enum Margin]。"
#: doc/classes/StyleBoxFlat.xml
msgid "Sets the border width to [code]width[/code] pixels for all margins."
@@ -74311,8 +74835,8 @@ msgid ""
"Sets the corner radius to [code]radius[/code] pixels for the given "
"[code]corner[/code]. See [enum Corner] for possible values."
msgstr ""
-"用给定的[code]corner[/code]设置角的åŠå¾„为[code]radius[/code]åƒç´ ã€‚å¯èƒ½çš„值è§"
-"[enum Corner]。"
+"用给定的 [code]corner[/code] 设置角的åŠå¾„为 [code]radius[/code] åƒç´ ã€‚å¯èƒ½çš„"
+"å–å€¼è§ [enum Corner]。"
#: doc/classes/StyleBoxFlat.xml
msgid "Sets the corner radius to [code]radius[/code] pixels for all corners."
@@ -74333,8 +74857,8 @@ msgid ""
"Sets the expand margin to [code]size[/code] pixels for the given "
"[code]margin[/code]. See [enum Margin] for possible values."
msgstr ""
-"将给定的 [code]margin[/code] 的扩展边è·è®¾ç½®ä¸º [code]size[/code] åƒç´ ã€‚有关å¯"
-"能的值,请å‚阅 [enum Margin]。"
+"将给定的 [code]margin[/code] 的扩展边è·è®¾ç½®ä¸º [code]size[/code] åƒç´ ã€‚å¯èƒ½çš„"
+"å–å€¼è§ [enum Margin]。"
#: doc/classes/StyleBoxFlat.xml doc/classes/StyleBoxTexture.xml
msgid "Sets the expand margin to [code]size[/code] pixels for all margins."
@@ -74377,7 +74901,7 @@ msgstr "StyleBox的背景颜色。"
#: doc/classes/StyleBoxFlat.xml
msgid "If [code]true[/code], the border will fade into the background color."
-msgstr "如果[code]true[/code],边框会淡入背景色。"
+msgstr "如果为 [code]true[/code],边框会淡入背景色。"
#: doc/classes/StyleBoxFlat.xml
msgid "Sets the color of the border."
@@ -74385,7 +74909,7 @@ msgstr "设置边框的颜色。"
#: doc/classes/StyleBoxFlat.xml
msgid "Border width for the bottom border."
-msgstr "底部边框的宽度。"
+msgstr "底边框的宽度。"
#: doc/classes/StyleBoxFlat.xml
msgid "Border width for the left border."
@@ -74397,7 +74921,7 @@ msgstr "å³è¾¹æ¡†çš„宽度。"
#: doc/classes/StyleBoxFlat.xml
msgid "Border width for the top border."
-msgstr "顶部边框的宽度。"
+msgstr "顶边框的宽度。"
#: doc/classes/StyleBoxFlat.xml
msgid ""
@@ -74421,27 +74945,27 @@ msgstr ""
msgid ""
"The bottom-left corner's radius. If [code]0[/code], the corner is not "
"rounded."
-msgstr "左下角的åŠå¾„。如果[code]0[/code],则角ä¸åœ†æ»‘。"
+msgstr "左下角的åŠå¾„。如果为 [code]0[/code],则该角ä¸åœ†æ»‘。"
#: doc/classes/StyleBoxFlat.xml
msgid ""
"The bottom-right corner's radius. If [code]0[/code], the corner is not "
"rounded."
-msgstr "å³ä¸‹è§’çš„åŠå¾„。如果[code]0[/code],则角ä¸åœ†æ»‘。"
+msgstr "å³ä¸‹è§’çš„åŠå¾„。如果为 [code]0[/code],则该角ä¸åœ†æ»‘。"
#: doc/classes/StyleBoxFlat.xml
msgid ""
"The top-left corner's radius. If [code]0[/code], the corner is not rounded."
-msgstr "左上角的åŠå¾„。如果[code]0[/code],则角ä¸åœ†æ»‘。"
+msgstr "左上角的åŠå¾„。如果为 [code]0[/code],则该角ä¸åœ†æ»‘。"
#: doc/classes/StyleBoxFlat.xml
msgid ""
"The top-right corner's radius. If [code]0[/code], the corner is not rounded."
-msgstr "å³ä¸Šè§’çš„åŠå¾„。如果[code]0[/code],则角ä¸åœ†æ»‘。"
+msgstr "å³ä¸Šè§’çš„åŠå¾„。如果为 [code]0[/code],则该角ä¸åœ†æ»‘。"
#: doc/classes/StyleBoxFlat.xml
msgid "Toggles drawing of the inner part of the stylebox."
-msgstr "切æ¢ç»˜åˆ¶StyleBox的内部部分。"
+msgstr "切æ¢ç»˜åˆ¶ StyleBox 的内部部分。"
#: doc/classes/StyleBoxFlat.xml
msgid ""
@@ -74590,12 +75114,12 @@ msgid ""
"If [code]true[/code], the line will be vertical. If [code]false[/code], the "
"line will be horizontal."
msgstr ""
-"如果 [code]true[/code],则该线将是垂直的。如果 [code]false[/code],该线将是水"
-"平的。"
+"如果为 [code]true[/code],则该线将是垂直的。如果 [code]false[/code],该线将是"
+"水平的。"
#: doc/classes/StyleBoxTexture.xml
msgid "Texture-based nine-patch [StyleBox]."
-msgstr "基于纹ç†çš„ä¹å®«æ ¼[StyleBox]。"
+msgstr "基于纹ç†çš„ä¹å®«æ ¼ [StyleBox]。"
#: doc/classes/StyleBoxTexture.xml
msgid ""
@@ -74612,37 +75136,34 @@ msgstr ""
msgid ""
"Returns the size of the given [code]margin[/code]. See [enum Margin] for "
"possible values."
-msgstr ""
-"返回给定 [code]margin[/code] 的大å°ã€‚有关å¯èƒ½çš„值,请å‚阅 [enum Margin]。"
+msgstr "返回给定 [code]margin[/code] 的大å°ã€‚å¯èƒ½çš„å–å€¼è§ [enum Margin]。"
#: doc/classes/StyleBoxTexture.xml
msgid ""
"Sets the margin to [code]size[/code] pixels for the given [code]margin[/"
"code]. See [enum Margin] for possible values."
msgstr ""
-"将给定的 [code]margin[/code] 的边è·è®¾ç½®ä¸º [code]size[/code] åƒç´ ã€‚有关å¯èƒ½çš„"
-"值,请å‚阅 [enum Margin]。"
+"将给定的 [code]margin[/code] 的边è·è®¾ç½®ä¸º [code]size[/code] åƒç´ ã€‚å¯èƒ½çš„å–值"
+"è§ [enum Margin]。"
#: doc/classes/StyleBoxTexture.xml
msgid ""
"Controls how the stylebox's texture will be stretched or tiled horizontally. "
"See [enum AxisStretchMode] for possible values."
msgstr ""
-"控制如何水平拉伸或平铺样å¼ç›’的纹ç†ã€‚有关å¯èƒ½çš„值,请å‚阅 [enum "
-"AxisStretchMode]。"
+"控制如何水平拉伸或平铺样å¼ç›’的纹ç†ã€‚å¯èƒ½çš„å–å€¼è§ [enum AxisStretchMode]。"
#: doc/classes/StyleBoxTexture.xml
msgid ""
"Controls how the stylebox's texture will be stretched or tiled vertically. "
"See [enum AxisStretchMode] for possible values."
msgstr ""
-"控制如何垂直拉伸或平铺StyleBox的纹ç†ã€‚有关å¯èƒ½çš„值,请å‚阅 [enum "
-"AxisStretchMode]。"
+"控制如何垂直拉伸或平铺 StyleBox 的纹ç†ã€‚å¯èƒ½çš„å–å€¼è§ [enum AxisStretchMode]。"
#: doc/classes/StyleBoxTexture.xml
msgid ""
"If [code]true[/code], the nine-patch texture's center tile will be drawn."
-msgstr "如果[code]true[/code],将绘制ä¹å®«æ ¼çº¹ç†çš„中心瓦片。"
+msgstr "如果为 [code]true[/code],将绘制ä¹å®«æ ¼çº¹ç†çš„中心图å—。"
#: doc/classes/StyleBoxTexture.xml
msgid ""
@@ -74676,9 +75197,10 @@ msgid ""
"This is also the value used as fallback for [member StyleBox."
"content_margin_bottom] if it is negative."
msgstr ""
-"增加3×3 StyleBox的底边è·ã€‚\n"
-"更高的值æ„å‘³ç€æ›´å¤šçš„æºçº¹ç†è¢«è®¤ä¸ºæ˜¯3×3 box的底边的一部分。\n"
-"如果[member StyleBox.content_margin_bottom]为负值,这个值也是作为åŽå¤‡å€¼ä½¿ç”¨ã€‚"
+"增加 3×3 StyleBox 的底边è·ã€‚\n"
+"更高的值æ„å‘³ç€æ›´å¤šçš„æºçº¹ç†è¢«è®¤ä¸ºæ˜¯ 3×3 box的底边的一部分。\n"
+"如果 [member StyleBox.content_margin_bottom] 为负值,这个值也是作为åŽå¤‡å€¼ä½¿"
+"用。"
#: doc/classes/StyleBoxTexture.xml
msgid ""
@@ -74688,9 +75210,9 @@ msgid ""
"This is also the value used as fallback for [member StyleBox."
"content_margin_left] if it is negative."
msgstr ""
-"增加 3×3 StyleBox的左边è·ã€‚\n"
+"增加 3×3 StyleBox 的左边è·ã€‚\n"
"较高的值æ„å‘³ç€æ›´å¤šçš„æºçº¹ç†è¢«è®¤ä¸ºæ˜¯ 3×3 box左边框的一部分。\n"
-"如果[member StyleBox.content_margin_left]为负值,这个值也是作为åŽå¤‡å€¼ä½¿ç”¨ã€‚"
+"如果 [member StyleBox.content_margin_left] 为负值,这个值也是作为åŽå¤‡å€¼ä½¿ç”¨ã€‚"
#: doc/classes/StyleBoxTexture.xml
msgid ""
@@ -74700,9 +75222,10 @@ msgid ""
"This is also the value used as fallback for [member StyleBox."
"content_margin_right] if it is negative."
msgstr ""
-"增加 3×3 StyleBoxçš„å³è¾¹è·ã€‚\n"
+"增加 3×3 StyleBox çš„å³è¾¹è·ã€‚\n"
"较高的值æ„å‘³ç€æ›´å¤šçš„æºçº¹ç†è¢«è®¤ä¸ºæ˜¯ 3×3 boxå³è¾¹æ¡†çš„一部分。\n"
-"如果[member StyleBox.content_margin_right]为负值,这个值也是作为åŽå¤‡å€¼ä½¿ç”¨ã€‚"
+"如果 [member StyleBox.content_margin_right] 为负值,这个值也是作为åŽå¤‡å€¼ä½¿"
+"用。"
#: doc/classes/StyleBoxTexture.xml
msgid ""
@@ -74712,9 +75235,9 @@ msgid ""
"This is also the value used as fallback for [member StyleBox."
"content_margin_top] if it is negative."
msgstr ""
-"增加 3×3 StyleBox的上边è·ã€‚\n"
+"增加 3×3 StyleBox 的上边è·ã€‚\n"
"较高的值æ„å‘³ç€æ›´å¤šçš„æºçº¹ç†è¢«è®¤ä¸ºæ˜¯ 3×3 box上边框的一部分。\n"
-"如果[member StyleBox.content_margin_top]为负值,这个值也是作为åŽå¤‡å€¼ä½¿ç”¨ã€‚"
+"如果 [member StyleBox.content_margin_top] 为负值,这个值也是作为åŽå¤‡å€¼ä½¿ç”¨ã€‚"
#: doc/classes/StyleBoxTexture.xml
msgid "Modulates the color of the texture when this style box is drawn."
@@ -74833,8 +75356,7 @@ msgid ""
"Specifies an array of bones to use for the [i]next[/i] vertex. [code]bones[/"
"code] must contain 4 integers."
msgstr ""
-"指定[i]下一个[/i]顶点所使用的骨骼数组。 [code]bones[/code] å¿…é¡»åŒ…å« 4 个整"
-"数。"
+"指定[i]下一个[/i]顶点所使用的骨骼数组。[code]bones[/code] å¿…é¡»åŒ…å« 4 个整数。"
#: doc/classes/SurfaceTool.xml
msgid ""
@@ -74921,9 +75443,9 @@ msgid ""
"set and you fail to submit it for the first vertex, this information may not "
"be used at all."
msgstr ""
-"指定[i]下一个[/i]顶点所使用的æƒé‡å€¼ã€‚ [code]weights[/code] å¿…é¡»åŒ…å« 4 个值。"
-"如果æ¯ä¸ªé¡¶ç‚¹éƒ½éœ€è¦è®¾ç½®æ­¤ä¿¡æ¯ï¼Œè€Œæ‚¨æœªèƒ½ä¸ºç¬¬ä¸€ä¸ªé¡¶ç‚¹æäº¤æ­¤ä¿¡æ¯ï¼Œæ­¤ä¿¡æ¯å¯èƒ½æ ¹æœ¬"
-"å°±ä¸ä¼šè¢«ä½¿ç”¨ã€‚"
+"指定[i]下一个[/i]顶点所使用的æƒé‡å€¼ã€‚[code]weights[/code] å¿…é¡»åŒ…å« 4 个值。如"
+"æžœæ¯ä¸ªé¡¶ç‚¹éƒ½éœ€è¦è®¾ç½®æ­¤ä¿¡æ¯ï¼Œè€Œæ‚¨æœªèƒ½ä¸ºç¬¬ä¸€ä¸ªé¡¶ç‚¹æäº¤æ­¤ä¿¡æ¯ï¼Œæ­¤ä¿¡æ¯å¯èƒ½æ ¹æœ¬å°±"
+"ä¸ä¼šè¢«ä½¿ç”¨ã€‚"
#: doc/classes/SurfaceTool.xml
msgid ""
@@ -75006,7 +75528,7 @@ msgid ""
"be set to [constant Mesh.PRIMITIVE_TRIANGLES]."
msgstr ""
"ä»Žé¡¶ç‚¹ç”Ÿæˆæ³•线,因此您ä¸å¿…手动执行。如果 [code]flip[/code] 为 [code]true[/"
-"code],则生æˆçš„æ³•线将被å转。 [method generate_normals] 应在生æˆå‡ ä½•体[i]之åŽ"
+"code],则生æˆçš„æ³•线将被å转。[method generate_normals] 应在生æˆå‡ ä½•体[i]之åŽ"
"[/i] 调用,在[i]之å‰[/i]使用 [method commit] 或 [method commit_to_arrays] æ"
"交网格。为了正确显示法线贴图表é¢ï¼Œæ‚¨è¿˜å¿…须使用 [method generate_tangents] 生"
"æˆåˆ‡çº¿ã€‚\n"
@@ -75187,7 +75709,7 @@ msgstr ""
#: doc/classes/TabContainer.xml doc/classes/Tabs.xml
msgid "If [code]true[/code], tabs can be rearranged with mouse drag."
-msgstr "如果 [code]true[/code],å¯ä»¥é€šè¿‡é¼ æ ‡æ‹–åŠ¨é‡æ–°æŽ’列选项å¡ã€‚"
+msgstr "如果为 [code]true[/code],å¯ä»¥é€šè¿‡é¼ æ ‡æ‹–åŠ¨é‡æ–°æŽ’列选项å¡ã€‚"
#: doc/classes/TabContainer.xml
msgid ""
@@ -75201,8 +75723,8 @@ msgid ""
"If [code]true[/code], tabs are visible. If [code]false[/code], tabs' content "
"and titles are hidden."
msgstr ""
-"如果 [code]true[/code],选项å¡å¯è§ã€‚如果 [code]false[/code],选项å¡çš„内容和标"
-"题被éšè—。"
+"如果为 [code]true[/code],选项å¡å¯è§ã€‚如果 [code]false[/code],选项å¡çš„内容和"
+"标题被éšè—。"
#: doc/classes/TabContainer.xml
msgid ""
@@ -75210,8 +75732,8 @@ msgid ""
"minimum size take into account in the total, instead of only the currently "
"visible one."
msgstr ""
-"如果 [code]true[/code],éšè—çš„å­ [Control] 节点在总数中考虑其最å°å¤§å°ï¼Œè€Œä¸æ˜¯"
-"仅考虑当å‰å¯è§çš„一个。"
+"如果为 [code]true[/code],éšè—çš„å­ [Control] 节点在总数中考虑其最å°å¤§å°ï¼Œè€Œä¸"
+"是仅考虑当å‰å¯è§çš„一个。"
#: doc/classes/TabContainer.xml
msgid ""
@@ -75301,13 +75823,13 @@ msgstr ""
#: doc/classes/TabContainer.xml
msgid "The icon for the menu button (see [method set_popup])."
-msgstr "èœå•按钮的图标(è§[method set_popup])。"
+msgstr "èœå•æŒ‰é’®çš„å›¾æ ‡ï¼ˆè§ [method set_popup])。"
#: doc/classes/TabContainer.xml
msgid ""
"The icon for the menu button (see [method set_popup]) when it's being "
"hovered with the cursor."
-msgstr "å½“å…‰æ ‡æ‚¬åœæ—¶èœå•按钮的图标(å‚阅 [method set_popup])。"
+msgstr "å½“å…‰æ ‡æ‚¬åœæ—¶èœå•æŒ‰é’®çš„å›¾æ ‡ï¼ˆè§ [method set_popup])。"
#: doc/classes/TabContainer.xml
msgid "The style for the background fill."
@@ -75334,7 +75856,7 @@ msgid ""
"Simple tabs control, similar to [TabContainer] but is only in charge of "
"drawing tabs, not interacting with children."
msgstr ""
-"简å•çš„é€‰é¡¹å¡æŽ§åˆ¶ï¼Œç±»ä¼¼äºŽ[TabContainer],但åªè´Ÿè´£ç»˜åˆ¶é€‰é¡¹å¡ï¼Œä¸ä¸Žå­èŠ‚ç‚¹äº’åŠ¨ã€‚"
+"简å•çš„é€‰é¡¹å¡æŽ§åˆ¶ï¼Œç±»ä¼¼äºŽ [TabContainer],但åªè´Ÿè´£ç»˜åˆ¶é€‰é¡¹å¡ï¼Œä¸ä¸Žå­èŠ‚ç‚¹äº’åŠ¨ã€‚"
#: doc/classes/Tabs.xml
msgid "Adds a new tab."
@@ -75383,7 +75905,7 @@ msgstr "删除索引 [code]tab_idx[/code] 处的选项å¡ã€‚"
#: doc/classes/Tabs.xml
msgid ""
"If [code]true[/code], enables selecting a tab with the right mouse button."
-msgstr "如果 [code]true[/code],å¯ç”¨é¼ æ ‡å³é”®é€‰æ‹©é€‰é¡¹å¡ã€‚"
+msgstr "如果为 [code]true[/code],å¯ç”¨é¼ æ ‡å³é”®é€‰æ‹©é€‰é¡¹å¡ã€‚"
#: doc/classes/Tabs.xml
msgid "Sets an [code]icon[/code] for the tab at index [code]tab_idx[/code]."
@@ -75410,7 +75932,7 @@ msgstr "选择索引 [code]tab_idx[/code] 处的选项å¡ã€‚"
msgid ""
"if [code]true[/code], the mouse's scroll wheel can be used to navigate the "
"scroll view."
-msgstr "如果 [code]true[/code],鼠标的滚轮å¯ç”¨äºŽå¯¼èˆªæ»šåŠ¨è§†å›¾ã€‚"
+msgstr "如果为 [code]true[/code],鼠标的滚轮å¯ç”¨äºŽå¯¼èˆªæ»šåŠ¨è§†å›¾ã€‚"
#: doc/classes/Tabs.xml
msgid "The alignment of all tabs. See [enum TabAlign] for details."
@@ -75474,7 +75996,7 @@ msgstr "选项å¡ä¹‹é—´çš„æ°´å¹³é—´éš”。"
#: doc/classes/Tabs.xml
msgid "The icon for the close button (see [member tab_close_display_policy])."
-msgstr "关闭按钮的图标(å‚阅 [member tab_close_display_policy])。"
+msgstr "å…³é—­æŒ‰é’®çš„å›¾æ ‡ï¼ˆè§ [member tab_close_display_policy])。"
#: doc/classes/Tabs.xml
msgid "Background of the close button when it's being hovered with the cursor."
@@ -75643,11 +76165,11 @@ msgstr "å–æ¶ˆå½“å‰é€‰æ‹©ã€‚"
#: doc/classes/TextEdit.xml
msgid "Folds all lines that are possible to be folded (see [method can_fold])."
-msgstr "æŠ˜å æ‰€æœ‰å¯èƒ½è¢«æŠ˜å çš„行(å‚阅 [method can_fold])。"
+msgstr "æŠ˜å æ‰€æœ‰å¯èƒ½è¢«æŠ˜å çš„è¡Œï¼ˆè§ [method can_fold])。"
#: doc/classes/TextEdit.xml
msgid "Folds the given line, if possible (see [method can_fold])."
-msgstr "如果å¯èƒ½ï¼ŒæŠ˜å ç»™å®šçš„行(å‚阅 [method can_fold])。"
+msgstr "如果å¯èƒ½ï¼ŒæŠ˜å ç»™å®šçš„è¡Œï¼ˆè§ [method can_fold])。"
#: doc/classes/TextEdit.xml
msgid "Returns an array containing the line number of each breakpoint."
@@ -75911,7 +76433,7 @@ msgstr ""
#: doc/classes/TextEdit.xml
msgid "If [code]true[/code], hides the line of the specified index."
-msgstr "如果 [code]true[/code],éšè—指定索引的行。"
+msgstr "如果为 [code]true[/code],éšè—指定索引的行。"
#: doc/classes/TextEdit.xml
msgid ""
@@ -75970,46 +76492,50 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr "为 [code]true[/code] æ—¶å³é”®å•击会显示上下文èœå•。"
#: doc/classes/TextEdit.xml
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "如果为 [code]true[/code],则å…许拖放选中的文本。"
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
-msgstr "如果 [code]true[/code],“空格â€å­—符将具有å¯è§è¡¨ç¤ºå½¢å¼ã€‚"
+msgstr "如果为 [code]true[/code],“空格â€å­—符将具有å¯è§è¡¨ç¤ºå½¢å¼ã€‚"
#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"tab\" character will have a visible "
"representation."
-msgstr "如果 [code]true[/code],“制表符â€å­—符将具有å¯è§è¡¨ç¤ºå½¢å¼ã€‚"
+msgstr "如果为 [code]true[/code],“制表符â€å­—符将具有å¯è§è¡¨ç¤ºå½¢å¼ã€‚"
#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the fold gutter is visible. This enables folding "
"groups of indented lines."
-msgstr "如果 [code]true[/code]ï¼Œåˆ™æŠ˜å æ å¯è§ã€‚è¿™å…许折å ç¼©è¿›è¡Œã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œåˆ™æŠ˜å æ å¯è§ã€‚è¿™å…许折å ç¼©è¿›è¡Œã€‚"
#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], all lines that have been set to hidden by [method "
"set_line_as_hidden], will not be visible."
msgstr ""
-"如果 [code]true[/code],所有已被 [method set_line_as_hidden] 设置为éšè—的行将"
-"ä¸å¯è§ã€‚"
+"如果为 [code]true[/code],所有已被 [method set_line_as_hidden] 设置为éšè—的行"
+"å°†ä¸å¯è§ã€‚"
#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], all occurrences of the selected text will be "
"highlighted."
-msgstr "如果 [code]true[/code],所选文本的所有匹é…项都将çªå‡ºæ˜¾ç¤ºã€‚"
+msgstr "如果为 [code]true[/code],所选文本的所有匹é…项都将çªå‡ºæ˜¾ç¤ºã€‚"
#: doc/classes/TextEdit.xml
msgid "If [code]true[/code], the line containing the cursor is highlighted."
-msgstr "如果 [code]true[/code],则包å«å…‰æ ‡çš„行会çªå‡ºæ˜¾ç¤ºã€‚"
+msgstr "如果为 [code]true[/code],则包å«å…‰æ ‡çš„行会çªå‡ºæ˜¾ç¤ºã€‚"
#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], a minimap is shown, providing an outline of your "
"source code."
-msgstr "如果 [code]true[/code],则显示å°åœ°å›¾ï¼Œæä¾›æºä»£ç çš„æ¦‚è¦ã€‚"
+msgstr "如果为 [code]true[/code],则显示å°åœ°å›¾ï¼Œæä¾›æºä»£ç çš„æ¦‚è¦ã€‚"
#: doc/classes/TextEdit.xml
msgid "The width, in pixels, of the minimap."
@@ -76020,16 +76546,16 @@ msgid ""
"If [code]true[/code], custom [code]font_color_selected[/code] will be used "
"for selected text."
msgstr ""
-"如果 [code]true[/code],自定义 [code]font_color_selected[/code] 将用于所选文"
-"本。"
+"如果为 [code]true[/code],自定义 [code]font_color_selected[/code] 将用于所选"
+"文本。"
#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], read-only mode is enabled. Existing text cannot be "
"modified and new text cannot be added."
msgstr ""
-"如果[code]true[/code],å¯ç”¨åªè¯»æ¨¡å¼ã€‚现有的文本ä¸èƒ½è¢«ä¿®æ”¹ï¼Œæ–°çš„æ–‡æœ¬ä¸èƒ½è¢«æ·»"
-"加。"
+"如果为 [code]true[/code],å¯ç”¨åªè¯»æ¨¡å¼ã€‚现有的文本ä¸èƒ½è¢«ä¿®æ”¹ï¼Œæ–°çš„æ–‡æœ¬ä¸èƒ½è¢«"
+"添加。"
#: doc/classes/TextEdit.xml
msgid ""
@@ -76050,9 +76576,9 @@ msgid ""
"If [code]false[/code], text can not be selected by the user or by the "
"[method select] or [method select_all] methods."
msgstr ""
-"如果[code]true[/code],文本å¯ä»¥è¢«é€‰æ‹©ã€‚\n"
-"如果[code]false[/code],用户或使用[method select]或[method select_all]方法都"
-"ä¸èƒ½é€‰æ‹©æ–‡æœ¬ã€‚"
+"如果为 [code]true[/code],文本å¯ä»¥è¢«é€‰æ‹©ã€‚\n"
+"如果为 [code]false[/code],用户或使用[method select]或[method select_all]方法"
+"都ä¸èƒ½é€‰æ‹©æ–‡æœ¬ã€‚"
#: doc/classes/TextEdit.xml
msgid ""
@@ -76065,22 +76591,22 @@ msgstr ""
#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], line numbers are displayed to the left of the text."
-msgstr "如果 [code]true[/code]ï¼Œè¡Œå·æ˜¾ç¤ºåœ¨æ–‡æœ¬çš„左侧。"
+msgstr "如果为 [code]true[/code]ï¼Œè¡Œå·æ˜¾ç¤ºåœ¨æ–‡æœ¬çš„左侧。"
#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], sets the [code]step[/code] of the scrollbars to "
"[code]0.25[/code] which results in smoother scrolling."
msgstr ""
-"如果 [code]true[/code],将滚动æ¡çš„æ­¥é•¿ [code]step[/code] 设置为 [code]0.25[/"
-"code],从而使滚动更加平滑。"
+"如果为 [code]true[/code],将滚动æ¡çš„æ­¥é•¿ [code]step[/code] 设置为 "
+"[code]0.25[/code],从而使滚动更加平滑。"
#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], any custom color properties that have been set for "
"this [TextEdit] will be visible."
msgstr ""
-"如果 [code]true[/code],为此 [TextEdit] 设置的任何自定义颜色属性都将å¯è§ã€‚"
+"如果为 [code]true[/code],为此 [TextEdit] 设置的任何自定义颜色属性都将å¯è§ã€‚"
#: doc/classes/TextEdit.xml
msgid "String value of the [TextEdit]."
@@ -76094,7 +76620,7 @@ msgstr "åž‚ç›´æ»šåŠ¨çš„çµæ•度。"
msgid ""
"If [code]true[/code], enables text wrapping when it goes beyond the edge of "
"what is visible."
-msgstr "如果 [code]true[/code],当文本超出å¯è§è¾¹ç¼˜æ—¶å¯ç”¨æ–‡æœ¬æ¢è¡Œã€‚"
+msgstr "如果为 [code]true[/code],当文本超出å¯è§è¾¹ç¼˜æ—¶å¯ç”¨æ–‡æœ¬æ¢è¡Œã€‚"
#: doc/classes/TextEdit.xml
msgid "Emitted when a breakpoint is placed via the breakpoint gutter."
@@ -76302,16 +76828,16 @@ msgid ""
"canvas_item_add_texture_rect] with a rect at [code]position[/code] and the "
"size of this [Texture]."
msgstr ""
-"在指定的ä½ç½®[code]position[/code]使用[VisualServer]APIçš„[CanvasItem]æ¥ç»˜åˆ¶çº¹"
-"ç†ã€‚相当于[method VisualServer.canvas_item_add_texture_rect],在ä½ç½®"
-"[code]position[/code]有一个矩形,尺寸为这个[Texture]。"
+"在指定的ä½ç½® [code]position[/code] 使用 [VisualServer] API çš„ [CanvasItem] æ¥"
+"绘制纹ç†ã€‚相当于 [method VisualServer.canvas_item_add_texture_rect],在ä½ç½® "
+"[code]position[/code] 有一个矩形,尺寸为这个 [Texture]。"
#: doc/classes/Texture.xml
msgid ""
"Draws the texture using a [CanvasItem] with the [VisualServer] API. "
"Equivalent to [method VisualServer.canvas_item_add_texture_rect]."
msgstr ""
-"使用 [VisualServer] API çš„ [CanvasItem] æ¥ç»˜åˆ¶çº¹ç†ã€‚相当于方法 [method "
+"使用 [VisualServer] API çš„ [CanvasItem] æ¥ç»˜åˆ¶çº¹ç†ã€‚相当于 [method "
"VisualServer.canvas_item_add_texture_rect]。"
#: doc/classes/Texture.xml
@@ -76319,16 +76845,16 @@ msgid ""
"Draws a part of the texture using a [CanvasItem] with the [VisualServer] "
"API. Equivalent to [method VisualServer.canvas_item_add_texture_rect_region]."
msgstr ""
-"使用 [VisualServer] API çš„ [CanvasItem] æ¥ç»˜åˆ¶çº¹ç†çš„一个部分。相当于方法 "
-"[method VisualServer.canvas_item_add_texture_rect_region]。"
+"使用 [VisualServer] API çš„ [CanvasItem] æ¥ç»˜åˆ¶çº¹ç†çš„一个部分。相当于 [method "
+"VisualServer.canvas_item_add_texture_rect_region]。"
#: doc/classes/Texture.xml
msgid ""
"Returns an [Image] that is a copy of data from this [Texture]. [Image]s can "
"be accessed and manipulated directly."
msgstr ""
-"返回一个 [Image],它是此 [Texture] 中数æ®çš„副本。 [Image] 图åƒå¯ä»¥ç›´æŽ¥è®¿é—®å’Œ"
-"æ“作。"
+"返回一个 [Image],它是此 [Texture] 中数æ®çš„副本。[Image] 图åƒå¯ä»¥ç›´æŽ¥è®¿é—®å’Œæ“"
+"作。"
#: doc/classes/Texture.xml
msgid "Returns the texture height."
@@ -76649,7 +77175,7 @@ msgid ""
msgstr ""
"是 [Texture3D] å’Œ [TextureArray] 的基类。ä¸èƒ½ç›´æŽ¥ä½¿ç”¨ï¼Œä½†åŒ…å«è®¿é—®å’Œä½¿ç”¨ "
"[Texture3D] å’Œ [TextureArray] 的所有必è¦åŠŸèƒ½ã€‚æ•°æ®æ˜¯ä»¥æ¯å±‚为å•ä½è®¾ç½®çš„。对于 "
-"[Texture3D],层指定了深度或 Z-index,它们å¯ä»¥è¢«è§†ä¸ºä¸€å †äºŒç»´åˆ‡ç‰‡ã€‚åŒæ ·åœ°ï¼Œå¯¹"
+"[Texture3D],层指定了深度或 Z-index,它们å¯ä»¥è¢«è§†ä¸ºä¸€å † 2D åˆ‡ç‰‡ã€‚åŒæ ·åœ°ï¼Œå¯¹"
"于 [TextureArray],层指定了数组层。"
#: doc/classes/TextureLayered.xml
@@ -76662,7 +77188,7 @@ msgstr "返回纹ç†çš„æ·±åº¦ã€‚深度是第三个维度(通常是 Z 轴)。
msgid ""
"Returns the current format being used by this texture. See [enum Image."
"Format] for details."
-msgstr "返回纹ç†å½“å‰ä½¿ç”¨çš„æ ¼å¼ã€‚详情è§[enum Image.Format]。"
+msgstr "返回纹ç†å½“å‰ä½¿ç”¨çš„æ ¼å¼ã€‚è¯¦æƒ…è§ [enum Image.Format]。"
#: doc/classes/TextureLayered.xml
msgid ""
@@ -76689,14 +77215,14 @@ msgid ""
"the texture. The [code]image[/code] must fit within the texture."
msgstr ""
"通过使用指定的[code]image[/code]的数æ®è¦†ç›–æ¥éƒ¨åˆ†è®¾ç½®æŒ‡å®šçš„[code]layer[/code]"
-"的数æ®ã€‚ [code]x_offset[/code] å’Œ [code]y_offset[/code] 确定 [Image] 在纹ç†ä¸Š"
-"\"stamped\" 标记的ä½ç½®ã€‚ [code]image[/code] 必须适åˆçº¹ç†ã€‚"
+"的数æ®ã€‚[code]x_offset[/code] å’Œ [code]y_offset[/code] 确定 [Image] 在纹ç†ä¸Š"
+"\"stamped\" 标记的ä½ç½®ã€‚[code]image[/code] 必须适åˆçº¹ç†ã€‚"
#: doc/classes/TextureLayered.xml
msgid ""
"Sets the data for the specified layer. Data takes the form of a 2-"
"dimensional [Image] resource."
-msgstr "设置指定图层的数æ®ã€‚æ•°æ®çš„形弿˜¯äºŒç»´çš„[Image]资æºã€‚"
+msgstr "设置指定图层的数æ®ã€‚æ•°æ®çš„形弿˜¯äºŒç»´çš„ [Image] 资æºã€‚"
#: doc/classes/TextureLayered.xml
msgid "Returns a dictionary with all the data used by this texture."
@@ -76711,7 +77237,7 @@ msgid ""
"Default flags for [TextureArray]. [constant FLAG_MIPMAPS], [constant "
"FLAG_REPEAT] and [constant FLAG_FILTER] are enabled."
msgstr ""
-"[TextureArray] 的默认标记。 å¯ç”¨ [constant FLAG_MIPMAPS]ã€[constant "
+"[TextureArray] 的默认标记。å¯ç”¨ [constant FLAG_MIPMAPS]ã€[constant "
"FLAG_REPEAT] 和 [constant FLAG_FILTER]。"
#: doc/classes/TextureLayered.xml
@@ -76724,7 +77250,7 @@ msgstr "纹ç†å°†åœ¨åˆ›å»ºæ—¶ç”Ÿæˆå¤šçº§æ¸è¿œçº¹ç†ã€‚"
#: doc/classes/TextureLayered.xml
msgid "Texture will repeat when UV used is outside the 0-1 range."
-msgstr "当使用的UV超出0-1范围时,纹ç†å°†é‡å¤ã€‚"
+msgstr "当使用的 UV 超出 0-1 范围时,纹ç†å°†é‡å¤ã€‚"
#: doc/classes/TextureLayered.xml
msgid ""
@@ -76747,12 +77273,12 @@ msgid ""
"of Godot's [Theme] resource. It can be used to create horizontal, vertical "
"and radial progress bars."
msgstr ""
-"TextureProgress的工作原ç†ä¸Ž[ProgressBar]类似,但最多使用3个纹ç†ï¼Œè€Œä¸æ˜¯Godot"
-"çš„[Theme]资æºã€‚它å¯ä»¥ç”¨æ¥åˆ›å»ºæ°´å¹³ã€åž‚直和径å‘的进度æ¡ã€‚"
+"TextureProgress 的工作原ç†ä¸Ž [ProgressBar] 类似,但最多使用 3 个纹ç†ï¼Œè€Œä¸æ˜¯ "
+"Godot çš„ [Theme] 资æºã€‚它å¯ä»¥ç”¨æ¥åˆ›å»ºæ°´å¹³ã€åž‚直和径å‘的进度æ¡ã€‚"
#: doc/classes/TextureProgress.xml
msgid "The fill direction. See [enum FillMode] for possible values."
-msgstr "å¡«å……æ–¹å‘。有关å¯èƒ½çš„值,å‚阅[enum FillMode]。"
+msgstr "å¡«å……æ–¹å‘。å¯èƒ½çš„å–å€¼è§ [enum FillMode]。"
#: doc/classes/TextureProgress.xml
msgid ""
@@ -76761,9 +77287,10 @@ msgid ""
"[member stretch_margin_bottom] to set up the nine patch's 3×3 grid. When "
"using a radial [member fill_mode], this setting will enable stretching."
msgstr ""
-"如果[code]true[/code],Godot会åƒåœ¨[NinePatchRect]ä¸­é‚£æ ·å¤„ç†æ¡å½¢çº¹ç†ã€‚使用"
-"[code]stretch_margin_*[/code]属性,如[member stretch_margin_bottom]æ¥è®¾ç½®ä¹å®«"
-"格的3×3网格。当使用径å‘çš„[member fill_mode]时,这个设置将å¯ç”¨æ‹‰ä¼¸åŠŸèƒ½ã€‚"
+"如果为 [code]true[/code],Godot 会åƒåœ¨ [NinePatchRect] ä¸­é‚£æ ·å¤„ç†æ¡å½¢çº¹ç†ã€‚使"
+"用 [code]stretch_margin_*[/code] 属性,如 [member stretch_margin_bottom] æ¥è®¾"
+"ç½®ä¹å®«æ ¼çš„ 3×3 网格。当使用径å‘çš„ [member fill_mode] 时,这个设置将å¯ç”¨æ‹‰ä¼¸åŠŸ"
+"能。"
#: doc/classes/TextureProgress.xml
msgid ""
@@ -76806,8 +77333,8 @@ msgid ""
"bottom corners and side will have a height of 16 pixels. You can set all 4 "
"margin values individually to create panels with non-uniform borders."
msgstr ""
-"ä¹å®«æ ¼åº•行的高度。边è·ä¸º16æ„味ç€ä¹å®«æ ¼çš„底角和侧é¢å°†æœ‰16åƒç´ çš„高度。你å¯ä»¥å•"
-"独设置所有4个边è·å€¼ï¼Œæ¥åˆ›å»ºå…·æœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
+"ä¹å®«æ ¼åº•行的高度。边è·ä¸º 16 æ„味ç€ä¹å®«æ ¼çš„底角和侧é¢å°†æœ‰ 16 åƒç´ çš„高度。你å¯"
+"以å•独设置所有 4 个边è·å€¼ï¼Œæ¥åˆ›å»ºå…·æœ‰éžç»Ÿä¸€è¾¹æ¡†çš„颿¿ã€‚"
#: doc/classes/TextureProgress.xml
msgid "The width of the 9-patch's left column."
@@ -76838,12 +77365,12 @@ msgid ""
"The [code]value[/code] property comes from [Range]. See [member Range."
"value], [member Range.min_value], [member Range.max_value]."
msgstr ""
-"基于节点的[code]value[/code]å’Œ[member fill_mode]进行è£å‰ª[Texture]。éšç€"
-"[code]value[/code]的增加,纹ç†ä¼šè¢«å¡«æ»¡ã€‚当[code]value[/code]达到"
-"[code]max_value[/code]时,它完全显示。如果[code]value[/code]等于"
+"基于节点的 [code]value[/code] å’Œ [member fill_mode] 进行è£å‰ª [Texture]。éšç€ "
+"[code]value[/code] 的增加,纹ç†ä¼šè¢«å¡«æ»¡ã€‚当 [code]value[/code] 达到 "
+"[code]max_value[/code] 时,它完全显示。如果 [code]value[/code] 等于 "
"[code]min_value[/code]ï¼Œå®ƒå°±å®Œå…¨ä¸æ˜¾ç¤ºäº†ã€‚\n"
-"[code]value[/code]属性æ¥è‡ª[Range]。å‚阅[member Range.value], [member Range."
-"min_value], [member Range.max_value]。"
+"[code]value[/code] 属性æ¥è‡ª [Range]ã€‚è§ [member Range.value]ã€[member Range."
+"min_value]ã€[member Range.max_value]。"
#: doc/classes/TextureProgress.xml
msgid ""
@@ -76851,12 +77378,12 @@ msgid ""
"and [member texture_under] with fancy borders, to avoid transparent margins "
"in your progress texture."
msgstr ""
-"[member texture_progress]çš„åç§»é‡ã€‚对于带有花哨的边框的[member texture_over]"
-"å’Œ[member texture_under]很有用,å¯ä»¥é¿å…进度纹ç†çš„è¾¹ç¼˜é€æ˜Žã€‚"
+"[member texture_progress] çš„åç§»é‡ã€‚对于带有花哨的边框的 [member "
+"texture_over] å’Œ [member texture_under] 很有用,å¯ä»¥é¿å…进度纹ç†çš„è¾¹ç¼˜é€æ˜Žã€‚"
#: doc/classes/TextureProgress.xml
msgid "[Texture] that draws under the progress bar. The bar's background."
-msgstr "在进度æ¡ä¸‹é¢ç»˜åˆ¶çš„[Texture]。å³èƒŒæ™¯ã€‚"
+msgstr "在进度æ¡ä¸‹é¢ç»˜åˆ¶çš„ [Texture]。å³èƒŒæ™¯ã€‚"
#: doc/classes/TextureProgress.xml
msgid ""
@@ -76878,7 +77405,7 @@ msgstr "å°†æ¡å½¢çš„ [code]texture_under[/code] 纹ç†çš„颜色相乘。"
#: doc/classes/TextureProgress.xml
msgid "The [member texture_progress] fills from left to right."
-msgstr "[member texture_progress]从左到å³å¡«å……。"
+msgstr "[member texture_progress] 从左到å³å¡«å……。"
#: doc/classes/TextureProgress.xml
msgid "The [member texture_progress] fills from right to left."
@@ -76964,7 +77491,7 @@ msgstr "如果为 [code]true[/code],纹ç†ç¼©æ”¾ä»¥é€‚åˆå…¶è¾¹ç•ŒçŸ©å½¢ã€‚"
msgid ""
"Controls the texture's behavior when resizing the node's bounding rectangle. "
"See [enum StretchMode]."
-msgstr "控件纹ç†åœ¨è°ƒæ•´èŠ‚ç‚¹è¾¹ç•ŒçŸ©å½¢æ—¶çš„è¡Œä¸ºã€‚å‚阅[enum StretchMode]。"
+msgstr "控件纹ç†åœ¨è°ƒæ•´èŠ‚ç‚¹è¾¹ç•ŒçŸ©å½¢æ—¶çš„è¡Œä¸ºã€‚è§ [enum StretchMode]。"
#: doc/classes/TextureRect.xml
msgid "The node's [Texture] resource."
@@ -77100,14 +77627,14 @@ msgid ""
"Returns all the [Color] types as a [PoolStringArray] filled with unique type "
"names, for use in [method get_color] and/or [method get_color_list]."
msgstr ""
-"返回所有的[Color]类型为[PoolStringArray],其中填充了唯一类型å称,供[method "
-"get_color]和/或[method get_color_list]使用。"
+"返回所有的 [Color] 类型为 [PoolStringArray],其中填充了唯一类型å称,供 "
+"[method get_color] 和/或 [method get_color_list] 使用。"
#: doc/classes/Theme.xml
msgid ""
"Returns the constant at [code]name[/code] if the theme has [code]node_type[/"
"code]."
-msgstr "如果主题有[code]node_type[/code],返回 [code]name[/code]处的常é‡ã€‚"
+msgstr "如果主题有 [code]node_type[/code],返回 [code]name[/code] 处的常é‡ã€‚"
#: doc/classes/Theme.xml
msgid ""
@@ -77115,8 +77642,8 @@ msgid ""
"name, for use in [method get_constant], if the theme has [code]node_type[/"
"code]."
msgstr ""
-"如果主题有[code]node_type[/code],将所有常é‡ä½œä¸º[PoolStringArray]返回,并填充"
-"æ¯ä¸ªå¸¸é‡çš„å称,以供[method get_constant]使用。"
+"如果主题有 [code]node_type[/code],将所有常é‡ä½œä¸º [PoolStringArray] 返回,并"
+"å¡«å……æ¯ä¸ªå¸¸é‡çš„å称,以供 [method get_constant] 使用。"
#: doc/classes/Theme.xml
msgid ""
@@ -77142,8 +77669,8 @@ msgid ""
"Returns all the [Font]s as a [PoolStringArray] filled with each [Font]'s "
"name, for use in [method get_font], if the theme has [code]node_type[/code]."
msgstr ""
-"如果主题有[code]node_type[/code],将所有的[Font]作为[PoolStringArray]返回,并"
-"å¡«å…¥æ¯ä¸ª[Font]çš„å称,以供[method get_font]使用。"
+"如果主题有 [code]node_type[/code],将所有的 [Font] 作为 [PoolStringArray] 返"
+"回,并填入æ¯ä¸ª [Font] çš„å称,以供 [method get_font] 使用。"
#: doc/classes/Theme.xml
msgid ""
@@ -77332,9 +77859,9 @@ msgid ""
"[code]name[/code] is in [code]node_type[/code].\n"
"Returns [code]false[/code] if the theme does not have [code]node_type[/code]."
msgstr ""
-"如果一个[code]data_type[/code]的主题项目与[code]name[/code]在"
-"[code]node_type[/code]中,则返回 [code]true[/code]。\n"
-"如果该主题没有[code]node_type[/code],则返回 [code]false[/code]。"
+"如果一个 [code]data_type[/code] 的主题项目与 [code]name[/code] 在 "
+"[code]node_type[/code] 中,则返回 [code]true[/code]。\n"
+"如果该主题没有 [code]node_type[/code],则返回 [code]false[/code]。"
#: doc/classes/Theme.xml
msgid ""
@@ -77352,7 +77879,7 @@ msgid ""
"themes together without modifying either one, create a new empty theme and "
"merge the other two into it one after another."
msgstr ""
-"用[code]other[/code][Theme]的值添加缺失的,和覆盖现有的定义。\n"
+"用 [code]other[/code] [Theme]的值添加缺失的,和覆盖现有的定义。\n"
"[b]注æ„:[/b]这将修改当å‰çš„主题。如果你想在ä¸ä¿®æ”¹ä»»ä½•一个主题的情况下将两个主"
"题åˆå¹¶åœ¨ä¸€èµ·ï¼Œè¯·åˆ›å»ºä¸€ä¸ªæ–°çš„空主题,然åŽå°†å¦å¤–两个主题é€ä¸ªåˆå¹¶åˆ°å…¶ä¸­ã€‚"
@@ -77371,8 +77898,8 @@ msgid ""
"theme has [code]node_type[/code]. If [code]name[/code] is already taken, "
"this method fails."
msgstr ""
-"如果主题有[code]node_type[/code],则将[code]old_name[/code]çš„[Color]é‡å‘½å为"
-"[code]name[/code]。如果[code]name[/code]å·²ç»è¢«å ç”¨ï¼Œåˆ™æ­¤æ–¹æ³•将失败。"
+"如果主题有 [code]node_type[/code],则将 [code]old_name[/code] çš„ [Color] é‡å‘½"
+"å为 [code]name[/code]。如果 [code]name[/code] å·²ç»è¢«å ç”¨ï¼Œåˆ™æ­¤æ–¹æ³•将失败。"
#: doc/classes/Theme.xml
msgid ""
@@ -77380,8 +77907,8 @@ msgid ""
"theme has [code]node_type[/code]. If [code]name[/code] is already taken, "
"this method fails."
msgstr ""
-"如果主题有[code]node_type[/code],则将[code]old_name[/code]的常é‡é‡å‘½å为"
-"[code]name[/code]。如果[code]name[/code]å·²ç»è¢«å ç”¨ï¼Œåˆ™æ­¤æ–¹æ³•失败。"
+"如果主题有 [code]node_type[/code],则将 [code]old_name[/code] 的常é‡é‡å‘½å为 "
+"[code]name[/code]。如果 [code]name[/code] å·²ç»è¢«å ç”¨ï¼Œåˆ™æ­¤æ–¹æ³•失败。"
#: doc/classes/Theme.xml
msgid ""
@@ -77389,8 +77916,8 @@ msgid ""
"theme has [code]node_type[/code]. If [code]name[/code] is already taken, "
"this method fails."
msgstr ""
-"如果主题有[code]node_type[/code],则将[code]old_name[/code]çš„[Font]é‡å‘½å为"
-"[code]name[/code]。如果[code]name[/code]å·²ç»è¢«å ç”¨ï¼Œåˆ™æ­¤æ–¹æ³•失败。"
+"如果主题有 [code]node_type[/code],则将 [code]old_name[/code] çš„ [Font] é‡å‘½"
+"å为 [code]name[/code]。如果 [code]name[/code] å·²ç»è¢«å ç”¨ï¼Œåˆ™æ­¤æ–¹æ³•失败。"
#: doc/classes/Theme.xml
msgid ""
@@ -77398,8 +77925,8 @@ msgid ""
"has [code]node_type[/code]. If [code]name[/code] is already taken, this "
"method fails."
msgstr ""
-"如果主题有[code]node_type[/code],将[code]old_name[/code]的图标é‡å‘½å为"
-"[code]name[/code]。如果[code]name[/code]å·²ç»è¢«å ç”¨ï¼Œåˆ™æ­¤æ–¹æ³•失败。"
+"如果主题有 [code]node_type[/code],则将 [code]old_name[/code] 的图标é‡å‘½å为 "
+"[code]name[/code]。如果 [code]name[/code] å·²ç»è¢«å ç”¨ï¼Œåˆ™æ­¤æ–¹æ³•失败。"
#: doc/classes/Theme.xml
msgid ""
@@ -77407,8 +77934,8 @@ msgid ""
"theme has [code]node_type[/code]. If [code]name[/code] is already taken, "
"this method fails."
msgstr ""
-"如果主题有[code]node_type[/code],则将[StyleBox]在[code]old_name[/code]é‡å‘½å"
-"为[code]name[/code]。如果[code]name[/code]å·²ç»è¢«å ç”¨ï¼Œæ­¤æ–¹æ³•会失败。"
+"如果主题有 [code]node_type[/code],则将 [StyleBox] 在 [code]old_name[/code] "
+"é‡å‘½å为 [code]name[/code]。如果 [code]name[/code] å·²ç»è¢«å ç”¨ï¼Œæ­¤æ–¹æ³•会失败。"
#: doc/classes/Theme.xml
msgid ""
@@ -77426,7 +77953,7 @@ msgid ""
"[code]node_type[/code].\n"
"Creates [code]node_type[/code] if the theme does not have it."
msgstr ""
-"在[code]node_type[/code]中的[code]name[/code]处,设置主题的[Color]为"
+"在 [code]node_type[/code] 中的 [code]name[/code] 处,设置主题的[Color]为"
"[code]color[/code]。\n"
"如果主题没有[code]node_type[/code],则创建该节点。"
@@ -77436,7 +77963,7 @@ msgid ""
"[code]node_type[/code].\n"
"Creates [code]node_type[/code] if the theme does not have it."
msgstr ""
-"在[code]node_type[/code]中的[code]name[/code]处,将主题的常é‡è®¾ç½®ä¸º"
+"在 [code]node_type[/code] 中的 [code]name[/code] 处,将主题的常é‡è®¾ç½®ä¸º"
"[code]constant[/code]。\n"
"如果主题没有,则创建[code]node_type[/code]。"
@@ -77446,7 +77973,7 @@ msgid ""
"[code]node_type[/code].\n"
"Creates [code]node_type[/code] if the theme does not have it."
msgstr ""
-"在[code]node_type[/code]中的[code]name[/code]处将主题的 [Font] 设置为"
+"在 [code]node_type[/code] 中的 [code]name[/code] 处将主题的 [Font] 设置为"
"[code]font[/code]。\n"
"如果主题没有[code]node_type[/code],则创建该节点。"
@@ -77456,7 +77983,7 @@ msgid ""
"in [code]node_type[/code].\n"
"Creates [code]node_type[/code] if the theme does not have it."
msgstr ""
-"在[code]node_type[/code]中的[code]name[/code]处设置主题的图标[Texture]为"
+"在 [code]node_type[/code] 中的 [code]name[/code] 处设置主题的图标[Texture]为"
"[code]texture[/code]。\n"
"如果主题没有[code]node_type[/code],则创建该节点。"
@@ -77531,11 +78058,11 @@ msgstr "主题的 [Font] 字体项类型。"
#: doc/classes/Theme.xml
msgid "Theme's icon [Texture] item type."
-msgstr "主题的图标[Texture]项类型。"
+msgstr "主题的图标 [Texture] 项类型。"
#: doc/classes/Theme.xml
msgid "Theme's [StyleBox] item type."
-msgstr "主题的[StyleBox]项目类型。"
+msgstr "主题的 [StyleBox] 项目类型。"
#: doc/classes/Theme.xml
msgid "Maximum value for the DataType enum."
@@ -77633,7 +78160,7 @@ msgstr ""
#: doc/classes/Thread.xml
msgid "A thread running with lower priority than normally."
-msgstr "一个线程以比正常情况下更低的优先级è¿è¡Œã€‚"
+msgstr "线程以比正常情况下更低的优先级è¿è¡Œã€‚"
#: doc/classes/Thread.xml
msgid "A thread with a standard priority."
@@ -77794,7 +78321,7 @@ msgstr ""
"[codeblock]\n"
"func set_cell(x, y, tile, flip_x=false, flip_y=false, transpose=false, "
"autotile_coord=Vector2()):\n"
-" # 在这里写下你的自定义逻辑。 \n"
+" # 在这里写下你的自定义逻辑。\n"
" # 调用默认方法:\n"
" .set_cell(x, y, tile, flip_x, flip_y, transpose, autotile_coord)\n"
"[/codeblock]"
@@ -77872,17 +78399,17 @@ msgstr "如果为 [code]true[/code],这个 TileMap 会烘焙导航地区。"
#: doc/classes/TileMap.xml
msgid "If [code]true[/code], the cell's UVs will be clipped."
-msgstr "如果[code]true[/code],å•元格的UV将被剪è£ã€‚"
+msgstr "如果为 [code]true[/code],å•元格的 UV 将被剪è£ã€‚"
#: doc/classes/TileMap.xml
msgid "The custom [Transform2D] to be applied to the TileMap's cells."
-msgstr "将应用到图å—地图的,å•元格的自定义[Transform2D]。"
+msgstr "将应用到 TileMap 的,å•元格的自定义 [Transform2D]。"
#: doc/classes/TileMap.xml
msgid ""
"Amount to offset alternating tiles. See [enum HalfOffset] for possible "
"values."
-msgstr "便¬¡æŽ’列的图å—çš„åç§»é‡ã€‚有关å¯èƒ½çš„值,å‚阅[enum HalfOffset]。"
+msgstr "便¬¡æŽ’列的图å—çš„åç§»é‡ã€‚å¯èƒ½çš„å–å€¼è§ [enum HalfOffset]。"
#: doc/classes/TileMap.xml
msgid ""
@@ -77896,13 +78423,13 @@ msgstr "图å—地图的å•元大å°ã€‚"
#: doc/classes/TileMap.xml
msgid "Position for tile origin. See [enum TileOrigin] for possible values."
-msgstr "图å—åŽŸç‚¹çš„åæ ‡ã€‚有关å¯èƒ½çš„值,å‚阅[enum TileOrigin]。"
+msgstr "图å—åŽŸç‚¹çš„åæ ‡ã€‚å¯èƒ½çš„å–å€¼è§ [enum TileOrigin]。"
#: doc/classes/TileMap.xml
msgid ""
"If [code]true[/code], the TileMap's direct children will be drawn in order "
"of their Y coordinate."
-msgstr "如果[code]true[/code],图å—地图的直接å­èŠ‚ç‚¹å°†æŒ‰å…¶Yåæ ‡é¡ºåºç»˜åˆ¶ã€‚"
+msgstr "如果为 [code]true[/code],TileMap 的直接å­èŠ‚ç‚¹å°†æŒ‰å…¶ Y åæ ‡é¡ºåºç»˜åˆ¶ã€‚"
#: doc/classes/TileMap.xml
msgid ""
@@ -77914,12 +78441,12 @@ msgid ""
"If [code]false[/code], the texture position start in the top-left corner "
"unless [member compatibility_mode] is enabled."
msgstr ""
-"如果[code]true[/code],纹ç†å°†è¢«é›†ä¸­åœ¨æ¯ä¸ªå›¾å—的中间。这对æŸäº›ç­‰è·æˆ–上å¸è§†è§’çš„"
-"模å¼å¾ˆæœ‰ç”¨ï¼Œå½“纹ç†è¢«åšå¾—比图å—å¤§æˆ–å°æ—¶ï¼Œä¾‹å¦‚,为了é¿å…瓷砖边缘的闪çƒã€‚åç§»é‡"
-"ä»è¢«åº”用,但从瓦片的中心开始。如果使用,[member compatibility_mode]会被忽"
-"略。\n"
-"如果[code]false[/code],纹ç†å标从左上角开始,除éž[member compatibility_mode]"
-"被å¯ç”¨ã€‚"
+"如果为 [code]true[/code],纹ç†å°†è¢«é›†ä¸­åœ¨æ¯ä¸ªå›¾å—的中间。这对æŸäº›ç­‰è·æˆ–上å¸è§†"
+"角的模å¼å¾ˆæœ‰ç”¨ï¼Œå½“纹ç†è¢«åšå¾—比图å—å¤§æˆ–å°æ—¶ï¼Œä¾‹å¦‚,为了é¿å…图å—边缘的闪çƒã€‚å"
+"ç§»é‡ä»è¢«åº”用,但从图å—的中心开始。如果使用,[member compatibility_mode] 会被"
+"忽略。\n"
+"如果为 [code]false[/code],纹ç†åæ ‡ä»Žå·¦ä¸Šè§’å¼€å§‹ï¼Œé™¤éž [member "
+"compatibility_mode] 被å¯ç”¨ã€‚"
#: doc/classes/TileMap.xml
msgid ""
@@ -77960,16 +78487,16 @@ msgid ""
"If [code]true[/code], TileMap collisions will be handled as a kinematic "
"body. If [code]false[/code], collisions will be handled as static body."
msgstr ""
-"如果[code]true[/code],图å—地图的碰撞将被当作è¿åЍ体处ç†ã€‚如果[code]false[/"
-"code]ï¼Œç¢°æ’žå°†è¢«å½“ä½œé™æ€ä½“æ¥å¤„ç†ã€‚"
+"如果为 [code]true[/code],图å—地图的碰撞将被当作è¿åЍ体处ç†ã€‚如果为 "
+"[code]false[/code]ï¼Œç¢°æ’žå°†è¢«å½“ä½œé™æ€ä½“æ¥å¤„ç†ã€‚"
#: doc/classes/TileMap.xml
msgid ""
"If [code]true[/code], this tilemap's collision shape will be added to the "
"collision shape of the parent. The parent has to be a [CollisionObject2D]."
msgstr ""
-"如果[code]true[/code],这个图å—地图的碰撞形状将被添加到父级的碰撞形状中。父级"
-"必须是一个[CollisionObject2D]。"
+"如果为 [code]true[/code],这个图å—地图的碰撞形状将被添加到父级的碰撞形状中。"
+"父级必须是一个[CollisionObject2D]。"
#: doc/classes/TileMap.xml
msgid ""
@@ -78000,7 +78527,7 @@ msgstr ""
#: doc/classes/TileMap.xml
msgid "The TileMap orientation mode. See [enum Mode] for possible values."
-msgstr "图å—åœ°å›¾çš„æ–¹å‘æ¨¡å¼ã€‚有关å¯èƒ½çš„值,å‚阅[enum Mode]。"
+msgstr "图å—åœ°å›¾çš„æ–¹å‘æ¨¡å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum Mode]。"
#: doc/classes/TileMap.xml
msgid "The navigation layers the TileMap generates its navigation regions in."
@@ -78022,13 +78549,13 @@ msgid ""
"runtime, enable [b]Visible Collision Shapes[/b] in the [b]Debug[/b] menu "
"instead."
msgstr ""
-"如果[code]true[/code],碰撞形状在编辑器中是å¯è§çš„。ä¸å½±å“碰撞形状在è¿è¡Œæ—¶çš„å¯"
-"è§æ€§ã€‚è¦åœ¨è¿è¡Œæ—¶æ˜¾ç¤ºç¢°æ’žå½¢çŠ¶ï¼Œè¯·åœ¨[b]调试[/b]èœå•中å¯ç”¨[b]å¯è§çš„碰撞形状[/"
-"b]。"
+"如果为 [code]true[/code],碰撞形状在编辑器中是å¯è§çš„。ä¸å½±å“碰撞形状在è¿è¡Œæ—¶"
+"çš„å¯è§æ€§ã€‚è¦åœ¨è¿è¡Œæ—¶æ˜¾ç¤ºç¢°æ’žå½¢çŠ¶ï¼Œè¯·åœ¨[b]调试[/b]èœå•中å¯ç”¨[b]å¯è§çš„碰撞形状"
+"[/b]。"
#: doc/classes/TileMap.xml
msgid "The assigned [TileSet]."
-msgstr "指定的[TileSet]图å—集。"
+msgstr "指定的 [TileSet] 图å—集。"
#: doc/classes/TileMap.xml
msgid "Emitted when a tilemap setting has changed."
@@ -78188,7 +78715,7 @@ msgstr ""
#: doc/classes/TileSet.xml
msgid "Sets the [enum BitmaskMode] of the autotile."
-msgstr "设置自动图å—çš„[enum BitmaskMode]ä½æŽ©ç æ¨¡å¼ã€‚"
+msgstr "设置自动图å—çš„ [enum BitmaskMode] ä½æŽ©ç æ¨¡å¼ã€‚"
#: doc/classes/TileSet.xml
msgid ""
@@ -78323,7 +78850,7 @@ msgstr "返回图å—形状的å•å‘碰撞值。"
#: doc/classes/TileSet.xml
msgid "Returns the [Transform2D] of a tile's shape."
-msgstr "返回图å—形状的[Transform2D]。"
+msgstr "返回图å—形状的 [Transform2D]。"
#: doc/classes/TileSet.xml
msgid ""
@@ -78361,11 +78888,11 @@ msgstr "返回图å—的纹ç†åç§»é‡ã€‚"
#: doc/classes/TileSet.xml
msgid "Returns the tile's [enum TileMode]."
-msgstr "返回图å—çš„[enum TileMode]。"
+msgstr "返回图å—çš„ [enum TileMode]。"
#: doc/classes/TileSet.xml
msgid "Returns the tile's Z index (drawing layer)."
-msgstr "返回图å—çš„Z索引,å³ç»˜åˆ¶å±‚。"
+msgstr "返回图å—çš„ Z 索引(绘制层)。"
#: doc/classes/TileSet.xml
msgid "Sets a light occluder for the tile."
@@ -78437,7 +78964,7 @@ msgstr "å¯ç”¨å›¾å—形状上的å•å‘碰撞。"
#: doc/classes/TileSet.xml
msgid "Sets a [Transform2D] on a tile's shape."
-msgstr "在图å—的形状上设置[Transform2D]。"
+msgstr "在图å—的形状上设置 [Transform2D]。"
#: doc/classes/TileSet.xml
msgid "Sets an array of shapes for the tile, enabling collision."
@@ -78453,7 +78980,7 @@ msgstr "设置图å—的纹ç†å移。"
#: doc/classes/TileSet.xml
msgid "Sets the tile's [enum TileMode]."
-msgstr "设置图å—çš„[enum TileMode]。"
+msgstr "设置图å—çš„ [enum TileMode]。"
#: doc/classes/TileSet.xml
msgid "Sets the tile's drawing index."
@@ -78572,7 +79099,7 @@ msgid ""
"with the exception of Daylight Savings Time as it cannot be determined from "
"the epoch."
msgstr ""
-"将给定的 Unix 时间戳转æ¢ä¸ºå­—典,包å«çš„键为: [code]year[/code]ã€[code]month[/"
+"将给定的 Unix 时间戳转æ¢ä¸ºå­—典,包å«çš„键为:[code]year[/code]ã€[code]month[/"
"code]ã€[code]day[/code]ã€[code]weekday[/code]。\n"
"如果 Unix æ—¶é—´æˆ³ä¸ºå½“å‰æ—¶é—´ï¼Œè¿”回的 Dictionary 的值与 [method "
"get_datetime_dict_from_system] 相åŒï¼ŒåŒºåˆ«æ˜¯æ— æ³•æ ¹æ®çºªå…ƒæŽ¨å®šå¤ä»¤æ—¶ã€‚"
@@ -78592,7 +79119,7 @@ msgid ""
"the middle."
msgstr ""
"将给定的时间值字典转æ¢ä¸º ISO 8601 日期和时间字符串(YYYY-MM-DDTHH:MM:SS)。\n"
-"给定的字典å¯ä»¥åŒ…å«ä»¥ä¸‹é”®ï¼š [code]year[/code]ã€[code]month[/code]ã€[code]day[/"
+"给定的字典å¯ä»¥åŒ…å«ä»¥ä¸‹é”®ï¼š[code]year[/code]ã€[code]month[/code]ã€[code]day[/"
"code]ã€[code]hour[/code]ã€[code]minute[/code]ã€[code]second[/code]。其他的记"
"录(包括 [code]dst[/code])都会被忽略。\n"
"字典为空时将返回 [code]0[/code]。如果çœç•¥äº†éƒ¨åˆ†é”®ï¼Œé»˜è®¤ä½¿ç”¨ Unix 纪元时间戳 0"
@@ -78690,7 +79217,7 @@ msgid ""
"[code]name[/code]. The [code]bias[/code] value is the offset from UTC in "
"minutes, since not all time zones are multiples of an hour from UTC."
msgstr ""
-"以字典的形å¼è¿”å›žå½“å‰æ—¶åŒºï¼ŒåŒ…å«çš„键为:[code]bias[/code](å倚)和 "
+"以字典的形å¼è¿”å›žå½“å‰æ—¶åŒºï¼ŒåŒ…å«çš„键为:[code]bias[/code](å置)和 "
"[code]name[/code](å称)。[code]bias[/code] 的值是从 UTC çš„åç§»é‡ï¼Œå•ä½ä¸º"
"åˆ†ï¼Œå› ä¸ºå¹¶ä¸æ˜¯æ‰€æœ‰æ—¶åŒºä¸Ž UTC 的时间差都是整数å€å°æ—¶ã€‚"
@@ -78711,7 +79238,7 @@ msgid ""
"given datetime dictionary."
msgstr ""
"将时间值字典转æ¢ä¸º Unix 时间戳。\n"
-"给定的字典å¯ä»¥åŒ…å«ä»¥ä¸‹é”®ï¼š [code]year[/code]ã€[code]month[/code]ã€[code]day[/"
+"给定的字典å¯ä»¥åŒ…å«ä»¥ä¸‹é”®ï¼š[code]year[/code]ã€[code]month[/code]ã€[code]day[/"
"code]ã€[code]hour[/code]ã€[code]minute[/code]ã€[code]second[/code]。其他的记"
"录(包括 [code]dst[/code])都会被忽略。\n"
"字典为空时将返回 [code]0[/code]。如果çœç•¥äº†éƒ¨åˆ†é”®ï¼Œé»˜è®¤ä½¿ç”¨ Unix 纪元时间戳 0"
@@ -78855,9 +79382,9 @@ msgid ""
"[code]wait_time[/code].\n"
"[b]Note:[/b] This method will not resume a paused timer. See [member paused]."
msgstr ""
-"å¯åŠ¨å®šæ—¶å™¨ã€‚å¦‚æžœ[code]time_sec>0[/code],将[code]wait_time[/code]设置为"
-"[code]time_sec[/code]。这也会将剩余时间é‡ç½®ä¸º[code]wait_time[/code]。\n"
-"[b]注æ„:[/b]这个方法ä¸ä¼šæ¢å¤ä¸€ä¸ªæš‚åœçš„定时器。å‚阅 [member paused]。"
+"å¯åŠ¨å®šæ—¶å™¨ã€‚å¦‚æžœ [code]time_sec > 0[/code],将 [code]wait_time[/code] 设置为 "
+"[code]time_sec[/code]。这也会将剩余时间é‡ç½®ä¸º [code]wait_time[/code]。\n"
+"[b]注æ„:[/b]这个方法ä¸ä¼šæ¢å¤å·²æš‚åœçš„å®šæ—¶å™¨ã€‚è§ [member paused]。"
#: doc/classes/Timer.xml
msgid "Stops the timer."
@@ -78870,7 +79397,7 @@ msgid ""
"[b]Note:[/b] This property is automatically set to [code]false[/code] after "
"the timer enters the scene tree and starts."
msgstr ""
-"如果[code]true[/code],定时器将在进入场景树时自动å¯åŠ¨ã€‚\n"
+"如果为 [code]true[/code],定时器将在进入场景树时自动å¯åŠ¨ã€‚\n"
"[b]注æ„:[/b]在定时器进入场景树并å¯åЍåŽï¼Œè¯¥å±žæ€§ä¼šè‡ªåŠ¨è®¾ç½®ä¸º [code]false[/"
"code]。"
@@ -78879,20 +79406,20 @@ msgid ""
"If [code]true[/code], the timer will stop when reaching 0. If [code]false[/"
"code], it will restart."
msgstr ""
-"如果[code]true[/code],定时器将在达到0æ—¶åœæ­¢ã€‚ 如果[code]false[/code],它将é‡"
-"æ–°å¯åŠ¨ã€‚"
+"如果为 [code]true[/code],定时器将在达到 0 æ—¶åœæ­¢ã€‚如果为 [code]false[/"
+"code]ï¼Œå®ƒå°†é‡æ–°å¯åŠ¨ã€‚"
#: doc/classes/Timer.xml
msgid ""
"If [code]true[/code], the timer is paused and will not process until it is "
"unpaused again, even if [method start] is called."
msgstr ""
-"如果[code]true[/code],定时器会被暂åœï¼Œå¹¶ä¸”ä¸å†å¤„ç†ï¼Œå³ä½¿è°ƒç”¨[method start],"
-"ç›´åˆ°å®ƒè¢«å–æ¶ˆæš‚åœã€‚"
+"如果为 [code]true[/code],定时器会被暂åœï¼Œå¹¶ä¸”ä¸å†å¤„ç†ï¼Œå³ä½¿è°ƒç”¨ [method "
+"start]ï¼Œç›´åˆ°å®ƒè¢«å–æ¶ˆæš‚åœã€‚"
#: doc/classes/Timer.xml
msgid "Processing mode. See [enum TimerProcessMode]."
-msgstr "å¤„ç†æ¨¡å¼ã€‚å‚阅[enum TimerProcessMode]。"
+msgstr "å¤„ç†æ¨¡å¼ã€‚è§ [enum TimerProcessMode]。"
#: doc/classes/Timer.xml
msgid ""
@@ -78900,8 +79427,9 @@ msgid ""
"[b]Note:[/b] You cannot set this value. To change the timer's remaining "
"time, use [method start]."
msgstr ""
-"定时器的剩余时间,å•使˜¯ç§’ã€‚å¦‚æžœå®šæ—¶å™¨å¤„äºŽéžæ¿€æ´»çжæ€ï¼Œåˆ™è¿”回0。\n"
-"[b]注æ„:[/b]ä½ ä¸èƒ½è®¾ç½®è¿™ä¸ªå€¼ã€‚è¦æ”¹å˜å®šæ—¶å™¨çš„剩余时间,请使用[method start]。"
+"定时器的剩余时间,å•使˜¯ç§’ã€‚å¦‚æžœå®šæ—¶å™¨å¤„äºŽéžæ¿€æ´»çжæ€ï¼Œåˆ™è¿”回 0。\n"
+"[b]注æ„:[/b]ä½ ä¸èƒ½è®¾ç½®è¿™ä¸ªå€¼ã€‚è¦æ”¹å˜å®šæ—¶å™¨çš„剩余时间,请使用 [method "
+"start]。"
#: doc/classes/Timer.xml
msgid ""
@@ -78943,8 +79471,8 @@ msgid ""
"btn.flat = true\n"
"[/codeblock]"
msgstr ""
-"这是一个辅助类,用于生æˆä¸€ä¸ªæ‰å¹³çš„[Button],å‚阅 [member Button.flat],创建一"
-"个[ToolButton]就相当于:\n"
+"这是一个辅助类,用于生æˆä¸€ä¸ªæ‰å¹³çš„ [Button]ï¼ˆè§ [member Button.flat]),创建"
+"一个 [ToolButton] 就相当于:\n"
"[codeblock]\n"
"var btn = Button.new()\n"
"btn.flat = true\n"
@@ -78952,11 +79480,11 @@ msgstr ""
#: doc/classes/ToolButton.xml
msgid "Default text [Color] of the [ToolButton]."
-msgstr "[ToolButton] 的默认文本 [Color]颜色。"
+msgstr "[ToolButton] 的默认文本 [Color] 颜色。"
#: doc/classes/ToolButton.xml
msgid "Text [Color] used when the [ToolButton] is disabled."
-msgstr "ç¦ç”¨ [ToolButton] 时使用的文本 [Color]颜色。"
+msgstr "ç¦ç”¨ [ToolButton] 时使用的文本 [Color] 颜色。"
#: doc/classes/ToolButton.xml
msgid ""
@@ -78969,11 +79497,11 @@ msgstr ""
#: doc/classes/ToolButton.xml
msgid "Text [Color] used when the [ToolButton] is being hovered."
-msgstr "[ToolButton] æ‚¬åœæ—¶ä½¿ç”¨çš„æ–‡æœ¬ [Color]颜色。"
+msgstr "[ToolButton] æ‚¬åœæ—¶ä½¿ç”¨çš„æ–‡æœ¬ [Color] 颜色。"
#: doc/classes/ToolButton.xml
msgid "Text [Color] used when the [ToolButton] is being pressed."
-msgstr "按下 [ToolButton] 时使用的文本 [Color]颜色。"
+msgstr "按下 [ToolButton] 时使用的文本 [Color] 颜色。"
#: doc/classes/ToolButton.xml
msgid "The horizontal space between [ToolButton]'s icon and text."
@@ -78981,11 +79509,11 @@ msgstr "[ToolButton] 的图标和文本之间的水平间è·ã€‚"
#: doc/classes/ToolButton.xml
msgid "[Font] of the [ToolButton]'s text."
-msgstr "[ToolButton]的文本的[Font]字体。"
+msgstr "[ToolButton] 的文本的 [Font] 字体。"
#: doc/classes/ToolButton.xml
msgid "[StyleBox] used when the [ToolButton] is disabled."
-msgstr "当[ToolButton]被ç¦ç”¨æ—¶ä½¿ç”¨çš„[StyleBox]。"
+msgstr "当 [ToolButton] 被ç¦ç”¨æ—¶ä½¿ç”¨çš„ [StyleBox]。"
#: doc/classes/ToolButton.xml
msgid ""
@@ -78998,7 +79526,7 @@ msgstr ""
#: doc/classes/ToolButton.xml
msgid "[StyleBox] used when the [ToolButton] is being hovered."
-msgstr "当[ToolButton]è¢«æ‚¬åœæ—¶ä½¿ç”¨çš„[StyleBox]。"
+msgstr "当 [ToolButton] è¢«æ‚¬åœæ—¶ä½¿ç”¨çš„ [StyleBox]。"
#: doc/classes/ToolButton.xml
msgid "Default [StyleBox] for the [ToolButton]."
@@ -79006,7 +79534,7 @@ msgstr "[ToolButton] 的默认 [StyleBox]。"
#: doc/classes/ToolButton.xml
msgid "[StyleBox] used when the [ToolButton] is being pressed."
-msgstr "当[ToolButton]被按下时使用的[StyleBox]。"
+msgstr "当 [ToolButton] 被按下时使用的 [StyleBox]。"
#: doc/classes/TouchScreenButton.xml
msgid "Button for touch screen devices for gameplay use."
@@ -79026,14 +79554,14 @@ msgid ""
"You can configure TouchScreenButton to be visible only on touch devices, "
"helping you develop your game both for desktop and mobile devices."
msgstr ""
-"TouchScreenButtonå…许你为触摸设备创建å±å¹•上的按钮。其为游æˆä½¿ç”¨ï¼Œæ¯”如在必须触"
-"摸æ‰èƒ½ç§»åŠ¨çš„è®¾å¤‡ã€‚ä¸Ž[Button]ä¸åŒï¼ŒTouchScreenButton原生支æŒå¤šç‚¹è§¦æ‘¸ã€‚几个"
-"TouchScreenButtonå¯ä»¥é€šè¿‡è§¦æ‘¸è¾“å…¥åŒæ—¶è¢«æŒ‰ä¸‹ã€‚\n"
-"这个节点继承自[Node2D]。与[Control]节点ä¸åŒï¼Œä½ ä¸èƒ½åœ¨å®ƒä¸Šé¢è®¾ç½®é”šç‚¹ã€‚如果è¦åˆ›"
-"建èœå•或用户界é¢ï¼Œå¯ç”¨[Button]节点代替。为了使按钮节点对触摸事件作出å应,å¯"
-"在项目设置中å¯ç”¨æ¨¡æ‹Ÿé¼ æ ‡é€‰é¡¹ã€‚\n"
-"å¯å°†TouchScreenButtoné…置为åªåœ¨è§¦æ‘¸è®¾å¤‡ä¸Šå¯è§ï¼Œæœ‰åŠ©ä½ åŒæ—¶ä¸ºæ¡Œé¢å’Œç§»åŠ¨è®¾å¤‡å¼€å‘"
-"游æˆã€‚"
+"TouchScreenButton å…许你为触摸设备创建å±å¹•上的按钮。其为游æˆä½¿ç”¨ï¼Œæ¯”如在必须"
+"触摸æ‰èƒ½ç§»åŠ¨çš„è®¾å¤‡ã€‚ä¸Ž [Button] ä¸åŒï¼ŒTouchScreenButton 原生支æŒå¤šç‚¹è§¦æ‘¸ã€‚几"
+"个 TouchScreenButton å¯ä»¥é€šè¿‡è§¦æ‘¸è¾“å…¥åŒæ—¶è¢«æŒ‰ä¸‹ã€‚\n"
+"这个节点继承自 [Node2D]。与 [Control] 节点ä¸åŒï¼Œä½ ä¸èƒ½åœ¨å®ƒä¸Šé¢è®¾ç½®é”šç‚¹ã€‚如果"
+"è¦åˆ›å»ºèœå•或用户界é¢ï¼Œå¯ç”¨ [Button] 节点代替。为了使按钮节点对触摸事件作出å"
+"应,å¯åœ¨é¡¹ç›®è®¾ç½®ä¸­å¯ç”¨æ¨¡æ‹Ÿé¼ æ ‡é€‰é¡¹ã€‚\n"
+"å¯å°† TouchScreenButton é…置为åªåœ¨è§¦æ‘¸è®¾å¤‡ä¸Šå¯è§ï¼Œæœ‰åŠ©ä½ åŒæ—¶ä¸ºæ¡Œé¢å’Œç§»åŠ¨è®¾å¤‡å¼€"
+"呿¸¸æˆã€‚"
#: doc/classes/TouchScreenButton.xml
msgid "Returns [code]true[/code] if this button is currently pressed."
@@ -79041,11 +79569,11 @@ msgstr "如果这个按钮当å‰è¢«æŒ‰ä¸‹ï¼Œåˆ™è¿”回 [code]true[/code]。"
#: doc/classes/TouchScreenButton.xml
msgid "The button's action. Actions can be handled with [InputEventAction]."
-msgstr "按钮的动作。动作å¯ä»¥ç”¨[InputEventAction]æ¥å¤„ç†ã€‚"
+msgstr "按钮的动作。动作å¯ä»¥ç”¨ [InputEventAction] æ¥å¤„ç†ã€‚"
#: doc/classes/TouchScreenButton.xml
msgid "The button's bitmask."
-msgstr "按钮的bit使ީç ã€‚"
+msgstr "æŒ‰é’®çš„ä½æŽ©ç ã€‚"
#: doc/classes/TouchScreenButton.xml
msgid "The button's texture for the normal state."
@@ -79058,9 +79586,9 @@ msgid ""
"pressure started outside the active area of the button.\n"
"[b]Note:[/b] This is a \"pass-by\" (not \"bypass\") press mode."
msgstr ""
-"如果[code]true[/code],åªè¦æŒ‰ä¸‹çš„æ‰‹æŒ‡è¿›å‡ºæŒ‰é’®ï¼Œå°±ä¼šå‘出 [signal pressed] å’Œ"
-"[signal released] ]ä¿¡å·ï¼Œå³ä½¿åŽ‹åŠ›å¼€å§‹äºŽæŒ‰é’®çš„æœ‰æ•ˆåŒºåŸŸä¹‹å¤–ã€‚\n"
-"[b]注æ„:[/b]è¿™æ˜¯ä¸€ç§ \"pass-by\" çš„æŒ‰åŽ‹æ¨¡å¼ ï¼Œè€Œä¸æ˜¯ \"bypass\"。"
+"如果为 [code]true[/code],åªè¦æŒ‰ä¸‹çš„æ‰‹æŒ‡è¿›å‡ºæŒ‰é’®ï¼Œå°±ä¼šå‘出 [signal pressed] "
+"å’Œ[signal released] ]ä¿¡å·ï¼Œå³ä½¿åŽ‹åŠ›å¼€å§‹äºŽæŒ‰é’®çš„æœ‰æ•ˆåŒºåŸŸä¹‹å¤–ã€‚\n"
+"[b]注æ„:[/b]这是一ç§â€œpass-byâ€çš„æŒ‰åŽ‹æ¨¡å¼ ï¼Œè€Œä¸æ˜¯â€œbypassâ€ã€‚"
#: doc/classes/TouchScreenButton.xml
msgid "The button's texture for the pressed state."
@@ -79075,17 +79603,17 @@ msgid ""
"If [code]true[/code], the button's shape is centered in the provided "
"texture. If no texture is used, this property has no effect."
msgstr ""
-"如果[code]true[/code],按钮的形状会在æä¾›çš„纹ç†ä¸­å±…中。如果没有使用纹ç†ï¼Œè¿™ä¸ª"
-"属性就没有效果。"
+"如果为 [code]true[/code],按钮的形状会在æä¾›çš„纹ç†ä¸­å±…中。如果没有使用纹ç†ï¼Œ"
+"这个属性就没有效果。"
#: doc/classes/TouchScreenButton.xml
msgid "If [code]true[/code], the button's shape is visible."
-msgstr "如果[code]true[/code],按钮的形状是å¯è§çš„。"
+msgstr "如果为 [code]true[/code],按钮的形状是å¯è§çš„。"
#: doc/classes/TouchScreenButton.xml
msgid ""
"The button's visibility mode. See [enum VisibilityMode] for possible values."
-msgstr "按钮的å¯è§æ€§æ¨¡å¼ã€‚有关å¯èƒ½çš„值,å‚阅[enum VisibilityMode]。"
+msgstr "按钮的å¯è§æ€§æ¨¡å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum VisibilityMode]。"
#: doc/classes/TouchScreenButton.xml
msgid "Emitted when the button is pressed (down)."
@@ -79161,7 +79689,7 @@ msgid ""
"given [code]weight[/code] (on the range of 0.0 to 1.0)."
msgstr ""
"è¿”å›žåœ¨æ­¤å˜æ¢å’Œå¦ä¸€ä¸ªå˜æ¢ä¹‹é—´é€šè¿‡ç»™å®šçš„[code]weight[/code]æ’å€¼çš„å˜æ¢ï¼ŒèŒƒå›´ä¸º"
-"0.0到1.0。"
+"0.0 到 1.0。"
#: doc/classes/Transform.xml doc/classes/Transform2D.xml
msgid ""
@@ -79190,9 +79718,9 @@ msgid ""
"perpendicular to both the [code]target[/code] and [code]up[/code] vectors.\n"
"Operations take place in global space."
msgstr ""
-"返回一个旋转åŽçš„å˜æ¢å‰¯æœ¬ï¼Œä½¿å…¶-Z轴指å‘[code]target[/code]ä½ç½®ã€‚\n"
-"å˜æ¢å°†é¦–先围绕给定的[code]up[/code]å‘釿—‹è½¬ï¼Œç„¶åŽè¿›ä¸€æ­¥é€šè¿‡å›´ç»•垂直于"
-"[code]target[/code]å’Œ[code]up[/code]å‘é‡çš„轴旋转,æ¥å®Œå…¨ä¸Žç›®æ ‡å¯¹é½ã€‚\n"
+"返回一个旋转åŽçš„å˜æ¢å‰¯æœ¬ï¼Œä½¿å…¶ -Z è½´æŒ‡å‘ [code]target[/code] ä½ç½®ã€‚\n"
+"å˜æ¢å°†é¦–先围绕给定的 [code]up[/code] å‘釿—‹è½¬ï¼Œç„¶åŽè¿›ä¸€æ­¥é€šè¿‡å›´ç»•垂直于 "
+"[code]target[/code] å’Œ [code]up[/code] å‘é‡çš„轴旋转,æ¥å®Œå…¨ä¸Žç›®æ ‡å¯¹é½ã€‚\n"
"æ“作是在全局空间进行的。"
#: doc/classes/Transform.xml doc/classes/Transform2D.xml
@@ -79248,7 +79776,7 @@ msgid ""
"method."
msgstr ""
"将给定的 [Vector3]ã€[Plane]ã€[AABB]ã€[PoolVector3Array] åšè¯¥å˜æ¢çš„é€†å˜æ¢ï¼Œå‰"
-"æå‡è®¾æ˜¯è¯¥å˜æ¢ä»…由旋转和平移构æˆï¼ˆä¸åŒ…æ‹¬ç¼©æ”¾ï¼‰ã€‚ç­‰ä»·äºŽè°ƒç”¨è¯¥å˜æ¢çš„ "
+"æå‡è®¾æ˜¯è¯¥å˜æ¢ä»…由旋转和平移构æˆï¼ˆä¸åŒ…æ‹¬ç¼©æ”¾ï¼‰ã€‚ç›¸å½“äºŽè°ƒç”¨è¯¥å˜æ¢çš„ "
"[code]inverse().xform(v)[/code]ã€‚ä»¿å°„å˜æ¢ï¼ˆå³åŒ…å«ç¼©æ”¾ï¼‰è¯·å‚阅 [method "
"affine_inverse] 方法。"
@@ -79265,7 +79793,7 @@ msgstr ""
msgid ""
"The translation offset of the transform (column 3, the fourth column). "
"Equivalent to array index [code]3[/code]."
-msgstr "å˜æ¢çš„平移åç§»é‡ï¼Œå³ç¬¬3ã€4列。相当于数组索引[code]3[/code]。"
+msgstr "å˜æ¢çš„平移åç§»é‡ï¼Œå³ç¬¬ 3ã€4 列。相当于数组索引 [code]3[/code]。"
#: doc/classes/Transform.xml
msgid ""
@@ -79306,7 +79834,7 @@ msgstr ""
#: doc/classes/Transform2D.xml
msgid "Constructs the transform from a 3D [Transform]."
-msgstr "从一个 3D [Transform] æž„å»ºå˜æ¢ã€‚"
+msgstr "从 3D [Transform] æž„å»ºå˜æ¢ã€‚"
#: doc/classes/Transform2D.xml
msgid ""
@@ -79386,7 +79914,7 @@ msgid ""
"scaling) see [method affine_inverse] method."
msgstr ""
"将给定的 [Vector2]ã€[Rect2]ã€[PoolVector2Array] åšè¯¥å˜æ¢çš„é€†å˜æ¢ï¼Œå‰æå‡è®¾æ˜¯"
-"è¯¥å˜æ¢ä»…由旋转和平移构æˆï¼ˆä¸åŒ…æ‹¬ç¼©æ”¾ï¼‰ã€‚ç­‰ä»·äºŽè°ƒç”¨è¯¥å˜æ¢çš„ [code]inverse()."
+"è¯¥å˜æ¢ä»…由旋转和平移构æˆï¼ˆä¸åŒ…æ‹¬ç¼©æ”¾ï¼‰ã€‚ç›¸å½“äºŽè°ƒç”¨è¯¥å˜æ¢çš„ [code]inverse()."
"xform(v)[/code]ã€‚ä»¿å°„å˜æ¢ï¼ˆå³åŒ…å«ç¼©æ”¾ï¼‰è¯·å‚阅 [method affine_inverse] 方法。"
#: doc/classes/Transform2D.xml
@@ -79538,12 +80066,23 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
"这展示了一个å¯ä»¥é€‰æ‹©ã€å±•开和折å çš„项目树。该树å¯ä»¥æœ‰å¤šåˆ—的自定义控件,如文本"
"ç¼–è¾‘ã€æŒ‰é’®å’Œå¼¹å‡ºçª—å£ã€‚它对于结构化显示和互动很有用。\n"
-"树通过代ç å»ºç«‹ï¼Œä½¿ç”¨[TreeItem]å¯¹è±¡æ¥æž„建结构。它们有一个å•独根节点,但如果添"
-"加一个虚拟的éšè—根节点,就å¯ä»¥æ¨¡æ‹Ÿå¤šä¸ªæ ¹ã€‚\n"
+"树通过代ç å»ºç«‹ï¼Œä½¿ç”¨ [TreeItem] å¯¹è±¡æ¥æž„建结构。它们有一个å•独根节点,但如果"
+"添加一个虚拟的éšè—根节点,就å¯ä»¥æ¨¡æ‹Ÿå¤šä¸ªæ ¹ã€‚\n"
"[codeblock]\n"
"func _ready():\n"
" var tree = Tree.new()\n"
@@ -79554,9 +80093,17 @@ msgstr ""
" var subchild1 = tree.create_item(child1)\n"
" subchild1.set_text(0, \"Subchild1\")\n"
"[/codeblock]\n"
-"è¦é历一个[Tree]对象中的所有[TreeItem]对象,在通过[method get_root]获得根之"
-"åŽï¼Œä½¿ç”¨[method TreeItem.get_next]å’Œ[method TreeItem.get_children]方法。你å¯"
-"以对一个[TreeItem]使用[method Object.free]æ¥æŠŠå®ƒä»Ž[Tree]中移除。"
+"è¦é历一个 [Tree] 对象中的所有 [TreeItem] 对象,在通过 [method get_root] 获得"
+"根之åŽï¼Œä½¿ç”¨ [method TreeItem.get_next] å’Œ [method TreeItem.get_children] æ–¹"
+"法。你å¯ä»¥å¯¹ä¸€ä¸ª [TreeItem] 使用 [method Object.free] æ¥æŠŠå®ƒä»Ž [Tree] 中移"
+"除。\n"
+"[b]å¢žé‡æœç´¢ï¼š[/b]与 [ItemList] å’Œ [PopupMenu] 类似,[Tree] 也支æŒåœ¨èšç„¦æŽ§ä»¶æ—¶"
+"在列表中进行æœç´¢ã€‚按下与æŸä¸ªæ¡ç›®å称首字æ¯ä¸€è‡´çš„æŒ‰é”®ï¼Œå°±ä¼šé€‰ä¸­ä»¥è¯¥å­—æ¯å¼€å¤´çš„"
+"第一个æ¡ç›®ã€‚在此之åŽï¼Œè¿›è¡Œå¢žé‡æœç´¢çš„办法有两ç§ï¼š1)在超时å‰å†æ¬¡æŒ‰ä¸‹åŒä¸€ä¸ªæŒ‰"
+"键,选中以该字æ¯å¼€å¤´çš„下一个æ¡ç›®ã€‚2ï¼‰åœ¨è¶…æ—¶å‰æŒ‰ä¸‹å‰©ä½™å­—æ¯å¯¹åº”的按键,直接匹é…"
+"并选中所需的æ¡ç›®ã€‚这两个动作都会在最åŽä¸€æ¬¡æŒ‰é”®è¶…æ—¶åŽé‡ç½®å›žåˆ—表顶端。你å¯ä»¥é€š"
+"过 [member ProjectSettings.gui/timers/incremental_search_max_interval_msec] "
+"修改超时时长。"
#: doc/classes/Tree.xml
msgid "Clears the tree. This removes all items."
@@ -79584,9 +80131,9 @@ msgid ""
"editable with [method TreeItem.set_editable]. Returns [code]true[/code] if "
"the item could be edited. Fails if no item is selected."
msgstr ""
-"编辑选中的树项,就åƒå®ƒè¢«ç‚¹å‡»ä¸€æ ·ã€‚该项必须通过[method TreeItem.set_editable]"
-"设置为å¯ç¼–辑。其å¯è¢«ç¼–辑,则返回 [code]true[/code]。如果没有项被选中,则失"
-"败。"
+"编辑选中的树项,就åƒå®ƒè¢«ç‚¹å‡»ä¸€æ ·ã€‚该项必须通过 [method TreeItem."
+"set_editable] 设置为å¯ç¼–辑。其å¯è¢«ç¼–辑,则返回 [code]true[/code]。如果没有项"
+"被选中,则失败。"
#: doc/classes/Tree.xml
msgid ""
@@ -79598,8 +80145,8 @@ msgid ""
"only visible in [constant SELECT_MULTI] mode."
msgstr ""
"使当å‰èŽ·å¾—ç„¦ç‚¹çš„å•å…ƒå¯è§ã€‚\n"
-"如果有必è¦ï¼Œå°†æ»šåŠ¨æ ‘ã€‚åœ¨[constant SELECT_ROW]模å¼ä¸‹ï¼Œä¸ä¼šåšæ°´å¹³æ»šåŠ¨ï¼Œå› ä¸ºæ‰€é€‰"
-"行中的所有å•元都按逻辑获得焦点。\n"
+"如果有必è¦ï¼Œå°†æ»šåŠ¨æ ‘ã€‚åœ¨ [constant SELECT_ROW] 模å¼ä¸‹ï¼Œä¸ä¼šåšæ°´å¹³æ»šåŠ¨ï¼Œå› ä¸ºæ‰€"
+"选行中的所有å•元都按逻辑获得焦点。\n"
"[b]注æ„:[/b]尽管这个方法的å称是这样的,但焦点光标本身åªåœ¨ [constant "
"SELECT_MULTI] 模å¼ä¸‹å¯è§ã€‚"
@@ -79626,7 +80173,7 @@ msgid ""
"Returns the rectangle for custom popups. Helper to create custom cell "
"controls that display a popup. See [method TreeItem.set_cell_mode]."
msgstr ""
-"返回自定义弹出窗å£çš„矩形。帮助创建显示弹出å¼çš„自定义å•元格控件。å‚阅[method "
+"返回自定义弹出窗å£çš„矩形。帮助创建显示弹出å¼çš„自定义å•å…ƒæ ¼æŽ§ä»¶ã€‚è§ [method "
"TreeItem.set_cell_mode]。"
#: doc/classes/Tree.xml
@@ -79639,10 +80186,10 @@ msgid ""
"To get the item which the returned drop section is relative to, use [method "
"get_item_at_position]."
msgstr ""
-"返回ä½äºŽ[code]position[/code]的放置部分,如果没有项目,则返回-100。\n"
-"在 \"项目上方\"ã€\"项目之上\"å’Œ \"项目下方\"的放置部分将分别返回-1ã€0或1çš„"
-"值。请å‚阅[enum DropModeFlags]以了解æ¯ä¸ªæ”¾ç½®éƒ¨åˆ†çš„æè¿°ã€‚\n"
-"è¦èŽ·å¾—è¿”å›žçš„æ”¾ç½®éƒ¨åˆ†ç›¸å¯¹é¡¹ï¼Œè¯·ä½¿ç”¨[method get_item_at_position]。"
+"返回ä½äºŽ [code]position[/code] 的放置部分,如果没有项目,则返回 -100。\n"
+"在“项目上方â€â€œé¡¹ç›®ä¹‹ä¸Šâ€å’Œâ€œé¡¹ç›®ä¸‹æ–¹â€çš„æ”¾ç½®éƒ¨åˆ†å°†åˆ†åˆ«è¿”回 -1ã€0 或 1 的值。请å‚"
+"阅 [enum DropModeFlags] 以了解æ¯ä¸ªæ”¾ç½®éƒ¨åˆ†çš„æè¿°ã€‚\n"
+"è¦èŽ·å¾—è¿”å›žçš„æ”¾ç½®éƒ¨åˆ†ç›¸å¯¹é¡¹ï¼Œè¯·ä½¿ç”¨ [method get_item_at_position]。"
#: doc/classes/Tree.xml
msgid ""
@@ -79718,9 +80265,10 @@ msgid ""
"To get the currently selected item(s), use [method get_next_selected]."
msgstr ""
"返回当å‰çš„焦点项,如果没有焦点项,则返回 [code]null[/code]。\n"
-"在[constant SELECT_ROW]å’Œ[constant SELECT_SINGLE]模å¼ä¸‹ï¼Œç„¦ç‚¹é¡¹ä¸Žé€‰æ‹©é¡¹ç›¸åŒã€‚"
-"在[constant SELECT_MULTI]模å¼ä¸‹ï¼Œç„¦ç‚¹é¡¹æ˜¯ç„¦ç‚¹å…‰æ ‡ä¸‹çš„项目,ä¸ä¸€å®šè¢«é€‰ä¸­ã€‚\n"
-"è¦è޷得当å‰é€‰ä¸­é¡¹ï¼Œè¯·ä½¿ç”¨[method get_next_selected]。"
+"在 [constant SELECT_ROW] å’Œ [constant SELECT_SINGLE] 模å¼ä¸‹ï¼Œç„¦ç‚¹é¡¹ä¸Žé€‰æ‹©é¡¹ç›¸"
+"åŒã€‚在 [constant SELECT_MULTI] 模å¼ä¸‹ï¼Œç„¦ç‚¹é¡¹æ˜¯ç„¦ç‚¹å…‰æ ‡ä¸‹çš„项目,ä¸ä¸€å®šè¢«é€‰"
+"中。\n"
+"è¦è޷得当å‰é€‰ä¸­é¡¹ï¼Œè¯·ä½¿ç”¨ [method get_next_selected]。"
#: doc/classes/Tree.xml
msgid ""
@@ -79732,11 +80280,11 @@ msgid ""
"To tell whether a column of an item is selected, use [method TreeItem."
"is_selected]."
msgstr ""
-"返回当å‰èŽ·å¾—ç„¦ç‚¹çš„åˆ—ï¼Œå¦‚æžœæ²¡æœ‰ç„¦ç‚¹åˆ—ï¼Œåˆ™è¿”å›ž-1。\n"
-"在[constant SELECT_SINGLE]模å¼ä¸‹ï¼Œç„¦ç‚¹åˆ—是被选中的列。在[constant SELECT_ROW]"
-"模å¼ä¸‹ï¼Œå¦‚果有任æ„项被选中,焦点列总是0。在[constant SELECT_MULTI]模å¼ä¸‹ï¼Œç„¦"
-"点列是焦点光标下的列,但ä¸ä¸€å®šæœ‰åˆ—被选中。\n"
-"è¦åˆ¤æ–­ä¸€ä¸ªé¡¹çš„æŸä¸€åˆ—æ˜¯å¦è¢«é€‰ä¸­ï¼Œè¯·ä½¿ç”¨[method TreeItem.is_selected]。"
+"返回当å‰èŽ·å¾—ç„¦ç‚¹çš„åˆ—ï¼Œå¦‚æžœæ²¡æœ‰ç„¦ç‚¹åˆ—ï¼Œåˆ™è¿”å›ž -1。\n"
+"在[constant SELECT_SINGLE] 模å¼ä¸‹ï¼Œç„¦ç‚¹åˆ—是被选中的列。在 [constant "
+"SELECT_ROW] 模å¼ä¸‹ï¼Œå¦‚果有任æ„项被选中,焦点列总是 0。在 [constant "
+"SELECT_MULTI] 模å¼ä¸‹ï¼Œç„¦ç‚¹åˆ—是焦点光标下的列,但ä¸ä¸€å®šæœ‰åˆ—被选中。\n"
+"è¦åˆ¤æ–­ä¸€ä¸ªé¡¹çš„æŸä¸€åˆ—æ˜¯å¦è¢«é€‰ä¸­ï¼Œè¯·ä½¿ç”¨ [method TreeItem.is_selected]。"
#: doc/classes/Tree.xml
msgid "Causes the [Tree] to jump to the specified [TreeItem]."
@@ -79748,8 +80296,8 @@ msgid ""
"Columns that have the \"Expand\" flag will use their \"min_width\" in a "
"similar fashion to [member Control.size_flags_stretch_ratio]."
msgstr ""
-"如果 [code]true[/code],该列将拥有 [Control] 的“Expandâ€æ ‡å¿—。拥有“Expandâ€æ ‡å¿—"
-"的列,将以类似于 [member Control.size_flags_stretch_ratio] 的方å¼ä½¿ç”¨"
+"如果为 [code]true[/code],该列将拥有 [Control] 的“Expandâ€æ ‡å¿—。拥有“Expandâ€æ ‡"
+"志的列,将以类似于 [member Control.size_flags_stretch_ratio] 的方å¼ä½¿ç”¨"
"其“min_widthâ€æœ€å°å®½åº¦ã€‚"
#: doc/classes/Tree.xml
@@ -79768,15 +80316,15 @@ msgstr "设置一个列的标题。"
#: doc/classes/Tree.xml
msgid ""
"If [code]true[/code], the currently selected cell may be selected again."
-msgstr "如果[code]true[/code],å¯ä»¥å†æ¬¡é€‰æ‹©å½“å‰é€‰å®šçš„å•元。"
+msgstr "如果为 [code]true[/code],å¯ä»¥å†æ¬¡é€‰æ‹©å½“å‰é€‰å®šçš„å•元。"
#: doc/classes/Tree.xml
msgid "If [code]true[/code], a right mouse button click can select items."
-msgstr "如果[code]true[/code],鼠标å³é”®ç‚¹å‡»å¯ä»¥é€‰æ‹©é¡¹ç›®ã€‚"
+msgstr "如果为 [code]true[/code],鼠标å³é”®ç‚¹å‡»å¯ä»¥é€‰æ‹©é¡¹ç›®ã€‚"
#: doc/classes/Tree.xml
msgid "If [code]true[/code], column titles are visible."
-msgstr "如果[code]true[/code],列标题å¯è§ã€‚"
+msgstr "如果为 [code]true[/code],列标题å¯è§ã€‚"
#: doc/classes/Tree.xml
msgid "The number of columns."
@@ -79790,29 +80338,29 @@ msgid ""
"This controls the drop sections, i.e. the decision and drawing of possible "
"drop locations based on the mouse position."
msgstr ""
-"作为一个标志的OR组åˆçš„æ”¾ç½®æ¨¡å¼ã€‚å‚阅[enum DropModeFlags]常é‡ã€‚一旦拖动完æˆï¼Œ"
-"å°†æ¢å¤åˆ°[constant DROP_MODE_DISABLED]。建议在[method Control.can_drop_data]中"
-"设置这个。\n"
+"作为一个标志的 OR 组åˆçš„æ”¾ç½®æ¨¡å¼ã€‚è§ [enum DropModeFlags] 常é‡ã€‚一旦拖动完"
+"æˆï¼Œå°†æ¢å¤åˆ° [constant DROP_MODE_DISABLED]。建议在 [method Control."
+"can_drop_data] 中设置这个。\n"
"æŽ§ä»¶æ”¾ç½®éƒ¨åˆ†ï¼Œå³æ ¹æ®é¼ æ ‡ä½ç½®å†³å®šå’Œç»˜åˆ¶å¯èƒ½çš„æ”¾ç½®ä½ç½®ã€‚"
#: doc/classes/Tree.xml
msgid "If [code]true[/code], the folding arrow is hidden."
-msgstr "如果[code]true[/code],éšè—折å ç®­å¤´ã€‚"
+msgstr "如果为 [code]true[/code],éšè—折å ç®­å¤´ã€‚"
#: doc/classes/Tree.xml
msgid "If [code]true[/code], the tree's root is hidden."
-msgstr "如果[code]true[/code],则éšè—树的根节点。"
+msgstr "如果为 [code]true[/code],则éšè—树的根节点。"
#: doc/classes/Tree.xml
msgid ""
"Allows single or multiple selection. See the [enum SelectMode] constants."
-msgstr "å…许å•选或多选。å‚阅[enum SelectMode]常é‡ã€‚"
+msgstr "å…许å•é€‰æˆ–å¤šé€‰ã€‚è§ [enum SelectMode] 常é‡ã€‚"
#: doc/classes/Tree.xml
msgid ""
"Emitted when a button on the tree was pressed (see [method TreeItem."
"add_button])."
-msgstr "当树中按钮被按下时触å‘,å‚阅[method TreeItem.add_button]。"
+msgstr "当树中按钮被按下时触å‘ï¼ˆè§ [method TreeItem.add_button])。"
#: doc/classes/Tree.xml
msgid "Emitted when a cell is selected."
@@ -79827,7 +80375,7 @@ msgid ""
"Emitted when a cell with the [constant TreeItem.CELL_MODE_CUSTOM] is clicked "
"to be edited."
msgstr ""
-"当具有[constant TreeItem.CELL_MODE_CUSTOM]çš„å•元格被点击,进行编辑时触å‘。"
+"当具有 [constant TreeItem.CELL_MODE_CUSTOM] çš„å•元格被点击,进行编辑时触å‘。"
#: doc/classes/Tree.xml
msgid ""
@@ -79854,8 +80402,8 @@ msgid ""
"Emitted when a custom button is pressed (i.e. in a [constant TreeItem."
"CELL_MODE_CUSTOM] mode cell)."
msgstr ""
-"当自定义按钮被按下时触å‘,å³åœ¨[constant TreeItem.CELL_MODE_CUSTOM]模å¼å•元格"
-"中。"
+"当自定义按钮被按下时触å‘(å³åœ¨ [constant TreeItem.CELL_MODE_CUSTOM] 模å¼å•å…ƒ"
+"格中)。"
#: doc/classes/Tree.xml
msgid "Emitted when an item's icon is double-clicked."
@@ -79882,7 +80430,7 @@ msgid ""
"Emitted instead of [code]item_selected[/code] if [code]select_mode[/code] is "
"[constant SELECT_MULTI]."
msgstr ""
-"如果[code]select_mode[/code]是[constant SELECT_MULTI],则触å‘代替"
+"如果 [code]select_mode[/code] 是 [constant SELECT_MULTI],则触å‘代替 "
"[code]item_selected[/code]。"
#: doc/classes/Tree.xml
@@ -79936,8 +80484,8 @@ msgid ""
"[b]Note:[/b] This is the default flag, it has no effect when combined with "
"other flags."
msgstr ""
-"ç¦ç”¨æ‰€æœ‰æ”¾ç½®éƒ¨åˆ†ï¼Œä½†ä»ç„¶å…许通过[method get_drop_section_at_position]检测 "
-"\"物å“上\" 的放置部分。\n"
+"ç¦ç”¨æ‰€æœ‰æ”¾ç½®éƒ¨åˆ†ï¼Œä½†ä»ç„¶å…许通过 [method get_drop_section_at_position] 检"
+"测“物å“上â€çš„æ”¾ç½®éƒ¨åˆ†ã€‚\n"
"[b]注æ„:[/b]è¿™æ˜¯é»˜è®¤çš„æ ‡å¿—ï¼Œå½“ä¸Žå…¶ä»–æ ‡å¿—ç»“åˆæ—¶ï¼Œå®ƒæ²¡æœ‰æ•ˆæžœã€‚"
#: doc/classes/Tree.xml
@@ -79947,9 +80495,9 @@ msgid ""
"When combined with [constant DROP_MODE_INBETWEEN], this drop section halves "
"the height and stays centered vertically."
msgstr ""
-"å¯ç”¨ \"项目上\" 的放置部分。这个放置部分覆盖整个项。\n"
-"当与[constant DROP_MODE_INBETWEEN]结åˆä½¿ç”¨æ—¶ï¼Œè¿™ä¸ªæ”¾ç½®éƒ¨åˆ†çš„高度å‡åŠï¼Œå¹¶ä¿æŒ"
-"垂直居中。"
+"å¯ç”¨â€œé¡¹ç›®ä¸Šâ€çš„æ”¾ç½®éƒ¨åˆ†ã€‚这个放置部分覆盖整个项。\n"
+"当与 [constant DROP_MODE_INBETWEEN] 结åˆä½¿ç”¨æ—¶ï¼Œè¿™ä¸ªæ”¾ç½®éƒ¨åˆ†çš„高度å‡åŠï¼Œå¹¶ä¿"
+"æŒåž‚直居中。"
#: doc/classes/Tree.xml
msgid ""
@@ -79959,41 +80507,42 @@ msgid ""
"When combined with [constant DROP_MODE_ON_ITEM], these drop sections halves "
"the height and stays on top / bottom accordingly."
msgstr ""
-"å¯ç”¨ \"项目上方\" å’Œ \"项目下方\" 的放置部分。\"项目上方\" 的放置部分覆盖项目"
-"的上åŠéƒ¨åˆ†ï¼Œ\"项目下方\" 的放置部分覆盖下åŠéƒ¨åˆ†ã€‚\n"
-"当与[constant DROP_MODE_ON_ITEM]ç»“åˆæ—¶ï¼Œè¿™äº›æ”¾ç½®éƒ¨åˆ†çš„高度å‡åŠï¼Œå¹¶ç›¸åº”地åœç•™"
-"在顶部或底部。"
+"å¯ç”¨â€œé¡¹ç›®ä¸Šæ–¹â€å’Œâ€œé¡¹ç›®ä¸‹æ–¹â€çš„æ”¾ç½®éƒ¨åˆ†ã€‚“项目上方â€çš„æ”¾ç½®éƒ¨åˆ†è¦†ç›–项目的上åŠéƒ¨"
+"分,“项目下方â€çš„æ”¾ç½®éƒ¨åˆ†è¦†ç›–下åŠéƒ¨åˆ†ã€‚\n"
+"当与 [constant DROP_MODE_ON_ITEM] ç»“åˆæ—¶ï¼Œè¿™äº›æ”¾ç½®éƒ¨åˆ†çš„高度å‡åŠï¼Œå¹¶ç›¸åº”地åœ"
+"留在顶部或底部。"
#: doc/classes/Tree.xml
msgid ""
"Text [Color] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's "
"hovered."
msgstr ""
-"当[constant TreeItem.CELL_MODE_CUSTOM]模å¼çš„å•å…ƒæ ¼è¢«æ‚¬åœæ—¶çš„æ–‡æœ¬[Color]颜色。"
+"当 [constant TreeItem.CELL_MODE_CUSTOM] 模å¼çš„å•å…ƒæ ¼è¢«æ‚¬åœæ—¶çš„æ–‡æœ¬ [Color] 颜"
+"色。"
#: doc/classes/Tree.xml
msgid ""
"[Color] used to draw possible drop locations. See [enum DropModeFlags] "
"constants for further description of drop locations."
msgstr ""
-"用于绘制å¯èƒ½çš„æ”¾ç½®ä½ç½®çš„[Color]颜色。有关放置ä½ç½®çš„æè¿°ï¼Œå‚阅[enum "
-"DropModeFlags]常é‡ã€‚"
+"用于绘制å¯èƒ½çš„æ”¾ç½®ä½ç½®çš„ [Color] 颜色。有关放置ä½ç½®çš„æè¿°ï¼Œå‚阅 [enum "
+"DropModeFlags] 常é‡ã€‚"
#: doc/classes/Tree.xml
msgid "[Color] of the guideline."
-msgstr "å‚考线的[Color]颜色。"
+msgstr "å‚考线的 [Color] 颜色。"
#: doc/classes/Tree.xml
msgid "[Color] of the relationship lines."
-msgstr "关系线的[Color]颜色。"
+msgstr "关系线的 [Color] 颜色。"
#: doc/classes/Tree.xml
msgid "Default text [Color] of the title button."
-msgstr "标题按钮的默认文本[Color]颜色。"
+msgstr "标题按钮的默认文本 [Color] 颜色。"
#: doc/classes/Tree.xml
msgid "The horizontal space between each button in a cell."
-msgstr "一个å•元中æ¯ä¸ªæŒ‰é’®ä¹‹é—´çš„æ°´å¹³ç©ºé—´ã€‚"
+msgstr "å•元格中按钮之间的水平间è·ã€‚"
#: doc/classes/Tree.xml
msgid ""
@@ -80102,8 +80651,7 @@ msgstr "当 [Tree] 未获èšç„¦æ—¶ï¼Œç”¨äºŽå…‰æ ‡çš„ [StyleBox]。"
#: doc/classes/Tree.xml
msgid ""
"Default [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell."
-msgstr ""
-"为 [constant TreeItem.CELL_MODE_CUSTOM] 模å¼çš„å•元格默认的 [StyleBox]。"
+msgstr "[constant TreeItem.CELL_MODE_CUSTOM] 模å¼çš„å•元格默认的 [StyleBox]。"
#: doc/classes/Tree.xml
msgid ""
@@ -80122,7 +80670,7 @@ msgstr ""
#: doc/classes/Tree.xml
msgid ""
"[StyleBox] for the selected items, used when the [Tree] is not being focused."
-msgstr "所选项目的 [StyleBox],当 [Tree] 没有获得焦点时使用。"
+msgstr "所选项目的 [StyleBox],在 [Tree] 没有获得焦点时使用。"
#: doc/classes/Tree.xml
msgid ""
@@ -80151,7 +80699,7 @@ msgid ""
"styled as well as contain buttons.\n"
"You can remove a [TreeItem] by using [method Object.free]."
msgstr ""
-"控件 [Tree] 中的å•个项目。å¯ä»¥æœ‰å­çº§ [TreeItem], æ ·å¼ï¼Œ 以åŠåŒ…嫿Œ‰é’®ã€‚\n"
+"控件 [Tree] 中的å•个项目。å¯ä»¥æœ‰å­çº§ [TreeItem]ã€æ ·å¼ã€åŒ…嫿Œ‰é’®ã€‚\n"
"您å¯ä»¥ä½¿ç”¨ [method Object.free] 删除 [TreeItem]。"
#: doc/classes/TreeItem.xml
@@ -80162,7 +80710,7 @@ msgid ""
"get_button_count] immediately before this method. Optionally, the button can "
"be [code]disabled[/code] and have a [code]tooltip[/code]."
msgstr ""
-"在 [code]column[/code] 列添加一个带有 [Texture] [code]button[/code] 的按钮。 "
+"在 [code]column[/code] 列添加一个带有 [Texture] [code]button[/code] 的按钮。"
"[code]id[/code] 用于标识按钮。如果未指定,则使用下一个å¯ç”¨ç´¢å¼•,å¯ä»¥åœ¨æ­¤æ–¹æ³•"
"之å‰è°ƒç”¨ [method get_button_count] æ¥èŽ·å–该索引。å¦å¤–,该按钮还å¯ä»¥é€šè¿‡ "
"[code]disabled[/code] ç¦ç”¨ã€é€šè¿‡ [code]tooltip[/code] 设置工具æç¤ºã€‚"
@@ -80172,8 +80720,8 @@ msgid ""
"Calls the [code]method[/code] on the actual TreeItem and its children "
"recursively. Pass parameters as a comma separated list."
msgstr ""
-"在实际的TreeItem树项åŠå…¶å­é¡¹ä¸Šé€’归地调用[code]method[/code]。以逗å·åˆ†éš”的列表"
-"å½¢å¼ä¼ é€’傿•°ã€‚"
+"在实际的 TreeItem 树项åŠå…¶å­é¡¹ä¸Šé€’归地调用 [code]method[/code]。以逗å·åˆ†éš”çš„"
+"列表形å¼ä¼ é€’傿•°ã€‚"
#: doc/classes/TreeItem.xml
msgid "Resets the background color for the given column to default."
@@ -80191,7 +80739,7 @@ msgstr "å–æ¶ˆé€‰æ‹©æŒ‡å®šåˆ—。"
msgid ""
"Removes the button at index [code]button_idx[/code] in column [code]column[/"
"code]."
-msgstr "删除列[code]column[/code]中索引[code]button_idx[/code]处的按钮。"
+msgstr "删除列 [code]column[/code] 中索引 [code]button_idx[/code] 处的按钮。"
#: doc/classes/TreeItem.xml
msgid ""
@@ -80239,15 +80787,15 @@ msgstr "返回 TreeItem 树项的第一个å­é¡¹ï¼Œå¦‚果没有,则返回一ä¸
#: doc/classes/TreeItem.xml
msgid "Returns the custom background color of column [code]column[/code]."
-msgstr "返回列[code]column[/code]的自定义背景颜色。"
+msgstr "返回列 [code]column[/code] 的自定义背景颜色。"
#: doc/classes/TreeItem.xml
msgid "Returns the custom color of column [code]column[/code]."
-msgstr "返回列[code]column[/code]的自定义颜色。"
+msgstr "返回列 [code]column[/code] 的自定义颜色。"
#: doc/classes/TreeItem.xml
msgid "Returns [code]true[/code] if [code]expand_right[/code] is set."
-msgstr "如果设置了[code]expand_right[/code],返回 [code]true[/code]。"
+msgstr "如果设置了 [code]expand_right[/code],则返回 [code]true[/code]。"
#: doc/classes/TreeItem.xml
msgid "Returns the given column's icon [Texture]. Error if no icon is set."
@@ -80259,7 +80807,7 @@ msgstr "返回列的图标的最大宽度。"
#: doc/classes/TreeItem.xml
msgid "Returns the [Color] modulating the column's icon."
-msgstr "返回调制列的图标的[Color]颜色。"
+msgstr "返回调制列的图标的 [Color] 颜色。"
#: doc/classes/TreeItem.xml
msgid "Returns the icon [Texture] region as [Rect2]."
@@ -80274,7 +80822,7 @@ msgstr "返回使用 [method set_metadata] 为指定列设置的元数æ®ã€‚"
#: doc/classes/TreeItem.xml
msgid ""
"Returns the next TreeItem in the tree or a null object if there is none."
-msgstr "返回树中的下一个TreeItem树项,如果没有,则返回一个空对象。"
+msgstr "返回树中的下一个 TreeItem,如果没有,则返回一个空对象。"
#: doc/classes/TreeItem.xml
msgid ""
@@ -80284,18 +80832,18 @@ msgid ""
"visible element in the tree when called on the last visible element, "
"otherwise it returns [code]null[/code]."
msgstr ""
-"返回树中下一个å¯è§çš„TreeItem树项,如果没有,则返回空对象。\n"
-"如果[code]wrap[/code]被å¯ç”¨ï¼Œå½“在最åŽä¸€ä¸ªå¯è§å…ƒç´ ä¸Šè°ƒç”¨æ—¶ï¼Œè¯¥æ–¹æ³•将环绕到树中"
-"的第一个å¯è§å…ƒç´ ï¼Œå¦åˆ™å®ƒå°†è¿”回 [code]null[/code]。"
+"返回树中下一个å¯è§çš„ TreeItem,如果没有,则返回空对象。\n"
+"如果 [code]wrap[/code] 被å¯ç”¨ï¼Œå½“在最åŽä¸€ä¸ªå¯è§å…ƒç´ ä¸Šè°ƒç”¨æ—¶ï¼Œè¯¥æ–¹æ³•将环绕到树"
+"中的第一个å¯è§å…ƒç´ ï¼Œå¦åˆ™å®ƒå°†è¿”回 [code]null[/code]。"
#: doc/classes/TreeItem.xml
msgid "Returns the parent TreeItem or a null object if there is none."
-msgstr "返回父级TreeItem树项,如果没有,则返回一个空对象。"
+msgstr "返回父级 TreeItem,如果没有,则返回一个空对象。"
#: doc/classes/TreeItem.xml
msgid ""
"Returns the previous TreeItem in the tree or a null object if there is none."
-msgstr "返回树中的å‰ä¸€ä¸ªTreeItem树项,如果没有,则返回一个空对象。"
+msgstr "返回树中的å‰ä¸€ä¸ª TreeItem,如果没有,则返回一个空对象。"
#: doc/classes/TreeItem.xml
msgid ""
@@ -80305,9 +80853,9 @@ msgid ""
"visible element in the tree when called on the first visible element, "
"otherwise it returns [code]null[/code]."
msgstr ""
-"返回树中å‰ä¸€ä¸ªå¯è§çš„TreeItem树项,如果没有,则返回null对象。\n"
-"如果[code]wrap[/code]被å¯ç”¨ï¼Œå½“在第一个å¯è§å…ƒç´ ä¸Šè°ƒç”¨æ—¶ï¼Œè¯¥æ–¹æ³•将环绕到树中最"
-"åŽä¸€ä¸ªå¯è§å…ƒç´ ï¼Œå¦åˆ™å®ƒå°†è¿”回 [code]null[/code]。"
+"返回树中å‰ä¸€ä¸ªå¯è§çš„ TreeItem,如果没有,则返回 null 对象。\n"
+"如果 [code]wrap[/code] 被å¯ç”¨ï¼Œå½“在第一个å¯è§å…ƒç´ ä¸Šè°ƒç”¨æ—¶ï¼Œè¯¥æ–¹æ³•将环绕到树中"
+"最åŽä¸€ä¸ªå¯è§å…ƒç´ ï¼Œå¦åˆ™å®ƒå°†è¿”回 [code]null[/code]。"
#: doc/classes/TreeItem.xml
msgid "Returns the value of a [constant CELL_MODE_RANGE] column."
@@ -80317,8 +80865,7 @@ msgstr "返回 [constant CELL_MODE_RANGE] 列的值。"
msgid ""
"Returns a dictionary containing the range parameters for a given column. The "
"keys are \"min\", \"max\", \"step\", and \"expr\"."
-msgstr ""
-"返回包å«ç»™å®šåˆ—çš„èŒƒå›´å‚æ•°çš„字典。键是 \"min\"ã€\"max\"ã€\"step \"å’Œ \"expr\"。"
+msgstr "返回包å«ç»™å®šåˆ—çš„èŒƒå›´å‚æ•°çš„字典。键是“minâ€ã€â€œmaxâ€ã€â€œstepâ€å’Œâ€œexprâ€ã€‚"
#: doc/classes/TreeItem.xml
msgid "Gets the suffix string shown after the column value."
@@ -80341,7 +80888,7 @@ msgid ""
"Returns [code]true[/code] if the button at index [code]button_idx[/code] for "
"the given column is disabled."
msgstr ""
-"如果给定列的索引[code]button_idx[/code]处的按钮被ç¦ç”¨ï¼Œè¿”回 [code]true[/"
+"如果给定列的索引 [code]button_idx[/code] 处的按钮被ç¦ç”¨ï¼Œè¿”回 [code]true[/"
"code]。"
#: doc/classes/TreeItem.xml
@@ -80350,23 +80897,23 @@ msgstr "如果给定的列被选中,返回 [code]true[/code]。"
#: doc/classes/TreeItem.xml
msgid "Returns [code]true[/code] if column [code]column[/code] is editable."
-msgstr "如果列[code]column[/code]是å¯ç¼–辑的,则返回 [code]true[/code]。"
+msgstr "如果列 [code]column[/code] 是å¯ç¼–辑的,则返回 [code]true[/code]。"
#: doc/classes/TreeItem.xml
msgid "Returns [code]true[/code] if column [code]column[/code] is selectable."
-msgstr "如果列[code]column[/code]是å¯é€‰æ‹©çš„,则返回 [code]true[/code]。"
+msgstr "如果列 [code]column[/code] 是å¯é€‰æ‹©çš„,则返回 [code]true[/code]。"
#: doc/classes/TreeItem.xml
msgid "Returns [code]true[/code] if column [code]column[/code] is selected."
-msgstr "如果列[code]column[/code]被选中,返回 [code]true[/code]。"
+msgstr "如果列 [code]column[/code] 被选中,返回 [code]true[/code]。"
#: doc/classes/TreeItem.xml
msgid "Moves this TreeItem to the bottom in the [Tree] hierarchy."
-msgstr "将此TreeItem树项移动到[Tree]层次结构的底部。"
+msgstr "将这个 TreeItem 移动到 [Tree] 层次结构的底部。"
#: doc/classes/TreeItem.xml
msgid "Moves this TreeItem to the top in the [Tree] hierarchy."
-msgstr "将此TreeItem树项移动到[Tree]树层次结构的顶部。"
+msgstr "将这个 TreeItem 移动到 [Tree] 层次结构的顶部。"
#: doc/classes/TreeItem.xml
msgid ""
@@ -80374,27 +80921,28 @@ msgid ""
"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]."
msgstr ""
-"将给定的å­é¡¹[TreeItem]和它的所有å­é¡¹ä»Ž[Tree]中移除。注æ„,它并未从内存中释放"
-"该项,所以之åŽå¯é‡æ–°ä½¿ç”¨ã€‚è¦å®Œå…¨åˆ é™¤ä¸€ä¸ª[TreeItem],请使用[method Object."
-"free]。"
+"将给定的å­é¡¹ [TreeItem] 和它的所有å­é¡¹ä»Ž [Tree] 中移除。注æ„,它并未从内存中"
+"释放该项,所以之åŽå¯é‡æ–°ä½¿ç”¨ã€‚è¦å®Œå…¨åˆ é™¤ä¸€ä¸ª [TreeItem],请使用 [method "
+"Object.free]。"
#: doc/classes/TreeItem.xml
msgid "Selects the column [code]column[/code]."
-msgstr "选择列[code]column[/code]。"
+msgstr "选择列 [code]column[/code]。"
#: doc/classes/TreeItem.xml
msgid ""
"Sets the given column's button [Texture] at index [code]button_idx[/code] to "
"[code]button[/code]."
msgstr ""
-"设置索引[code]button_idx[/code]的给定列的按钮[code]button[/code]的[Texture]。"
+"设置索引 [code]button_idx[/code] 的给定列的按钮 [code]button[/code] 的 "
+"[Texture]。"
#: doc/classes/TreeItem.xml
msgid ""
"If [code]true[/code], disables the button at index [code]button_idx[/code] "
"in column [code]column[/code]."
msgstr ""
-"如果[code]true[/code],则ç¦ç”¨åˆ—[code]column[/code]中索引[code]button_idx[/"
+"如果为 [code]true[/code],则ç¦ç”¨åˆ—[code]column[/code]中索引[code]button_idx[/"
"code]的按钮。"
#: doc/classes/TreeItem.xml
@@ -80402,11 +80950,11 @@ msgid ""
"Sets the given column's cell mode to [code]mode[/code]. See [enum "
"TreeCellMode] constants."
msgstr ""
-"设置给定列的å•元格模å¼ä¸º[code]mode[/code]。å‚阅[enum TreeCellMode]常é‡ã€‚"
+"设置给定列的å•元格模å¼ä¸º [code]mode[/code]ã€‚è§ [enum TreeCellMode] 常é‡ã€‚"
#: doc/classes/TreeItem.xml
msgid "If [code]true[/code], the column [code]column[/code] is checked."
-msgstr "如果[code]true[/code],则选中[code]column[/code]。"
+msgstr "如果为 [code]true[/code],则选中 [code]column[/code]。"
#: doc/classes/TreeItem.xml
msgid ""
@@ -80425,10 +80973,10 @@ msgid ""
"The [code]callback[/code] should accept two arguments: the [TreeItem] that "
"is drawn and its position and size as a [Rect2]."
msgstr ""
-"设置给定列的自定义绘制回调到[code]object[/code]上的[code]callback[/code]回调"
-"方法。\n"
-"[code]callback[/code]应该接å—ä¸¤ä¸ªå‚æ•°ï¼šè¢«ç»˜åˆ¶çš„[TreeItem]树项以åŠå®ƒçš„ä½ç½®å’Œå¤§"
-"å°æ˜¯ä¸€ä¸ª[Rect2]。"
+"设置给定列的自定义绘制回调到 [code]object[/code] 上的 [code]callback[/code] "
+"回调方法。\n"
+"[code]callback[/code] 应该接å—ä¸¤ä¸ªå‚æ•°ï¼šè¢«ç»˜åˆ¶çš„ [TreeItem] 以åŠå®ƒçš„ä½ç½®å’Œå¤§"
+"å°æ˜¯ä¸€ä¸ª [Rect2]。"
#: doc/classes/TreeItem.xml
msgid "If [code]true[/code], column [code]column[/code] is editable."
@@ -80449,7 +80997,7 @@ msgstr "设置给定列图标的最大宽度。"
#: doc/classes/TreeItem.xml
msgid "Modulates the given column's icon with [code]modulate[/code]."
-msgstr "用[code]modulate[/code]调制给定列的图标。"
+msgstr "用 [code]modulate[/code] 调制给定列的图标。"
#: doc/classes/TreeItem.xml
msgid "Sets the given column's icon's texture region."
@@ -80476,18 +81024,18 @@ msgid ""
"exponential scale as with [member Range.exp_edit]."
msgstr ""
"è®¾ç½®åˆ—çš„å¯æŽ¥å—值的范围。该列必须处于 [constant CELL_MODE_RANGE] 模å¼ã€‚\n"
-"如果 [code]expr[/code] 是 [code]true[/code]ï¼Œç¼–è¾‘æ¨¡å¼æ»‘å—将使用指数刻度,与 "
+"如果 [code]expr[/code] 为 [code]true[/code]ï¼Œç¼–è¾‘æ¨¡å¼æ»‘å—将使用指数刻度,与 "
"[member Range.exp_edit] 一样。"
#: doc/classes/TreeItem.xml
msgid "If [code]true[/code], the given column is selectable."
-msgstr "如果[code]true[/code],给定的列是å¯é€‰æ‹©çš„。"
+msgstr "如果为 [code]true[/code],给定的列是å¯é€‰ä¸­çš„。"
#: doc/classes/TreeItem.xml
msgid ""
"Sets a string to be shown after a column's value (for example, a unit "
"abbreviation)."
-msgstr "设置字符串,显示在列的值之åŽï¼Œä¾‹å¦‚,å•ä½çš„缩写。"
+msgstr "设置字符串,显示在列的值之åŽï¼ˆä¾‹å¦‚,å•ä½çš„缩写)。"
#: doc/classes/TreeItem.xml
msgid "Sets the given column's text value."
@@ -80497,7 +81045,7 @@ msgstr "设置给定列的文本值。"
msgid ""
"Sets the given column's text alignment. See [enum TextAlign] for possible "
"values."
-msgstr "è®¾ç½®ç»™å®šåˆ—çš„æ–‡æœ¬å¯¹é½æ–¹å¼ã€‚å¯èƒ½çš„值,å‚阅[enum TextAlign]。"
+msgstr "è®¾ç½®ç»™å®šåˆ—çš„æ–‡æœ¬å¯¹é½æ–¹å¼ã€‚å¯èƒ½çš„å–å€¼è§ [enum TextAlign]。"
#: doc/classes/TreeItem.xml
msgid "Sets the given column's tooltip text."
@@ -80505,7 +81053,7 @@ msgstr "设置给定列的工具æç¤ºæ–‡æœ¬ã€‚"
#: doc/classes/TreeItem.xml
msgid "If [code]true[/code], the TreeItem is collapsed."
-msgstr "如果[code]true[/code],TreeItem树项被折å ã€‚"
+msgstr "如果为 [code]true[/code],则该 TreeItem 被折å ã€‚"
#: doc/classes/TreeItem.xml
msgid "The custom minimum height."
@@ -80513,7 +81061,7 @@ msgstr "自定义最å°é«˜åº¦ã€‚"
#: doc/classes/TreeItem.xml
msgid "If [code]true[/code], folding is disabled for this TreeItem."
-msgstr "如果[code]true[/code],则TreeItem树项ç¦ç”¨æŠ˜å ã€‚"
+msgstr "如果为 [code]true[/code],则这个 TreeItem ç¦ç”¨æŠ˜å ã€‚"
#: doc/classes/TreeItem.xml
msgid "Cell contains a string."
@@ -80533,15 +81081,15 @@ msgstr "å•元包å«å›¾æ ‡ã€‚"
#: doc/classes/TreeItem.xml
msgid "Align text to the left. See [code]set_text_align()[/code]."
-msgstr "将文本å‘左对é½ã€‚å‚阅[code]set_text_align()[/code]。"
+msgstr "将文本å‘左对é½ã€‚è§ [code]set_text_align()[/code]。"
#: doc/classes/TreeItem.xml
msgid "Center text. See [code]set_text_align()[/code]."
-msgstr "将文本居中。å‚阅[code]set_text_align()[/code]。"
+msgstr "å°†æ–‡æœ¬å±…ä¸­ã€‚è§ [code]set_text_align()[/code]。"
#: doc/classes/TreeItem.xml
msgid "Align text to the right. See [code]set_text_align()[/code]."
-msgstr "将文本å‘å³å¯¹é½ã€‚å‚阅[code]set_text_align()[/code]。"
+msgstr "将文本å‘å³å¯¹é½ã€‚è§ [code]set_text_align()[/code]。"
#: doc/classes/TriangleMesh.xml
msgid "Internal mesh type."
@@ -80851,7 +81399,7 @@ msgstr "è¿”å›žè¡¥é—´çš„å½“å‰æ—¶é—´ã€‚"
#: doc/classes/Tween.xml
msgid "The tween's animation process thread. See [enum TweenProcessMode]."
-msgstr "补间动画处ç†çº¿ç¨‹ã€‚å‚阅[enum TweenProcessMode]。"
+msgstr "补间动画处ç†çº¿ç¨‹ã€‚è§ [enum TweenProcessMode]。"
#: doc/classes/Tween.xml
msgid ""
@@ -80866,7 +81414,7 @@ msgstr ""
#: doc/classes/Tween.xml
msgid "If [code]true[/code], the tween loops."
-msgstr "如果[code]true[/code],补间循环。"
+msgstr "如果为 [code]true[/code],则补间循环。"
#: doc/classes/Tween.xml
msgid "Emitted when all processes in a tween end."
@@ -80890,7 +81438,7 @@ msgstr "补间通过 [code]_physics_process[/code] 回调进行更新。"
#: doc/classes/Tween.xml
msgid "The tween updates with the [code]_process[/code] callback."
-msgstr "补间通过[code]_process[/code]回调进行更新。"
+msgstr "补间通过 [code]_process[/code] 回调进行更新。"
#: doc/classes/Tween.xml
msgid "The animation is interpolated linearly."
@@ -80903,23 +81451,23 @@ msgstr "动画使用正弦函数进行æ’值。"
#: doc/classes/Tween.xml
msgid ""
"The animation is interpolated with a quintic (to the power of 5) function."
-msgstr "动画是用五次方,å³5的幂函数进行æ’值的。"
+msgstr "åŠ¨ç”»æ˜¯ç”¨äº”æ¬¡æ–¹ï¼Œå³ 5 的幂函数进行æ’值的。"
#: doc/classes/Tween.xml
msgid ""
"The animation is interpolated with a quartic (to the power of 4) function."
-msgstr "动画是用一个四次方,å³4的幂函数æ’值的。"
+msgstr "åŠ¨ç”»æ˜¯ç”¨ä¸€ä¸ªå››æ¬¡æ–¹ï¼Œå³ 4 的幂函数æ’值的。"
#: doc/classes/Tween.xml
msgid ""
"The animation is interpolated with a quadratic (to the power of 2) function."
-msgstr "动画是用二次方,å³2的幂函数æ’值的。"
+msgstr "åŠ¨ç”»æ˜¯ç”¨äºŒæ¬¡æ–¹ï¼Œå³ 2 的幂函数æ’值的。"
#: doc/classes/Tween.xml
msgid ""
"The animation is interpolated with an exponential (to the power of x) "
"function."
-msgstr "动画是用一个指数,å³x的幂函数æ’值的。"
+msgstr "åŠ¨ç”»æ˜¯ç”¨ä¸€ä¸ªæŒ‡æ•°ï¼Œå³ x 的幂函数æ’值的。"
#: doc/classes/Tween.xml
msgid ""
@@ -80929,7 +81477,7 @@ msgstr "动画弹性æ’值,在边缘摆动。"
#: doc/classes/Tween.xml
msgid ""
"The animation is interpolated with a cubic (to the power of 3) function."
-msgstr "动画是用一个立方,å³3的幂函数æ’值的。"
+msgstr "åŠ¨ç”»æ˜¯ç”¨ä¸€ä¸ªç«‹æ–¹ï¼Œå³ 3 的幂函数æ’值的。"
#: doc/classes/Tween.xml
msgid "The animation is interpolated with a function using square roots."
@@ -80961,7 +81509,7 @@ msgstr "[constant EASE_IN] å’Œ [constant EASE_OUT] 的组åˆã€‚两端的æ’值æœ
msgid ""
"A combination of [constant EASE_IN] and [constant EASE_OUT]. The "
"interpolation is fastest at both ends."
-msgstr "[constant EASE_IN] and [constant EASE_OUT]的组åˆã€‚两端的æ’值最快。"
+msgstr "[constant EASE_IN] å’Œ [constant EASE_OUT] 的组åˆã€‚两端的æ’值最快。"
#: doc/classes/Tweener.xml
msgid "Abstract class for all Tweeners used by [SceneTreeTween]."
@@ -81041,8 +81589,8 @@ msgid ""
" connected = true\n"
"[/codeblock]"
msgstr ""
-"一个简å•çš„æœåŠ¡å™¨ï¼Œå®ƒæ‰“å¼€ä¸€ä¸ª UDP 套接字,并在收到新的数æ®åŒ…时,返回连接的 "
-"[PacketPeerUDP]。请å‚阅 [method PacketPeerUDP.connect_to_host]。\n"
+"简å•çš„æœåŠ¡å™¨ï¼Œå®ƒæ‰“å¼€ä¸€ä¸ª UDP 套接字,并在收到新的数æ®åŒ…时,返回连接的 "
+"[PacketPeerUDP]。å¦è¯·å‚阅 [method PacketPeerUDP.connect_to_host]。\n"
"å¯åЍæœåС噍åŽï¼ˆ[method listen]),你将需è¦å®šæœŸ [method poll] 它(例如在 "
"[method Node._process] 内),æ‰ä¼šå¤„ç†æ–°çš„æ•°æ®åŒ…ã€å°†å®ƒä»¬ä¼ é€’给适当的 "
"[PacketPeerUDP]ã€æŽ¥å—æ–°è¿žæŽ¥ã€‚\n"
@@ -81147,8 +81695,8 @@ msgid ""
"also [method is_connection_available], [method PacketPeerUDP."
"connect_to_host]."
msgstr ""
-"返回第一个挂起的连接,注,连接到适当的地å€åŠç«¯å£ã€‚如果没有新的连接å¯ç”¨ï¼Œå°†è¿”"
-"回 [code]null[/code]。å‚阅[method is_connection_available], [method "
+"返回第一个挂起的连接(连接到适当的地å€åŠç«¯å£ï¼‰ã€‚如果没有新的连接å¯ç”¨ï¼Œå°†è¿”回 "
+"[code]null[/code]。å¦è¯·å‚阅 [method is_connection_available]ã€[method "
"PacketPeerUDP.connect_to_host]。"
#: doc/classes/UDPServer.xml
@@ -81204,9 +81752,9 @@ msgstr ""
"åœ¨ç¼–è¾‘å™¨æˆ–è‡ªå®šä¹‰å·¥å…·ä¸­ç®¡ç†æ’¤é”€åŠé‡åšæ“ä½œçš„è¾…åŠ©å·¥å…·ã€‚å®ƒçš„å·¥ä½œåŽŸç†æ˜¯"
"在“actionâ€ï¼ˆåŠ¨ä½œï¼‰ä¸­æ³¨å†Œæ–¹æ³•å’Œå±žæ€§çš„å˜åŒ–。\n"
"常è§çš„è¡Œä¸ºæ˜¯é¦–å…ˆåˆ›å»ºä¸€ä¸ªåŠ¨ä½œï¼Œç„¶åŽæ·»åŠ ç”¨äºŽ do/undo(执行/撤销)的方法调用或属"
-"æ€§æ›´æ”¹ï¼Œç„¶åŽæäº¤åŠ¨ä½œã€‚ \n"
+"æ€§æ›´æ”¹ï¼Œç„¶åŽæäº¤åŠ¨ä½œã€‚\n"
"䏋颿˜¯ä¸€ä¸ªæ’件中例å­ï¼Œå±•示如何在 Godot 编辑器自己的 [UndoRedo] 中添加一个动"
-"作。 \n"
+"作。\n"
"[codeblock]\n"
"var undo_redo = get_undo_redo() # EditorPlugin 的方法。\n"
"\n"
@@ -81506,10 +82054,10 @@ msgid ""
"[code]TCP[/code] or [code]UDP[/code]. See [enum UPNPResult] for possible "
"return values."
msgstr ""
-"删除默认网关上给定端å£å’Œå议组åˆçš„ç«¯å£æ˜ å°„,如果存在的è¯ã€‚[code]port[/code]å¿…"
-"须是1到65535之间的有效端å£ï¼Œ[code]proto[/code]å¯ä»¥æ˜¯[code]TCP[/code]或"
-"[code]UDP[/code]。å¯èƒ½çš„返回值,å‚阅[enum UPNPResult]。å‚阅[method "
-"get_gateway]。"
+"如果默认网关上存在给定的端å£å’Œå议组åˆçš„ç«¯å£æ˜ å°„ï¼ˆè§ [method get_gateway]),"
+"则将其删除。[code]port[/code] 必须是 1 到 65535 之间的有效端å£ï¼Œ[code]proto[/"
+"code] å¯ä»¥æ˜¯ [code]TCP[/code] 或 [code]UDP[/code]。å¯èƒ½çš„è¿”å›žå€¼è§ [enum "
+"UPNPResult]。"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
@@ -81529,11 +82077,11 @@ msgstr ""
#: modules/upnp/doc_classes/UPNP.xml
msgid "Returns the [UPNPDevice] at the given [code]index[/code]."
-msgstr "返回给定[code]index[/code]处的[UPNPDevice]。"
+msgstr "返回给定 [code]index[/code] 处的 [UPNPDevice]。"
#: modules/upnp/doc_classes/UPNP.xml
msgid "Returns the number of discovered [UPNPDevice]s."
-msgstr "返回已å‘现的[UPNPDevice]的数é‡ã€‚"
+msgstr "返回已å‘现的 [UPNPDevice] 的数é‡ã€‚"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
@@ -81548,24 +82096,25 @@ msgid ""
"Returns the external [IP] address of the default gateway (see [method "
"get_gateway]) as string. Returns an empty string on error."
msgstr ""
-"返回默认网关的外部[IP]地å€å­—符串。错误时返回一个空字符串。å‚阅[method "
-"get_gateway]。"
+"返回默认网关的外部 [IP] 地å€å­—ç¬¦ä¸²ï¼ˆè§ [method get_gateway])。错误时返回空字"
+"符串。"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
"Removes the device at [code]index[/code] from the list of discovered devices."
-msgstr "å°†[code]index[/code]处的设备从已å‘现的设备列表中移除。"
+msgstr "å°† [code]index[/code] 处的设备从已å‘现的设备列表中移除。"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
"Sets the device at [code]index[/code] from the list of discovered devices to "
"[code]device[/code]."
msgstr ""
-"å°†[code]index[/code]处的设备从已å‘现的设备列表中设置为[code]device[/code]。"
+"å°† [code]index[/code] 处的设备从已å‘现的设备列表中设置为 [code]device[/"
+"code]。"
#: modules/upnp/doc_classes/UPNP.xml
msgid "If [code]true[/code], IPv6 is used for [UPNPDevice] discovery."
-msgstr "如果[code]true[/code],则IPv6用于[UPNPDevice]å‘现。"
+msgstr "如果为 [code]true[/code],则 IPv6 用于 [UPNPDevice] å‘现。"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
@@ -81574,8 +82123,8 @@ msgid ""
"the source port 1900 (same as destination port). Otherwise, the value will "
"be used as the port."
msgstr ""
-"如果[code]0[/code],系统会自动选择用于å‘现的本地端å£ã€‚如果[code]1[/code],将"
-"从æºç«¯å£1900进行å‘现,注,与目的端å£ç›¸åŒã€‚å¦åˆ™ï¼Œå°†ä½¿ç”¨è¯¥å€¼ä½œä¸ºç«¯å£ã€‚"
+"如果为 [code]0[/code],系统会自动选择用于å‘现的本地端å£ã€‚如果为 [code]1[/"
+"code],将从æºç«¯å£ 1900 进行å‘现(与目的端å£ç›¸åŒï¼‰ã€‚å¦åˆ™ï¼Œå°†ä½¿ç”¨è¯¥å€¼ä½œä¸ºç«¯å£ã€‚"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
@@ -81585,21 +82134,21 @@ msgstr "用于å‘现的多播接å£ã€‚如果为空,则使用默认的多播接
#: modules/upnp/doc_classes/UPNP.xml
msgid "UPNP command or discovery was successful."
-msgstr "UPNP命令或å‘现æˆåŠŸã€‚"
+msgstr "UPNP 命令或å‘现æˆåŠŸã€‚"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
"Not authorized to use the command on the [UPNPDevice]. May be returned when "
"the user disabled UPNP on their router."
msgstr ""
-"未授æƒåœ¨[UPNPDevice]上使用该命令。当用户在其路由器上ç¦ç”¨UPNP时,å¯èƒ½ä¼šè¢«è¿”"
-"回。"
+"未授æƒåœ¨ [UPNPDevice] 上使用该命令。当用户在其路由器上ç¦ç”¨ UPNP 时,å¯èƒ½ä¼šè¢«"
+"返回。"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
"No port mapping was found for the given port, protocol combination on the "
"given [UPNPDevice]."
-msgstr "在给定的[UPNPDevice]上没有找到给定端å£ã€å议组åˆçš„ç«¯å£æ˜ å°„。"
+msgstr "在给定的 [UPNPDevice] 上没有找到给定端å£ã€å议组åˆçš„ç«¯å£æ˜ å°„。"
#: modules/upnp/doc_classes/UPNP.xml
msgid "Inconsistent parameters."
@@ -81610,8 +82159,8 @@ msgid ""
"No such entry in array. May be returned if a given port, protocol "
"combination is not found on an [UPNPDevice]."
msgstr ""
-"数组中没有此æ¡ç›®ã€‚如果在[UPNPDevice]上没有找到给定的端å£ã€å议组åˆï¼Œå¯èƒ½ä¼šè¢«"
-"返回。"
+"数组中没有此æ¡ç›®ã€‚如果在 [UPNPDevice] 上没有找到给定的端å£ã€å议组åˆï¼Œå¯èƒ½ä¼š"
+"被返回。"
#: modules/upnp/doc_classes/UPNP.xml
msgid "The action failed."
@@ -81620,15 +82169,15 @@ msgstr "æ“作失败。"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
"The [UPNPDevice] does not allow wildcard values for the source IP address."
-msgstr "[UPNPDevice]ä¸å…许æºIP地å€çš„通é…符值。"
+msgstr "[UPNPDevice] ä¸å…è®¸æº IP 地å€çš„通é…符值。"
#: modules/upnp/doc_classes/UPNP.xml
msgid "The [UPNPDevice] does not allow wildcard values for the external port."
-msgstr "[UPNPDevice]ä¸å…许外部端å£çš„通é…符值。"
+msgstr "[UPNPDevice] ä¸å…许外部端å£çš„通é…符值。"
#: modules/upnp/doc_classes/UPNP.xml
msgid "The [UPNPDevice] does not allow wildcard values for the internal port."
-msgstr "[UPNPDevice]ä¸å…许内部端å£çš„通é…符值。"
+msgstr "[UPNPDevice] ä¸å…许内部端å£çš„通é…符值。"
#: modules/upnp/doc_classes/UPNP.xml
msgid "The remote host value must be a wildcard."
@@ -81665,7 +82214,8 @@ msgstr "外部和内部端å£å€¼å¿…须相åŒã€‚"
msgid ""
"Only permanent leases are supported. Do not use the [code]duration[/code] "
"parameter when adding port mappings."
-msgstr "åªæ”¯æŒæ°¸ä¹…ç§Ÿç”¨ã€‚åœ¨æ·»åŠ ç«¯å£æ˜ å°„时,ä¸è¦ä½¿ç”¨[code]duration[/code]傿•°ã€‚"
+msgstr ""
+"åªæ”¯æŒæ°¸ä¹…ç§Ÿç”¨ã€‚åœ¨æ·»åŠ ç«¯å£æ˜ å°„时,ä¸è¦ä½¿ç”¨ [code]duration[/code] 傿•°ã€‚"
#: modules/upnp/doc_classes/UPNP.xml
msgid "Invalid gateway."
@@ -81697,7 +82247,7 @@ msgstr "æ— æ•ˆå‚æ•°ã€‚"
#: modules/upnp/doc_classes/UPNP.xml modules/upnp/doc_classes/UPNPDevice.xml
msgid "HTTP error."
-msgstr "HTTP错误。"
+msgstr "HTTP 错误。"
#: modules/upnp/doc_classes/UPNP.xml
msgid "Socket error."
@@ -81712,16 +82262,16 @@ msgid ""
"No gateway available. You may need to call [method discover] first, or "
"discovery didn't detect any valid IGDs (InternetGatewayDevices)."
msgstr ""
-"没有å¯ç”¨çš„网关。你å¯èƒ½éœ€è¦å…ˆè°ƒç”¨[method discover] ,å¦åˆ™å‘现没有检测到任何有"
-"效的IGD(InternetGatewayDevices)。"
+"没有å¯ç”¨çš„网关。你å¯èƒ½éœ€è¦å…ˆè°ƒç”¨ [method discover] ,å¦åˆ™å‘现没有检测到任何有"
+"效的 IGD(InternetGatewayDevices)。"
#: modules/upnp/doc_classes/UPNP.xml
msgid ""
"No devices available. You may need to call [method discover] first, or "
"discovery didn't detect any valid [UPNPDevice]s."
msgstr ""
-"没有å¯ç”¨çš„设备。你å¯èƒ½éœ€è¦å…ˆè°ƒç”¨[method discover],或者å‘现没有检测到任何有效"
-"的[UPNPDevice]。"
+"没有å¯ç”¨çš„设备。你å¯èƒ½éœ€è¦å…ˆè°ƒç”¨ [method discover],或者å‘现没有检测到任何有"
+"效的 [UPNPDevice]。"
#: modules/upnp/doc_classes/UPNP.xml modules/upnp/doc_classes/UPNPDevice.xml
msgid "Unknown error."
@@ -81739,9 +82289,9 @@ msgid ""
"and external IP address and status). Note that methods on this class are "
"synchronous and block the calling thread."
msgstr ""
-"UPNP设备。å‚阅 [UPNP] 了解UPNPå‘现和实用功能。æä¾›å¯¹UPNP控制命令的低层访问。"
-"å…许管ç†ç«¯å£æ˜ å°„(端å£è½¬å‘)和查询设备的网络信æ¯ï¼Œå¦‚本地和外部IP地å€å’Œçжæ€ã€‚"
-"请注æ„ï¼Œè¿™ä¸ªç±»çš„æ–¹æ³•æ˜¯åŒæ­¥çš„,会阻塞调用线程。"
+"UPNP 设备。å‚阅 [UPNP] 了解 UPNP å‘现和实用功能。æä¾›å¯¹ UPNP 控制命令的低层访"
+"问。å…许管ç†ç«¯å£æ˜ å°„(端å£è½¬å‘)和查询设备的网络信æ¯ï¼Œå¦‚本地和外部IP地å€å’Œçж"
+"æ€ã€‚请注æ„ï¼Œè¿™ä¸ªç±»çš„æ–¹æ³•æ˜¯åŒæ­¥çš„,会阻塞调用线程。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid ""
@@ -81749,15 +82299,15 @@ msgid ""
"for the given protocol to the local machine. See [method UPNP."
"add_port_mapping]."
msgstr ""
-"æ·»åŠ ä¸€ä¸ªç«¯å£æ˜ å°„,将这个[UPNPDevice]上给定的外部端å£è½¬å‘到本地机器上,以给定"
-"çš„å议。å‚阅 [method UPNP.add_port_mapping]。"
+"æ·»åŠ ä¸€ä¸ªç«¯å£æ˜ å°„,将这个 [UPNPDevice] 上给定的外部端å£è½¬å‘到本地机器上,以给"
+"定的åè®®ã€‚è§ [method UPNP.add_port_mapping]。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid ""
"Deletes the port mapping identified by the given port and protocol "
"combination on this device. See [method UPNP.delete_port_mapping]."
msgstr ""
-"删除该设备上由给定的端å£å’Œå议组åˆç¡®å®šçš„ç«¯å£æ˜ å°„。å‚阅[method UPNP."
+"删除该设备上由给定的端å£å’Œå议组åˆç¡®å®šçš„ç«¯å£æ˜ å°„ã€‚è§ [method UPNP."
"delete_port_mapping]。"
#: modules/upnp/doc_classes/UPNPDevice.xml
@@ -81765,35 +82315,35 @@ msgid ""
"Returns [code]true[/code] if this is a valid IGD (InternetGatewayDevice) "
"which potentially supports port forwarding."
msgstr ""
-"如果这是一个有效的IGD(InternetGatewayDevice),å¯èƒ½æ”¯æŒç«¯å£è½¬å‘,则返回 "
+"如果这是一个有效的 IGD(InternetGatewayDevice),å¯èƒ½æ”¯æŒç«¯å£è½¬å‘,则返回 "
"[code]true[/code]。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid ""
"Returns the external IP address of this [UPNPDevice] or an empty string."
-msgstr "返回这个[UPNPDevice]的外部IPåœ°å€æˆ–空字符串。"
+msgstr "返回这个 [UPNPDevice] 的外部 IP åœ°å€æˆ–空字符串。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid "URL to the device description."
-msgstr "设备æè¿°çš„URL。"
+msgstr "设备æè¿°çš„ URL。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid "IDG control URL."
-msgstr "IDG控件URL。"
+msgstr "IDG 控件 URL。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid ""
"Address of the local machine in the network connecting it to this "
"[UPNPDevice]."
-msgstr "将其连接到该[UPNPDevice]的网络中的本地机器的地å€ã€‚"
+msgstr "将其连接到该 [UPNPDevice] 的网络中的本地机器的地å€ã€‚"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid "IGD service type."
-msgstr "IGDæœåŠ¡ç±»åž‹ã€‚"
+msgstr "IGD æœåŠ¡ç±»åž‹ã€‚"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid "IGD status. See [enum IGDStatus]."
-msgstr "IGD状æ€ã€‚å‚阅[enum IGDStatus]。"
+msgstr "IGD 状æ€ã€‚è§ [enum IGDStatus]。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid "Service type."
@@ -81805,11 +82355,11 @@ msgstr "OK。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid "Empty HTTP response."
-msgstr "空的HTTPå“应。"
+msgstr "空的 HTTP å“应。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid "Returned response contained no URLs."
-msgstr "返回的å“应ä¸åŒ…å«ä»»ä½•URL。"
+msgstr "返回的å“应ä¸åŒ…å«ä»»ä½• URL。"
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid "Not a valid IGD."
@@ -81995,11 +82545,11 @@ msgstr "垂直盒å¼å®¹å™¨ã€‚请å‚阅 [BoxContainer]。"
#: doc/classes/VBoxContainer.xml
msgid "The vertical space between the [VBoxContainer]'s elements."
-msgstr "[VBoxContainer]的元素之间的垂直空间。"
+msgstr "[VBoxContainer] 的元素之间的垂直空间。"
#: doc/classes/Vector2.xml
msgid "Vector used for 2D math."
-msgstr "用于二维数学的å‘é‡ã€‚"
+msgstr "用于 2D 数学的å‘é‡ã€‚"
#: doc/classes/Vector2.xml
msgid ""
@@ -82040,14 +82590,15 @@ msgid ""
"Equivalent to the result of [method @GDScript.atan2] when called with the "
"vector's [member y] and [member x] as parameters: [code]atan2(y, x)[/code]."
msgstr ""
-"返回这个å‘é‡ç›¸å¯¹äºŽæ­£X轴的角度,或[code](1, 0)[/code]å‘é‡ï¼Œå•ä½ä¸ºå¼§åº¦ã€‚\n"
-"例如,[code]Vector2.RIGHT.angle()[/code]将返回0,[code]Vector2.DOWN.angle()[/"
-"code]将返回 [code]PI / 2[/code](四分之一转,或90度),[code]Vector2(1, -1)."
-"angle()[/code]将返回 [code]-PI / 4[/code] (负八分之一转,或-45度)。\n"
+"返回这个å‘é‡ç›¸å¯¹äºŽæ­£ X 轴的角度,或 [code](1, 0)[/code] å‘é‡ï¼Œå•ä½ä¸ºå¼§åº¦ã€‚\n"
+"例如,[code]Vector2.RIGHT.angle()[/code] 将返回 0,[code]Vector2.DOWN.angle()"
+"[/code] 将返回 [code]PI / 2[/code](四分之一转,或 90 度),[code]Vector2(1, "
+"-1).angle()[/code] 将返回 [code]-PI / 4[/code] (负八分之一转,或 -45 "
+"度)。\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
"vector2_angle.png]返回角度的说明。[/url]\n"
-"相当于以å‘é‡çš„[member y] å’Œ [member x]ä¸ºå‚æ•°è°ƒç”¨[method @GDScript.atan2]æ—¶çš„"
-"结果。[code]atan2(y, x)[/code]。"
+"相当于以å‘é‡çš„ [member y] å’Œ [member x] ä¸ºå‚æ•°è°ƒç”¨ [method @GDScript.atan2] "
+"时的结果。[code]atan2(y, x)[/code]。"
#: doc/classes/Vector2.xml
msgid ""
@@ -82074,7 +82625,7 @@ msgstr ""
msgid ""
"Returns the aspect ratio of this vector, the ratio of [member x] to [member "
"y]."
-msgstr "返回这个å‘é‡çš„长宽比,å³[member x] 与[member y]的比例。"
+msgstr "返回这个å‘é‡çš„é•¿å®½æ¯”ï¼Œå³ [member x] 与 [member y] 的比例。"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
@@ -82123,14 +82674,14 @@ msgid ""
msgstr ""
"用[code]pre_a[/code]å’Œ[code]post_b[/code]ä½œä¸ºå¥æŸ„,在这个å‘é‡å’Œ[code]b[/code]"
"之间进行三次æ’值,并在[code]weight[/code]ä½ç½®è¿”回结果。[code]weight[/code]çš„"
-"范围是0.0到1.0,表示æ’值的é‡ã€‚"
+"范围是0.0 到 1.0,表示æ’值的é‡ã€‚"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
"Returns the normalized vector pointing from this vector to [code]b[/code]. "
"This is equivalent to using [code](b - a).normalized()[/code]."
msgstr ""
-"返回从这个å‘釿Œ‡å‘[code]b[/code]的归一化å‘é‡ã€‚这相当于使用[code](b-a)."
+"返回从这个å‘釿Œ‡å‘ [code]b[/code] 的归一化å‘é‡ã€‚相当于使用 [code](b-a)."
"normalized()[/code]。"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
@@ -82139,9 +82690,9 @@ msgid ""
"This method runs faster than [method distance_to], so prefer it if you need "
"to compare vectors or need the squared distance for some formula."
msgstr ""
-"返回这个å‘é‡ä¸Ž[code]b[/code]之间的平方è·ç¦»ã€‚\n"
-"这个方法比[method distance_to]è¿è¡Œå¾—æ›´å¿«ï¼Œæ‰€ä»¥å¦‚æžœä½ éœ€è¦æ¯”较å‘釿ˆ–需è¦ä¸€äº›å…¬"
-"å¼çš„平方è·ç¦»ï¼Œåˆ™æ›´å–œæ¬¢å®ƒã€‚"
+"返回这个å‘é‡ä¸Ž [code]b[/code] 之间的平方è·ç¦»ã€‚\n"
+"这个方法比 [method distance_to] è¿è¡Œå¾—æ›´å¿«ï¼Œæ‰€ä»¥å¦‚æžœä½ éœ€è¦æ¯”较å‘釿ˆ–需è¦ä¸€äº›"
+"å…¬å¼çš„平方è·ç¦»ï¼Œåˆ™æ›´å–œæ¬¢å®ƒã€‚"
#: doc/classes/Vector2.xml
msgid "Returns the distance between this vector and [code]to[/code]."
@@ -82161,13 +82712,13 @@ msgid ""
"aligned.\n"
"[b]Note:[/b] [code]a.dot(b)[/code] is equivalent to [code]b.dot(a)[/code]."
msgstr ""
-"返回此å‘é‡ä¸Ž[code]with[/code]的点积。这å¯ä»¥ç”¨æ¥æ¯”较两个å‘é‡ä¹‹é—´çš„角度。例如,"
-"è¿™å¯ä»¥ç”¨æ¥ç¡®å®šä¸€ä¸ªæ•Œäººæ˜¯å¦æ­£æœå‘玩家。\n"
-"对于直角90度,点积将是[code]0[/code],对于窄于90度的角度,点积大于0,对于宽于"
-"90度的角度,点积å°äºŽ0。\n"
-"当使用归一化å•ä½å‘釿—¶ï¼Œå½“å‘釿œå‘ç›¸åæ–¹å‘时,结果总是在[code]-1.0[/code]"
-"(180度角)和[code]1.0[/code](0度角)之间,当å‘é‡å¯¹é½ã€‚\n"
-"[b]注æ„:[/b][code]a.dot(b)[/code]ç­‰åŒäºŽ[code]b.dot(a)[/code]。"
+"返回此å‘é‡ä¸Ž [code]with[/code] 的点积。这å¯ä»¥ç”¨æ¥æ¯”较两个å‘é‡ä¹‹é—´çš„角度。例"
+"如,这å¯ä»¥ç”¨æ¥ç¡®å®šä¸€ä¸ªæ•Œäººæ˜¯å¦æ­£æœå‘玩家。\n"
+"对于直角 90 度,点积将是 [code]0[/code],对于窄于 90 度的角度,点积大于 0,对"
+"于宽于 90 度的角度,点积å°äºŽ 0。\n"
+"当使用归一化å•ä½å‘釿—¶ï¼Œå½“å‘釿œå‘ç›¸åæ–¹å‘时,结果总是在 [code]-1.0[/code]"
+"(180 度角)和 [code]1.0[/code](0 度角)之间,当å‘é‡å¯¹é½ã€‚\n"
+"[b]注æ„:[/b][code]a.dot(b)[/code] 与 [code]b.dot(a)[/code] 等价。"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
@@ -82181,8 +82732,8 @@ msgid ""
"approximately equal, by running [method @GDScript.is_equal_approx] on each "
"component."
msgstr ""
-"通过对æ¯ä¸ªåˆ†é‡è¿è¡Œ[method @GDScript.is_equal_approx],如果这个å‘é‡å’Œ[code]v[/"
-"code]近似相等,返回 [code]true[/code]。"
+"通过对æ¯ä¸ªåˆ†é‡è¿è¡Œ [method @GDScript.is_equal_approx],如果这个å‘é‡å’Œ "
+"[code]v[/code] 近似相等,返回 [code]true[/code]。"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
@@ -82202,14 +82753,14 @@ msgid ""
"compare vectors or need the squared distance for some formula."
msgstr ""
"返回这个å‘é‡çš„平方长度,å³å¹³æ–¹å¤§å°ã€‚\n"
-"这个方法比[method length]è¿è¡Œå¾—æ›´å¿«ï¼Œæ‰€ä»¥å¦‚æžœä½ éœ€è¦æ¯”较å‘釿ˆ–需è¦ä¸€äº›å…¬å¼çš„å¹³"
-"æ–¹è·ç¦»æ—¶ï¼Œæ›´å–œæ¬¢ç”¨å®ƒã€‚"
+"这个方法比 [method length] è¿è¡Œå¾—æ›´å¿«ï¼Œæ‰€ä»¥å¦‚æžœä½ éœ€è¦æ¯”较å‘釿ˆ–需è¦ä¸€äº›å…¬å¼çš„"
+"平方è·ç¦»æ—¶ï¼Œæ›´å–œæ¬¢ç”¨å®ƒã€‚"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
"Returns the vector with a maximum length by limiting its length to "
"[code]length[/code]."
-msgstr "通过é™åˆ¶å…¶é•¿åº¦ä¸º[code]length[/code],返回具有最大长度的å‘é‡ã€‚"
+msgstr "通过é™åˆ¶å…¶é•¿åº¦ä¸º [code]length[/code],返回具有最大长度的å‘é‡ã€‚"
#: doc/classes/Vector2.xml
msgid ""
@@ -82217,8 +82768,8 @@ msgid ""
"[code]to[/code] by amount [code]weight[/code]. [code]weight[/code] is on the "
"range of 0.0 to 1.0, representing the amount of interpolation."
msgstr ""
-"返回这个å‘é‡ä¸Ž[code]to[/code]之间线性æ’值的结果,æ’值é‡ä¸º[code]weight[/"
-"code]。[code]weight[/code]的范围是0.0到1.0,表示æ’值的数é‡ã€‚"
+"返回这个å‘é‡ä¸Ž [code]to[/code] 之间线性æ’值的结果,æ’值é‡ä¸º [code]weight[/"
+"code]。[code]weight[/code] 的范围是 0.0 到 1.0,表示æ’值的数é‡ã€‚"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
@@ -82232,15 +82783,15 @@ msgstr ""
msgid ""
"Returns the vector scaled to unit length. Equivalent to [code]v / v.length()"
"[/code]."
-msgstr "返回缩放为å•ä½é•¿åº¦çš„å‘é‡ã€‚相当于[code]v/v.length()[/code]。"
+msgstr "返回缩放为å•ä½é•¿åº¦çš„å‘é‡ã€‚相当于 [code]v/v.length()[/code]。"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
"Returns a vector composed of the [method @GDScript.fposmod] of this vector's "
"components and [code]mod[/code]."
msgstr ""
-"返回一个由这个å‘é‡åˆ†é‡çš„[method @GDScript.fposmod]å’Œ[code]mod[/code]组æˆçš„å‘"
-"é‡ã€‚"
+"返回一个由这个å‘é‡åˆ†é‡çš„ [method @GDScript.fposmod] å’Œ [code]mod[/code] 组æˆ"
+"çš„å‘é‡ã€‚"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
@@ -82294,7 +82845,7 @@ msgid ""
"[b]Note:[/b] Both vectors must be normalized."
msgstr ""
"返回这个å‘é‡ä¸Ž[code]to[/code]之间的çƒé¢çº¿æ€§æ’值的结果,按[code]weight[/code]"
-"的数é‡ã€‚[code]weight[/code]的范围是0.0到1.0,表示æ’值的数é‡ã€‚\n"
+"的数é‡ã€‚[code]weight[/code]的范围是0.0 到 1.0,表示æ’值的数é‡ã€‚\n"
"[b]注æ„:[/b]两个å‘é‡éƒ½å¿…须被归一化。"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
@@ -82380,7 +82931,7 @@ msgid ""
msgstr ""
"3 元素结构,å¯ç”¨äºŽè¡¨ç¤º 3D 空间中的ä½ç½®æˆ–任何其他数值三元组。\n"
"[b]注æ„:[/b]在布尔上下文中,如果 Vector3 等于 [code]Vector3(0, 0, 0)[/"
-"code],将评估为 [code]false[/code]。å¦åˆ™ï¼Œ Vector3 将始终评估为 [code]true[/"
+"code],将评估为 [code]false[/code]。å¦åˆ™ï¼ŒVector3 将始终评估为 [code]true[/"
"code]。"
#: doc/classes/Vector3.xml
@@ -82430,7 +82981,7 @@ msgstr ""
"于宽于 90 度的角度,点积å°äºŽ 0。\n"
"当使用归一化å•ä½å‘é‡ï¼Œå‘釿œå‘ç›¸åæ–¹å‘时,结果总是在 [code]-1.0[/code](180 "
"度角)和 [code]1.0[/code](0 度角)之间,当å‘é‡å¯¹é½ã€‚\n"
-"[b]注æ„:[/b][code]a.dot(b)[/code] ç­‰åŒäºŽ [code]b.dot(a)[/code]。"
+"[b]注æ„:[/b][code]a.dot(b)[/code] 与 [code]b.dot(a)[/code] 等价。"
#: doc/classes/Vector3.xml
msgid ""
@@ -82500,7 +83051,7 @@ msgid ""
"components set as the scale."
msgstr ""
"返回一个以该å‘é‡ä¸ºä¸»å¯¹è§’线的对角线矩阵。\n"
-"这相当于一个没有旋转或剪切的 Basis,这个å‘é‡çš„分é‡è¢«è®¾å®šä¸ºç¼©æ”¾ã€‚"
+"相当于一个没有旋转或剪切的 Basis,这个å‘é‡çš„分é‡è¢«è®¾å®šä¸ºç¼©æ”¾ã€‚"
#: doc/classes/Vector3.xml
msgid ""
@@ -82608,11 +83159,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -82719,8 +83270,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -82766,7 +83317,7 @@ msgid ""
"0.1 and 0.3 depending on the type of car."
msgstr ""
"这是悬架å¯ä»¥ç§»åŠ¨çš„è·ç¦»ã€‚由于Godot çš„å•ä½ç›¸å½“äºŽç±³ï¼Œæ‰€ä»¥ä¿æŒè¿™ä¸ªè®¾ç½®ç›¸å¯¹è¾ƒä½Žã€‚"
-"æ ¹æ®æ±½è½¦çš„类型,试试0.1å’Œ0.3之间的值。"
+"æ ¹æ®æ±½è½¦çš„类型,试试 0.1 å’Œ 0.3 之间的值。"
#: doc/classes/VehicleWheel.xml
msgid ""
@@ -82774,7 +83325,7 @@ msgid ""
"value is used in conjunction with [member VehicleBody.steering] and ignored "
"if you are using the per-wheel [member steering] value instead."
msgstr ""
-"如果[code]true[/code]ï¼Œå½“æ±½è½¦è½¬å‘æ—¶ï¼Œå…¶è½®å­å°†è¢«è½¬åŠ¨ã€‚æ­¤å€¼å’Œ[member "
+"如果为 [code]true[/code]ï¼Œå½“æ±½è½¦è½¬å‘æ—¶ï¼Œå…¶è½®å­å°†è¢«è½¬åŠ¨ã€‚æ­¤å€¼å’Œ[member "
"VehicleBody.steering]一起使用,如果使用æ¯ä¸ªè½®å­çš„[member steering]值æ¥ä»£æ›¿ï¼Œ"
"则会被忽略。"
@@ -82785,9 +83336,9 @@ msgid ""
"VehicleBody.engine_force] and ignored if you are using the per-wheel [member "
"engine_force] value instead."
msgstr ""
-"如果[code]true[/code],此轮å­å°†å¼•擎力传递给地é¢ï¼ŒæŽ¨åŠ¨è½¦è¾†å‰è¿›ã€‚此值和[member "
-"VehicleBody.engine_force]一起使用,如果使用æ¯ä¸ªè½®å­çš„[member engine_force]"
-"值,则忽略该值。"
+"如果为 [code]true[/code],此轮å­å°†å¼•擎力传递给地é¢ï¼ŒæŽ¨åŠ¨è½¦è¾†å‰è¿›ã€‚此值和"
+"[member VehicleBody.engine_force]一起使用,如果使用æ¯ä¸ªè½®å­çš„[member "
+"engine_force]值,则忽略该值。"
#: doc/classes/VehicleWheel.xml
msgid ""
@@ -82901,7 +83452,7 @@ msgstr "è¦æ’­æ”¾çš„嵌入å¼éŸ³è½¨ã€‚"
#: doc/classes/VideoPlayer.xml
msgid "If [code]true[/code], playback starts when the scene loads."
-msgstr "如果[code]true[/code],当场景加载时开始播放。"
+msgstr "如果为 [code]true[/code],当场景加载时开始播放。"
#: doc/classes/VideoPlayer.xml
msgid "Amount of time in milliseconds to store in buffer while playing."
@@ -82917,12 +83468,12 @@ msgid ""
"control minimum size will be automatically adjusted to match the video "
"stream's dimensions."
msgstr ""
-"如果[code]true[/code],视频会缩放到控件的尺寸。å¦åˆ™ï¼ŒæŽ§ä»¶çš„æœ€å°å°ºå¯¸å°†è¢«è‡ªåŠ¨è°ƒ"
-"整以匹é…视频æµçš„尺寸。"
+"如果为 [code]true[/code],视频会缩放到控件的尺寸。å¦åˆ™ï¼ŒæŽ§ä»¶çš„æœ€å°å°ºå¯¸å°†è¢«è‡ª"
+"动调整以匹é…视频æµçš„尺寸。"
#: doc/classes/VideoPlayer.xml
msgid "If [code]true[/code], the video is paused."
-msgstr "如果[code]true[/code],则暂åœè§†é¢‘。"
+msgstr "如果为 [code]true[/code],则暂åœè§†é¢‘。"
#: doc/classes/VideoPlayer.xml
msgid "The assigned video stream. See description for supported formats."
@@ -83006,15 +83557,16 @@ msgid ""
"extension, you will have to rename the extension to [code].ogv[/code] to use "
"those videos within Godot."
msgstr ""
-"[VideoStream]资æºå¤„ç†[url=https://www.theora.org/]Ogg Theora[/url]视频格å¼ï¼Œ"
-"扩展å为[code].ogv[/code]。Theoraç¼–è§£ç å™¨æ¯”[VideoStreamWebm]çš„VP8å’ŒVP9效率"
-"低,但它以较少的CPUèµ„æºæ¥è§£ç ã€‚Theoraç¼–è§£ç å™¨æ˜¯åœ¨CPU上解ç ã€‚\n"
-"[b]注æ„:[/b]虽然Ogg Theora视频也å¯ä»¥æœ‰[code].ogg[/code]扩展å,但必须将扩展"
-"åæ”¹ä¸º[code].ogv[/code],以便在Godot内使用。"
+"[VideoStream] 资æºå¤„ç† [url=https://www.theora.org/]Ogg Theora[/url] 视频格"
+"å¼ï¼Œæ‰©å±•å为 [code].ogv[/code]。Theora ç¼–è§£ç å™¨æ¯” [VideoStreamWebm] çš„ VP8 "
+"å’Œ VP9 效率低,但它以较少的 CPU èµ„æºæ¥è§£ç ã€‚Theora ç¼–è§£ç å™¨æ˜¯åœ¨ CPU 上解"
+"ç ã€‚\n"
+"[b]注æ„:[/b]虽然 Ogg Theora 视频也å¯ä»¥æœ‰ [code].ogg[/code] 扩展å,但必须将"
+"æ‰©å±•åæ”¹ä¸º [code].ogv[/code],以便在 Godot 内使用。"
#: modules/theora/doc_classes/VideoStreamTheora.xml
msgid "Returns the Ogg Theora video file handled by this [VideoStreamTheora]."
-msgstr "返回由这个[VideoStreamTheora]处ç†çš„Ogg Theora视频文件。"
+msgstr "返回由这个 [VideoStreamTheora] 处ç†çš„ Ogg Theora 视频文件。"
#: modules/theora/doc_classes/VideoStreamTheora.xml
msgid ""
@@ -83022,12 +83574,12 @@ msgid ""
"handles. The [code]file[/code] name should have the [code].ogv[/code] "
"extension."
msgstr ""
-"设置该[VideoStreamTheora]资æºå¤„ç†çš„Ogg Theora视频文件。[code]file[/code]çš„å"
-"称应该有[code].ogv[/code]扩展å。"
+"设置该 [VideoStreamTheora] 资æºå¤„ç†çš„ Ogg Theora 视频文件。[code]file[/code] "
+"çš„å称应该有 [code].ogv[/code] 扩展å。"
#: modules/webm/doc_classes/VideoStreamWebm.xml
msgid "[VideoStream] resource for WebM videos."
-msgstr "[VideoStream] WebM视频的资æºã€‚"
+msgstr "[VideoStream] WebM 视频的资æºã€‚"
#: modules/webm/doc_classes/VideoStreamWebm.xml
msgid ""
@@ -83470,13 +84022,15 @@ msgstr "阴影图集上第四象é™çš„细分é‡ã€‚"
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
"阴影图集的分辨率(用于全å‘光和èšå…‰ï¼‰ã€‚该值将四èˆäº”入到最接近的 2 的幂。\n"
-"[b]注æ„:[/b]如果设置为 0,阴影将ä¸å¯è§ã€‚由于用户创建的视区默认值为 0,因此必"
-"须手动将此值设置为大于 0。"
+"[b]注æ„:[/b]如果设置为 [code]0[/code],点阴影和方å‘阴影[i]都[/i]å°†ä¸å¯è§ã€‚ç”±"
+"于用户创建的视区默认值为 [code]0[/code],因此必须手动将此值设置为大于 "
+"[code]0[/code](一般至少是 [code]256[/code])。"
#: doc/classes/Viewport.xml
msgid ""
@@ -83506,11 +84060,18 @@ msgstr "如果为 [code]true[/code],尺寸é‡å†™ä¹Ÿä¼šå½±å“拉伸。"
msgid ""
"If [code]true[/code], the viewport should render its background as "
"transparent."
-msgstr "如果为 [code]true[/code]ï¼Œè¯¥è§†çª—åº”ä½¿å…¶èƒŒæ™¯æ¸²æŸ“ä¸ºé€æ˜Žã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œè¯¥è§†åŒºåº”ä½¿å…¶èƒŒæ™¯æ¸²æŸ“ä¸ºé€æ˜Žã€‚"
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
-msgstr "视窗的渲染模å¼ã€‚"
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
+msgstr ""
+"视区的渲染模å¼ã€‚\n"
+"[b]注æ„:[/b]如果设为 [constant USAGE_2D] 或 [constant "
+"USAGE_2D_NO_SAMPLING],则å¯ç”¨ [member hdr] ä¸ä¼šç”Ÿæ•ˆï¼Œå› ä¸º 2D 䏿”¯æŒ HDR。"
#: doc/classes/Viewport.xml
msgid ""
@@ -83839,11 +84400,11 @@ msgstr "设置由给定的[enum Enabler]常é‡è¯†åˆ«çš„å¯ç”¨ç¨‹åºçš„æ´»åŠ¨çŠ¶æ
#: doc/classes/VisibilityEnabler.xml
msgid "If [code]true[/code], [RigidBody] nodes will be paused."
-msgstr "如果[code]true[/code],[RigidBody]节点将被暂åœã€‚"
+msgstr "如果为 [code]true[/code],[RigidBody]节点将被暂åœã€‚"
#: doc/classes/VisibilityEnabler.xml doc/classes/VisibilityEnabler2D.xml
msgid "If [code]true[/code], [AnimationPlayer] nodes will be paused."
-msgstr "如果[code]true[/code],[AnimationPlayer]节点将被暂åœã€‚"
+msgstr "如果为 [code]true[/code],[AnimationPlayer]节点将被暂åœã€‚"
#: doc/classes/VisibilityEnabler.xml doc/classes/VisibilityEnabler2D.xml
msgid "This enabler will pause [AnimationPlayer] nodes."
@@ -83882,26 +84443,27 @@ msgstr ""
#: doc/classes/VisibilityEnabler2D.xml
msgid "If [code]true[/code], [RigidBody2D] nodes will be paused."
-msgstr "如果[code]true[/code],[RigidBody2D]节点将被暂åœã€‚"
+msgstr "如果为 [code]true[/code],[RigidBody2D]节点将被暂åœã€‚"
#: doc/classes/VisibilityEnabler2D.xml
msgid "If [code]true[/code], [AnimatedSprite] nodes will be paused."
-msgstr "如果[code]true[/code],[AnimatedSprite]节点将被暂åœã€‚"
+msgstr "如果为 [code]true[/code],[AnimatedSprite]节点将被暂åœã€‚"
#: doc/classes/VisibilityEnabler2D.xml
msgid "If [code]true[/code], [Particles2D] nodes will be paused."
-msgstr "如果[code]true[/code],[Particles2D]节点将被暂åœã€‚"
+msgstr "如果为 [code]true[/code],[Particles2D]节点将被暂åœã€‚"
#: doc/classes/VisibilityEnabler2D.xml
msgid ""
"If [code]true[/code], the parent's [method Node._physics_process] will be "
"stopped."
-msgstr "如果[code]true[/code],父级的[method Node._physics_process]å°†è¢«åœæ­¢ã€‚"
+msgstr ""
+"如果为 [code]true[/code],父级的[method Node._physics_process]å°†è¢«åœæ­¢ã€‚"
#: doc/classes/VisibilityEnabler2D.xml
msgid ""
"If [code]true[/code], the parent's [method Node._process] will be stopped."
-msgstr "如果[code]true[/code],父级的[method Node._process]å°†è¢«åœæ­¢ã€‚"
+msgstr "如果为 [code]true[/code],父级的[method Node._process]å°†è¢«åœæ­¢ã€‚"
#: doc/classes/VisibilityEnabler2D.xml
msgid "This enabler will freeze [RigidBody2D] nodes."
@@ -83912,15 +84474,13 @@ msgid "This enabler will stop [Particles2D] nodes."
msgstr "这个å¯ç”¨ç¨‹åºå°†åœæ­¢ [Particles2D] 节点。"
#: doc/classes/VisibilityEnabler2D.xml
-#, fuzzy
msgid "This enabler will stop the parent's [method Node._process] function."
-msgstr "这个å¯ç”¨ç¨‹åºå°†åœæ­¢çˆ¶ç±»çš„ _process 函数。"
+msgstr "这个å¯ç”¨ç¨‹åºå°†åœæ­¢çˆ¶ç±»çš„ [method Node._process] 函数。"
#: doc/classes/VisibilityEnabler2D.xml
-#, fuzzy
msgid ""
"This enabler will stop the parent's [method Node._physics_process] function."
-msgstr "这个å¯ç”¨ç¨‹åºå°†åœæ­¢çˆ¶ç±»çš„ _physics_process 函数。"
+msgstr "这个å¯ç”¨ç¨‹åºå°†åœæ­¢çˆ¶ç±»çš„ [method Node._physics_process] 函数。"
#: doc/classes/VisibilityEnabler2D.xml
msgid "This enabler will stop [AnimatedSprite] nodes animations."
@@ -83960,7 +84520,7 @@ msgid ""
"right after it is instantiated, even if it will be on screen in the draw "
"pass."
msgstr ""
-"如果[code]true[/code],则边界框在å±å¹•上。\n"
+"如果为 [code]true[/code],则边界框在å±å¹•上。\n"
"[b]注æ„:[/b]一旦添加到场景树中,需è¦ä¸€å¸§æ¥è®¡ç®—节点的å¯è§æ€§ï¼Œæ‰€ä»¥è¿™ä¸ªæ–¹æ³•将在"
"它被实例化åŽç«‹å³è¿”回 [code]false[/code],å³ä½¿å±å¹•在绘制过程中。"
@@ -84025,7 +84585,7 @@ msgid ""
"right after it is instantiated, even if it will be on screen in the draw "
"pass."
msgstr ""
-"如果[code]true[/code],则边界矩形在å±å¹•上。\n"
+"如果为 [code]true[/code],则边界矩形在å±å¹•上。\n"
"[b]注æ„:[/b]一旦添加到场景树中,需è¦ä¸€å¸§æ¥è®¡ç®—节点的å¯è§æ€§ï¼Œæ‰€ä»¥è¿™ä¸ªæ–¹æ³•将在"
"它被实例化åŽç«‹å³è¿”回 [code]false[/code],å³ä½¿å±å¹•在绘制过程中。"
@@ -84119,8 +84679,8 @@ msgid ""
"changes how the engine handles the [VisualInstance] under the hood. "
"Equivalent to [method VisualServer.instance_set_base]."
msgstr ""
-"设置由该[VisualInstance]实例化的资æºï¼Œè¿™å°†æ”¹å˜å¼•擎对该[VisualInstance]的处ç†"
-"æ–¹å¼ã€‚相当于[method VisualServer.instance_set_base]。"
+"设置由该 [VisualInstance] 实例化的资æºï¼Œè¿™å°†æ”¹å˜å¼•擎对该 [VisualInstance] çš„"
+"å¤„ç†æ–¹å¼ã€‚相当于 [method VisualServer.instance_set_base]。"
#: doc/classes/VisualInstance.xml
msgid "Enables a particular layer in [member layers]."
@@ -84351,7 +84911,7 @@ msgstr "å½“èŠ‚ç‚¹ç«¯å£æ›´æ”¹æ—¶è§¦å‘。"
#: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml
msgid "A Visual Script node representing a constant from the base types."
-msgstr "一个 Visual Script 节点,表示基本类型中的一个常é‡ã€‚"
+msgstr "Visual Script 节点,表示基本类型中的一个常é‡ã€‚"
#: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml
msgid ""
@@ -84504,8 +85064,8 @@ msgid ""
"ease-in, 1+ is ease out. Negative values are in-out/out in."
msgstr ""
"缓动函数,基于指数。[code]s[/code]是函数的x值,[code]curve[/code]为0时,函数"
-"为常é‡å‡½æ•°ï¼Œ1是线性函数,0到1是缓入,1+是缓出。0到-1是缓出å†ç¼“入,低于-1是缓"
-"å…¥å†ç¼“出。"
+"为常é‡å‡½æ•°ï¼Œ1是线性函数,0 到 1是缓入,1+是缓出。0到-1是缓出å†ç¼“入,低于-1是"
+"缓入å†ç¼“出。"
#: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
msgid ""
@@ -84558,8 +85118,8 @@ msgid ""
"Return a random floating-point value between 0 and 1. To obtain a random "
"value between 0 to N, you can use it with multiplication."
msgstr ""
-"返回一个介于0到1ä¹‹é—´çš„éšæœºæµ®ç‚¹å€¼ã€‚è¦èŽ·å¾—ä¸€ä¸ªä»‹äºŽ0到Nä¹‹é—´çš„éšæœºå€¼ï¼Œå¯ä»¥å°†å…¶ä¸Ž"
-"乘法结åˆä½¿ç”¨ã€‚"
+"返回一个介于0 到 1ä¹‹é—´çš„éšæœºæµ®ç‚¹å€¼ã€‚è¦èŽ·å¾—ä¸€ä¸ªä»‹äºŽ0到Nä¹‹é—´çš„éšæœºå€¼ï¼Œå¯ä»¥å°†å…¶"
+"与乘法结åˆä½¿ç”¨ã€‚"
#: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
msgid "Return a random floating-point value between the two inputs."
@@ -84603,7 +85163,7 @@ msgid ""
"never outside it. Equivalent to [code]min(max(input, range_low), range_high)"
"[/code]."
msgstr ""
-"返回é™å®šåœ¨ç»™å®šèŒƒå›´å†…的输入,确ä¿ç»“果永远ä¸ä¼šè¶…出该范围。相当于"
+"返回é™å®šåœ¨ç»™å®šèŒƒå›´å†…的输入,确ä¿ç»“果永远ä¸ä¼šè¶…出该范围。相当于 "
"[code]min(max(input, range_low), range_high)[/code]。"
#: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
@@ -85168,7 +85728,7 @@ msgstr ""
msgid ""
"If [code]false[/code], call errors (e.g. wrong number of arguments) will be "
"ignored."
-msgstr "如果[code]false[/code]ï¼Œè°ƒç”¨é”™è¯¯å°†è¢«å¿½ç•¥ï¼Œä¾‹å¦‚å‚æ•°æ•°é‡é”™è¯¯ã€‚"
+msgstr "如果为 [code]false[/code]ï¼Œè°ƒç”¨é”™è¯¯å°†è¢«å¿½ç•¥ï¼Œä¾‹å¦‚å‚æ•°æ•°é‡é”™è¯¯ã€‚"
#: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml
msgid "The method will be called on this [Object]."
@@ -85340,8 +85900,7 @@ msgstr "图内å¯ç¼–辑节点的 Visual Script 虚类。"
msgid ""
"A Visual Script virtual class that defines the shape and the default "
"behavior of the nodes that have to be in-graph editable nodes."
-msgstr ""
-"一个 Visual Script å¯è§†åŒ–类,用于定义必须是图形内å¯ç¼–辑节点的形状和默认行为。"
+msgstr "Visual Script 虚类,用于定义必须是图形内å¯ç¼–辑节点的形状和默认行为。"
#: modules/visual_script/doc_classes/VisualScriptLists.xml
msgid "Adds an input port to the Visual Script node."
@@ -85525,7 +86084,7 @@ msgstr "当å¯ç”¨çš„输入/è¾“å‡ºç«¯å£æ›´æ”¹æ—¶è§¦å‘。"
#: modules/visual_script/doc_classes/VisualScriptOperator.xml
msgid "A Visual Script node that performs an operation on two values."
-msgstr "一个 Visual Script 节点,对两个值执行æ“作。"
+msgstr "Visual Script 节点,对两个值执行æ“作。"
#: modules/visual_script/doc_classes/VisualScriptOperator.xml
msgid ""
@@ -85577,7 +86136,7 @@ msgstr "è¦åŠ è½½çš„[Resource]资æºã€‚"
#: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml
msgid "A Visual Script node returning a value of a property from an [Object]."
-msgstr "一个Visual Script节点,从[Object]返回属性值。"
+msgstr "Visual Script 节点,返回 [Object] çš„æŸä¸ªå±žæ€§çš„值。"
#: modules/visual_script/doc_classes/VisualScriptPropertyGet.xml
msgid ""
@@ -86038,7 +86597,7 @@ msgstr ""
#: modules/visual_script/doc_classes/VisualScriptYield.xml
msgid "A Visual Script node used to pause a function execution."
-msgstr "一个Visual Script节点,用于暂åœå‡½æ•°çš„æ‰§è¡Œã€‚"
+msgstr "Visual Script 节点,用于暂åœå‡½æ•°çš„æ‰§è¡Œã€‚"
#: modules/visual_script/doc_classes/VisualScriptYield.xml
msgid ""
@@ -86067,11 +86626,11 @@ msgstr "物ç†å¸§æœŸé—´Yield。"
#: modules/visual_script/doc_classes/VisualScriptYield.xml
msgid "Yields a function and waits the given time."
-msgstr "一个函数Yields并等待给定的时间。"
+msgstr "将函数 Yield 并等待给定的时间。"
#: modules/visual_script/doc_classes/VisualScriptYieldSignal.xml
msgid "A Visual Script node yielding for a signal."
-msgstr "一个Visual Script节点yieldä¿¡å·ã€‚"
+msgstr "Visual Script 节点,用于 yield ä¿¡å·ã€‚"
#: modules/visual_script/doc_classes/VisualScriptYieldSignal.xml
msgid ""
@@ -86177,8 +86736,8 @@ msgid ""
"Once finished with your RID, you will want to free the RID using the "
"VisualServer's [method free_rid] static method."
msgstr ""
-"创建一个相机并将其添加到VisualServer中。它å¯ä»¥é€šè¿‡è¿”回的RID进行访问。这个RID"
-"将用于所有[code]camera_*[/code] VisualServer函数。\n"
+"创建一个相机并将其添加到 VisualServer 中。它å¯ä»¥é€šè¿‡è¿”回的RID进行访问。这个"
+"RID将用于所有[code]camera_*[/code] VisualServer函数。\n"
"一旦完æˆäº†å¯¹RID的处ç†ï¼Œä½ å°†éœ€è¦ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释"
"放RID。"
@@ -86188,14 +86747,14 @@ msgid ""
"which 3D layers are rendered by this camera. Equivalent to [member Camera."
"cull_mask]."
msgstr ""
-"设置与此相机相关的剔除é®ç½©ã€‚剔除é®ç½©æè¿°äº†æ­¤ç›¸æœºæ¸²æŸ“çš„ 3D 层。相当于[member "
+"设置与此相机相关的剔除é®ç½©ã€‚剔除é®ç½©æè¿°äº†æ­¤ç›¸æœºæ¸²æŸ“çš„ 3D 层。相当于 [member "
"Camera.cull_mask]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the environment used by this camera. Equivalent to [member Camera."
"environment]."
-msgstr "设置此相机所使用的环境。等åŒäºŽ[member Camera.environment]。"
+msgstr "设置此相机所使用的环境。相当于 [member Camera.environment]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -86231,8 +86790,9 @@ msgid ""
"the vertical aspect ratio which is equivalent to [constant Camera."
"KEEP_HEIGHT]."
msgstr ""
-"如果 [code]true[/code], ä¿ç•™æ°´å¹³é•¿å®½æ¯”,相当于 [constant Camera.KEEP_WIDTH]。"
-"如果[code]false[/code],ä¿ç•™åž‚直长宽比,相当于[constant Camera.KEEP_HEIGHT]。"
+"如果 [code]true[/code],ä¿ç•™æ°´å¹³é•¿å®½æ¯”,相当于 [constant Camera.KEEP_WIDTH]。"
+"如果为 [code]false[/code],ä¿ç•™åž‚直长宽比,相当于 [constant Camera."
+"KEEP_HEIGHT]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -86368,7 +86928,7 @@ msgstr "设置 [CanvasItem] 的索引。"
#: doc/classes/VisualServer.xml
msgid ""
"The light mask. See [LightOccluder2D] for more information on light masks."
-msgstr "光线é®ç½©ã€‚关于其更多信æ¯ï¼Œè¯·å‚阅[LightOccluder2D]。"
+msgstr "光线é®ç½©ã€‚详情请å‚阅 [LightOccluder2D]。"
#: doc/classes/VisualServer.xml
msgid "Sets a new material to the [CanvasItem]."
@@ -86449,8 +87009,8 @@ msgid ""
"Once finished with your RID, you will want to free the RID using the "
"VisualServer's [method free_rid] static method."
msgstr ""
-"创建ç¯å…‰é®æŒ¡å™¨å¹¶å°†å…¶æ·»åŠ åˆ°VisualServer中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RIDå¯"
-"用于所有[code]canvas_light_ocluder_*[/code] VisualServer函数。\n"
+"创建ç¯å…‰é®æŒ¡å™¨å¹¶å°†å…¶æ·»åŠ åˆ° VisualServer 中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RID"
+"å¯ç”¨äºŽæ‰€æœ‰[code]canvas_light_ocluder_*[/code] VisualServer函数。\n"
"一旦完æˆäº†RID处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放RID。"
#: doc/classes/VisualServer.xml
@@ -86534,13 +87094,13 @@ msgstr "使阴影å˜å¾—平滑。数值越低越光滑。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets texture to be used by light. Equivalent to [member Light2D.texture]."
-msgstr "设置ç¯å…‰ä½¿ç”¨çš„纹ç†ã€‚ç­‰åŒäºŽ[member Light2D.texture]。"
+msgstr "设置ç¯å…‰ä½¿ç”¨çš„纹ç†ã€‚相当于 [member Light2D.texture]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the offset of the light's texture. Equivalent to [member Light2D."
"offset]."
-msgstr "设置ç¯å…‰çº¹ç†çš„åç§»é‡ã€‚ç­‰åŒäºŽ[member Light2D.offset]。"
+msgstr "设置ç¯å…‰çº¹ç†çš„åç§»é‡ã€‚相当于 [member Light2D.offset]。"
#: doc/classes/VisualServer.xml
msgid "Sets the canvas light's [Transform2D]."
@@ -86562,8 +87122,8 @@ msgid ""
"Once finished with your RID, you will want to free the RID using the "
"VisualServer's [method free_rid] static method."
msgstr ""
-"创建新的光é®è”½å™¨å¤šè¾¹å½¢å¹¶å°†å…¶æ·»åŠ åˆ°VisualServer中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚è¿™"
-"个RIDå¯ç”¨äºŽæ‰€æœ‰[code]canvas_occluder_polygon_*[/code] VisualServer函数。\n"
+"创建新的光é®è”½å™¨å¤šè¾¹å½¢å¹¶å°†å…¶æ·»åŠ åˆ° VisualServer 中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚"
+"这个RIDå¯ç”¨äºŽæ‰€æœ‰[code]canvas_occluder_polygon_*[/code] VisualServer函数。\n"
"一旦完æˆäº†RID处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放RID。"
#: doc/classes/VisualServer.xml
@@ -86621,8 +87181,8 @@ msgid ""
"Once finished with your RID, you will want to free the RID using the "
"VisualServer's [method free_rid] static method."
msgstr ""
-"创建一个环境并将其添加到VisualServer中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RIDå¯åœ¨"
-"所有[code]environment_*[/code]VisualServer函数中使用。\n"
+"创建一个环境并将其添加到 VisualServer 中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RIDå¯"
+"在所有[code]environment_*[/code]VisualServer函数中使用。\n"
"一旦完æˆäº†å¯¹RID的处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放RID。"
#: doc/classes/VisualServer.xml
@@ -86639,7 +87199,8 @@ msgstr "è®¾ç½®çŽ¯å¢ƒå…‰å‚æ•°ã€‚详情请å‚阅 [Environment]。"
msgid ""
"Sets the [i]BGMode[/i] of the environment. Equivalent to [member Environment."
"background_mode]."
-msgstr "设置环境的[i]BGMode[/i]。相当于[member Environment.background_mode]。"
+msgstr ""
+"设置环境的 [i]BGMode[/i]。相当于 [member Environment.background_mode]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -86774,7 +87335,7 @@ msgid ""
"[b]Note:[/b] When running a headless or server binary, this function returns "
"an empty string."
msgstr ""
-"返回视频适é…器的å称(例如:\"GeForce GTX 1080/PCIe/SSE2\")。\n"
+"返回视频适é…器的å称(例如 \"GeForce GTX 1080/PCIe/SSE2\")。\n"
"[b]注æ„:[/b]当è¿è¡Œä¸€ä¸ªç²¾ç®€æˆ–æœåС噍坿‰§è¡Œæ–‡ä»¶æ—¶ï¼Œè¿™ä¸ªå‡½æ•°è¿”回一个空字符串。"
#: doc/classes/VisualServer.xml
@@ -86783,12 +87344,12 @@ msgid ""
"[b]Note:[/b] When running a headless or server binary, this function returns "
"an empty string."
msgstr ""
-"返回视频适é…器的供应商(例如,\"NVIDIA Corporation\")。\n"
+"返回视频适é…器的供应商(例如 \"NVIDIA Corporation\")。\n"
"[b]注æ„:[/b]当è¿è¡Œç²¾ç®€æˆ–æœåС噍坿‰§è¡Œæ–‡ä»¶æ—¶ï¼Œè¯¥å‡½æ•°è¿”回一个空字符串。"
#: doc/classes/VisualServer.xml
msgid "Returns the id of a white texture. Creates one if none exists."
-msgstr "返回白色纹ç†çš„id。如果ä¸å­˜åœ¨ï¼Œåˆ™åˆ›å»ºä¸€ä¸ªã€‚"
+msgstr "返回白色纹ç†çš„ id。如果ä¸å­˜åœ¨ï¼Œåˆ™åˆ›å»ºä¸€ä¸ªã€‚"
#: doc/classes/VisualServer.xml
msgid ""
@@ -86804,7 +87365,7 @@ msgstr ""
"于所有 [code]gi_probe_*[/code] VisualServer 函数。\n"
"å®Œæˆ RID 处ç†åŽï¼Œå¯ä½¿ç”¨ VisualServer çš„ [method free_rid] 陿€æ–¹æ³•释放 "
"RID。\n"
-"è¦æ”¾ç½®åœ¨åœºæ™¯ä¸­ï¼Œè¯·ä½¿ç”¨è¿”回的 RID, 使用 [method instance_set_base] 将此 GI 探"
+"è¦æ”¾ç½®åœ¨åœºæ™¯ä¸­ï¼Œè¯·ä½¿ç”¨è¿”回的 RID,使用 [method instance_set_base] 将此 GI 探"
"针附加到实例。"
#: doc/classes/VisualServer.xml
@@ -86812,57 +87373,57 @@ msgid ""
"Returns the bias value for the GI probe. Bias is used to avoid self "
"occlusion. Equivalent to [member GIProbeData.bias]."
msgstr ""
-"返回GI探针的å置值。å置是用æ¥é¿å…è‡ªæˆ‘é®æŒ¡çš„。相当于[member GIProbeData."
+"返回该 GI 探针的å置值。å置是用æ¥é¿å…è‡ªæˆ‘é®æŒ¡çš„。相当于 [member GIProbeData."
"bias]。"
#: doc/classes/VisualServer.xml
msgid ""
"Returns the axis-aligned bounding box that covers the full extent of the GI "
"probe."
-msgstr "返回覆盖GI探针全部范围的轴对é½çš„边界框。"
+msgstr "返回覆盖该 GI 探针全部范围的轴对é½çš„边界框。"
#: doc/classes/VisualServer.xml
msgid "Returns the cell size set by [method gi_probe_set_cell_size]."
-msgstr "返回由[method gi_probe_set_cell_size]设置的å•元大å°ã€‚"
+msgstr "返回由 [method gi_probe_set_cell_size] 设置的å•元大å°ã€‚"
#: doc/classes/VisualServer.xml
msgid "Returns the data used by the GI probe."
-msgstr "返回GI探针所使用的数æ®ã€‚"
+msgstr "返回该 GI 探针所使用的数æ®ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"Returns the dynamic range set for this GI probe. Equivalent to [member "
"GIProbe.dynamic_range]."
-msgstr "返回该GI探针的动æ€èŒƒå›´è®¾ç½®ã€‚相当于[member GIProbe.dynamic_range]。"
+msgstr "返回该 GI 探针的动æ€èŒƒå›´è®¾ç½®ã€‚相当于 [member GIProbe.dynamic_range]。"
#: doc/classes/VisualServer.xml
msgid ""
"Returns the energy multiplier for this GI probe. Equivalent to [member "
"GIProbe.energy]."
-msgstr "返回这个GI探针的能é‡ä¹˜æ•°ã€‚相当于[member GIProbe.energy]。"
+msgstr "返回这个 GI 探针的能é‡ä¹˜æ•°ã€‚相当于 [member GIProbe.energy]。"
#: doc/classes/VisualServer.xml
msgid ""
"Returns the normal bias for this GI probe. Equivalent to [member GIProbe."
"normal_bias]."
-msgstr "返回该GI探针的法线å置。相当于[member GIProbe.normal_bias]。"
+msgstr "返回这个 GI 探针的法线å置。相当于 [member GIProbe.normal_bias]。"
#: doc/classes/VisualServer.xml
msgid ""
"Returns the propagation value for this GI probe. Equivalent to [member "
"GIProbe.propagation]."
-msgstr "返回这个GI探针的传播值。相当于[member GIProbe.propagation]。"
+msgstr "返回这个 GI 探针的传播值。相当于 [member GIProbe.propagation]。"
#: doc/classes/VisualServer.xml
msgid "Returns the Transform set by [method gi_probe_set_to_cell_xform]."
-msgstr "返回由[method gi_probe_set_to_cell_xform]è®¾ç½®çš„å˜æ¢ã€‚"
+msgstr "返回由 [method gi_probe_set_to_cell_xform] è®¾ç½®çš„å˜æ¢ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"Returns [code]true[/code] if the GI probe data associated with this GI probe "
"is compressed. Equivalent to [member GIProbe.compress]."
msgstr ""
-"如果与此GI探针相关的数æ®è¢«åŽ‹ç¼©ï¼Œè¿”å›ž [code]true[/code]。相当于[member "
+"如果与该 GI 探针相关的数æ®è¢«åŽ‹ç¼©ï¼Œè¿”å›ž [code]true[/code]。相当于 [member "
"GIProbe.compress]。"
#: doc/classes/VisualServer.xml
@@ -86870,23 +87431,23 @@ msgid ""
"Returns [code]true[/code] if the GI probe is set to interior, meaning it "
"does not account for sky light. Equivalent to [member GIProbe.interior]."
msgstr ""
-"如果 GI 探针设置为内部,则返回 [code]true[/code],这æ„味ç€å®ƒä¸è€ƒè™‘天空光。相"
-"当于[member GIProbe.interior]。"
+"如果该 GI 探针设置为内部,则返回 [code]true[/code],这æ„味ç€å®ƒä¸è€ƒè™‘天空光。"
+"相当于 [member GIProbe.interior]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the bias value to avoid self-occlusion. Equivalent to [member GIProbe."
"bias]."
-msgstr "设置å置值以é¿å…è‡ªé®æŒ¡ã€‚相当于[member GIProbe.bias]。"
+msgstr "设置å置值以é¿å…è‡ªé®æŒ¡ã€‚相当于 [member GIProbe.bias]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the axis-aligned bounding box that covers the extent of the GI probe."
-msgstr "设置覆盖 GI 探针范围的轴对é½è¾¹ç•Œæ¡†ã€‚"
+msgstr "设置覆盖该 GI 探针范围的轴对é½è¾¹ç•Œæ¡†ã€‚"
#: doc/classes/VisualServer.xml
msgid "Sets the size of individual cells within the GI probe."
-msgstr "设置 GI 探针内å•个å•元的大å°ã€‚"
+msgstr "设置该 GI 探针内å•个å•元的大å°ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
@@ -86894,8 +87455,8 @@ msgid ""
"take up less space but may look worse. Equivalent to [member GIProbe."
"compress]."
msgstr ""
-"设置GI探针数æ®çš„压缩设置。压缩åŽçš„æ•°æ®å°†å ç”¨æ›´å°‘的空间,但å¯èƒ½çœ‹èµ·æ¥æ›´ç³Ÿç³•。"
-"相当于[member GIProbe.compress]。"
+"设置该 GI 探针数æ®çš„压缩设置。压缩åŽçš„æ•°æ®å°†å ç”¨æ›´å°‘的空间,但å¯èƒ½çœ‹èµ·æ¥æ›´ç³Ÿ"
+"糕。相当于 [member GIProbe.compress]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -86903,8 +87464,8 @@ msgid ""
"this is created and called internally within the [GIProbe] node. You should "
"not try to set this yourself."
msgstr ""
-"设置用于照明计算的GI探针的数æ®ã€‚通常这是在[GIProbe]节点内部创建和调用的。你ä¸"
-"应该å°è¯•自己设置。"
+"设置用于照明计算的 GI 探针的数æ®ã€‚通常这是在 [GIProbe] 节点内部创建和调用的。"
+"ä½ ä¸åº”该å°è¯•自己设置。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -86912,8 +87473,8 @@ msgid ""
"bright lights can be. A smaller range captures greater detail but limits how "
"bright lights can be. Equivalent to [member GIProbe.dynamic_range]."
msgstr ""
-"设定GI探针的动æ€èŒƒå›´ã€‚动æ€èŒƒå›´è®¾å®šäº†ç¯å…‰çš„亮度é™åˆ¶ã€‚较å°çš„范围å¯ä»¥æ•æ‰åˆ°æ›´å¤š"
-"的细节,但是é™åˆ¶äº†ç¯å…‰çš„亮度。相当于[member GIProbe.dynamic_range]。"
+"设置该 GI 探针的动æ€èŒƒå›´ã€‚动æ€èŒƒå›´è®¾å®šäº†ç¯å…‰çš„亮度é™åˆ¶ã€‚较å°çš„范围å¯ä»¥æ•æ‰åˆ°"
+"更多的细节,但是é™åˆ¶äº†ç¯å…‰çš„亮度。相当于 [member GIProbe.dynamic_range]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -86921,7 +87482,7 @@ msgid ""
"indirect light from the GI probe brighter. Equivalent to [member GIProbe."
"energy]."
msgstr ""
-"设置该GI探针的能é‡ä¹˜æ•°ã€‚较高的能é‡ä½¿GI探针的间接光更亮。相当于[member "
+"设置这个 GI 探针的能é‡ä¹˜æ•°ã€‚较高的能é‡ä½¿ GI 探针的间接光更亮。相当于 [member "
"GIProbe.energy]。"
#: doc/classes/VisualServer.xml
@@ -86930,7 +87491,7 @@ msgid ""
"not include the sky when calculating lighting. Equivalent to [member GIProbe."
"interior]."
msgstr ""
-"设置该 GI 探针的内部值。设置为内部的 GI 探针在计算照明时ä¸åŒ…括天空。相当于 "
+"设置这个 GI 探针的内部值。设置为内部的 GI 探针在计算照明时ä¸åŒ…括天空。相当于 "
"[member GIProbe.interior]。"
#: doc/classes/VisualServer.xml
@@ -86939,18 +87500,18 @@ msgid ""
"other form of bias and may help reduce self-occlusion. Equivalent to [member "
"GIProbe.normal_bias]."
msgstr ""
-"设置该GI探针的法线å置。法线å置的行为类似于其他形å¼çš„åç½®ï¼Œå¯æœ‰åŠ©äºŽå‡å°‘自我"
-"鮿Œ¡ã€‚相当于[member GIProbe.normal_bias]。"
+"设置这个 GI 探针的法线å置。法线å置的行为类似于其他形å¼çš„åç½®ï¼Œå¯æœ‰åŠ©äºŽå‡å°‘"
+"è‡ªæˆ‘é®æŒ¡ã€‚相当于 [member GIProbe.normal_bias]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the propagation of light within this GI probe. Equivalent to [member "
"GIProbe.propagation]."
-msgstr "设置光在这个GI探针中的传播。相当于[member GIProbe.propagation]。"
+msgstr "设置光在这个 GI 探针中的传播。相当于 [member GIProbe.propagation]。"
#: doc/classes/VisualServer.xml
msgid "Sets the to cell [Transform] for this GI probe."
-msgstr "为这个GI探针设置å•å…ƒ[Transform]。"
+msgstr "为这个 GI 探针设置å•å…ƒ [Transform]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -86978,18 +87539,18 @@ msgid ""
"[code]skinning_fallback[/code] in case the hardware doesn't support the "
"default GPU skinning process."
msgstr ""
-"如果æ“ä½œç³»ç»Ÿæ”¯æŒæŸé¡¹åŠŸèƒ½ï¼Œåˆ™è¿”å›ž [code]true[/code]。特性å¯èƒ½æ˜¯[code]s3tc[/"
-"code], [code]etc[/code], [code]etc2[/code], [code]pvrtc[/code] 和 "
+"如果æ“ä½œç³»ç»Ÿæ”¯æŒæŸé¡¹åŠŸèƒ½ï¼Œåˆ™è¿”å›ž [code]true[/code]。特性å¯èƒ½æ˜¯ [code]s3tc[/"
+"code]ã€[code]etc[/code]ã€[code]etc2[/code]ã€[code]pvrtc[/code] å’Œ "
"[code]skinning_fallback[/code]。\n"
-"当使用GLES2æ¸²æŸ“æ—¶ï¼Œåœ¨ç¡¬ä»¶ä¸æ”¯æŒé»˜è®¤çš„GPU蒙皮过程的情况下,返回 [code]true[/"
-"code]与[code]skinning_fallback[/code]。"
+"当使用 GLES2 æ¸²æŸ“æ—¶ï¼Œåœ¨ç¡¬ä»¶ä¸æ”¯æŒé»˜è®¤çš„ GPU 蒙皮过程的情况下,返回 "
+"[code]true[/code] 与 [code]skinning_fallback[/code]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets up [ImmediateGeometry] internals to prepare for drawing. Equivalent to "
"[method ImmediateGeometry.begin]."
msgstr ""
-"设置[ImmediateGeometry]的内部结构,为绘图åšå‡†å¤‡ã€‚相当于[method "
+"设置 [ImmediateGeometry] 的内部结构,为绘图åšå‡†å¤‡ã€‚相当于 [method "
"ImmediateGeometry.begin]。"
#: doc/classes/VisualServer.xml
@@ -87004,7 +87565,8 @@ msgstr ""
msgid ""
"Sets the color to be used with next vertex. Equivalent to [method "
"ImmediateGeometry.set_color]."
-msgstr "设置用于下一个顶点的颜色。相当于[method ImmediateGeometry.set_color]。"
+msgstr ""
+"设置用于下一个顶点的颜色。相当于 [method ImmediateGeometry.set_color]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87016,60 +87578,61 @@ msgid ""
"To place in a scene, attach this immediate geometry to an instance using "
"[method instance_set_base] using the returned RID."
msgstr ""
-"创建直接几何图形并将其添加到VisualServer中。它å¯ä»¥é€šè¿‡è¿”回的RID进行访问。这个"
-"RIDå¯åœ¨æ‰€æœ‰[code]immediate_*[/code]VisualServer函数中使用。\n"
-"一旦完æˆäº†å¯¹RID的处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放"
-"RID。\n"
-"è¦åœ¨åœºæ™¯ä¸­æ”¾ç½®ï¼Œä½¿ç”¨è¿”回的RID用[method instance_set_base]将这个直接几何体附加"
-"到一个实例上。"
+"创建直接几何图形并将其添加到 VisualServer 中。它å¯ä»¥é€šè¿‡è¿”回的 RID 进行访问。"
+"这个 RID å¯åœ¨æ‰€æœ‰ [code]immediate_*[/code] VisualServer 函数中使用。\n"
+"一旦完æˆäº†å¯¹ RID 的处ç†ï¼Œå¯ä½¿ç”¨ VisualServer çš„ [method free_rid] 陿€æ–¹æ³•释"
+"放 RID。\n"
+"è¦åœ¨åœºæ™¯ä¸­æ”¾ç½®ï¼Œä½¿ç”¨è¿”回的 RID 用 [method instance_set_base] 将这个直接几何体"
+"附加到一个实例上。"
#: doc/classes/VisualServer.xml
msgid ""
"Ends drawing the [ImmediateGeometry] and displays it. Equivalent to [method "
"ImmediateGeometry.end]."
msgstr ""
-"结æŸç»˜åˆ¶[ImmediateGeometry]并显示它。相当于[method ImmediateGeometry.end]。"
+"结æŸç»˜åˆ¶ [ImmediateGeometry] 并进行显示。相当于 [method ImmediateGeometry."
+"end]。"
#: doc/classes/VisualServer.xml
msgid "Returns the material assigned to the [ImmediateGeometry]."
-msgstr "返回分é…ç»™[ImmediateGeometry]çš„æè´¨ã€‚"
+msgstr "返回分é…给该 [ImmediateGeometry] çš„æè´¨ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the normal to be used with next vertex. Equivalent to [method "
"ImmediateGeometry.set_normal]."
msgstr ""
-"设置用于下一个顶点的法线。相当于[method ImmediateGeometry.set_normal]。"
+"设置用于下一个顶点的法线。相当于 [method ImmediateGeometry.set_normal]。"
#: doc/classes/VisualServer.xml
msgid "Sets the material to be used to draw the [ImmediateGeometry]."
-msgstr "设置用于绘制[ImmediateGeometry]çš„æè´¨ã€‚"
+msgstr "设置用于绘制该 [ImmediateGeometry] çš„æè´¨ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the tangent to be used with next vertex. Equivalent to [method "
"ImmediateGeometry.set_tangent]."
msgstr ""
-"设置用于下一个顶点的切线。相当于[method ImmediateGeometry.set_tangent]。"
+"设置用于下一个顶点的切线。相当于 [method ImmediateGeometry.set_tangent]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the UV to be used with next vertex. Equivalent to [method "
"ImmediateGeometry.set_uv]."
-msgstr "设置用于下一个顶点的UV。相当于[method ImmediateGeometry.set_uv]。"
+msgstr "设置用于下一个顶点的 UV。相当于 [method ImmediateGeometry.set_uv]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the UV2 to be used with next vertex. Equivalent to [method "
"ImmediateGeometry.set_uv2]."
-msgstr "设置用于下一个顶点的UV2。相当于[method ImmediateGeometry.set_uv2]。"
+msgstr "设置用于下一个顶点的 UV2。相当于 [method ImmediateGeometry.set_uv2]。"
#: doc/classes/VisualServer.xml
msgid ""
"Adds the next vertex using the information provided in advance. Equivalent "
"to [method ImmediateGeometry.add_vertex]."
msgstr ""
-"使用预先æä¾›çš„ä¿¡æ¯æ·»åŠ ä¸‹ä¸€ä¸ªé¡¶ç‚¹ã€‚ç›¸å½“äºŽ[method ImmediateGeometry."
+"使用预先æä¾›çš„ä¿¡æ¯æ·»åŠ ä¸‹ä¸€ä¸ªé¡¶ç‚¹ã€‚ç›¸å½“äºŽ [method ImmediateGeometry."
"add_vertex]。"
#: doc/classes/VisualServer.xml
@@ -87078,8 +87641,8 @@ msgid ""
"helper class that calls [method immediate_vertex] under the hood. Equivalent "
"to [method ImmediateGeometry.add_vertex]."
msgstr ""
-"使用预先æä¾›çš„ä¿¡æ¯æ·»åŠ ä¸‹ä¸€ä¸ªé¡¶ç‚¹ã€‚è¿™æ˜¯ä¸€ä¸ªè¾…åŠ©ç±»ï¼Œå®ƒåœ¨åŽå°è°ƒç”¨[method "
-"immediate_vertex]。相当于[method ImmediateGeometry.add_vertex]。"
+"使用预先æä¾›çš„ä¿¡æ¯æ·»åŠ ä¸‹ä¸€ä¸ªé¡¶ç‚¹ã€‚è¿™æ˜¯ä¸€ä¸ªè¾…åŠ©ç±»ï¼Œå®ƒåœ¨åŽå°è°ƒç”¨ [method "
+"immediate_vertex]。相当于 [method ImmediateGeometry.add_vertex]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87096,9 +87659,9 @@ msgid ""
"instance for proper culling with [method instances_cull_aabb], [method "
"instances_cull_convex], and [method instances_cull_ray]."
msgstr ""
-"将唯一的对象ID附加到实例上。必须将对象ID附加到实例上,以便通过[method "
-"instances_cull_aabb]ã€[method instances_cull_convex]å’Œ[method "
-"instances_cull_ray]进行正确的筛除。"
+"将唯一的对象 ID 附加到实例上。必须将对象 ID 附加到实例上,以便通过 [method "
+"instances_cull_aabb]ã€[method instances_cull_convex] å’Œ [method "
+"instances_cull_ray] 进行正确的筛除。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87117,7 +87680,7 @@ msgid ""
"particles, meshes, and reflection probes need to be associated with an "
"instance to be visible in the scenario using [method instance_set_base]."
msgstr ""
-"创建一个å¯è§†åŒ–实例并将其添加到VisualServer中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个"
+"创建一个å¯è§†åŒ–实例并将其添加到 VisualServer 中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个"
"RIDå¯åœ¨æ‰€æœ‰[code]instance_*[/code]VisualServer函数中使用。\n"
"一旦完æˆäº†å¯¹RID的处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放"
"RID。\n"
@@ -87132,8 +87695,9 @@ msgid ""
"Once finished with your RID, you will want to free the RID using the "
"VisualServer's [method free_rid] static method."
msgstr ""
-"创建一个å¯è§†åŒ–实例,将其添加到VisualServer中,并设置基本和效果。å¯ä»¥ç”¨è¿”回的"
-"RIDæ¥è®¿é—®å®ƒã€‚这个RIDå¯åœ¨æ‰€æœ‰[code]instance_*[/code]VisualServer函数中使用。\n"
+"创建一个å¯è§†åŒ–实例,将其添加到 VisualServer 中,并设置基本和效果。å¯ä»¥ç”¨è¿”回"
+"çš„RIDæ¥è®¿é—®å®ƒã€‚这个RIDå¯åœ¨æ‰€æœ‰[code]instance_*[/code]VisualServer函数中使"
+"用。\n"
"一旦完æˆäº†å¯¹RID的处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放RID。"
#: doc/classes/VisualServer.xml
@@ -87153,7 +87717,7 @@ msgid ""
"Sets the flag for a given [enum InstanceFlags]. See [enum InstanceFlags] for "
"more details."
msgstr ""
-"设置给定的[enum InstanceFlags]标志。更多细节请å‚阅[enum InstanceFlags]。"
+"设置给定的 [enum InstanceFlags] 标志。更多细节请å‚阅 [enum InstanceFlags]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87161,7 +87725,7 @@ msgid ""
"materials for the mesh associated with this instance. Equivalent to [member "
"GeometryInstance.material_overlay]."
msgstr ""
-"为该实例的网格设置æè´¨ï¼Œå°†åœ¨æ‰€æœ‰è¡¨é¢çš„æ´»åЍæè´¨ä¸Šå±‚进行渲染。等价于 [member "
+"为该实例的网格设置æè´¨ï¼Œå°†åœ¨æ‰€æœ‰è¡¨é¢çš„æ´»åЍæè´¨ä¸Šå±‚进行渲染。相当于 [member "
"GeometryInstance.material_overlay]。"
#: doc/classes/VisualServer.xml
@@ -87170,7 +87734,7 @@ msgid ""
"associated with this instance. Equivalent to [member GeometryInstance."
"material_override]."
msgstr ""
-"设置一个æè´¨ï¼Œè¦†ç›–与此实例关è”的网格上的所有表é¢çš„æè´¨ã€‚相当于[member "
+"设置一个æè´¨ï¼Œè¦†ç›–与此实例关è”的网格上的所有表é¢çš„æè´¨ã€‚相当于 [member "
"GeometryInstance.material_override]。"
#: doc/classes/VisualServer.xml
@@ -87181,9 +87745,9 @@ msgid ""
"reflection probe, lightmap capture, and the GI probe are all types that can "
"be set as the base of an instance in order to be displayed in the scenario."
msgstr ""
-"设置实例的基类。基类å¯ä»¥æ˜¯VisualServer中创建的任何å¯ä»¥æ˜¾ç¤ºçš„3D对象。例如,光"
-"照类型ã€ç½‘æ ¼ã€å¤šç½‘æ ¼ã€åŸºæœ¬å‡ ä½•ã€ç²’å­ç³»ç»Ÿã€å射探针ã€å…‰ç…§å›¾æ•æ‰å’ŒGI探针等类型"
-"都å¯ä»¥è¢«è®¾ç½®ä¸ºå®žä¾‹çš„基类,以便在场景中显示。"
+"设置实例的基类。基类å¯ä»¥æ˜¯ VisualServer 中创建的任何å¯ä»¥æ˜¾ç¤ºçš„3D对象。例如,"
+"光照类型ã€ç½‘æ ¼ã€å¤šç½‘æ ¼ã€åŸºæœ¬å‡ ä½•ã€ç²’å­ç³»ç»Ÿã€å射探针ã€å…‰ç…§å›¾æ•æ‰å’ŒGI探针等类"
+"型都å¯ä»¥è¢«è®¾ç½®ä¸ºå®žä¾‹çš„基类,以便在场景中显示。"
#: doc/classes/VisualServer.xml
msgid "Sets the weight for a given blend shape associated with this instance."
@@ -87194,12 +87758,12 @@ msgid ""
"Sets a custom AABB to use when culling objects from the view frustum. "
"Equivalent to [method GeometryInstance.set_custom_aabb]."
msgstr ""
-"设置自定义的AABB,当从视图中剔除对象时使用。相当于[method GeometryInstance."
+"设置自定义的 AABB,当从视图中剔除对象时使用。相当于 [method GeometryInstance."
"set_custom_aabb]。"
#: doc/classes/VisualServer.xml
msgid "Function not implemented in Godot 3.x."
-msgstr "在Godot 3.x中没有实现的功能。"
+msgstr "在 Godot 3.x 中没有实现的功能。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87207,14 +87771,14 @@ msgid ""
"view frustum. This allows you to avoid culling objects that fall outside the "
"view frustum. Equivalent to [member GeometryInstance.extra_cull_margin]."
msgstr ""
-"设置边è·ï¼Œåœ¨å‰”除视域范围内的对象时增加AABB的大å°ã€‚è¿™å¯ä»¥è®©ä½ é¿å…剔除è½åœ¨è§†åŸŸ"
-"范围外的物体。相当于[member GeometryInstance.extra_cull_margin]。"
+"设置边è·ï¼Œåœ¨å‰”除视域范围内的对象时增加 AABB 的大å°ã€‚è¿™å¯ä»¥è®©ä½ é¿å…剔除è½åœ¨è§†"
+"域范围外的物体。相当于 [member GeometryInstance.extra_cull_margin]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the render layers that this instance will be drawn to. Equivalent to "
"[member VisualInstance.layers]."
-msgstr "设置该实例将被绘制的渲染层。相当于[member VisualInstance.layers]。"
+msgstr "设置该实例将被绘制的渲染层。相当于 [member VisualInstance.layers]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87226,13 +87790,14 @@ msgstr "设置实例所在的场景。场景是对象将在其中显示的 3D ä¸
msgid ""
"Sets the material of a specific surface. Equivalent to [method MeshInstance."
"set_surface_material]."
-msgstr "设置特定表é¢çš„æè´¨ã€‚相当于[method MeshInstance.set_surface_material]。"
+msgstr ""
+"设置特定表é¢çš„æè´¨ã€‚相当于 [method MeshInstance.set_surface_material]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the world space transform of the instance. Equivalent to [member "
"Spatial.transform]."
-msgstr "è®¾ç½®å®žä¾‹çš„ä¸–ç•Œç©ºé—´å˜æ¢ã€‚相当于[member Spatial.transform]。"
+msgstr "è®¾ç½®å®žä¾‹çš„ä¸–ç•Œç©ºé—´å˜æ¢ã€‚相当于 [member Spatial.transform]。"
#: doc/classes/VisualServer.xml
msgid "Sets the lightmap to use with this instance."
@@ -87255,10 +87820,10 @@ msgid ""
"[b]Warning:[/b] This function is primarily intended for editor usage. For in-"
"game use cases, prefer physics collision."
msgstr ""
-"返回一个与所æä¾›çš„AABB相交的物体ID数组。åªè€ƒè™‘å¯è§†åŒ–çš„3D节点,例如"
-"[MeshInstance]或[DirectionalLight]。使用[method @GDScript.instance_from_id]æ¥"
-"获å–实际节点。这必须æä¾›ä¸€ä¸ªåœºæ™¯çš„RID,该RID在你想查询的[World]中是å¯ç”¨çš„。这"
-"将强制更新所有排队等待更新的资æºã€‚\n"
+"返回一个与所æä¾›çš„ AABB 相交的物体 ID 数组。åªè€ƒè™‘å¯è§†åŒ–çš„ 3D 节点,例如 "
+"[MeshInstance] 或 [DirectionalLight]。使用 [method @GDScript."
+"instance_from_id] æ¥èŽ·å–实际节点。这必须æä¾›ä¸€ä¸ªåœºæ™¯çš„ RID,该 RID 在你想查询"
+"çš„ [World] 中是å¯ç”¨çš„。这将强制更新所有排队等待更新的资æºã€‚\n"
"[b]警告:[/b]这个函数主è¦ç”¨äºŽç¼–辑器使用。对于游æˆä¸­çš„使用情况,最好是物ç†ç¢°"
"撞。"
@@ -87356,14 +87921,14 @@ msgstr ""
#: doc/classes/VisualServer.xml
msgid "Sets the color of the light. Equivalent to [member Light.light_color]."
-msgstr "设置ç¯å…‰çš„颜色。相当于[member Light.light_color]。"
+msgstr "设置ç¯å…‰çš„颜色。相当于 [member Light.light_color]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the cull mask for this Light. Lights only affect objects in the "
"selected layers. Equivalent to [member Light.light_cull_mask]."
msgstr ""
-"设置此ç¯å…‰çš„剔除é®ç½©ã€‚ç¯å…‰ä»…å½±å“选定图层中的对象。相当于[member Light."
+"设置此ç¯å…‰çš„剔除é®ç½©ã€‚ç¯å…‰ä»…å½±å“选定图层中的对象。相当于 [member Light."
"light_cull_mask]。"
#: doc/classes/VisualServer.xml
@@ -87371,7 +87936,7 @@ msgid ""
"If [code]true[/code], light will subtract light instead of adding light. "
"Equivalent to [member Light.light_negative]."
msgstr ""
-"如果[code]true[/code],光将å‡åŽ»å…‰è€Œä¸æ˜¯å¢žåŠ å…‰ã€‚ç›¸å½“äºŽ[member Light."
+"如果为 [code]true[/code],光将å‡åŽ»å…‰è€Œä¸æ˜¯å¢žåŠ å…‰ã€‚ç›¸å½“äºŽ [member Light."
"light_negative]。"
#: doc/classes/VisualServer.xml
@@ -87379,7 +87944,7 @@ msgid ""
"Sets the specified light parameter. See [enum LightParam] for options. "
"Equivalent to [method Light.set_param]."
msgstr ""
-"设置指定的ç¯å…‰å‚数。å‚阅[enum LightParam]的选项。相当于[method Light."
+"设置指定的ç¯å…‰å‚数。å‚阅 [enum LightParam] 的选项。相当于 [method Light."
"set_param]。"
#: doc/classes/VisualServer.xml
@@ -87390,8 +87955,8 @@ msgid ""
"shadows with [method instance_geometry_set_cast_shadows_setting]. Equivalent "
"to [member Light.shadow_reverse_cull_face]."
msgstr ""
-"如果[code]true[/code],å转网格的背é¢å‰”除。当你有一个平é¢ç½‘æ ¼åŽé¢æœ‰ç¯å…‰æ—¶ï¼Œè¿™"
-"å¯èƒ½å¾ˆæœ‰ç”¨ã€‚如果你需è¦åœ¨ç½‘格的两é¢éƒ½æŠ•下阴影,å¯ä»¥ç”¨[method "
+"如果为 [code]true[/code],å转网格的背é¢å‰”除。当你有一个平é¢ç½‘æ ¼åŽé¢æœ‰ç¯å…‰"
+"时,这å¯èƒ½å¾ˆæœ‰ç”¨ã€‚如果你需è¦åœ¨ç½‘格的两é¢éƒ½æŠ•下阴影,å¯ä»¥ç”¨[method "
"instance_geometry_set_cast_shadows_setting]将网格设置为使用åŒé¢é˜´å½±ã€‚相当于"
"[member Light.shadow_reverse_cull_face]。"
@@ -87400,13 +87965,14 @@ msgid ""
"If [code]true[/code], light will cast shadows. Equivalent to [member Light."
"shadow_enabled]."
msgstr ""
-"如果[code]true[/code],光线会投射阴影。相当于[member Light.shadow_enabled]。"
+"如果为 [code]true[/code],光线会投射阴影。相当于 [member Light."
+"shadow_enabled]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the color of the shadow cast by the light. Equivalent to [member Light."
"shadow_color]."
-msgstr "设置ç¯å…‰æŠ•射阴影的颜色。相当于[member Light.shadow_color]。"
+msgstr "设置ç¯å…‰æŠ•射阴影的颜色。相当于 [member Light.shadow_color]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87432,8 +87998,8 @@ msgid ""
"To place in a scene, attach this lightmap capture to an instance using "
"[method instance_set_base] using the returned RID."
msgstr ""
-"创建一个光照贴图æ•获并将其添加到VisualServer中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个"
-"RIDå¯ç”¨äºŽæ‰€æœ‰[code]lightmap_capture_*[/code] VisualServer函数。\n"
+"创建一个光照贴图æ•获并将其添加到 VisualServer 中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚è¿™"
+"个RIDå¯ç”¨äºŽæ‰€æœ‰[code]lightmap_capture_*[/code] VisualServer函数。\n"
"一旦完æˆäº†RID处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放RID。\n"
"è¦åœ¨åœºæ™¯ä¸­æ”¾ç½®ï¼Œä½¿ç”¨è¿”回的RID,用[method instance_set_base]将这个lightmap "
"capture附加到一个实例上。"
@@ -87475,7 +88041,7 @@ msgid ""
"Sets the energy multiplier for this lightmap capture. Equivalent to [member "
"BakedLightmapData.energy]."
msgstr ""
-"设置此光照贴图æ•获的能é‡ä¹˜æ•°ã€‚相当于[member BakedLightmapData.energy]。"
+"设置此光照贴图æ•获的能é‡ä¹˜æ•°ã€‚相当于 [member BakedLightmapData.energy]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87492,14 +88058,14 @@ msgid ""
"BakedLightmapData.octree]."
msgstr ""
"设置此光照贴图æ•获è¦ä½¿ç”¨çš„八剿 ‘。该函数通常由 [BakedLightmap] 节点使用。相当"
-"于[member BakedLightmapData.octree]。"
+"于 [member BakedLightmapData.octree]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the subdivision level of this lightmap capture's octree. Equivalent to "
"[member BakedLightmapData.cell_subdiv]."
msgstr ""
-"设置此光照贴图æ•èŽ·å…«å‰æ ‘的细分级别。相当于[member BakedLightmapData."
+"设置此光照贴图æ•èŽ·å…«å‰æ ‘的细分级别。相当于 [member BakedLightmapData."
"cell_subdiv]。"
#: doc/classes/VisualServer.xml
@@ -87507,7 +88073,7 @@ msgid ""
"Sets the octree cell transform for this lightmap capture's octree. "
"Equivalent to [member BakedLightmapData.cell_space_transform]."
msgstr ""
-"设置此光照贴图æ•èŽ·çš„å…«å‰æ ‘çš„å…«å‰æ ‘å•å…ƒå˜æ¢ã€‚相当于[member BakedLightmapData."
+"设置此光照贴图æ•èŽ·çš„å…«å‰æ ‘çš„å…«å‰æ ‘å•å…ƒå˜æ¢ã€‚相当于 [member BakedLightmapData."
"cell_space_transform]。"
#: doc/classes/VisualServer.xml
@@ -87716,22 +88282,20 @@ msgstr ""
msgid ""
"Calculates and returns the axis-aligned bounding box that encloses all "
"instances within the multimesh."
-msgstr ""
-"计算并返回轴对é½çš„边界框(包围盒),该边界框(包围盒)将所有的实例都包å«åœ¨"
-"multimesh中。"
+msgstr "计算并返回轴对é½çš„包围盒,该包围盒将所有的实例都包å«åœ¨ multimesh 中。"
#: doc/classes/VisualServer.xml
msgid "Returns the number of instances allocated for this multimesh."
-msgstr "返回分é…给这个multimesh的实例的数é‡ã€‚"
+msgstr "返回分é…给这个 multimesh 的实例的数é‡ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"Returns the RID of the mesh that will be used in drawing this multimesh."
-msgstr "返回用于绘制此multimesh的RID。"
+msgstr "返回用于绘制此 multimesh 的 RID。"
#: doc/classes/VisualServer.xml
msgid "Returns the number of visible instances for this multimesh."
-msgstr "返回此multimeshçš„å¯è§å®žä¾‹æ•°ã€‚"
+msgstr "返回此 multimesh çš„å¯è§å®žä¾‹æ•°ã€‚"
#: doc/classes/VisualServer.xml
msgid "Returns the color by which the specified instance will be modulated."
@@ -87743,19 +88307,20 @@ msgstr "返回与指定实例相关的自定义数æ®ã€‚"
#: doc/classes/VisualServer.xml
msgid "Returns the [Transform] of the specified instance."
-msgstr "返回指定实例的[Transform]。"
+msgstr "返回指定实例的 [Transform]。"
#: doc/classes/VisualServer.xml
msgid ""
"Returns the [Transform2D] of the specified instance. For use when the "
"multimesh is set to use 2D transforms."
-msgstr "返回指定实例的 [Transform2D]。åªåœ¨multimesh设置为使用 2D å˜æ¢æ—¶ä½¿ç”¨ã€‚"
+msgstr ""
+"返回指定实例的 [Transform2D]。åªåœ¨ multimesh 设置为使用 2D å˜æ¢æ—¶ä½¿ç”¨ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the color by which this instance will be modulated. Equivalent to "
"[method MultiMesh.set_instance_color]."
-msgstr "设置这个实例的调制颜色。等åŒäºŽ[method MultiMesh.set_instance_color]。"
+msgstr "设置这个实例的调制颜色。相当于 [method MultiMesh.set_instance_color]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87763,22 +88328,22 @@ msgid ""
"but is interpreted as a [code]vec4[/code] in the shader. Equivalent to "
"[method MultiMesh.set_instance_custom_data]."
msgstr ""
-"为这个实例设置自定义数æ®ã€‚自定义数æ®ä»¥[Color]的形å¼ä¼ é€’,但在ç€è‰²å™¨ä¸­ä¼šè¢«è§£é‡Š"
-"为[code]vec4[/code]。等åŒäºŽ[method MultiMesh.set_instance_custom_data]。"
+"为这个实例设置自定义数æ®ã€‚自定义数æ®ä»¥ [Color] 的形å¼ä¼ é€’,但在ç€è‰²å™¨ä¸­ä¼šè¢«è§£"
+"释为 [code]vec4[/code]。相当于 [method MultiMesh.set_instance_custom_data]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the [Transform] for this instance. Equivalent to [method MultiMesh."
"set_instance_transform]."
msgstr ""
-"设置此实例的 [Transform]。相当于[method MultiMesh.set_instance_transform]。"
+"设置此实例的 [Transform]。相当于 [method MultiMesh.set_instance_transform]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the [Transform2D] for this instance. For use when multimesh is used in "
"2D. Equivalent to [method MultiMesh.set_instance_transform_2d]."
msgstr ""
-"为此实例设置 [Transform2D]。用于在 2D 中使用multimesh时。相当于[method "
+"为此实例设置 [Transform2D]。用于在 2D 中使用 multimesh 时。相当于 [method "
"MultiMesh.set_instance_transform_2d]。"
#: doc/classes/VisualServer.xml
@@ -87810,7 +88375,7 @@ msgstr ""
msgid ""
"Sets the mesh to be drawn by the multimesh. Equivalent to [member MultiMesh."
"mesh]."
-msgstr "设置Multimesh所è¦ç»˜åˆ¶çš„网格。等åŒäºŽ [member MultiMesh.mesh]。"
+msgstr "设置 Multimesh 所è¦ç»˜åˆ¶çš„网格。相当于 [member MultiMesh.mesh]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87818,8 +88383,8 @@ msgid ""
"that have been allocated are drawn. Equivalent to [member MultiMesh."
"visible_instance_count]."
msgstr ""
-"设置在给定时间内å¯è§çš„实例的数é‡ã€‚如果是-1,所有被分é…的实例都会被画出æ¥ã€‚ç­‰"
-"åŒäºŽ[member MultiMesh.visible_instance_count]。"
+"设置在给定时间内å¯è§çš„实例的数é‡ã€‚如果是 -1,所有被分é…的实例都会被画出æ¥ã€‚相"
+"当于 [member MultiMesh.visible_instance_count]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87859,7 +88424,8 @@ msgid ""
"Calculates and returns the axis-aligned bounding box that contains all the "
"particles. Equivalent to [method Particles.capture_aabb]."
msgstr ""
-"è®¡ç®—å¹¶è¿”å›žåŒ…å«æ‰€æœ‰ç²’å­çš„轴对é½è¾¹ç•Œæ¡†ã€‚相当于[method Particles.capture_aabb]。"
+"è®¡ç®—å¹¶è¿”å›žåŒ…å«æ‰€æœ‰ç²’å­çš„轴对é½è¾¹ç•Œæ¡†ã€‚相当于 [method Particles."
+"capture_aabb]。"
#: doc/classes/VisualServer.xml
msgid "Returns [code]true[/code] if particles are currently set to emitting."
@@ -87886,14 +88452,14 @@ msgstr ""
msgid ""
"Reset the particles on the next update. Equivalent to [method Particles."
"restart]."
-msgstr "在下次更新时é‡ç½®ç²’å­ã€‚相当于[method Particles.restart]。"
+msgstr "在下次更新时é‡ç½®ç²’å­ã€‚相当于 [method Particles.restart]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the number of particles to be drawn and allocates the memory for them. "
"Equivalent to [member Particles.amount]."
msgstr ""
-"设置è¦ç»˜åˆ¶çš„ç²’å­çš„æ•°é‡ï¼Œå¹¶ä¸ºå…¶åˆ†é…内存。相当于[member Particles.amount]。"
+"设置è¦ç»˜åˆ¶çš„ç²’å­çš„æ•°é‡ï¼Œå¹¶ä¸ºå…¶åˆ†é…内存。相当于 [member Particles.amount]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87938,8 +88504,8 @@ msgid ""
"not reset the particles, but only stops their emission. Equivalent to "
"[member Particles.emitting]."
msgstr ""
-"如果[code]true[/code],粒å­ä¼šéšç€æ—¶é—´çš„æŽ¨ç§»è€Œå‘射出æ¥ã€‚设置为falseä¸ä¼šé‡ç½®ç²’"
-"å­ï¼Œè€Œåªæ˜¯åœæ­¢å…¶å‘射。相当于[member Particles.emitting]。"
+"如果为 [code]true[/code],粒å­ä¼šéšç€æ—¶é—´çš„æŽ¨ç§»è€Œå‘射出æ¥ã€‚设置为falseä¸ä¼šé‡ç½®"
+"ç²’å­ï¼Œè€Œåªæ˜¯åœæ­¢å…¶å‘射。相当于[member Particles.emitting]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -87957,7 +88523,7 @@ msgid ""
"If [code]true[/code], uses fractional delta which smooths the movement of "
"the particles. Equivalent to [member Particles.fract_delta]."
msgstr ""
-"如果 [code]true[/code]ï¼Œåˆ™ä½¿ç”¨åˆ†æ•°å¢žé‡æ¥å¹³æ»‘ç²’å­çš„è¿åŠ¨ã€‚ç›¸å½“äºŽ [member "
+"如果为 [code]true[/code]ï¼Œåˆ™ä½¿ç”¨åˆ†æ•°å¢žé‡æ¥å¹³æ»‘ç²’å­çš„è¿åŠ¨ã€‚ç›¸å½“äºŽ [member "
"Particles.fract_delta]。"
#: doc/classes/VisualServer.xml
@@ -87971,7 +88537,7 @@ msgid ""
"If [code]true[/code], particles will emit once and then stop. Equivalent to "
"[member Particles.one_shot]."
msgstr ""
-"如果 [code]true[/code],粒å­å°†å‘射一次然åŽåœæ­¢ã€‚相当于 [member Particles."
+"如果为 [code]true[/code],粒å­å°†å‘射一次然åŽåœæ­¢ã€‚相当于 [member Particles."
"one_shot]。"
#: doc/classes/VisualServer.xml
@@ -88012,8 +88578,8 @@ msgid ""
"If [code]true[/code], particles use local coordinates. If [code]false[/code] "
"they use global coordinates. Equivalent to [member Particles.local_coords]."
msgstr ""
-"如果 [code]true[/code],粒å­ä½¿ç”¨å±€éƒ¨å标。如果 [code]false[/code] 其使用全局"
-"åæ ‡ã€‚相当于 [member Particles.local_coords]。"
+"如果为 [code]true[/code],粒å­ä½¿ç”¨å±€éƒ¨å标。如果 [code]false[/code] 其使用全"
+"局忠‡ã€‚相当于 [member Particles.local_coords]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88025,8 +88591,8 @@ msgid ""
"To place in a scene, attach this reflection probe to an instance using "
"[method instance_set_base] using the returned RID."
msgstr ""
-"创建一个å射探针并将其添加到VisualServer中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RID"
-"å¯ç”¨äºŽæ‰€æœ‰[code]reflection_probe_*[/code] VisualServer函数。\n"
+"创建一个å射探针并将其添加到 VisualServer 中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个"
+"RIDå¯ç”¨äºŽæ‰€æœ‰[code]reflection_probe_*[/code] VisualServer函数。\n"
"一旦完æˆäº†RID处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放RID。\n"
"è¦åœ¨åœºæ™¯ä¸­æ”¾ç½®ï¼Œä½¿ç”¨è¿”回的RID,用[method instance_set_base]将这个å射探针附加"
"到一个实例上。"
@@ -88036,8 +88602,8 @@ msgid ""
"If [code]true[/code], reflections will ignore sky contribution. Equivalent "
"to [member ReflectionProbe.interior_enable]."
msgstr ""
-"如果 [code]true[/code],å射将忽略天空的贡献。相当于 [member ReflectionProbe."
-"interior_enable]。"
+"如果为 [code]true[/code],å射将忽略天空的贡献。相当于 [member "
+"ReflectionProbe.interior_enable]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88045,8 +88611,8 @@ msgid ""
"matching cull mask will be rendered by this probe. Equivalent to [member "
"ReflectionProbe.cull_mask]."
msgstr ""
-"为这个å射探针设置渲染é®è”½ã€‚åªæœ‰å…·æœ‰åŒ¹é…çš„é®è”½ç½©çš„实例æ‰ä¼šè¢«è¿™ä¸ªæŽ¢é’ˆæ¸²æŸ“。等"
-"åŒäºŽ[member ReflectionProbe.cull_mask]。"
+"为这个å射探针设置渲染é®è”½ã€‚åªæœ‰å…·æœ‰åŒ¹é…çš„é®è”½ç½©çš„实例æ‰ä¼šè¢«è¿™ä¸ªæŽ¢é’ˆæ¸²æŸ“。相"
+"当于 [member ReflectionProbe.cull_mask]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88054,7 +88620,7 @@ msgid ""
"more correct in certain situations. Equivalent to [member ReflectionProbe."
"box_projection]."
msgstr ""
-"如果 [code]true[/code],则使用箱体投影。这å¯ä»¥ä½¿å射在æŸäº›æƒ…å†µä¸‹çœ‹èµ·æ¥æ›´æ­£"
+"如果为 [code]true[/code],则使用箱体投影。这å¯ä»¥ä½¿å射在æŸäº›æƒ…å†µä¸‹çœ‹èµ·æ¥æ›´æ­£"
"确。相当于 [member ReflectionProbe.box_projection]。"
#: doc/classes/VisualServer.xml
@@ -88063,22 +88629,22 @@ msgid ""
"the reflection much slower to compute. Equivalent to [member ReflectionProbe."
"enable_shadows]."
msgstr ""
-"如果 [code]true[/code],计算å射探针中的阴影。这会使得å射的计算速度慢得多。"
-"相当于 [member ReflectionProbe.enable_shadows]。"
+"如果为 [code]true[/code],计算å射探针中的阴影。这会使得å射的计算速度慢得"
+"多。相当于 [member ReflectionProbe.enable_shadows]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the size of the area that the reflection probe will capture. Equivalent "
"to [member ReflectionProbe.extents]."
msgstr ""
-"设置å射探针将æ•获的区域的大å°ã€‚等效于 [member ReflectionProbe.extents]。"
+"设置å射探针将æ•获的区域的大å°ã€‚相当于 [member ReflectionProbe.extents]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the intensity of the reflection probe. Intensity modulates the strength "
"of the reflection. Equivalent to [member ReflectionProbe.intensity]."
msgstr ""
-"设置å射探针的强度。强度调节å射的强度。等效于 [member ReflectionProbe."
+"设置å射探针的强度。强度调节å射的强度。相当于 [member ReflectionProbe."
"intensity]。"
#: doc/classes/VisualServer.xml
@@ -88086,7 +88652,7 @@ msgid ""
"Sets the ambient light color for this reflection probe when set to interior "
"mode. Equivalent to [member ReflectionProbe.interior_ambient_color]."
msgstr ""
-"è®¾ç½®ä¸ºå†…éƒ¨æ¨¡å¼æ—¶ï¼Œä¸ºæ­¤å射探针设置环境光颜色。相当于[member ReflectionProbe."
+"è®¾ç½®ä¸ºå†…éƒ¨æ¨¡å¼æ—¶ï¼Œä¸ºæ­¤å射探针设置环境光颜色。相当于 [member ReflectionProbe."
"interior_ambient_color]。"
#: doc/classes/VisualServer.xml
@@ -88095,7 +88661,7 @@ msgid ""
"contribution when set to interior mode. Equivalent to [member "
"ReflectionProbe.interior_ambient_energy]."
msgstr ""
-"å½“è®¾ç½®ä¸ºå†…éƒ¨æ¨¡å¼æ—¶ï¼Œè®¾ç½®æ­¤å射探针环境光贡献的能é‡ä¹˜æ•°ã€‚相当于[member "
+"å½“è®¾ç½®ä¸ºå†…éƒ¨æ¨¡å¼æ—¶ï¼Œè®¾ç½®æ­¤å射探针环境光贡献的能é‡ä¹˜æ•°ã€‚相当于 [member "
"ReflectionProbe.interior_ambient_energy]。"
#: doc/classes/VisualServer.xml
@@ -88114,7 +88680,7 @@ msgid ""
"Sets the max distance away from the probe an object can be before it is "
"culled. Equivalent to [member ReflectionProbe.max_distance]."
msgstr ""
-"设置物体在被删除å‰ä¸ŽæŽ¢é’ˆçš„æœ€å¤§è·ç¦»ã€‚ç­‰åŒäºŽ[member ReflectionProbe."
+"设置物体在被删除å‰ä¸ŽæŽ¢é’ˆçš„æœ€å¤§è·ç¦»ã€‚相当于 [member ReflectionProbe."
"max_distance]。"
#: doc/classes/VisualServer.xml
@@ -88122,7 +88688,7 @@ msgid ""
"Sets the origin offset to be used when this reflection probe is in box "
"project mode. Equivalent to [member ReflectionProbe.origin_offset]."
msgstr ""
-"设置当此åå°„æŽ¢é’ˆå¤„äºŽæ¡†é¡¹ç›®æ¨¡å¼æ—¶è¦ä½¿ç”¨çš„æºå移。相当于[member "
+"设置当此åå°„æŽ¢é’ˆå¤„äºŽæ¡†é¡¹ç›®æ¨¡å¼æ—¶è¦ä½¿ç”¨çš„æºå移。相当于 [member "
"ReflectionProbe.origin_offset]。"
#: doc/classes/VisualServer.xml
@@ -88130,8 +88696,8 @@ msgid ""
"Sets how often the reflection probe updates. Can either be once or every "
"frame. See [enum ReflectionProbeUpdateMode] for options."
msgstr ""
-"设置å射探针的更新频率。å¯ä»¥æ˜¯ä¸€æ¬¡ï¼Œä¹Ÿå¯ä»¥æ˜¯æ¯ä¸€å¸§ã€‚å‚阅[enum "
-"ReflectionProbeUpdateMode]选项。"
+"设置å射探针的更新频率。å¯ä»¥æ˜¯ä¸€æ¬¡ï¼Œä¹Ÿå¯ä»¥æ˜¯æ¯ä¸€å¸§ã€‚å‚阅 [enum "
+"ReflectionProbeUpdateMode] 选项。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88140,9 +88706,9 @@ msgid ""
"The callback method must use only 1 argument which will be called with "
"[code]userdata[/code]."
msgstr ""
-"在画完一帧åŽï¼Œåœ¨[code]where[/code]上安排一个回调给相应的命åçš„[code]method[/"
-"code]。\n"
-"回调方法必须åªä½¿ç”¨1ä¸ªå‚æ•°ï¼Œå®ƒå°†ä¸Ž[code]userdata[/code]一起被调用。"
+"在画完一帧åŽï¼Œåœ¨ [code]where[/code] 上安排一个回调给相应的命åçš„ "
+"[code]method[/code]。\n"
+"回调方法必须åªä½¿ç”¨ 1 ä¸ªå‚æ•°ï¼Œå®ƒå°†ä¸Ž [code]userdata[/code] 一起被调用。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88153,17 +88719,17 @@ msgid ""
"VisualServer's [method free_rid] static method.\n"
"The scenario is the 3D world that all the visual instances exist in."
msgstr ""
-"创建一个场景并将其添加到VisualServer中。它å¯ä»¥é€šè¿‡è¿”回的RID进行访问。这个RID"
-"å¯åœ¨æ‰€æœ‰[code]scenario_*[/code]VisualServer函数中使用。\n"
-"一旦完æˆäº†å¯¹RID的处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放"
-"RID。\n"
-"场景是所有视觉实例所存在的三维世界。"
+"创建一个场景并将其添加到 VisualServer 中。它å¯ä»¥é€šè¿‡è¿”回的 RID 进行访问。这"
+"个 RID å¯åœ¨æ‰€æœ‰ [code]scenario_*[/code] VisualServer 函数中使用。\n"
+"一旦完æˆäº†å¯¹ RID 的处ç†ï¼Œå¯ä½¿ç”¨ VisualServer çš„ [method free_rid] 陿€æ–¹æ³•释"
+"放 RID。\n"
+"场景是所有视觉实例所存在的 3D 世界。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the [enum ScenarioDebugMode] for this scenario. See [enum "
"ScenarioDebugMode] for options."
-msgstr "设置该场景的[enum ScenarioDebugMode]。"
+msgstr "设置该场景的 [enum ScenarioDebugMode]。"
#: doc/classes/VisualServer.xml
msgid "Sets the environment that will be used with this scenario."
@@ -88192,16 +88758,16 @@ msgid ""
"with linear interpolation. If [code]use_filter[/code] is [code]false[/code], "
"the image will be scaled with nearest-neighbor interpolation."
msgstr ""
-"设置一个å¯åЍ图åƒã€‚颜色定义了背景颜色。如果[code]scale[/code]是[code]true[/"
-"code],图åƒå°†è¢«ç¼©æ”¾ä»¥é€‚应å±å¹•尺寸。如果[code]use_filter[/code]是[code]true[/"
-"code],图åƒå°†ä»¥çº¿æ€§æ’值进行缩放。如果[code]use_filter[/code]是[code]false[/"
-"code],图åƒå°†ä»¥è¿‘é‚»æ’值的方å¼ç¼©æ”¾ã€‚"
+"设置一个å¯åЍ图åƒã€‚颜色定义了背景颜色。如果 [code]scale[/code] 是 [code]true[/"
+"code],图åƒå°†è¢«ç¼©æ”¾ä»¥é€‚应å±å¹•尺寸。如果 [code]use_filter[/code] 是 "
+"[code]true[/code],图åƒå°†ä»¥çº¿æ€§æ’值进行缩放。如果 [code]use_filter[/code] 是 "
+"[code]false[/code],图åƒå°†ä»¥è¿‘é‚»æ’值的方å¼ç¼©æ”¾ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"If [code]true[/code], the engine will generate wireframes for use with the "
"wireframe debug mode."
-msgstr "如果 [code]true[/code],引擎将生æˆç”¨äºŽçº¿æ¡†è°ƒè¯•模å¼çš„线框。"
+msgstr "如果为 [code]true[/code],引擎将生æˆç”¨äºŽçº¿æ¡†è°ƒè¯•模å¼çš„线框。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88233,8 +88799,8 @@ msgid ""
"count the real time as it goes by, without narrowing or stretching it."
msgstr ""
"设置应用于ç€è‰²å™¨ [code]TIME[/code] 内置时间æµé€çš„æ¯”例。\n"
-"默认值是[code]1.0[/code],表示[code]TIME[/code]会éšç€æ—¶é—´çš„æŽ¨ç§»è®¡ç®—实时时间,"
-"ä¸ä¼šç¼©å°æˆ–拉伸它。"
+"默认值是 [code]1.0[/code],表示 [code]TIME[/code] 会éšç€æ—¶é—´çš„æŽ¨ç§»è®¡ç®—实时时"
+"间,ä¸ä¼šç¼©å°æˆ–拉伸它。"
#: doc/classes/VisualServer.xml
msgid "Enables or disables occlusion culling."
@@ -88317,8 +88883,8 @@ msgid ""
"Once finished with your RID, you will want to free the RID using the "
"VisualServer's [method free_rid] static method."
msgstr ""
-"创建一个空的天空并将其添加到VisualServer中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RID"
-"å¯ç”¨äºŽæ‰€æœ‰[code]sky_*[/code] VisualServer函数。\n"
+"创建一个空的天空并将其添加到 VisualServer 中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个"
+"RIDå¯ç”¨äºŽæ‰€æœ‰[code]sky_*[/code] VisualServer函数。\n"
"一旦完æˆäº†å¯¹RID的处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放RID。"
#: doc/classes/VisualServer.xml
@@ -88358,8 +88924,8 @@ msgid ""
"Once finished with your RID, you will want to free the RID using the "
"VisualServer's [method free_rid] static method."
msgstr ""
-"创建一个空纹ç†å¹¶å°†å…¶æ·»åŠ åˆ°VisualServer中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RIDå¯"
-"用于所有[code]texture_*[/code] VisualServer函数中。\n"
+"创建一个空纹ç†å¹¶å°†å…¶æ·»åŠ åˆ° VisualServer 中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RID"
+"å¯ç”¨äºŽæ‰€æœ‰[code]texture_*[/code] VisualServer函数中。\n"
"一旦完æˆäº†å¯¹RID的处ç†ï¼Œå¯ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放RID。"
#: doc/classes/VisualServer.xml
@@ -88385,7 +88951,7 @@ msgstr "返回纹ç†çš„æ·±åº¦ã€‚"
#: doc/classes/VisualServer.xml
msgid "Returns the flags of a texture."
-msgstr "返回一个纹ç†çš„æ ‡å¿—flags。"
+msgstr "返回纹ç†çš„æ ‡å¿—。"
#: doc/classes/VisualServer.xml
msgid "Returns the format of the texture's image."
@@ -88405,7 +88971,7 @@ msgstr "返回纹ç†å›¾åƒçš„opengl id。"
#: doc/classes/VisualServer.xml
msgid "Returns the type of the texture, can be any of the [enum TextureType]."
-msgstr "返回纹ç†çš„类型,å¯ä»¥æ˜¯[enum TextureType]中的任何一ç§ã€‚"
+msgstr "返回纹ç†çš„类型,å¯ä»¥æ˜¯ [enum TextureType] 中的任何一ç§ã€‚"
#: doc/classes/VisualServer.xml
msgid "Returns the texture's width."
@@ -88428,7 +88994,7 @@ msgstr ""
#: doc/classes/VisualServer.xml
msgid "Sets the texture's flags. See [enum TextureFlags] for options."
-msgstr "设置纹ç†çš„æ ‡å¿—flags。选项è§[enum TextureFlags]。"
+msgstr "设置纹ç†çš„æ ‡å¿—。å¯é€‰é¡¹è§ [enum TextureFlags]。"
#: doc/classes/VisualServer.xml
msgid "Sets the texture's path."
@@ -88543,8 +89109,8 @@ msgid ""
"Once finished with your RID, you will want to free the RID using the "
"VisualServer's [method free_rid] static method."
msgstr ""
-"创建一个空视窗并将其添加到VisualServer中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RIDå°†"
-"用于所有[code]viewport_*[/code] 的VisualServer函数。\n"
+"创建一个空视窗并将其添加到 VisualServer 中。å¯ä»¥ç”¨è¿”回的RIDæ¥è®¿é—®å®ƒã€‚这个RID"
+"将用于所有[code]viewport_*[/code] 的VisualServer函数。\n"
"一旦你用完了RID,你è¦ä½¿ç”¨VisualServerçš„[method free_rid]陿€æ–¹æ³•释放RID。"
#: doc/classes/VisualServer.xml
@@ -88568,7 +89134,7 @@ msgstr "从画布分离视窗,å之亦然。"
#: doc/classes/VisualServer.xml
msgid "If [code]true[/code], sets the viewport active, else sets it inactive."
msgstr ""
-"如果 [code]true[/code],则将视窗设置为活动状æ€ï¼Œå¦åˆ™å°†å…¶è®¾ç½®ä¸ºéžæ´»åŠ¨çŠ¶æ€ã€‚"
+"如果为 [code]true[/code],则将视窗设置为活动状æ€ï¼Œå¦åˆ™å°†å…¶è®¾ç½®ä¸ºéžæ´»åŠ¨çŠ¶æ€ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88577,8 +89143,8 @@ msgid ""
"specifies the stacking order of the canvas among those in the same layer."
msgstr ""
"设置视窗画布的堆å é¡ºåºã€‚\n"
-"[code]layer[/code]是实际的画布层,而[code]sublayer[/code]则指定画布在åŒä¸€å±‚中"
-"的堆å é¡ºåºã€‚"
+"[code]layer[/code] 是实际的画布层,而 [code]sublayer[/code] 则指定画布在åŒä¸€"
+"层中的堆å é¡ºåºã€‚"
#: doc/classes/VisualServer.xml
msgid "Sets the transformation of a viewport's canvas."
@@ -88587,13 +89153,13 @@ msgstr "è®¾ç½®è§†çª—ç”»å¸ƒçš„å˜æ¢ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the clear mode of a viewport. See [enum ViewportClearMode] for options."
-msgstr "设置视窗的清除模å¼ã€‚详è§[enum ViewportClearMode]。"
+msgstr "设置视窗的清除模å¼ã€‚å¯é€‰é¡¹è§ [enum ViewportClearMode]。"
#: doc/classes/VisualServer.xml
msgid ""
"Sets the debug draw mode of a viewport. See [enum ViewportDebugDraw] for "
"options."
-msgstr "设置视窗的调试绘图模å¼ã€‚详è§[enum ViewportDebugDraw]。"
+msgstr "设置视窗的调试绘图模å¼ã€‚å¯é€‰é¡¹è§ [enum ViewportDebugDraw]。"
#: doc/classes/VisualServer.xml
msgid "If [code]true[/code], a viewport's 3D rendering is disabled."
@@ -88602,7 +89168,7 @@ msgstr "如果为 [code]true[/code],则视窗的 3D 渲染将ç¦ç”¨ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"If [code]true[/code], rendering of a viewport's environment is disabled."
-msgstr "如果 [code]true[/code],则ç¦ç”¨è§†çª—环境的渲染。"
+msgstr "如果为 [code]true[/code],则ç¦ç”¨è§†çª—环境的渲染。"
#: doc/classes/VisualServer.xml
msgid "Sets the viewport's global transformation matrix."
@@ -88610,11 +89176,11 @@ msgstr "è®¾ç½®è§†çª—çš„å…¨å±€å˜æ¢çŸ©é˜µã€‚"
#: doc/classes/VisualServer.xml
msgid "If [code]true[/code], the viewport renders to hdr."
-msgstr "如果 [code]true[/code],视窗将呈现为 hdr。"
+msgstr "如果为 [code]true[/code],视窗将呈现为 hdr。"
#: doc/classes/VisualServer.xml
msgid "If [code]true[/code], the viewport's canvas is not rendered."
-msgstr "如果 [code]true[/code]ï¼Œåˆ™ä¸æ¸²æŸ“视窗的画布。"
+msgstr "如果为 [code]true[/code]ï¼Œåˆ™ä¸æ¸²æŸ“视窗的画布。"
#: doc/classes/VisualServer.xml
msgid "Currently unimplemented in Godot 3.x."
@@ -88622,7 +89188,7 @@ msgstr "ç›®å‰åœ¨ Godot 3.x 中未实现。"
#: doc/classes/VisualServer.xml
msgid "Sets the anti-aliasing mode. See [enum ViewportMSAA] for options."
-msgstr "设置抗锯齿模å¼ã€‚详è§[enum ViewportMSAA]。"
+msgstr "设置抗锯齿模å¼ã€‚å¯é€‰é¡¹è§ [enum ViewportMSAA]。"
#: doc/classes/VisualServer.xml
msgid "Sets the viewport's parent to another viewport."
@@ -88643,8 +89209,8 @@ msgid ""
"will be drawn, no automatic scaling is possible, even if your game scene is "
"significantly larger than the window size."
msgstr ""
-"如果[code]true[/code],直接将视窗的内容渲染到å±å¹•上。这å…许一个低级别的优化,"
-"ä½ å¯ä»¥è·³è¿‡ç»˜åˆ¶è§†çª—到根视窗。虽然这ç§ä¼˜åŒ–å¯ä»¥æ˜¾è‘—æé«˜é€Ÿåº¦ï¼ˆç‰¹åˆ«æ˜¯åœ¨æ—§è®¾å¤‡"
+"如果为 [code]true[/code],直接将视窗的内容渲染到å±å¹•上。这å…许一个低级别的优"
+"化,你å¯ä»¥è·³è¿‡ç»˜åˆ¶è§†çª—到根视窗。虽然这ç§ä¼˜åŒ–å¯ä»¥æ˜¾è‘—æé«˜é€Ÿåº¦ï¼ˆç‰¹åˆ«æ˜¯åœ¨æ—§è®¾å¤‡"
"上),但它是以牺牲å¯ç”¨æ€§ä¸ºä»£ä»·çš„。当å¯ç”¨è¿™ä¸ªåŠŸèƒ½æ—¶ï¼Œä½ ä¸èƒ½ä»Žè§†çª—或"
"[code]SCREEN_TEXTURE[/code]中读å–。你也会失去æŸäº›çª—å£è®¾ç½®çš„好处,比如å„ç§æ‹‰ä¼¸"
"模å¼ã€‚å¦ä¸€ä¸ªéœ€è¦æ³¨æ„çš„åŽæžœæ˜¯ï¼Œåœ¨2D中,渲染是以窗å£å标进行的,所以如果你有一"
@@ -88658,7 +89224,7 @@ msgid ""
"environment information, reflection atlas etc."
msgstr ""
"设置一个视窗的场景。\n"
-"场景包å«[enum ScenarioDebugMode]的信æ¯ã€çŽ¯å¢ƒä¿¡æ¯ã€å射图集等。"
+"åœºæ™¯åŒ…å« [enum ScenarioDebugMode] 的信æ¯ã€çŽ¯å¢ƒä¿¡æ¯ã€å射图集等。"
#: doc/classes/VisualServer.xml
msgid "Sets the shadow atlas quadrant's subdivision."
@@ -88693,13 +89259,13 @@ msgstr "设置视窗的宽度和高度。"
#: doc/classes/VisualServer.xml
msgid ""
"If [code]true[/code], the viewport renders its background as transparent."
-msgstr "如果 [code]true[/code]ï¼Œè§†çª—å°†å…¶èƒŒæ™¯æ¸²æŸ“ä¸ºé€æ˜Žã€‚"
+msgstr "如果为 [code]true[/code]ï¼Œè§†çª—å°†å…¶èƒŒæ™¯æ¸²æŸ“ä¸ºé€æ˜Žã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"Sets when the viewport should be updated. See [enum ViewportUpdateMode] "
"constants for options."
-msgstr "设置应更新视窗的时间。请å‚阅 [enum ViewportUpdateMode] 。"
+msgstr "设置应更新视窗的时间。å¯é€‰é¡¹è¯·å‚阅 [enum ViewportUpdateMode] 。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88712,7 +89278,7 @@ msgid ""
"If [code]true[/code], the viewport uses augmented or virtual reality "
"technologies. See [ARVRInterface]."
msgstr ""
-"如果 [code]true[/code],则视窗使用增强或虚拟现实技术。å‚阅 [ARVRInterface]。"
+"如果为 [code]true[/code]ï¼Œåˆ™è§†çª—ä½¿ç”¨å¢žå¼ºæˆ–è™šæ‹ŸçŽ°å®žæŠ€æœ¯ã€‚è§ [ARVRInterface]。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88739,14 +89305,14 @@ msgid ""
"recovered by enabling contrast-adaptive sharpening (see [method "
"viewport_set_sharpen_intensity])."
msgstr ""
-"å¯ç”¨è¯¥è§†çª—的快速近似抗锯齿。FXAAæ˜¯ä¸€ç§æµè¡Œçš„å±å¹•空间抗锯齿方法,它速度快,但"
-"会使图åƒçœ‹èµ·æ¥å¾ˆæ¨¡ç³Šï¼Œç‰¹åˆ«æ˜¯åœ¨ä½Žåˆ†è¾¨çŽ‡ä¸‹ã€‚åœ¨å¤§çš„åˆ†è¾¨çŽ‡ä¸‹ï¼Œå¦‚1440på’Œ4K,它ä»ç„¶"
-"å¯ä»¥å·¥ä½œå¾—比较好。一些æŸå¤±çš„é”度å¯ä»¥é€šè¿‡å¯ç”¨å¯¹æ¯”度适应性é”åŒ–æ¥æ¢å¤ï¼ˆè§"
+"å¯ç”¨è¯¥è§†çª—的快速近似抗锯齿。FXAA æ˜¯ä¸€ç§æµè¡Œçš„å±å¹•空间抗锯齿方法,它速度快,但"
+"会使图åƒçœ‹èµ·æ¥å¾ˆæ¨¡ç³Šï¼Œç‰¹åˆ«æ˜¯åœ¨ä½Žåˆ†è¾¨çŽ‡ä¸‹ã€‚åœ¨ 1440p å’Œ 4K 等高分辨率下,它ä»ç„¶"
+"å¯ä»¥å·¥ä½œå¾—比较好。一些æŸå¤±çš„é”度å¯ä»¥é€šè¿‡å¯ç”¨å¯¹æ¯”度适应性é”åŒ–æ¥æ¢å¤ï¼ˆè§ "
"[method viewport_set_sharpen_intensity])。"
#: doc/classes/VisualServer.xml
msgid "If [code]true[/code], the viewport's rendering is flipped vertically."
-msgstr "如果 [code]true[/code],则视窗的渲染垂直翻转。"
+msgstr "如果为 [code]true[/code],则视窗的渲染垂直翻转。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88754,8 +89320,8 @@ msgid ""
"is still being processed. You can call [method force_draw] to draw a frame "
"even with rendering disabled."
msgstr ""
-"如果[code]false[/code],则完全ç¦ç”¨æ¸²æŸ“,但引擎逻辑ä»åœ¨å¤„ç†ä¸­ã€‚å³ä½¿ç¦ç”¨æ¸²æŸ“,"
-"您也å¯ä»¥è°ƒç”¨ [method force_draw] æ¥ç»˜åˆ¶å¸§ã€‚"
+"如果为 [code]false[/code],则完全ç¦ç”¨æ¸²æŸ“,但引擎逻辑ä»åœ¨å¤„ç†ä¸­ã€‚å³ä½¿ç¦ç”¨æ¸²"
+"染,您也å¯ä»¥è°ƒç”¨ [method force_draw] æ¥ç»˜åˆ¶å¸§ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
@@ -88838,7 +89404,7 @@ msgstr "由六个é¢ç»„æˆçš„纹ç†ï¼Œå¯ä»¥åœ¨ç€è‰²å™¨ä¸­ä½¿ç”¨ [code]vec3[/co
#: doc/classes/VisualServer.xml
msgid "An array of 2-dimensional textures."
-msgstr "一组二维纹ç†ã€‚"
+msgstr "二维纹ç†çš„æ•°ç»„。"
#: doc/classes/VisualServer.xml
msgid "A 3-dimensional texture with width, height, and depth."
@@ -88957,10 +89523,11 @@ msgid ""
"ARRAY_COMPRESS_WEIGHTS], and [constant "
"ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION] quickly."
msgstr ""
-"用于快速设置标志[constant ARRAY_COMPRESS_NORMAL]ã€[constant "
+"用于快速设置标志 [constant ARRAY_COMPRESS_NORMAL]ã€[constant "
"ARRAY_COMPRESS_TANGENT]ã€[constant ARRAY_COMPRESS_COLOR]ã€[constant "
"ARRAY_COMPRESS_TEX_UV]ã€[constant ARRAY_COMPRESS_TEX_UV2]ã€[constant "
-"ARRAY_COMPRESS_WEIGHTS] 和[constant ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION] 。"
+"ARRAY_COMPRESS_WEIGHTS] 和 [constant "
+"ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION] 。"
#: doc/classes/VisualServer.xml
msgid "Primitive to draw consists of points."
@@ -89073,17 +89640,17 @@ msgstr "第三次拆分所å ç”¨çš„é˜´å½±å›¾é›†çš„æ¯”ä¾‹ã€‚ç¬¬å››ä¸ªæ‹†åˆ†å æ®
msgid ""
"Normal bias used to offset shadow lookup by object normal. Can be used to "
"fix self-shadowing artifacts."
-msgstr "法线å移,用于抵消物体法线的阴影查找。å¯ä»¥ç”¨æ¥ä¿®å¤è‡ªé˜´å½±çš„伪影。"
+msgstr "法线å置,用于抵消物体法线的阴影查找。å¯ä»¥ç”¨æ¥ä¿®å¤è‡ªé˜´å½±çš„伪影。"
#: doc/classes/VisualServer.xml
msgid "Bias the shadow lookup to fix self-shadowing artifacts."
-msgstr "对阴影查找进行å移,以修å¤è‡ªæˆ‘阴影的å‡è±¡ã€‚"
+msgstr "对阴影查找进行å置,以修å¤è‡ªæˆ‘阴影的å‡è±¡ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
"Increases bias on further splits to fix self-shadowing that only occurs far "
"away from the camera."
-msgstr "增加对进一步分割的å差,以修å¤ä»…在远离相机的地方å‘生的自身阴影。"
+msgstr "增加对进一步分割的å置,以修å¤ä»…在远离相机的地方å‘生的自身阴影。"
#: doc/classes/VisualServer.xml
msgid "Represents the size of the [enum LightParam] enum."
@@ -89246,7 +89813,7 @@ msgstr "在这一帧中,2d绘制所调用的数é‡ã€‚"
#: doc/classes/VisualServer.xml
msgid "Represents the size of the [enum ViewportRenderInfo] enum."
-msgstr "代表[enum ViewportRenderInfo]枚举的大å°ã€‚"
+msgstr "代表 [enum ViewportRenderInfo] 枚举的大å°ã€‚"
#: doc/classes/VisualServer.xml
msgid "Debug draw is disabled. Default setting."
@@ -89254,15 +89821,15 @@ msgstr "调试绘制被ç¦ç”¨ã€‚默认设置。"
#: doc/classes/VisualServer.xml
msgid "Debug draw sets objects to unshaded."
-msgstr "调试绘制将对象设置为无阴影。"
+msgstr "调试绘制,ä¸ä½¿ç”¨ç€è‰²æµç¨‹ç»˜åˆ¶å¯¹è±¡ã€‚"
#: doc/classes/VisualServer.xml
msgid "Overwrites clear color to [code](0,0,0,0)[/code]."
-msgstr "将清除颜色覆盖为[code](0,0,0,0)[/code]。"
+msgstr "将清除颜色覆盖为 [code](0,0,0,0)[/code]。"
#: doc/classes/VisualServer.xml
msgid "Debug draw draws objects in wireframe."
-msgstr "调试绘制 在线框中绘制对象。"
+msgstr "调试绘制,将对象用线框形å¼ç»˜åˆ¶ã€‚"
#: doc/classes/VisualServer.xml
msgid "Do not use a debug mode."
@@ -89286,7 +89853,8 @@ msgid ""
"Draw all objects without shading. Equivalent to setting all objects shaders "
"to [code]unshaded[/code]."
msgstr ""
-"绘制没有阴影的所有物体。相当于将所有物体的ç€è‰²å™¨è®¾ç½®ä¸º[code]unshaded[/code]。"
+"ä¸ä½¿ç”¨ç€è‰²æµç¨‹ç»˜åˆ¶å¯¹è±¡ã€‚相当于将所有物体的ç€è‰²å™¨è®¾ç½®ä¸º [code]unshaded[/"
+"code]。"
#: doc/classes/VisualServer.xml
msgid "The instance does not have a type."
@@ -89326,7 +89894,7 @@ msgstr "该实例是一个光照贴图æ•获。"
#: doc/classes/VisualServer.xml
msgid "Represents the size of the [enum InstanceType] enum."
-msgstr "代表[enum InstanceType]枚举的大å°ã€‚"
+msgstr "代表 [enum InstanceType] 枚举的大å°ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
@@ -89344,7 +89912,7 @@ msgstr "当设置时,手动请求在下一帧绘制几何图形。"
#: doc/classes/VisualServer.xml
msgid "Represents the size of the [enum InstanceFlags] enum."
-msgstr "代表[enum InstanceFlags]枚举的大å°ã€‚"
+msgstr "代表 [enum InstanceFlags] 枚举的大å°ã€‚"
#: doc/classes/VisualServer.xml
msgid "Disable shadows from this instance."
@@ -89372,13 +89940,13 @@ msgstr "ä¹å®«æ ¼åœ¨éœ€è¦çš„地方被拉伸。"
#: doc/classes/VisualServer.xml
msgid "The nine patch gets filled with tiles where needed."
-msgstr "ä¹å®«æ ¼åœ¨éœ€è¦çš„地方填充瓷砖。"
+msgstr "ä¹å®«æ ¼åœ¨éœ€è¦çš„地方填充图å—。"
#: doc/classes/VisualServer.xml
msgid ""
"The nine patch gets filled with tiles where needed and stretches them a bit "
"if needed."
-msgstr "ä¹å®«æ ¼åœ¨éœ€è¦çš„åœ°æ–¹å¡«å……ç“·ç –ï¼Œå¹¶åœ¨éœ€è¦æ—¶å°†å®ƒä»¬æ‹‰ä¼¸ä¸€ç‚¹ã€‚"
+msgstr "ä¹å®«æ ¼åœ¨éœ€è¦çš„地方填充图å—ï¼Œå¹¶åœ¨éœ€è¦æ—¶å°†å®ƒä»¬æ‹‰ä¼¸ä¸€ç‚¹ã€‚"
#: doc/classes/VisualServer.xml
msgid "Adds light color additive to the canvas."
@@ -89402,23 +89970,23 @@ msgstr "ä¸è¦å¯¹ç”»å¸ƒä¸Šçš„光影应用滤镜。"
#: doc/classes/VisualServer.xml
msgid "Use PCF3 filtering to filter canvas light shadows."
-msgstr "使用PCF3过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
+msgstr "使用 PCF3 过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
#: doc/classes/VisualServer.xml
msgid "Use PCF5 filtering to filter canvas light shadows."
-msgstr "使用PCF5过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
+msgstr "使用 PCF5 过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
#: doc/classes/VisualServer.xml
msgid "Use PCF7 filtering to filter canvas light shadows."
-msgstr "使用PCF7过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
+msgstr "使用 PCF7 过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
#: doc/classes/VisualServer.xml
msgid "Use PCF9 filtering to filter canvas light shadows."
-msgstr "使用PCF9过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
+msgstr "使用 PCF9 过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
#: doc/classes/VisualServer.xml
msgid "Use PCF13 filtering to filter canvas light shadows."
-msgstr "使用PCF13过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
+msgstr "使用 PCF13 过滤法æ¥è¿‡æ»¤ç”»å¸ƒçš„光影。"
#: doc/classes/VisualServer.xml
msgid "Culling of the canvas occluder is disabled."
@@ -89481,12 +90049,12 @@ msgstr "帧中2d绘制调用数é‡ã€‚"
#: doc/classes/VisualServer.xml
msgid "Hardware supports shaders. This enum is currently unused in Godot 3.x."
-msgstr "硬件支æŒç€è‰²å™¨ã€‚这个枚举目å‰åœ¨Godot 3.x中没有使用。"
+msgstr "硬件支æŒç€è‰²å™¨ã€‚这个枚举目å‰åœ¨ Godot 3.x 中没有使用。"
#: doc/classes/VisualServer.xml
msgid ""
"Hardware supports multithreading. This enum is currently unused in Godot 3.x."
-msgstr "硬件支æŒå¤šçº¿ç¨‹ã€‚这个枚举目å‰åœ¨Godot 3.x中没有使用。"
+msgstr "硬件支æŒå¤šçº¿ç¨‹ã€‚这个枚举目å‰åœ¨ Godot 3.x 中没有使用。"
#: doc/classes/VisualServer.xml
msgid "Use [Transform2D] to store MultiMesh transform."
@@ -89570,7 +90138,7 @@ msgid ""
"Use a specified canvas layer as the background. This can be useful for "
"instantiating a 2D scene in a 3D world."
msgstr ""
-"使用一个指定的画布层作为背景。这对在三维世界中实例化一个二维场景很有用。"
+"使用一个指定的画布层作为背景。这对在 3D 世界中实例化一个 2D 场景很有用。"
#: doc/classes/VisualServer.xml
msgid ""
@@ -89822,12 +90390,12 @@ msgid ""
"Returns an [Array] containing default values for all of the input ports of "
"the node in the form [code][index0, value0, index1, value1, ...][/code]."
msgstr ""
-"返回一个包å«èŠ‚ç‚¹æ‰€æœ‰è¾“å…¥ç«¯å£é»˜è®¤å€¼çš„[Array],形å¼ä¸º[code][index0, value0, "
+"返回一个包å«èŠ‚ç‚¹æ‰€æœ‰è¾“å…¥ç«¯å£é»˜è®¤å€¼çš„ [Array],形å¼ä¸º [code][index0, value0, "
"index1, value1, ...][/code]。"
#: doc/classes/VisualShaderNode.xml
msgid "Returns the default value of the input [code]port[/code]."
-msgstr "返回输入[code]port[/code]的默认值。"
+msgstr "返回输入 [code]port[/code] 的默认值。"
#: doc/classes/VisualShaderNode.xml
msgid ""
@@ -89835,8 +90403,8 @@ msgid ""
"[index0, value0, index1, value1, ...][/code]. For example: [code][0, "
"Vector3(0, 0, 0), 1, Vector3(0, 0, 0)][/code]."
msgstr ""
-"使用[code][index0, value0, index1, value1, ...][/code]å½¢å¼çš„[Array]设置默认输"
-"入端å£å€¼ã€‚例如: [code][0, Vector3(0, 0, 0), 1, Vector3(0, 0, 0)][/code]。"
+"使用 [code][index0, value0, index1, value1, ...][/code] å½¢å¼çš„ [Array] 设置默"
+"认输入端å£å€¼ã€‚例如: [code][0, Vector3(0, 0, 0), 1, Vector3(0, 0, 0)][/code]。"
#: doc/classes/VisualShaderNode.xml
msgid "Sets the default value for the selected input [code]port[/code]."
@@ -89885,12 +90453,12 @@ msgid ""
"Sampler type. Translated to reference of sampler uniform in shader code. Can "
"only be used for input ports in non-uniform nodes."
msgstr ""
-"采样器类型。转æ¢ä¸ºç€è‰²å™¨ä»£ç ä¸­çš„采样器uniform引用。åªèƒ½ç”¨äºŽnon-uniform节点中"
-"的输入端å£ã€‚"
+"采样器类型。转æ¢ä¸ºç€è‰²å™¨ä»£ç ä¸­çš„采样器 uniform 引用。åªèƒ½ç”¨äºŽéž uniform 节点"
+"中的输入端å£ã€‚"
#: doc/classes/VisualShaderNode.xml
msgid "Represents the size of the [enum PortType] enum."
-msgstr "表示[enum PortType]枚举的大å°ã€‚"
+msgstr "表示 [enum PortType] 枚举的大å°ã€‚"
#: doc/classes/VisualShaderNodeBooleanConstant.xml
msgid "A boolean constant to be used within the visual shader graph."
@@ -89902,19 +90470,19 @@ msgid ""
"Translated to [code]bool[/code] in the shader language."
msgstr ""
"åªæœ‰ä¸€ä¸ªè¾“出端å£ï¼Œæ²¡æœ‰è¾“入。\n"
-"在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ[code]bool[/code]。"
+"在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ [code]bool[/code]。"
#: doc/classes/VisualShaderNodeBooleanConstant.xml
msgid "A boolean constant which represents a state of this node."
-msgstr "一个布尔常é‡ï¼Œè¡¨ç¤ºè¯¥èŠ‚ç‚¹çš„çŠ¶æ€ã€‚"
+msgstr "布尔常é‡ï¼Œè¡¨ç¤ºè¯¥èŠ‚ç‚¹çš„çŠ¶æ€ã€‚"
#: doc/classes/VisualShaderNodeBooleanUniform.xml
msgid "A boolean uniform to be used within the visual shader graph."
-msgstr "一个在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„布尔uniform。"
+msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„布尔 uniform。"
#: doc/classes/VisualShaderNodeBooleanUniform.xml
msgid "Translated to [code]uniform bool[/code] in the shader language."
-msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ[code]uniform bool[/code]。"
+msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ [code]uniform bool[/code]。"
#: doc/classes/VisualShaderNodeBooleanUniform.xml
#: doc/classes/VisualShaderNodeColorUniform.xml
@@ -89934,7 +90502,7 @@ msgstr "å¯ç”¨ [member default_value]。"
#: doc/classes/VisualShaderNodeColorConstant.xml
msgid "A [Color] constant to be used within the visual shader graph."
-msgstr "一个[Color]常é‡ï¼Œåœ¨å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨ã€‚"
+msgstr "[Color] 常é‡ï¼Œåœ¨å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨ã€‚"
#: doc/classes/VisualShaderNodeColorConstant.xml
msgid ""
@@ -89947,11 +90515,11 @@ msgstr ""
#: doc/classes/VisualShaderNodeColorConstant.xml
msgid "A [Color] constant which represents a state of this node."
-msgstr "一个[Color]常é‡ï¼Œè¡¨ç¤ºè¿™ä¸ªèŠ‚ç‚¹çš„çŠ¶æ€ã€‚"
+msgstr "[Color] 常é‡ï¼Œè¡¨ç¤ºè¿™ä¸ªèŠ‚ç‚¹çš„çŠ¶æ€ã€‚"
#: doc/classes/VisualShaderNodeColorFunc.xml
msgid "A [Color] function to be used within the visual shader graph."
-msgstr "一个[Color]函数,在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨ã€‚"
+msgstr "[Color] 函数,在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨ã€‚"
#: doc/classes/VisualShaderNodeColorFunc.xml
msgid ""
@@ -89962,7 +90530,7 @@ msgstr "接å—一个 [Color] 到输入端å£ï¼Œå¹¶æ ¹æ® [member function] 对å…
#: doc/classes/VisualShaderNodeColorFunc.xml
msgid ""
"A function to be applied to the input color. See [enum Function] for options."
-msgstr "è¦åº”用于输入颜色的函数。å‚阅[enum Function]的选项。"
+msgstr "è¦åº”用于输入颜色的函数。å‚阅 [enum Function] 的选项。"
#: doc/classes/VisualShaderNodeColorFunc.xml
msgid ""
@@ -90006,7 +90574,7 @@ msgstr ""
#: doc/classes/VisualShaderNodeColorOp.xml
msgid "A [Color] operator to be used within the visual shader graph."
-msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„[Color]è¿ç®—符。"
+msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„ [Color] è¿ç®—符。"
#: doc/classes/VisualShaderNodeColorOp.xml
msgid "Applies [member operator] to two color inputs."
@@ -90015,7 +90583,7 @@ msgstr "将 [member operator] 应用于两个颜色输入。"
#: doc/classes/VisualShaderNodeColorOp.xml
msgid ""
"An operator to be applied to the inputs. See [enum Operator] for options."
-msgstr "è¦åº”用于输入的è¿ç®—符。å‚阅[enum Operator]的选项。"
+msgstr "è¦åº”用于输入的è¿ç®—符。å‚阅 [enum Operator] 的选项。"
#: doc/classes/VisualShaderNodeColorOp.xml
msgid ""
@@ -90036,7 +90604,7 @@ msgid ""
"result = abs(a - b);\n"
"[/codeblock]"
msgstr ""
-"用下é¢çš„å…¬å¼äº§ç”Ÿå·®å¼‚效果。\n"
+"用以下公å¼äº§ç”Ÿå·®å¼‚效果。\n"
"[codeblock]\n"
"result = abs(a - b);\n"
"[/codeblock]"
@@ -90048,7 +90616,7 @@ msgid ""
"result = min(a, b);\n"
"[/codeblock]"
msgstr ""
-"用以下公å¼äº§ç”Ÿå˜æš—的效果。\n"
+"用以下公å¼äº§ç”Ÿå˜æš—效果。\n"
"[codeblock]\n"
"result = min(a, b);\n"
"[/codeblock]"
@@ -90132,7 +90700,7 @@ msgid ""
"}\n"
"[/codeblock]"
msgstr ""
-"用以下公å¼äº§ç”ŸæŸ”和的光线效果。\n"
+"用以下公å¼äº§ç”ŸæŸ”光效果。\n"
"[codeblock]\n"
"for (int i = 0; i < 3; i++) {\n"
" float base = a[i];\n"
@@ -90160,7 +90728,7 @@ msgid ""
"}\n"
"[/codeblock]"
msgstr ""
-"用下é¢çš„å…¬å¼äº§ç”Ÿä¸€ä¸ªç¡¬å…‰æ•ˆæžœã€‚\n"
+"用以下公å¼äº§ç”Ÿç¡¬å…‰æ•ˆæžœã€‚\n"
"[codeblock]\n"
"for (int i = 0; i < 3; i++) {\n"
" float base = a[i];\n"
@@ -90175,11 +90743,11 @@ msgstr ""
#: doc/classes/VisualShaderNodeColorUniform.xml
msgid "A [Color] uniform to be used within the visual shader graph."
-msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„一个[Color]uniform。"
+msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„一个 [Color] uniform。"
#: doc/classes/VisualShaderNodeColorUniform.xml
msgid "Translated to [code]uniform vec4[/code] in the shader language."
-msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ[code]uniform vec4[/code]。"
+msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ [code]uniform vec4[/code]。"
#: doc/classes/VisualShaderNodeCompare.xml
msgid "A comparison function for common types within the visual shader graph."
@@ -90223,23 +90791,23 @@ msgstr "布林类型。"
#: doc/classes/VisualShaderNodeCompare.xml
msgid "A transform ([code]mat4[/code]) type."
-msgstr "å˜æ¢ç±»åž‹ï¼Œå³[code]mat4[/code]。"
+msgstr "å˜æ¢ç±»åž‹ï¼Œå³ [code]mat4[/code]。"
#: doc/classes/VisualShaderNodeCompare.xml
msgid "Comparison for equality ([code]a == b[/code])."
-msgstr "相等比较,å³[code]a == b[/code]。"
+msgstr "ç›¸ç­‰æ¯”è¾ƒï¼Œå³ [code]a == b[/code]。"
#: doc/classes/VisualShaderNodeCompare.xml
msgid "Comparison for inequality ([code]a != b[/code])."
-msgstr "ä¸ç­‰æ¯”较,å³[code]a != b[/code]。"
+msgstr "ä¸ç­‰æ¯”è¾ƒï¼Œå³ [code]a != b[/code]。"
#: doc/classes/VisualShaderNodeCompare.xml
msgid ""
"Comparison for greater than ([code]a > b[/code]). Cannot be used if [member "
"type] set to [constant CTYPE_BOOLEAN] or [constant CTYPE_TRANSFORM]."
msgstr ""
-"大于比较,å³[code]a > b[/code]。如果 [member type] 设置为 [constant "
-"CTYPE_BOOLEAN]或 [constant CTYPE_TRANSFORM]则ä¸èƒ½ä½¿ç”¨ã€‚"
+"å¤§äºŽæ¯”è¾ƒï¼Œå³ [code]a > b[/code]。如果 [member type] 设置为 [constant "
+"CTYPE_BOOLEAN] 或 [constant CTYPE_TRANSFORM] 则ä¸èƒ½ä½¿ç”¨ã€‚"
#: doc/classes/VisualShaderNodeCompare.xml
msgid ""
@@ -90247,24 +90815,24 @@ msgid ""
"if [member type] set to [constant CTYPE_BOOLEAN] or [constant "
"CTYPE_TRANSFORM]."
msgstr ""
-"大于或等于的比较,å³[code]a >= b[/code]。如果[member type]设置为 [constant "
-"CTYPE_BOOLEAN] 或[constant CTYPE_TRANSFORM]则ä¸èƒ½ä½¿ç”¨ã€‚"
+"å¤§äºŽæˆ–ç­‰äºŽçš„æ¯”è¾ƒï¼Œå³ [code]a >= b[/code]。如果 [member type] 设置为 "
+"[constant CTYPE_BOOLEAN] 或 [constant CTYPE_TRANSFORM] 则ä¸èƒ½ä½¿ç”¨ã€‚"
#: doc/classes/VisualShaderNodeCompare.xml
msgid ""
"Comparison for less than ([code]a < b[/code]). Cannot be used if [member "
"type] set to [constant CTYPE_BOOLEAN] or [constant CTYPE_TRANSFORM]."
msgstr ""
-"å°äºŽæ¯”较,å³[code]a < b[/code]。如果 [member type] 设置为[constant "
-"CTYPE_BOOLEAN]或 [constant CTYPE_TRANSFORM]则ä¸èƒ½ä½¿ç”¨ã€‚"
+"å°äºŽæ¯”è¾ƒï¼Œå³ [code]a < b[/code]。如果 [member type] 设置为 [constant "
+"CTYPE_BOOLEAN] 或 [constant CTYPE_TRANSFORM] 则ä¸èƒ½ä½¿ç”¨ã€‚"
#: doc/classes/VisualShaderNodeCompare.xml
msgid ""
"Comparison for less than or equal ([code]a < b[/code]). Cannot be used if "
"[member type] set to [constant CTYPE_BOOLEAN] or [constant CTYPE_TRANSFORM]."
msgstr ""
-"å°äºŽæˆ–等于的比较,å³[code]a < b[/code]。如果[member type] 设置为[constant "
-"CTYPE_BOOLEAN]或[constant CTYPE_TRANSFORM]则ä¸èƒ½ä½¿ç”¨ã€‚"
+"å°äºŽæˆ–ç­‰äºŽçš„æ¯”è¾ƒï¼Œå³ [code]a < b[/code]。如果 [member type] 设置为 [constant "
+"CTYPE_BOOLEAN] 或 [constant CTYPE_TRANSFORM] 则ä¸èƒ½ä½¿ç”¨ã€‚"
#: doc/classes/VisualShaderNodeCompare.xml
msgid ""
@@ -90280,7 +90848,7 @@ msgstr "如果å‘é‡ä¸­çš„ä»»æ„åˆ†é‡æ»¡è¶³æ¯”较æ¡ä»¶ï¼Œåˆ™ç»“果为真。"
#: doc/classes/VisualShaderNodeCubeMap.xml
msgid "A [CubeMap] sampling node to be used within the visual shader graph."
-msgstr "[CubeMap]采样节点,在å¯è§†åŒ–ç€è‰²å™¨å›¾å½¢ä¸­ä½¿ç”¨ã€‚"
+msgstr "[CubeMap] 采样节点,在å¯è§†åŒ–ç€è‰²å™¨å›¾å½¢ä¸­ä½¿ç”¨ã€‚"
#: doc/classes/VisualShaderNodeCubeMap.xml
msgid ""
@@ -90295,8 +90863,8 @@ msgid ""
"The [CubeMap] texture to sample when using [constant SOURCE_TEXTURE] as "
"[member source]."
msgstr ""
-"当使用[constant SOURCE_TEXTURE]作为 [member source] 时,è¦é‡‡æ ·çš„[CubeMap]纹"
-"ç†ã€‚"
+"当使用 [constant SOURCE_TEXTURE] 作为 [member source] 时,è¦é‡‡æ ·çš„ [CubeMap] "
+"纹ç†ã€‚"
#: doc/classes/VisualShaderNodeCubeMap.xml
msgid ""
@@ -90341,7 +90909,8 @@ msgid ""
"Adds [code]hint_albedo[/code] as hint to the uniform declaration for proper "
"sRGB to linear conversion."
msgstr ""
-"å°†[code]hint_albedo[/code]作为æç¤ºæ·»åŠ åˆ°uniform声明中,以便将sRGB转æ¢ä¸ºçº¿æ€§ã€‚"
+"å°† [code]hint_albedo[/code] 作为æç¤ºæ·»åŠ åˆ° uniform 声明中,以便将 sRGB 转æ¢ä¸º"
+"线性。"
#: doc/classes/VisualShaderNodeCubeMap.xml
#: doc/classes/VisualShaderNodeTexture.xml
@@ -90350,8 +90919,8 @@ msgid ""
"Adds [code]hint_normal[/code] as hint to the uniform declaration, which "
"internally converts the texture for proper usage as normal map."
msgstr ""
-"å°†[code]hint_normal[/code]作为æç¤ºæ·»åŠ åˆ°uniform声明中,该声明在内部将纹ç†è½¬æ¢"
-"为法线贴图。"
+"å°† [code]hint_normal[/code] 作为æç¤ºæ·»åŠ åˆ° uniform 声明中,该声明在内部将纹ç†"
+"转æ¢ä¸ºæ³•线贴图。"
#: doc/classes/VisualShaderNodeCubeMapUniform.xml
msgid "A [CubeMap] uniform node to be used within the visual shader graph."
@@ -90595,7 +91164,7 @@ msgstr "计算å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä¸¤ä¸ªå‘é‡çš„点积。"
#: doc/classes/VisualShaderNodeDotProduct.xml
msgid "Translates to [code]dot(a, b)[/code] in the shader language."
-msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ[code]dot(a, b)[/code]。"
+msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ [code]dot(a, b)[/code]。"
#: doc/classes/VisualShaderNodeExpression.xml
msgid ""
@@ -90612,10 +91181,10 @@ msgid ""
"global constants. See [VisualShaderNodeGlobalExpression] for such global "
"definitions."
msgstr ""
-"自定义Godotç€è‰²å™¨è¯­è¨€è¡¨è¾¾å¼ï¼Œæœ‰è‡ªå®šä¹‰æ•°é‡çš„输入和输出端å£ã€‚\n"
-"所æä¾›çš„代ç ç›´æŽ¥æ³¨å…¥åˆ°å›¾å½¢åŒ¹é…ç€è‰²å™¨å‡½æ•°ä¸­ï¼Œå³[code]vertex[/code], "
-"[code]fragment[/code], or [code]light[/code],所以它ä¸èƒ½ç”¨äºŽå£°æ˜Žå‡½æ•°ã€å˜ä½“ã€"
-"uniforms或全局常é‡ã€‚请å‚阅[VisualShaderNodeGlobalExpression]以了解此类全局定"
+"自定义 Godot ç€è‰²å™¨è¯­è¨€è¡¨è¾¾å¼ï¼Œæœ‰è‡ªå®šä¹‰æ•°é‡çš„输入和输出端å£ã€‚\n"
+"所æä¾›çš„代ç ç›´æŽ¥æ³¨å…¥åˆ°å›¾å½¢åŒ¹é…ç€è‰²å™¨å‡½æ•°ä¸­ï¼ˆ[code]vertex[/code]ã€"
+"[code]fragment[/code] 或 [code]light[/code]),所以它ä¸èƒ½ç”¨äºŽå£°æ˜Žå‡½æ•°ã€å˜ä½“ã€"
+"uniform 或全局常é‡ã€‚请å‚阅[VisualShaderNodeGlobalExpression]以了解此类全局定"
"义。"
#: doc/classes/VisualShaderNodeExpression.xml
@@ -90626,8 +91195,8 @@ msgid ""
"declare functions, varyings, uniforms, or global constants."
msgstr ""
"Godot ç€è‰²å™¨è¯­è¨€ä¸­çš„表达å¼ï¼Œå®ƒå°†è¢«æ³¨å…¥åˆ°å›¾å½¢åŒ¹é…çš„ç€è‰²å™¨å‡½æ•°ï¼ˆ[code]vertex[/"
-"code], [code]fragment[/code], or [code]light[/code])的开头,因此ä¸èƒ½ç”¨äºŽå£°æ˜Ž"
-"函数ã€varyingsã€uniforms或全局常é‡ã€‚"
+"code]ã€[code]fragment[/code] 或 [code]light[/code])的开头,因此ä¸èƒ½ç”¨äºŽå£°æ˜Ž"
+"函数ã€varyingã€uniform 或全局常é‡ã€‚"
#: doc/classes/VisualShaderNodeFaceForward.xml
msgid ""
@@ -90644,10 +91213,10 @@ msgid ""
"is smaller than zero the return value is [code]N[/code]. Otherwise, [code]-"
"N[/code] is returned."
msgstr ""
-"在ç€è‰²å™¨è¯­è¨€ä¸­ç¿»è¯‘为[code]faceforward(N, I, Nref)[/code]。该函数有三个å‘é‡å‚"
-"数。[code]N[/code],定å‘矢é‡ï¼Œ[code]I[/code],入射矢é‡ï¼Œä»¥åŠ[code]Nref[/"
-"code],å‚考矢é‡ã€‚如果[code]I[/code]å’Œ[code]Nref[/code]的点积å°äºŽé›¶ï¼Œè¿”回值为"
-"[code]N[/code]。å¦åˆ™ï¼Œå°†è¿”回 [code]-N[/code]。"
+"在ç€è‰²å™¨è¯­è¨€ä¸­ç¿»è¯‘为 [code]faceforward(N, I, Nref)[/code]。该函数有三个å‘é‡å‚"
+"数。[code]N[/code],定å‘å‘é‡ï¼Œ[code]I[/code],入射å‘é‡ï¼Œä»¥åŠ[code]Nref[/"
+"code],å‚考矢é‡ã€‚如果 [code]I[/code] å’Œ [code]Nref[/code] 的点积å°äºŽé›¶ï¼Œè¿”回"
+"值为 [code]N[/code]。å¦åˆ™ï¼Œå°†è¿”回 [code]-N[/code]。"
#: doc/classes/VisualShaderNodeFresnel.xml
msgid "A Fresnel effect to be used within the visual shader graph."
@@ -90818,7 +91387,7 @@ msgid ""
"type (check [code]Tutorials[/code] section for link)."
msgstr ""
"æä¾›å¯¹ç€è‰²å™¨å¯ç”¨çš„输入å˜é‡ï¼ˆå†…置)的访问。关于æ¯ç§ç€è‰²å™¨ç±»åž‹çš„å¯ç”¨å†…ç½®å˜é‡åˆ—"
-"表,请å‚阅ç€è‰²å™¨å‚è€ƒï¼Œå³æŸ¥çœ‹[code]Tutorials[/code]教程部分的链接。"
+"表,请å‚阅ç€è‰²å™¨å‚考(查看[code]教程[/code]部分的链接)。"
#: doc/classes/VisualShaderNodeInput.xml
msgid ""
@@ -90934,7 +91503,7 @@ msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­çš„两个标é‡ä¹‹é—´è¿›è¡Œçº¿æ€§æ’值。"
#: doc/classes/VisualShaderNodeScalarInterp.xml
msgid "Translates to [code]mix(a, b, weight)[/code] in the shader language."
-msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢ä¸º[code]mix(a, b, weight)[/code]。"
+msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢ä¸º [code]mix(a, b, weight)[/code]。"
#: doc/classes/VisualShaderNodeScalarSmoothStep.xml
msgid "Calculates a scalar SmoothStep function within the visual shader graph."
@@ -90949,10 +91518,10 @@ msgid ""
"code]. Otherwise the return value is interpolated between [code]0.0[/code] "
"and [code]1.0[/code] using Hermite polynomials."
msgstr ""
-"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ[code]smoothstep(edge0, edge1, x)[/code]。\n"
-"如果[code]x[/code]å°äºŽ[code]edge0[/code],返回 [code]0.0[/code];如果"
-"[code]x[/code]大于[code]edge1[/code],返回 [code]1.0[/code]。å¦åˆ™è¿”回值在"
-"[code]0.0[/code]å’Œ[code]1.0[/code]之间使用Hermite多项å¼è¿›è¡Œæ’值。"
+"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ [code]smoothstep(edge0, edge1, x)[/code]。\n"
+"如果 [code]x[/code] å°äºŽ [code]edge0[/code],返回 [code]0.0[/code];如果 "
+"[code]x[/code] 大于 [code]edge1[/code],返回 [code]1.0[/code]。å¦åˆ™è¿”回值在 "
+"[code]0.0[/code] å’Œ [code]1.0[/code] 之间使用 Hermite 多项å¼è¿›è¡Œæ’值。"
#: doc/classes/VisualShaderNodeScalarSwitch.xml
msgid "A boolean/scalar function for use within the visual shader graph."
@@ -91087,23 +91656,23 @@ msgstr "将输入端å£ä¸­æä¾›çš„纹ç†ç”¨äºŽæ­¤å‡½æ•°ã€‚"
#: doc/classes/VisualShaderNodeTextureUniform.xml
msgid "Performs a uniform texture lookup within the visual shader graph."
-msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­æ‰§è¡Œuniformçš„çº¹ç†æŸ¥æ‰¾ã€‚"
+msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­æ‰§è¡Œ uniform çš„çº¹ç†æŸ¥æ‰¾ã€‚"
#: doc/classes/VisualShaderNodeTextureUniform.xml
msgid ""
"Performs a lookup operation on the texture provided as a uniform for the "
"shader."
-msgstr "对作为uniformç€è‰²å™¨æä¾›çš„纹ç†è¿›è¡ŒæŸ¥æ‰¾æ“作。"
+msgstr "对作为 uniform ç€è‰²å™¨æä¾›çš„纹ç†è¿›è¡ŒæŸ¥æ‰¾æ“作。"
#: doc/classes/VisualShaderNodeTextureUniform.xml
msgid "Sets the default color if no texture is assigned to the uniform."
-msgstr "如果没有给uniform分é…纹ç†ï¼Œåˆ™è®¾ç½®é»˜è®¤é¢œè‰²ã€‚"
+msgstr "如果没有给 uniform 分é…纹ç†ï¼Œåˆ™è®¾ç½®é»˜è®¤é¢œè‰²ã€‚"
#: doc/classes/VisualShaderNodeTextureUniform.xml
msgid ""
"Adds [code]hint_aniso[/code] as hint to the uniform declaration to use for a "
"flowmap."
-msgstr "å°†[code]hint_aniso[/code]作为æç¤ºæ·»åŠ åˆ°uniform声明中,用于æµç¨‹å›¾ã€‚"
+msgstr "å°† [code]hint_aniso[/code] 作为æç¤ºæ·»åŠ åˆ° uniform 声明中,用于æµå‘图。"
#: doc/classes/VisualShaderNodeTextureUniform.xml
msgid "Defaults to white color."
@@ -91117,7 +91686,7 @@ msgstr "默认为黑色。"
msgid ""
"Performs a uniform texture lookup with triplanar within the visual shader "
"graph."
-msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ç”¨ä¸‰è§’é¢è¿›è¡Œuniformçº¹ç†æŸ¥æ‰¾ã€‚"
+msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ç”¨ä¸‰è§’é¢è¿›è¡Œ uniform çº¹ç†æŸ¥æ‰¾ã€‚"
#: doc/classes/VisualShaderNodeTextureUniformTriplanar.xml
msgid ""
@@ -91128,7 +91697,7 @@ msgstr "对作为uniformç€è‰²å™¨æä¾›çš„纹ç†è¿›è¡ŒæŸ¥æ‰¾æ“作,并支æŒä¸
#: doc/classes/VisualShaderNodeTransformCompose.xml
msgid ""
"Composes a [Transform] from four [Vector3]s within the visual shader graph."
-msgstr "从å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­çš„四个[Vector3]组æˆä¸€ä¸ª[Transform]。"
+msgstr "从å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­çš„四个 [Vector3] 组æˆä¸€ä¸ª [Transform]。"
#: doc/classes/VisualShaderNodeTransformCompose.xml
msgid ""
@@ -91136,25 +91705,25 @@ msgid ""
"Each vector is one row in the matrix and the last column is a [code]vec4(0, "
"0, 0, 1)[/code]."
msgstr ""
-"使用四个类型为[code]vec3[/code]çš„å‘é‡åˆ›å»ºä¸€ä¸ª4x4å˜æ¢çŸ©é˜µã€‚æ¯ä¸ªå‘釿˜¯çŸ©é˜µä¸­çš„"
-"一行,最åŽä¸€åˆ—是一个[code]vec4(0, 0, 0, 1)[/code]。"
+"使用四个类型为 [code]vec3[/code] çš„å‘é‡åˆ›å»ºä¸€ä¸ª 4x4 å˜æ¢çŸ©é˜µã€‚æ¯ä¸ªå‘釿˜¯çŸ©é˜µ"
+"中的一行,最åŽä¸€åˆ—是一个 [code]vec4(0, 0, 0, 1)[/code]。"
#: doc/classes/VisualShaderNodeTransformConstant.xml
msgid "A [Transform] constant for use within the visual shader graph."
-msgstr "一个[Transform]常é‡ï¼Œåœ¨å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨ã€‚"
+msgstr "[Transform] 常é‡ï¼Œåœ¨å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨ã€‚"
#: doc/classes/VisualShaderNodeTransformConstant.xml
msgid "A constant [Transform], which can be used as an input node."
-msgstr "一个常é‡[Transform],å¯ä»¥ä½œä¸ºä¸€ä¸ªè¾“入节点使用。"
+msgstr "å¸¸é‡ [Transform],å¯ä»¥ä½œä¸ºä¸€ä¸ªè¾“入节点使用。"
#: doc/classes/VisualShaderNodeTransformConstant.xml
msgid "A [Transform] constant which represents the state of this node."
-msgstr "一个[Transform]常é‡ï¼Œè¡¨ç¤ºè¿™ä¸ªèŠ‚ç‚¹çš„çŠ¶æ€ã€‚"
+msgstr "[Transform] 常é‡ï¼Œè¡¨ç¤ºè¿™ä¸ªèŠ‚ç‚¹çš„çŠ¶æ€ã€‚"
#: doc/classes/VisualShaderNodeTransformDecompose.xml
msgid ""
"Decomposes a [Transform] into four [Vector3]s within the visual shader graph."
-msgstr "将一个[Transform]分解为å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­çš„四个[Vector3]。"
+msgstr "将一个 [Transform] 分解为å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­çš„四个 [Vector3]。"
#: doc/classes/VisualShaderNodeTransformDecompose.xml
msgid ""
@@ -91200,47 +91769,47 @@ msgstr "è¦å¯¹å˜æ¢è¿›è¡Œçš„乘法类型。å‚阅[enum Operator]的选项。"
#: doc/classes/VisualShaderNodeTransformMult.xml
msgid "Multiplies transform [code]a[/code] by the transform [code]b[/code]."
-msgstr "å°†å˜æ¢[code]a[/code]ä¹˜ä»¥å˜æ¢[code]b[/code]。"
+msgstr "å°†å˜æ¢ [code]a[/code] ä¹˜ä»¥å˜æ¢ [code]b[/code]。"
#: doc/classes/VisualShaderNodeTransformMult.xml
msgid "Multiplies transform [code]b[/code] by the transform [code]a[/code]."
-msgstr "å°†å˜æ¢[code]b[/code]ä¹˜ä»¥å˜æ¢[code]a[/code]。"
+msgstr "å°†å˜æ¢ [code]b[/code] ä¹˜ä»¥å˜æ¢ [code]a[/code]。"
#: doc/classes/VisualShaderNodeTransformMult.xml
msgid ""
"Performs a component-wise multiplication of transform [code]a[/code] by the "
"transform [code]b[/code]."
-msgstr "å¯¹å˜æ¢[code]a[/code]ä¸Žå˜æ¢[code]b[/code]è¿›è¡Œåˆ†é‡æ˜Žæ™ºçš„乘法。"
+msgstr "å¯¹å˜æ¢ [code]a[/code] ä¸Žå˜æ¢ [code]b[/code] è¿›è¡Œåˆ†é‡æ˜Žæ™ºçš„乘法。"
#: doc/classes/VisualShaderNodeTransformMult.xml
msgid ""
"Performs a component-wise multiplication of transform [code]b[/code] by the "
"transform [code]a[/code]."
-msgstr "å¯¹å˜æ¢[code]b[/code]ä¸Žå˜æ¢[code]a[/code]è¿›è¡Œåˆ†é‡æ˜Žæ™ºçš„乘法。"
+msgstr "å¯¹å˜æ¢ [code]b[/code] ä¸Žå˜æ¢ [code]a[/code] è¿›è¡Œåˆ†é‡æ˜Žæ™ºçš„乘法。"
#: doc/classes/VisualShaderNodeTransformUniform.xml
msgid "A [Transform] uniform for use within the visual shader graph."
-msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„[Transform]uniform。"
+msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„ [Transform] uniform。"
#: doc/classes/VisualShaderNodeTransformUniform.xml
msgid "Translated to [code]uniform mat4[/code] in the shader language."
-msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ[code]uniform mat4[/code]。"
+msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ [code]uniform mat4[/code]。"
#: doc/classes/VisualShaderNodeTransformVecMult.xml
msgid ""
"Multiplies a [Transform] and a [Vector3] within the visual shader graph."
-msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ï¼Œå°†ä¸€ä¸ª[Transform]和一个[Vector3]相乘。"
+msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ï¼Œå°†ä¸€ä¸ª [Transform] 和一个 [Vector3] 相乘。"
#: doc/classes/VisualShaderNodeTransformVecMult.xml
msgid ""
"A multiplication operation on a transform (4x4 matrix) and a vector, with "
"support for different multiplication operators."
-msgstr "å¯¹ä¸€ä¸ªå˜æ¢ï¼ˆ4x4矩阵)和一个å‘é‡è¿›è¡Œä¹˜æ³•è¿ç®—,支æŒä¸åŒçš„乘法è¿ç®—符。"
+msgstr "å¯¹ä¸€ä¸ªå˜æ¢ï¼ˆ4x4 矩阵)和一个å‘é‡è¿›è¡Œä¹˜æ³•è¿ç®—,支æŒä¸åŒçš„乘法è¿ç®—符。"
#: doc/classes/VisualShaderNodeTransformVecMult.xml
msgid ""
"The multiplication type to be performed. See [enum Operator] for options."
-msgstr "è¦æ‰§è¡Œçš„乘法类型。å‚阅[enum Operator]的选项。"
+msgstr "è¦æ‰§è¡Œçš„乘法类型。å‚阅 [enum Operator] 的选项。"
#: doc/classes/VisualShaderNodeTransformVecMult.xml
msgid "Multiplies transform [code]a[/code] by the vector [code]b[/code]."
@@ -91301,23 +91870,23 @@ msgstr "该引用所指å‘çš„ uniform çš„å称。"
#: doc/classes/VisualShaderNodeVec3Constant.xml
msgid "A [Vector3] constant to be used within the visual shader graph."
-msgstr "一个 [Vector3] 常é‡ï¼Œç”¨äºŽå¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ã€‚"
+msgstr "[Vector3] 常é‡ï¼Œç”¨äºŽå¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ã€‚"
#: doc/classes/VisualShaderNodeVec3Constant.xml
msgid "A constant [Vector3], which can be used as an input node."
-msgstr "ä¸€ä¸ªå¸¸é‡ [Vector3],它å¯ä»¥ä½œä¸ºè¾“入节点使用。"
+msgstr "å¸¸é‡ [Vector3],它å¯ä»¥ä½œä¸ºè¾“入节点使用。"
#: doc/classes/VisualShaderNodeVec3Constant.xml
msgid "A [Vector3] constant which represents the state of this node."
-msgstr "一个 [Vector3] 常é‡ï¼Œè¡¨ç¤ºè¯¥èŠ‚ç‚¹çš„çŠ¶æ€ã€‚"
+msgstr "[Vector3] 常é‡ï¼Œè¡¨ç¤ºè¯¥èŠ‚ç‚¹çš„çŠ¶æ€ã€‚"
#: doc/classes/VisualShaderNodeVec3Uniform.xml
msgid "A [Vector3] uniform to be used within the visual shader graph."
-msgstr "一个 [Vector3] çš„ uniform,在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨ã€‚"
+msgstr "[Vector3] çš„ uniform,在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨ã€‚"
#: doc/classes/VisualShaderNodeVec3Uniform.xml
msgid "Translated to [code]uniform vec3[/code] in the shader language."
-msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ[code]uniform vec3[/code]。"
+msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ [code]uniform vec3[/code]。"
#: doc/classes/VisualShaderNodeVectorClamp.xml
msgid "Clamps a vector value within the visual shader graph."
@@ -91329,30 +91898,30 @@ msgid ""
"values. The operation is performed on each component of the vector "
"individually."
msgstr ""
-"将一个值é™åˆ¶åœ¨[code]min[/code]å’Œ[code]max[/code]之间。该æ“作是对å‘é‡çš„æ¯ä¸ªåˆ†"
-"é‡å•独执行的。"
+"将一个值é™åˆ¶åœ¨ [code]min[/code] å’Œ [code]max[/code] 之间。该æ“作是对å‘é‡çš„æ¯"
+"个分é‡å•独执行的。"
#: doc/classes/VisualShaderNodeVectorCompose.xml
msgid "Composes a [Vector3] from three scalars within the visual shader graph."
-msgstr "从å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­çš„三个标é‡ç»„æˆä¸€ä¸ª[Vector3]。"
+msgstr "从å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­çš„三个标é‡ç»„æˆä¸€ä¸ª [Vector3]。"
#: doc/classes/VisualShaderNodeVectorCompose.xml
msgid ""
"Creates a [code]vec3[/code] using three scalar values that can be provided "
"from separate inputs."
msgstr ""
-"使用三个标é‡å€¼åˆ›å»ºä¸€ä¸ª[code]vec3[/code],这些标é‡å€¼å¯ä»¥ç”±å•独的输入æä¾›ã€‚"
+"使用三个标é‡å€¼åˆ›å»ºä¸€ä¸ª [code]vec3[/code],这些标é‡å€¼å¯ä»¥ç”±å•独的输入æä¾›ã€‚"
#: doc/classes/VisualShaderNodeVectorDecompose.xml
msgid ""
"Decomposes a [Vector3] into three scalars within the visual shader graph."
-msgstr "将一个[Vector3]分解为å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­çš„三个标é‡ã€‚"
+msgstr "将一个 [Vector3] 分解为å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­çš„三个标é‡ã€‚"
#: doc/classes/VisualShaderNodeVectorDecompose.xml
msgid ""
"Takes a [code]vec3[/code] and decomposes it into three scalar values that "
"can be used as separate inputs."
-msgstr "å–一个[code]vec3[/code]并将其分解为三个标é‡å€¼ï¼Œå¯ä½œä¸ºå•独的输入。"
+msgstr "å–一个 [code]vec3[/code] 并将其分解为三个标é‡å€¼ï¼Œå¯ä½œä¸ºå•独的输入。"
#: doc/classes/VisualShaderNodeVectorDerivativeFunc.xml
msgid "Calculates a vector derivative within the visual shader graph."
@@ -91360,7 +91929,7 @@ msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­è®¡ç®—一个å‘é‡å¯¼æ•°ã€‚"
#: doc/classes/VisualShaderNodeVectorDerivativeFunc.xml
msgid "A derivative type. See [enum Function] for options."
-msgstr "派生类型。选项å‚阅[enum Function]。"
+msgstr "派生类型。选项å‚阅 [enum Function]。"
#: doc/classes/VisualShaderNodeVectorDistance.xml
msgid ""
@@ -91374,8 +91943,8 @@ msgid ""
"vector [code]p1[/code].\n"
"Translated to [code]distance(p0, p1)[/code] in the shader language."
msgstr ""
-"计算从å‘é‡[code]p0[/code]表示的点到å‘é‡[code]p1[/code]çš„è·ç¦»ã€‚\n"
-"在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ[code]distance(p0, p1)[/code]。"
+"计算从å‘é‡ [code]p0[/code] 表示的点到å‘é‡ [code]p1[/code] çš„è·ç¦»ã€‚\n"
+"在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ [code]distance(p0, p1)[/code]。"
#: doc/classes/VisualShaderNodeVectorFunc.xml
msgid "A vector function to be used within the visual shader graph."
@@ -91387,7 +91956,7 @@ msgstr "å¯è§†åŒ–ç€è‰²å™¨èŠ‚ç‚¹ï¼Œèƒ½å¤Ÿä½¿ç”¨å‘釿‰§è¡Œä¸åŒçš„函数。"
#: doc/classes/VisualShaderNodeVectorFunc.xml
msgid "The function to be performed. See [enum Function] for options."
-msgstr "è¦æ‰§è¡Œçš„函数。å‚阅[enum Function]的选项。"
+msgstr "è¦æ‰§è¡Œçš„函数。å‚阅 [enum Function] 的选项。"
#: doc/classes/VisualShaderNodeVectorFunc.xml
msgid ""
@@ -91549,8 +92118,8 @@ msgid ""
"Translates to [code]mix(a, b, weight)[/code] in the shader language, where "
"[code]weight[/code] is a [Vector3] with weights for each component."
msgstr ""
-"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ[code]mix(a, b, weight)[/code],其中[code]weight[/code]是"
-"一个[Vector3],æ¯ä¸ªåˆ†é‡çš„æƒé‡ã€‚"
+"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ [code]mix(a, b, weight)[/code],其中 [code]weight[/"
+"code] 是一个 [Vector3],æ¯ä¸ªåˆ†é‡çš„æƒé‡ã€‚"
#: doc/classes/VisualShaderNodeVectorLen.xml
msgid "Returns the length of a [Vector3] within the visual shader graph."
@@ -91645,8 +92214,8 @@ msgid ""
"[code]I[/code] is the incident vector, [code]N[/code] is the normal vector "
"and [code]eta[/code] is the ratio of the indices of the refraction."
msgstr ""
-"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ[code]refract(I, N, eta)[/code],其中[code]I[/code]是入射"
-"å‘é‡ï¼Œ[code]N[/code]是法线å‘é‡ï¼Œ[code]eta[/code]是折射的比率。"
+"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ [code]refract(I, N, eta)[/code],其中 [code]I[/code] 是"
+"入射å‘é‡ï¼Œ[code]N[/code] 是法线å‘é‡ï¼Œ[code]eta[/code] 是折射的比率。"
#: doc/classes/VisualShaderNodeVectorScalarMix.xml
msgid ""
@@ -91660,8 +92229,8 @@ msgid ""
"[code]a[/code] and [code]b[/code] are vectors and [code]weight[/code] is a "
"scalar."
msgstr ""
-"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ[code]mix(a, b, weight)[/code],其中[code]a[/code]å’Œ"
-"[code]b[/code]是å‘é‡ï¼Œ[code]weight[/code]是标é‡ã€‚"
+"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ [code]mix(a, b, weight)[/code],其中 [code]a[/code] å’Œ "
+"[code]b[/code] 是å‘é‡ï¼Œ[code]weight[/code] 是标é‡ã€‚"
#: doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml
msgid ""
@@ -91678,11 +92247,11 @@ msgid ""
"code]. Otherwise the return value is interpolated between [code]0.0[/code] "
"and [code]1.0[/code] using Hermite polynomials."
msgstr ""
-"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ[code]smoothstep(edge0, edge1, x)[/code],其中[code]x[/"
-"code]是一个标é‡ã€‚\n"
-"如果[code]x[/code]å°äºŽ[code]edge0[/code],返回 [code]0.0[/code],如果"
-"[code]x[/code]大于[code]edge1[/code],返回 [code]1.0[/code]。å¦åˆ™è¿”回值在"
-"[code]0.0[/code]å’Œ[code]1.0[/code]之间使用Hermite多项å¼è¿›è¡Œæ’值。"
+"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ [code]smoothstep(edge0, edge1, x)[/code],其中 [code]x[/"
+"code] 是一个标é‡ã€‚\n"
+"如果 [code]x[/code] å°äºŽ [code]edge0[/code],返回 [code]0.0[/code],如果 "
+"[code]x[/code] 大于 [code]edge1[/code],返回 [code]1.0[/code]。å¦åˆ™è¿”回值在"
+"[code]0.0[/code] å’Œ [code]1.0[/code] 之间使用 Hermite 多项å¼è¿›è¡Œæ’值。"
#: doc/classes/VisualShaderNodeVectorScalarStep.xml
msgid "Calculates a vector Step function within the visual shader graph."
@@ -91694,8 +92263,8 @@ msgid ""
"Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge[/code] "
"and [code]1.0[/code] otherwise."
msgstr ""
-"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ[code]step(edge, x)[/code]。\n"
-"如果[code]x[/code]å°äºŽ[code]edge[/code],返回 [code]0.0[/code],å¦åˆ™è¿”回 "
+"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ [code]step(edge, x)[/code]。\n"
+"如果 [code]x[/code] å°äºŽ [code]edge[/code],返回 [code]0.0[/code],å¦åˆ™è¿”回 "
"[code]1.0[/code]。"
#: doc/classes/VisualShaderNodeVectorSmoothStep.xml
@@ -91711,11 +92280,11 @@ msgid ""
"code]. Otherwise the return value is interpolated between [code]0.0[/code] "
"and [code]1.0[/code] using Hermite polynomials."
msgstr ""
-"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ[code]smoothstep(edge0, edge1, x)[/code],其中[code]x[/"
-"code]是一个å‘é‡ã€‚\n"
-"如果[code]x[/code]å°äºŽ[code]edge0[/code],返回 [code]0.0[/code],如果"
-"[code]x[/code]大于[code]edge1[/code],返回 [code]1.0[/code]。å¦åˆ™è¿”回值在"
-"[code]0.0[/code]å’Œ[code]1.0[/code]之间使用Hermite多项å¼è¿›è¡Œæ’值。"
+"在ç€è‰²å™¨è¯­è¨€ä¸­è½¬æ¢æˆ [code]smoothstep(edge0, edge1, x)[/code],其中 [code]x[/"
+"code] 是一个å‘é‡ã€‚\n"
+"如果 [code]x[/code] å°äºŽ [code]edge0[/code],返回 [code]0.0[/code],如果 "
+"[code]x[/code] 大于 [code]edge1[/code],返回 [code]1.0[/code]。å¦åˆ™è¿”回值在 "
+"[code]0.0[/code] å’Œ [code]1.0[/code] 之间使用 Hermite 多项å¼è¿›è¡Œæ’值。"
#: doc/classes/VScrollBar.xml
msgid "Vertical scroll bar."
@@ -91763,8 +92332,8 @@ msgid ""
"The style for the separator line. Works best with [StyleBoxLine] (remember "
"to enable [member StyleBoxLine.vertical])."
msgstr ""
-"分隔线的样å¼ã€‚与[StyleBoxLine]一起使用效果最好,记得è¦å¯ç”¨[member "
-"StyleBoxLine.vertical]。"
+"分隔线的样å¼ã€‚与 [StyleBoxLine] 一起使用效果最好(记得è¦å¯ç”¨ [member "
+"StyleBoxLine.vertical])。"
#: doc/classes/VSlider.xml
msgid "Vertical slider."
@@ -91777,7 +92346,7 @@ msgid ""
"[b]Note:[/b] The [signal Range.changed] and [signal Range.value_changed] "
"signals are part of the [Range] class which this class inherits from."
msgstr ""
-"垂直滑动æ¡ã€‚请å‚阅 [Slider]。这个控件是从底部(最å°ï¼‰æ»‘到顶部(最大)的。\n"
+"垂直滑动æ¡ã€‚è§ [Slider]。这个控件是从底部(最å°ï¼‰æ»‘到顶部(最大)的。\n"
"[b]注æ„:[/b][signal Range.changed] å’Œ [signal Range.value_changed] ä¿¡å·æ˜¯ "
"[Range] 类的一部分,该类继承自它。"
@@ -91798,7 +92367,7 @@ msgstr "垂直拆分容器。"
#: doc/classes/VSplitContainer.xml
msgid ""
"Vertical split container. See [SplitContainer]. This goes from top to bottom."
-msgstr "垂直拆分容器。å‚阅[SplitContainer]。这是从上到下的。"
+msgstr "åž‚ç›´æ‹†åˆ†å®¹å™¨ã€‚è§ [SplitContainer]。这是从上到下的。"
#: doc/classes/WeakRef.xml
msgid ""
@@ -91846,8 +92415,8 @@ msgid ""
"after the connection is established (will return [code]65535[/code] until "
"then)."
msgstr ""
-"返回创建时分é…给该通é“çš„ID,或在å商时自动分é…。\n"
-"å¦‚æžœè¯¥é€šé“æ²¡æœ‰è¿›è¡Œå¸¦å¤–å商,那么该IDå°†åªåœ¨è¿žæŽ¥å»ºç«‹åŽå¯ç”¨ï¼Œåœ¨æ­¤ä¹‹å‰å°†è¿”回 "
+"返回创建时分é…给该通é“çš„ ID,或在å商时自动分é…。\n"
+"å¦‚æžœè¯¥é€šé“æ²¡æœ‰è¿›è¡Œå¸¦å¤–å商,那么该 ID å°†åªåœ¨è¿žæŽ¥å»ºç«‹åŽå¯ç”¨ï¼Œåœ¨æ­¤ä¹‹å‰å°†è¿”回 "
"[code]65535[/code]。"
#: modules/webrtc/doc_classes/WebRTCDataChannel.xml
@@ -91860,8 +92429,8 @@ msgid ""
"during creation.\n"
"Will be [code]65535[/code] if not specified."
msgstr ""
-"返回创建时分é…给这个通é“çš„[code]maxPacketLifeTime[/code]值。\n"
-"如果没有指定,将是[code]65535[/code]。"
+"返回创建时分é…给这个通é“çš„ [code]maxPacketLifeTime[/code] 值。\n"
+"如果没有指定,将是 [code]65535[/code]。"
#: modules/webrtc/doc_classes/WebRTCDataChannel.xml
msgid ""
@@ -91869,8 +92438,8 @@ msgid ""
"during creation.\n"
"Will be [code]65535[/code] if not specified."
msgstr ""
-"返回创建时分é…给这个通é“çš„[code]maxRetransmits[/code]值。\n"
-"如果没有指定,将是[code]65535[/code]。"
+"返回创建时分é…给这个通é“çš„ [code]maxRetransmits[/code] 值。\n"
+"如果没有指定,将是 [code]65535[/code]。"
#: modules/webrtc/doc_classes/WebRTCDataChannel.xml
msgid ""
@@ -91880,7 +92449,7 @@ msgstr "返回创建时分é…给这个通é“çš„å­å议。如果没有指定,
#: modules/webrtc/doc_classes/WebRTCDataChannel.xml
msgid "Returns the current state of this channel, see [enum ChannelState]."
-msgstr "返回该通é“的当å‰çжæ€ï¼Œå‚阅[enum ChannelState]。"
+msgstr "返回该通é“的当å‰çжæ€ï¼Œè§ [enum ChannelState]。"
#: modules/webrtc/doc_classes/WebRTCDataChannel.xml
msgid ""
@@ -91903,7 +92472,7 @@ msgid ""
"Returns [code]true[/code] if the last received packet was transferred as "
"text. See [member write_mode]."
msgstr ""
-"å¦‚æžœæœ€åŽæ”¶åˆ°çš„æ•°æ®åŒ…是以文本形å¼ä¼ è¾“,则返回 [code]true[/code]。å‚阅[member "
+"å¦‚æžœæœ€åŽæ”¶åˆ°çš„æ•°æ®åŒ…是以文本形å¼ä¼ è¾“,则返回 [code]true[/code]ã€‚è§ [member "
"write_mode]。"
#: modules/webrtc/doc_classes/WebRTCDataChannel.xml
@@ -91916,16 +92485,16 @@ msgid ""
"Tells the channel to send data over this channel as text. An external peer "
"(non-Godot) would receive this as a string."
msgstr ""
-"告诉通é“以文本形å¼åœ¨è¿™ä¸ªé€šé“上å‘逿•°æ®ã€‚外部对等体(éžGodot)会以字符串的形å¼"
-"接收。"
+"告诉通é“以文本形å¼åœ¨è¿™ä¸ªé€šé“上å‘逿•°æ®ã€‚å¤–éƒ¨å¯¹ç­‰ä½“ï¼ˆéž Godot)会以字符串的形"
+"å¼æŽ¥æ”¶ã€‚"
#: modules/webrtc/doc_classes/WebRTCDataChannel.xml
msgid ""
"Tells the channel to send data over this channel as binary. An external peer "
"(non-Godot) would receive this as array buffer or blob."
msgstr ""
-"告诉通é“以二进制形å¼åœ¨æ­¤é€šé“上å‘逿•°æ®ã€‚外部对等体(éžGodot)将以数组缓冲区或"
-"blobçš„å½¢å¼æŽ¥æ”¶ã€‚"
+"告诉通é“以二进制形å¼åœ¨æ­¤é€šé“上å‘逿•°æ®ã€‚å¤–éƒ¨å¯¹ç­‰ä½“ï¼ˆéž Godot)将以数组缓冲区"
+"或 blob çš„å½¢å¼æŽ¥æ”¶ã€‚"
#: modules/webrtc/doc_classes/WebRTCDataChannel.xml
msgid "The channel was created, but it's still trying to connect."
@@ -91950,8 +92519,8 @@ msgid ""
"A simple interface to create a peer-to-peer mesh network composed of "
"[WebRTCPeerConnection] that is compatible with the [MultiplayerAPI]."
msgstr ""
-"简å•的接å£ï¼Œç”¨äºŽåˆ›å»ºç”±[WebRTCPeerConnection]组æˆçš„点对点网状网络,与"
-"[MultiplayerAPI]兼容。"
+"简å•的接å£ï¼Œç”¨äºŽåˆ›å»ºç”± [WebRTCPeerConnection] 组æˆçš„点对点网状网络,与 "
+"[MultiplayerAPI] 兼容。"
#: modules/webrtc/doc_classes/WebRTCMultiplayer.xml
msgid ""
@@ -91990,12 +92559,12 @@ msgid ""
"the [code]maxPacketLifetime[/code] option when creating unreliable and "
"ordered channels (see [method WebRTCPeerConnection.create_data_channel])."
msgstr ""
-"以给定的[code]peer_id[/code]添加一个新的对等体到网状结构。该"
-"[WebRTCPeerConnection]必须处于[constant WebRTCPeerConnection.STATE_NEW]状"
+"以给定的 [code]peer_id[/code] 添加一个新的对等体到网状结构。该 "
+"[WebRTCPeerConnection] 必须处于 [constant WebRTCPeerConnection.STATE_NEW] 状"
"æ€ã€‚\n"
"将为å¯é çš„ã€ä¸å¯é çš„和有åºçš„传输创建三个通é“。在创建ä¸å¯é å’Œæœ‰åºé€šé“时,"
-"[code]unreliable_lifetime[/code]的值将被传递给[code]maxPacketLifetime[/code]"
-"选项,å‚阅[method WebRTCPeerConnection.create_data_channel]。"
+"[code]unreliable_lifetime[/code] 的值将被传递给 [code]maxPacketLifetime[/"
+"code]é€‰é¡¹ï¼ˆè§ [method WebRTCPeerConnection.create_data_channel])。"
#: modules/webrtc/doc_classes/WebRTCMultiplayer.xml
msgid "Close all the add peer connections and channels, freeing all resources."
@@ -92009,25 +92578,25 @@ msgid ""
"[WebRTCDataChannel], and [code]connected[/code] a boolean representing if "
"the peer connection is currently connected (all three channels are open)."
msgstr ""
-"返回一个具有给定[code]peer_id[/code]的对等体的字典表示,有三个键。"
-"[code]connection[/code]包å«åˆ°è¿™ä¸ªå¯¹ç­‰ä½“çš„[WebRTCPeerConnection],"
-"[code]channels[/code]三个[WebRTCDataChannel]的数组,以åŠ[code]connected[/"
-"code]一个布尔值,表示对等体连接是å¦å½“å‰å·²è¿žæŽ¥ï¼Œæ³¨ï¼Œæ‰€æœ‰ä¸‰ä¸ªé€šé“都打开。"
+"返回一个具有给定 [code]peer_id[/code] 的对等体的字典表示,有三个键。"
+"[code]connection[/code] 包å«åˆ°è¿™ä¸ªå¯¹ç­‰ä½“çš„ [WebRTCPeerConnection],"
+"[code]channels[/code] 三个 [WebRTCDataChannel] çš„æ•°ç»„ï¼Œä»¥åŠ [code]connected[/"
+"code] 一个布尔值,表示对等体连接是å¦å½“å‰å·²è¿žæŽ¥ï¼ˆæ‰€æœ‰ä¸‰ä¸ªé€šé“都打开)。"
#: modules/webrtc/doc_classes/WebRTCMultiplayer.xml
msgid ""
"Returns a dictionary which keys are the peer ids and values the peer "
"representation as in [method get_peer]."
msgstr ""
-"返回一个字典,其键是对等体的id,其值是对等体的表示,如[method get_peer]。"
+"返回一个字典,其键是对等体的 id,其值是对等体的表示,如 [method get_peer]。"
#: modules/webrtc/doc_classes/WebRTCMultiplayer.xml
msgid ""
"Returns [code]true[/code] if the given [code]peer_id[/code] is in the peers "
"map (it might not be connected though)."
msgstr ""
-"如果给定的[code]peer_id[/code]在对等体映射中,则返回 [code]true[/code],尽管"
-"它å¯èƒ½æ²¡æœ‰è¿žæŽ¥ã€‚"
+"如果给定的 [code]peer_id[/code] 在对等体映射中,则返回 [code]true[/code],尽"
+"管它å¯èƒ½æ²¡æœ‰è¿žæŽ¥ã€‚"
#: modules/webrtc/doc_classes/WebRTCMultiplayer.xml
msgid ""
@@ -92048,18 +92617,18 @@ msgid ""
"server_disconnected] will be emitted and state will become [constant "
"NetworkedMultiplayerPeer.CONNECTION_CONNECTED]."
msgstr ""
-"用给定的[code]peer_id[/code](必须在1å’Œ2147483647之间)åˆå§‹åŒ–多人游æˆå¯¹ç­‰"
-"体。\n"
-"如果[code]server_compatibilty[/code]是[code]false[/code](默认),多人对等体"
-"将立å³å¤„于[constant NetworkedMultiplayerPeer.CONNECTION_CONNECTED]状æ€ï¼Œ"
-"[signal NetworkedMultiplayerPeer.connection_succeeded]å°†ä¸ä¼šè¢«å‘射出æ¥ã€‚\n"
-"如果[code]server_compatibilty[/code]为 [code]true[/code],对等体将抑制所有"
-"[signal NetworkedMultiplayerPeer.peer_connected]ä¿¡å·ï¼Œç›´åˆ°ä¸€ä¸ªid为[constant "
-"NetworkedMultiplayerPeer.TARGET_PEER_SERVER]的对等体连接,然åŽå‘出[signal "
-"NetworkedMultiplayerPeer.connection_succeeded]。之åŽå°†å¯¹æ¯ä¸ªå·²ç»è¿žæŽ¥çš„对等体"
-"å’Œå¯èƒ½è¿žæŽ¥çš„任何新对等体å‘出[signal NetworkedMultiplayerPeer.peer_connected]"
-"的信å·ã€‚如果æœåŠ¡å™¨å¯¹ç­‰ä½“åœ¨æ­¤ä¹‹åŽæ–­å¼€è¿žæŽ¥ï¼Œä¿¡å·[signal "
-"NetworkedMultiplayerPeer.server_disconnected]将被å‘出,状æ€å°†å˜æˆ[constant "
+"用给定的 [code]peer_id[/code](必须在 1 å’Œ 2147483647 之间)åˆå§‹åŒ–多人游æˆå¯¹"
+"等体。\n"
+"如果[code]server_compatibilty[/code] 是 [code]false[/code](默认),多人对等"
+"体将立å³å¤„于 [constant NetworkedMultiplayerPeer.CONNECTION_CONNECTED] 状æ€ï¼Œ"
+"[signal NetworkedMultiplayerPeer.connection_succeeded] å°†ä¸ä¼šè¢«å‘射出æ¥ã€‚\n"
+"如果[code]server_compatibilty[/code] 为 [code]true[/code],对等体将抑制所有 "
+"[signal NetworkedMultiplayerPeer.peer_connected] ä¿¡å·ï¼Œç›´åˆ°ä¸€ä¸ª id 为 "
+"[constant NetworkedMultiplayerPeer.TARGET_PEER_SERVER] 的对等体连接,然åŽå‘"
+"出 [signal NetworkedMultiplayerPeer.connection_succeeded]。之åŽå°†å¯¹æ¯ä¸ªå·²ç»è¿ž"
+"接的对等体和å¯èƒ½è¿žæŽ¥çš„任何新对等体å‘出 [signal NetworkedMultiplayerPeer."
+"peer_connected] 的信å·ã€‚如果æœåŠ¡å™¨å¯¹ç­‰ä½“åœ¨æ­¤ä¹‹åŽæ–­å¼€è¿žæŽ¥ï¼Œä¿¡å· [signal "
+"NetworkedMultiplayerPeer.server_disconnected] 将被å‘出,状æ€å°†å˜æˆ [constant "
"NetworkedMultiplayerPeer.CONNECTION_CONNECTED]。"
#: modules/webrtc/doc_classes/WebRTCMultiplayer.xml
@@ -92069,13 +92638,13 @@ msgid ""
"emitted for it, then [signal NetworkedMultiplayerPeer.peer_disconnected] "
"will be emitted."
msgstr ""
-"从网格中移除给定的[code]peer_id[/code]的对等体。如果对等体是连接的,并为其å‘"
-"出[signal NetworkedMultiplayerPeer.peer_connected],那么[signal "
-"NetworkedMultiplayerPeer.peer_disconnected]将被å‘出。"
+"从网格中移除给定的 [code]peer_id[/code] 的对等体。如果对等体是连接的,并为其"
+"å‘出 [signal NetworkedMultiplayerPeer.peer_connected],那么 [signal "
+"NetworkedMultiplayerPeer.peer_disconnected] 将被å‘出。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid "Interface to a WebRTC peer connection."
-msgstr "与WebRTC对等体连接的接å£ã€‚"
+msgstr "与 WebRTC 对等体连接的接å£ã€‚"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid ""
@@ -92093,14 +92662,14 @@ msgid ""
"After these steps, the connection should become connected. Keep on reading "
"or look into the tutorial for more information."
msgstr ""
-"本地计算机和远程对等体之间的WebRTC连接。æä¾›ä¸€ä¸ªæŽ¥å£æ¥è¿žæŽ¥ã€ç»´æŠ¤å’Œç›‘控连"
+"本地计算机和远程对等体之间的 WebRTC 连接。æä¾›ä¸€ä¸ªæŽ¥å£æ¥è¿žæŽ¥ã€ç»´æŠ¤å’Œç›‘控连"
"接。\n"
-"从当å‰å¼€å§‹ï¼Œåœ¨ä¸¤ä¸ªå¯¹ç­‰ä½“之间建立WebRTCè¿žæŽ¥ï¼Œè¿™ä¸æ˜¯ä¸€é¡¹ç®€å•的任务,但它å¯ä»¥åˆ†"
-"解为3ä¸ªä¸»è¦æ­¥éª¤ã€‚\n"
+"从当å‰å¼€å§‹ï¼Œåœ¨ä¸¤ä¸ªå¯¹ç­‰ä½“之间建立 WebRTC è¿žæŽ¥ï¼Œè¿™ä¸æ˜¯ä¸€é¡¹ç®€å•的任务,但它å¯ä»¥"
+"分解为 3 ä¸ªä¸»è¦æ­¥éª¤ã€‚\n"
"- 想è¦å¯åŠ¨è¿žæŽ¥çš„å¯¹ç­‰ä½“ï¼ˆ[code]A[/code]从现在开始)创建一个æäº¤ï¼Œå¹¶å°†å…¶å‘é€ç»™"
"å¦ä¸€ä¸ªå¯¹ç­‰ä½“([code]B[/code]从现在开始)。\n"
-"- [code]B[/code]收到è¦çº¦ï¼Œç”Ÿæˆå’Œå›žç­”,并将其å‘é€ç»™[code]A[/code])。\n"
-"- [code]A[/code]å’Œ[code]B[/code]ç„¶åŽç”Ÿæˆå¹¶ç›¸äº’交æ¢ICE候选。\n"
+"- [code]B[/code] 收到è¦çº¦ï¼Œç”Ÿæˆå’Œå›žç­”,并将其å‘é€ç»™ [code]A[/code])。\n"
+"- [code]A[/code] å’Œ [code]B[/code] ç„¶åŽç”Ÿæˆå¹¶ç›¸äº’äº¤æ¢ ICE 候选。\n"
"在这些步骤之åŽï¼Œè¿žæŽ¥åº”该æˆåŠŸå»ºç«‹ã€‚ç»§ç»­é˜…è¯»æˆ–æŸ¥çœ‹æ•™ç¨‹ä»¥äº†è§£æ›´å¤šä¿¡æ¯ã€‚"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
@@ -92118,7 +92687,7 @@ msgid ""
"call [method initialize]."
msgstr ""
"关闭对等体连接和与之相关的所有数æ®é€šé“。\n"
-"[b]注æ„:[/b]ä½ ä¸èƒ½ä¸ºä¸€ä¸ªæ–°çš„连接é‡å¤ä½¿ç”¨è¿™ä¸ªå¯¹è±¡ï¼Œé™¤éžä½ è°ƒç”¨[method "
+"[b]注æ„:[/b]ä½ ä¸èƒ½ä¸ºä¸€ä¸ªæ–°çš„连接é‡å¤ä½¿ç”¨è¿™ä¸ªå¯¹è±¡ï¼Œé™¤éžä½ è°ƒç”¨ [method "
"initialize]。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
@@ -92197,14 +92766,14 @@ msgid ""
"session_description_created] will be called when the session is ready to be "
"sent."
msgstr ""
-"创建一个新的SDPæäº¤ï¼Œä»¥å¼€å§‹ä¸Žè¿œç¨‹å¯¹ç­‰ä½“çš„WebRTC连接。在调用此方法之å‰ï¼Œè‡³å°‘è¦"
-"创建一个[WebRTCDataChannel]。\n"
-"如果这个函数返回[constant OK],当会è¯å‡†å¤‡å¥½è¢«å‘逿—¶ï¼Œ[signal "
-"session_description_created]将被调用。"
+"创建一个新的 SDP æäº¤ï¼Œä»¥å¼€å§‹ä¸Žè¿œç¨‹å¯¹ç­‰ä½“çš„ WebRTC 连接。在调用此方法之å‰ï¼Œè‡³"
+"å°‘è¦åˆ›å»ºä¸€ä¸ª [WebRTCDataChannel]。\n"
+"如果这个函数返回 [constant OK],当会è¯å‡†å¤‡å¥½è¢«å‘逿—¶ï¼Œ[signal "
+"session_description_created] 将被调用。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid "Returns the connection state. See [enum ConnectionState]."
-msgstr "返回连接状æ€ã€‚å‚阅[enum ConnectionState]。"
+msgstr "返回连接状æ€ã€‚è§ [enum ConnectionState]。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid ""
@@ -92256,8 +92825,8 @@ msgid ""
"Call this method frequently (e.g. in [method Node._process] or [method Node."
"_physics_process]) to properly receive signals."
msgstr ""
-"ç»å¸¸è°ƒç”¨è¿™ä¸ªæ–¹æ³•以正确接收信å·ï¼Œä¾‹å¦‚在[method Node._process]或[method Node."
-"_physics_process]中。"
+"ç»å¸¸è°ƒç”¨è¿™ä¸ªæ–¹æ³•以正确接收信å·ï¼Œä¾‹å¦‚在 [method Node._process] 或 [method "
+"Node._physics_process] 中。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid ""
@@ -92267,10 +92836,10 @@ msgid ""
"ice_candidate_created] (unless an [enum Error] different from [constant OK] "
"is returned)."
msgstr ""
-"设置本地对等体的SDPæè¿°ã€‚这应是在å“应[signal session_description_created]æ—¶è°ƒ"
-"用的。\n"
-"调用此函数åŽï¼Œå¯¹ç­‰ä½“将开始å‘出[signal ice_candidate_created],除éžè¿”回与"
-"[constant OK]ä¸åŒçš„[enum Error]。"
+"设置本地对等体的 SDP æè¿°ã€‚这应是在å“应 [signal session_description_created] "
+"时调用的。\n"
+"调用此函数åŽï¼Œå¯¹ç­‰ä½“将开始å‘出 [signal ice_candidate_created],除éžè¿”回与 "
+"[constant OK] ä¸åŒçš„ [enum Error]。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid ""
@@ -92281,11 +92850,11 @@ msgid ""
"If [code]type[/code] is [code]answer[/code] the peer will start emitting "
"[signal ice_candidate_created]."
msgstr ""
-"设置远程对等体的SDPæè¿°ã€‚应用远程对等体产生的值æ¥è°ƒç”¨ï¼Œå¹¶é€šè¿‡ä¿¡å·æœåŠ¡å™¨æŽ¥"
+"设置远程对等体的 SDP æè¿°ã€‚应用远程对等体产生的值æ¥è°ƒç”¨ï¼Œå¹¶é€šè¿‡ä¿¡å·æœåŠ¡å™¨æŽ¥"
"收。\n"
-"如果[code]type[/code]是[code]offer[/code],对等体将å‘出[signal "
-"session_description_created]并给出适当的答案。\n"
-"如果[code]type[/code]是[code]answer[/code],对等体将开始å‘出[signal "
+"如果 [code]type[/code] 是 [code]offer[/code],对等体将å‘出 [signal "
+"session_description_created] 并给出适当的答案。\n"
+"如果 [code]type[/code] 是 [code]answer[/code],对等体将开始å‘出 [signal "
"ice_candidate_created]。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
@@ -92306,7 +92875,8 @@ msgid ""
"Emitted when a new ICE candidate has been created. The three parameters are "
"meant to be passed to the remote peer over the signaling server."
msgstr ""
-"当新的ICE候选者被创建时触å‘ã€‚è¿™ä¸‰ä¸ªå‚æ•°æ˜¯ä¸ºäº†é€šè¿‡ä¿¡å·æœåŠ¡å™¨ä¼ é€’ç»™è¿œç¨‹å¯¹ç­‰ä½“ã€‚"
+"当新的 ICE 候选者被创建时触å‘ã€‚è¿™ä¸‰ä¸ªå‚æ•°æ˜¯ä¸ºäº†é€šè¿‡ä¿¡å·æœåŠ¡å™¨ä¼ é€’ç»™è¿œç¨‹å¯¹ç­‰"
+"体。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid ""
@@ -92315,8 +92885,8 @@ msgid ""
"meant to be passed to [method set_local_description] on this object, and "
"sent to the remote peer over the signaling server."
msgstr ""
-"在æˆåŠŸè°ƒç”¨[method create_offer]或[method set_remote_description]åŽè§¦å‘,当它"
-"äº§ç”Ÿä¸€ä¸ªåº”ç­”æ—¶ã€‚è¿™äº›å‚æ•°æ˜¯ä¸ºäº†ä¼ é€’给这个对象上的[method "
+"在æˆåŠŸè°ƒç”¨ [method create_offer] 或 [method set_remote_description] åŽè§¦å‘,"
+"å½“å®ƒäº§ç”Ÿä¸€ä¸ªåº”ç­”æ—¶ã€‚è¿™äº›å‚æ•°æ˜¯ä¸ºäº†ä¼ é€’给这个对象上的 [method "
"set_local_description]ï¼Œå¹¶é€šè¿‡ä¿¡å·æœåС噍å‘é€ç»™è¿œç¨‹å¯¹ç­‰ä½“。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
@@ -92329,28 +92899,28 @@ msgstr "连接是新的,数æ®é€šé“å’Œæäº¤å¯ä»¥åœ¨è¿™ç§çжæ€ä¸‹åˆ›å»ºã€‚
msgid ""
"The peer is connecting, ICE is in progress, none of the transports has "
"failed."
-msgstr "对等体正在连接,ICE正在进行中,没有任何传输失败。"
+msgstr "对等体正在连接,ICE 正在进行中,没有任何传输失败。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid "The peer is connected, all ICE transports are connected."
-msgstr "对等体已连接,所有的ICE传输都已连接。"
+msgstr "对等体已连接,所有的 ICE 传输都已连接。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid "At least one ICE transport is disconnected."
-msgstr "至少有一个ICE传输被断开连接。"
+msgstr "至少有一个 ICE 传输被断开连接。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid "One or more of the ICE transports failed."
-msgstr "一个或更多的ICE传输失败。"
+msgstr "一个或更多的 ICE 传输失败。"
#: modules/webrtc/doc_classes/WebRTCPeerConnection.xml
msgid ""
"The peer connection is closed (after calling [method close] for example)."
-msgstr "对等连接已关闭,例如在调用[method close]åŽã€‚"
+msgstr "对等连接已关闭,例如在调用 [method close] åŽã€‚"
#: modules/websocket/doc_classes/WebSocketClient.xml
msgid "A WebSocket client implementation."
-msgstr "WebSocket客户端的实现。"
+msgstr "WebSocket 客户端的实现。"
#: modules/websocket/doc_classes/WebSocketClient.xml
msgid ""
@@ -92364,12 +92934,13 @@ msgid ""
"You will receive appropriate signals when connecting, disconnecting, or when "
"new data is available."
msgstr ""
-"该类实现了一个与任何符åˆRFC 6455çš„WebSocketæœåŠ¡å™¨å…¼å®¹çš„WebSocket客户端。\n"
-"这个客户端å¯ä»¥é€‰æ‹©æ€§åœ°ä½œä¸º[MultiplayerAPI]的网络对等体使用。\n"
-"在å¯åŠ¨å®¢æˆ·ç«¯åŽï¼ˆ[method connect_to_url]),你需è¦[method "
-"NetworkedMultiplayerPeer.poll]它以固定的时间间隔,例如在[method Node."
-"_process]内。\n"
-"å½“è¿žæŽ¥ã€æ–­å¼€è¿žæŽ¥æˆ–æœ‰æ–°æ•°æ®æ—¶ï¼Œä½ å°†æ”¶åˆ°é€‚当的信å·ã€‚"
+"该类实现了一个 WebSocket å®¢æˆ·ç«¯ï¼Œä¸Žä»»ä½•ç¬¦åˆ RFC 6455 çš„ WebSocket æœåС噍兼"
+"容。\n"
+"这个客户端å¯ä»¥é€‰æ‹©æ€§åœ°ä½œä¸º [MultiplayerAPI] 的网络对等体使用。\n"
+"在å¯åŠ¨å®¢æˆ·ç«¯åŽï¼ˆ[method connect_to_url]),你需è¦ä»¥å›ºå®šçš„æ—¶é—´é—´éš”调用 "
+"[method NetworkedMultiplayerPeer.poll](例如在 [method Node._process] "
+"内)。\n"
+"å½“è¿žæŽ¥ã€æ–­å¼€è¿žæŽ¥æˆ–æœ‰æ–°æ•°æ®æ—¶ï¼Œä½ å°†æ”¶åˆ°ç›¸åº”的信å·ã€‚"
#: modules/websocket/doc_classes/WebSocketClient.xml
msgid ""
@@ -92395,38 +92966,38 @@ msgid ""
"[b]Note:[/b] Specifying [code]custom_headers[/code] is not supported in "
"HTML5 exports due to browsers restrictions."
msgstr ""
-"连接到给定的URL,请求给定的[code]protocols[/code]之一作为å­å议。如果列表为"
-"空,默认为空,将ä¸è¯·æ±‚å­å议。\n"
-"如果[code]true[/code]作为[code]gd_mp_api[/code]被传递,客户端将表现得åƒ"
-"[MultiplayerAPI]的网络对等体,与éžGodotæœåŠ¡å™¨çš„è¿žæŽ¥å°†ä¸å·¥ä½œï¼Œå¹¶ä¸”[signal "
+"连接到给定的 URL,请求给定的 [code]protocols[/code] 之一作为å­å议。如果列表"
+"为空,默认为空,将ä¸è¯·æ±‚å­å议。\n"
+"如果 [code]true[/code] 作为 [code]gd_mp_api[/code] è¢«ä¼ é€’ï¼Œå®¢æˆ·ç«¯å°†è¡¨çŽ°å¾—åƒ "
+"[MultiplayerAPI] çš„ç½‘ç»œå¯¹ç­‰ä½“ï¼Œä¸Žéž Godot æœåŠ¡å™¨çš„è¿žæŽ¥å°†ä¸å·¥ä½œï¼Œå¹¶ä¸”[signal "
"data_received]å°†ä¸è¢«è§¦å‘。\n"
-"如果[code]false[/code]被传递,默认传递,你必须调用[PacketPeer]函数,"
-"[code]put_packet[/code], [code]get_packet[/code]等,对通过[code]get_peer(1)[/"
-"code]返回的[WebSocketPeer]ï¼Œè€Œä¸æ˜¯ç›´æŽ¥å¯¹è¯¥å¯¹è±¡ï¼Œä¾‹å¦‚,[code]get_peer(1)."
+"如果 [code]false[/code] 被传递,默认传递,你必须调用 [PacketPeer]函数,"
+"[code]put_packet[/code], [code]get_packet[/code] 等,对通过[code]get_peer(1)"
+"[/code] 返回的 [WebSocketPeer]ï¼Œè€Œä¸æ˜¯ç›´æŽ¥å¯¹è¯¥å¯¹è±¡ï¼Œä¾‹å¦‚ [code]get_peer(1)."
"put_packet(data)[/code]。\n"
-"ä½ å¯ä»¥é€‰æ‹©ä¼ é€’一个[code]custom_headers[/code]çš„åˆ—è¡¨ï¼Œä»¥æ·»åŠ åˆ°æ¡æ‰‹çš„HTTP请求"
-"中。\n"
-"[b]注æ„:[/b]为了é¿å…HTML5中的混åˆå†…容警告或错误,须使用以[code]wss://[/code]"
-"(安全)开头的[code]url[/code]ï¼Œè€Œä¸æ˜¯[code]ws://[/code]ã€‚è¿™æ ·åšæ—¶ï¼Œç¡®ä¿ä½¿ç”¨"
-"与æœåŠ¡å™¨çš„SSLè¯ä¹¦ä¸­å®šä¹‰çš„å®Œå…¨åˆæ ¼çš„域å。ä¸è¦ç›´æŽ¥é€šè¿‡IP地å€è¿›è¡Œ[code]wss://[/"
-"code]连接,因为它ä¸ä¼šä¸ŽSSLè¯ä¹¦ç›¸åŒ¹é…。\n"
-"[b]注æ„:[/b]由于æµè§ˆå™¨çš„é™åˆ¶ï¼ŒæŒ‡å®š[code]custom_headers[/code]在HTML5导出中ä¸"
-"被支æŒã€‚"
+"ä½ å¯ä»¥é€‰æ‹©ä¼ é€’一个 [code]custom_headers[/code] çš„åˆ—è¡¨ï¼Œä»¥æ·»åŠ åˆ°æ¡æ‰‹çš„ HTTP 请"
+"求中。\n"
+"[b]注æ„:[/b]为了é¿å… HTML5 中的混åˆå†…容警告或错误,须使用以 [code]wss://[/"
+"code](安全)开头的 [code]url[/code]ï¼Œè€Œä¸æ˜¯ [code]ws://[/code]ã€‚è¿™æ ·åšæ—¶ï¼Œç¡®"
+"ä¿ä½¿ç”¨ä¸ŽæœåŠ¡å™¨çš„ SSL è¯ä¹¦ä¸­å®šä¹‰çš„å®Œå…¨åˆæ ¼çš„域å。ä¸è¦ç›´æŽ¥é€šè¿‡ IP 地å€è¿›è¡Œ "
+"[code]wss://[/code] 连接,因为它ä¸ä¼šä¸Ž SSL è¯ä¹¦ç›¸åŒ¹é…。\n"
+"[b]注æ„:[/b]由于æµè§ˆå™¨çš„é™åˆ¶ï¼ŒæŒ‡å®š [code]custom_headers[/code] 在 HTML5 导出"
+"中ä¸è¢«æ”¯æŒã€‚"
#: modules/websocket/doc_classes/WebSocketClient.xml
msgid ""
"Disconnects this client from the connected host. See [method WebSocketPeer."
"close] for more information."
msgstr ""
-"断开此客户端与所连接主机的连接。更多信æ¯å‚阅[method WebSocketPeer.close]。"
+"断开此客户端与所连接主机的连接。详情请å‚阅 [method WebSocketPeer.close]。"
#: modules/websocket/doc_classes/WebSocketClient.xml
msgid "Return the IP address of the currently connected host."
-msgstr "返回当å‰è¿žæŽ¥çš„主机的IP地å€ã€‚"
+msgstr "返回当å‰è¿žæŽ¥çš„主机的 IP 地å€ã€‚"
#: modules/websocket/doc_classes/WebSocketClient.xml
msgid "Return the IP port of the currently connected host."
-msgstr "返回当å‰è¿žæŽ¥çš„主机的IP端å£ã€‚"
+msgstr "返回当å‰è¿žæŽ¥çš„主机的 IP 端å£ã€‚"
#: modules/websocket/doc_classes/WebSocketClient.xml
msgid ""
@@ -92436,9 +93007,9 @@ msgid ""
"[b]Note:[/b] Specifying a custom [code]trusted_ssl_certificate[/code] is not "
"supported in HTML5 exports due to browsers restrictions."
msgstr ""
-"如果指定,该[X509Certificate]将是连接到SSL主机时唯一接å—çš„è¯ä¹¦ã€‚任何由æœåС噍"
-"æä¾›çš„å…¶ä»–è¯ä¹¦å°†è¢«è§†ä¸ºæ— æ•ˆã€‚\n"
-"[b]注æ„:[/b]由于æµè§ˆå™¨çš„é™åˆ¶ï¼Œåœ¨HTML5å¯¼å‡ºä¸­ä¸æ”¯æŒæŒ‡å®šä¸€ä¸ªè‡ªå®šä¹‰çš„"
+"如果指定,该 [X509Certificate] 将是连接到 SSL 主机时唯一接å—çš„è¯ä¹¦ã€‚任何由æœ"
+"务器æä¾›çš„å…¶ä»–è¯ä¹¦å°†è¢«è§†ä¸ºæ— æ•ˆã€‚\n"
+"[b]注æ„:[/b]由于æµè§ˆå™¨çš„é™åˆ¶ï¼Œåœ¨ HTML5 å¯¼å‡ºä¸­ä¸æ”¯æŒæŒ‡å®šä¸€ä¸ªè‡ªå®šä¹‰çš„ "
"[code]trusted_ssl_certificate[/code]。"
#: modules/websocket/doc_classes/WebSocketClient.xml
@@ -92447,7 +93018,7 @@ msgid ""
"[b]Note:[/b] You must specify the certificates to be used in the Project "
"Settings for it to work when exported."
msgstr ""
-"如果 [code]true[/code],则å¯ç”¨ SSL è¯ä¹¦éªŒè¯ã€‚\n"
+"如果为 [code]true[/code],则å¯ç”¨ SSL è¯ä¹¦éªŒè¯ã€‚\n"
"[b]注æ„:[/b]你必须在项目设置中指定è¦ä½¿ç”¨çš„è¯ä¹¦ï¼Œä»¥ä¾¿åœ¨å¯¼å‡ºæ—¶å‘挥作用。"
#: modules/websocket/doc_classes/WebSocketClient.xml
@@ -92455,7 +93026,7 @@ msgid ""
"Emitted when the connection to the server is closed. [code]was_clean_close[/"
"code] will be [code]true[/code] if the connection was shutdown cleanly."
msgstr ""
-"当与æœåŠ¡å™¨çš„è¿žæŽ¥è¢«å…³é—­æ—¶è§¦å‘。[code]was_clean_close[/code] 将是[code]true[/"
+"当与æœåŠ¡å™¨çš„è¿žæŽ¥è¢«å…³é—­æ—¶è§¦å‘。[code]was_clean_close[/code] 将是 [code]true[/"
"code] 如果连接完全关闭。"
#: modules/websocket/doc_classes/WebSocketClient.xml
@@ -92467,8 +93038,8 @@ msgid ""
"Emitted when a connection with the server is established, [code]protocol[/"
"code] will contain the sub-protocol agreed with the server."
msgstr ""
-"当与æœåŠ¡å™¨å»ºç«‹è¿žæŽ¥æ—¶è§¦å‘,[code]protocol[/code]å议将包å«ä¸ŽæœåŠ¡å™¨è¾¾æˆä¸€è‡´çš„å­"
-"å议。"
+"当与æœåŠ¡å™¨å»ºç«‹è¿žæŽ¥æ—¶è§¦å‘,[code]protocol[/code] 将包å«ä¸ŽæœåŠ¡å™¨è¾¾æˆä¸€è‡´çš„å­å"
+"议。"
#: modules/websocket/doc_classes/WebSocketClient.xml
msgid ""
@@ -92485,9 +93056,9 @@ msgid ""
"until you get a [signal connection_closed] signal to achieve the clean "
"close. See [method WebSocketPeer.close] for more details."
msgstr ""
-"当æœåŠ¡å™¨è¯·æ±‚å®Œå…¨å…³é—­æ—¶è§¦å‘。你应该继续进行轮询,直到获得[signal "
-"connection_closed]ä¿¡å·ï¼Œä»¥å®žçŽ°å½»åº•çš„å…³é—­ã€‚æ›´å¤šç»†èŠ‚å‚阅[method WebSocketPeer."
-"close]。"
+"当æœåŠ¡å™¨è¯·æ±‚å®Œå…¨å…³é—­æ—¶è§¦å‘。你应该继续进行轮询,直到获得 [signal "
+"connection_closed] ä¿¡å·ï¼Œä»¥å®žçŽ°å½»åº•çš„å…³é—­ã€‚æ›´å¤šç»†èŠ‚å‚阅 [method "
+"WebSocketPeer.close]。"
#: modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
msgid "Base class for WebSocket server and client."
@@ -92518,13 +93089,13 @@ msgid ""
"[b]Note:[/b] HTML5 exports only use the input buffer since the output one is "
"managed by browsers."
msgstr ""
-"é…置该WebSocket对等体的缓冲区大å°ã€‚默认值å¯ä»¥åœ¨é¡¹ç›®è®¾ç½®ä¸­çš„[code]network/"
-"limits[/code]下指定。对于æœåŠ¡å™¨ï¼Œæ•°å€¼æ˜¯æŒ‡æ¯ä¸ªè¿žæŽ¥çš„对等体。\n"
+"é…置该 WebSocket 对等体的缓冲区大å°ã€‚默认值å¯ä»¥åœ¨é¡¹ç›®è®¾ç½®ä¸­çš„ [code]network/"
+"limits[/code] 下指定。对于æœåŠ¡å™¨ï¼Œæ•°å€¼æ˜¯æŒ‡æ¯ä¸ªè¿žæŽ¥çš„对等体。\n"
"å‰ä¸¤ä¸ªå‚数定义了输入缓冲区的大å°å’ŒæŽ’队数æ®åŒ…çš„é™åˆ¶ï¼ŒåŽä¸¤ä¸ªå‚数定义了输出缓冲"
"区。\n"
-"缓冲区的大å°ä»¥KiB为å•ä½ï¼Œæ‰€ä»¥[code]4=2^12=4096字节[/code]ã€‚æ‰€æœ‰çš„å‚æ•°éƒ½å°†è¢«å››"
-"èˆäº”入到最接近的2的幂。\n"
-"[b]注æ„:[/b]HTML5输出åªä½¿ç”¨è¾“入缓冲区,因为输出缓冲区是由æµè§ˆå™¨ç®¡ç†çš„。"
+"缓冲区的大å°ä»¥ KiB 为å•ä½ï¼Œæ‰€ä»¥ [code]4=2^12=4096字节[/code]ã€‚æ‰€æœ‰çš„å‚æ•°éƒ½å°†"
+"被四èˆäº”入到最接近的 2 的幂。\n"
+"[b]注æ„:[/b]HTML5 输出åªä½¿ç”¨è¾“入缓冲区,因为输出缓冲区是由æµè§ˆå™¨ç®¡ç†çš„。"
#: modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml
msgid ""
@@ -92562,13 +93133,13 @@ msgid ""
"[b]Note:[/b] The HTML5 export might not support all status codes. Please "
"refer to browser-specific documentation for more details."
msgstr ""
-"关闭此WebSocket连接。[code]code[/code]是关闭的状æ€ä»£ç ï¼Œæœ‰æ•ˆçжæ€ä»£ç çš„列表å‚"
-"阅RFC 6455第7.4节。[code]reason[/code] 是关闭连接的åªè¯»åŽŸå› ï¼ˆå¯ä»¥æ˜¯ä»»ä½•å°äºŽ"
-"123字节的UTF-8字符串)。\n"
-"[b]注æ„:[/b]为了实现彻底的关闭,你需è¦ç»§ç»­è½®è¯¢ï¼Œç›´åˆ°æ”¶åˆ°[signal "
-"WebSocketClient.connection_closed]或[signal WebSocketServer."
+"关闭此 WebSocket 连接。[code]code[/code] 是关闭的状æ€ä»£ç ï¼Œæœ‰æ•ˆçжæ€ä»£ç çš„列表"
+"å‚阅 RFC 6455 第 7.4 节。[code]reason[/code] 是关闭连接的åªè¯»åŽŸå› ï¼ˆå¯ä»¥æ˜¯ä»»ä½•"
+"å°äºŽ 123 字节的 UTF-8 字符串)。\n"
+"[b]注æ„:[/b]为了实现彻底的关闭,你需è¦ç»§ç»­è½®è¯¢ï¼Œç›´åˆ°æ”¶åˆ° [signal "
+"WebSocketClient.connection_closed] 或 [signal WebSocketServer."
"client_disconnected]。\n"
-"[b]注æ„:[/b]HTML5导出å¯èƒ½ä¸æ”¯æŒæ‰€æœ‰çжæ€ä»£ç ã€‚请å‚考特定æµè§ˆå™¨çš„æ–‡æ¡£ä»¥äº†è§£æ›´"
+"[b]注æ„:[/b]HTML5 导出å¯èƒ½ä¸æ”¯æŒæ‰€æœ‰çжæ€ä»£ç ã€‚请å‚考特定æµè§ˆå™¨çš„æ–‡æ¡£ä»¥äº†è§£æ›´"
"多细节。"
#: modules/websocket/doc_classes/WebSocketPeer.xml
@@ -92593,12 +93164,12 @@ msgid ""
"[/b] HTML5 exports use WebSocket.bufferedAmount, while other platforms use "
"an internal buffer."
msgstr ""
-"返回输出的websocketç¼“å†²åŒºä¸­çš„å½“å‰æ•°æ®é‡ã€‚[b]注æ„:[/b]HTML5导出使用WebSocket."
-"bufferedAmount,而其他平å°ä½¿ç”¨å†…部缓冲区。"
+"返回输出的 websocket ç¼“å†²åŒºä¸­çš„å½“å‰æ•°æ®é‡ã€‚[b]注æ„:[/b]HTML5 导出使用 "
+"WebSocket.bufferedAmount,而其他平å°ä½¿ç”¨å†…部缓冲区。"
#: modules/websocket/doc_classes/WebSocketPeer.xml
msgid "Gets the current selected write mode. See [enum WriteMode]."
-msgstr "获å–当å‰é€‰æ‹©çš„写入模å¼ã€‚å‚阅[enum WriteMode]。"
+msgstr "获å–当å‰é€‰æ‹©çš„写入模å¼ã€‚è§ [enum WriteMode]。"
#: modules/websocket/doc_classes/WebSocketPeer.xml
msgid "Returns [code]true[/code] if this peer is currently connected."
@@ -92623,24 +93194,24 @@ msgid ""
"Returns [code]true[/code] if the last received packet was sent as a text "
"payload. See [enum WriteMode]."
msgstr ""
-"å¦‚æžœæœ€åŽæ”¶åˆ°çš„æ•°æ®åŒ…是作为文本有效载è·å‘é€çš„,返回 [code]true[/code]。å‚阅"
+"å¦‚æžœæœ€åŽæ”¶åˆ°çš„æ•°æ®åŒ…是作为文本有效载è·å‘é€çš„,返回 [code]true[/code]ã€‚è§ "
"[enum WriteMode]。"
#: modules/websocket/doc_classes/WebSocketPeer.xml
msgid ""
"Specifies that WebSockets messages should be transferred as text payload "
"(only valid UTF-8 is allowed)."
-msgstr "指定WebSockets消æ¯åº”作为文本有效载è·ä¼ è¾“(åªå…许有效的UTF-8)。"
+msgstr "指定 WebSockets 消æ¯åº”作为文本有效载è·ä¼ è¾“(åªå…许有效的 UTF-8)。"
#: modules/websocket/doc_classes/WebSocketPeer.xml
msgid ""
"Specifies that WebSockets messages should be transferred as binary payload "
"(any byte combination is allowed)."
-msgstr "指定WebSockets消æ¯åº”以二进制有效载è·çš„å½¢å¼ä¼ è¾“(å…许任何字节组åˆï¼‰ã€‚"
+msgstr "指定 WebSockets 消æ¯åº”以二进制有效载è·çš„å½¢å¼ä¼ è¾“(å…许任何字节组åˆï¼‰ã€‚"
#: modules/websocket/doc_classes/WebSocketServer.xml
msgid "A WebSocket server implementation."
-msgstr "WebSocketæœåŠ¡å™¨çš„å®žçŽ°ã€‚"
+msgstr "WebSocket æœåŠ¡å™¨çš„å®žçŽ°ã€‚"
#: modules/websocket/doc_classes/WebSocketServer.xml
msgid ""
@@ -92663,7 +93234,7 @@ msgid ""
"Disconnects the peer identified by [code]id[/code] from the server. See "
"[method WebSocketPeer.close] for more information."
msgstr ""
-"断开由[code]id[/code]标识的对等体与æœåŠ¡å™¨çš„è¿žæŽ¥ã€‚æ›´å¤šä¿¡æ¯å‚阅[method "
+"断开由 [code]id[/code] 标识的对等体与æœåŠ¡å™¨çš„è¿žæŽ¥ã€‚è¯¦æƒ…è¯·å‚阅 [method "
"WebSocketPeer.close]。"
#: modules/websocket/doc_classes/WebSocketServer.xml
@@ -92691,15 +93262,16 @@ msgid ""
"[code]get_peer(id).get_available_packet_count[/code])."
msgstr ""
"在给定的端å£ä¸Šå¼€å§‹ç›‘å¬ã€‚\n"
-"ä½ å¯ä»¥é€šè¿‡ \"åè®®\" 数组指定所需的å­å议。如果列表为空(默认情况下),将ä¸è¯·"
+"ä½ å¯ä»¥é€šè¿‡â€œprotocolsâ€æ•°ç»„指定所需的å­å议。如果列表为空(默认情况下),将ä¸è¯·"
"求任何å­å议。\n"
-"如果[code]true[/code]作为[code]gd_mp_api[/code]传递,æœåŠ¡å™¨å°†è¡¨çŽ°å¾—åƒ"
-"[MultiplayerAPI]的网络对等体,æ¥è‡ªéžGodot客户端的连接将ä¸å·¥ä½œï¼Œå¹¶ä¸”[signal "
-"data_received]å°†ä¸è¢«è§¦å‘。\n"
-"如果[code]false[/code]被传递(默认),你必须调用[PacketPeer]函数"
-"([code]put_packet[/code], [code]get_packet[/code], etc.),在通过"
-"[code]get_peer(id)[/code]返回的[WebSocketPeer]上,与具有给定[code]id[/code]的"
-"对等体进行通信,例如,[code]get_peer(id).get_available_packet_count[/code]。"
+"如果传递的 [code]gd_mp_api[/code] 为 [code]true[/code],æœåŠ¡å™¨å°†è¡¨çŽ°å¾—åƒ "
+"[MultiplayerAPI] 的网络对等体,æ¥è‡ªéž Godot 客户端的连接将ä¸å·¥ä½œï¼Œå¹¶ä¸” "
+"[signal data_received] å°†ä¸è¢«è§¦å‘。\n"
+"如果传递的是 [code]false[/code](默认),你必须调用 [PacketPeer] 函数"
+"([code]put_packet[/code]ã€[code]get_packet[/code] 等),在通过 "
+"[code]get_peer(id)[/code] 返回的 [WebSocketPeer] 上,与具有给定 [code]id[/"
+"code] 的对等体进行通信(例如 [code]get_peer(id).get_available_packet_count[/"
+"code])。"
#: modules/websocket/doc_classes/WebSocketServer.xml
msgid ""
@@ -92716,8 +93288,9 @@ msgid ""
"specified IP address. Setting [code]bind_ip[/code] to [code]127.0.0.1[/code] "
"will cause the server to listen only to the local host."
msgstr ""
-"当ä¸è®¾ç½®ä¸º[code]*[/code]时,将é™åˆ¶è¿›å…¥çš„连接到指定的IP地å€ã€‚å°†[code]bind_ip[/"
-"code]设置为[code]127.0.0.1[/code]将导致æœåС噍åªç›‘嬿œ¬åœ°ä¸»æœºã€‚"
+"当ä¸è®¾ç½®ä¸º [code]*[/code] 时,将é™åˆ¶è¿›å…¥çš„连接到指定的 IP 地å€ã€‚å°† "
+"[code]bind_ip[/code] 设置为 [code]127.0.0.1[/code] 将导致æœåС噍åªç›‘嬿œ¬åœ°ä¸»"
+"机。"
#: modules/websocket/doc_classes/WebSocketServer.xml
msgid ""
@@ -92743,8 +93316,8 @@ msgid ""
"cause the server to require SSL instead of regular TCP (i.e. the [code]wss://"
"[/code] protocol)."
msgstr ""
-"当设置为有效的[CryptoKey]时,与[member ssl_certificate]一起,将导致æœåŠ¡å™¨éœ€è¦"
-"SSLè€Œä¸æ˜¯æ™®é€šçš„TCP,å³[code]wss://[/code]å议。"
+"当设置为有效的 [CryptoKey] 时,与 [member ssl_certificate] 一起,将导致æœåС噍"
+"éœ€è¦ SSL è€Œä¸æ˜¯æ™®é€šçš„ TCPï¼Œå³ [code]wss://[/code] å议。"
#: modules/websocket/doc_classes/WebSocketServer.xml
msgid ""
@@ -92752,8 +93325,8 @@ msgid ""
"cause the server to require SSL instead of regular TCP (i.e. the [code]wss://"
"[/code] protocol)."
msgstr ""
-"当设置为有效的[X509Certificate]时,连åŒ[member private_key],将导致æœåŠ¡å™¨éœ€è¦"
-"SSLè€Œä¸æ˜¯æ™®é€šçš„TCP,å³[code]wss://[/code]å议。"
+"当设置为有效的 [X509Certificate] æ—¶ï¼Œè¿žåŒ [member private_key],将导致æœåС噍"
+"éœ€è¦ SSL è€Œä¸æ˜¯æ™®é€šçš„ TCPï¼Œå³ [code]wss://[/code] å议。"
#: modules/websocket/doc_classes/WebSocketServer.xml
msgid ""
@@ -92947,7 +93520,7 @@ msgstr ""
" webxr_interface.xr_standard_mapping = true\n"
"\n"
" # WebXR使用了大é‡çš„异步回调,\n"
-" # 所以我们è¦è¿žæŽ¥å„ç§ä¿¡å·æ¥æŽ¥æ”¶å®ƒä»¬ã€‚ \n"
+" # 所以我们è¦è¿žæŽ¥å„ç§ä¿¡å·æ¥æŽ¥æ”¶å®ƒä»¬ã€‚ \n"
" webxr_interface.connect(\"session_supported\", self, "
"\"_webxr_session_supported\")\n"
" webxr_interface.connect(\"session_started\", self, "
@@ -92959,7 +93532,7 @@ msgstr ""
"\n"
" # 这将立å³è¿”回——自身的_webxr_session_supported()方法\n"
" # (我们在上é¢è¿žæŽ¥äº†'session_supported' ä¿¡å·)将在ç¨åŽè¢«è°ƒç”¨\n"
-" # 让我们知é“它是å¦è¢«æ”¯æŒã€‚ \n"
+" # 让我们知é“它是å¦è¢«æ”¯æŒã€‚ \n"
" webxr_interface.is_session_supported(\"immersive-vr\")\n"
"\n"
"func _webxr_session_supported(session_mode, supported):\n"
@@ -92972,7 +93545,7 @@ msgstr ""
" return\n"
"\n"
" # 获得沉浸å¼çš„VRä½“éªŒï¼Œè€Œä¸æ˜¯AR('immersive-ar')\n"
-" # 或一个简å•çš„3DoF查看器('viewer')。 \n"
+" # 或一个简å•çš„3DoF查看器('viewer')。 \n"
" webxr_interface.session_mode = 'immersive-vr'\n"
" # 'bounded-floor'是房间大å°ï¼Œ'local-floor'æ˜¯ç«™ç€æˆ–åç€çš„\n"
" # 体验(如果你有3DoF耳机,它会让你离地é¢1.6米)。\n"
@@ -93002,7 +93575,7 @@ msgstr ""
" get_viewport().arvr = true\n"
" # 这将是您从上é¢è¯·æ±‚的类型中最终得到的引用空间类型。\n"
" # 如果你想让游æˆåœ¨'bounded-floor'å’Œ 'local-floor' 中有一点ä¸åŒï¼Œ\n"
-" # 这是很有用的。 \n"
+" # 这是很有用的。 \n"
" print (\"Reference space type: \" + webxr_interface."
"reference_space_type)\n"
"\n"
@@ -93057,10 +93630,10 @@ msgid ""
"- [signal squeezestart]"
msgstr ""
"获å–给定 [code]controller_id[/code] çš„ [ARVRPositionalTracker]。\n"
-"在 WebXR 的上下文中, \"controller\"控制器å¯ä»¥æ˜¯é«˜çº§ VR 控制器,如 Oculus "
-"Touch 或 Index 控制器,甚至å¯ä»¥æ˜¯å±å¹•上的点击ã€è¯­éŸ³å‘½ä»¤æˆ–设备本身的按钮按下。"
-"当使用éžä¼ ç»ŸæŽ§åˆ¶å™¨æ—¶ï¼Œå°† [ARVRPositionalTracker] çš„ä½ç½®å’Œæ–¹å‘解释为指å‘用户希"
-"望与之交互的对象的射线。\n"
+"在 WebXR 的上下文中,“controllerâ€æŽ§åˆ¶å™¨å¯ä»¥æ˜¯é«˜çº§ VR 控制器,如 Oculus Touch "
+"或 Index 控制器,甚至å¯ä»¥æ˜¯å±å¹•上的点击ã€è¯­éŸ³å‘½ä»¤æˆ–设备本身的按钮按下。当使用"
+"éžä¼ ç»ŸæŽ§åˆ¶å™¨æ—¶ï¼Œå°† [ARVRPositionalTracker] çš„ä½ç½®å’Œæ–¹å‘解释为指å‘用户希望与之"
+"交互的对象的射线。\n"
"ä½¿ç”¨æ­¤æ–¹æ³•èŽ·å–æœ‰å…³è§¦å‘以下信å·ä¹‹ä¸€çš„æŽ§åˆ¶å™¨çš„ä¿¡æ¯ï¼š\n"
"- [signal selectstart]\n"
"- [signal select]\n"
@@ -93091,11 +93664,11 @@ msgid ""
"This method returns nothing, instead it emits the [signal session_supported] "
"signal with the result."
msgstr ""
-"检查给定的[code]session_mode[/code]是å¦è¢«ç”¨æˆ·çš„æµè§ˆå™¨æ”¯æŒã€‚\n"
-"å¯èƒ½çš„值æ¥è‡ª[url=https://developer.mozilla.org/en-US/docs/Web/API/"
-"XRSessionMode]WebXR的XRSessionMode[/url],包括:[code]\"immersive-vr\"[/"
-"code], [code]\"immersive-ar\"[/code], 和[code]\"inline\"[/code]。\n"
-"此方法ä¸è¿”回任何东西,而是将结果å‘é€ç»™[signal session_supported]ä¿¡å·ã€‚"
+"检查给定的 [code]session_mode[/code] 是å¦è¢«ç”¨æˆ·çš„æµè§ˆå™¨æ”¯æŒã€‚\n"
+"å¯èƒ½çš„值æ¥è‡ª [url=https://developer.mozilla.org/en-US/docs/Web/API/"
+"XRSessionMode]WebXR 的 XRSessionMode[/url],包括:[code]\"immersive-vr\"[/"
+"code]ã€[code]\"immersive-ar\"[/code] å’Œ [code]\"inline\"[/code]。\n"
+"此方法ä¸è¿”回任何东西,而是将结果å‘é€ç»™ [signal session_supported] ä¿¡å·ã€‚"
#: modules/webxr/doc_classes/WebXRInterface.xml
msgid ""
@@ -93144,12 +93717,13 @@ msgid ""
"use a particular reference space type, it must be listed in either [member "
"required_features] or [member optional_features]."
msgstr ""
-"引用空间类型,æ¥è‡ª[member requested_reference_space_types]属性中设置的请求类"
-"型列表,最终由[method ARVRInterface.initialize]在设置WebXRä¼šè¯æ—¶ä½¿ç”¨ã€‚\n"
-"å¯èƒ½çš„值æ¥è‡ª[url=https://developer.mozilla.org/en-US/docs/Web/API/"
-"XRReferenceSpaceType]WebXR的XRReferenceSpaceType[/url]。如果你想使用一个特定"
-"的引用空间类型,它必须被列入[member required_features]或[member "
-"optional_features]中。"
+"引用空间类型,æ¥è‡ª [member requested_reference_space_types] 属性中设置的请求"
+"类型列表,最终由 [method ARVRInterface.initialize] 在设置 WebXR ä¼šè¯æ—¶ä½¿"
+"用。\n"
+"å¯èƒ½çš„值æ¥è‡ª [url=https://developer.mozilla.org/en-US/docs/Web/API/"
+"XRReferenceSpaceType]WebXR 的 XRReferenceSpaceType[/url]。如果你想使用一个特"
+"定的引用空间类型,它必须被列入 [member required_features] 或 [member "
+"optional_features] 中。"
#: modules/webxr/doc_classes/WebXRInterface.xml
msgid ""
@@ -93167,7 +93741,7 @@ msgid ""
msgstr ""
"[method ARVRInterface.initialize] 设置 WebXR ä¼šè¯æ—¶ä½¿ç”¨çš„引用空间类型的逗å·åˆ†"
"隔列表。\n"
-"按顺åºè¯·æ±‚引用空间类型,将使用用户设备或æµè§ˆå™¨æ”¯æŒçš„第一个。 [member "
+"按顺åºè¯·æ±‚引用空间类型,将使用用户设备或æµè§ˆå™¨æ”¯æŒçš„第一个。[member "
"reference_space_type] å±žæ€§åŒ…å«æœ€ç»ˆä½¿ç”¨çš„引用空间类型。\n"
"这对已ç»åˆå§‹åŒ–çš„æŽ¥å£æ²¡æœ‰ä»»ä½•å½±å“。\n"
"å¯èƒ½çš„值æ¥è‡ª [url=https://developer.mozilla.org/en-US/docs/Web/API/"
@@ -93206,11 +93780,11 @@ msgid ""
"API/XRSessionMode]WebXR's XRSessionMode[/url], including: [code]\"immersive-"
"vr\"[/code], [code]\"immersive-ar\"[/code], and [code]\"inline\"[/code]."
msgstr ""
-"设置WebXRä¼šè¯æ—¶ï¼Œ[method ARVRInterface.initialize]æ‰€ä½¿ç”¨çš„ä¼šè¯æ¨¡å¼ã€‚\n"
+"设置 WebXR ä¼šè¯æ—¶ï¼Œ[method ARVRInterface.initialize] æ‰€ä½¿ç”¨çš„ä¼šè¯æ¨¡å¼ã€‚\n"
"在已ç»åˆå§‹åŒ–çš„æƒ…å†µä¸‹ï¼Œè¿™å¯¹æŽ¥å£æ²¡æœ‰ä»»ä½•å½±å“。\n"
-"å¯èƒ½çš„值æ¥è‡ª[url=https://developer.mozilla.org/en-US/docs/Web/API/"
-"XRSessionMode]WebXR的XRSessionMode[/url],包括:[code]\"immersive-vr\"[/"
-"code], [code]\"immersive-ar\"[/code], 和[code]\"inline\"[/code]。"
+"å¯èƒ½çš„值æ¥è‡ª [url=https://developer.mozilla.org/en-US/docs/Web/API/"
+"XRSessionMode]WebXR 的 XRSessionMode[/url],包括:[code]\"immersive-vr\"[/"
+"code]ã€[code]\"immersive-ar\"[/code] å’Œ [code]\"inline\"[/code]。"
#: modules/webxr/doc_classes/WebXRInterface.xml
msgid ""
@@ -93223,7 +93797,7 @@ msgstr ""
"指示用户是å¦å¯ä»¥çœ‹åˆ° WebXR 会è¯çš„图åƒã€‚\n"
"å¯èƒ½çš„值æ¥è‡ª [url=https://developer.mozilla.org/en-US/docs/Web/API/"
"XRVisibilityState]WebXR 的 XRVisibilityState[/url],包括 [code]\"hidden\"[/"
-"code], [code]\"visible\"[/code], 和 [code]\"visible-blurred\"[/code]。"
+"code]ã€[code]\"visible\"[/code] å’Œ [code]\"visible-blurred\"[/code]。"
#: modules/webxr/doc_classes/WebXRInterface.xml
msgid ""
@@ -93296,9 +93870,9 @@ msgid ""
"[code]message[/code] may optionally contain an error message from WebXR, or "
"an empty string if no message is available."
msgstr ""
-"如果会è¯å¯åŠ¨å¤±è´¥ï¼Œç”±[method ARVRInterface.initialize]触å‘。\n"
-"[code]message[/code]å¯ä»¥é€‰æ‹©åŒ…å«ä¸€ä¸ªæ¥è‡ªWebXR的错误信æ¯ï¼Œå¦‚果没有信æ¯ï¼Œåˆ™ä¸ºç©º"
-"字符串。"
+"如果会è¯å¯åŠ¨å¤±è´¥ï¼Œç”± [method ARVRInterface.initialize] 触å‘。\n"
+"[code]message[/code] å¯ä»¥é€‰æ‹©åŒ…å«ä¸€ä¸ªæ¥è‡ª WebXR 的错误信æ¯ï¼Œå¦‚果没有信æ¯ï¼Œåˆ™"
+"为空字符串。"
#: modules/webxr/doc_classes/WebXRInterface.xml
msgid ""
@@ -93307,17 +93881,17 @@ msgid ""
"At this point, it's safe to do [code]get_viewport().arvr = true[/code] to "
"instruct Godot to start rendering to the AR/VR device."
msgstr ""
-"å¦‚æžœä¼šè¯æˆåŠŸå¯åŠ¨ï¼Œç”±[method ARVRInterface.initialize]触å‘。\n"
-"此时,应该执行[code]get_viewport().arvr = true[/code]æ¥æŒ‡ç¤ºGodot开始å‘AR/VR设"
-"备进行渲染是安全的。"
+"å¦‚æžœä¼šè¯æˆåŠŸå¯åŠ¨ï¼Œç”± [method ARVRInterface.initialize] 触å‘。\n"
+"此时,应该执行 [code]get_viewport().arvr = true[/code] æ¥æŒ‡ç¤º Godot å¼€å§‹å‘ "
+"AR/VR 设备进行渲染是安全的。"
#: modules/webxr/doc_classes/WebXRInterface.xml
msgid ""
"Emitted by [method is_session_supported] to indicate if the given "
"[code]session_mode[/code] is supported or not."
msgstr ""
-"ç”±[method is_session_supported]触å‘ï¼Œè¡¨ç¤ºæ˜¯å¦æ”¯æŒæŒ‡å®šçš„[code]session_mode[/"
-"code]。"
+"ç”± [method is_session_supported] 触å‘ï¼Œè¡¨ç¤ºæ˜¯å¦æ”¯æŒæŒ‡å®šçš„ "
+"[code]session_mode[/code]。"
#: modules/webxr/doc_classes/WebXRInterface.xml
msgid ""
@@ -93351,7 +93925,7 @@ msgstr ""
#: modules/webxr/doc_classes/WebXRInterface.xml
msgid "Emitted when [member visibility_state] has changed."
-msgstr "当[member visibility_state]已更改时触å‘。"
+msgstr "当 [member visibility_state] 已更改时触å‘。"
#: modules/webxr/doc_classes/WebXRInterface.xml
msgid "We don't know the target ray mode."
@@ -93381,8 +93955,8 @@ msgid ""
"default toplevel [Control] that draws a window decoration and allows motion "
"and resizing."
msgstr ""
-"Windowdialog是所有基于窗å£çš„å¯¹è¯æ¡†çš„基类。它是一个默认的顶层[Control]控件,å¯"
-"以绘制一个窗å£è£…饰,并å…许移动和调整大å°ã€‚"
+"Windowdialog 是所有基于窗å£çš„å¯¹è¯æ¡†çš„基类。它是一个默认的顶层 [Control] 控"
+"件,å¯ä»¥ç»˜åˆ¶ä¸€ä¸ªçª—å£è£…饰,并å…许移动和调整大å°ã€‚"
#: doc/classes/WindowDialog.xml
msgid ""
@@ -93397,7 +93971,7 @@ msgstr ""
#: doc/classes/WindowDialog.xml
msgid "If [code]true[/code], the user can resize the window."
-msgstr "如果[code]true[/code],用户å¯ä»¥è°ƒæ•´çª—å£å¤§å°ã€‚"
+msgstr "如果为 [code]true[/code],用户å¯ä»¥è°ƒæ•´çª—å£å¤§å°ã€‚"
#: doc/classes/WindowDialog.xml
msgid "The text displayed in the window's title bar."
@@ -93415,7 +93989,7 @@ msgstr "关闭按钮的水平å移。"
msgid ""
"The thickness of the border that can be dragged when scaling the window (if "
"[member resizable] is enabled)."
-msgstr "ç¼©æ”¾çª—å£æ—¶å¯ä»¥æ‹–动的边框的粗细,如果å¯ç”¨äº†[member resizable]。"
+msgstr "ç¼©æ”¾çª—å£æ—¶å¯ä»¥æ‹–动的边框的粗细,如果å¯ç”¨äº† [member resizable]。"
#: doc/classes/WindowDialog.xml
msgid "The vertical offset of the title text."
@@ -93464,16 +94038,13 @@ msgstr "ç›´æŽ¥è®¿é—®ä¸–ç•Œç‰©ç† 3D 空间状æ€ã€‚用于查询当å‰å’Œæ½œåœ¨çš
#: doc/classes/World.xml
msgid "The World's [Environment]."
-msgstr "World的[Environment]环境。"
+msgstr "World 的 [Environment] 环境。"
#: doc/classes/World.xml
-#, fuzzy
msgid ""
"The World's fallback environment will be used if [member environment] fails "
"or is missing."
-msgstr ""
-"如果 World 的 [Environment] 失败或丢失,将使用 World 的 "
-"fallback_environment。"
+msgstr "该 World 的回退环境会在 [member environment] 失败或丢失时使用。"
#: doc/classes/World.xml
msgid ""
@@ -93513,7 +94084,7 @@ msgid ""
"current and potential collisions. When using multi-threaded physics, access "
"is limited to [code]_physics_process(delta)[/code] in the main thread."
msgstr ""
-"直接访问世界物ç†äºŒç»´ç©ºé—´çжæ€ã€‚用于查询当å‰å’Œæ½œåœ¨çš„ç¢°æ’žã€‚ä½¿ç”¨å¤šçº¿ç¨‹ç‰©ç†æ—¶ï¼Œè®¿"
+"ç›´æŽ¥è®¿é—®ä¸–ç•Œç‰©ç† 2D 空间状æ€ã€‚用于查询当å‰å’Œæ½œåœ¨çš„ç¢°æ’žã€‚ä½¿ç”¨å¤šçº¿ç¨‹ç‰©ç†æ—¶ï¼Œè®¿"
"问仅é™äºŽä¸»çº¿ç¨‹ä¸­çš„ [code]_physics_process(delta)[/code]。"
#: doc/classes/World2D.xml
@@ -93526,7 +94097,7 @@ msgid ""
"The [RID] of this world's physics space resource. Used by the "
"[Physics2DServer] for 2D physics, treating it as both a space and an area."
msgstr ""
-"这个世界物ç†ç©ºé—´èµ„æºçš„[RID]。 [Physics2DServer] 用于 2D 物ç†ï¼Œå°†å…¶è§†ä¸ºç©ºé—´å’Œ"
+"这个世界物ç†ç©ºé—´èµ„æºçš„ [RID]。[Physics2DServer] 用于 2D 物ç†ï¼Œå°†å…¶è§†ä¸ºç©ºé—´å’Œ"
"区域。"
#: doc/classes/WorldEnvironment.xml
@@ -93654,8 +94225,8 @@ msgid ""
"current node type is neither [constant NODE_ELEMENT] nor [constant "
"NODE_ELEMENT_END]."
msgstr ""
-"获å–当å‰å…ƒç´ èŠ‚ç‚¹çš„å称。如果当å‰èŠ‚ç‚¹ç±»åž‹æ—¢ä¸æ˜¯[constant NODE_ELEMENT]ä¹Ÿä¸æ˜¯"
-"[constant NODE_ELEMENT_END],将引å‘一个错误。"
+"获å–当å‰å…ƒç´ èŠ‚ç‚¹çš„å称。如果当å‰èŠ‚ç‚¹ç±»åž‹æ—¢ä¸æ˜¯ [constant NODE_ELEMENT] 也ä¸"
+"是 [constant NODE_ELEMENT_END],将引å‘一个错误。"
#: doc/classes/XMLParser.xml
msgid ""
diff --git a/doc/translations/zh_TW.po b/doc/translations/zh_TW.po
index ba40f5ee74..cd8d5c0eb5 100644
--- a/doc/translations/zh_TW.po
+++ b/doc/translations/zh_TW.po
@@ -482,7 +482,7 @@ msgid ""
"- 1.0: Linear\n"
"- Greater than 1.0 (exclusive): Ease in\n"
"[/codeblock]\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"ease_cheatsheet.png]ease() curve values cheatsheet[/url]\n"
"See also [method smoothstep]. If you need to perform more advanced "
"transitions, use [Tween] or [AnimationPlayer]."
@@ -1203,7 +1203,7 @@ msgid ""
"[method smoothstep] returns the smoothest possible curve with no sudden "
"changes in the derivative. If you need to perform more advanced transitions, "
"use [Tween] or [AnimationPlayer].\n"
-"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.4/img/"
+"[url=https://raw.githubusercontent.com/godotengine/godot-docs/3.5/img/"
"smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, "
"-1.6521) return values[/url]"
msgstr ""
@@ -10080,7 +10080,13 @@ msgid "If [code]true[/code], audio plays when added to scene tree."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml doc/classes/AudioStreamPlayer2D.xml
-msgid "Bus on which this audio is playing."
+msgid ""
+"Bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml
@@ -10245,7 +10251,13 @@ msgid ""
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
-msgid "The bus on which this audio is playing."
+msgid ""
+"The bus on which this audio is playing.\n"
+"[b]Note:[/b] When setting this property, keep in mind that no validation is "
+"performed to see if the given name matches an existing bus. This is because "
+"audio bus layouts might be loaded after this property is set. If this given "
+"name can't be resolved at runtime, it will fall back to [code]\"Master\"[/"
+"code]."
msgstr ""
#: doc/classes/AudioStreamPlayer3D.xml
@@ -12257,10 +12269,12 @@ msgid ""
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
#: doc/classes/Camera2D.xml doc/classes/ClippedCamera.xml
+#: doc/classes/InterpolatedCamera.xml
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -19559,13 +19573,17 @@ msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"occurs only on the splits far away, increasing this value can fix them. This "
+"is ignored when [member directional_shadow_mode] is [constant "
+"SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"transitions between splits. Enabling shadow blend splitting also has a "
+"moderate performance cost. This is ignored when [member "
+"directional_shadow_mode] is [constant SHADOW_ORTHOGONAL]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19575,7 +19593,11 @@ msgid ""
msgstr ""
#: doc/classes/DirectionalLight.xml
-msgid "The maximum distance for shadow splits."
+msgid ""
+"The maximum distance for shadow splits. Increasing this value will make "
+"directional shadows visible from further away, at the cost of lower overall "
+"shadow detail and performance (since more objects need to be included in the "
+"directional shadow rendering)."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -19592,23 +19614,23 @@ msgstr ""
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or "
-"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_2_SPLITS] or [constant "
+"SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
-"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
+"directional_shadow_mode] is [constant SHADOW_PARALLEL_4_SPLITS]."
msgstr ""
#: doc/classes/DirectionalLight.xml
@@ -28417,7 +28439,7 @@ msgid ""
" # Note: Don't make simultaneous requests using a single HTTPRequest "
"node.\n"
" # The snippet below is provided for reference only.\n"
-" var body = {\"name\": \"Godette\"}\n"
+" var body = to_json({\"name\": \"Godette\"})\n"
" error = http_request.request(\"https://httpbin.org/post\", [], true, "
"HTTPClient.METHOD_POST, body)\n"
" if error != OK:\n"
@@ -28556,13 +28578,14 @@ msgstr ""
#: doc/classes/HTTPRequest.xml
msgid ""
-"If set to a value greater than [code]0.0[/code], the HTTP request will time "
-"out after [code]timeout[/code] seconds have passed and the request is not "
-"[i]completed[/i] yet. For small HTTP requests such as REST API usage, set "
-"[member timeout] to a value greater than [code]0.0[/code] to prevent the "
-"application from getting stuck if the request fails to get a response in a "
-"timely manner. For file downloads, leave this to [code]0.0[/code] to prevent "
-"the download from failing if it takes too much time."
+"If set to a value greater than [code]0.0[/code] before the request starts, "
+"the HTTP request will time out after [code]timeout[/code] seconds have "
+"passed and the request is not [i]completed[/i] yet. For small HTTP requests "
+"such as REST API usage, set [member timeout] to a value between [code]10.0[/"
+"code] and [code]30.0[/code] to prevent the application from getting stuck if "
+"the request fails to get a response in a timely manner. For file downloads, "
+"leave this to [code]0.0[/code] to prevent the download from failing if it "
+"takes too much time."
msgstr ""
#: doc/classes/HTTPRequest.xml
@@ -29977,7 +30000,10 @@ msgid ""
"input at the cost of increased CPU usage. In applications where drawing "
"freehand lines is required, input accumulation should generally be disabled "
"while the user is drawing the line to get results that closely follow the "
-"actual input."
+"actual input.\n"
+"[b]Note:[/b] Input accumulation is [i]enabled[/i] by default. It is "
+"recommended to keep it enabled for games which don't require very reactive "
+"input, as this will decrease CPU usage."
msgstr ""
#: doc/classes/Input.xml
@@ -30551,10 +30577,14 @@ msgstr ""
msgid ""
"Contains mouse and pen motion information. Supports relative, absolute "
"positions and speed. See [method Node._input].\n"
-"[b]Note:[/b] By default, this event is only emitted once per frame rendered "
-"at most. If you need more precise input reporting, set [member Input."
-"use_accumulated_input] to [code]false[/code] to make events emitted as often "
-"as possible. If you use InputEventMouseMotion to draw lines, consider "
+"[b]Note:[/b] The behavior of this event is affected by the value of [member "
+"Input.use_accumulated_input]. When set to [code]true[/code] (default), mouse/"
+"pen motion events received from the OS will be merged to emit an accumulated "
+"event only once per frame rendered at most. When set to [code]false[/code], "
+"the events will be emitted as received, which means that they can be emitted "
+"multiple times per frame rendered, allowing for precise input reporting at "
+"the expense of CPU usage.\n"
+"[b]Note:[/b] If you use InputEventMouseMotion to draw lines, consider "
"implementing [url=https://en.wikipedia.org/wiki/"
"Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to "
"avoid visible gaps in lines if the user is moving the mouse quickly."
@@ -30566,6 +30596,12 @@ msgstr ""
#: doc/classes/InputEventMouseMotion.xml
msgid ""
+"Returns [code]true[/code] when using the eraser end of a stylus pen.\n"
+"[b]Note:[/b] This property is implemented on Linux, macOS and Windows."
+msgstr ""
+
+#: doc/classes/InputEventMouseMotion.xml
+msgid ""
"Represents the pressure the user puts on the pen. Ranges from [code]0.0[/"
"code] to [code]1.0[/code]."
msgstr ""
@@ -30878,6 +30914,11 @@ msgstr ""
#: doc/classes/InterpolatedCamera.xml
msgid ""
+"The camera's process callback. See [enum InterpolatedCameraProcessMode]."
+msgstr ""
+
+#: doc/classes/InterpolatedCamera.xml
+msgid ""
"How quickly the camera moves toward its target. Higher values will result in "
"tighter camera motion."
msgstr ""
@@ -31042,7 +31083,18 @@ msgid ""
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
"fully fit its content by default. You need to set [member "
-"fixed_column_width] greater than zero to wrap the text."
+"fixed_column_width] greater than zero to wrap the text.\n"
+"[b]Incremental search:[/b] Like [PopupMenu] and [Tree], [ItemList] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/ItemList.xml
@@ -34794,12 +34846,18 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Returns the override [Material] for a surface of the [Mesh] resource.\n"
+"[b]Note:[/b] This function only returns [i]override[/i] materials associated "
+"with this [MeshInstance]. Consider using [method get_active_material] or "
+"[method Mesh.surface_get_material] to get materials associated with the "
+"[Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Returns the number of surface materials."
-msgstr ""
+#, fuzzy
+msgid "Returns the number of surface override materials."
+msgstr "å›žå‚³åƒæ•¸çš„æ­£å¼¦å€¼ã€‚"
#: doc/classes/MeshInstance.xml
msgid ""
@@ -34835,7 +34893,10 @@ msgid ""
msgstr ""
#: doc/classes/MeshInstance.xml
-msgid "Sets the [Material] for a surface of the [Mesh] resource."
+msgid ""
+"Sets the override [Material] for the specified surface of the [Mesh] "
+"resource. This material is associated with this [MeshInstance] rather than "
+"with the [Mesh] resource."
msgstr ""
#: doc/classes/MeshInstance.xml
@@ -35634,6 +35695,9 @@ msgstr ""
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
"child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this "
@@ -35680,6 +35744,9 @@ msgstr "å›žå‚³åƒæ•¸çš„æ­£å¼¦å€¼ã€‚"
#: doc/classes/Navigation.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"NavigationServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
@@ -35723,6 +35790,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
@@ -35742,6 +35812,9 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid ""
+"[i]Deprecated.[/i] [Navigation2D] node and [method get_simple_path] are "
+"deprecated and will be removed in a future version. Use [method "
+"Navigation2DServer.map_get_path] instead.\n"
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
@@ -35877,11 +35950,47 @@ msgid "Destroys the given RID."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns all created navigation map [RID]s on the NavigationServer. This "
+"returns both 2D and 3D created navigation maps as there is technically no "
+"distinction between them."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Create a new map."
msgstr ""
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
+"This function immediately forces synchronization of the specified navigation "
+"[code]map[/code] [RID]. By default navigation maps are only synchronized at "
+"the end of each physics frame. This function can be used to immediately "
+"(re)calculate all the navigation meshes and region connections of the "
+"navigation map. This makes it possible to query a navigation path for a "
+"changed map immediately and in the same frame (multiple times if needed).\n"
+"Due to technical restrictions the current NavigationServer command queue "
+"will be flushed. This means all already queued update commands for this "
+"physics frame will be executed, even those intended for other maps, regions "
+"and agents not part of the specified map. The expensive computation of the "
+"navigation meshes and region connections of a map will only be done for the "
+"specified map. Other maps will receive the normal synchronization at the end "
+"of the physics frame. Should the specified map receive changes after the "
+"forced update it will update again as well when the other maps receive their "
+"update.\n"
+"Avoidance processing and dispatch of the [code]safe_velocity[/code] signals "
+"is untouched by this function and continues to happen for all maps and "
+"agents at the end of the physics frame.\n"
+"[b]Note:[/b] With great power comes great responsibility. This function "
+"should only be used by users that really know what they are doing and have a "
+"good reason for it. Forcing an immediate update of a navigation map requires "
+"locking the NavigationServer and flushing the entire NavigationServer "
+"command queue. Not only can this severely impact the performance of a game "
+"but it can also introduce bugs if used inappropriately without much "
+"foresight."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
"Returns all navigation agents [RID]s that are currently assigned to the "
"requested navigation [code]map[/code]."
msgstr ""
@@ -35997,6 +36106,23 @@ msgid "Returns the [code]travel_cost[/code] of this [code]region[/code]."
msgstr "計算兩個å‘é‡çš„外ç©ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
+msgid ""
+"Returns [code]true[/code] if the provided [code]point[/code] in world space "
+"is currently owned by the provided navigation [code]region[/code]. Owned in "
+"this context means that one of the region's navigation mesh polygon faces "
+"has a possible position at the closest distance to this point compared to "
+"all other navigation meshes from other navigation regions that are also "
+"registered on the navigation map of the provided region.\n"
+"If multiple navigation meshes have positions at equal distance the "
+"navigation region whose polygons are processed first wins the ownership. "
+"Polygons are processed in the same order that navigation regions were "
+"registered on the NavigationServer.\n"
+"[b]Note:[/b] If navigation meshes from different navigation regions overlap "
+"(which should be avoided in general) the result might not be what is "
+"expected."
+msgstr ""
+
+#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
#, fuzzy
msgid "Sets the [code]enter_cost[/code] for this [code]region[/code]."
msgstr "計算兩個å‘é‡çš„外ç©ã€‚"
@@ -36210,20 +36336,40 @@ msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
+"The distance threshold before a path point is considered to be reached. This "
+"will allow an agent to not have to hit a path point on the path exactly, but "
+"in the area. If this value is set to high the NavigationAgent will skip "
+"points on the path which can lead to leaving the navigation mesh. If this "
+"value is set to low the NavigationAgent will be stuck in a repath loop cause "
+"it will constantly overshoot or undershoot the distance to the next point on "
+"each physics frame update."
+msgstr ""
+
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
+msgid ""
"The maximum distance the agent is allowed away from the ideal path to the "
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
-#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-msgid "The radius of the agent."
+#: doc/classes/NavigationAgent.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding. To change an actor's pathfinding radius "
+"bake [NavigationMesh] resources with a different [member NavigationMesh."
+"agent_radius] property and use different navigation maps for each actor size."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"The distance threshold before a target is considered to be reached. This "
-"will allow an agent to not have to hit a point on the path exactly, but in "
-"the area."
+"The distance threshold before the final target point is considered to be "
+"reached. This will allow an agent to not have to hit the point of the final "
+"target exactly, but only the area. If this value is set to low the "
+"NavigationAgent will be stuck in a repath loop cause it will constantly "
+"overshoot or undershoot the distance to the final target point on each "
+"physics frame update."
msgstr ""
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
@@ -36319,6 +36465,14 @@ msgid ""
"least one matching layer."
msgstr ""
+#: doc/classes/NavigationAgent2D.xml
+msgid ""
+"The radius of the avoidance agent. This is the \"body\" of the avoidance "
+"agent and not the avoidance maneuver starting radius (which is controlled by "
+"[member neighbor_dist]).\n"
+"Does not affect normal pathfinding."
+msgstr ""
+
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36440,6 +36594,16 @@ msgid ""
msgstr ""
#: doc/classes/NavigationMesh.xml
+msgid ""
+"If the baking [AABB] has a volume the navigation mesh baking will be "
+"restricted to its enclosing area."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
+msgid "The position offset applied to the [member filter_baking_aabb] [AABB]."
+msgstr ""
+
+#: doc/classes/NavigationMesh.xml
msgid "If [code]true[/code], marks spans that are ledges as non-walkable."
msgstr ""
@@ -36610,7 +36774,15 @@ msgid ""
"geometry for walkable terrain suitable to [NavigationMesh] agent properties "
"by creating a voxel world around the meshes bounding area.\n"
"The finalized navigation mesh is then returned and stored inside the "
-"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes."
+"[NavigationMesh] for use as a resource inside [NavigationMeshInstance] "
+"nodes.\n"
+"[b]Note:[/b] Using meshes to not only define walkable surfaces but also "
+"obstruct navigation baking does not always work. The navigation baking has "
+"no concept of what is a geometry \"inside\" when dealing with mesh source "
+"geometry and this is intentional. Depending on current baking parameters, as "
+"soon as the obstructing mesh is large enough to fit a navigation mesh area "
+"inside, the baking will generate navigation mesh areas that are inside the "
+"obstructing source geometry mesh."
msgstr ""
#: doc/classes/NavigationMeshGenerator.xml
@@ -38492,13 +38664,19 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when a child node enters the scene tree, either because it entered "
-"on its own or because this node entered with it."
+"on its own or because this node entered with it.\n"
+"This signal is emitted [i]after[/i] the child node's own [constant "
+"NOTIFICATION_ENTER_TREE] and [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
msgid ""
-"Emitted when a child node exits the scene tree, either because it exited on "
-"its own or because this node exited."
+"Emitted when a child node is about to exit the scene tree, either because it "
+"is being removed or freed directly, or because this node is exiting the "
+"tree.\n"
+"When this signal is received, the child [code]node[/code] is still in the "
+"tree and valid. This signal is emitted [i]after[/i] the child node's own "
+"[signal tree_exiting] and [constant NOTIFICATION_EXIT_TREE]."
msgstr ""
#: doc/classes/Node.xml
@@ -38510,7 +38688,10 @@ msgid "Emitted when the node is renamed."
msgstr ""
#: doc/classes/Node.xml
-msgid "Emitted when the node enters the tree."
+msgid ""
+"Emitted when the node enters the tree.\n"
+"This signal is emitted [i]after[/i] the related [constant "
+"NOTIFICATION_ENTER_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
@@ -38520,15 +38701,21 @@ msgstr ""
#: doc/classes/Node.xml
msgid ""
"Emitted when the node is still active but about to exit the tree. This is "
-"the right place for de-initialization (or a \"destructor\", if you will)."
+"the right place for de-initialization (or a \"destructor\", if you will).\n"
+"This signal is emitted [i]before[/i] the related [constant "
+"NOTIFICATION_EXIT_TREE] notification."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node enters a [SceneTree]."
+msgid ""
+"Notification received when the node enters a [SceneTree].\n"
+"This notification is emitted [i]before[/i] the related [signal tree_entered]."
msgstr ""
#: doc/classes/Node.xml
-msgid "Notification received when the node is about to exit a [SceneTree]."
+msgid ""
+"Notification received when the node is about to exit a [SceneTree].\n"
+"This notification is emitted [i]after[/i] the related [signal tree_exiting]."
msgstr ""
#: doc/classes/Node.xml
@@ -40240,6 +40427,10 @@ msgid ""
" if argument.find(\"=\") > -1:\n"
" var key_value = argument.split(\"=\")\n"
" arguments[key_value[0].lstrip(\"--\")] = key_value[1]\n"
+" else:\n"
+" # Options without an argument will be present in the dictionary,\n"
+" # with the value set to an empty string.\n"
+" arguments[argument.lstrip(\"--\")] = \"\"\n"
"[/codeblock]"
msgstr ""
@@ -45349,6 +45540,13 @@ msgstr ""
msgid "Changes the byte at the given index."
msgstr ""
+#: doc/classes/PoolByteArray.xml doc/classes/PoolColorArray.xml
+#: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml
+#: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml
+#: doc/classes/PoolVector3Array.xml
+msgid "Sorts the elements of the array in ascending order."
+msgstr ""
+
#: doc/classes/PoolByteArray.xml
msgid ""
"Returns the slice of the [PoolByteArray] between indices (inclusive) as a "
@@ -45761,7 +45959,18 @@ msgstr ""
#: doc/classes/PopupMenu.xml
msgid ""
"[PopupMenu] is a [Control] that displays a list of options. They are popular "
-"in toolbars or context menus."
+"in toolbars or context menus.\n"
+"[b]Incremental search:[/b] Like [ItemList] and [Tree], [PopupMenu] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/PopupMenu.xml
@@ -49337,20 +49546,28 @@ msgid ""
"cause.\n"
"The default value is a conservative one, so you are advised to tweak it "
"according to the hardware you are targeting.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"The default is a very conservative override for [code]rendering/gles3/"
-"shaders/max_concurrent_compiles[/code].\n"
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
"Depending on the specific devices you are targeting, you may want to raise "
"it.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"The default is a very conservative override for [member rendering/gles3/"
+"shaders/max_simultaneous_compiles].\n"
+"Depending on the specific browsers you are targeting, you may want to raise "
+"it.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49358,19 +49575,28 @@ msgid ""
"The maximum size, in megabytes, that the ubershader cache can grow up to. On "
"startup, the least recently used entries will be deleted until the total "
"size is within bounds.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/"
-"code], so a smaller maximum size can be configured for mobile platforms, "
-"where storage space is more limited.\n"
-"[b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/"
-"shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/"
-"code]."
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for mobile platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a "
+"smaller maximum size can be configured for web platforms, where storage "
+"space is more limited.\n"
+"[b]Note:[/b] Currently, shader caching is generally unavailable on web "
+"platforms.\n"
+"[b]Note:[/b] This setting is only meaningful if [member rendering/gles3/"
+"shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -49402,14 +49628,22 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"An override for [code]rendering/gles3/shaders/shader_compilation_mode[/"
-"code], so asynchronous compilation can be disabled for mobile.\n"
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on mobile platforms.\n"
"You may want to do that since mobile GPUs generally won't support "
"ubershaders due to their complexity."
msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"An override for [member rendering/gles3/shaders/shader_compilation_mode], so "
+"asynchronous compilation can be disabled on web platforms.\n"
+"You may want to do that since certain browsers (especially on mobile "
+"platforms) generally won't support ubershaders due to their complexity."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Max buffer size for blend shapes. Any blend shape bigger than this will not "
"work."
msgstr ""
@@ -49863,8 +50097,8 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
-"Size for shadow atlas (used for OmniLights and SpotLights). See "
-"documentation."
+"Size for shadow atlas (used for OmniLights and SpotLights). The value will "
+"be rounded up to the nearest power of 2. See shadow mapping documentation."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -54100,24 +54334,23 @@ msgid ""
"manually (i.e. by using [code]Tween.new()[/code]) are invalid. They can't be "
"used for tweening values, but you can do manual interpolation with [method "
"interpolate_value].\n"
-"A [SceneTreeTween] animation is composed of a sequence of [Tweener]s, which "
-"by default are executed one after another. You can create a sequence by "
-"appending [Tweener]s to the [SceneTreeTween]. Animating something with a "
-"[Tweener] is called tweening. Example tweening sequence looks like this:\n"
+"A tween animation is created by adding [Tweener]s to the [SceneTreeTween] "
+"object, using [method tween_property], [method tween_interval], [method "
+"tween_callback] or [method tween_method]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1)\n"
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"This sequence will make the [code]$Sprite[/code] node turn red, then shrink "
-"and finally the [method Node.queue_free] is called to remove the sprite. See "
-"methods [method tween_property], [method tween_interval], [method "
-"tween_callback] and [method tween_method] for more usage information.\n"
+"This sequence will make the [code]$Sprite[/code] node turn red, then shrink, "
+"before finally calling [method Node.queue_free] to free the sprite. "
+"[Tweener]s are executed one after another by default. This behavior can be "
+"changed using [method parallel] and [method set_parallel].\n"
"When a [Tweener] is created with one of the [code]tween_*[/code] methods, a "
"chained method call can be used to tweak the properties of this [Tweener]. "
-"For example, if you want to set different transition type in the above "
-"example, you can do:\n"
+"For example, if you want to set a different transition type in the above "
+"example, you can use [method set_trans]:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween()\n"
"tween.tween_property($Sprite, \"modulate\", Color.red, 1).set_trans(Tween."
@@ -54126,8 +54359,9 @@ msgid ""
"TRANS_BOUNCE)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Most of the [SceneTreeTween] methods can be chained this way too. In this "
-"example the [SceneTreeTween] is bound and have set a default transition:\n"
+"Most of the [SceneTreeTween] methods can be chained this way too. In the "
+"following example the [SceneTreeTween] is bound to the running script's node "
+"and a default transition is set for its [Tweener]s:\n"
"[codeblock]\n"
"var tween = get_tree().create_tween().bind_node(self).set_trans(Tween."
"TRANS_ELASTIC)\n"
@@ -54135,16 +54369,16 @@ msgid ""
"tween.tween_property($Sprite, \"scale\", Vector2(), 1)\n"
"tween.tween_callback($Sprite, \"queue_free\")\n"
"[/codeblock]\n"
-"Another interesting use for [SceneTreeTween]s is animating arbitrary set of "
+"Another interesting use for [SceneTreeTween]s is animating arbitrary sets of "
"objects:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"for sprite in get_children():\n"
-" tween.tween_property(sprite, \"position\", Vector2(), 1)\n"
+" tween.tween_property(sprite, \"position\", Vector2(0, 0), 1)\n"
"[/codeblock]\n"
"In the example above, all children of a node are moved one after another to "
"position (0, 0).\n"
-"Some [Tweener]s use transitions and eases. The first accepts an [enum Tween."
+"Some [Tweener]s use transitions and eases. The first accepts a [enum Tween."
"TransitionType] constant, and refers to the way the timing of the animation "
"is handled (see [url=https://easings.net/]easings.net[/url] for some "
"examples). The second accepts an [enum Tween.EaseType] constant, and "
@@ -54156,7 +54390,7 @@ msgid ""
"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
"[b]Note:[/b] All [SceneTreeTween]s will automatically start by default. To "
"prevent a [SceneTreeTween] from autostarting, you can call [method stop] "
-"immediately after it was created."
+"immediately after it is created."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54186,21 +54420,24 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
-"Processes the [SceneTreeTween] by given [code]delta[/code] value, in "
-"seconds. Mostly useful when the [SceneTreeTween] is paused, for controlling "
-"it manually. Can also be used to end the [SceneTreeTween] animation "
-"immediately, by using [code]delta[/code] longer than the whole duration.\n"
+"Processes the [SceneTreeTween] by the given [code]delta[/code] value, in "
+"seconds. This is mostly useful for manual control when the [SceneTreeTween] "
+"is paused. It can also be used to end the [SceneTreeTween] animation "
+"immediately, by setting [code]delta[/code] longer than the whole duration of "
+"the [SceneTreeTween] animation.\n"
"Returns [code]true[/code] if the [SceneTreeTween] still has [Tweener]s that "
"haven't finished.\n"
-"[b]Note:[/b] The [SceneTreeTween] will become invalid after finished, but "
-"you can call [method stop] after the step, to keep it and reset."
+"[b]Note:[/b] The [SceneTreeTween] will become invalid in the next processing "
+"frame after its animation finishes. Calling [method stop] after performing "
+"[method custom_step] instead keeps and resets the [SceneTreeTween]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Returns the total time in seconds the [SceneTreeTween] has been animating (i."
-"e. time since it started, not counting pauses etc.). The time is affected by "
-"[method set_speed_scale] and [method stop] will reset it to [code]0[/code].\n"
+"e. the time since it started, not counting pauses etc.). The time is "
+"affected by [method set_speed_scale], and [method stop] will reset it to "
+"[code]0[/code].\n"
"[b]Note:[/b] As it results from accumulating frame deltas, the time returned "
"after the [SceneTreeTween] has finished animating will be slightly greater "
"than the actual [SceneTreeTween] duration."
@@ -54236,11 +54473,11 @@ msgstr ""
msgid ""
"Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a "
"[SceneTreeTween] contained by the scene tree (i.e. the array from [method "
-"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). "
-"[SceneTreeTween] might become invalid when it has finished tweening or was "
-"killed, also when created with [code]Tween.new()[/code]. Invalid "
-"[SceneTreeTween] can't have [Tweener]s appended, because it can't animate "
-"them. You can however still use [method interpolate_value]."
+"SceneTree.get_processed_tweens] will contain this [SceneTreeTween]). A "
+"[SceneTreeTween] might become invalid when it has finished tweening, is "
+"killed, or when created with [code]SceneTreeTween.new()[/code]. Invalid "
+"[SceneTreeTween]s can't have [Tweener]s appended. You can however still use "
+"[method interpolate_value]."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -54281,13 +54518,13 @@ msgid ""
"Sets the number of times the tweening sequence will be repeated, i.e. "
"[code]set_loops(2)[/code] will run the animation twice.\n"
"Calling this method without arguments will make the [SceneTreeTween] 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).\n"
+"infinitely, until either it is killed with [method kill], the "
+"[SceneTreeTween]'s bound node is freed, or all the animated objects have "
+"been freed (which makes further animation impossible).\n"
"[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 "
+"infinite loops. To prevent the game freezing, 0-duration looped animations "
+"(e.g. a single [CallbackTweener] with no delay) are stopped after a small "
+"number of loops, which may produce unexpected results. If a "
"[SceneTreeTween]'s lifetime depends on some node, always use [method "
"bind_node]."
msgstr ""
@@ -54351,10 +54588,10 @@ msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Creates and appends an [IntervalTweener]. This method can be used to create "
-"delays in the tween animation, as an alternative for using the delay in "
-"other [Tweener]s or when there's no animation (in which case the "
-"[SceneTreeTween] acts as a timer). [code]time[/code] is the length of the "
-"interval, in seconds.\n"
+"delays in the tween animation, as an alternative to using the delay in other "
+"[Tweener]s, or when there's no animation (in which case the [SceneTreeTween] "
+"acts as a timer). [code]time[/code] is the length of the interval, in "
+"seconds.\n"
"Example: creating an interval in code execution.\n"
"[codeblock]\n"
"# ... some code\n"
@@ -54408,8 +54645,8 @@ msgid ""
"Creates and appends a [PropertyTweener]. This method tweens a "
"[code]property[/code] of an [code]object[/code] between an initial value and "
"[code]final_val[/code] in a span of time equal to [code]duration[/code], in "
-"seconds. The initial value by default is a value at the time the tweening of "
-"the [PropertyTweener] start. For example:\n"
+"seconds. The initial value by default is the property's value at the time "
+"the tweening of the [PropertyTweener] starts. For example:\n"
"[codeblock]\n"
"var tween = create_tween()\n"
"tween.tween_property($Sprite, \"position\", Vector2(100, 200), 1)\n"
@@ -54440,16 +54677,15 @@ msgid ""
"Emitted when the [SceneTreeTween] has finished all tweening. Never emitted "
"when the [SceneTreeTween] is set to infinite looping (see [method "
"set_loops]).\n"
-"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) after this signal "
-"is emitted, but it doesn't happen immediately, but on the next processing "
-"frame. Calling [method stop] inside the signal callback will preserve the "
-"[SceneTreeTween]."
+"[b]Note:[/b] The [SceneTreeTween] is removed (invalidated) in the next "
+"processing frame after this signal is emitted. Calling [method stop] inside "
+"the signal callback will prevent the [SceneTreeTween] from being removed."
msgstr ""
#: doc/classes/SceneTreeTween.xml
msgid ""
"Emitted when a full loop is complete (see [method set_loops]), providing the "
-"loop index. This signal is not emitted after final loop, use [signal "
+"loop index. This signal is not emitted after the final loop, use [signal "
"finished] instead for this case."
msgstr ""
@@ -54457,7 +54693,7 @@ msgstr ""
msgid ""
"Emitted when one step of the [SceneTreeTween] is complete, providing the "
"step index. One step is either a single [Tweener] or a group of [Tweener]s "
-"running parallelly."
+"running in parallel."
msgstr ""
#: doc/classes/SceneTreeTween.xml
@@ -55767,11 +56003,30 @@ msgid ""
msgstr ""
#: doc/classes/Spatial.xml
+msgid ""
+"Rotation part of the global transformation in radians, specified in terms of "
+"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
+"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
+"vector. The three Euler angles, which are the three independent parameters "
+"of the Euler-angle parametrization of the rotation matrix, are stored in a "
+"[Vector3] data structure not because the rotation is a vector, but only "
+"because [Vector3] exists as a convenient data-structure to store 3 floating-"
+"point numbers. Therefore, applying affine operations on the rotation "
+"\"vector\" is not meaningful."
+msgstr ""
+
+#: doc/classes/Spatial.xml
msgid "World space (global) [Transform] of this node."
msgstr ""
#: doc/classes/Spatial.xml
msgid ""
+"Global position of this node. This is equivalent to [code]global_transform."
+"origin[/code]."
+msgstr ""
+
+#: doc/classes/Spatial.xml
+msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
"[b]Note:[/b] In the mathematical sense, rotation is a matrix and not a "
@@ -58239,7 +58494,31 @@ msgstr ""
#: doc/classes/String.xml
msgid ""
"Formats the string by replacing all occurrences of [code]placeholder[/code] "
-"with [code]values[/code]."
+"with the elements of [code]values[/code].\n"
+"[code]values[/code] can be a [Dictionary] or an [Array]. Any underscores in "
+"[code]placeholder[/code] will be replaced with the corresponding keys in "
+"advance. Array elements use their index as keys.\n"
+"[codeblock]\n"
+"# Prints: Waiting for Godot is a play by Samuel Beckett, and Godot Engine is "
+"named after it.\n"
+"var use_array_values = \"Waiting for {0} is a play by {1}, and {0} Engine is "
+"named after it.\"\n"
+"print(use_array_values.format([\"Godot\", \"Samuel Beckett\"]))\n"
+"\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {id} is {name}.\".format({\"id\": 42, \"name\": \"Godot\"}))\n"
+"[/codeblock]\n"
+"Some additional handling is performed when [code]values[/code] is an array. "
+"If [code]placeholder[/code] does not contain an underscore, the elements of "
+"the array will be used to replace one occurrence of the placeholder in turn; "
+"If an array element is another 2-element array, it'll be interpreted as a "
+"key-value pair.\n"
+"[codeblock]\n"
+"# Prints: User 42 is Godot.\n"
+"print(\"User {} is {}.\".format([42, \"Godot\"], \"{}\"))\n"
+"print(\"User {id} is {name}.\".format([[\"id\", 42], [\"name\", "
+"\"Godot\"]]))\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/String.xml
@@ -58429,11 +58708,11 @@ msgstr ""
msgid ""
"Returns [code]true[/code] if this string contains a valid integer.\n"
"[codeblock]\n"
-"print(\"7\".is_valid_int()) # Prints \"True\"\n"
-"print(\"14.6\".is_valid_int()) # Prints \"False\"\n"
-"print(\"L\".is_valid_int()) # Prints \"False\"\n"
-"print(\"+3\".is_valid_int()) # Prints \"True\"\n"
-"print(\"-12\".is_valid_int()) # Prints \"True\"\n"
+"print(\"7\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"14.6\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"L\".is_valid_integer()) # Prints \"False\"\n"
+"print(\"+3\".is_valid_integer()) # Prints \"True\"\n"
+"print(\"-12\".is_valid_integer()) # Prints \"True\"\n"
"[/codeblock]"
msgstr ""
@@ -58836,9 +59115,11 @@ msgstr ""
#: doc/classes/StyleBox.xml
msgid ""
-"Draws this stylebox using a [CanvasItem] with given [RID].\n"
-"You can get a [RID] value using [method Object.get_instance_id] on a "
-"[CanvasItem]-derived node."
+"Draws this stylebox using a canvas item identified by the given [RID].\n"
+"The [RID] value can either be the result of [method CanvasItem."
+"get_canvas_item] called on an existing [CanvasItem]-derived node, or "
+"directly from creating a canvas item in the [VisualServer] with [method "
+"VisualServer.canvas_item_create]."
msgstr ""
#: doc/classes/StyleBox.xml
@@ -60384,6 +60665,11 @@ msgid "If [code]true[/code], a right-click displays the context menu."
msgstr ""
#: doc/classes/TextEdit.xml
+#, fuzzy
+msgid "If [code]true[/code], allow drag and drop of selected text."
+msgstr "å›žå‚³åƒæ•¸çš„餘弦值。"
+
+#: doc/classes/TextEdit.xml
msgid ""
"If [code]true[/code], the \"space\" character will have a visible "
"representation."
@@ -63318,7 +63604,18 @@ msgid ""
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
-"to remove it from the [Tree]."
+"to remove it from the [Tree].\n"
+"[b]Incremental search:[/b] Like [ItemList] and [PopupMenu], [Tree] supports "
+"searching within the list while the control is focused. Press a key that "
+"matches the first letter of an item's name to select the first item starting "
+"with the given letter. After that point, there are two ways to perform "
+"incremental search: 1) Press the same key again before the timeout duration "
+"to select the next item starting with the same letter. 2) Press letter keys "
+"that match the rest of the word before the timeout duration to match to "
+"select the item in question directly. Both of these actions will be reset to "
+"the beginning of the list if the timeout duration has passed since the last "
+"keystroke was registered. You can adjust the timeout duration by changing "
+"[member ProjectSettings.gui/timers/incremental_search_max_interval_msec]."
msgstr ""
#: doc/classes/Tree.xml
@@ -65774,11 +66071,11 @@ msgstr ""
#: doc/classes/VehicleBody.xml
msgid ""
"Accelerates the vehicle by applying an engine force. The vehicle is only "
-"speed up if the wheels that have [member VehicleWheel.use_as_traction] set "
-"to [code]true[/code] and are in contact with a surface. The [member "
-"RigidBody.mass] of the vehicle has an effect on the acceleration of the "
-"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 "
-"range for acceleration.\n"
+"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to "
+"[code]true[/code] and are in contact with a surface. The [member RigidBody."
+"mass] of the vehicle has an effect on the acceleration of the vehicle. For a "
+"vehicle with a mass set to 1000, try a value in the 25 - 50 range for "
+"acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
"you will need to add logic for this if you wish to simulate gears.\n"
"A negative value will result in the vehicle reversing."
@@ -65858,8 +66155,8 @@ msgstr ""
#: doc/classes/VehicleWheel.xml
msgid ""
-"Accelerates the wheel by applying an engine force. The wheel is only speed "
-"up if it is in contact with a surface. The [member RigidBody.mass] of the "
+"Accelerates the wheel by applying an engine force. The wheel is only sped up "
+"if it is in contact with a surface. The [member RigidBody.mass] of the "
"vehicle has an effect on the acceleration of the vehicle. For a vehicle with "
"a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n"
"[b]Note:[/b] The simulation does not take the effect of gears into account, "
@@ -66466,9 +66763,10 @@ msgstr ""
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
-"[b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-"
-"created viewports default to a value of 0, this value must be set above 0 "
-"manually."
+"[b]Note:[/b] If this is set to [code]0[/code], both point [i]and[/i] "
+"directional shadows won't be visible. Since user-created viewports default "
+"to a value of [code]0[/code], this value must be set above [code]0[/code] "
+"manually (typically at least [code]256[/code])."
msgstr ""
#: doc/classes/Viewport.xml
@@ -66497,7 +66795,11 @@ msgid ""
msgstr ""
#: doc/classes/Viewport.xml
-msgid "The rendering mode of viewport."
+msgid ""
+"The rendering mode of viewport.\n"
+"[b]Note:[/b] If set to [constant USAGE_2D] or [constant "
+"USAGE_2D_NO_SAMPLING], [member hdr] will have no effect when enabled since "
+"HDR is not supported for 2D."
msgstr ""
#: doc/classes/Viewport.xml
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 276e69e470..cc38c2352f 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -38,7 +38,7 @@
#define kOutputBus 0
#define kInputBus 1
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
OSStatus AudioDriverCoreAudio::input_device_address_cb(AudioObjectID inObjectID,
UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses,
void *inClientData) {
@@ -72,7 +72,7 @@ Error AudioDriverCoreAudio::init() {
AudioComponentDescription desc;
memset(&desc, 0, sizeof(desc));
desc.componentType = kAudioUnitType_Output;
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
desc.componentSubType = kAudioUnitSubType_HALOutput;
#else
desc.componentSubType = kAudioUnitSubType_RemoteIO;
@@ -85,7 +85,7 @@ Error AudioDriverCoreAudio::init() {
OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
@@ -135,7 +135,7 @@ Error AudioDriverCoreAudio::init() {
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32));
ERR_FAIL_COND_V(result != noErr, FAILED);
#endif
@@ -313,7 +313,7 @@ void AudioDriverCoreAudio::finish() {
ERR_PRINT("AudioUnitUninitialize failed");
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
@@ -339,7 +339,7 @@ Error AudioDriverCoreAudio::capture_init() {
AudioComponentDescription desc;
memset(&desc, 0, sizeof(desc));
desc.componentType = kAudioUnitType_Output;
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
desc.componentSubType = kAudioUnitSubType_HALOutput;
#else
desc.componentSubType = kAudioUnitSubType_RemoteIO;
@@ -352,7 +352,7 @@ Error AudioDriverCoreAudio::capture_init() {
OSStatus result = AudioComponentInstanceNew(comp, &input_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
@@ -370,7 +370,7 @@ Error AudioDriverCoreAudio::capture_init() {
ERR_FAIL_COND_V(result != noErr, FAILED);
UInt32 size;
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioDeviceID deviceId;
size = sizeof(AudioDeviceID);
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
@@ -447,7 +447,7 @@ void AudioDriverCoreAudio::capture_finish() {
ERR_PRINT("AudioUnitUninitialize failed");
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
@@ -491,7 +491,7 @@ Error AudioDriverCoreAudio::capture_stop() {
return OK;
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
Array AudioDriverCoreAudio::_get_device_list(bool capture) {
Array list;
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index f86037f092..0a4bbd662d 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -36,7 +36,7 @@
#include "servers/audio_server.h"
#import <AudioUnit/AudioUnit.h>
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
#import <CoreAudio/AudioHardware.h>
#endif
@@ -58,7 +58,7 @@ class AudioDriverCoreAudio : public AudioDriver {
Vector<int32_t> samples_in;
Vector<int16_t> input_buf;
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
Array _get_device_list(bool capture = false);
void _set_device(const String &device, bool capture = false);
@@ -106,7 +106,7 @@ public:
bool try_lock();
void stop();
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
virtual Array get_device_list();
virtual String get_device();
virtual void set_device(String device);
diff --git a/drivers/gl_context/SCsub b/drivers/gl_context/SCsub
index ddeec6f4c6..7e8bd22960 100644
--- a/drivers/gl_context/SCsub
+++ b/drivers/gl_context/SCsub
@@ -2,7 +2,7 @@
Import("env")
-if env["platform"] in ["haiku", "osx", "windows", "linuxbsd"]:
+if env["platform"] in ["haiku", "macos", "windows", "linuxbsd"]:
# Thirdparty source files
thirdparty_dir = "#thirdparty/glad/"
thirdparty_sources = [
diff --git a/drivers/gles3/environment/fog.cpp b/drivers/gles3/environment/fog.cpp
new file mode 100644
index 0000000000..02d88f6871
--- /dev/null
+++ b/drivers/gles3/environment/fog.cpp
@@ -0,0 +1,66 @@
+/*************************************************************************/
+/* fog.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifdef GLES3_ENABLED
+
+#include "fog.h"
+
+using namespace GLES3;
+
+/* FOG */
+
+RID Fog::fog_volume_allocate() {
+ return RID();
+}
+
+void Fog::fog_volume_initialize(RID p_rid) {
+}
+
+void Fog::fog_free(RID p_rid) {
+}
+
+void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
+}
+
+void Fog::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) {
+}
+
+void Fog::fog_volume_set_material(RID p_fog_volume, RID p_material) {
+}
+
+AABB Fog::fog_volume_get_aabb(RID p_fog_volume) const {
+ return AABB();
+}
+
+RS::FogVolumeShape Fog::fog_volume_get_shape(RID p_fog_volume) const {
+ return RS::FOG_VOLUME_SHAPE_BOX;
+}
+
+#endif // GLES3_ENABLED
diff --git a/drivers/gles3/environment/fog.h b/drivers/gles3/environment/fog.h
new file mode 100644
index 0000000000..22bf3bb017
--- /dev/null
+++ b/drivers/gles3/environment/fog.h
@@ -0,0 +1,62 @@
+/*************************************************************************/
+/* fog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef FOG_GLES3_H
+#define FOG_GLES3_H
+
+#ifdef GLES3_ENABLED
+
+#include "core/templates/local_vector.h"
+#include "core/templates/rid_owner.h"
+#include "core/templates/self_list.h"
+#include "servers/rendering/environment/renderer_fog.h"
+
+namespace GLES3 {
+
+class Fog : public RendererFog {
+public:
+ /* FOG VOLUMES */
+
+ virtual RID fog_volume_allocate() override;
+ virtual void fog_volume_initialize(RID p_rid) override;
+ virtual void fog_free(RID p_rid) override;
+
+ virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override;
+ virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override;
+ virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override;
+ virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override;
+ virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override;
+};
+
+} // namespace GLES3
+
+#endif // GLES3_ENABLED
+
+#endif // !FOG_GLES3_H
diff --git a/drivers/gles3/environment/gi.cpp b/drivers/gles3/environment/gi.cpp
index 98d698b2ae..84cdb81d35 100644
--- a/drivers/gles3/environment/gi.cpp
+++ b/drivers/gles3/environment/gi.cpp
@@ -126,13 +126,6 @@ bool GI::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const {
return false;
}
-void GI::voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) {
-}
-
-float GI::voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const {
- return 0;
-}
-
uint32_t GI::voxel_gi_get_version(RID p_voxel_gi) const {
return 0;
}
diff --git a/drivers/gles3/environment/gi.h b/drivers/gles3/environment/gi.h
index bff482d7fa..b633520784 100644
--- a/drivers/gles3/environment/gi.h
+++ b/drivers/gles3/environment/gi.h
@@ -86,9 +86,6 @@ public:
virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override;
virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override;
- virtual void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) override;
- virtual float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const override;
-
virtual uint32_t voxel_gi_get_version(RID p_voxel_gi) const override;
};
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index d41c844d1d..82f7450bc2 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -34,12 +34,12 @@
#include "core/os/os.h"
#include "rasterizer_scene_gles3.h"
-#include "rasterizer_storage_gles3.h"
#include "core/config/project_settings.h"
#include "servers/rendering/rendering_server_default.h"
#include "storage/config.h"
#include "storage/material_storage.h"
+#include "storage/mesh_storage.h"
#include "storage/texture_storage.h"
#ifndef GLES_OVER_GL
@@ -1416,9 +1416,8 @@ RasterizerCanvasGLES3 *RasterizerCanvasGLES3::get_singleton() {
return singleton;
}
-RasterizerCanvasGLES3::RasterizerCanvasGLES3(RasterizerStorageGLES3 *p_storage) {
+RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
singleton = this;
- storage = p_storage;
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
GLES3::Config *config = GLES3::Config::get_singleton();
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index bf13c91e1c..caf649aaf6 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -34,7 +34,6 @@
#ifdef GLES3_ENABLED
#include "rasterizer_scene_gles3.h"
-#include "rasterizer_storage_gles3.h"
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_compositor.h"
#include "storage/material_storage.h"
@@ -204,8 +203,6 @@ public:
typedef void Texture;
- RasterizerStorageGLES3 *storage = nullptr;
-
void canvas_begin(RID p_to_render_target, bool p_to_backbuffer);
//virtual void draw_window_margins(int *black_margin, RID *black_image) override;
@@ -260,7 +257,7 @@ public:
void set_time(double p_time);
static RasterizerCanvasGLES3 *get_singleton();
- RasterizerCanvasGLES3(RasterizerStorageGLES3 *p_storage);
+ RasterizerCanvasGLES3();
~RasterizerCanvasGLES3();
};
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 78ffb42557..33303b1e38 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "rasterizer_gles3.h"
+#include "storage/utilities.h"
#ifdef GLES3_ENABLED
@@ -68,7 +69,7 @@
#endif
#endif
-#if !defined(IPHONE_ENABLED) && !defined(JAVASCRIPT_ENABLED)
+#if !defined(IOS_ENABLED) && !defined(JAVASCRIPT_ENABLED)
// We include EGL below to get debug callback on GLES2 platforms,
// but EGL is not available on iOS.
#define CAN_DEBUG
@@ -99,8 +100,9 @@ void RasterizerGLES3::begin_frame(double frame_step) {
canvas->set_time(time_total);
scene->set_time(time_total, frame_step);
- storage->info.render_final = storage->info.render;
- storage->info.render.reset();
+ GLES3::Utilities *utilities = GLES3::Utilities::get_singleton();
+ utilities->info.render_final = utilities->info.render;
+ utilities->info.render.reset();
//scene->iteration();
}
@@ -197,14 +199,15 @@ void RasterizerGLES3::initialize() {
void RasterizerGLES3::finalize() {
memdelete(scene);
memdelete(canvas);
- memdelete(storage);
memdelete(gi);
+ memdelete(fog);
memdelete(copy_effects);
memdelete(light_storage);
memdelete(particles_storage);
memdelete(mesh_storage);
memdelete(material_storage);
memdelete(texture_storage);
+ memdelete(utilities);
memdelete(config);
}
@@ -265,6 +268,7 @@ RasterizerGLES3::RasterizerGLES3() {
// OpenGL needs to be initialized before initializing the Rasterizers
config = memnew(GLES3::Config);
+ utilities = memnew(GLES3::Utilities);
texture_storage = memnew(GLES3::TextureStorage);
material_storage = memnew(GLES3::MaterialStorage);
mesh_storage = memnew(GLES3::MeshStorage);
@@ -272,9 +276,9 @@ RasterizerGLES3::RasterizerGLES3() {
light_storage = memnew(GLES3::LightStorage);
copy_effects = memnew(GLES3::CopyEffects);
gi = memnew(GLES3::GI);
- storage = memnew(RasterizerStorageGLES3);
- canvas = memnew(RasterizerCanvasGLES3(storage));
- scene = memnew(RasterizerSceneGLES3(storage));
+ fog = memnew(GLES3::Fog);
+ canvas = memnew(RasterizerCanvasGLES3());
+ scene = memnew(RasterizerSceneGLES3());
}
RasterizerGLES3::~RasterizerGLES3() {
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index c0322dc45b..e842b6d70c 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -34,10 +34,10 @@
#ifdef GLES3_ENABLED
#include "effects/copy_effects.h"
+#include "environment/fog.h"
#include "environment/gi.h"
#include "rasterizer_canvas_gles3.h"
#include "rasterizer_scene_gles3.h"
-#include "rasterizer_storage_gles3.h"
#include "servers/rendering/renderer_compositor.h"
#include "storage/config.h"
#include "storage/light_storage.h"
@@ -45,6 +45,7 @@
#include "storage/mesh_storage.h"
#include "storage/particles_storage.h"
#include "storage/texture_storage.h"
+#include "storage/utilities.h"
class RasterizerGLES3 : public RendererCompositor {
private:
@@ -55,27 +56,29 @@ private:
protected:
GLES3::Config *config = nullptr;
+ GLES3::Utilities *utilities = nullptr;
GLES3::TextureStorage *texture_storage = nullptr;
GLES3::MaterialStorage *material_storage = nullptr;
GLES3::MeshStorage *mesh_storage = nullptr;
GLES3::ParticlesStorage *particles_storage = nullptr;
GLES3::LightStorage *light_storage = nullptr;
GLES3::GI *gi = nullptr;
+ GLES3::Fog *fog = nullptr;
GLES3::CopyEffects *copy_effects = nullptr;
- RasterizerStorageGLES3 *storage = nullptr;
RasterizerCanvasGLES3 *canvas = nullptr;
RasterizerSceneGLES3 *scene = nullptr;
void _blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect);
public:
+ RendererUtilities *get_utilities() { return utilities; }
RendererLightStorage *get_light_storage() { return light_storage; }
RendererMaterialStorage *get_material_storage() { return material_storage; }
RendererMeshStorage *get_mesh_storage() { return mesh_storage; }
RendererParticlesStorage *get_particles_storage() { return particles_storage; }
RendererTextureStorage *get_texture_storage() { return texture_storage; }
RendererGI *get_gi() { return gi; }
- RendererStorage *get_storage() { return storage; }
+ RendererFog *get_fog() { return fog; }
RendererCanvasRender *get_canvas() { return canvas; }
RendererSceneRender *get_scene() { return scene; }
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 33c7b9bf32..eee303a2ca 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -33,6 +33,9 @@
#include "core/templates/sort_array.h"
#include "servers/rendering/rendering_server_default.h"
#include "storage/config.h"
+#include "storage/light_storage.h"
+#include "storage/mesh_storage.h"
+#include "storage/texture_storage.h"
#ifdef GLES3_ENABLED
@@ -45,7 +48,7 @@ RasterizerSceneGLES3 *RasterizerSceneGLES3::get_singleton() {
}
RendererSceneRender::GeometryInstance *RasterizerSceneGLES3::geometry_instance_create(RID p_base) {
- RS::InstanceType type = storage->get_base_type(p_base);
+ RS::InstanceType type = RSG::utilities->get_base_type(p_base);
ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
GeometryInstanceGLES3 *ginstance = geometry_instance_alloc.alloc();
@@ -285,16 +288,16 @@ void RasterizerSceneGLES3::_update_dirty_geometry_instances() {
}
}
-void RasterizerSceneGLES3::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) {
+void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) {
switch (p_notification) {
- case RendererStorage::DEPENDENCY_CHANGED_MATERIAL:
- case RendererStorage::DEPENDENCY_CHANGED_MESH:
- case RendererStorage::DEPENDENCY_CHANGED_PARTICLES:
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
- case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: {
+ case Dependency::DEPENDENCY_CHANGED_MATERIAL:
+ case Dependency::DEPENDENCY_CHANGED_MESH:
+ case Dependency::DEPENDENCY_CHANGED_PARTICLES:
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {
static_cast<RasterizerSceneGLES3 *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata);
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
ginstance->instance_count = GLES3::MeshStorage::get_singleton()->multimesh_get_instances_to_draw(ginstance->data->base);
@@ -306,7 +309,7 @@ void RasterizerSceneGLES3::_geometry_instance_dependency_changed(RendererStorage
}
}
-void RasterizerSceneGLES3::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) {
+void RasterizerSceneGLES3::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
static_cast<RasterizerSceneGLES3 *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
}
@@ -376,7 +379,7 @@ void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(Geometry
sdcache->surface_index = p_surface;
if (ginstance->data->dirty_dependencies) {
- storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
+ RSG::utilities->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
}
//shadow
@@ -1310,10 +1313,10 @@ void RasterizerSceneGLES3::camera_effects_set_dof_blur(RID p_camera_effects, boo
void RasterizerSceneGLES3::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) {
}
-void RasterizerSceneGLES3::shadows_quality_set(RS::ShadowQuality p_quality) {
+void RasterizerSceneGLES3::positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {
}
-void RasterizerSceneGLES3::directional_shadow_quality_set(RS::ShadowQuality p_quality) {
+void RasterizerSceneGLES3::directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {
}
RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
@@ -1609,10 +1612,10 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
correction.set_depth_correction(p_flip_y);
CameraMatrix projection = correction * p_render_data->cam_projection;
//store camera into ubo
- RasterizerStorageGLES3::store_camera(projection, scene_state.ubo.projection_matrix);
- RasterizerStorageGLES3::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
- RasterizerStorageGLES3::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
- RasterizerStorageGLES3::store_transform(p_render_data->inv_cam_transform, scene_state.ubo.view_matrix);
+ GLES3::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix);
+ GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
+ GLES3::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
+ GLES3::MaterialStorage::store_transform(p_render_data->inv_cam_transform, scene_state.ubo.view_matrix);
scene_state.ubo.directional_light_count = p_render_data->directional_light_count;
@@ -1659,7 +1662,7 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
Basis sky_transform = env->sky_orientation;
sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
- RasterizerStorageGLES3::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
+ GLES3::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
}
@@ -1974,7 +1977,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *
if (p_render_buffers.is_valid()) {
clear_color = texture_storage->render_target_get_clear_request_color(rb->render_target);
} else {
- clear_color = storage->get_default_clear_color();
+ clear_color = texture_storage->get_default_clear_color();
}
Environment *env = environment_owner.get_or_null(p_environment);
@@ -2657,12 +2660,10 @@ void RasterizerSceneGLES3::decals_set_filter(RS::DecalFilter p_filter) {
void RasterizerSceneGLES3::light_projectors_set_filter(RS::LightProjectorFilter p_filter) {
}
-RasterizerSceneGLES3::RasterizerSceneGLES3(RasterizerStorageGLES3 *p_storage) {
+RasterizerSceneGLES3::RasterizerSceneGLES3() {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
GLES3::Config *config = GLES3::Config::get_singleton();
- storage = p_storage;
-
{
// Setup Lights
@@ -2870,15 +2871,15 @@ RasterizerSceneGLES3::~RasterizerSceneGLES3() {
// Scene Shader
GLES3::MaterialStorage::get_singleton()->shaders.scene_shader.version_free(scene_globals.shader_default_version);
GLES3::MaterialStorage::get_singleton()->shaders.cubemap_filter_shader.version_free(scene_globals.cubemap_filter_shader_version);
- storage->free(scene_globals.default_material);
- storage->free(scene_globals.default_shader);
+ RSG::material_storage->material_free(scene_globals.default_material);
+ RSG::material_storage->shader_free(scene_globals.default_shader);
// Sky Shader
GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_free(sky_globals.shader_default_version);
- storage->free(sky_globals.default_material);
- storage->free(sky_globals.default_shader);
- storage->free(sky_globals.fog_material);
- storage->free(sky_globals.fog_shader);
+ RSG::material_storage->material_free(sky_globals.default_material);
+ RSG::material_storage->shader_free(sky_globals.default_shader);
+ RSG::material_storage->material_free(sky_globals.fog_material);
+ RSG::material_storage->shader_free(sky_globals.fog_shader);
glDeleteBuffers(1, &sky_globals.screen_triangle);
glDeleteVertexArrays(1, &sky_globals.screen_triangle_array);
glDeleteTextures(1, &sky_globals.radical_inverse_vdc_cache_tex);
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 4757a3f161..af47e2eab0 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -37,7 +37,6 @@
#include "core/templates/paged_allocator.h"
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
-#include "rasterizer_storage_gles3.h"
#include "scene/resources/mesh.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_scene_render.h"
@@ -45,6 +44,8 @@
#include "shader_gles3.h"
#include "shaders/cubemap_filter.glsl.gen.h"
#include "shaders/sky.glsl.gen.h"
+#include "storage/material_storage.h"
+#include "storage/utilities.h"
enum RenderListType {
RENDER_LIST_OPAQUE, //used for opaque objects
@@ -125,7 +126,6 @@ struct RenderDataGLES3 {
RendererScene::RenderInfo *render_info = nullptr;
};
-class RasterizerStorageGLES3;
class RasterizerCanvasGLES3;
class RasterizerSceneGLES3 : public RendererSceneRender {
@@ -323,7 +323,7 @@ private:
bool mirror = false;
bool dirty_dependencies = false;
- RendererStorage::DependencyTracker dependency_tracker;
+ DependencyTracker dependency_tracker;
};
Data *data = nullptr;
@@ -345,8 +345,8 @@ private:
INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
};
- static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
- static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker);
SelfList<GeometryInstanceGLES3>::List geometry_instance_dirty_list;
@@ -651,7 +651,6 @@ protected:
RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM;
bool ssao_half_size = false;
- bool ssao_using_half_size = false;
float ssao_adaptive_target = 0.5;
int ssao_blur_passes = 2;
float ssao_fadeout_from = 50.0;
@@ -739,7 +738,6 @@ protected:
void _free_sky_data(Sky *p_sky);
public:
- RasterizerStorageGLES3 *storage;
RasterizerCanvasGLES3 *canvas;
GeometryInstance *geometry_instance_create(RID p_base) override;
@@ -856,8 +854,8 @@ public:
void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) override;
void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override;
- void shadows_quality_set(RS::ShadowQuality p_quality) override;
- void directional_shadow_quality_set(RS::ShadowQuality p_quality) override;
+ void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override;
+ void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override;
RID light_instance_create(RID p_light) override;
void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override;
@@ -943,7 +941,7 @@ public:
void light_projectors_set_filter(RS::LightProjectorFilter p_filter) override;
static RasterizerSceneGLES3 *get_singleton();
- RasterizerSceneGLES3(RasterizerStorageGLES3 *p_storage);
+ RasterizerSceneGLES3();
~RasterizerSceneGLES3();
};
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
deleted file mode 100644
index 3b80d88666..0000000000
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ /dev/null
@@ -1,569 +0,0 @@
-/*************************************************************************/
-/* rasterizer_storage_gles3.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "rasterizer_storage_gles3.h"
-
-#ifdef GLES3_ENABLED
-
-#include "core/config/project_settings.h"
-#include "core/math/transform_3d.h"
-// #include "rasterizer_canvas_gles3.h"
-#include "rasterizer_scene_gles3.h"
-#include "servers/rendering/shader_language.h"
-
-/* MISC */
-
-void RasterizerStorageGLES3::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
- if (GLES3::MeshStorage::get_singleton()->owns_mesh(p_base)) {
- GLES3::Mesh *mesh = GLES3::MeshStorage::get_singleton()->get_mesh(p_base);
- p_instance->update_dependency(&mesh->dependency);
- } else if (GLES3::MeshStorage::get_singleton()->owns_multimesh(p_base)) {
- GLES3::MultiMesh *multimesh = GLES3::MeshStorage::get_singleton()->get_multimesh(p_base);
- p_instance->update_dependency(&multimesh->dependency);
- if (multimesh->mesh.is_valid()) {
- base_update_dependency(multimesh->mesh, p_instance);
- }
- } else if (GLES3::LightStorage::get_singleton()->owns_light(p_base)) {
- GLES3::Light *l = GLES3::LightStorage::get_singleton()->get_light(p_base);
- p_instance->update_dependency(&l->dependency);
- }
-}
-
-Vector<uint8_t> RasterizerStorageGLES3::buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size) {
- Vector<uint8_t> ret;
- ret.resize(p_buffer_size);
- glBindBuffer(p_target, p_buffer);
-
-#if defined(__EMSCRIPTEN__)
- {
- uint8_t *w = ret.ptrw();
- glGetBufferSubData(p_target, 0, p_buffer_size, w);
- }
-#else
- void *data = glMapBufferRange(p_target, 0, p_buffer_size, GL_MAP_READ_BIT);
- ERR_FAIL_NULL_V(data, Vector<uint8_t>());
- {
- uint8_t *w = ret.ptrw();
- memcpy(w, data, p_buffer_size);
- }
- glUnmapBuffer(p_target);
-#endif
- glBindBuffer(p_target, 0);
- return ret;
-}
-
-/* OCCLUDER */
-
-void RasterizerStorageGLES3::occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {
-}
-
-/* FOG */
-
-RID RasterizerStorageGLES3::fog_volume_allocate() {
- return RID();
-}
-
-void RasterizerStorageGLES3::fog_volume_initialize(RID p_rid) {
-}
-
-void RasterizerStorageGLES3::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
-}
-
-void RasterizerStorageGLES3::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) {
-}
-
-void RasterizerStorageGLES3::fog_volume_set_material(RID p_fog_volume, RID p_material) {
-}
-
-AABB RasterizerStorageGLES3::fog_volume_get_aabb(RID p_fog_volume) const {
- return AABB();
-}
-
-RS::FogVolumeShape RasterizerStorageGLES3::fog_volume_get_shape(RID p_fog_volume) const {
- return RS::FOG_VOLUME_SHAPE_BOX;
-}
-
-/* VISIBILITY NOTIFIER */
-RID RasterizerStorageGLES3::visibility_notifier_allocate() {
- return RID();
-}
-
-void RasterizerStorageGLES3::visibility_notifier_initialize(RID p_notifier) {
-}
-
-void RasterizerStorageGLES3::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) {
-}
-
-void RasterizerStorageGLES3::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) {
-}
-
-AABB RasterizerStorageGLES3::visibility_notifier_get_aabb(RID p_notifier) const {
- return AABB();
-}
-
-void RasterizerStorageGLES3::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
-}
-
-/* CANVAS SHADOW */
-
-RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) {
- CanvasLightShadow *cls = memnew(CanvasLightShadow);
-
- if (p_width > config->max_texture_size) {
- p_width = config->max_texture_size;
- }
-
- cls->size = p_width;
- cls->height = 16;
-
- glActiveTexture(GL_TEXTURE0);
-
- glGenFramebuffers(1, &cls->fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
-
- glGenRenderbuffers(1, &cls->depth);
- glBindRenderbuffer(GL_RENDERBUFFER, cls->depth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, cls->depth);
-
- glGenTextures(1, &cls->distance);
- glBindTexture(GL_TEXTURE_2D, cls->distance);
- if (config->use_rgba_2d_shadows) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, cls->size, cls->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- } else {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, cls->size, cls->height, 0, GL_RED, GL_FLOAT, nullptr);
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, cls->distance, 0);
-
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- //printf("errnum: %x\n",status);
- glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
-
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- memdelete(cls);
- ERR_FAIL_COND_V(status != GL_FRAMEBUFFER_COMPLETE, RID());
- }
-
- return canvas_light_shadow_owner.make_rid(cls);
-}
-
-/* LIGHT SHADOW MAPPING */
-/*
-
-RID RasterizerStorageGLES3::canvas_light_occluder_create() {
- CanvasOccluder *co = memnew(CanvasOccluder);
- co->index_id = 0;
- co->vertex_id = 0;
- co->len = 0;
-
- return canvas_occluder_owner.make_rid(co);
-}
-
-void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines) {
- CanvasOccluder *co = canvas_occluder_owner.get(p_occluder);
- ERR_FAIL_COND(!co);
-
- co->lines = p_lines;
-
- if (p_lines.size() != co->len) {
- if (co->index_id) {
- glDeleteBuffers(1, &co->index_id);
- } if (co->vertex_id) {
- glDeleteBuffers(1, &co->vertex_id);
- }
-
- co->index_id = 0;
- co->vertex_id = 0;
- co->len = 0;
- }
-
- if (p_lines.size()) {
- PoolVector<float> geometry;
- PoolVector<uint16_t> indices;
- int lc = p_lines.size();
-
- geometry.resize(lc * 6);
- indices.resize(lc * 3);
-
- PoolVector<float>::Write vw = geometry.write();
- PoolVector<uint16_t>::Write iw = indices.write();
-
- PoolVector<Vector2>::Read lr = p_lines.read();
-
- const int POLY_HEIGHT = 16384;
-
- for (int i = 0; i < lc / 2; i++) {
- vw[i * 12 + 0] = lr[i * 2 + 0].x;
- vw[i * 12 + 1] = lr[i * 2 + 0].y;
- vw[i * 12 + 2] = POLY_HEIGHT;
-
- vw[i * 12 + 3] = lr[i * 2 + 1].x;
- vw[i * 12 + 4] = lr[i * 2 + 1].y;
- vw[i * 12 + 5] = POLY_HEIGHT;
-
- vw[i * 12 + 6] = lr[i * 2 + 1].x;
- vw[i * 12 + 7] = lr[i * 2 + 1].y;
- vw[i * 12 + 8] = -POLY_HEIGHT;
-
- vw[i * 12 + 9] = lr[i * 2 + 0].x;
- vw[i * 12 + 10] = lr[i * 2 + 0].y;
- vw[i * 12 + 11] = -POLY_HEIGHT;
-
- iw[i * 6 + 0] = i * 4 + 0;
- iw[i * 6 + 1] = i * 4 + 1;
- iw[i * 6 + 2] = i * 4 + 2;
-
- iw[i * 6 + 3] = i * 4 + 2;
- iw[i * 6 + 4] = i * 4 + 3;
- iw[i * 6 + 5] = i * 4 + 0;
- }
-
- //if same buffer len is being set, just use BufferSubData to avoid a pipeline flush
-
- if (!co->vertex_id) {
- glGenBuffers(1, &co->vertex_id);
- glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
- glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
- } else {
- glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
- glBufferSubData(GL_ARRAY_BUFFER, 0, lc * 6 * sizeof(real_t), vw.ptr());
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
-
- if (!co->index_id) {
- glGenBuffers(1, &co->index_id);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_DYNAMIC_DRAW);
- } else {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, lc * 3 * sizeof(uint16_t), iw.ptr());
- }
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
-
- co->len = lc;
- }
-}
-*/
-
-RS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
- if (GLES3::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
- return RS::INSTANCE_MESH;
- } else if (GLES3::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
- return RS::INSTANCE_MULTIMESH;
- } else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) {
- return RS::INSTANCE_LIGHT;
- }
- return RS::INSTANCE_NONE;
-}
-
-bool RasterizerStorageGLES3::free(RID p_rid) {
- if (GLES3::TextureStorage::get_singleton()->owns_render_target(p_rid)) {
- GLES3::TextureStorage::get_singleton()->render_target_free(p_rid);
- return true;
- } else if (GLES3::TextureStorage::get_singleton()->owns_texture(p_rid)) {
- GLES3::TextureStorage::get_singleton()->texture_free(p_rid);
- return true;
- } else if (GLES3::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
- GLES3::TextureStorage::get_singleton()->canvas_texture_free(p_rid);
- return true;
- } else if (GLES3::MaterialStorage::get_singleton()->owns_shader(p_rid)) {
- GLES3::MaterialStorage::get_singleton()->shader_free(p_rid);
- return true;
- } else if (GLES3::MaterialStorage::get_singleton()->owns_material(p_rid)) {
- GLES3::MaterialStorage::get_singleton()->material_free(p_rid);
- return true;
- } else if (GLES3::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
- GLES3::MeshStorage::get_singleton()->mesh_free(p_rid);
- return true;
- } else if (GLES3::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
- GLES3::MeshStorage::get_singleton()->multimesh_free(p_rid);
- return true;
- } else if (GLES3::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) {
- GLES3::MeshStorage::get_singleton()->mesh_instance_free(p_rid);
- return true;
- } else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) {
- GLES3::LightStorage::get_singleton()->light_free(p_rid);
- return true;
- } else {
- return false;
- }
- /*
- else if (reflection_probe_owner.owns(p_rid)) {
- // delete the texture
- ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
- reflection_probe->instance_remove_deps();
-
- reflection_probe_owner.free(p_rid);
- memdelete(reflection_probe);
-
- return true;
- } else if (lightmap_capture_data_owner.owns(p_rid)) {
- // delete the texture
- LightmapCapture *lightmap_capture = lightmap_capture_data_owner.get_or_null(p_rid);
- lightmap_capture->instance_remove_deps();
-
- lightmap_capture_data_owner.free(p_rid);
- memdelete(lightmap_capture);
- return true;
-
- } else if (canvas_occluder_owner.owns(p_rid)) {
- CanvasOccluder *co = canvas_occluder_owner.get_or_null(p_rid);
- if (co->index_id) {
- glDeleteBuffers(1, &co->index_id);
- }
- if (co->vertex_id) {
- glDeleteBuffers(1, &co->vertex_id);
- }
-
- canvas_occluder_owner.free(p_rid);
- memdelete(co);
-
- return true;
-
- } else if (canvas_light_shadow_owner.owns(p_rid)) {
- CanvasLightShadow *cls = canvas_light_shadow_owner.get_or_null(p_rid);
- glDeleteFramebuffers(1, &cls->fbo);
- glDeleteRenderbuffers(1, &cls->depth);
- glDeleteTextures(1, &cls->distance);
- canvas_light_shadow_owner.free(p_rid);
- memdelete(cls);
-
- return true;
- */
-}
-
-bool RasterizerStorageGLES3::has_os_feature(const String &p_feature) const {
- if (!config) {
- return false;
- }
-
- if (p_feature == "rgtc") {
- return config->rgtc_supported;
- }
-
- if (p_feature == "s3tc") {
- return config->s3tc_supported;
- }
-
- if (p_feature == "bptc") {
- return config->bptc_supported;
- }
-
- if (p_feature == "etc" || p_feature == "etc2") {
- return config->etc2_supported;
- }
-
- return false;
-}
-
-////////////////////////////////////////////
-
-void RasterizerStorageGLES3::set_debug_generate_wireframes(bool p_generate) {
-}
-
-//void RasterizerStorageGLES3::render_info_begin_capture() {
-// info.snap = info.render;
-//}
-
-//void RasterizerStorageGLES3::render_info_end_capture() {
-// info.snap.object_count = info.render.object_count - info.snap.object_count;
-// info.snap.draw_call_count = info.render.draw_call_count - info.snap.draw_call_count;
-// info.snap.material_switch_count = info.render.material_switch_count - info.snap.material_switch_count;
-// info.snap.surface_switch_count = info.render.surface_switch_count - info.snap.surface_switch_count;
-// info.snap.shader_rebind_count = info.render.shader_rebind_count - info.snap.shader_rebind_count;
-// info.snap.vertices_count = info.render.vertices_count - info.snap.vertices_count;
-// info.snap._2d_item_count = info.render._2d_item_count - info.snap._2d_item_count;
-// info.snap._2d_draw_call_count = info.render._2d_draw_call_count - info.snap._2d_draw_call_count;
-//}
-
-//int RasterizerStorageGLES3::get_captured_render_info(RS::RenderInfo p_info) {
-// switch (p_info) {
-// case RS::INFO_OBJECTS_IN_FRAME: {
-// return info.snap.object_count;
-// } break;
-// case RS::INFO_VERTICES_IN_FRAME: {
-// return info.snap.vertices_count;
-// } break;
-// case RS::INFO_MATERIAL_CHANGES_IN_FRAME: {
-// return info.snap.material_switch_count;
-// } break;
-// case RS::INFO_SHADER_CHANGES_IN_FRAME: {
-// return info.snap.shader_rebind_count;
-// } break;
-// case RS::INFO_SURFACE_CHANGES_IN_FRAME: {
-// return info.snap.surface_switch_count;
-// } break;
-// case RS::INFO_DRAW_CALLS_IN_FRAME: {
-// return info.snap.draw_call_count;
-// } break;
-// /*
-// case RS::INFO_2D_ITEMS_IN_FRAME: {
-// return info.snap._2d_item_count;
-// } break;
-// case RS::INFO_2D_DRAW_CALLS_IN_FRAME: {
-// return info.snap._2d_draw_call_count;
-// } break;
-// */
-// default: {
-// return get_render_info(p_info);
-// }
-// }
-//}
-
-//int RasterizerStorageGLES3::get_render_info(RS::RenderInfo p_info) {
-// switch (p_info) {
-// case RS::INFO_OBJECTS_IN_FRAME:
-// return info.render_final.object_count;
-// case RS::INFO_VERTICES_IN_FRAME:
-// return info.render_final.vertices_count;
-// case RS::INFO_MATERIAL_CHANGES_IN_FRAME:
-// return info.render_final.material_switch_count;
-// case RS::INFO_SHADER_CHANGES_IN_FRAME:
-// return info.render_final.shader_rebind_count;
-// case RS::INFO_SURFACE_CHANGES_IN_FRAME:
-// return info.render_final.surface_switch_count;
-// case RS::INFO_DRAW_CALLS_IN_FRAME:
-// return info.render_final.draw_call_count;
-// /*
-// case RS::INFO_2D_ITEMS_IN_FRAME:
-// return info.render_final._2d_item_count;
-// case RS::INFO_2D_DRAW_CALLS_IN_FRAME:
-// return info.render_final._2d_draw_call_count;
-//*/
-// case RS::INFO_USAGE_VIDEO_MEM_TOTAL:
-// return 0; //no idea
-// case RS::INFO_VIDEO_MEM_USED:
-// return info.vertex_mem + info.texture_mem;
-// case RS::INFO_TEXTURE_MEM_USED:
-// return info.texture_mem;
-// case RS::INFO_VERTEX_MEM_USED:
-// return info.vertex_mem;
-// default:
-// return 0; //no idea either
-// }
-//}
-
-String RasterizerStorageGLES3::get_video_adapter_name() const {
- return (const char *)glGetString(GL_RENDERER);
-}
-
-String RasterizerStorageGLES3::get_video_adapter_vendor() const {
- return (const char *)glGetString(GL_VENDOR);
-}
-
-RenderingDevice::DeviceType RasterizerStorageGLES3::get_video_adapter_type() const {
- return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER;
-}
-
-String RasterizerStorageGLES3::get_video_adapter_api_version() const {
- return (const char *)glGetString(GL_VERSION);
-}
-
-void RasterizerStorageGLES3::initialize() {
- config = GLES3::Config::get_singleton();
-
- // skeleton buffer
- {
- resources.skeleton_transform_buffer_size = 0;
- glGenBuffers(1, &resources.skeleton_transform_buffer);
- }
-
- // radical inverse vdc cache texture
- // used for cubemap filtering
- glGenTextures(1, &resources.radical_inverse_vdc_cache_tex);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, resources.radical_inverse_vdc_cache_tex);
- /*
- uint8_t radical_inverse[512];
-
- for (uint32_t i = 0; i < 512; i++) {
- uint32_t bits = i;
-
- bits = (bits << 16) | (bits >> 16);
- bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >> 1);
- bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >> 2);
- bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >> 4);
- bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >> 8);
-
- float value = float(bits) * 2.3283064365386963e-10;
- radical_inverse[i] = uint8_t(CLAMP(value * 255.0, 0, 255));
- }
-
- //glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 512, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, radical_inverse);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //need this for proper sampling
- */
- glBindTexture(GL_TEXTURE_2D, 0);
-
- {
- glGenFramebuffers(1, &resources.mipmap_blur_fbo);
- glGenTextures(1, &resources.mipmap_blur_color);
- }
-
-#ifdef GLES_OVER_GL
- glEnable(GL_PROGRAM_POINT_SIZE);
-#endif
-}
-
-void RasterizerStorageGLES3::finalize() {
-}
-
-void RasterizerStorageGLES3::update_memory_info() {
-}
-
-uint64_t RasterizerStorageGLES3::get_rendering_info(RS::RenderingInfo p_info) {
- return 0;
-}
-
-void RasterizerStorageGLES3::update_dirty_resources() {
- GLES3::MaterialStorage::get_singleton()->_update_global_variables();
- GLES3::MaterialStorage::get_singleton()->_update_queued_materials();
- //GLES3::MeshStorage::get_singleton()->_update_dirty_skeletons();
- GLES3::MeshStorage::get_singleton()->_update_dirty_multimeshes();
-}
-
-RasterizerStorageGLES3::RasterizerStorageGLES3() {
- initialize();
-}
-
-RasterizerStorageGLES3::~RasterizerStorageGLES3() {
-}
-
-#endif // GLES3_ENABLED
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
deleted file mode 100644
index c42efbce19..0000000000
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/*************************************************************************/
-/* rasterizer_storage_gles3.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef RASTERIZER_STORAGE_OPENGL_H
-#define RASTERIZER_STORAGE_OPENGL_H
-
-#ifdef GLES3_ENABLED
-
-#include "core/templates/local_vector.h"
-#include "core/templates/rid_owner.h"
-#include "core/templates/self_list.h"
-#include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering/renderer_storage.h"
-#include "servers/rendering/shader_compiler.h"
-#include "servers/rendering/shader_language.h"
-#include "storage/config.h"
-#include "storage/light_storage.h"
-#include "storage/material_storage.h"
-#include "storage/mesh_storage.h"
-#include "storage/texture_storage.h"
-
-// class RasterizerCanvasGLES3;
-// class RasterizerSceneGLES3;
-
-class RasterizerStorageGLES3 : public RendererStorage {
-public:
- // RasterizerCanvasGLES3 *canvas;
- // RasterizerSceneGLES3 *scene;
-
- GLES3::Config *config = nullptr;
-
- static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
- p_array[0] = p_mtx.basis.rows[0][0];
- p_array[1] = p_mtx.basis.rows[1][0];
- p_array[2] = p_mtx.basis.rows[2][0];
- p_array[3] = 0;
- p_array[4] = p_mtx.basis.rows[0][1];
- p_array[5] = p_mtx.basis.rows[1][1];
- p_array[6] = p_mtx.basis.rows[2][1];
- p_array[7] = 0;
- p_array[8] = p_mtx.basis.rows[0][2];
- p_array[9] = p_mtx.basis.rows[1][2];
- p_array[10] = p_mtx.basis.rows[2][2];
- p_array[11] = 0;
- p_array[12] = p_mtx.origin.x;
- p_array[13] = p_mtx.origin.y;
- p_array[14] = p_mtx.origin.z;
- p_array[15] = 1;
- }
-
- static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
- p_array[0] = p_mtx.rows[0][0];
- p_array[1] = p_mtx.rows[1][0];
- p_array[2] = p_mtx.rows[2][0];
- p_array[3] = 0;
- p_array[4] = p_mtx.rows[0][1];
- p_array[5] = p_mtx.rows[1][1];
- p_array[6] = p_mtx.rows[2][1];
- p_array[7] = 0;
- p_array[8] = p_mtx.rows[0][2];
- p_array[9] = p_mtx.rows[1][2];
- p_array[10] = p_mtx.rows[2][2];
- p_array[11] = 0;
- }
-
- static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- p_array[i * 4 + j] = p_mtx.matrix[i][j];
- }
- }
- }
-
- // Buffer size is specified in bytes
- static Vector<uint8_t> buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size);
-
- struct Resources {
- GLuint mipmap_blur_fbo;
- GLuint mipmap_blur_color;
-
- GLuint radical_inverse_vdc_cache_tex;
- bool use_rgba_2d_shadows;
-
- size_t skeleton_transform_buffer_size;
- GLuint skeleton_transform_buffer;
- LocalVector<float> skeleton_transform_cpu_buffer;
-
- } resources;
-
- struct Info {
- uint64_t texture_mem = 0;
- uint64_t vertex_mem = 0;
-
- struct Render {
- uint32_t object_count;
- uint32_t draw_call_count;
- uint32_t material_switch_count;
- uint32_t surface_switch_count;
- uint32_t shader_rebind_count;
- uint32_t vertices_count;
- uint32_t _2d_item_count;
- uint32_t _2d_draw_call_count;
-
- void reset() {
- object_count = 0;
- draw_call_count = 0;
- material_switch_count = 0;
- surface_switch_count = 0;
- shader_rebind_count = 0;
- vertices_count = 0;
- _2d_item_count = 0;
- _2d_draw_call_count = 0;
- }
- } render, render_final, snap;
-
- Info() {
- render.reset();
- render_final.reset();
- }
-
- } info;
-
- /////////////////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////API////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-
-public:
- virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override;
-
- /* OCCLUDER */
-
- void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices);
-
- /* FOG VOLUMES */
-
- RID fog_volume_allocate() override;
- void fog_volume_initialize(RID p_rid) override;
-
- void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override;
- void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override;
- void fog_volume_set_material(RID p_fog_volume, RID p_material) override;
- AABB fog_volume_get_aabb(RID p_fog_volume) const override;
- RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override;
-
- /* VISIBILITY NOTIFIER */
- RID visibility_notifier_allocate() override;
- void visibility_notifier_initialize(RID p_notifier) override;
- void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override;
- void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override;
-
- AABB visibility_notifier_get_aabb(RID p_notifier) const override;
- void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override;
-
- // access from canvas
- // GLES3::RenderTarget * render_target_get(RID p_render_target);
-
- /* CANVAS SHADOW */
-
- struct CanvasLightShadow {
- RID self;
- int size;
- int height;
- GLuint fbo;
- GLuint depth;
- GLuint distance; //for older devices
- };
-
- RID_PtrOwner<CanvasLightShadow> canvas_light_shadow_owner;
-
- RID canvas_light_shadow_buffer_create(int p_width);
-
- /* LIGHT SHADOW MAPPING */
- /*
- struct CanvasOccluder {
- RID self;
-
- GLuint vertex_id; // 0 means, unconfigured
- GLuint index_id; // 0 means, unconfigured
- LocalVector<Vector2> lines;
- int len;
- };
-
- RID_Owner<CanvasOccluder> canvas_occluder_owner;
-
- RID canvas_light_occluder_create();
- void canvas_light_occluder_set_polylines(RID p_occluder, const LocalVector<Vector2> &p_lines);
-*/
-
- RS::InstanceType get_base_type(RID p_rid) const override;
-
- bool free(RID p_rid) override;
-
- void initialize();
- void finalize();
-
- void update_memory_info() override;
- uint64_t get_rendering_info(RS::RenderingInfo p_info) override;
-
- bool has_os_feature(const String &p_feature) const override;
-
- void update_dirty_resources() override;
-
- void set_debug_generate_wireframes(bool p_generate) override;
-
- // void render_info_begin_capture() override;
- // void render_info_end_capture() override;
- // int get_captured_render_info(RS::RenderInfo p_info) override;
-
- // int get_render_info(RS::RenderInfo p_info) override;
- String get_video_adapter_name() const override;
- String get_video_adapter_vendor() const override;
- RenderingDevice::DeviceType get_video_adapter_type() const override;
- String get_video_adapter_api_version() const override;
-
- void capture_timestamps_begin() override {}
- void capture_timestamp(const String &p_name) override {}
- uint32_t get_captured_timestamps_count() const override {
- return 0;
- }
- uint64_t get_captured_timestamps_frame() const override {
- return 0;
- }
- uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override {
- return 0;
- }
- uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override {
- return 0;
- }
- String get_captured_timestamp_name(uint32_t p_index) const override {
- return String();
- }
-
- RasterizerStorageGLES3();
- ~RasterizerStorageGLES3();
-};
-
-#endif // GLES3_ENABLED
-
-#endif // RASTERIZER_STORAGE_OPENGL_H
diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub
index d8dd573f57..83ffe8b1e1 100644
--- a/drivers/gles3/shaders/SCsub
+++ b/drivers/gles3/shaders/SCsub
@@ -10,7 +10,7 @@ if "GLES3_GLSL" in env["BUILDERS"]:
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
# make sure we recompile shaders if include files change
- env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files)
+ env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#gles3_builders.py"])
env.GLES3_GLSL("canvas.glsl")
env.GLES3_GLSL("copy.glsl")
diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp
index 954aa11c0d..22578c9e91 100644
--- a/drivers/gles3/storage/light_storage.cpp
+++ b/drivers/gles3/storage/light_storage.cpp
@@ -139,12 +139,12 @@ void LightStorage::light_set_param(RID p_light, RS::LightParam p_param, float p_
case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
case RS::LIGHT_PARAM_SHADOW_BIAS: {
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
} break;
case RS::LIGHT_PARAM_SIZE: {
if ((light->param[p_param] > CMP_EPSILON) != (p_value > CMP_EPSILON)) {
//changing from no size to size and the opposite
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
}
} break;
default: {
@@ -160,7 +160,7 @@ void LightStorage::light_set_shadow(RID p_light, bool p_enabled) {
light->shadow = p_enabled;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_projector(RID p_light, RID p_texture) {
@@ -182,7 +182,7 @@ void LightStorage::light_set_projector(RID p_light, RID p_texture) {
if (light->projector.is_valid()) {
texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
}
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
}
}
@@ -200,7 +200,7 @@ void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
light->cull_mask = p_mask;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
@@ -220,7 +220,7 @@ void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled)
light->reverse_cull = p_enabled;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
@@ -230,7 +230,7 @@ void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mod
light->bake_mode = p_bake_mode;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
@@ -240,7 +240,7 @@ void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMo
light->omni_shadow_mode = p_mode;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
RS::LightOmniShadowMode LightStorage::light_omni_get_shadow_mode(RID p_light) {
@@ -256,7 +256,7 @@ void LightStorage::light_directional_set_shadow_mode(RID p_light, RS::LightDirec
light->directional_shadow_mode = p_mode;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable) {
@@ -265,7 +265,7 @@ void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable
light->directional_blend_splits = p_enable;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
bool LightStorage::light_directional_get_blend_splits(RID p_light) const {
@@ -476,4 +476,104 @@ float LightStorage::lightmap_get_probe_capture_update_speed() const {
return 0;
}
+/* LIGHT SHADOW MAPPING */
+/*
+
+RID LightStorage::canvas_light_occluder_create() {
+ CanvasOccluder *co = memnew(CanvasOccluder);
+ co->index_id = 0;
+ co->vertex_id = 0;
+ co->len = 0;
+
+ return canvas_occluder_owner.make_rid(co);
+}
+
+void LightStorage::canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines) {
+ CanvasOccluder *co = canvas_occluder_owner.get(p_occluder);
+ ERR_FAIL_COND(!co);
+
+ co->lines = p_lines;
+
+ if (p_lines.size() != co->len) {
+ if (co->index_id) {
+ glDeleteBuffers(1, &co->index_id);
+ } if (co->vertex_id) {
+ glDeleteBuffers(1, &co->vertex_id);
+ }
+
+ co->index_id = 0;
+ co->vertex_id = 0;
+ co->len = 0;
+ }
+
+ if (p_lines.size()) {
+ PoolVector<float> geometry;
+ PoolVector<uint16_t> indices;
+ int lc = p_lines.size();
+
+ geometry.resize(lc * 6);
+ indices.resize(lc * 3);
+
+ PoolVector<float>::Write vw = geometry.write();
+ PoolVector<uint16_t>::Write iw = indices.write();
+
+ PoolVector<Vector2>::Read lr = p_lines.read();
+
+ const int POLY_HEIGHT = 16384;
+
+ for (int i = 0; i < lc / 2; i++) {
+ vw[i * 12 + 0] = lr[i * 2 + 0].x;
+ vw[i * 12 + 1] = lr[i * 2 + 0].y;
+ vw[i * 12 + 2] = POLY_HEIGHT;
+
+ vw[i * 12 + 3] = lr[i * 2 + 1].x;
+ vw[i * 12 + 4] = lr[i * 2 + 1].y;
+ vw[i * 12 + 5] = POLY_HEIGHT;
+
+ vw[i * 12 + 6] = lr[i * 2 + 1].x;
+ vw[i * 12 + 7] = lr[i * 2 + 1].y;
+ vw[i * 12 + 8] = -POLY_HEIGHT;
+
+ vw[i * 12 + 9] = lr[i * 2 + 0].x;
+ vw[i * 12 + 10] = lr[i * 2 + 0].y;
+ vw[i * 12 + 11] = -POLY_HEIGHT;
+
+ iw[i * 6 + 0] = i * 4 + 0;
+ iw[i * 6 + 1] = i * 4 + 1;
+ iw[i * 6 + 2] = i * 4 + 2;
+
+ iw[i * 6 + 3] = i * 4 + 2;
+ iw[i * 6 + 4] = i * 4 + 3;
+ iw[i * 6 + 5] = i * 4 + 0;
+ }
+
+ //if same buffer len is being set, just use BufferSubData to avoid a pipeline flush
+
+ if (!co->vertex_id) {
+ glGenBuffers(1, &co->vertex_id);
+ glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
+ glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
+ } else {
+ glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, lc * 6 * sizeof(real_t), vw.ptr());
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+
+ if (!co->index_id) {
+ glGenBuffers(1, &co->index_id);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_DYNAMIC_DRAW);
+ } else {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, lc * 3 * sizeof(uint16_t), iw.ptr());
+ }
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
+
+ co->len = lc;
+ }
+}
+*/
+
#endif // !GLES3_ENABLED
diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h
index 5acaf45aa3..575ab93eab 100644
--- a/drivers/gles3/storage/light_storage.h
+++ b/drivers/gles3/storage/light_storage.h
@@ -37,8 +37,8 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/light_storage.h"
+#include "servers/rendering/storage/utilities.h"
#include "platform_config.h"
#ifndef OPENGL_INCLUDE_H
@@ -72,7 +72,7 @@ struct Light {
RS::LightDirectionalSkyMode directional_sky_mode = RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY;
uint64_t version = 0;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* REFLECTION PROBE */
@@ -93,7 +93,7 @@ struct ReflectionProbe {
uint32_t cull_mask = (1 << 20) - 1;
float mesh_lod_threshold = 0.01;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* LIGHTMAP */
@@ -115,7 +115,7 @@ struct Lightmap {
int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
};
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
class LightStorage : public RendererLightStorage {
@@ -321,6 +321,23 @@ public:
virtual bool lightmap_is_interior(RID p_lightmap) const override;
virtual void lightmap_set_probe_capture_update_speed(float p_speed) override;
virtual float lightmap_get_probe_capture_update_speed() const override;
+
+ /* LIGHT SHADOW MAPPING */
+ /*
+ struct CanvasOccluder {
+ RID self;
+
+ GLuint vertex_id; // 0 means, unconfigured
+ GLuint index_id; // 0 means, unconfigured
+ LocalVector<Vector2> lines;
+ int len;
+ };
+
+ RID_Owner<CanvasOccluder> canvas_occluder_owner;
+
+ RID canvas_light_occluder_create();
+ void canvas_light_occluder_set_polylines(RID p_occluder, const LocalVector<Vector2> &p_lines);
+ */
};
} // namespace GLES3
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index fd50bdedbd..8a8d79b3f7 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -1378,6 +1378,7 @@ MaterialStorage::MaterialStorage() {
actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
actions.usage_defines["LIGHT"] = "#define LIGHT_SHADER_CODE_USED\n";
+ actions.usage_defines["SPECULAR_SHININESS"] = "#define SPECULAR_SHININESS_USED\n";
actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
@@ -2456,7 +2457,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
for (Material *E : shader->owners) {
Material *material = E;
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
}
@@ -2593,7 +2594,7 @@ void MaterialStorage::material_set_shader(RID p_material, RID p_shader) {
}
if (p_shader.is_null()) {
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
material->shader_id = 0;
return;
}
@@ -2616,7 +2617,7 @@ void MaterialStorage::material_set_shader(RID p_material, RID p_shader) {
material->data->set_next_pass(material->next_pass);
material->data->set_render_priority(material->priority);
//updating happens later
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
@@ -2662,7 +2663,7 @@ void MaterialStorage::material_set_next_pass(RID p_material, RID p_next_material
material->data->set_next_pass(p_next_material);
}
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
void MaterialStorage::material_set_render_priority(RID p_material, int priority) {
@@ -2715,7 +2716,7 @@ void MaterialStorage::material_get_instance_shader_parameters(RID p_material, Li
}
}
-void MaterialStorage::material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) {
+void MaterialStorage::material_update_dependency(RID p_material, DependencyTracker *p_instance) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
p_instance->update_dependency(&material->dependency);
diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h
index 09f6680bec..6ad277c2b9 100644
--- a/drivers/gles3/storage/material_storage.h
+++ b/drivers/gles3/storage/material_storage.h
@@ -37,10 +37,10 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/shader_compiler.h"
#include "servers/rendering/shader_language.h"
#include "servers/rendering/storage/material_storage.h"
+#include "servers/rendering/storage/utilities.h"
#include "../shaders/canvas.glsl.gen.h"
#include "../shaders/cubemap_filter.glsl.gen.h"
@@ -125,7 +125,7 @@ struct Material {
RID next_pass;
SelfList<Material> update_element;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
Material() :
update_element(this) {}
@@ -453,6 +453,48 @@ public:
MaterialStorage();
virtual ~MaterialStorage();
+ static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.basis.rows[0][0];
+ p_array[1] = p_mtx.basis.rows[1][0];
+ p_array[2] = p_mtx.basis.rows[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_mtx.basis.rows[0][1];
+ p_array[5] = p_mtx.basis.rows[1][1];
+ p_array[6] = p_mtx.basis.rows[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_mtx.basis.rows[0][2];
+ p_array[9] = p_mtx.basis.rows[1][2];
+ p_array[10] = p_mtx.basis.rows[2][2];
+ p_array[11] = 0;
+ p_array[12] = p_mtx.origin.x;
+ p_array[13] = p_mtx.origin.y;
+ p_array[14] = p_mtx.origin.z;
+ p_array[15] = 1;
+ }
+
+ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.rows[0][0];
+ p_array[1] = p_mtx.rows[1][0];
+ p_array[2] = p_mtx.rows[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_mtx.rows[0][1];
+ p_array[5] = p_mtx.rows[1][1];
+ p_array[6] = p_mtx.rows[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_mtx.rows[0][2];
+ p_array[9] = p_mtx.rows[1][2];
+ p_array[10] = p_mtx.rows[2][2];
+ p_array[11] = 0;
+ }
+
+ static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ p_array[i * 4 + j] = p_mtx.matrix[i][j];
+ }
+ }
+ }
+
struct Shaders {
CanvasShaderGLES3 canvas_shader;
SkyShaderGLES3 sky_shader;
@@ -534,7 +576,7 @@ public:
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override;
- virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override;
+ virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override;
_FORCE_INLINE_ uint32_t material_get_shader_id(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp
index 5aa82bfcc1..88b81805fa 100644
--- a/drivers/gles3/storage/mesh_storage.cpp
+++ b/drivers/gles3/storage/mesh_storage.cpp
@@ -31,8 +31,8 @@
#ifdef GLES3_ENABLED
#include "mesh_storage.h"
-#include "../rasterizer_storage_gles3.h"
#include "material_storage.h"
+#include "utilities.h"
using namespace GLES3;
@@ -64,6 +64,8 @@ void MeshStorage::mesh_free(RID p_rid) {
mesh_clear(p_rid);
mesh_set_shadow_mesh(p_rid, RID());
Mesh *mesh = mesh_owner.get_or_null(p_rid);
+ ERR_FAIL_COND(!mesh);
+
mesh->dependency.deleted_notify(p_rid);
if (mesh->instances.size()) {
ERR_PRINT("deleting mesh with active instances");
@@ -72,7 +74,7 @@ void MeshStorage::mesh_free(RID p_rid) {
for (Mesh *E : mesh->shadow_owners) {
Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
- shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
}
mesh_owner.free(p_rid);
@@ -268,12 +270,12 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
_mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1);
}
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
for (Mesh *E : mesh->shadow_owners) {
Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
- shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
mesh->material_cache.clear();
@@ -314,7 +316,7 @@ void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_mat
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
mesh->surfaces[p_surface]->material = p_material;
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
mesh->material_cache.clear();
}
@@ -335,10 +337,10 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
RS::SurfaceData sd;
sd.format = s.format;
- sd.vertex_data = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_buffer_size);
+ sd.vertex_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_buffer_size);
if (s.attribute_buffer != 0) {
- sd.attribute_data = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, s.attribute_buffer, s.attribute_buffer_size);
+ sd.attribute_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.attribute_buffer, s.attribute_buffer_size);
}
sd.vertex_count = s.vertex_count;
@@ -346,14 +348,14 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
sd.primitive = s.primitive;
if (sd.index_count) {
- sd.index_data = RasterizerStorageGLES3::buffer_get_data(GL_ELEMENT_ARRAY_BUFFER, s.index_buffer, s.index_buffer_size);
+ sd.index_data = Utilities::buffer_get_data(GL_ELEMENT_ARRAY_BUFFER, s.index_buffer, s.index_buffer_size);
}
sd.aabb = s.aabb;
for (uint32_t i = 0; i < s.lod_count; i++) {
RS::SurfaceData::LOD lod;
lod.edge_length = s.lods[i].edge_length;
- lod.index_data = RasterizerStorageGLES3::buffer_get_data(GL_ELEMENT_ARRAY_BUFFER, s.lods[i].index_buffer, s.lods[i].index_buffer_size);
+ lod.index_data = Utilities::buffer_get_data(GL_ELEMENT_ARRAY_BUFFER, s.lods[i].index_buffer, s.lods[i].index_buffer_size);
sd.lods.push_back(lod);
}
@@ -504,7 +506,7 @@ void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) {
shadow_mesh->shadow_owners.insert(mesh);
}
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
void MeshStorage::mesh_clear(RID p_mesh) {
@@ -553,12 +555,12 @@ void MeshStorage::mesh_clear(RID p_mesh) {
_mesh_instance_clear(mi);
}
mesh->has_bone_weights = false;
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
for (Mesh *E : mesh->shadow_owners) {
Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
- shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
}
@@ -899,7 +901,7 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MULTIMESH);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH);
}
int MeshStorage::multimesh_get_instance_count(RID p_multimesh) const {
@@ -926,14 +928,14 @@ void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
} else if (multimesh->instances) {
// Need to re-create AABB. Unfortunately, calling this has a penalty.
if (multimesh->buffer_set) {
- Vector<uint8_t> buffer = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));
+ Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));
const uint8_t *r = buffer.ptr();
const float *data = (const float *)r;
_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
}
}
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
#define MULTIMESH_DIRTY_REGION_SIZE 512
@@ -950,7 +952,7 @@ void MeshStorage::_multimesh_make_local(MultiMesh *multimesh) const {
float *w = multimesh->data_cache.ptrw();
if (multimesh->buffer_set) {
- Vector<uint8_t> buffer = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));
+ Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));
{
const uint8_t *r = buffer.ptr();
@@ -1348,7 +1350,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
const float *data = multimesh->data_cache.ptr();
_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
}
@@ -1363,7 +1365,7 @@ Vector<float> MeshStorage::multimesh_get_buffer(RID p_multimesh) const {
} else {
// Buffer not cached, so fetch from GPU memory. This can be a stalling operation, avoid whenever possible.
- Vector<uint8_t> buffer = RasterizerStorageGLES3::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));
+ Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float));
ret.resize(multimesh->instances * multimesh->stride_cache);
{
float *w = ret.ptrw();
@@ -1439,7 +1441,7 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible
multimesh->visible_instances = p_visible;
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
}
int MeshStorage::multimesh_get_visible_instances(RID p_multimesh) const {
@@ -1493,7 +1495,7 @@ void MeshStorage::_update_dirty_multimeshes() {
if (multimesh->aabb_dirty && multimesh->mesh.is_valid()) {
_multimesh_re_create_aabb(multimesh, data, visible_instances);
multimesh->aabb_dirty = false;
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
}
@@ -1542,7 +1544,12 @@ Transform2D MeshStorage::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bo
return Transform2D();
}
-void MeshStorage::skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) {
+void MeshStorage::skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) {
+}
+
+/* OCCLUDER */
+
+void MeshStorage::occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {
}
#endif // GLES3_ENABLED
diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h
index 3bb7061413..c51cd5dcd6 100644
--- a/drivers/gles3/storage/mesh_storage.h
+++ b/drivers/gles3/storage/mesh_storage.h
@@ -37,6 +37,7 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/storage/mesh_storage.h"
+#include "servers/rendering/storage/utilities.h"
#include "platform_config.h"
#ifndef OPENGL_INCLUDE_H
@@ -126,7 +127,7 @@ struct Mesh {
RID shadow_mesh;
HashSet<Mesh *> shadow_owners;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* Mesh Instance */
@@ -179,7 +180,7 @@ struct MultiMesh {
bool dirty = false;
MultiMesh *dirty_list = nullptr;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
struct Skeleton {
@@ -194,7 +195,7 @@ struct Skeleton {
uint64_t version = 1;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
class MeshStorage : public RendererMeshStorage {
@@ -531,7 +532,11 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override;
- virtual void skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) override;
+ virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override;
+
+ /* OCCLUDER */
+
+ void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices);
};
} // namespace GLES3
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index 42c80da39a..c05f516548 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -183,6 +183,12 @@ TextureStorage::TextureStorage() {
texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
}
}
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+#ifdef GLES_OVER_GL
+ glEnable(GL_PROGRAM_POINT_SIZE);
+#endif
}
TextureStorage::~TextureStorage() {
@@ -244,6 +250,55 @@ void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS:
ct->texture_repeat = p_repeat;
}
+/* CANVAS SHADOW */
+
+RID TextureStorage::canvas_light_shadow_buffer_create(int p_width) {
+ Config *config = Config::get_singleton();
+ CanvasLightShadow *cls = memnew(CanvasLightShadow);
+
+ if (p_width > config->max_texture_size) {
+ p_width = config->max_texture_size;
+ }
+
+ cls->size = p_width;
+ cls->height = 16;
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glGenFramebuffers(1, &cls->fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
+
+ glGenRenderbuffers(1, &cls->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, cls->depth);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, cls->depth);
+
+ glGenTextures(1, &cls->distance);
+ glBindTexture(GL_TEXTURE_2D, cls->distance);
+ if (config->use_rgba_2d_shadows) {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, cls->size, cls->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, cls->size, cls->height, 0, GL_RED, GL_FLOAT, nullptr);
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, cls->distance, 0);
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ //printf("errnum: %x\n",status);
+ glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ memdelete(cls);
+ ERR_FAIL_COND_V(status != GL_FRAMEBUFFER_COMPLETE, RID());
+ }
+
+ return canvas_light_shadow_owner.make_rid(cls);
+}
+
/* Texture API */
Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const {
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index d6d04e45a1..b5d5641086 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -132,6 +132,17 @@ struct CanvasTexture {
bool cleared_cache = true;
};
+/* CANVAS SHADOW */
+
+struct CanvasLightShadow {
+ RID self;
+ int size;
+ int height;
+ GLuint fbo;
+ GLuint depth;
+ GLuint distance; //for older devices
+};
+
struct RenderTarget;
struct Texture {
@@ -364,6 +375,10 @@ private:
RID_Owner<CanvasTexture, true> canvas_texture_owner;
+ /* CANVAS SHADOW */
+
+ RID_PtrOwner<CanvasLightShadow> canvas_light_shadow_owner;
+
/* Texture API */
mutable RID_Owner<Texture> texture_owner;
@@ -403,6 +418,10 @@ public:
virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override;
virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override;
+ /* CANVAS SHADOW */
+
+ RID canvas_light_shadow_buffer_create(int p_width);
+
/* Texture API */
Texture *get_texture(RID p_rid) {
@@ -527,6 +546,16 @@ public:
void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps);
void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color);
void render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region);
+ virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) override{};
+ virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override{};
+
+ void bind_framebuffer(GLuint framebuffer) {
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ }
+
+ void bind_framebuffer_system() {
+ glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+ }
String get_framebuffer_error(GLenum p_status);
};
diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp
new file mode 100644
index 0000000000..a00210a2ab
--- /dev/null
+++ b/drivers/gles3/storage/utilities.cpp
@@ -0,0 +1,353 @@
+/*************************************************************************/
+/* utilities.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifdef GLES3_ENABLED
+
+#include "utilities.h"
+#include "config.h"
+#include "light_storage.h"
+#include "material_storage.h"
+#include "mesh_storage.h"
+#include "particles_storage.h"
+#include "texture_storage.h"
+
+using namespace GLES3;
+
+Utilities *Utilities::singleton = nullptr;
+
+Utilities::Utilities() {
+ singleton = this;
+}
+
+Utilities::~Utilities() {
+ singleton = nullptr;
+}
+
+Vector<uint8_t> Utilities::buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size) {
+ Vector<uint8_t> ret;
+ ret.resize(p_buffer_size);
+ glBindBuffer(p_target, p_buffer);
+
+#if defined(__EMSCRIPTEN__)
+ {
+ uint8_t *w = ret.ptrw();
+ glGetBufferSubData(p_target, 0, p_buffer_size, w);
+ }
+#else
+ void *data = glMapBufferRange(p_target, 0, p_buffer_size, GL_MAP_READ_BIT);
+ ERR_FAIL_NULL_V(data, Vector<uint8_t>());
+ {
+ uint8_t *w = ret.ptrw();
+ memcpy(w, data, p_buffer_size);
+ }
+ glUnmapBuffer(p_target);
+#endif
+ glBindBuffer(p_target, 0);
+ return ret;
+}
+
+/* INSTANCES */
+
+RS::InstanceType Utilities::get_base_type(RID p_rid) const {
+ if (GLES3::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
+ return RS::INSTANCE_MESH;
+ } else if (GLES3::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
+ return RS::INSTANCE_MULTIMESH;
+ } else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) {
+ return RS::INSTANCE_LIGHT;
+ }
+ return RS::INSTANCE_NONE;
+}
+
+bool Utilities::free(RID p_rid) {
+ if (GLES3::TextureStorage::get_singleton()->owns_render_target(p_rid)) {
+ GLES3::TextureStorage::get_singleton()->render_target_free(p_rid);
+ return true;
+ } else if (GLES3::TextureStorage::get_singleton()->owns_texture(p_rid)) {
+ GLES3::TextureStorage::get_singleton()->texture_free(p_rid);
+ return true;
+ } else if (GLES3::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
+ GLES3::TextureStorage::get_singleton()->canvas_texture_free(p_rid);
+ return true;
+ } else if (GLES3::MaterialStorage::get_singleton()->owns_shader(p_rid)) {
+ GLES3::MaterialStorage::get_singleton()->shader_free(p_rid);
+ return true;
+ } else if (GLES3::MaterialStorage::get_singleton()->owns_material(p_rid)) {
+ GLES3::MaterialStorage::get_singleton()->material_free(p_rid);
+ return true;
+ } else if (GLES3::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
+ GLES3::MeshStorage::get_singleton()->mesh_free(p_rid);
+ return true;
+ } else if (GLES3::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
+ GLES3::MeshStorage::get_singleton()->multimesh_free(p_rid);
+ return true;
+ } else if (GLES3::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) {
+ GLES3::MeshStorage::get_singleton()->mesh_instance_free(p_rid);
+ return true;
+ } else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) {
+ GLES3::LightStorage::get_singleton()->light_free(p_rid);
+ return true;
+ } else {
+ return false;
+ }
+ /*
+ else if (reflection_probe_owner.owns(p_rid)) {
+ // delete the texture
+ ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
+ reflection_probe->instance_remove_deps();
+
+ reflection_probe_owner.free(p_rid);
+ memdelete(reflection_probe);
+
+ return true;
+ } else if (lightmap_capture_data_owner.owns(p_rid)) {
+ // delete the texture
+ LightmapCapture *lightmap_capture = lightmap_capture_data_owner.get_or_null(p_rid);
+ lightmap_capture->instance_remove_deps();
+
+ lightmap_capture_data_owner.free(p_rid);
+ memdelete(lightmap_capture);
+ return true;
+
+ } else if (canvas_occluder_owner.owns(p_rid)) {
+ CanvasOccluder *co = canvas_occluder_owner.get_or_null(p_rid);
+ if (co->index_id) {
+ glDeleteBuffers(1, &co->index_id);
+ }
+ if (co->vertex_id) {
+ glDeleteBuffers(1, &co->vertex_id);
+ }
+
+ canvas_occluder_owner.free(p_rid);
+ memdelete(co);
+
+ return true;
+
+ } else if (canvas_light_shadow_owner.owns(p_rid)) {
+ CanvasLightShadow *cls = canvas_light_shadow_owner.get_or_null(p_rid);
+ glDeleteFramebuffers(1, &cls->fbo);
+ glDeleteRenderbuffers(1, &cls->depth);
+ glDeleteTextures(1, &cls->distance);
+ canvas_light_shadow_owner.free(p_rid);
+ memdelete(cls);
+
+ return true;
+ }
+ */
+}
+
+/* DEPENDENCIES */
+
+void Utilities::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
+ if (MeshStorage::get_singleton()->owns_mesh(p_base)) {
+ Mesh *mesh = MeshStorage::get_singleton()->get_mesh(p_base);
+ p_instance->update_dependency(&mesh->dependency);
+ } else if (MeshStorage::get_singleton()->owns_multimesh(p_base)) {
+ MultiMesh *multimesh = MeshStorage::get_singleton()->get_multimesh(p_base);
+ p_instance->update_dependency(&multimesh->dependency);
+ if (multimesh->mesh.is_valid()) {
+ base_update_dependency(multimesh->mesh, p_instance);
+ }
+ } else if (LightStorage::get_singleton()->owns_light(p_base)) {
+ Light *l = LightStorage::get_singleton()->get_light(p_base);
+ p_instance->update_dependency(&l->dependency);
+ }
+}
+
+/* VISIBILITY NOTIFIER */
+
+RID Utilities::visibility_notifier_allocate() {
+ return RID();
+}
+
+void Utilities::visibility_notifier_initialize(RID p_notifier) {
+}
+
+void Utilities::visibility_notifier_free(RID p_notifier) {
+}
+
+void Utilities::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) {
+}
+
+void Utilities::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) {
+}
+
+AABB Utilities::visibility_notifier_get_aabb(RID p_notifier) const {
+ return AABB();
+}
+
+void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
+}
+
+/* TIMING */
+
+//void Utilities::render_info_begin_capture() {
+// info.snap = info.render;
+//}
+
+//void Utilities::render_info_end_capture() {
+// info.snap.object_count = info.render.object_count - info.snap.object_count;
+// info.snap.draw_call_count = info.render.draw_call_count - info.snap.draw_call_count;
+// info.snap.material_switch_count = info.render.material_switch_count - info.snap.material_switch_count;
+// info.snap.surface_switch_count = info.render.surface_switch_count - info.snap.surface_switch_count;
+// info.snap.shader_rebind_count = info.render.shader_rebind_count - info.snap.shader_rebind_count;
+// info.snap.vertices_count = info.render.vertices_count - info.snap.vertices_count;
+// info.snap._2d_item_count = info.render._2d_item_count - info.snap._2d_item_count;
+// info.snap._2d_draw_call_count = info.render._2d_draw_call_count - info.snap._2d_draw_call_count;
+//}
+
+//int Utilities::get_captured_render_info(RS::RenderInfo p_info) {
+// switch (p_info) {
+// case RS::INFO_OBJECTS_IN_FRAME: {
+// return info.snap.object_count;
+// } break;
+// case RS::INFO_VERTICES_IN_FRAME: {
+// return info.snap.vertices_count;
+// } break;
+// case RS::INFO_MATERIAL_CHANGES_IN_FRAME: {
+// return info.snap.material_switch_count;
+// } break;
+// case RS::INFO_SHADER_CHANGES_IN_FRAME: {
+// return info.snap.shader_rebind_count;
+// } break;
+// case RS::INFO_SURFACE_CHANGES_IN_FRAME: {
+// return info.snap.surface_switch_count;
+// } break;
+// case RS::INFO_DRAW_CALLS_IN_FRAME: {
+// return info.snap.draw_call_count;
+// } break;
+// /*
+// case RS::INFO_2D_ITEMS_IN_FRAME: {
+// return info.snap._2d_item_count;
+// } break;
+// case RS::INFO_2D_DRAW_CALLS_IN_FRAME: {
+// return info.snap._2d_draw_call_count;
+// } break;
+// */
+// default: {
+// return get_render_info(p_info);
+// }
+// }
+//}
+
+//int Utilities::get_render_info(RS::RenderInfo p_info) {
+// switch (p_info) {
+// case RS::INFO_OBJECTS_IN_FRAME:
+// return info.render_final.object_count;
+// case RS::INFO_VERTICES_IN_FRAME:
+// return info.render_final.vertices_count;
+// case RS::INFO_MATERIAL_CHANGES_IN_FRAME:
+// return info.render_final.material_switch_count;
+// case RS::INFO_SHADER_CHANGES_IN_FRAME:
+// return info.render_final.shader_rebind_count;
+// case RS::INFO_SURFACE_CHANGES_IN_FRAME:
+// return info.render_final.surface_switch_count;
+// case RS::INFO_DRAW_CALLS_IN_FRAME:
+// return info.render_final.draw_call_count;
+// /*
+// case RS::INFO_2D_ITEMS_IN_FRAME:
+// return info.render_final._2d_item_count;
+// case RS::INFO_2D_DRAW_CALLS_IN_FRAME:
+// return info.render_final._2d_draw_call_count;
+//*/
+// case RS::INFO_USAGE_VIDEO_MEM_TOTAL:
+// return 0; //no idea
+// case RS::INFO_VIDEO_MEM_USED:
+// return info.vertex_mem + info.texture_mem;
+// case RS::INFO_TEXTURE_MEM_USED:
+// return info.texture_mem;
+// case RS::INFO_VERTEX_MEM_USED:
+// return info.vertex_mem;
+// default:
+// return 0; //no idea either
+// }
+//}
+
+/* MISC */
+
+void Utilities::update_dirty_resources() {
+ MaterialStorage::get_singleton()->_update_global_variables();
+ MaterialStorage::get_singleton()->_update_queued_materials();
+ //MeshStorage::get_singleton()->_update_dirty_skeletons();
+ MeshStorage::get_singleton()->_update_dirty_multimeshes();
+}
+
+void Utilities::set_debug_generate_wireframes(bool p_generate) {
+}
+
+bool Utilities::has_os_feature(const String &p_feature) const {
+ Config *config = Config::get_singleton();
+ if (!config) {
+ return false;
+ }
+
+ if (p_feature == "rgtc") {
+ return config->rgtc_supported;
+ }
+
+ if (p_feature == "s3tc") {
+ return config->s3tc_supported;
+ }
+
+ if (p_feature == "bptc") {
+ return config->bptc_supported;
+ }
+
+ if (p_feature == "etc" || p_feature == "etc2") {
+ return config->etc2_supported;
+ }
+
+ return false;
+}
+
+void Utilities::update_memory_info() {
+}
+
+uint64_t Utilities::get_rendering_info(RS::RenderingInfo p_info) {
+ return 0;
+}
+
+String Utilities::get_video_adapter_name() const {
+ return (const char *)glGetString(GL_RENDERER);
+}
+
+String Utilities::get_video_adapter_vendor() const {
+ return (const char *)glGetString(GL_VENDOR);
+}
+
+RenderingDevice::DeviceType Utilities::get_video_adapter_type() const {
+ return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER;
+}
+
+String Utilities::get_video_adapter_api_version() const {
+ return (const char *)glGetString(GL_VERSION);
+}
+
+#endif // GLES3_ENABLED
diff --git a/drivers/gles3/storage/utilities.h b/drivers/gles3/storage/utilities.h
new file mode 100644
index 0000000000..523033886c
--- /dev/null
+++ b/drivers/gles3/storage/utilities.h
@@ -0,0 +1,159 @@
+/*************************************************************************/
+/* utilities.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef UTILITIES_GLES3_H
+#define UTILITIES_GLES3_H
+
+#ifdef GLES3_ENABLED
+
+#include "servers/rendering/storage/utilities.h"
+
+#include "platform_config.h"
+#ifndef OPENGL_INCLUDE_H
+#include <GLES3/gl3.h>
+#else
+#include OPENGL_INCLUDE_H
+#endif
+
+namespace GLES3 {
+
+class Utilities : public RendererUtilities {
+private:
+ static Utilities *singleton;
+
+public:
+ static Utilities *get_singleton() { return singleton; }
+
+ Utilities();
+ ~Utilities();
+
+ // Buffer size is specified in bytes
+ static Vector<uint8_t> buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size);
+
+ /* INSTANCES */
+
+ virtual RS::InstanceType get_base_type(RID p_rid) const override;
+ virtual bool free(RID p_rid) override;
+
+ /* DEPENDENCIES */
+
+ virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override;
+
+ /* VISIBILITY NOTIFIER */
+ virtual RID visibility_notifier_allocate() override;
+ virtual void visibility_notifier_initialize(RID p_notifier) override;
+ virtual void visibility_notifier_free(RID p_notifier) override;
+
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override;
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override;
+
+ virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override;
+ virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override;
+
+ /* TIMING */
+
+ struct Info {
+ uint64_t texture_mem = 0;
+ uint64_t vertex_mem = 0;
+
+ struct Render {
+ uint32_t object_count;
+ uint32_t draw_call_count;
+ uint32_t material_switch_count;
+ uint32_t surface_switch_count;
+ uint32_t shader_rebind_count;
+ uint32_t vertices_count;
+ uint32_t _2d_item_count;
+ uint32_t _2d_draw_call_count;
+
+ void reset() {
+ object_count = 0;
+ draw_call_count = 0;
+ material_switch_count = 0;
+ surface_switch_count = 0;
+ shader_rebind_count = 0;
+ vertices_count = 0;
+ _2d_item_count = 0;
+ _2d_draw_call_count = 0;
+ }
+ } render, render_final, snap;
+
+ Info() {
+ render.reset();
+ render_final.reset();
+ }
+
+ } info;
+
+ virtual void capture_timestamps_begin() override {}
+ virtual void capture_timestamp(const String &p_name) override {}
+ virtual uint32_t get_captured_timestamps_count() const override {
+ return 0;
+ }
+ virtual uint64_t get_captured_timestamps_frame() const override {
+ return 0;
+ }
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override {
+ return 0;
+ }
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override {
+ return 0;
+ }
+ virtual String get_captured_timestamp_name(uint32_t p_index) const override {
+ return String();
+ }
+
+ // void render_info_begin_capture() override;
+ // void render_info_end_capture() override;
+ // int get_captured_render_info(RS::RenderInfo p_info) override;
+
+ // int get_render_info(RS::RenderInfo p_info) override;
+
+ /* MISC */
+
+ virtual void update_dirty_resources() override;
+ virtual void set_debug_generate_wireframes(bool p_generate) override;
+
+ virtual bool has_os_feature(const String &p_feature) const override;
+
+ virtual void update_memory_info() override;
+
+ virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override;
+ virtual String get_video_adapter_name() const override;
+ virtual String get_video_adapter_vendor() const override;
+ virtual RenderingDevice::DeviceType get_video_adapter_type() const override;
+ virtual String get_video_adapter_api_version() const override;
+};
+
+} // namespace GLES3
+
+#endif // GLES3_ENABLED
+
+#endif // !UTILITIES_GLES3_H
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 7e6105f033..39dbadf3cd 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -33,6 +33,7 @@
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
#include "core/os/memory.h"
+#include "core/os/os.h"
#include "core/string/print_string.h"
#include "core/templates/list.h"
@@ -49,10 +50,6 @@
#include <mntent.h>
#endif
-Ref<DirAccess> DirAccessUnix::create_fs() {
- return memnew(DirAccessUnix);
-}
-
Error DirAccessUnix::list_dir_begin() {
list_dir_end(); //close any previous dir opening!
@@ -216,10 +213,11 @@ static bool _filter_drive(struct mntent *mnt) {
#endif
static void _get_drives(List<String> *list) {
+ // Add root.
list->push_back("/");
#if defined(HAVE_MNTENT) && defined(X11_ENABLED)
- // Check /etc/mtab for the list of mounted partitions
+ // Check /etc/mtab for the list of mounted partitions.
FILE *mtab = setmntent("/etc/mtab", "r");
if (mtab) {
struct mntent mnt;
@@ -239,7 +237,7 @@ static void _get_drives(List<String> *list) {
}
#endif
- // Add $HOME
+ // Add $HOME.
const char *home = getenv("HOME");
if (home) {
// Only add if it's not a duplicate
@@ -248,7 +246,8 @@ static void _get_drives(List<String> *list) {
list->push_back(home_name);
}
- // Check $HOME/.config/gtk-3.0/bookmarks
+ // Check GTK+3 bookmarks for both XDG locations (Documents, Downloads, etc.)
+ // and potential user-defined bookmarks.
char path[1024];
snprintf(path, 1024, "%s/.config/gtk-3.0/bookmarks", home);
FILE *fd = fopen(path, "r");
@@ -257,7 +256,7 @@ static void _get_drives(List<String> *list) {
while (fgets(string, 1024, fd)) {
// Parse only file:// links
if (strncmp(string, "file://", 7) == 0) {
- // Strip any unwanted edges on the strings and push_back if it's not a duplicate
+ // Strip any unwanted edges on the strings and push_back if it's not a duplicate.
String fpath = String::utf8(string + 7).strip_edges().split_spaces()[0].uri_decode();
if (!list->find(fpath)) {
list->push_back(fpath);
@@ -267,6 +266,12 @@ static void _get_drives(List<String> *list) {
fclose(fd);
}
+
+ // Add Desktop dir.
+ String dpath = OS::get_singleton()->get_system_dir(OS::SystemDir::SYSTEM_DIR_DESKTOP);
+ if (dpath.length() > 0 && !list->find(dpath)) {
+ list->push_back(dpath);
+ }
}
list->sort();
@@ -338,7 +343,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
String prev_dir;
char real_current_dir_name[2048];
ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == nullptr, ERR_BUG);
- if (prev_dir.parse_utf8(real_current_dir_name)) {
+ if (prev_dir.parse_utf8(real_current_dir_name) != OK) {
prev_dir = real_current_dir_name; //no utf8, maybe latin?
}
@@ -500,7 +505,7 @@ DirAccessUnix::DirAccessUnix() {
// set current directory to an absolute path of the current directory
char real_current_dir_name[2048];
ERR_FAIL_COND(getcwd(real_current_dir_name, 2048) == nullptr);
- if (current_dir.parse_utf8(real_current_dir_name)) {
+ if (current_dir.parse_utf8(real_current_dir_name) != OK) {
current_dir = real_current_dir_name;
}
diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h
index 69530de337..5e2129b74a 100644
--- a/drivers/unix/dir_access_unix.h
+++ b/drivers/unix/dir_access_unix.h
@@ -43,13 +43,11 @@
class DirAccessUnix : public DirAccess {
DIR *dir_stream = nullptr;
- static Ref<DirAccess> create_fs();
-
- String current_dir;
bool _cisdir = false;
bool _cishidden = false;
protected:
+ String current_dir;
virtual String fix_unicode_name(const char *p_name) const { return String::utf8(p_name); }
virtual bool is_hidden(const String &p_name);
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index e0b2994b63..99836b7bea 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -333,10 +333,6 @@ Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_per
return FAILED;
}
-Ref<FileAccess> FileAccessUnix::create_libc() {
- return memnew(FileAccessUnix);
-}
-
CloseNotificationFunc FileAccessUnix::close_notification_func = nullptr;
FileAccessUnix::~FileAccessUnix() {
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 4340bbbc82..0261b8be53 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -49,7 +49,6 @@ class FileAccessUnix : public FileAccess {
String path;
String path_src;
- static Ref<FileAccess> create_libc();
void _close();
public:
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 52a4d538e1..5bf14056ab 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -65,7 +65,7 @@
#include <time.h>
#include <unistd.h>
-#if defined(OSX_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28)
+#if defined(MACOS_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28)
// Random location for getentropy. Fitting.
#include <sys/random.h>
#define UNIX_GET_ENTROPY
@@ -313,7 +313,12 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, St
if (p_pipe_mutex) {
p_pipe_mutex->lock();
}
- (*r_pipe) += String::utf8(buf);
+ String pipe_out;
+ if (pipe_out.parse_utf8(buf) == OK) {
+ (*r_pipe) += pipe_out;
+ } else {
+ (*r_pipe) += String(buf); // If not valid UTF-8 try decode as Latin-1
+ }
if (p_pipe_mutex) {
p_pipe_mutex->unlock();
}
diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub
index b6ceb1cdea..a076c0ac54 100644
--- a/drivers/vulkan/SCsub
+++ b/drivers/vulkan/SCsub
@@ -15,11 +15,11 @@ if env["use_volk"]:
if env["platform"] == "android":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_ANDROID_KHR"])
-elif env["platform"] == "iphone":
+elif env["platform"] == "ios":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_IOS_MVK"])
-elif env["platform"] == "linuxbsd":
+elif env["platform"] == "linuxbsd" and env["x11"]:
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_XLIB_KHR"])
-elif env["platform"] == "osx":
+elif env["platform"] == "macos":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_MACOS_MVK"])
elif env["platform"] == "windows":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_WIN32_KHR"])
@@ -40,7 +40,7 @@ elif env["platform"] == "android":
# Our current NDK version only provides old Vulkan headers,
# so we have to limit VMA.
env_thirdparty_vma.AppendUnique(CPPDEFINES=["VMA_VULKAN_VERSION=1000000"])
-elif env["platform"] == "osx" or env["platform"] == "iphone":
+elif env["platform"] == "macos" or env["platform"] == "ios":
# MoltenVK supports only Vulkan 1.1 API, limit VMA to the same version.
env_thirdparty_vma.AppendUnique(CPPDEFINES=["VMA_VULKAN_VERSION=1001000"])
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 99aa0e2442..9abd4780eb 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -36,6 +36,7 @@
#include "core/io/marshalls.h"
#include "core/os/os.h"
#include "core/templates/hashfuncs.h"
+#include "core/version.h"
#include "drivers/vulkan/vulkan_context.h"
#include "thirdparty/misc/smolv.h"
@@ -106,7 +107,7 @@ RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID
return buffer;
}
-static void update_external_dependency_for_store(VkSubpassDependency &dependency, bool is_sampled, bool is_storage, bool is_depth) {
+static void update_external_dependency_for_store(VkSubpassDependency2KHR &dependency, bool is_sampled, bool is_storage, bool is_depth) {
// Transitioning from write to read, protect the shaders that may use this next
// Allow for copies/image layout transitions
dependency.dstStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
@@ -1400,7 +1401,7 @@ Error RenderingDeviceVulkan::_insert_staging_block() {
return OK;
}
-Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_t p_required_align, uint32_t &r_alloc_offset, uint32_t &r_alloc_size, bool p_can_segment, bool p_on_draw_command_buffer) {
+Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_t p_required_align, uint32_t &r_alloc_offset, uint32_t &r_alloc_size, bool p_can_segment) {
//determine a block to use
r_alloc_size = p_amount;
@@ -1542,7 +1543,7 @@ Error RenderingDeviceVulkan::_buffer_update(Buffer *p_buffer, size_t p_offset, c
uint32_t block_write_offset;
uint32_t block_write_amount;
- Error err = _staging_buffer_allocate(MIN(to_submit, staging_buffer_block_size), p_required_align, block_write_offset, block_write_amount, p_use_draw_command_buffer);
+ Error err = _staging_buffer_allocate(MIN(to_submit, staging_buffer_block_size), p_required_align, block_write_offset, block_write_amount);
if (err) {
return err;
}
@@ -1758,6 +1759,10 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
}
+ if (p_format.usage_bits & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
+ image_create_info.usage |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
+ }
+
if (p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT) {
image_create_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
}
@@ -2376,6 +2381,22 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
return _texture_update(p_texture, p_layer, p_data, p_post_barrier, false);
}
+static _ALWAYS_INLINE_ void _copy_region(uint8_t const *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_x, uint32_t p_src_y, uint32_t p_src_w, uint32_t p_src_h, uint32_t p_src_full_w, uint32_t p_unit_size) {
+ uint32_t src_offset = (p_src_y * p_src_full_w + p_src_x) * p_unit_size;
+ uint32_t dst_offset = 0;
+ for (uint32_t y = p_src_h; y > 0; y--) {
+ uint8_t const *__restrict src = p_src + src_offset;
+ uint8_t *__restrict dst = p_dst + dst_offset;
+ for (uint32_t x = p_src_w * p_unit_size; x > 0; x--) {
+ *dst = *src;
+ src++;
+ dst++;
+ }
+ src_offset += p_src_full_w * p_unit_size;
+ dst_offset += p_src_w * p_unit_size;
+ }
+}
+
Error RenderingDeviceVulkan::_texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier, bool p_use_setup_queue) {
_THREAD_SAFE_METHOD_
@@ -2461,8 +2482,8 @@ Error RenderingDeviceVulkan::_texture_update(RID p_texture, uint32_t p_layer, co
const uint8_t *read_ptr = read_ptr_mipmap + image_size * z / depth;
- for (uint32_t x = 0; x < width; x += region_size) {
- for (uint32_t y = 0; y < height; y += region_size) {
+ for (uint32_t y = 0; y < height; y += region_size) {
+ for (uint32_t x = 0; x < width; x += region_size) {
uint32_t region_w = MIN(region_size, width - x);
uint32_t region_h = MIN(region_size, height - y);
@@ -2474,7 +2495,7 @@ Error RenderingDeviceVulkan::_texture_update(RID p_texture, uint32_t p_layer, co
to_allocate >>= get_compressed_image_format_pixel_rshift(texture->format);
uint32_t alloc_offset, alloc_size;
- Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false, !p_use_setup_queue);
+ Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
uint8_t *write_ptr;
@@ -2505,31 +2526,11 @@ Error RenderingDeviceVulkan::_texture_update(RID p_texture, uint32_t p_layer, co
//uint32_t hb = height / block_h;
uint32_t region_wb = region_w / block_w;
uint32_t region_hb = region_h / block_h;
- for (uint32_t xr = 0; xr < region_wb; xr++) {
- for (uint32_t yr = 0; yr < region_hb; yr++) {
- uint32_t src_offset = ((yr + yb) * wb + xr + xb) * block_size;
- uint32_t dst_offset = (yr * region_wb + xr) * block_size;
- //copy block
- for (uint32_t i = 0; i < block_size; i++) {
- write_ptr[dst_offset + i] = read_ptr[src_offset + i];
- }
- }
- }
-
+ _copy_region(read_ptr, write_ptr, xb, yb, region_wb, region_hb, wb, block_size);
} else {
//regular image (pixels)
//must copy a pixel region
-
- for (uint32_t xr = 0; xr < region_w; xr++) {
- for (uint32_t yr = 0; yr < region_h; yr++) {
- uint32_t src_offset = ((yr + y) * width + xr + x) * pixel_size;
- uint32_t dst_offset = (yr * region_w + xr) * pixel_size;
- //copy block
- for (uint32_t i = 0; i < pixel_size; i++) {
- write_ptr[dst_offset + i] = read_ptr[src_offset + i];
- }
- }
- }
+ _copy_region(read_ptr, write_ptr, x, y, region_w, region_h, width, pixel_size);
}
{ //unmap
@@ -2572,11 +2573,11 @@ Error RenderingDeviceVulkan::_texture_update(RID p_texture, uint32_t p_layer, co
uint32_t access_flags = 0;
if (p_post_barrier & BARRIER_MASK_COMPUTE) {
barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- access_flags |= VK_ACCESS_SHADER_READ_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
}
if (p_post_barrier & BARRIER_MASK_RASTER) {
barrier_flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- access_flags |= VK_ACCESS_SHADER_READ_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
}
if (p_post_barrier & BARRIER_MASK_TRANSFER) {
barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
@@ -2990,7 +2991,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
image_memory_barrier.subresourceRange.baseArrayLayer = p_src_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
{ //make dst readable
@@ -3016,6 +3017,13 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
}
}
+ if (dst_tex->used_in_frame != frames_drawn) {
+ dst_tex->used_in_raster = false;
+ dst_tex->used_in_compute = false;
+ dst_tex->used_in_frame = frames_drawn;
+ }
+ dst_tex->used_in_transfer = true;
+
return OK;
}
@@ -3359,17 +3367,24 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; // From Section 7.1 of Vulkan API Spec v1.1.148
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | // From Section 7.1 of Vulkan API Spec v1.1.148
+ VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
VkPipelineStageFlags reading_stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
- VkSubpassDependency dependencies[2] = { { VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, default_access_mask, 0 },
- { 0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, default_access_mask, 0, 0 } };
- VkSubpassDependency &dependency_from_external = dependencies[0];
- VkSubpassDependency &dependency_to_external = dependencies[1];
+ VkSubpassDependency2KHR dependencies[2] = {
+ { VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR, nullptr, VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, default_access_mask, 0, 0 },
+ { VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR, nullptr, 0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, default_access_mask, 0, 0, 0 }
+ };
+ VkSubpassDependency2KHR &dependency_from_external = dependencies[0];
+ VkSubpassDependency2KHR &dependency_to_external = dependencies[1];
LocalVector<int32_t> attachment_last_pass;
attachment_last_pass.resize(p_attachments.size());
- Vector<VkAttachmentDescription> attachments;
+ // These are only used if we use multiview but we need to define them in scope.
+ const uint32_t view_mask = (1 << p_view_count) - 1;
+ const uint32_t correlation_mask = (1 << p_view_count) - 1;
+
+ Vector<VkAttachmentDescription2KHR> attachments;
Vector<int> attachment_remap;
for (int i = 0; i < p_attachments.size(); i++) {
@@ -3380,10 +3395,12 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, VK_NULL_HANDLE);
ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, VK_NULL_HANDLE);
- ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)),
- VK_NULL_HANDLE, "Texture format for index (" + itos(i) + ") requires an attachment (color, depth, input or stencil) bit set.");
+ ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT | TEXTURE_USAGE_VRS_ATTACHMENT_BIT)),
+ VK_NULL_HANDLE, "Texture format for index (" + itos(i) + ") requires an attachment (color, depth-stencil, input or VRS) bit set.");
- VkAttachmentDescription description = {};
+ VkAttachmentDescription2KHR description = {};
+ description.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
+ description.pNext = nullptr;
description.flags = 0;
description.format = vulkan_formats[p_attachments[i].format];
description.samples = rasterization_sample_count[p_attachments[i].samples];
@@ -3392,83 +3409,95 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
bool is_storage = p_attachments[i].usage_flags & TEXTURE_USAGE_STORAGE_BIT;
bool is_depth = p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
- // For each UNDEFINED, assume the prior use was a *read*, as we'd be discarding the output of a write
- // Also, each UNDEFINED will do an immediate layout transition (write), s.t. we must ensure execution synchronization vs.
- // the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that
- // stage
-
- switch (is_depth ? p_initial_depth_action : p_initial_action) {
- case INITIAL_ACTION_CLEAR_REGION:
- case INITIAL_ACTION_CLEAR: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- dependency_from_external.srcStageMask |= reading_stages;
- } else {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- dependency_from_external.srcStageMask |= reading_stages;
- }
- } break;
- case INITIAL_ACTION_KEEP: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- dependency_from_external.srcStageMask |= reading_stages;
- } else {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- dependency_from_external.srcStageMask |= reading_stages;
- }
- } break;
- case INITIAL_ACTION_DROP: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- dependency_from_external.srcStageMask |= reading_stages;
- } else {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- dependency_from_external.srcStageMask |= reading_stages;
- }
- } break;
- case INITIAL_ACTION_CLEAR_REGION_CONTINUE:
- case INITIAL_ACTION_CONTINUE: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- description.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- } else {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- dependency_from_external.srcStageMask |= reading_stages;
+ // We can setup a framebuffer where we write to our VRS texture to set it up.
+ // We make the assumption here that if our texture is actually used as our VRS attachment,
+ // it is used as such for each subpass. This is fairly certain seeing the restrictions on subpasses.
+ bool is_vrs = p_attachments[i].usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT && i == p_passes[0].vrs_attachment;
+
+ if (is_vrs) {
+ // For VRS we only read, there is no writing to this texture
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ } else {
+ // For each UNDEFINED, assume the prior use was a *read*, as we'd be discarding the output of a write
+ // Also, each UNDEFINED will do an immediate layout transition (write), s.t. we must ensure execution synchronization vs.
+ // the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that
+ // stage
+
+ switch (is_depth ? p_initial_depth_action : p_initial_action) {
+ case INITIAL_ACTION_CLEAR_REGION:
+ case INITIAL_ACTION_CLEAR: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ dependency_from_external.srcStageMask |= reading_stages;
+ } else {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ dependency_from_external.srcStageMask |= reading_stages;
+ }
+ } break;
+ case INITIAL_ACTION_KEEP: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ dependency_from_external.srcStageMask |= reading_stages;
+ } else {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ dependency_from_external.srcStageMask |= reading_stages;
+ }
+ } break;
+ case INITIAL_ACTION_DROP: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ dependency_from_external.srcStageMask |= reading_stages;
+ } else {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ dependency_from_external.srcStageMask |= reading_stages;
+ }
+ } break;
+ case INITIAL_ACTION_CLEAR_REGION_CONTINUE:
+ case INITIAL_ACTION_CONTINUE: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ } else {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ dependency_from_external.srcStageMask |= reading_stages;
+ }
+ } break;
+ default: {
+ ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here
}
- } break;
- default: {
- ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here
}
}
@@ -3482,6 +3511,10 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
if (p_passes[last_pass].depth_attachment == i) {
used_last = true;
}
+ } else if (is_vrs) {
+ if (p_passes[last_pass].vrs_attachment == i) {
+ used_last = true;
+ }
} else {
if (p_passes[last_pass].resolve_attachments.size()) {
//if using resolve attachments, check resolve attachments
@@ -3523,58 +3556,69 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
}
- switch (is_depth ? final_depth_action : final_action) {
- case FINAL_ACTION_READ: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- update_external_dependency_for_store(dependency_to_external, is_sampled, is_storage, false);
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
- description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
- update_external_dependency_for_store(dependency_to_external, is_sampled, is_storage, true);
- } else {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- // TODO: What does this mean about the next usage (and thus appropriate dependency masks
- }
- } break;
- case FINAL_ACTION_DISCARD: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
- } else {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- }
- } break;
- case FINAL_ACTION_CONTINUE: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
- description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- } else {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- }
+ if (is_vrs) {
+ // We don't change our VRS texture during this process
- } break;
- default: {
- ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+ // TODO do we need to update our external dependency ?
+ // update_external_dependency_for_store(dependency_to_external, is_sampled, is_storage, false);
+ } else {
+ switch (is_depth ? final_depth_action : final_action) {
+ case FINAL_ACTION_READ: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ update_external_dependency_for_store(dependency_to_external, is_sampled, is_storage, false);
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
+ description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ update_external_dependency_for_store(dependency_to_external, is_sampled, is_storage, true);
+ } else {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ // TODO: What does this mean about the next usage (and thus appropriate dependency masks
+ }
+ } break;
+ case FINAL_ACTION_DISCARD: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ } else {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ }
+ } break;
+ case FINAL_ACTION_CONTINUE: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
+ description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ } else {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ }
+
+ } break;
+ default: {
+ ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here
+ }
}
}
@@ -3583,12 +3627,14 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
attachments.push_back(description);
}
- LocalVector<VkSubpassDescription> subpasses;
- LocalVector<LocalVector<VkAttachmentReference>> color_reference_array;
- LocalVector<LocalVector<VkAttachmentReference>> input_reference_array;
- LocalVector<LocalVector<VkAttachmentReference>> resolve_reference_array;
+ LocalVector<VkSubpassDescription2KHR> subpasses;
+ LocalVector<LocalVector<VkAttachmentReference2KHR>> color_reference_array;
+ LocalVector<LocalVector<VkAttachmentReference2KHR>> input_reference_array;
+ LocalVector<LocalVector<VkAttachmentReference2KHR>> resolve_reference_array;
LocalVector<LocalVector<uint32_t>> preserve_reference_array;
- LocalVector<VkAttachmentReference> depth_reference_array;
+ LocalVector<VkAttachmentReference2KHR> depth_reference_array;
+ LocalVector<VkAttachmentReference2KHR> vrs_reference_array;
+ LocalVector<VkFragmentShadingRateAttachmentInfoKHR> vrs_attachment_info_array;
subpasses.resize(p_passes.size());
color_reference_array.resize(p_passes.size());
@@ -3596,20 +3642,25 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
resolve_reference_array.resize(p_passes.size());
preserve_reference_array.resize(p_passes.size());
depth_reference_array.resize(p_passes.size());
+ vrs_reference_array.resize(p_passes.size());
+ vrs_attachment_info_array.resize(p_passes.size());
- LocalVector<VkSubpassDependency> subpass_dependencies;
+ LocalVector<VkSubpassDependency2KHR> subpass_dependencies;
for (int i = 0; i < p_passes.size(); i++) {
const FramebufferPass *pass = &p_passes[i];
- LocalVector<VkAttachmentReference> &color_references = color_reference_array[i];
+ LocalVector<VkAttachmentReference2KHR> &color_references = color_reference_array[i];
TextureSamples texture_samples = TEXTURE_SAMPLES_1;
bool is_multisample_first = true;
+ void *subpass_nextptr = nullptr;
for (int j = 0; j < pass->color_attachments.size(); j++) {
int32_t attachment = pass->color_attachments[j];
- VkAttachmentReference reference;
+ VkAttachmentReference2KHR reference;
+ reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ reference.pNext = nullptr;
if (attachment == FramebufferPass::ATTACHMENT_UNUSED) {
reference.attachment = VK_ATTACHMENT_UNUSED;
reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -3628,14 +3679,17 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachment_last_pass[attachment] = i;
}
+ reference.aspectMask = 0;
color_references.push_back(reference);
}
- LocalVector<VkAttachmentReference> &input_references = input_reference_array[i];
+ LocalVector<VkAttachmentReference2KHR> &input_references = input_reference_array[i];
for (int j = 0; j < pass->input_attachments.size(); j++) {
int32_t attachment = pass->input_attachments[j];
- VkAttachmentReference reference;
+ VkAttachmentReference2KHR reference;
+ reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ reference.pNext = nullptr;
if (attachment == FramebufferPass::ATTACHMENT_UNUSED) {
reference.attachment = VK_ATTACHMENT_UNUSED;
reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -3647,10 +3701,11 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
reference.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
attachment_last_pass[attachment] = i;
}
+ reference.aspectMask = 0; // TODO we need to set this here, possibly VK_IMAGE_ASPECT_COLOR_BIT ??
input_references.push_back(reference);
}
- LocalVector<VkAttachmentReference> &resolve_references = resolve_reference_array[i];
+ LocalVector<VkAttachmentReference2KHR> &resolve_references = resolve_reference_array[i];
if (pass->resolve_attachments.size() > 0) {
ERR_FAIL_COND_V_MSG(pass->resolve_attachments.size() != pass->color_attachments.size(), VK_NULL_HANDLE, "The amount of resolve attachments (" + itos(pass->resolve_attachments.size()) + ") must match the number of color attachments (" + itos(pass->color_attachments.size()) + ").");
@@ -3658,7 +3713,9 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
for (int j = 0; j < pass->resolve_attachments.size(); j++) {
int32_t attachment = pass->resolve_attachments[j];
- VkAttachmentReference reference;
+ VkAttachmentReference2KHR reference;
+ reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ reference.pNext = nullptr;
if (attachment == FramebufferPass::ATTACHMENT_UNUSED) {
reference.attachment = VK_ATTACHMENT_UNUSED;
reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -3673,10 +3730,13 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
attachment_last_pass[attachment] = i;
}
+ reference.aspectMask = 0;
resolve_references.push_back(reference);
}
- VkAttachmentReference &depth_stencil_reference = depth_reference_array[i];
+ VkAttachmentReference2KHR &depth_stencil_reference = depth_reference_array[i];
+ depth_stencil_reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ depth_stencil_reference.pNext = nullptr;
if (pass->depth_attachment != FramebufferPass::ATTACHMENT_UNUSED) {
int32_t attachment = pass->depth_attachment;
@@ -3685,6 +3745,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
depth_stencil_reference.attachment = attachment_remap[attachment];
depth_stencil_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ depth_stencil_reference.aspectMask = 0;
attachment_last_pass[attachment] = i;
if (is_multisample_first) {
@@ -3699,6 +3760,32 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
depth_stencil_reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
}
+ if (context->get_vrs_capabilities().attachment_vrs_supported && pass->vrs_attachment != FramebufferPass::ATTACHMENT_UNUSED) {
+ int32_t attachment = pass->vrs_attachment;
+ ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer VRS format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), VRS attachment.");
+ ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer VRS format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as VRS, but it's not a VRS attachment.");
+ ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer VRS attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
+
+ VkAttachmentReference2KHR &vrs_reference = vrs_reference_array[i];
+ vrs_reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ vrs_reference.pNext = nullptr;
+ vrs_reference.attachment = attachment_remap[attachment];
+ vrs_reference.layout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
+ vrs_reference.aspectMask = 0;
+
+ Size2i texel_size = context->get_vrs_capabilities().max_texel_size;
+
+ VkFragmentShadingRateAttachmentInfoKHR &vrs_attachment_info = vrs_attachment_info_array[i];
+ vrs_attachment_info.sType = VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR;
+ vrs_attachment_info.pNext = nullptr;
+ vrs_attachment_info.pFragmentShadingRateAttachment = &vrs_reference;
+ vrs_attachment_info.shadingRateAttachmentTexelSize = { uint32_t(texel_size.x), uint32_t(texel_size.y) };
+
+ attachment_last_pass[attachment] = i;
+
+ subpass_nextptr = &vrs_attachment_info;
+ }
+
LocalVector<uint32_t> &preserve_references = preserve_reference_array[i];
for (int j = 0; j < pass->preserve_attachments.size(); j++) {
@@ -3715,9 +3802,12 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
}
- VkSubpassDescription &subpass = subpasses[i];
+ VkSubpassDescription2KHR &subpass = subpasses[i];
+ subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
+ subpass.pNext = subpass_nextptr;
subpass.flags = 0;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ subpass.viewMask = view_mask;
subpass.inputAttachmentCount = input_references.size();
if (input_references.size()) {
subpass.pInputAttachments = input_references.ptr();
@@ -3754,7 +3844,9 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
if (i > 0) {
- VkSubpassDependency dependency;
+ VkSubpassDependency2KHR dependency;
+ dependency.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR;
+ dependency.pNext = nullptr;
dependency.srcSubpass = i - 1;
dependency.dstSubpass = i;
dependency.srcStageMask = 0;
@@ -3764,6 +3856,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
+ dependency.viewOffset = 0;
subpass_dependencies.push_back(dependency);
}
/*
@@ -3781,10 +3874,11 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
*/
}
- VkRenderPassCreateInfo render_pass_create_info;
- render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ VkRenderPassCreateInfo2KHR render_pass_create_info;
+ render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
render_pass_create_info.pNext = nullptr;
render_pass_create_info.flags = 0;
+
render_pass_create_info.attachmentCount = attachments.size();
render_pass_create_info.pAttachments = attachments.ptr();
render_pass_create_info.subpassCount = subpasses.size();
@@ -3801,13 +3895,15 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
render_pass_create_info.pDependencies = nullptr;
}
- // These are only used if we use multiview but we need to define them in scope.
- const uint32_t view_mask = (1 << p_view_count) - 1;
- const uint32_t correlation_mask = (1 << p_view_count) - 1;
+ render_pass_create_info.correlatedViewMaskCount = 1;
+ render_pass_create_info.pCorrelatedViewMasks = &correlation_mask;
+
Vector<uint32_t> view_masks;
VkRenderPassMultiviewCreateInfo render_pass_multiview_create_info;
if (p_view_count > 1) {
+ // this may no longer be needed with the new settings already including this
+
const VulkanContext::MultiviewCapabilities capabilities = context->get_multiview_capabilities();
// For now this only works with multiview!
@@ -3834,8 +3930,8 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
VkRenderPass render_pass;
- VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass);
- ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateRenderPass failed with error " + itos(res) + ".");
+ VkResult res = context->vkCreateRenderPass2KHR(device, &render_pass_create_info, nullptr, &render_pass);
+ ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateRenderPass2KHR failed with error " + itos(res) + ".");
return render_pass;
}
@@ -3896,7 +3992,9 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
return E->get();
}
- VkSubpassDescription subpass;
+ VkSubpassDescription2KHR subpass;
+ subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
+ subpass.pNext = nullptr;
subpass.flags = 0;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.inputAttachmentCount = 0; //unsupported for now
@@ -3908,8 +4006,8 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = nullptr;
- VkRenderPassCreateInfo render_pass_create_info;
- render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ VkRenderPassCreateInfo2KHR render_pass_create_info;
+ render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
render_pass_create_info.pNext = nullptr;
render_pass_create_info.flags = 0;
render_pass_create_info.attachmentCount = 0;
@@ -3918,11 +4016,13 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
render_pass_create_info.pSubpasses = &subpass;
render_pass_create_info.dependencyCount = 0;
render_pass_create_info.pDependencies = nullptr;
+ render_pass_create_info.correlatedViewMaskCount = 0;
+ render_pass_create_info.pCorrelatedViewMasks = nullptr;
VkRenderPass render_pass;
- VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass);
+ VkResult res = context->vkCreateRenderPass2KHR(device, &render_pass_create_info, nullptr, &render_pass);
- ERR_FAIL_COND_V_MSG(res, 0, "vkCreateRenderPass for empty fb failed with error " + itos(res) + ".");
+ ERR_FAIL_COND_V_MSG(res, 0, "vkCreateRenderPass2KHR for empty fb failed with error " + itos(res) + ".");
if (render_pass == VK_NULL_HANDLE) { //was likely invalid
return INVALID_ID;
@@ -3975,6 +4075,8 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac
if (texture && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
pass.depth_attachment = i;
+ } else if (texture && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
+ pass.vrs_attachment = i;
} else {
pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED);
}
@@ -4005,6 +4107,10 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
size.width = texture->width;
size.height = texture->height;
size_set = true;
+ } else if (texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
+ // If this is not the first attachement we assume this is used as the VRS attachment
+ // in this case this texture will be 1/16th the size of the color attachement.
+ // So we skip the size check
} else {
ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(),
"All textures in a framebuffer should be the same size.");
@@ -4348,7 +4454,7 @@ String RenderingDeviceVulkan::_shader_uniform_debug(RID p_shader, int p_set) {
if (!ret.is_empty()) {
ret += "\n";
}
- ret += "Set: " + itos(i) + " Binding: " + itos(ui.binding) + " Type: " + shader_uniform_names[ui.type] + " Length: " + itos(ui.length);
+ ret += "Set: " + itos(i) + " Binding: " + itos(ui.binding) + " Type: " + shader_uniform_names[ui.type] + " Writable: " + (ui.writable ? "Y" : "N") + " Length: " + itos(ui.length);
}
}
return ret;
@@ -4548,11 +4654,12 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
//version 1: initial
//version 2: Added shader name
+//version 3: Added writable
-#define SHADER_BINARY_VERSION 2
+#define SHADER_BINARY_VERSION 3
String RenderingDeviceVulkan::shader_get_binary_cache_key() const {
- return "Vulkan-SV" + itos(SHADER_BINARY_VERSION);
+ return "Vulkan-SV" + itos(SHADER_BINARY_VERSION) + "-" + String(VERSION_NUMBER) + "-" + String(VERSION_HASH);
}
struct RenderingDeviceVulkanShaderBinaryDataBinding {
@@ -4560,6 +4667,7 @@ struct RenderingDeviceVulkanShaderBinaryDataBinding {
uint32_t binding;
uint32_t stages;
uint32_t length; //size of arrays (in total elements), or ubos (in bytes * total elements)
+ uint32_t writable;
};
struct RenderingDeviceVulkanShaderBinarySpecializationConstant {
@@ -4649,6 +4757,7 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
bool need_array_dimensions = false;
bool need_block_size = false;
+ bool may_be_writable = false;
switch (binding.descriptor_type) {
case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER: {
@@ -4666,6 +4775,7 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
info.type = UNIFORM_TYPE_IMAGE;
need_array_dimensions = true;
+ may_be_writable = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
info.type = UNIFORM_TYPE_TEXTURE_BUFFER;
@@ -4674,6 +4784,7 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
info.type = UNIFORM_TYPE_IMAGE_BUFFER;
need_array_dimensions = true;
+ may_be_writable = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
info.type = UNIFORM_TYPE_UNIFORM_BUFFER;
@@ -4682,6 +4793,7 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
info.type = UNIFORM_TYPE_STORAGE_BUFFER;
need_block_size = true;
+ may_be_writable = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
ERR_PRINT("Dynamic uniform buffer not supported.");
@@ -4720,6 +4832,12 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
info.length = 0;
}
+ if (may_be_writable) {
+ info.writable = !(binding.type_description->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) && !(binding.block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
+ } else {
+ info.writable = false;
+ }
+
info.binding = binding.binding;
uint32_t set = binding.set;
@@ -4742,9 +4860,14 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
ERR_FAIL_COND_V_MSG(uniform_info[set][k].length != info.length, Vector<uint8_t>(),
"On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different uniform size.");
+ //also, verify that it has the same writability
+ ERR_FAIL_COND_V_MSG(uniform_info[set][k].writable != info.writable, Vector<uint8_t>(),
+ "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different writability.");
+
//just append stage mask and return
uniform_info.write[set].write[k].stages |= 1 << stage;
exists = true;
+ break;
}
}
@@ -5040,7 +5163,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
ERR_FAIL_COND_V(binptr[0] != 'G' || binptr[1] != 'V' || binptr[2] != 'B' || binptr[3] != 'D', RID());
uint32_t bin_version = decode_uint32(binptr + 4);
- ERR_FAIL_COND_V(bin_version > SHADER_BINARY_VERSION, RID());
+ ERR_FAIL_COND_V(bin_version != SHADER_BINARY_VERSION, RID());
uint32_t bin_data_size = decode_uint32(binptr + 8);
@@ -5087,6 +5210,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
for (uint32_t j = 0; j < set_count; j++) {
UniformInfo info;
info.type = UniformType(set_ptr[j].type);
+ info.writable = set_ptr[j].writable;
info.length = set_ptr[j].length;
info.binding = set_ptr[j].binding;
info.stages = set_ptr[j].stages;
@@ -5410,7 +5534,6 @@ RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Ve
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID());
Buffer buffer;
- buffer.usage = p_usage;
uint32_t flags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
if (p_usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT) {
flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
@@ -6536,11 +6659,28 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
dynamic_state_create_info.dynamicStateCount = dynamic_states.size();
dynamic_state_create_info.pDynamicStates = dynamic_states.ptr();
+ void *graphics_pipeline_nextptr = nullptr;
+
+ VkPipelineFragmentShadingRateStateCreateInfoKHR vrs_create_info;
+ if (context->get_vrs_capabilities().attachment_vrs_supported) {
+ // If VRS is used, this defines how the different VRS types are combined.
+ // combinerOps[0] decides how we use the output of pipeline and primitive (drawcall) VRS
+ // combinerOps[1] decides how we use the output of combinerOps[0] and our attachment VRS
+
+ vrs_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR;
+ vrs_create_info.pNext = nullptr;
+ vrs_create_info.fragmentSize = { 4, 4 };
+ vrs_create_info.combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; // We don't use pipeline/primitive VRS so this really doesn't matter
+ vrs_create_info.combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR; // always use the outcome of attachment VRS if enabled
+
+ graphics_pipeline_nextptr = &vrs_create_info;
+ }
+
//finally, pipeline create info
VkGraphicsPipelineCreateInfo graphics_pipeline_create_info;
graphics_pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
- graphics_pipeline_create_info.pNext = nullptr;
+ graphics_pipeline_create_info.pNext = graphics_pipeline_nextptr;
graphics_pipeline_create_info.flags = 0;
Vector<VkPipelineShaderStageCreateInfo> pipeline_stages = shader->pipeline_stages;
@@ -6705,7 +6845,7 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader, const Vector<Pi
const PipelineSpecializationConstant &psc = p_specialization_constants[j];
if (psc.constant_id == sc.constant.constant_id) {
ERR_FAIL_COND_V_MSG(psc.type != sc.constant.type, RID(), "Specialization constant provided for id (" + itos(sc.constant.constant_id) + ") is of the wrong type.");
- data_ptr[i] = sc.constant.int_value;
+ data_ptr[i] = psc.int_value;
break;
}
}
@@ -6889,8 +7029,10 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu
Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]);
if (texture) {
attachments.push_back(texture->view);
- ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
- ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
+ if (!(texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT)) { // VRS attachment will be a different size.
+ ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
+ ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
+ }
}
}
framebuffer_create_info.attachmentCount = attachments.size();
@@ -7025,7 +7167,6 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
}
void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil) {
- ERR_FAIL_COND_MSG(p_clear_color && p_clear_colors.size() != framebuffer->texture_ids.size(), "Clear color values supplied (" + itos(p_clear_colors.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(framebuffer->texture_ids.size()) + ").");
Vector<VkClearAttachment> clear_attachments;
int color_index = 0;
int texture_index = 0;
@@ -7114,11 +7255,14 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
}
}
- if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values
+ if (p_initial_color_action == INITIAL_ACTION_CLEAR || needs_clear_color) { //check clear values
int color_count = 0;
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
- if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+ // We only check for our VRS usage bit if this is not the first texture id.
+ // If it is the first we're likely populating our VRS texture.
+ // Bit dirty but..
+ if (!texture || (!(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(i != 0 && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT))) {
color_count++;
}
}
@@ -7175,6 +7319,9 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) {
_THREAD_SAFE_METHOD_
+ ERR_FAIL_COND_V_MSG(draw_list != nullptr, ERR_BUSY, "Only one draw list can be active at the same time.");
+ ERR_FAIL_COND_V_MSG(compute_list != nullptr && !compute_list->state.allow_draw_overlap, ERR_BUSY, "Only one draw/compute list can be active at the same time.");
+
ERR_FAIL_COND_V(p_splits < 1, ERR_INVALID_DECLARATION);
Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_framebuffer);
@@ -7208,7 +7355,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
}
}
- if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values
+ if (p_initial_color_action == INITIAL_ACTION_CLEAR || needs_clear_color) { //check clear values
int color_count = 0;
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
@@ -7899,10 +8046,6 @@ void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) {
// * Some buffer is copied
// * Another render pass happens (since we may be done)
-#ifdef FORCE_FULL_BARRIER
- _full_barrier(true);
-#else
-
VkMemoryBarrier mem_barrier;
mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
mem_barrier.pNext = nullptr;
@@ -7913,6 +8056,8 @@ void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) {
vkCmdPipelineBarrier(frames[frame].draw_command_buffer, src_stage, barrier_flags, 0, 1, &mem_barrier, 0, nullptr, image_barrier_count, image_barriers);
}
+#ifdef FORCE_FULL_BARRIER
+ _full_barrier(true);
#endif
}
@@ -8267,7 +8412,7 @@ void RenderingDeviceVulkan::compute_list_dispatch_indirect(ComputeListID p_list,
Buffer *buffer = storage_buffer_owner.get_or_null(p_buffer);
ERR_FAIL_COND(!buffer);
- ERR_FAIL_COND_MSG(!(buffer->usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT), "Buffer provided was not created to do indirect dispatch.");
+ ERR_FAIL_COND_MSG(!(buffer->usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), "Buffer provided was not created to do indirect dispatch.");
ERR_FAIL_COND_MSG(p_offset + 12 > buffer->size, "Offset provided (+12) is past the end of buffer.");
@@ -8383,9 +8528,6 @@ void RenderingDeviceVulkan::compute_list_end(uint32_t p_post_barrier) {
}
}
-#ifdef FORCE_FULL_BARRIER
- _full_barrier(true);
-#else
VkMemoryBarrier mem_barrier;
mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
mem_barrier.pNext = nullptr;
@@ -8396,6 +8538,8 @@ void RenderingDeviceVulkan::compute_list_end(uint32_t p_post_barrier) {
vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, barrier_flags, 0, 1, &mem_barrier, 0, nullptr, image_barrier_count, image_barriers);
}
+#ifdef FORCE_FULL_BARRIER
+ _full_barrier(true);
#endif
memdelete(compute_list);
@@ -8723,7 +8867,7 @@ void RenderingDeviceVulkan::_begin_frame() {
}
if (frames[frame].timestamp_count) {
- vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);
+ vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values.ptr(), sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);
vkCmdResetQueryPool(frames[frame].setup_command_buffer, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count);
SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names);
SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values);
@@ -8979,17 +9123,6 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
{
device_capabilities.version_major = p_context->get_vulkan_major();
device_capabilities.version_minor = p_context->get_vulkan_minor();
-
- // get info about subgroups
- VulkanContext::SubgroupCapabilities subgroup_capabilities = p_context->get_subgroup_capabilities();
- device_capabilities.subgroup_size = subgroup_capabilities.size;
- device_capabilities.subgroup_in_shaders = subgroup_capabilities.supported_stages_flags_rd();
- device_capabilities.subgroup_operations = subgroup_capabilities.supported_operations_flags_rd();
-
- // get info about further features
- VulkanContext::MultiviewCapabilities multiview_capabilies = p_context->get_multiview_capabilities();
- device_capabilities.supports_multiview = multiview_capabilies.is_supported && multiview_capabilies.max_view_count > 1;
- device_capabilities.supports_fsr_half_float = p_context->get_shader_capabilities().shader_float16_is_supported && p_context->get_storage_buffer_capabilities().storage_buffer_16_bit_access_is_supported;
}
context = p_context;
@@ -9014,7 +9147,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
vmaCreateAllocator(&allocatorInfo, &allocator);
}
- frames = memnew_arr(Frame, frame_count);
+ frames.resize(frame_count);
frame = 0;
//create setup and frame buffers
for (int i = 0; i < frame_count; i++) {
@@ -9060,12 +9193,12 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
vkCreateQueryPool(device, &query_pool_create_info, nullptr, &frames[i].timestamp_pool);
- frames[i].timestamp_names = memnew_arr(String, max_timestamp_query_elements);
- frames[i].timestamp_cpu_values = memnew_arr(uint64_t, max_timestamp_query_elements);
+ frames[i].timestamp_names.resize(max_timestamp_query_elements);
+ frames[i].timestamp_cpu_values.resize(max_timestamp_query_elements);
frames[i].timestamp_count = 0;
- frames[i].timestamp_result_names = memnew_arr(String, max_timestamp_query_elements);
- frames[i].timestamp_cpu_result_values = memnew_arr(uint64_t, max_timestamp_query_elements);
- frames[i].timestamp_result_values = memnew_arr(uint64_t, max_timestamp_query_elements);
+ frames[i].timestamp_result_names.resize(max_timestamp_query_elements);
+ frames[i].timestamp_cpu_result_values.resize(max_timestamp_query_elements);
+ frames[i].timestamp_result_values.resize(max_timestamp_query_elements);
frames[i].timestamp_result_count = 0;
}
}
@@ -9338,7 +9471,7 @@ String RenderingDeviceVulkan::get_captured_timestamp_name(uint32_t p_index) cons
return frames[frame].timestamp_result_names[p_index];
}
-uint64_t RenderingDeviceVulkan::limit_get(Limit p_limit) {
+uint64_t RenderingDeviceVulkan::limit_get(Limit p_limit) const {
switch (p_limit) {
case LIMIT_MAX_BOUND_UNIFORM_SETS:
return limits.maxBoundDescriptorSets;
@@ -9408,7 +9541,18 @@ uint64_t RenderingDeviceVulkan::limit_get(Limit p_limit) {
return limits.maxComputeWorkGroupSize[1];
case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z:
return limits.maxComputeWorkGroupSize[2];
-
+ case LIMIT_SUBGROUP_SIZE: {
+ VulkanContext::SubgroupCapabilities subgroup_capabilities = context->get_subgroup_capabilities();
+ return subgroup_capabilities.size;
+ }
+ case LIMIT_SUBGROUP_IN_SHADERS: {
+ VulkanContext::SubgroupCapabilities subgroup_capabilities = context->get_subgroup_capabilities();
+ return subgroup_capabilities.supported_stages_flags_rd();
+ }
+ case LIMIT_SUBGROUP_OPERATIONS: {
+ VulkanContext::SubgroupCapabilities subgroup_capabilities = context->get_subgroup_capabilities();
+ return subgroup_capabilities.supported_operations_flags_rd();
+ }
default:
ERR_FAIL_V(0);
}
@@ -9466,18 +9610,13 @@ void RenderingDeviceVulkan::finalize() {
_free_pending_resources(f);
vkDestroyCommandPool(device, frames[i].command_pool, nullptr);
vkDestroyQueryPool(device, frames[i].timestamp_pool, nullptr);
- memdelete_arr(frames[i].timestamp_names);
- memdelete_arr(frames[i].timestamp_cpu_values);
- memdelete_arr(frames[i].timestamp_result_names);
- memdelete_arr(frames[i].timestamp_result_values);
- memdelete_arr(frames[i].timestamp_cpu_result_values);
}
for (int i = 0; i < split_draw_list_allocators.size(); i++) {
vkDestroyCommandPool(device, split_draw_list_allocators[i].command_pool, nullptr);
}
- memdelete_arr(frames);
+ frames.clear();
for (int i = 0; i < staging_buffer_blocks.size(); i++) {
vmaDestroyBuffer(allocator, staging_buffer_blocks[i].buffer, staging_buffer_blocks[i].allocation);
@@ -9513,6 +9652,25 @@ RenderingDevice *RenderingDeviceVulkan::create_local_device() {
return rd;
}
+bool RenderingDeviceVulkan::has_feature(const Features p_feature) const {
+ switch (p_feature) {
+ case SUPPORTS_MULTIVIEW: {
+ VulkanContext::MultiviewCapabilities multiview_capabilies = context->get_multiview_capabilities();
+ return multiview_capabilies.is_supported && multiview_capabilies.max_view_count > 1;
+ } break;
+ case SUPPORTS_FSR_HALF_FLOAT: {
+ return context->get_shader_capabilities().shader_float16_is_supported && context->get_storage_buffer_capabilities().storage_buffer_16_bit_access_is_supported;
+ } break;
+ case SUPPORTS_ATTACHMENT_VRS: {
+ VulkanContext::VRSCapabilities vrs_capabilities = context->get_vrs_capabilities();
+ return vrs_capabilities.attachment_vrs_supported;
+ } break;
+ default: {
+ return false;
+ }
+ }
+}
+
RenderingDeviceVulkan::RenderingDeviceVulkan() {
device_capabilities.device_family = DEVICE_VULKAN;
}
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 3b21ee67a1..7c8021251f 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -206,7 +206,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint64_t staging_buffer_max_size = 0;
bool staging_buffer_used = false;
- Error _staging_buffer_allocate(uint32_t p_amount, uint32_t p_required_align, uint32_t &r_alloc_offset, uint32_t &r_alloc_size, bool p_can_segment = true, bool p_on_draw_command_buffer = false);
+ Error _staging_buffer_allocate(uint32_t p_amount, uint32_t p_required_align, uint32_t &r_alloc_offset, uint32_t &r_alloc_size, bool p_can_segment = true);
Error _insert_staging_block();
struct Buffer {
@@ -241,6 +241,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
Vector<AttachmentFormat> attachments;
Vector<FramebufferPass> passes;
uint32_t view_count = 1;
+
bool operator<(const FramebufferFormatKey &p_key) const {
if (view_count != p_key.view_count) {
return view_count < p_key.view_count;
@@ -544,12 +545,13 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct UniformInfo {
UniformType type = UniformType::UNIFORM_TYPE_MAX;
+ bool writable = false;
int binding = 0;
uint32_t stages = 0;
int length = 0; //size of arrays (in total elements), or ubos (in bytes * total elements)
bool operator!=(const UniformInfo &p_info) const {
- return (binding != p_info.binding || type != p_info.type || stages != p_info.stages || length != p_info.length);
+ return (binding != p_info.binding || type != p_info.type || writable != p_info.writable || stages != p_info.stages || length != p_info.length);
}
bool operator<(const UniformInfo &p_info) const {
@@ -559,6 +561,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
if (type != p_info.type) {
return type < p_info.type;
}
+ if (writable != p_info.writable) {
+ return writable < p_info.writable;
+ }
if (stages != p_info.stages) {
return stages < p_info.stages;
}
@@ -633,7 +638,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
};
bool is_compute = false;
- int max_output = 0;
Vector<Set> sets;
Vector<uint32_t> set_formats;
Vector<VkPipelineShaderStageCreateInfo> pipeline_stages;
@@ -866,11 +870,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t pipeline_dynamic_state = 0;
VertexFormatID pipeline_vertex_format = INVALID_ID;
RID pipeline_shader;
- uint32_t invalid_set_from = 0;
bool pipeline_uses_restart_indices = false;
uint32_t pipeline_primitive_divisor = 0;
uint32_t pipeline_primitive_minimum = 0;
- Vector<uint32_t> pipeline_set_formats;
uint32_t pipeline_push_constant_size = 0;
bool pipeline_push_constant_supplied = false;
} validation;
@@ -944,7 +946,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
bool pipeline_active = false;
RID pipeline_shader;
uint32_t invalid_set_from = 0;
- Vector<uint32_t> pipeline_set_formats;
uint32_t pipeline_push_constant_size = 0;
bool pipeline_push_constant_supplied = false;
} validation;
@@ -994,19 +995,19 @@ class RenderingDeviceVulkan : public RenderingDevice {
VkQueryPool timestamp_pool;
- String *timestamp_names = nullptr;
- uint64_t *timestamp_cpu_values = nullptr;
+ TightLocalVector<String> timestamp_names;
+ TightLocalVector<uint64_t> timestamp_cpu_values;
uint32_t timestamp_count = 0;
- String *timestamp_result_names = nullptr;
- uint64_t *timestamp_cpu_result_values = nullptr;
- uint64_t *timestamp_result_values = nullptr;
+ TightLocalVector<String> timestamp_result_names;
+ TightLocalVector<uint64_t> timestamp_cpu_result_values;
+ TightLocalVector<uint64_t> timestamp_result_values;
uint32_t timestamp_result_count = 0;
uint64_t index = 0;
};
uint32_t max_timestamp_query_elements = 0;
- Frame *frames = nullptr; //frames available, for main device they are cycled (usually 3), for local devices only 1
+ TightLocalVector<Frame> frames; //frames available, for main device they are cycled (usually 3), for local devices only 1
int frame = 0; //current frame
int frame_count = 0; //total amount of frames
uint64_t frames_drawn = 0;
@@ -1203,7 +1204,7 @@ public:
/**** Limits ****/
/****************/
- virtual uint64_t limit_get(Limit p_limit);
+ virtual uint64_t limit_get(Limit p_limit) const;
virtual void prepare_screen_for_drawing();
void initialize(VulkanContext *p_context, bool p_local_device = false);
@@ -1234,6 +1235,8 @@ public:
virtual uint64_t get_driver_resource(DriverResource p_resource, RID p_rid = RID(), uint64_t p_index = 0);
+ virtual bool has_feature(const Features p_feature) const;
+
RenderingDeviceVulkan();
~RenderingDeviceVulkan();
};
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 7944057041..524693eb03 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -48,6 +48,18 @@
VulkanHooks *VulkanContext::vulkan_hooks = nullptr;
+VkResult VulkanContext::vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
+ if (fpCreateRenderPass2KHR == nullptr) {
+ fpCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetInstanceProcAddr(inst, "vkCreateRenderPass2KHR");
+ }
+
+ if (fpCreateRenderPass2KHR == nullptr) {
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ } else {
+ return (fpCreateRenderPass2KHR)(device, pCreateInfo, pAllocator, pRenderPass);
+ }
+}
+
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
@@ -72,20 +84,20 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
strstr(pCallbackData->pMessage, "must be a memory object") != nullptr) {
return VK_FALSE;
}
- /*
- // This is a valid warning because its illegal in Vulkan, but in practice it should work according to VK_KHR_maintenance2
- if (strstr(pCallbackData->pMessage, "VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 with tiling VK_IMAGE_TILING_OPTIMAL does not support usage that includes VK_IMAGE_USAGE_STORAGE_BIT") != nullptr) {
- return VK_FALSE;
- }
- if (strstr(pCallbackData->pMessage, "VK_FORMAT_R4G4B4A4_UNORM_PACK16 with tiling VK_IMAGE_TILING_OPTIMAL does not support usage that includes VK_IMAGE_USAGE_STORAGE_BIT") != nullptr) {
- return VK_FALSE;
- }
-*/
// Workaround for Vulkan-Loader usability bug: https://github.com/KhronosGroup/Vulkan-Loader/issues/262.
if (strstr(pCallbackData->pMessage, "wrong ELF class: ELFCLASS32") != nullptr) {
return VK_FALSE;
}
+
+#ifdef WINDOWS_ENABLED
+ // Some software installs Vulkan overlays in Windows registry and never cleans them up on uninstall.
+ // So we get spammy error level messages from the loader about those - make them verbose instead.
+ if (strstr(pCallbackData->pMessage, "loader_get_json: Failed to open JSON file") != nullptr) {
+ messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
+ }
+#endif
+
if (pCallbackData->pMessageIdName && strstr(pCallbackData->pMessageIdName, "UNASSIGNED-CoreValidation-DrawState-ClearCmdBeforeDraw") != nullptr) {
return VK_FALSE;
}
@@ -215,13 +227,13 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char *const *c
Error VulkanContext::_get_preferred_validation_layers(uint32_t *count, const char *const **names) {
static const LocalVector<LocalVector<const char *>> instance_validation_layers_alt{
- // Preferred set of validation layers
+ // Preferred set of validation layers.
{ "VK_LAYER_KHRONOS_validation" },
- // Alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers
+ // Alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers.
{ "VK_LAYER_LUNARG_standard_validation" },
- // Alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers
+ // Alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers.
{ "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects" }
};
@@ -269,7 +281,7 @@ typedef VkResult(VKAPI_PTR *_vkEnumerateInstanceVersion)(uint32_t *);
Error VulkanContext::_obtain_vulkan_version() {
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkApplicationInfo.html#_description
- // for Vulkan 1.0 vkEnumerateInstanceVersion is not available, including not in the loader we compile against on Android.
+ // For Vulkan 1.0 vkEnumerateInstanceVersion is not available, including not in the loader we compile against on Android.
_vkEnumerateInstanceVersion func = (_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion");
if (func != nullptr) {
uint32_t api_version;
@@ -279,15 +291,15 @@ Error VulkanContext::_obtain_vulkan_version() {
vulkan_minor = VK_API_VERSION_MINOR(api_version);
vulkan_patch = VK_API_VERSION_PATCH(api_version);
} else {
- // according to the documentation this shouldn't fail with anything except a memory allocation error
- // in which case we're in deep trouble anyway
+ // According to the documentation this shouldn't fail with anything except a memory allocation error
+ // in which case we're in deep trouble anyway.
ERR_FAIL_V(ERR_CANT_CREATE);
}
} else {
print_line("vkEnumerateInstanceVersion not available, assuming Vulkan 1.0.");
}
- // we don't go above 1.2
+ // We don't go above 1.2.
if ((vulkan_major > 1) || (vulkan_major == 1 && vulkan_minor > 2)) {
vulkan_major = 1;
vulkan_minor = 2;
@@ -303,7 +315,7 @@ Error VulkanContext::_initialize_extensions() {
enabled_extension_count = 0;
enabled_debug_utils = false;
enabled_debug_report = false;
- /* Look for instance extensions */
+ // Look for instance extensions.
VkBool32 surfaceExtFound = 0;
VkBool32 platformSurfaceExtFound = 0;
memset(extension_names, 0, sizeof(extension_names));
@@ -403,7 +415,7 @@ String VulkanContext::SubgroupCapabilities::supported_stages_desc() const {
res += ", STAGE_COMPUTE";
}
- /* these are not defined on Android GRMBL */
+ // These are not defined on Android GRMBL.
if (supportedStages & 0x00000100 /* VK_SHADER_STAGE_RAYGEN_BIT_KHR */) {
res += ", STAGE_RAYGEN_KHR";
}
@@ -429,7 +441,7 @@ String VulkanContext::SubgroupCapabilities::supported_stages_desc() const {
res += ", STAGE_MESH_NV";
}
- return res.substr(2); // remove first ", "
+ return res.substr(2); // Remove first ", "
}
uint32_t VulkanContext::SubgroupCapabilities::supported_operations_flags_rd() const {
@@ -494,19 +506,22 @@ String VulkanContext::SubgroupCapabilities::supported_operations_desc() const {
res += ", FEATURE_PARTITIONED_NV";
}
- return res.substr(2); // remove first ", "
+ return res.substr(2); // Remove first ", "
}
Error VulkanContext::_check_capabilities() {
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_multiview.html
// https://www.khronos.org/blog/vulkan-subgroup-tutorial
- // for Vulkan 1.0 vkGetPhysicalDeviceProperties2 is not available, including not in the loader we compile against on Android.
+ // For Vulkan 1.0 vkGetPhysicalDeviceProperties2 is not available, including not in the loader we compile against on Android.
- // so we check if the functions are accessible by getting their function pointers and skipping if not
- // (note that the desktop loader does a better job here but the android loader doesn't)
+ // So we check if the functions are accessible by getting their function pointers and skipping if not
+ // (note that the desktop loader does a better job here but the android loader doesn't.)
- // assume not supported until proven otherwise
+ // Assume not supported until proven otherwise.
+ vrs_capabilities.pipeline_vrs_supported = false;
+ vrs_capabilities.primitive_vrs_supported = false;
+ vrs_capabilities.attachment_vrs_supported = false;
multiview_capabilities.is_supported = false;
multiview_capabilities.geometry_shader_is_supported = false;
multiview_capabilities.tessellation_shader_is_supported = false;
@@ -523,17 +538,25 @@ Error VulkanContext::_check_capabilities() {
storage_buffer_capabilities.storage_push_constant_16_is_supported = false;
storage_buffer_capabilities.storage_input_output_16 = false;
- // check for extended features
+ // Check for extended features.
PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2");
if (vkGetPhysicalDeviceFeatures2_func == nullptr) {
- // In Vulkan 1.0 might be accessible under its original extension name
+ // In Vulkan 1.0 might be accessible under its original extension name.
vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2KHR");
}
if (vkGetPhysicalDeviceFeatures2_func != nullptr) {
- // check our extended features
+ // Check our extended features.
+ VkPhysicalDeviceFragmentShadingRateFeaturesKHR vrs_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR,
+ /*pNext*/ nullptr,
+ /*pipelineFragmentShadingRate*/ false,
+ /*primitiveFragmentShadingRate*/ false,
+ /*attachmentFragmentShadingRate*/ false,
+ };
+
VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {
/*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
- /*pNext*/ nullptr,
+ /*pNext*/ &vrs_features,
/*shaderFloat16*/ false,
/*shaderInt8*/ false,
};
@@ -561,6 +584,10 @@ Error VulkanContext::_check_capabilities() {
vkGetPhysicalDeviceFeatures2_func(gpu, &device_features);
+ vrs_capabilities.pipeline_vrs_supported = vrs_features.pipelineFragmentShadingRate;
+ vrs_capabilities.primitive_vrs_supported = vrs_features.primitiveFragmentShadingRate;
+ vrs_capabilities.attachment_vrs_supported = vrs_features.attachmentFragmentShadingRate;
+
multiview_capabilities.is_supported = multiview_features.multiview;
multiview_capabilities.geometry_shader_is_supported = multiview_features.multiviewGeometryShader;
multiview_capabilities.tessellation_shader_is_supported = multiview_features.multiviewTessellationShader;
@@ -574,31 +601,40 @@ Error VulkanContext::_check_capabilities() {
storage_buffer_capabilities.storage_input_output_16 = storage_feature.storageInputOutput16;
}
- // check extended properties
+ // Check extended properties.
PFN_vkGetPhysicalDeviceProperties2 device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2");
if (device_properties_func == nullptr) {
- // In Vulkan 1.0 might be accessible under its original extension name
+ // In Vulkan 1.0 might be accessible under its original extension name.
device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2KHR");
}
if (device_properties_func != nullptr) {
+ VkPhysicalDeviceFragmentShadingRatePropertiesKHR vrsProperties;
VkPhysicalDeviceMultiviewProperties multiviewProperties;
VkPhysicalDeviceSubgroupProperties subgroupProperties;
VkPhysicalDeviceProperties2 physicalDeviceProperties;
+ void *nextptr = nullptr;
subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
- subgroupProperties.pNext = nullptr;
-
- physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ subgroupProperties.pNext = nextptr;
+ nextptr = &subgroupProperties;
if (multiview_capabilities.is_supported) {
multiviewProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
- multiviewProperties.pNext = &subgroupProperties;
+ multiviewProperties.pNext = nextptr;
- physicalDeviceProperties.pNext = &multiviewProperties;
- } else {
- physicalDeviceProperties.pNext = &subgroupProperties;
+ nextptr = &multiviewProperties;
}
+ if (vrs_capabilities.attachment_vrs_supported) {
+ vrsProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR;
+ vrsProperties.pNext = nextptr;
+
+ nextptr = &vrsProperties;
+ }
+
+ physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ physicalDeviceProperties.pNext = nextptr;
+
device_properties_func(gpu, &physicalDeviceProperties);
subgroup_capabilities.size = subgroupProperties.subgroupSize;
@@ -609,6 +645,28 @@ Error VulkanContext::_check_capabilities() {
// - supportedOperations has VK_SUBGROUP_FEATURE_QUAD_BIT
subgroup_capabilities.quadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages;
+ if (vrs_capabilities.pipeline_vrs_supported || vrs_capabilities.primitive_vrs_supported || vrs_capabilities.attachment_vrs_supported) {
+ print_verbose("- Vulkan Variable Rate Shading supported:");
+ if (vrs_capabilities.pipeline_vrs_supported) {
+ print_verbose(" Pipeline fragment shading rate");
+ }
+ if (vrs_capabilities.primitive_vrs_supported) {
+ print_verbose(" Primitive fragment shading rate");
+ }
+ if (vrs_capabilities.attachment_vrs_supported) {
+ // TODO expose these somehow to the end user
+ vrs_capabilities.min_texel_size.x = vrsProperties.minFragmentShadingRateAttachmentTexelSize.width;
+ vrs_capabilities.min_texel_size.y = vrsProperties.minFragmentShadingRateAttachmentTexelSize.height;
+ vrs_capabilities.max_texel_size.x = vrsProperties.maxFragmentShadingRateAttachmentTexelSize.width;
+ vrs_capabilities.max_texel_size.y = vrsProperties.maxFragmentShadingRateAttachmentTexelSize.height;
+
+ print_verbose(String(" Attachment fragment shading rate") + String(", min texel size: (") + itos(vrs_capabilities.min_texel_size.x) + String(", ") + itos(vrs_capabilities.min_texel_size.y) + String(")") + String(", max texel size: (") + itos(vrs_capabilities.max_texel_size.x) + String(", ") + itos(vrs_capabilities.max_texel_size.y) + String(")"));
+ }
+
+ } else {
+ print_verbose("- Vulkan Variable Rate Shading not supported");
+ }
+
if (multiview_capabilities.is_supported) {
multiview_capabilities.max_view_count = multiviewProperties.maxMultiviewViewCount;
multiview_capabilities.max_instance_count = multiviewProperties.maxMultiviewInstanceIndex;
@@ -635,10 +693,10 @@ Error VulkanContext::_check_capabilities() {
}
Error VulkanContext::_create_instance() {
- /* obtain version */
+ // Obtain Vulkan version.
_obtain_vulkan_version();
- /* initialise extensions */
+ // Initialize extensions.
{
Error err = _initialize_extensions();
if (err != OK) {
@@ -726,8 +784,7 @@ Error VulkanContext::_create_instance() {
#endif
if (enabled_debug_utils) {
- // Setup VK_EXT_debug_utils function pointers always (we use them for
- // debug labels and names).
+ // Setup VK_EXT_debug_utils function pointers always (we use them for debug labels and names).
CreateDebugUtilsMessengerEXT =
(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(inst, "vkCreateDebugUtilsMessengerEXT");
DestroyDebugUtilsMessengerEXT =
@@ -800,7 +857,7 @@ Error VulkanContext::_create_instance() {
}
Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
- /* Make initial call to query gpu_count, then second call for gpu info*/
+ // Make initial call to query gpu_count, then second call for gpu info.
uint32_t gpu_count = 0;
VkResult err = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -836,7 +893,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
return ERR_CANT_CREATE;
}
- // not really needed but nice to print the correct entry
+ // Not really needed but nice to print the correct entry.
for (uint32_t i = 0; i < gpu_count; ++i) {
if (physical_devices[i] == gpu) {
device_index = i;
@@ -948,13 +1005,13 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
free(physical_devices);
- /* Look for device extensions */
+ // Look for device extensions.
uint32_t device_extension_count = 0;
VkBool32 swapchainExtFound = 0;
enabled_extension_count = 0;
memset(extension_names, 0, sizeof(extension_names));
- /* Get identifier properties */
+ // Get identifier properties.
vkGetPhysicalDeviceProperties(gpu, &gpu_props);
device_name = gpu_props.deviceName;
@@ -996,9 +1053,16 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
extension_names[enabled_extension_count++] = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
}
if (!strcmp(VK_KHR_MULTIVIEW_EXTENSION_NAME, device_extensions[i].extensionName)) {
- // if multiview is supported, enable it
+ // If multiview is supported, enable it.
extension_names[enabled_extension_count++] = VK_KHR_MULTIVIEW_EXTENSION_NAME;
}
+ if (!strcmp(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, device_extensions[i].extensionName)) {
+ // if shading rate image is supported, enable it
+ extension_names[enabled_extension_count++] = VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME;
+ }
+ if (!strcmp(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, device_extensions[i].extensionName)) {
+ extension_names[enabled_extension_count++] = VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME;
+ }
if (enabled_extension_count >= MAX_EXTENSIONS) {
free(device_extensions);
ERR_FAIL_V_MSG(ERR_BUG, "Enabled extension count reaches MAX_EXTENSIONS, BUG");
@@ -1049,19 +1113,18 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
" extension.\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?\n"
"vkCreateInstance Failure");
- /* Call with nullptr data to get count */
+ // Call with nullptr data to get count.
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, nullptr);
ERR_FAIL_COND_V(queue_family_count == 0, ERR_CANT_CREATE);
queue_props = (VkQueueFamilyProperties *)malloc(queue_family_count * sizeof(VkQueueFamilyProperties));
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, queue_props);
-
// Query fine-grained feature support for this device.
// If app has specific feature requirements it should check supported
// features based on this query
vkGetPhysicalDeviceFeatures(gpu, &physical_device_features);
- physical_device_features.robustBufferAccess = false; //turn off robust buffer access, which can hamper performance on some hardware
+ physical_device_features.robustBufferAccess = false; // Turn off robust buffer access, which can hamper performance on some hardware.
#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
{ \
@@ -1076,7 +1139,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfacePresentModesKHR);
GET_INSTANCE_PROC_ADDR(inst, GetSwapchainImagesKHR);
- // get info about what our vulkan driver is capable off
+ // Gets capability info for current Vulkan driver.
{
Error res = _check_capabilities();
if (res != OK) {
@@ -1110,11 +1173,23 @@ Error VulkanContext::_create_device() {
};
nextptr = &shader_features;
+ VkPhysicalDeviceFragmentShadingRateFeaturesKHR vrs_features;
+ if (vrs_capabilities.pipeline_vrs_supported || vrs_capabilities.primitive_vrs_supported || vrs_capabilities.attachment_vrs_supported) {
+ // insert into our chain to enable these features if they are available
+ vrs_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
+ vrs_features.pNext = nextptr;
+ vrs_features.pipelineFragmentShadingRate = vrs_capabilities.pipeline_vrs_supported;
+ vrs_features.primitiveFragmentShadingRate = vrs_capabilities.primitive_vrs_supported;
+ vrs_features.attachmentFragmentShadingRate = vrs_capabilities.attachment_vrs_supported;
+
+ nextptr = &vrs_features;
+ }
+
VkPhysicalDeviceVulkan11Features vulkan11features;
VkPhysicalDevice16BitStorageFeaturesKHR storage_feature;
VkPhysicalDeviceMultiviewFeatures multiview_features;
if (vulkan_major > 1 || vulkan_minor >= 2) {
- // In Vulkan 1.2 and newer we use a newer struct to enable various features
+ // In Vulkan 1.2 and newer we use a newer struct to enable various features.
vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
vulkan11features.pNext = nextptr;
@@ -1132,7 +1207,7 @@ Error VulkanContext::_create_device() {
vulkan11features.shaderDrawParameters = 0;
nextptr = &vulkan11features;
} else {
- // On Vulkan 1.0 and 1.1 we use our older structs to initialise these features
+ // On Vulkan 1.0 and 1.1 we use our older structs to initialise these features.
storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
storage_feature.pNext = nextptr;
storage_feature.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
@@ -1161,7 +1236,7 @@ Error VulkanContext::_create_device() {
/*ppEnabledLayerNames*/ nullptr,
/*enabledExtensionCount*/ enabled_extension_count,
/*ppEnabledExtensionNames*/ (const char *const *)extension_names,
- /*pEnabledFeatures*/ &physical_device_features, // If specific features are required, pass them in here
+ /*pEnabledFeatures*/ &physical_device_features, // If specific features are required, pass them in here.
};
if (separate_present_queue) {
queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@@ -1193,7 +1268,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
}
// Search for a graphics and a present queue in the array of queue
- // families, try to find one that supports both
+ // families, try to find one that supports both.
uint32_t graphicsQueueFamilyIndex = UINT32_MAX;
uint32_t presentQueueFamilyIndex = UINT32_MAX;
for (uint32_t i = 0; i < queue_family_count; i++) {
@@ -1223,7 +1298,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
free(supportsPresent);
- // Generate error if could not find both a graphics and a present queue
+ // Generate error if could not find both a graphics and a present queue.
ERR_FAIL_COND_V_MSG(graphicsQueueFamilyIndex == UINT32_MAX || presentQueueFamilyIndex == UINT32_MAX, ERR_CANT_CREATE,
"Could not find both graphics and present queues\n");
@@ -1279,7 +1354,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
color_space = surfFormats[0].colorSpace;
} else {
// These should be ordered with the ones we want to use on top and fallback modes further down
- // we want an 32bit RGBA unsigned normalised buffer or similar
+ // we want a 32bit RGBA unsigned normalised buffer or similar.
const VkFormat allowed_formats[] = {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM
@@ -1291,7 +1366,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "formatCount less than 1");
}
- // Find the first format that we support
+ // Find the first format that we support.
format = VK_FORMAT_UNDEFINED;
for (uint32_t af = 0; af < allowed_formats_count && format == VK_FORMAT_UNDEFINED; af++) {
for (uint32_t sf = 0; sf < formatCount && format == VK_FORMAT_UNDEFINED; sf++) {
@@ -1323,7 +1398,7 @@ Error VulkanContext::_create_semaphores() {
VkResult err;
// Create semaphores to synchronize acquiring presentable buffers before
- // rendering and waiting for drawing to be complete before presenting
+ // rendering and waiting for drawing to be complete before presenting.
VkSemaphoreCreateInfo semaphoreCreateInfo = {
/*sType*/ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
/*pNext*/ nullptr,
@@ -1331,7 +1406,7 @@ Error VulkanContext::_create_semaphores() {
};
// Create fences that we can use to throttle if we get too far
- // ahead of the image presents
+ // ahead of the image presents.
VkFenceCreateInfo fence_ci = {
/*sType*/ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
/*pNext*/ nullptr,
@@ -1351,7 +1426,7 @@ Error VulkanContext::_create_semaphores() {
}
frame_index = 0;
- // Get Memory information and properties
+ // Get Memory information and properties.
vkGetPhysicalDeviceMemoryProperties(gpu, &memory_properties);
return OK;
@@ -1426,7 +1501,7 @@ bool VulkanContext::window_is_valid_swapchain(DisplayServer::WindowID p_window)
VkRenderPass VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
Window *w = &windows[p_window];
- //vulkan use of currentbuffer
+ // Vulkan use of currentbuffer.
return w->render_pass;
}
@@ -1434,7 +1509,7 @@ VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_wi
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
ERR_FAIL_COND_V(!buffers_prepared, VK_NULL_HANDLE);
Window *w = &windows[p_window];
- //vulkan use of currentbuffer
+ // Vulkan use of currentbuffer.
if (w->swapchain_image_resources != VK_NULL_HANDLE) {
return w->swapchain_image_resources[w->current_buffer].framebuffer;
} else {
@@ -1459,7 +1534,7 @@ Error VulkanContext::_clean_up_swap_chain(Window *window) {
}
vkDeviceWaitIdle(device);
- //this destroys images associated it seems
+ // This destroys images associated it seems.
fpDestroySwapchainKHR(device, window->swapchain, nullptr);
window->swapchain = VK_NULL_HANDLE;
vkDestroyRenderPass(device, window->render_pass, nullptr);
@@ -1485,7 +1560,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
_clean_up_swap_chain(window);
}
- // Check the surface capabilities and formats
+ // Check the surface capabilities and formats.
VkSurfaceCapabilitiesKHR surfCapabilities;
err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, window->surface, &surfCapabilities);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -1502,7 +1577,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
}
VkExtent2D swapchainExtent;
- // width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF.
+ // Width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF.
if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) {
// If the surface size is undefined, the size is set to the size
// of the images requested, which must fit within the minimum and
@@ -1522,7 +1597,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
swapchainExtent.height = surfCapabilities.maxImageExtent.height;
}
} else {
- // If the surface size is defined, the swap chain size must match
+ // If the surface size is defined, the swap chain size must match.
swapchainExtent = surfCapabilities.currentExtent;
window->width = surfCapabilities.currentExtent.width;
window->height = surfCapabilities.currentExtent.height;
@@ -1530,7 +1605,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
if (window->width == 0 || window->height == 0) {
free(presentModes);
- //likely window minimized, no swapchain created
+ // Likely window minimized, no swapchain created.
return OK;
}
// The FIFO present mode is guaranteed by the spec to be supported
@@ -1592,7 +1667,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
window->presentMode = requested_present_mode;
} else {
WARN_PRINT("Requested VSync mode is not available!");
- window->vsync_mode = DisplayServer::VSYNC_ENABLED; //Set to default
+ window->vsync_mode = DisplayServer::VSYNC_ENABLED; // Set to default.
}
print_verbose("Using present mode: " + String(string_VkPresentModeKHR(window->presentMode)));
@@ -1601,13 +1676,13 @@ Error VulkanContext::_update_swap_chain(Window *window) {
// Determine the number of VkImages to use in the swap chain.
// Application desires to acquire 3 images at a time for triple
- // buffering
+ // buffering.
uint32_t desiredNumOfSwapchainImages = 3;
if (desiredNumOfSwapchainImages < surfCapabilities.minImageCount) {
desiredNumOfSwapchainImages = surfCapabilities.minImageCount;
}
// If maxImageCount is 0, we can ask for as many images as we want;
- // otherwise we're limited to maxImageCount
+ // otherwise we're limited to maxImageCount.
if ((surfCapabilities.maxImageCount > 0) && (desiredNumOfSwapchainImages > surfCapabilities.maxImageCount)) {
// Application must settle for fewer images than desired:
desiredNumOfSwapchainImages = surfCapabilities.maxImageCount;
@@ -1620,7 +1695,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
preTransform = surfCapabilities.currentTransform;
}
- // Find a supported composite alpha mode - one of these is guaranteed to be set
+ // Find a supported composite alpha mode - one of these is guaranteed to be set.
VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = {
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
@@ -1667,7 +1742,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
if (swapchainImageCount == 0) {
- //assign here for the first time.
+ // Assign here for the first time.
swapchainImageCount = sp_image_count;
} else {
ERR_FAIL_COND_V(swapchainImageCount != sp_image_count, ERR_BUG);
@@ -1725,7 +1800,9 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/******** FRAMEBUFFER ************/
{
- const VkAttachmentDescription attachment = {
+ const VkAttachmentDescription2KHR attachment = {
+ /*sType*/ VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*format*/ format,
/*samples*/ VK_SAMPLE_COUNT_1_BIT,
@@ -1737,14 +1814,20 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*finalLayout*/ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
};
- const VkAttachmentReference color_reference = {
+ const VkAttachmentReference2KHR color_reference = {
+ /*sType*/ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR,
+ /*pNext*/ nullptr,
/*attachment*/ 0,
/*layout*/ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ /*aspectMask*/ 0,
};
- const VkSubpassDescription subpass = {
+ const VkSubpassDescription2KHR subpass = {
+ /*sType*/ VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*pipelineBindPoint*/ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ /*viewMask*/ 1,
/*inputAttachmentCount*/ 0,
/*pInputAttachments*/ nullptr,
/*colorAttachmentCount*/ 1,
@@ -1754,8 +1837,10 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*preserveAttachmentCount*/ 0,
/*pPreserveAttachments*/ nullptr,
};
- const VkRenderPassCreateInfo rp_info = {
- /*sTyp*/ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+
+ uint32_t view_masks = 1;
+ const VkRenderPassCreateInfo2KHR rp_info = {
+ /*sType*/ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR,
/*pNext*/ nullptr,
/*flags*/ 0,
/*attachmentCount*/ 1,
@@ -1764,9 +1849,11 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*pSubpasses*/ &subpass,
/*dependencyCount*/ 0,
/*pDependencies*/ nullptr,
+ /*correlatedViewMaskCount*/ 1,
+ /*pCorrelatedViewMasks*/ &view_masks,
};
- err = vkCreateRenderPass(device, &rp_info, nullptr, &window->render_pass);
+ err = vkCreateRenderPass2KHR(device, &rp_info, nullptr, &window->render_pass);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
for (uint32_t i = 0; i < swapchainImageCount; i++) {
@@ -1839,7 +1926,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
}
}
- //reset current buffer
+ // Reset current buffer.
window->current_buffer = 0;
return OK;
@@ -1860,27 +1947,30 @@ Error VulkanContext::initialize() {
return OK;
}
-void VulkanContext::set_setup_buffer(const VkCommandBuffer &pCommandBuffer) {
- command_buffer_queue.write[0] = pCommandBuffer;
+void VulkanContext::set_setup_buffer(VkCommandBuffer p_command_buffer) {
+ command_buffer_queue.write[0] = p_command_buffer;
}
-void VulkanContext::append_command_buffer(const VkCommandBuffer &pCommandBuffer) {
+void VulkanContext::append_command_buffer(VkCommandBuffer p_command_buffer) {
if (command_buffer_queue.size() <= command_buffer_count) {
command_buffer_queue.resize(command_buffer_count + 1);
}
- command_buffer_queue.write[command_buffer_count] = pCommandBuffer;
+ command_buffer_queue.write[command_buffer_count] = p_command_buffer;
command_buffer_count++;
}
void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
- // ensure everything else pending is executed
+ // Ensure everything else pending is executed.
vkDeviceWaitIdle(device);
- //flush the pending setup buffer
+ // Flush the pending setup buffer.
+
+ bool setup_flushable = p_flush_setup && command_buffer_queue[0];
+ bool pending_flushable = p_flush_pending && command_buffer_count > 1;
- if (p_flush_setup && command_buffer_queue[0]) {
- //use a fence to wait for everything done
+ if (setup_flushable) {
+ // Use a fence to wait for everything done.
VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.pNext = nullptr;
@@ -1889,33 +1979,33 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
submit_info.pWaitSemaphores = nullptr;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = command_buffer_queue.ptr();
- submit_info.signalSemaphoreCount = 0;
- submit_info.pSignalSemaphores = nullptr;
+ submit_info.signalSemaphoreCount = pending_flushable ? 1 : 0;
+ submit_info.pSignalSemaphores = pending_flushable ? &draw_complete_semaphores[frame_index] : nullptr;
VkResult err = vkQueueSubmit(graphics_queue, 1, &submit_info, VK_NULL_HANDLE);
command_buffer_queue.write[0] = nullptr;
ERR_FAIL_COND(err);
- vkDeviceWaitIdle(device);
}
- if (p_flush_pending && command_buffer_count > 1) {
- //use a fence to wait for everything done
+ if (pending_flushable) {
+ // Use a fence to wait for everything to finish.
VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.pNext = nullptr;
- submit_info.pWaitDstStageMask = nullptr;
- submit_info.waitSemaphoreCount = 0;
- submit_info.pWaitSemaphores = nullptr;
+ VkPipelineStageFlags wait_stage_mask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ submit_info.pWaitDstStageMask = setup_flushable ? &wait_stage_mask : nullptr;
+ submit_info.waitSemaphoreCount = setup_flushable ? 1 : 0;
+ submit_info.pWaitSemaphores = setup_flushable ? &draw_complete_semaphores[frame_index] : nullptr;
submit_info.commandBufferCount = command_buffer_count - 1;
submit_info.pCommandBuffers = command_buffer_queue.ptr() + 1;
submit_info.signalSemaphoreCount = 0;
submit_info.pSignalSemaphores = nullptr;
VkResult err = vkQueueSubmit(graphics_queue, 1, &submit_info, VK_NULL_HANDLE);
- ERR_FAIL_COND(err);
- vkDeviceWaitIdle(device);
-
command_buffer_count = 1;
+ ERR_FAIL_COND(err);
}
+
+ vkDeviceWaitIdle(device);
}
Error VulkanContext::prepare_buffers() {
@@ -1925,7 +2015,7 @@ Error VulkanContext::prepare_buffers() {
VkResult err;
- // Ensure no more than FRAME_LAG renderings are outstanding
+ // Ensure no more than FRAME_LAG renderings are outstanding.
vkWaitForFences(device, 1, &fences[frame_index], VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &fences[frame_index]);
@@ -1945,13 +2035,13 @@ Error VulkanContext::prepare_buffers() {
w->image_acquired_semaphores[frame_index], VK_NULL_HANDLE, &w->current_buffer);
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
- // swapchain is out of date (e.g. the window was resized) and
+ // Swapchain is out of date (e.g. the window was resized) and
// must be recreated:
print_verbose("Vulkan: Early out of date swapchain, recreating.");
- //resize_notify();
+ // resize_notify();
_update_swap_chain(w);
} else if (err == VK_SUBOPTIMAL_KHR) {
- // swapchain is not as optimal as it could be, but the platform's
+ // Swapchain is not as optimal as it could be, but the platform's
// presentation engine will still present the image correctly.
print_verbose("Vulkan: Early suboptimal swapchain.");
break;
@@ -1998,7 +2088,7 @@ Error VulkanContext::swap_buffers() {
uint32_t commands_to_submit = 0;
if (command_buffer_queue[0] == nullptr) {
- //no setup command, but commands to submit, submit from the first and skip command
+ // No setup command, but commands to submit, submit from the first and skip command.
if (command_buffer_count > 1) {
commands_ptr = command_buffer_queue.ptr() + 1;
commands_to_submit = command_buffer_count - 1;
@@ -2041,7 +2131,7 @@ Error VulkanContext::swap_buffers() {
if (separate_present_queue) {
// If we are using separate queues, change image ownership to the
// present queue before presenting, waiting for the draw complete
- // semaphore and signalling the ownership released semaphore when finished
+ // semaphore and signalling the ownership released semaphore when finished.
VkFence nullFence = VK_NULL_HANDLE;
pipe_stage_flags[0] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
submit_info.waitSemaphoreCount = 1;
@@ -2068,7 +2158,7 @@ Error VulkanContext::swap_buffers() {
}
// If we are using separate queues, we have to wait for image ownership,
- // otherwise wait for draw complete
+ // otherwise wait for draw complete.
VkPresentInfoKHR present = {
/*sType*/ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
/*pNext*/ nullptr,
@@ -2173,12 +2263,12 @@ Error VulkanContext::swap_buffers() {
frame_index %= FRAME_LAG;
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
- // swapchain is out of date (e.g. the window was resized) and
+ // Swapchain is out of date (e.g. the window was resized) and
// must be recreated:
print_verbose("Vulkan: Swapchain is out of date, recreating.");
resize_notify();
} else if (err == VK_SUBOPTIMAL_KHR) {
- // swapchain is not as optimal as it could be, but the platform's
+ // Swapchain is not as optimal as it could be, but the platform's
// presentation engine will still present the image correctly.
print_verbose("Vulkan: Swapchain is suboptimal.");
} else {
@@ -2223,7 +2313,7 @@ VkPhysicalDeviceLimits VulkanContext::get_device_limits() const {
RID VulkanContext::local_device_create() {
LocalDevice ld;
- { //create device
+ { // Create device.
VkResult err;
float queue_priorities[1] = { 0.0 };
VkDeviceQueueCreateInfo queues[2];
@@ -2244,13 +2334,13 @@ RID VulkanContext::local_device_create() {
/*ppEnabledLayerNames */ nullptr,
/*enabledExtensionCount */ enabled_extension_count,
/*ppEnabledExtensionNames */ (const char *const *)extension_names,
- /*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here
+ /*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here.
};
err = vkCreateDevice(gpu, &sdevice, nullptr, &ld.device);
ERR_FAIL_COND_V(err, RID());
}
- { //create graphics queue
+ { // Create graphics queue.
vkGetDeviceQueue(ld.device, graphics_queue_family_index, 0, &ld.queue);
}
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 236e3bf35f..b2eb43975f 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -69,6 +69,15 @@ public:
uint32_t max_instance_count;
};
+ struct VRSCapabilities {
+ bool pipeline_vrs_supported; // We can specify our fragment rate on a pipeline level
+ bool primitive_vrs_supported; // We can specify our fragment rate on each drawcall
+ bool attachment_vrs_supported; // We can provide a density map attachment on our framebuffer
+
+ Size2i min_texel_size;
+ Size2i max_texel_size;
+ };
+
struct ShaderCapabilities {
bool shader_float16_is_supported;
bool shader_int8_is_supported;
@@ -104,6 +113,7 @@ private:
uint32_t vulkan_patch = 0;
SubgroupCapabilities subgroup_capabilities;
MultiviewCapabilities multiview_capabilities;
+ VRSCapabilities vrs_capabilities;
ShaderCapabilities shader_capabilities;
StorageBufferCapabilities storage_buffer_capabilities;
@@ -117,8 +127,8 @@ private:
// Present queue.
bool queues_initialized = false;
- uint32_t graphics_queue_family_index = 0;
- uint32_t present_queue_family_index = 0;
+ uint32_t graphics_queue_family_index = UINT32_MAX;
+ uint32_t present_queue_family_index = UINT32_MAX;
bool separate_present_queue = false;
VkQueue graphics_queue = VK_NULL_HANDLE;
VkQueue present_queue = VK_NULL_HANDLE;
@@ -206,6 +216,7 @@ private:
PFN_vkQueuePresentKHR fpQueuePresentKHR = nullptr;
PFN_vkGetRefreshCycleDurationGOOGLE fpGetRefreshCycleDurationGOOGLE = nullptr;
PFN_vkGetPastPresentationTimingGOOGLE fpGetPastPresentationTimingGOOGLE = nullptr;
+ PFN_vkCreateRenderPass2KHR fpCreateRenderPass2KHR = nullptr;
VkDebugUtilsMessengerEXT dbg_messenger = VK_NULL_HANDLE;
VkDebugReportCallbackEXT dbg_debug_report = VK_NULL_HANDLE;
@@ -256,10 +267,14 @@ protected:
Error _get_preferred_validation_layers(uint32_t *count, const char *const **names);
public:
+ // Extension calls
+ VkResult vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass);
+
uint32_t get_vulkan_major() const { return vulkan_major; };
uint32_t get_vulkan_minor() const { return vulkan_minor; };
SubgroupCapabilities get_subgroup_capabilities() const { return subgroup_capabilities; };
MultiviewCapabilities get_multiview_capabilities() const { return multiview_capabilities; };
+ VRSCapabilities get_vrs_capabilities() const { return vrs_capabilities; };
ShaderCapabilities get_shader_capabilities() const { return shader_capabilities; };
StorageBufferCapabilities get_storage_buffer_capabilities() const { return storage_buffer_capabilities; };
@@ -289,8 +304,8 @@ public:
VkFormat get_screen_format() const;
VkPhysicalDeviceLimits get_device_limits() const;
- void set_setup_buffer(const VkCommandBuffer &pCommandBuffer);
- void append_command_buffer(const VkCommandBuffer &pCommandBuffer);
+ void set_setup_buffer(VkCommandBuffer p_command_buffer);
+ void append_command_buffer(VkCommandBuffer p_command_buffer);
void resize_notify();
void flush(bool p_flush_setup = false, bool p_flush_pending = false);
Error prepare_buffers();
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index 698390a61e..8c59d65c80 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -1199,7 +1199,7 @@ void ActionMapEditor::use_external_search_box(LineEdit *p_searchbox) {
ActionMapEditor::ActionMapEditor() {
// Main Vbox Container
VBoxContainer *main_vbox = memnew(VBoxContainer);
- main_vbox->set_anchors_and_offsets_preset(PRESET_WIDE);
+ main_vbox->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
add_child(main_vbox);
HBoxContainer *top_hbox = memnew(HBoxContainer);
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index 391cd009f1..44e04efb5d 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -1593,7 +1593,7 @@ AnimationBezierTrackEdit::AnimationBezierTrackEdit() {
play_position = memnew(Control);
play_position->set_mouse_filter(MOUSE_FILTER_PASS);
add_child(play_position);
- play_position->set_anchors_and_offsets_preset(PRESET_WIDE);
+ play_position->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
play_position->connect("draw", callable_mp(this, &AnimationBezierTrackEdit::_play_position_draw));
set_focus_mode(FOCUS_CLICK);
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index e612130041..703cfaee3d 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -1577,10 +1577,10 @@ void AnimationTimelineEdit::_notification(int p_what) {
int decimals = 2;
bool step_found = false;
- const float period_width = font->get_char_size('.', 0, font_size).width;
- float max_digit_width = font->get_char_size('0', 0, font_size).width;
+ const float period_width = font->get_char_size('.', font_size).width;
+ float max_digit_width = font->get_char_size('0', font_size).width;
for (int i = 1; i <= 9; i++) {
- const float digit_width = font->get_char_size('0' + i, 0, font_size).width;
+ const float digit_width = font->get_char_size('0' + i, font_size).width;
max_digit_width = MAX(digit_width, max_digit_width);
}
const int max_sc = int(Math::ceil(zoomw / scale));
@@ -1628,7 +1628,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE));
draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), itos(frame), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec);
- prev_frame_ofs = i + font->get_string_size(itos(frame), font_size).x + 5 * EDSCALE;
+ prev_frame_ofs = i + font->get_string_size(itos(frame), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x + 5 * EDSCALE;
}
}
}
@@ -1890,7 +1890,7 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
play_position = memnew(Control);
play_position->set_mouse_filter(MOUSE_FILTER_PASS);
add_child(play_position);
- play_position->set_anchors_and_offsets_preset(PRESET_WIDE);
+ play_position->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
play_position->connect("draw", callable_mp(this, &AnimationTimelineEdit::_play_position_draw));
add_track = memnew(MenuButton);
@@ -2919,7 +2919,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
add_child(path_popup);
path = memnew(LineEdit);
path_popup->add_child(path);
- path->set_anchors_and_offsets_preset(PRESET_WIDE);
+ path->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
path->connect("text_submitted", callable_mp(this, &AnimationTrackEdit::_path_submitted));
}
@@ -3212,7 +3212,7 @@ AnimationTrackEdit::AnimationTrackEdit() {
play_position = memnew(Control);
play_position->set_mouse_filter(MOUSE_FILTER_PASS);
add_child(play_position);
- play_position->set_anchors_and_offsets_preset(PRESET_WIDE);
+ play_position->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
play_position->connect("draw", callable_mp(this, &AnimationTrackEdit::_play_position_draw));
set_focus_mode(FOCUS_CLICK);
set_mouse_filter(MOUSE_FILTER_PASS); // Scroll has to work too for selection.
@@ -3696,7 +3696,7 @@ void AnimationTrackEditor::commit_insert_queue() {
insert_confirm_bezier->set_visible(all_bezier);
insert_confirm_reset->set_visible(reset_allowed);
- insert_confirm->get_ok_button()->set_text(TTR("Create"));
+ insert_confirm->set_ok_button_text(TTR("Create"));
insert_confirm->popup_centered();
} else {
_insert_track(reset_allowed && EDITOR_GET("editors/animation/default_create_reset_tracks"), all_bezier && EDITOR_GET("editors/animation/default_create_bezier_tracks"));
@@ -3725,11 +3725,11 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
}
}
-void AnimationTrackEditor::_insert_track(bool p_create_reset, bool p_create_beziers) {
+void AnimationTrackEditor::_insert_track(bool p_reset_wanted, bool p_create_beziers) {
undo_redo->create_action(TTR("Anim Insert"));
Ref<Animation> reset_anim;
- if (p_create_reset) {
+ if (p_reset_wanted) {
reset_anim = _create_and_get_reset_animation();
}
@@ -3739,7 +3739,7 @@ void AnimationTrackEditor::_insert_track(bool p_create_reset, bool p_create_bezi
if (insert_data.front()->get().advance) {
advance = true;
}
- next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, p_create_reset, reset_anim, p_create_beziers);
+ next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, p_reset_wanted, reset_anim, p_create_beziers);
insert_data.pop_front();
}
@@ -4207,9 +4207,42 @@ static Vector<String> _get_bezier_subindices_for_type(Variant::Type p_type, bool
return subindices;
}
-AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, Ref<Animation> p_reset_anim, bool p_create_beziers) {
+AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_reset_wanted, Ref<Animation> p_reset_anim, bool p_create_beziers) {
bool created = false;
- if (p_id.track_idx < 0) {
+
+ bool create_normal_track = p_id.track_idx < 0;
+ bool create_reset_track = p_reset_wanted && track_type_is_resettable(p_id.type);
+
+ Animation::UpdateMode update_mode = Animation::UPDATE_DISCRETE;
+ if (create_normal_track || create_reset_track) {
+ if (p_id.type == Animation::TYPE_VALUE || p_id.type == Animation::TYPE_BEZIER) {
+ // Hack.
+ NodePath np;
+ animation->add_track(p_id.type);
+ animation->track_set_path(animation->get_track_count() - 1, p_id.path);
+ PropertyInfo h = _find_hint_for_track(animation->get_track_count() - 1, np);
+ animation->remove_track(animation->get_track_count() - 1); // Hack.
+
+ if (h.type == Variant::FLOAT ||
+ h.type == Variant::VECTOR2 ||
+ h.type == Variant::RECT2 ||
+ h.type == Variant::VECTOR3 ||
+ h.type == Variant::AABB ||
+ h.type == Variant::QUATERNION ||
+ h.type == Variant::COLOR ||
+ h.type == Variant::PLANE ||
+ h.type == Variant::TRANSFORM2D ||
+ h.type == Variant::TRANSFORM3D) {
+ update_mode = Animation::UPDATE_CONTINUOUS;
+ }
+
+ if (h.usage & PROPERTY_USAGE_ANIMATE_AS_TRIGGER) {
+ update_mode = Animation::UPDATE_TRIGGER;
+ }
+ }
+ }
+
+ if (create_normal_track) {
if (p_create_beziers) {
bool valid;
Vector<String> subindices = _get_bezier_subindices_for_type(p_id.value.get_type(), &valid);
@@ -4219,7 +4252,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
id.type = Animation::TYPE_BEZIER;
id.value = p_id.value.get(subindices[i].substr(1, subindices[i].length()));
id.path = String(p_id.path) + subindices[i];
- p_next_tracks = _confirm_insert(id, p_next_tracks, p_create_reset, p_reset_anim, false);
+ p_next_tracks = _confirm_insert(id, p_next_tracks, p_reset_wanted, p_reset_anim, false);
}
return p_next_tracks;
@@ -4227,37 +4260,6 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
}
created = true;
undo_redo->create_action(TTR("Anim Insert Track & Key"));
- Animation::UpdateMode update_mode = Animation::UPDATE_DISCRETE;
-
- if (p_id.type == Animation::TYPE_VALUE || p_id.type == Animation::TYPE_BEZIER) {
- // Wants a new track.
-
- {
- // Hack.
- NodePath np;
- animation->add_track(p_id.type);
- animation->track_set_path(animation->get_track_count() - 1, p_id.path);
- PropertyInfo h = _find_hint_for_track(animation->get_track_count() - 1, np);
- animation->remove_track(animation->get_track_count() - 1); // Hack.
-
- if (h.type == Variant::FLOAT ||
- h.type == Variant::VECTOR2 ||
- h.type == Variant::RECT2 ||
- h.type == Variant::VECTOR3 ||
- h.type == Variant::AABB ||
- h.type == Variant::QUATERNION ||
- h.type == Variant::COLOR ||
- h.type == Variant::PLANE ||
- h.type == Variant::TRANSFORM2D ||
- h.type == Variant::TRANSFORM3D) {
- update_mode = Animation::UPDATE_CONTINUOUS;
- }
-
- if (h.usage & PROPERTY_USAGE_ANIMATE_AS_TRIGGER) {
- update_mode = Animation::UPDATE_TRIGGER;
- }
- }
- }
p_id.track_idx = p_next_tracks.normal;
@@ -4320,8 +4322,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
}
}
- if (p_create_reset && track_type_is_resettable(p_id.type)) {
- bool create_reset_track = true;
+ if (create_reset_track) {
Animation *reset_anim = p_reset_anim.ptr();
for (int i = 0; i < reset_anim->get_track_count(); i++) {
if (reset_anim->track_get_path(i) == p_id.path) {
@@ -4332,6 +4333,9 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
if (create_reset_track) {
undo_redo->add_do_method(reset_anim, "add_track", p_id.type);
undo_redo->add_do_method(reset_anim, "track_set_path", p_next_tracks.reset, p_id.path);
+ if (p_id.type == Animation::TYPE_VALUE) {
+ undo_redo->add_do_method(reset_anim, "value_track_set_update_mode", p_next_tracks.reset, update_mode);
+ }
undo_redo->add_do_method(reset_anim, "track_insert_key", p_next_tracks.reset, 0.0f, value);
undo_redo->add_undo_method(reset_anim, "remove_track", reset_anim->get_track_count());
p_next_tracks.reset++;
@@ -6241,7 +6245,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
info_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
info_message->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
- info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ info_message->set_anchors_and_offsets_preset(PRESET_FULL_RECT, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
main_panel->add_child(info_message);
timeline = memnew(AnimationTimelineEdit);
@@ -6473,7 +6477,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
optimize_max_angle->set_step(0.1);
optimize_max_angle->set_value(22);
- optimize_dialog->get_ok_button()->set_text(TTR("Optimize"));
+ optimize_dialog->set_ok_button_text(TTR("Optimize"));
optimize_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_OPTIMIZE_ANIMATION_CONFIRM));
//
@@ -6498,7 +6502,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
cleanup_vb->add_child(cleanup_all);
cleanup_dialog->set_title(TTR("Clean-Up Animation(s) (NO UNDO!)"));
- cleanup_dialog->get_ok_button()->set_text(TTR("Clean-Up"));
+ cleanup_dialog->set_ok_button_text(TTR("Clean-Up"));
cleanup_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_CLEAN_UP_ANIMATION_CONFIRM));
@@ -6518,7 +6522,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
track_copy_dialog = memnew(ConfirmationDialog);
add_child(track_copy_dialog);
track_copy_dialog->set_title(TTR("Select Tracks to Copy"));
- track_copy_dialog->get_ok_button()->set_text(TTR("Copy"));
+ track_copy_dialog->set_ok_button_text(TTR("Copy"));
VBoxContainer *track_vbox = memnew(VBoxContainer);
track_copy_dialog->add_child(track_vbox);
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 55c3bd922a..dede2e9bbe 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -375,8 +375,8 @@ class AnimationTrackEditor : public VBoxContainer {
reset = p_reset_anim ? p_reset_anim->get_track_count() : 0;
}
};
- TrackIndices _confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, Ref<Animation> p_reset_anim, bool p_create_beziers);
- void _insert_track(bool p_create_reset, bool p_create_beziers);
+ TrackIndices _confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_reset_wanted, Ref<Animation> p_reset_anim, bool p_create_beziers);
+ void _insert_track(bool p_reset_wanted, bool p_create_beziers);
void _root_removed();
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 272de725c8..3a0edf301d 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -332,7 +332,7 @@ void FindReplaceBar::_update_results_count() {
if (results_count_to_current > results_count) {
results_count_to_current = results_count_to_current - results_count;
- } else if (results_count_to_current == 0) {
+ } else if (results_count_to_current <= 0) {
results_count_to_current = results_count;
}
@@ -1636,30 +1636,35 @@ void CodeTextEditor::_apply_settings_change() {
_update_text_editor_theme();
font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size");
-
int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures");
- switch (ot_mode) {
- case 1: { // Disable ligatures.
- text_editor->clear_opentype_features();
- text_editor->set_opentype_feature("calt", 0);
- } break;
- case 2: { // Custom.
- text_editor->clear_opentype_features();
- Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(",");
- Dictionary ftrs;
- for (int i = 0; i < subtag.size(); i++) {
- Vector<String> subtag_a = subtag[i].split("=");
- if (subtag_a.size() == 2) {
- text_editor->set_opentype_feature(subtag_a[0], subtag_a[1].to_int());
- } else if (subtag_a.size() == 1) {
- text_editor->set_opentype_feature(subtag_a[0], 1);
+
+ Ref<FontVariation> fc = text_editor->get_theme_font(SNAME("font"));
+ if (fc.is_valid()) {
+ switch (ot_mode) {
+ case 1: { // Disable ligatures.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 0;
+ fc->set_opentype_features(ftrs);
+ } break;
+ case 2: { // Custom.
+ Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(",");
+ Dictionary ftrs;
+ for (int i = 0; i < subtag.size(); i++) {
+ Vector<String> subtag_a = subtag[i].split("=");
+ if (subtag_a.size() == 2) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
+ } else if (subtag_a.size() == 1) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = 1;
+ }
}
- }
- } break;
- default: { // Default.
- text_editor->clear_opentype_features();
- text_editor->set_opentype_feature("calt", 1);
- } break;
+ fc->set_opentype_features(ftrs);
+ } break;
+ default: { // Default.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 1;
+ fc->set_opentype_features(ftrs);
+ } break;
+ }
}
text_editor->set_code_hint_draw_below(EDITOR_GET("text_editor/completion/put_callhint_tooltip_below_current_line"));
@@ -1862,28 +1867,33 @@ CodeTextEditor::CodeTextEditor() {
text_editor->set_v_size_flags(SIZE_EXPAND_FILL);
int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures");
- switch (ot_mode) {
- case 1: { // Disable ligatures.
- text_editor->clear_opentype_features();
- text_editor->set_opentype_feature("calt", 0);
- } break;
- case 2: { // Custom.
- text_editor->clear_opentype_features();
- Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(",");
- Dictionary ftrs;
- for (int i = 0; i < subtag.size(); i++) {
- Vector<String> subtag_a = subtag[i].split("=");
- if (subtag_a.size() == 2) {
- text_editor->set_opentype_feature(subtag_a[0], subtag_a[1].to_int());
- } else if (subtag_a.size() == 1) {
- text_editor->set_opentype_feature(subtag_a[0], 1);
+ Ref<FontVariation> fc = text_editor->get_theme_font(SNAME("font"));
+ if (fc.is_valid()) {
+ switch (ot_mode) {
+ case 1: { // Disable ligatures.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 0;
+ fc->set_opentype_features(ftrs);
+ } break;
+ case 2: { // Custom.
+ Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(",");
+ Dictionary ftrs;
+ for (int i = 0; i < subtag.size(); i++) {
+ Vector<String> subtag_a = subtag[i].split("=");
+ if (subtag_a.size() == 2) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
+ } else if (subtag_a.size() == 1) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = 1;
+ }
}
- }
- } break;
- default: { // Default.
- text_editor->clear_opentype_features();
- text_editor->set_opentype_feature("calt", 1);
- } break;
+ fc->set_opentype_features(ftrs);
+ } break;
+ default: { // Default.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 1;
+ fc->set_opentype_features(ftrs);
+ } break;
+ }
}
text_editor->set_draw_line_numbers(true);
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 74fea03fee..ce94edd583 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -494,8 +494,8 @@ ConnectDialog::ConnectDialog() {
error = memnew(AcceptDialog);
add_child(error);
error->set_title(TTR("Cannot connect signal"));
- error->get_ok_button()->set_text(TTR("Close"));
- get_ok_button()->set_text(TTR("Connect"));
+ error->set_ok_button_text(TTR("Close"));
+ set_ok_button_text(TTR("Connect"));
}
ConnectDialog::~ConnectDialog() {
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 31c169a0fb..c41eeb520a 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -57,10 +57,10 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const St
if (p_replace_mode) {
set_title(vformat(TTR("Change %s Type"), base_type));
- get_ok_button()->set_text(TTR("Change"));
+ set_ok_button_text(TTR("Change"));
} else {
set_title(vformat(TTR("Create New %s"), base_type));
- get_ok_button()->set_text(TTR("Create"));
+ set_ok_button_text(TTR("Create"));
}
_load_favorites_and_history();
diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp
index 023204b74a..bdab1cfecb 100644
--- a/editor/debugger/editor_debugger_tree.cpp
+++ b/editor/debugger/editor_debugger_tree.cpp
@@ -258,7 +258,7 @@ void EditorDebuggerTree::_item_menu_id_pressed(int p_option) {
ResourceSaver::get_recognized_extensions(sd, &extensions);
file_dialog->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
- file_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
+ file_dialog->add_filter("*." + extensions[i], extensions[i].to_upper());
}
file_dialog->popup_file_dialog();
diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp
index 764e842539..55d025f675 100644
--- a/editor/debugger/editor_performance_profiler.cpp
+++ b/editor/debugger/editor_performance_profiler.cpp
@@ -136,7 +136,7 @@ void EditorPerformanceProfiler::_monitor_draw() {
monitor_draw->draw_string(graph_font, rect.position + Point2(0, graph_font->get_ascent(font_size)), current.item->get_text(0), HORIZONTAL_ALIGNMENT_LEFT, rect.size.x, font_size, draw_color);
draw_color.a = 0.9f;
- float value_position = rect.size.width - graph_font->get_string_size(current.item->get_text(1), font_size).width;
+ float value_position = rect.size.width - graph_font->get_string_size(current.item->get_text(1), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
if (value_position < 0) {
value_position = 0;
}
@@ -184,7 +184,7 @@ void EditorPerformanceProfiler::_monitor_draw() {
monitor_draw->draw_line(rect.position + Point2(from, 0), rect.position + Point2(from, rect.size.y), line_color, Math::round(EDSCALE));
String label = _create_label(e->get(), current.type);
- Size2 size = graph_font->get_string_size(label, font_size);
+ Size2 size = graph_font->get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
Vector2 text_top_left_position = Vector2(from, h2) - (size + Vector2(MARKER_MARGIN, MARKER_MARGIN));
if (text_top_left_position.x < 0) {
text_top_left_position.x = from + MARKER_MARGIN;
@@ -393,7 +393,7 @@ EditorPerformanceProfiler::EditorPerformanceProfiler() {
info_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
info_message->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
- info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ info_message->set_anchors_and_offsets_preset(PRESET_FULL_RECT, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
monitor_draw->add_child(info_message);
for (int i = 0; i < Performance::MONITOR_MAX; i++) {
diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp
index 1b1cdbd9ef..28b5d4be15 100644
--- a/editor/debugger/editor_profiler.cpp
+++ b/editor/debugger/editor_profiler.cpp
@@ -312,7 +312,7 @@ void EditorProfiler::_update_plot() {
if (graph_texture.is_null()) {
graph_texture.instantiate();
}
- graph_texture->create_from_image(img);
+ graph_texture->set_image(img);
}
graph_texture->update(img);
diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp
index 9def646f3f..ee67cbdaea 100644
--- a/editor/debugger/editor_visual_profiler.cpp
+++ b/editor/debugger/editor_visual_profiler.cpp
@@ -306,7 +306,7 @@ void EditorVisualProfiler::_update_plot() {
if (graph_texture.is_null()) {
graph_texture.instantiate();
}
- graph_texture->create_from_image(img);
+ graph_texture->set_image(img);
}
graph_texture->update(img);
@@ -469,7 +469,7 @@ void EditorVisualProfiler::_graph_tex_draw() {
graph->draw_line(Vector2(0, frame_y), Vector2(half_width, frame_y), color * Color(1, 1, 1, 0.5));
const String limit_str = String::num(graph_limit, 2) + " ms";
- graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1, 0.75));
+ graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1, 0.75));
}
if (graph_height_gpu > 0) {
@@ -480,11 +480,11 @@ void EditorVisualProfiler::_graph_tex_draw() {
graph->draw_line(Vector2(half_width, frame_y), Vector2(graph->get_size().x, frame_y), color * Color(1, 1, 1, 0.5));
const String limit_str = String::num(graph_limit, 2) + " ms";
- graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1, 0.75));
+ graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1, 0.75));
}
- graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x, font->get_ascent(font_size) + 2), "CPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1));
- graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x + graph->get_size().width / 2, font->get_ascent(font_size) + 2), "GPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1));
+ graph->draw_string(font, Vector2(font->get_string_size("X", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x, font->get_ascent(font_size) + 2), "CPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1));
+ graph->draw_string(font, Vector2(font->get_string_size("X", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x + graph->get_size().width / 2, font->get_ascent(font_size) + 2), "GPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, color * Color(1, 1, 1));
}
void EditorVisualProfiler::_graph_tex_mouse_exit() {
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index c209c67dcb..f8b82ecc51 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -428,6 +428,9 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
case RemoteDebugger::MESSAGE_TYPE_LOG: {
msg_type = EditorLog::MSG_TYPE_STD;
} break;
+ case RemoteDebugger::MESSAGE_TYPE_LOG_RICH: {
+ msg_type = EditorLog::MSG_TYPE_STD_RICH;
+ } break;
case RemoteDebugger::MESSAGE_TYPE_ERROR: {
msg_type = EditorLog::MSG_TYPE_ERROR;
} break;
@@ -1419,6 +1422,10 @@ bool ScriptEditorDebugger::is_skip_breakpoints() {
void ScriptEditorDebugger::_error_activated() {
TreeItem *selected = error_tree->get_selected();
+ if (!selected) {
+ return;
+ }
+
TreeItem *ci = selected->get_first_child();
if (ci) {
selected->set_collapsed(!selected->is_collapsed());
@@ -1427,6 +1434,11 @@ void ScriptEditorDebugger::_error_activated() {
void ScriptEditorDebugger::_error_selected() {
TreeItem *selected = error_tree->get_selected();
+
+ if (!selected) {
+ return;
+ }
+
Array meta = selected->get_metadata(0);
if (meta.size() == 0) {
return;
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index 9a1b2b5ff5..aa03b7e252 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -575,7 +575,7 @@ void DependencyRemoveDialog::_bind_methods() {
}
DependencyRemoveDialog::DependencyRemoveDialog() {
- get_ok_button()->set_text(TTR("Remove"));
+ set_ok_button_text(TTR("Remove"));
VBoxContainer *vb = memnew(VBoxContainer);
add_child(vb);
@@ -641,8 +641,8 @@ DependencyErrorDialog::DependencyErrorDialog() {
files->set_v_size_flags(Control::SIZE_EXPAND_FILL);
set_min_size(Size2(500, 220) * EDSCALE);
- get_ok_button()->set_text(TTR("Open Anyway"));
- get_cancel_button()->set_text(TTR("Close"));
+ set_ok_button_text(TTR("Open Anyway"));
+ set_cancel_button_text(TTR("Close"));
text = memnew(Label);
vb->add_child(text);
@@ -780,7 +780,7 @@ void OrphanResourcesDialog::_bind_methods() {
OrphanResourcesDialog::OrphanResourcesDialog() {
set_title(TTR("Orphan Resource Explorer"));
delete_confirm = memnew(ConfirmationDialog);
- get_ok_button()->set_text(TTR("Delete"));
+ set_ok_button_text(TTR("Delete"));
add_child(delete_confirm);
dep_edit = memnew(DependencyEditor);
add_child(dep_edit);
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index e6cd1e0b48..a6c7970264 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -178,6 +178,20 @@ void DocTools::merge_from(const DocTools &p_data) {
}
}
+ for (int i = 0; i < c.annotations.size(); i++) {
+ DocData::MethodDoc &m = c.annotations.write[i];
+
+ for (int j = 0; j < cf.annotations.size(); j++) {
+ if (cf.annotations[j].name != m.name) {
+ continue;
+ }
+ const DocData::MethodDoc &mf = cf.annotations[j];
+
+ m.description = mf.description;
+ break;
+ }
+ }
+
for (int i = 0; i < c.properties.size(); i++) {
DocData::PropertyDoc &p = c.properties.write[i];
@@ -429,7 +443,7 @@ void DocTools::generate(bool p_basic_types) {
PropertyInfo retinfo = mb->get_return_info();
found_type = true;
- if (retinfo.type == Variant::INT && retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (retinfo.type == Variant::INT && retinfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
prop.enumeration = retinfo.class_name;
prop.type = "int";
} else if (retinfo.class_name != StringName()) {
@@ -575,6 +589,7 @@ void DocTools::generate(bool p_basic_types) {
constant.value = itos(ClassDB::get_integer_constant(name, E));
constant.is_value_valid = true;
constant.enumeration = ClassDB::get_integer_constant_enum(name, E);
+ constant.is_bitfield = ClassDB::is_enum_bitfield(name, constant.enumeration);
c.constants.push_back(constant);
}
@@ -959,8 +974,41 @@ void DocTools::generate(bool p_basic_types) {
c.constants.push_back(cd);
}
+ // Get annotations.
+ List<MethodInfo> ainfo;
+ lang->get_public_annotations(&ainfo);
+
+ for (const MethodInfo &ai : ainfo) {
+ DocData::MethodDoc atd;
+ atd.name = ai.name;
+
+ if (ai.flags & METHOD_FLAG_VARARG) {
+ if (!atd.qualifiers.is_empty()) {
+ atd.qualifiers += " ";
+ }
+ atd.qualifiers += "vararg";
+ }
+
+ DocData::return_doc_from_retinfo(atd, ai.return_val);
+
+ for (int j = 0; j < ai.arguments.size(); j++) {
+ DocData::ArgumentDoc ad;
+ DocData::argument_doc_from_arginfo(ad, ai.arguments[j]);
+
+ int darg_idx = j - (ai.arguments.size() - ai.default_arguments.size());
+ if (darg_idx >= 0) {
+ Variant default_arg = ai.default_arguments[darg_idx];
+ ad.default_value = default_arg.get_construct_string().replace("\n", " ");
+ }
+
+ atd.arguments.push_back(ad);
+ }
+
+ c.annotations.push_back(atd);
+ }
+
// Skip adding the lang if it doesn't expose anything (e.g. C#).
- if (c.methods.is_empty() && c.constants.is_empty()) {
+ if (c.methods.is_empty() && c.constants.is_empty() && c.annotations.is_empty()) {
continue;
}
@@ -1162,6 +1210,9 @@ Error DocTools::_load(Ref<XMLParser> parser) {
} else if (name2 == "signals") {
Error err2 = _parse_methods(parser, c.signals);
ERR_FAIL_COND_V(err2, err2);
+ } else if (name2 == "annotations") {
+ Error err2 = _parse_methods(parser, c.annotations);
+ ERR_FAIL_COND_V(err2, err2);
} else if (name2 == "members") {
while (parser->read() == OK) {
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
@@ -1244,6 +1295,9 @@ Error DocTools::_load(Ref<XMLParser> parser) {
if (parser->has_attribute("enum")) {
constant2.enumeration = parser->get_attribute_value("enum");
}
+ if (parser->has_attribute("is_bitfield")) {
+ constant2.is_bitfield = parser->get_attribute_value("is_bitfield").to_lower() == "true";
+ }
if (!parser->is_empty()) {
parser->read();
if (parser->get_node_type() == XMLParser::NODE_TEXT) {
@@ -1424,7 +1478,11 @@ Error DocTools::save_classes(const String &p_default_path, const HashMap<String,
const DocData::ConstantDoc &k = c.constants[i];
if (k.is_value_valid) {
if (!k.enumeration.is_empty()) {
- _write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
+ if (k.is_bitfield) {
+ _write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\" is_bitfield=\"true\">");
+ } else {
+ _write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
+ }
} else {
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\">");
}
@@ -1442,6 +1500,8 @@ Error DocTools::save_classes(const String &p_default_path, const HashMap<String,
_write_string(f, 1, "</constants>");
}
+ _write_method_doc(f, "annotation", c.annotations);
+
if (!c.theme_properties.is_empty()) {
c.theme_properties.sort();
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index ef29448854..3d4bee4b4e 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -355,7 +355,7 @@ EditorAssetInstaller::EditorAssetInstaller() {
error = memnew(AcceptDialog);
add_child(error);
- get_ok_button()->set_text(TTR("Install"));
+ set_ok_button_text(TTR("Install"));
set_title(TTR("Asset Installer"));
set_hide_on_ok(true);
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 89dc106717..fa365c4368 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -1332,7 +1332,7 @@ EditorAudioBuses::EditorAudioBuses() {
List<String> ext;
ResourceLoader::get_recognized_extensions_for_type("AudioBusLayout", &ext);
for (const String &E : ext) {
- file_dialog->add_filter(vformat("*.%s; %s", E, TTR("Audio Bus Layout")));
+ file_dialog->add_filter("*." + E, TTR("Audio Bus Layout"));
}
add_child(file_dialog);
file_dialog->connect("file_selected", callable_mp(this, &EditorAudioBuses::_file_dialog_callback));
@@ -1394,7 +1394,7 @@ Size2 EditorAudioMeterNotches::get_minimum_size() const {
for (int i = 0; i < notches.size(); i++) {
if (notches[i].render_db_value) {
- width = MAX(width, font->get_string_size(String::num(Math::abs(notches[i].db_value)) + "dB", font_size).x);
+ width = MAX(width, font->get_string_size(String::num(Math::abs(notches[i].db_value)) + "dB", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x);
height += font_height;
}
}
diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp
new file mode 100644
index 0000000000..6a5604290f
--- /dev/null
+++ b/editor/editor_build_profile.cpp
@@ -0,0 +1,797 @@
+/*************************************************************************/
+/* editor_build_profile.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "editor_build_profile.h"
+
+#include "core/io/dir_access.h"
+#include "core/io/json.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_file_system.h"
+#include "editor/editor_node.h"
+#include "editor/editor_property_name_processor.h"
+#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
+
+const char *EditorBuildProfile::build_option_identifiers[BUILD_OPTION_MAX] = {
+ // This maps to SCons build options.
+ "disable_3d",
+ "disable_2d_physics",
+ "disable_3d_physics",
+ "disable_navigation",
+ "openxr",
+ "opengl3",
+ "vulkan",
+};
+
+const bool EditorBuildProfile::build_option_disable_values[BUILD_OPTION_MAX] = {
+ // This maps to SCons build options.
+ true,
+ true,
+ true,
+ true,
+ false,
+ false,
+ false
+};
+
+void EditorBuildProfile::set_disable_class(const StringName &p_class, bool p_disabled) {
+ if (p_disabled) {
+ disabled_classes.insert(p_class);
+ } else {
+ disabled_classes.erase(p_class);
+ }
+}
+
+bool EditorBuildProfile::is_class_disabled(const StringName &p_class) const {
+ if (p_class == StringName()) {
+ return false;
+ }
+ return disabled_classes.has(p_class) || is_class_disabled(ClassDB::get_parent_class_nocheck(p_class));
+}
+
+void EditorBuildProfile::set_item_collapsed(const StringName &p_class, bool p_collapsed) {
+ if (p_collapsed) {
+ collapsed_classes.insert(p_class);
+ } else {
+ collapsed_classes.erase(p_class);
+ }
+}
+
+bool EditorBuildProfile::is_item_collapsed(const StringName &p_class) const {
+ return collapsed_classes.has(p_class);
+}
+
+void EditorBuildProfile::set_disable_build_option(BuildOption p_build_option, bool p_disable) {
+ ERR_FAIL_INDEX(p_build_option, BUILD_OPTION_MAX);
+ build_options_disabled[p_build_option] = p_disable;
+}
+
+void EditorBuildProfile::clear_disabled_classes() {
+ disabled_classes.clear();
+ collapsed_classes.clear();
+}
+
+bool EditorBuildProfile::is_build_option_disabled(BuildOption p_build_option) const {
+ ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, false);
+ return build_options_disabled[p_build_option];
+}
+
+bool EditorBuildProfile::get_build_option_disable_value(BuildOption p_build_option) {
+ ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, false);
+ return build_option_disable_values[p_build_option];
+}
+
+void EditorBuildProfile::set_force_detect_classes(const String &p_classes) {
+ force_detect_classes = p_classes;
+}
+
+String EditorBuildProfile::get_force_detect_classes() const {
+ return force_detect_classes;
+}
+
+String EditorBuildProfile::get_build_option_name(BuildOption p_build_option) {
+ ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, String());
+ const char *build_option_names[BUILD_OPTION_MAX] = {
+ TTRC("3D Engine"),
+ TTRC("2D Physics"),
+ TTRC("3D Physics"),
+ TTRC("Navigation"),
+ TTRC("XR"),
+ TTRC("RenderingDevice"),
+ TTRC("OpenGL"),
+ TTRC("Vulkan"),
+ };
+ return TTRGET(build_option_names[p_build_option]);
+}
+
+String EditorBuildProfile::get_build_option_description(BuildOption p_build_option) {
+ ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, String());
+
+ const char *build_option_descriptions[BUILD_OPTION_MAX] = {
+ TTRC("3D Nodes as well as RenderingServer access to 3D features."),
+ TTRC("2D Physics nodes and PhysicsServer2D."),
+ TTRC("3D Physics nodes and PhysicsServer3D."),
+ TTRC("Navigation, both 2D and 3D."),
+ TTRC("XR (AR and VR)."),
+ TTRC("RenderingDevice based rendering (if disabled, the OpenGL back-end is required)."),
+ TTRC("OpenGL back-end (if disabled, the RenderingDevice back-end is required)."),
+ TTRC("Vulkan back-end of RenderingDevice."),
+ };
+
+ return TTRGET(build_option_descriptions[p_build_option]);
+}
+
+Error EditorBuildProfile::save_to_file(const String &p_path) {
+ Dictionary data;
+ data["type"] = "build_profile";
+ Array dis_classes;
+ for (const StringName &E : disabled_classes) {
+ dis_classes.push_back(String(E));
+ }
+ dis_classes.sort();
+ data["disabled_classes"] = dis_classes;
+
+ Dictionary dis_build_options;
+ for (int i = 0; i < BUILD_OPTION_MAX; i++) {
+ if (build_options_disabled[i]) {
+ dis_build_options[build_option_identifiers[i]] = build_option_disable_values[i];
+ }
+ }
+
+ data["disabled_build_options"] = dis_build_options;
+
+ if (!force_detect_classes.is_empty()) {
+ data["force_detect_classes"] = force_detect_classes;
+ }
+
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE);
+ ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_CREATE, "Cannot create file '" + p_path + "'.");
+
+ JSON json;
+ String text = json.stringify(data, "\t");
+ f->store_string(text);
+ return OK;
+}
+
+Error EditorBuildProfile::load_from_file(const String &p_path) {
+ Error err;
+ String text = FileAccess::get_file_as_string(p_path, &err);
+ if (err != OK) {
+ return err;
+ }
+
+ JSON json;
+ err = json.parse(text);
+ if (err != OK) {
+ ERR_PRINT("Error parsing '" + p_path + "' on line " + itos(json.get_error_line()) + ": " + json.get_error_message());
+ return ERR_PARSE_ERROR;
+ }
+
+ Dictionary data = json.get_data();
+
+ if (!data.has("type") || String(data["type"]) != "build_profile") {
+ ERR_PRINT("Error parsing '" + p_path + "', it's not a build profile.");
+ return ERR_PARSE_ERROR;
+ }
+
+ disabled_classes.clear();
+
+ if (data.has("disabled_classes")) {
+ Array disabled_classes_arr = data["disabled_classes"];
+ for (int i = 0; i < disabled_classes_arr.size(); i++) {
+ disabled_classes.insert(disabled_classes_arr[i]);
+ }
+ }
+
+ for (int i = 0; i < BUILD_OPTION_MAX; i++) {
+ build_options_disabled[i] = false;
+ }
+
+ if (data.has("disabled_build_options")) {
+ Dictionary disabled_build_options_arr = data["disabled_build_options"];
+ List<Variant> keys;
+ disabled_build_options_arr.get_key_list(&keys);
+
+ for (const Variant &K : keys) {
+ String key = K;
+
+ for (int i = 0; i < BUILD_OPTION_MAX; i++) {
+ String f = build_option_identifiers[i];
+ if (f == key) {
+ build_options_disabled[i] = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (data.has("force_detect_classes")) {
+ force_detect_classes = data["force_detect_classes"];
+ }
+
+ return OK;
+}
+
+void EditorBuildProfile::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_disable_class", "class_name", "disable"), &EditorBuildProfile::set_disable_class);
+ ClassDB::bind_method(D_METHOD("is_class_disabled", "class_name"), &EditorBuildProfile::is_class_disabled);
+
+ ClassDB::bind_method(D_METHOD("set_disable_build_option", "build_option", "disable"), &EditorBuildProfile::set_disable_build_option);
+ ClassDB::bind_method(D_METHOD("is_build_option_disabled", "build_option"), &EditorBuildProfile::is_build_option_disabled);
+
+ ClassDB::bind_method(D_METHOD("get_build_option_name", "build_option"), &EditorBuildProfile::_get_build_option_name);
+
+ ClassDB::bind_method(D_METHOD("save_to_file", "path"), &EditorBuildProfile::save_to_file);
+ ClassDB::bind_method(D_METHOD("load_from_file", "path"), &EditorBuildProfile::load_from_file);
+
+ BIND_ENUM_CONSTANT(BUILD_OPTION_3D);
+ BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_2D);
+ BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_3D);
+ BIND_ENUM_CONSTANT(BUILD_OPTION_NAVIGATION);
+ BIND_ENUM_CONSTANT(BUILD_OPTION_XR);
+ BIND_ENUM_CONSTANT(BUILD_OPTION_RENDERING_DEVICE);
+ BIND_ENUM_CONSTANT(BUILD_OPTION_OPENGL);
+ BIND_ENUM_CONSTANT(BUILD_OPTION_VULKAN);
+ BIND_ENUM_CONSTANT(BUILD_OPTION_MAX);
+}
+
+EditorBuildProfile::EditorBuildProfile() {}
+
+//////////////////////////
+
+void EditorBuildProfileManager::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ String last_file = EditorSettings::get_singleton()->get_project_metadata("build_profile", "last_file_path", "");
+ if (!last_file.is_empty()) {
+ _import_profile(last_file);
+ }
+ if (edited.is_null()) {
+ edited.instantiate();
+ _update_edited_profile();
+ }
+
+ } break;
+ }
+}
+
+void EditorBuildProfileManager::_profile_action(int p_action) {
+ last_action = Action(p_action);
+
+ switch (p_action) {
+ case ACTION_RESET: {
+ confirm_dialog->set_text("Reset the edited profile?");
+ confirm_dialog->popup_centered();
+ } break;
+ case ACTION_LOAD: {
+ import_profile->popup_file_dialog();
+ } break;
+ case ACTION_SAVE: {
+ if (!profile_path->get_text().is_empty()) {
+ Error err = edited->save_to_file(profile_path->get_text());
+ if (err != OK) {
+ EditorNode::get_singleton()->show_warning(TTR("File saving failed."));
+ }
+ break;
+ }
+ [[fallthrough]];
+ }
+ case ACTION_SAVE_AS: {
+ export_profile->popup_file_dialog();
+ export_profile->set_current_file(profile_path->get_text());
+ } break;
+ case ACTION_NEW: {
+ confirm_dialog->set_text("Create a new profile?");
+ confirm_dialog->popup_centered();
+ } break;
+ case ACTION_DETECT: {
+ confirm_dialog->set_text("This will scan all files in the current project to detect used classes.");
+ confirm_dialog->popup_centered();
+ } break;
+ case ACTION_MAX: {
+ } break;
+ }
+}
+
+void EditorBuildProfileManager::_find_files(EditorFileSystemDirectory *p_dir, const HashMap<String, DetectedFile> &p_cache, HashMap<String, DetectedFile> &r_detected) {
+ if (p_dir == nullptr) {
+ return;
+ }
+
+ for (int i = 0; i < p_dir->get_file_count(); i++) {
+ String p = p_dir->get_file_path(i);
+
+ uint64_t timestamp = 0;
+ String md5;
+
+ if (p_cache.has(p)) {
+ const DetectedFile &cache = p_cache[p];
+ // Check if timestamp and MD5 match.
+ timestamp = FileAccess::get_modified_time(p);
+ bool cache_valid = true;
+ if (cache.timestamp != timestamp) {
+ md5 = FileAccess::get_md5(p);
+ if (md5 != cache.md5) {
+ cache_valid = false;
+ }
+ }
+
+ if (cache_valid) {
+ r_detected.insert(p, cache);
+ continue;
+ }
+ }
+
+ // Not cached, or cache invalid.
+
+ DetectedFile cache;
+
+ HashSet<StringName> classes;
+ ResourceLoader::get_classes_used(p, &classes);
+
+ for (const StringName &E : classes) {
+ cache.classes.push_back(E);
+ }
+
+ if (md5.is_empty()) {
+ cache.timestamp = FileAccess::get_modified_time(p);
+ cache.md5 = FileAccess::get_md5(p);
+ } else {
+ cache.timestamp = timestamp;
+ cache.md5 = md5;
+ }
+
+ r_detected.insert(p, cache);
+ }
+
+ for (int i = 0; i < p_dir->get_subdir_count(); i++) {
+ _find_files(p_dir->get_subdir(i), p_cache, r_detected);
+ }
+}
+
+void EditorBuildProfileManager::_detect_classes() {
+ HashMap<String, DetectedFile> previous_file_cache;
+
+ Ref<FileAccess> f = FileAccess::open("res://.godot/editor/used_class_cache", FileAccess::READ);
+ if (f.is_valid()) {
+ while (!f->eof_reached()) {
+ String l = f->get_line();
+ Vector<String> fields = l.split("::");
+ if (fields.size() == 4) {
+ String path = fields[0];
+ DetectedFile df;
+ df.timestamp = fields[1].to_int();
+ df.md5 = fields[2];
+ df.classes = fields[3].split(",");
+ previous_file_cache.insert(path, df);
+ }
+ }
+ f.unref();
+ }
+
+ HashMap<String, DetectedFile> updated_file_cache;
+
+ _find_files(EditorFileSystem::get_singleton()->get_filesystem(), previous_file_cache, updated_file_cache);
+
+ HashSet<StringName> used_classes;
+
+ // Find classes and update the disk cache in the process.
+ f = FileAccess::open("res://.godot/editor/used_class_cache", FileAccess::WRITE);
+
+ for (const KeyValue<String, DetectedFile> &E : updated_file_cache) {
+ String l = E.key + "::" + itos(E.value.timestamp) + "::" + E.value.md5 + "::";
+ for (int i = 0; i < E.value.classes.size(); i++) {
+ String c = E.value.classes[i];
+ if (i > 0) {
+ l += ",";
+ }
+ l += c;
+ used_classes.insert(c);
+ }
+ f->store_line(l);
+ }
+
+ f.unref();
+
+ // Add forced ones.
+
+ Vector<String> force_detect = edited->get_force_detect_classes().split(",");
+ for (int i = 0; i < force_detect.size(); i++) {
+ String c = force_detect[i].strip_edges();
+ if (c.is_empty()) {
+ continue;
+ }
+ used_classes.insert(c);
+ }
+
+ // Filter all classes to discard inherited ones.
+
+ HashSet<StringName> all_used_classes;
+
+ for (const StringName &E : used_classes) {
+ StringName c = E;
+ if (!ClassDB::class_exists(c)) {
+ // Maybe this is an old class that got replaced? try getting compat class.
+ c = ClassDB::get_compatibility_class(c);
+ if (!c) {
+ // No luck, skip.
+ continue;
+ }
+ }
+ while (c) {
+ all_used_classes.insert(c);
+ c = ClassDB::get_parent_class(c);
+ }
+ }
+
+ edited->clear_disabled_classes();
+
+ List<StringName> all_classes;
+ ClassDB::get_class_list(&all_classes);
+
+ for (const StringName &E : all_classes) {
+ if (all_used_classes.has(E)) {
+ // This class is valid, do nothing.
+ continue;
+ }
+
+ StringName p = ClassDB::get_parent_class(E);
+ if (!p || all_used_classes.has(p)) {
+ // If no parent, or if the parent is enabled, then add to disabled classes.
+ // This way we avoid disabling redundant classes.
+ edited->set_disable_class(E, true);
+ }
+ }
+}
+
+void EditorBuildProfileManager::_action_confirm() {
+ switch (last_action) {
+ case ACTION_RESET: {
+ edited.instantiate();
+ _update_edited_profile();
+ } break;
+ case ACTION_LOAD: {
+ } break;
+ case ACTION_SAVE: {
+ } break;
+ case ACTION_SAVE_AS: {
+ } break;
+ case ACTION_NEW: {
+ profile_path->set_text("");
+ edited.instantiate();
+ _update_edited_profile();
+ } break;
+ case ACTION_DETECT: {
+ _detect_classes();
+ _update_edited_profile();
+ } break;
+ case ACTION_MAX: {
+ } break;
+ }
+}
+
+void EditorBuildProfileManager::_fill_classes_from(TreeItem *p_parent, const String &p_class, const String &p_selected) {
+ TreeItem *class_item = class_list->create_item(p_parent);
+ class_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
+ class_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_class, "Node"));
+ String text = p_class;
+
+ bool disabled = edited->is_class_disabled(p_class);
+ if (disabled) {
+ class_item->set_custom_color(0, class_list->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
+ }
+
+ class_item->set_text(0, text);
+ class_item->set_editable(0, true);
+ class_item->set_selectable(0, true);
+ class_item->set_metadata(0, p_class);
+
+ bool collapsed = edited->is_item_collapsed(p_class);
+ class_item->set_collapsed(collapsed);
+
+ if (p_class == p_selected) {
+ class_item->select(0);
+ }
+ if (disabled) {
+ // Class disabled, do nothing else (do not show further).
+ return;
+ }
+
+ class_item->set_checked(0, true); // If it's not disabled, its checked.
+
+ List<StringName> child_classes;
+ ClassDB::get_direct_inheriters_from_class(p_class, &child_classes);
+ child_classes.sort_custom<StringName::AlphCompare>();
+
+ for (const StringName &name : child_classes) {
+ if (String(name).begins_with("Editor") || ClassDB::get_api_type(name) != ClassDB::API_CORE) {
+ continue;
+ }
+ _fill_classes_from(class_item, name, p_selected);
+ }
+}
+
+void EditorBuildProfileManager::_class_list_item_selected() {
+ if (updating_build_options) {
+ return;
+ }
+
+ TreeItem *item = class_list->get_selected();
+ if (!item) {
+ return;
+ }
+
+ Variant md = item->get_metadata(0);
+ if (md.get_type() == Variant::STRING || md.get_type() == Variant::STRING_NAME) {
+ String class_name = md;
+ String class_description;
+
+ DocTools *dd = EditorHelp::get_doc_data();
+ HashMap<String, DocData::ClassDoc>::Iterator E = dd->class_list.find(class_name);
+ if (E) {
+ class_description = DTR(E->value.brief_description);
+ }
+
+ description_bit->set_text(class_description);
+ } else if (md.get_type() == Variant::INT) {
+ int build_option_id = md;
+ String build_option_description = EditorBuildProfile::get_build_option_description(EditorBuildProfile::BuildOption(build_option_id));
+
+ description_bit->set_text(TTRGET(build_option_description));
+ return;
+ } else {
+ return;
+ }
+}
+
+void EditorBuildProfileManager::_class_list_item_edited() {
+ if (updating_build_options) {
+ return;
+ }
+
+ TreeItem *item = class_list->get_edited();
+ if (!item) {
+ return;
+ }
+
+ bool checked = item->is_checked(0);
+
+ Variant md = item->get_metadata(0);
+ if (md.get_type() == Variant::STRING || md.get_type() == Variant::STRING_NAME) {
+ String class_selected = md;
+ edited->set_disable_class(class_selected, !checked);
+ _update_edited_profile();
+ } else if (md.get_type() == Variant::INT) {
+ int build_option_selected = md;
+ edited->set_disable_build_option(EditorBuildProfile::BuildOption(build_option_selected), !checked);
+ }
+}
+
+void EditorBuildProfileManager::_class_list_item_collapsed(Object *p_item) {
+ if (updating_build_options) {
+ return;
+ }
+
+ TreeItem *item = Object::cast_to<TreeItem>(p_item);
+ if (!item) {
+ return;
+ }
+
+ Variant md = item->get_metadata(0);
+ if (md.get_type() != Variant::STRING && md.get_type() != Variant::STRING_NAME) {
+ return;
+ }
+
+ String class_name = md;
+ bool collapsed = item->is_collapsed();
+ edited->set_item_collapsed(class_name, collapsed);
+}
+
+void EditorBuildProfileManager::_update_edited_profile() {
+ String class_selected;
+ int build_option_selected = -1;
+
+ if (class_list->get_selected()) {
+ Variant md = class_list->get_selected()->get_metadata(0);
+ if (md.get_type() == Variant::STRING || md.get_type() == Variant::STRING_NAME) {
+ class_selected = md;
+ } else if (md.get_type() == Variant::INT) {
+ build_option_selected = md;
+ }
+ }
+
+ class_list->clear();
+
+ updating_build_options = true;
+
+ TreeItem *root = class_list->create_item();
+
+ TreeItem *build_options = class_list->create_item(root);
+ build_options->set_text(0, TTR("General Features:"));
+ for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_MAX; i++) {
+ TreeItem *build_option;
+ build_option = class_list->create_item(build_options);
+
+ build_option->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
+ build_option->set_text(0, EditorBuildProfile::get_build_option_name(EditorBuildProfile::BuildOption(i)));
+ build_option->set_selectable(0, true);
+ build_option->set_editable(0, true);
+ build_option->set_metadata(0, i);
+ if (!edited->is_build_option_disabled(EditorBuildProfile::BuildOption(i))) {
+ build_option->set_checked(0, true);
+ }
+
+ if (i == build_option_selected) {
+ build_option->select(0);
+ }
+ }
+
+ TreeItem *classes = class_list->create_item(root);
+ classes->set_text(0, TTR("Nodes and Classes:"));
+
+ _fill_classes_from(classes, "Node", class_selected);
+ _fill_classes_from(classes, "Resource", class_selected);
+
+ force_detect_classes->set_text(edited->get_force_detect_classes());
+
+ updating_build_options = false;
+
+ _class_list_item_selected();
+}
+
+void EditorBuildProfileManager::_force_detect_classes_changed(const String &p_text) {
+ if (updating_build_options) {
+ return;
+ }
+ edited->set_force_detect_classes(force_detect_classes->get_text());
+}
+
+void EditorBuildProfileManager::_import_profile(const String &p_path) {
+ Ref<EditorBuildProfile> profile;
+ profile.instantiate();
+ Error err = profile->load_from_file(p_path);
+ String basefile = p_path.get_file();
+ if (err != OK) {
+ EditorNode::get_singleton()->show_warning(vformat(TTR("File '%s' format is invalid, import aborted."), basefile));
+ return;
+ }
+
+ profile_path->set_text(p_path);
+ EditorSettings::get_singleton()->set_project_metadata("build_profile", "last_file_path", p_path);
+
+ edited = profile;
+ _update_edited_profile();
+}
+
+void EditorBuildProfileManager::_export_profile(const String &p_path) {
+ ERR_FAIL_COND(edited.is_null());
+ Error err = edited->save_to_file(p_path);
+ if (err != OK) {
+ EditorNode::get_singleton()->show_warning(vformat(TTR("Error saving profile to path: '%s'."), p_path));
+ } else {
+ profile_path->set_text(p_path);
+ EditorSettings::get_singleton()->set_project_metadata("build_profile", "last_file_path", p_path);
+ }
+}
+
+Ref<EditorBuildProfile> EditorBuildProfileManager::get_current_profile() {
+ return edited;
+}
+
+EditorBuildProfileManager *EditorBuildProfileManager::singleton = nullptr;
+
+void EditorBuildProfileManager::_bind_methods() {
+ ClassDB::bind_method("_update_selected_profile", &EditorBuildProfileManager::_update_edited_profile);
+}
+
+EditorBuildProfileManager::EditorBuildProfileManager() {
+ VBoxContainer *main_vbc = memnew(VBoxContainer);
+ add_child(main_vbc);
+
+ HBoxContainer *path_hbc = memnew(HBoxContainer);
+ profile_path = memnew(LineEdit);
+ path_hbc->add_child(profile_path);
+ profile_path->set_editable(true);
+ profile_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+
+ profile_actions[ACTION_NEW] = memnew(Button(TTR("New")));
+ path_hbc->add_child(profile_actions[ACTION_NEW]);
+ profile_actions[ACTION_NEW]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_NEW));
+
+ profile_actions[ACTION_LOAD] = memnew(Button(TTR("Load")));
+ path_hbc->add_child(profile_actions[ACTION_LOAD]);
+ profile_actions[ACTION_LOAD]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_LOAD));
+
+ profile_actions[ACTION_SAVE] = memnew(Button(TTR("Save")));
+ path_hbc->add_child(profile_actions[ACTION_SAVE]);
+ profile_actions[ACTION_SAVE]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_SAVE));
+
+ profile_actions[ACTION_SAVE_AS] = memnew(Button(TTR("Save As")));
+ path_hbc->add_child(profile_actions[ACTION_SAVE_AS]);
+ profile_actions[ACTION_SAVE_AS]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_SAVE_AS));
+
+ main_vbc->add_margin_child(TTR("Profile:"), path_hbc);
+
+ main_vbc->add_child(memnew(HSeparator));
+
+ HBoxContainer *profiles_hbc = memnew(HBoxContainer);
+
+ profile_actions[ACTION_RESET] = memnew(Button(TTR("Reset to Defaults")));
+ profiles_hbc->add_child(profile_actions[ACTION_RESET]);
+ profile_actions[ACTION_RESET]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_RESET));
+
+ profile_actions[ACTION_DETECT] = memnew(Button(TTR("Detect from Project")));
+ profiles_hbc->add_child(profile_actions[ACTION_DETECT]);
+ profile_actions[ACTION_DETECT]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_DETECT));
+
+ main_vbc->add_margin_child(TTR("Actions:"), profiles_hbc);
+
+ class_list = memnew(Tree);
+ class_list->set_hide_root(true);
+ class_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true);
+ class_list->connect("cell_selected", callable_mp(this, &EditorBuildProfileManager::_class_list_item_selected));
+ class_list->connect("item_edited", callable_mp(this, &EditorBuildProfileManager::_class_list_item_edited), varray(), CONNECT_DEFERRED);
+ class_list->connect("item_collapsed", callable_mp(this, &EditorBuildProfileManager::_class_list_item_collapsed));
+ // It will be displayed once the user creates or chooses a profile.
+ main_vbc->add_margin_child(TTR("Configure Engine Build Profile:"), class_list, true);
+
+ description_bit = memnew(EditorHelpBit);
+ description_bit->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
+ main_vbc->add_margin_child(TTR("Description:"), description_bit, false);
+
+ confirm_dialog = memnew(ConfirmationDialog);
+ add_child(confirm_dialog);
+ confirm_dialog->set_title(TTR("Please Confirm:"));
+ confirm_dialog->connect("confirmed", callable_mp(this, &EditorBuildProfileManager::_action_confirm));
+
+ import_profile = memnew(EditorFileDialog);
+ add_child(import_profile);
+ import_profile->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
+ import_profile->add_filter("*.build", TTR("Egine Build Profile"));
+ import_profile->connect("files_selected", callable_mp(this, &EditorBuildProfileManager::_import_profile));
+ import_profile->set_title(TTR("Load Profile"));
+ import_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+
+ export_profile = memnew(EditorFileDialog);
+ add_child(export_profile);
+ export_profile->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
+ export_profile->add_filter("*.build", TTR("Egine Build Profile"));
+ export_profile->connect("file_selected", callable_mp(this, &EditorBuildProfileManager::_export_profile));
+ export_profile->set_title(TTR("Export Profile"));
+ export_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+
+ force_detect_classes = memnew(LineEdit);
+ main_vbc->add_margin_child(TTR("Forced classes on detect:"), force_detect_classes);
+ force_detect_classes->connect("text_changed", callable_mp(this, &EditorBuildProfileManager::_force_detect_classes_changed));
+
+ set_title(TTR("Edit Build Configuration Profile"));
+
+ singleton = this;
+}
diff --git a/editor/editor_build_profile.h b/editor/editor_build_profile.h
new file mode 100644
index 0000000000..bb6494b8c9
--- /dev/null
+++ b/editor/editor_build_profile.h
@@ -0,0 +1,173 @@
+/*************************************************************************/
+/* editor_build_profile.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef EDITOR_BUILD_PROFILE_H
+#define EDITOR_BUILD_PROFILE_H
+
+#include "core/io/file_access.h"
+#include "core/object/ref_counted.h"
+#include "editor/editor_help.h"
+#include "scene/gui/dialogs.h"
+#include "scene/gui/option_button.h"
+#include "scene/gui/separator.h"
+#include "scene/gui/split_container.h"
+#include "scene/gui/tree.h"
+
+class EditorBuildProfile : public RefCounted {
+ GDCLASS(EditorBuildProfile, RefCounted);
+
+public:
+ enum BuildOption {
+ BUILD_OPTION_3D,
+ BUILD_OPTION_PHYSICS_2D,
+ BUILD_OPTION_PHYSICS_3D,
+ BUILD_OPTION_NAVIGATION,
+ BUILD_OPTION_XR,
+ BUILD_OPTION_RENDERING_DEVICE,
+ BUILD_OPTION_OPENGL,
+ BUILD_OPTION_VULKAN,
+ BUILD_OPTION_MAX
+ };
+
+private:
+ HashSet<StringName> disabled_classes;
+
+ HashSet<StringName> collapsed_classes;
+
+ String force_detect_classes;
+
+ bool build_options_disabled[BUILD_OPTION_MAX] = {};
+ static const char *build_option_identifiers[BUILD_OPTION_MAX];
+ static const bool build_option_disable_values[BUILD_OPTION_MAX];
+
+ String _get_build_option_name(BuildOption p_build_option) { return get_build_option_name(p_build_option); }
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_disable_class(const StringName &p_class, bool p_disabled);
+ bool is_class_disabled(const StringName &p_class) const;
+
+ void set_item_collapsed(const StringName &p_class, bool p_collapsed);
+ bool is_item_collapsed(const StringName &p_class) const;
+
+ void set_disable_build_option(BuildOption p_build_option, bool p_disable);
+ bool is_build_option_disabled(BuildOption p_build_option) const;
+
+ void set_force_detect_classes(const String &p_classes);
+ String get_force_detect_classes() const;
+
+ void clear_disabled_classes();
+
+ Error save_to_file(const String &p_path);
+ Error load_from_file(const String &p_path);
+
+ static String get_build_option_name(BuildOption p_build_option);
+ static String get_build_option_description(BuildOption p_build_option);
+ static bool get_build_option_disable_value(BuildOption p_build_option);
+
+ EditorBuildProfile();
+};
+
+VARIANT_ENUM_CAST(EditorBuildProfile::BuildOption)
+
+class EditorFileSystemDirectory;
+
+class EditorBuildProfileManager : public AcceptDialog {
+ GDCLASS(EditorBuildProfileManager, AcceptDialog);
+
+ enum Action {
+ ACTION_NEW,
+ ACTION_RESET,
+ ACTION_LOAD,
+ ACTION_SAVE,
+ ACTION_SAVE_AS,
+ ACTION_DETECT,
+ ACTION_MAX
+ };
+
+ Action last_action = ACTION_NEW;
+
+ ConfirmationDialog *confirm_dialog = nullptr;
+ Button *profile_actions[ACTION_MAX];
+
+ Tree *class_list = nullptr;
+ EditorHelpBit *description_bit = nullptr;
+
+ EditorFileDialog *import_profile = nullptr;
+ EditorFileDialog *export_profile = nullptr;
+
+ LineEdit *profile_path = nullptr;
+
+ LineEdit *force_detect_classes = nullptr;
+
+ void _profile_action(int p_action);
+ void _action_confirm();
+
+ void _update_edited_profile();
+ void _fill_classes_from(TreeItem *p_parent, const String &p_class, const String &p_selected);
+
+ Ref<EditorBuildProfile> edited;
+
+ void _import_profile(const String &p_path);
+ void _export_profile(const String &p_path);
+
+ bool updating_build_options = false;
+
+ void _class_list_item_selected();
+ void _class_list_item_edited();
+ void _class_list_item_collapsed(Object *p_item);
+ void _detect_classes();
+
+ void _force_detect_classes_changed(const String &p_text);
+
+ struct DetectedFile {
+ uint32_t timestamp = 0;
+ String md5;
+ Vector<String> classes;
+ };
+
+ void _find_files(EditorFileSystemDirectory *p_dir, const HashMap<String, DetectedFile> &p_cache, HashMap<String, DetectedFile> &r_detected);
+
+ static EditorBuildProfileManager *singleton;
+
+protected:
+ static void _bind_methods();
+ void _notification(int p_what);
+
+public:
+ Ref<EditorBuildProfile> get_current_profile();
+
+ static EditorBuildProfileManager *get_singleton() { return singleton; }
+ EditorBuildProfileManager();
+};
+
+#endif // EDITOR_BUILD_PROFILE_H
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 64c234a07c..e9e3320a3d 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -534,6 +534,7 @@ void EditorData::remove_scene(int p_idx) {
}
memdelete(edited_scene[p_idx].root);
+ edited_scene.write[p_idx].root = nullptr;
}
if (current_edited_scene > p_idx) {
diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp
index 8494991892..4cbc0cf25d 100644
--- a/editor/editor_dir_dialog.cpp
+++ b/editor/editor_dir_dialog.cpp
@@ -211,5 +211,5 @@ EditorDirDialog::EditorDirDialog() {
mkdirerr->set_text(TTR("Could not create folder."));
add_child(mkdirerr);
- get_ok_button()->set_text(TTR("Choose"));
+ set_ok_button_text(TTR("Choose"));
}
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index bb9d930cf5..46907bdf8a 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -272,7 +272,7 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
} else {
p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
p_log->add_text(" ");
- p_log->add_text(TTR("Completed sucessfully."));
+ p_log->add_text(TTR("Completed successfully."));
if (msg_count > 0) {
has_messages = true;
}
@@ -491,7 +491,7 @@ Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const {
String EditorExportPlatform::find_export_template(String template_file_name, String *err) const {
String current_version = VERSION_FULL_CONFIG;
- String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(current_version).plus_file(template_file_name);
+ String template_path = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(current_version).plus_file(template_file_name);
if (FileAccess::exists(template_path)) {
return template_path;
@@ -698,12 +698,12 @@ String EditorExportPlugin::get_ios_cpp_code() const {
return ios_cpp_code;
}
-void EditorExportPlugin::add_osx_plugin_file(const String &p_path) {
- osx_plugin_files.push_back(p_path);
+void EditorExportPlugin::add_macos_plugin_file(const String &p_path) {
+ macos_plugin_files.push_back(p_path);
}
-const Vector<String> &EditorExportPlugin::get_osx_plugin_files() const {
- return osx_plugin_files;
+const Vector<String> &EditorExportPlugin::get_macos_plugin_files() const {
+ return macos_plugin_files;
}
void EditorExportPlugin::add_ios_project_static_lib(const String &p_path) {
@@ -746,7 +746,7 @@ void EditorExportPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_ios_linker_flags);
ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file);
ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code);
- ClassDB::bind_method(D_METHOD("add_osx_plugin_file", "path"), &EditorExportPlugin::add_osx_plugin_file);
+ ClassDB::bind_method(D_METHOD("add_macos_plugin_file", "path"), &EditorExportPlugin::add_macos_plugin_file);
ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);
GDVIRTUAL_BIND(_export_file, "path", "type", "features");
diff --git a/editor/editor_export.h b/editor/editor_export.h
index 6f41736d2d..9179a3e2b0 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -366,7 +366,7 @@ class EditorExportPlugin : public RefCounted {
Vector<String> ios_bundle_files;
String ios_cpp_code;
- Vector<String> osx_plugin_files;
+ Vector<String> macos_plugin_files;
_FORCE_INLINE_ void _clear() {
shared_objects.clear();
@@ -381,7 +381,7 @@ class EditorExportPlugin : public RefCounted {
ios_plist_content = "";
ios_linker_flags = "";
ios_cpp_code = "";
- osx_plugin_files.clear();
+ macos_plugin_files.clear();
}
void _export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features);
@@ -402,7 +402,7 @@ protected:
void add_ios_linker_flags(const String &p_flags);
void add_ios_bundle_file(const String &p_path);
void add_ios_cpp_code(const String &p_code);
- void add_osx_plugin_file(const String &p_path);
+ void add_macos_plugin_file(const String &p_path);
void skip();
@@ -423,7 +423,7 @@ public:
String get_ios_linker_flags() const;
Vector<String> get_ios_bundle_files() const;
String get_ios_cpp_code() const;
- const Vector<String> &get_osx_plugin_files() const;
+ const Vector<String> &get_macos_plugin_files() const;
EditorExportPlugin();
};
diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp
index f8fc28c31c..9e2d56b2b9 100644
--- a/editor/editor_feature_profile.cpp
+++ b/editor/editor_feature_profile.cpp
@@ -983,7 +983,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
add_child(new_profile_dialog);
new_profile_dialog->connect("confirmed", callable_mp(this, &EditorFeatureProfileManager::_create_new_profile));
new_profile_dialog->register_text_enter(new_profile_name);
- new_profile_dialog->get_ok_button()->set_text(TTR("Create"));
+ new_profile_dialog->set_ok_button_text(TTR("Create"));
erase_profile_dialog = memnew(ConfirmationDialog);
add_child(erase_profile_dialog);
@@ -993,7 +993,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
import_profiles = memnew(EditorFileDialog);
add_child(import_profiles);
import_profiles->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
- import_profiles->add_filter("*.profile; " + TTR("Godot Feature Profile"));
+ import_profiles->add_filter("*.profile", TTR("Godot Feature Profile"));
import_profiles->connect("files_selected", callable_mp(this, &EditorFeatureProfileManager::_import_profiles));
import_profiles->set_title(TTR("Import Profile(s)"));
import_profiles->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
@@ -1001,7 +1001,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
export_profile = memnew(EditorFileDialog);
add_child(export_profile);
export_profile->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
- export_profile->add_filter("*.profile; " + TTR("Godot Feature Profile"));
+ export_profile->add_filter("*.profile", TTR("Godot Feature Profile"));
export_profile->connect("file_selected", callable_mp(this, &EditorFeatureProfileManager::_export_profile));
export_profile->set_title(TTR("Export Profile"));
export_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 95f72476aa..9f446ab38f 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -227,10 +227,10 @@ void EditorFileDialog::update_dir() {
switch (mode) {
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(TTR("Select Current Folder"));
+ set_ok_button_text(TTR("Select Current Folder"));
break;
case FILE_MODE_OPEN_ANY:
case FILE_MODE_SAVE_FILE:
@@ -507,7 +507,7 @@ void EditorFileDialog::_item_selected(int p_item) {
file->set_text(d["name"]);
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
} else if (mode == FILE_MODE_OPEN_DIR) {
- get_ok_button()->set_text(TTR("Select This Folder"));
+ set_ok_button_text(TTR("Select This Folder"));
}
get_ok_button()->set_disabled(_is_open_should_be_disabled());
@@ -540,13 +540,13 @@ void EditorFileDialog::_items_clear_selection(const Vector2 &p_pos, MouseButton
switch (mode) {
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
get_ok_button()->set_disabled(!item_list->is_anything_selected());
break;
case FILE_MODE_OPEN_DIR:
get_ok_button()->set_disabled(false);
- get_ok_button()->set_text(TTR("Select Current Folder"));
+ set_ok_button_text(TTR("Select Current Folder"));
break;
case FILE_MODE_OPEN_ANY:
@@ -731,9 +731,9 @@ void EditorFileDialog::update_file_name() {
String base_name = file_str.get_basename();
Vector<String> filter_substr = filter_str.split(";");
if (filter_substr.size() >= 2) {
- file_str = base_name + "." + filter_substr[0].strip_edges().lstrip("*.").to_lower();
+ file_str = base_name + "." + filter_substr[0].strip_edges().get_extension().to_lower();
} else {
- file_str = base_name + "." + filter_str.get_extension().strip_edges().to_lower();
+ file_str = base_name + "." + filter_str.strip_edges().get_extension().to_lower();
}
file->set_text(file_str);
}
@@ -976,8 +976,12 @@ void EditorFileDialog::clear_filters() {
invalidate();
}
-void EditorFileDialog::add_filter(const String &p_filter) {
- filters.push_back(p_filter);
+void EditorFileDialog::add_filter(const String &p_filter, const String &p_description) {
+ if (p_description.is_empty()) {
+ filters.push_back(p_filter);
+ } else {
+ filters.push_back(vformat("%s ; %s", p_filter, p_description));
+ }
update_filters();
invalidate();
}
@@ -1033,27 +1037,27 @@ void EditorFileDialog::set_file_mode(FileMode p_mode) {
mode = p_mode;
switch (mode) {
case FILE_MODE_OPEN_FILE:
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
set_title(TTR("Open a File"));
can_create_dir = false;
break;
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
set_title(TTR("Open File(s)"));
can_create_dir = false;
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
set_title(TTR("Open a Directory"));
can_create_dir = true;
break;
case FILE_MODE_OPEN_ANY:
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
set_title(TTR("Open a File or Directory"));
can_create_dir = true;
break;
case FILE_MODE_SAVE_FILE:
- get_ok_button()->set_text(TTR("Save"));
+ set_ok_button_text(TTR("Save"));
set_title(TTR("Save a File"));
can_create_dir = true;
break;
@@ -1481,7 +1485,7 @@ void EditorFileDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_cancel_pressed"), &EditorFileDialog::_cancel_pressed);
ClassDB::bind_method(D_METHOD("clear_filters"), &EditorFileDialog::clear_filters);
- ClassDB::bind_method(D_METHOD("add_filter", "filter"), &EditorFileDialog::add_filter);
+ ClassDB::bind_method(D_METHOD("add_filter", "filter", "description"), &EditorFileDialog::add_filter, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_current_dir"), &EditorFileDialog::get_current_dir);
ClassDB::bind_method(D_METHOD("get_current_file"), &EditorFileDialog::get_current_file);
ClassDB::bind_method(D_METHOD("get_current_path"), &EditorFileDialog::get_current_path);
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index 5f2e29b690..51629f2682 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -212,7 +212,7 @@ protected:
public:
void popup_file_dialog();
void clear_filters();
- void add_filter(const String &p_filter);
+ void add_filter(const String &p_filter, const String &p_description = "");
void set_enable_multiple_selection(bool p_enable);
Vector<String> get_selected_files() const;
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index adbba98897..2f106739a4 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -872,7 +872,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAc
fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path);
fi->modified_time = 0;
fi->import_modified_time = 0;
- fi->import_valid = ResourceLoader::is_import_valid(path);
+ fi->import_valid = fi->type == "TextFile" ? true : ResourceLoader::is_import_valid(path);
ItemAction ia;
ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT;
@@ -1023,7 +1023,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
fi->type = "TextFile";
}
fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path);
- fi->import_valid = ResourceLoader::is_import_valid(path);
+ fi->import_valid = fi->type == "TextFile" ? true : ResourceLoader::is_import_valid(path);
fi->import_group_file = ResourceLoader::get_import_group_file(path);
{
@@ -2024,7 +2024,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMap<String
fs->files[cpos]->deps = _get_dependencies(p_file);
fs->files[cpos]->type = importer->get_resource_type();
fs->files[cpos]->uid = uid;
- fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file);
+ fs->files[cpos]->import_valid = fs->files[cpos]->type == "TextFile" ? true : ResourceLoader::is_import_valid(p_file);
if (ResourceUID::get_singleton()->has_id(uid)) {
ResourceUID::get_singleton()->set_id(uid, p_file);
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index 51d4d474c5..a02051c8ee 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -37,212 +37,8 @@
#include "scene/resources/default_theme/default_theme.h"
#include "scene/resources/font.h"
-#define MAKE_FALLBACKS(m_name) \
- m_name->add_data(FontArabic); \
- m_name->add_data(FontBengali); \
- m_name->add_data(FontDevanagari); \
- m_name->add_data(FontGeorgian); \
- m_name->add_data(FontHebrew); \
- m_name->add_data(FontMalayalam); \
- m_name->add_data(FontOriya); \
- m_name->add_data(FontSinhala); \
- m_name->add_data(FontTamil); \
- m_name->add_data(FontTelugu); \
- m_name->add_data(FontThai); \
- m_name->add_data(FontJapanese); \
- m_name->add_data(FontFallback);
-
-// Note: In some languages, the use of italic/slanted fonts is controversial. Therefore, we are limiting simulated slant to the main font (Latin, Cyrillic, and Greek) and using bold fonts for the rest.
-
-#define MAKE_FALLBACKS_SLANTED(m_name) \
- m_name->add_data(FontArabicBold); \
- m_name->add_data(FontBengaliBold); \
- m_name->add_data(FontDevanagariBold); \
- m_name->add_data(FontGeorgianBold); \
- m_name->add_data(FontHebrewBold); \
- m_name->add_data(FontMalayalamBold); \
- m_name->add_data(FontOriyaBold); \
- m_name->add_data(FontSinhalaBold); \
- m_name->add_data(FontTamilBold); \
- m_name->add_data(FontTeluguBold); \
- m_name->add_data(FontThaiBold); \
- m_name->add_data(FontJapaneseBold); \
- m_name->add_data(FontFallbackBold);
-
-#define MAKE_FALLBACKS_BOLD(m_name) \
- m_name->add_data(FontArabicBold); \
- m_name->add_data(FontBengaliBold); \
- m_name->add_data(FontDevanagariBold); \
- m_name->add_data(FontGeorgianBold); \
- m_name->add_data(FontHebrewBold); \
- m_name->add_data(FontMalayalamBold); \
- m_name->add_data(FontOriyaBold); \
- m_name->add_data(FontSinhalaBold); \
- m_name->add_data(FontTamilBold); \
- m_name->add_data(FontTeluguBold); \
- m_name->add_data(FontThaiBold); \
- m_name->add_data(FontJapaneseBold); \
- m_name->add_data(FontFallbackBold);
-
-#define MAKE_DEFAULT_FONT(m_name, m_variations) \
- Ref<Font> m_name; \
- m_name.instantiate(); \
- if (CustomFont.is_valid()) { \
- m_name->add_data(CustomFont); \
- m_name->add_data(DefaultFont); \
- } else { \
- m_name->add_data(DefaultFont); \
- } \
- { \
- Dictionary variations; \
- if (!m_variations.is_empty()) { \
- Vector<String> variation_tags = m_variations.split(","); \
- for (int i = 0; i < variation_tags.size(); i++) { \
- Vector<String> tokens = variation_tags[i].split("="); \
- if (tokens.size() == 2) { \
- variations[tokens[0]] = tokens[1].to_float(); \
- } \
- } \
- } \
- m_name->set_variation_coordinates(variations); \
- } \
- m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \
- m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
- MAKE_FALLBACKS(m_name);
-
-#define MAKE_DEFAULT_FONT_MSDF(m_name, m_variations) \
- Ref<Font> m_name; \
- m_name.instantiate(); \
- if (CustomFont.is_valid()) { \
- m_name->add_data(CustomFontMSDF); \
- m_name->add_data(DefaultFontMSDF); \
- } else { \
- m_name->add_data(DefaultFontMSDF); \
- } \
- { \
- Dictionary variations; \
- if (!m_variations.is_empty()) { \
- Vector<String> variation_tags = m_variations.split(","); \
- for (int i = 0; i < variation_tags.size(); i++) { \
- Vector<String> tokens = variation_tags[i].split("="); \
- if (tokens.size() == 2) { \
- variations[tokens[0]] = tokens[1].to_float(); \
- } \
- } \
- } \
- m_name->set_variation_coordinates(variations); \
- } \
- m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \
- m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
- MAKE_FALLBACKS(m_name);
-
-#define MAKE_SLANTED_FONT(m_name, m_variations) \
- Ref<Font> m_name; \
- m_name.instantiate(); \
- m_name.instantiate(); \
- if (CustomFontSlanted.is_valid()) { \
- m_name->add_data(CustomFontSlanted); \
- m_name->add_data(DefaultFontSlanted); \
- } else { \
- m_name->add_data(DefaultFontSlanted); \
- } \
- { \
- Dictionary variations; \
- if (!m_variations.is_empty()) { \
- Vector<String> variation_tags = m_variations.split(","); \
- for (int i = 0; i < variation_tags.size(); i++) { \
- Vector<String> tokens = variation_tags[i].split("="); \
- if (tokens.size() == 2) { \
- variations[tokens[0]] = tokens[1].to_float(); \
- } \
- } \
- } \
- m_name->set_variation_coordinates(variations); \
- } \
- m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \
- m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
- MAKE_FALLBACKS_SLANTED(m_name);
-
-#define MAKE_BOLD_FONT(m_name, m_variations) \
- Ref<Font> m_name; \
- m_name.instantiate(); \
- if (CustomFontBold.is_valid()) { \
- m_name->add_data(CustomFontBold); \
- m_name->add_data(DefaultFontBold); \
- } else { \
- m_name->add_data(DefaultFontBold); \
- } \
- { \
- Dictionary variations; \
- if (!m_variations.is_empty()) { \
- Vector<String> variation_tags = m_variations.split(","); \
- for (int i = 0; i < variation_tags.size(); i++) { \
- Vector<String> tokens = variation_tags[i].split("="); \
- if (tokens.size() == 2) { \
- variations[tokens[0]] = tokens[1].to_float(); \
- } \
- } \
- } \
- m_name->set_variation_coordinates(variations); \
- } \
- m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \
- m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
- MAKE_FALLBACKS_BOLD(m_name);
-
-#define MAKE_BOLD_FONT_MSDF(m_name, m_variations) \
- Ref<Font> m_name; \
- m_name.instantiate(); \
- if (CustomFontBold.is_valid()) { \
- m_name->add_data(CustomFontBoldMSDF); \
- m_name->add_data(DefaultFontBoldMSDF); \
- } else { \
- m_name->add_data(DefaultFontBoldMSDF); \
- } \
- { \
- Dictionary variations; \
- if (!m_variations.is_empty()) { \
- Vector<String> variation_tags = m_variations.split(","); \
- for (int i = 0; i < variation_tags.size(); i++) { \
- Vector<String> tokens = variation_tags[i].split("="); \
- if (tokens.size() == 2) { \
- variations[tokens[0]] = tokens[1].to_float(); \
- } \
- } \
- } \
- m_name->set_variation_coordinates(variations); \
- } \
- m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \
- m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
- MAKE_FALLBACKS_BOLD(m_name);
-
-#define MAKE_SOURCE_FONT(m_name, m_variations) \
- Ref<Font> m_name; \
- m_name.instantiate(); \
- if (CustomFontSource.is_valid()) { \
- m_name->add_data(CustomFontSource); \
- m_name->add_data(dfmono); \
- } else { \
- m_name->add_data(dfmono); \
- } \
- { \
- Dictionary variations; \
- if (!m_variations.is_empty()) { \
- Vector<String> variation_tags = m_variations.split(","); \
- for (int i = 0; i < variation_tags.size(); i++) { \
- Vector<String> tokens = variation_tags[i].split("="); \
- if (tokens.size() == 2) { \
- variations[tokens[0]] = tokens[1].to_float(); \
- } \
- } \
- } \
- m_name->set_variation_coordinates(variations); \
- } \
- m_name->set_spacing(TextServer::SPACING_TOP, -EDSCALE); \
- m_name->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE); \
- MAKE_FALLBACKS(m_name);
-
-Ref<FontData> load_cached_external_font(const String &p_path, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false) {
- Ref<FontData> font;
+Ref<FontFile> load_external_font(const String &p_path, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) {
+ Ref<FontFile> font;
font.instantiate();
Vector<uint8_t> data = FileAccess::get_file_as_array(p_path);
@@ -254,11 +50,15 @@ Ref<FontData> load_cached_external_font(const String &p_path, TextServer::Hintin
font->set_force_autohinter(p_autohint);
font->set_subpixel_positioning(p_font_subpixel_positioning);
+ if (r_fallbacks != nullptr) {
+ r_fallbacks->push_back(font);
+ }
+
return font;
}
-Ref<FontData> load_cached_internal_font(const uint8_t *p_data, size_t p_size, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false) {
- Ref<FontData> font;
+Ref<FontFile> load_internal_font(const uint8_t *p_data, size_t p_size, TextServer::Hinting p_hinting, bool p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) {
+ Ref<FontFile> font;
font.instantiate();
font->set_data_ptr(p_data, p_size);
@@ -268,14 +68,29 @@ Ref<FontData> load_cached_internal_font(const uint8_t *p_data, size_t p_size, Te
font->set_force_autohinter(p_autohint);
font->set_subpixel_positioning(p_font_subpixel_positioning);
+ if (r_fallbacks != nullptr) {
+ r_fallbacks->push_back(font);
+ }
+
return font;
}
+Ref<FontVariation> make_bold_font(const Ref<Font> &p_font, double p_embolden, TypedArray<Font> *r_fallbacks = nullptr) {
+ Ref<FontVariation> font_var;
+ font_var.instantiate();
+ font_var->set_base_font(p_font);
+ font_var->set_variation_embolden(p_embolden);
+
+ if (r_fallbacks != nullptr) {
+ r_fallbacks->push_back(font_var);
+ }
+
+ return font_var;
+}
+
void editor_register_fonts(Ref<Theme> p_theme) {
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- /* Custom font */
-
bool font_antialiased = (bool)EditorSettings::get_singleton()->get("interface/editor/font_antialiased");
int font_hinting_setting = (int)EditorSettings::get_singleton()->get("interface/editor/font_hinting");
TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)EditorSettings::get_singleton()->get("interface/editor/font_subpixel_positioning");
@@ -287,7 +102,7 @@ void editor_register_fonts(Ref<Theme> p_theme) {
// - macOS doesn't use font hinting.
// - Windows uses ClearType, which is in between "Light" and "Normal" hinting.
// - Linux has configurable font hinting, but most distributions including Ubuntu default to "Light".
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
font_hinting = TextServer::HINTING_NONE;
#else
font_hinting = TextServer::HINTING_LIGHT;
@@ -304,184 +119,268 @@ void editor_register_fonts(Ref<Theme> p_theme) {
break;
}
+ // Load built-in fonts.
const int default_font_size = int(EDITOR_GET("interface/editor/main_font_size")) * EDSCALE;
const float embolden_strength = 0.6;
+ Ref<Font> default_font = load_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false);
+ Ref<Font> default_font_msdf = load_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
+
+ TypedArray<Font> fallbacks;
+ Ref<FontFile> arabic_font = load_internal_font(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> bengali_font = load_internal_font(_font_NotoSansBengaliUI_Regular, _font_NotoSansBengaliUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> devanagari_font = load_internal_font(_font_NotoSansDevanagariUI_Regular, _font_NotoSansDevanagariUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> georgian_font = load_internal_font(_font_NotoSansGeorgian_Regular, _font_NotoSansGeorgian_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> hebrew_font = load_internal_font(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> malayalam_font = load_internal_font(_font_NotoSansMalayalamUI_Regular, _font_NotoSansMalayalamUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> oriya_font = load_internal_font(_font_NotoSansOriyaUI_Regular, _font_NotoSansOriyaUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> sinhala_font = load_internal_font(_font_NotoSansSinhalaUI_Regular, _font_NotoSansSinhalaUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> tamil_font = load_internal_font(_font_NotoSansTamilUI_Regular, _font_NotoSansTamilUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> telugu_font = load_internal_font(_font_NotoSansTeluguUI_Regular, _font_NotoSansTeluguUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> thai_font = load_internal_font(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> fallback_font = load_internal_font(_font_DroidSansFallback, _font_DroidSansFallback_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ Ref<FontFile> japanese_font = load_internal_font(_font_DroidSansJapanese, _font_DroidSansJapanese_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks);
+ default_font->set_fallbacks(fallbacks);
+ default_font_msdf->set_fallbacks(fallbacks);
+
+ Ref<FontFile> default_font_bold = load_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false);
+ Ref<FontFile> default_font_bold_msdf = load_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
+
+ TypedArray<Font> fallbacks_bold;
+ Ref<FontFile> arabic_font_bold = load_internal_font(_font_NotoNaskhArabicUI_Bold, _font_NotoNaskhArabicUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> bengali_font_bold = load_internal_font(_font_NotoSansBengaliUI_Bold, _font_NotoSansBengaliUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> devanagari_font_bold = load_internal_font(_font_NotoSansDevanagariUI_Bold, _font_NotoSansDevanagariUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> georgian_font_bold = load_internal_font(_font_NotoSansGeorgian_Bold, _font_NotoSansGeorgian_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> hebrew_font_bold = load_internal_font(_font_NotoSansHebrew_Bold, _font_NotoSansHebrew_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> malayalam_font_bold = load_internal_font(_font_NotoSansMalayalamUI_Bold, _font_NotoSansMalayalamUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> oriya_font_bold = load_internal_font(_font_NotoSansOriyaUI_Bold, _font_NotoSansOriyaUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> sinhala_font_bold = load_internal_font(_font_NotoSansSinhalaUI_Bold, _font_NotoSansSinhalaUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> tamil_font_bold = load_internal_font(_font_NotoSansTamilUI_Bold, _font_NotoSansTamilUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> telugu_font_bold = load_internal_font(_font_NotoSansTeluguUI_Bold, _font_NotoSansTeluguUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontFile> thai_font_bold = load_internal_font(_font_NotoSansThaiUI_Bold, _font_NotoSansThaiUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, false, &fallbacks_bold);
+ Ref<FontVariation> fallback_font_bold = make_bold_font(fallback_font, embolden_strength, &fallbacks_bold);
+ Ref<FontVariation> japanese_font_bold = make_bold_font(japanese_font, embolden_strength, &fallbacks_bold);
+ default_font_bold->set_fallbacks(fallbacks_bold);
+ default_font_bold_msdf->set_fallbacks(fallbacks_bold);
+
+ Ref<FontFile> default_font_mono = load_internal_font(_font_JetBrainsMono_Regular, _font_JetBrainsMono_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ default_font_mono->set_fallbacks(fallbacks);
+
+ // Init base font configs and load custom fonts.
String custom_font_path = EditorSettings::get_singleton()->get("interface/editor/main_font");
- Ref<FontData> CustomFont;
+ String custom_font_path_bold = EditorSettings::get_singleton()->get("interface/editor/main_font_bold");
+ String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font");
+
+ Ref<FontVariation> default_fc;
+ default_fc.instantiate();
if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
- CustomFont = load_cached_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ Ref<FontFile> custom_font = load_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ {
+ TypedArray<Font> fallback_custom;
+ fallback_custom.push_back(default_font);
+ custom_font->set_fallbacks(fallback_custom);
+ }
+ default_fc->set_base_font(custom_font);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/main_font", "");
+ default_fc->set_base_font(default_font);
}
+ default_fc->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
+ default_fc->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
- Ref<FontData> CustomFontMSDF;
+ Ref<FontVariation> default_fc_msdf;
+ default_fc_msdf.instantiate();
if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
- CustomFontMSDF = load_cached_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
+ Ref<FontFile> custom_font = load_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ {
+ TypedArray<Font> fallback_custom;
+ fallback_custom.push_back(default_font_msdf);
+ custom_font->set_fallbacks(fallback_custom);
+ }
+ default_fc_msdf->set_base_font(custom_font);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/main_font", "");
+ default_fc_msdf->set_base_font(default_font_msdf);
}
+ default_fc_msdf->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
+ default_fc_msdf->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
- Ref<FontData> CustomFontSlanted;
- if (CustomFont.is_valid()) {
- CustomFontSlanted = CustomFont->duplicate();
- CustomFontSlanted->set_transform(Transform2D(1.0, 0.4, 0.0, 1.0, 0.0, 0.0));
- }
-
- /* Custom Bold font */
-
- String custom_font_path_bold = EditorSettings::get_singleton()->get("interface/editor/main_font_bold");
- Ref<FontData> CustomFontBold;
+ Ref<FontVariation> bold_fc;
+ bold_fc.instantiate();
if (custom_font_path_bold.length() > 0 && dir->file_exists(custom_font_path_bold)) {
- CustomFontBold = load_cached_external_font(custom_font_path_bold, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ Ref<FontFile> custom_font = load_external_font(custom_font_path_bold, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ {
+ TypedArray<Font> fallback_custom;
+ fallback_custom.push_back(default_font_bold);
+ custom_font->set_fallbacks(fallback_custom);
+ }
+ bold_fc->set_base_font(custom_font);
+ } else if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
+ Ref<FontFile> custom_font = load_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ {
+ TypedArray<Font> fallback_custom;
+ fallback_custom.push_back(default_font_bold);
+ custom_font->set_fallbacks(fallback_custom);
+ }
+ bold_fc->set_base_font(custom_font);
+ bold_fc->set_variation_embolden(embolden_strength);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/main_font_bold", "");
+ bold_fc->set_base_font(default_font_bold);
}
+ bold_fc->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
+ bold_fc->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
- if (CustomFont.is_valid() && !CustomFontBold.is_valid()) {
- CustomFontBold = CustomFont->duplicate();
- CustomFontBold->set_embolden(embolden_strength);
- }
-
- Ref<FontData> CustomFontBoldMSDF;
- if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
- CustomFontBoldMSDF = load_cached_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
+ Ref<FontVariation> bold_fc_msdf;
+ bold_fc_msdf.instantiate();
+ if (custom_font_path_bold.length() > 0 && dir->file_exists(custom_font_path_bold)) {
+ Ref<FontFile> custom_font = load_external_font(custom_font_path_bold, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ {
+ TypedArray<Font> fallback_custom;
+ fallback_custom.push_back(default_font_bold_msdf);
+ custom_font->set_fallbacks(fallback_custom);
+ }
+ bold_fc_msdf->set_base_font(custom_font);
+ } else if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) {
+ Ref<FontFile> custom_font = load_external_font(custom_font_path, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ {
+ TypedArray<Font> fallback_custom;
+ fallback_custom.push_back(default_font_bold_msdf);
+ custom_font->set_fallbacks(fallback_custom);
+ }
+ bold_fc_msdf->set_base_font(custom_font);
+ bold_fc_msdf->set_variation_embolden(embolden_strength);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/main_font_bold", "");
+ bold_fc_msdf->set_base_font(default_font_bold_msdf);
}
+ bold_fc_msdf->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
+ bold_fc_msdf->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
- /* Custom source code font */
-
- String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font");
- Ref<FontData> CustomFontSource;
+ Ref<FontVariation> mono_fc;
+ mono_fc.instantiate();
if (custom_font_path_source.length() > 0 && dir->file_exists(custom_font_path_source)) {
- CustomFontSource = load_cached_external_font(custom_font_path_source, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ Ref<FontFile> custom_font = load_external_font(custom_font_path_source, font_hinting, font_antialiased, true, font_subpixel_positioning);
+ {
+ TypedArray<Font> fallback_custom;
+ fallback_custom.push_back(default_font_mono);
+ custom_font->set_fallbacks(fallback_custom);
+ }
+ mono_fc->set_base_font(custom_font);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/code_font", "");
+ mono_fc->set_base_font(default_font_mono);
}
+ mono_fc->set_spacing(TextServer::SPACING_TOP, -EDSCALE);
+ mono_fc->set_spacing(TextServer::SPACING_BOTTOM, -EDSCALE);
+
+ Ref<FontVariation> mono_other_fc = mono_fc->duplicate();
+
+ // Enable contextual alternates (coding ligatures) and custom features for the source editor font.
+ int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures");
+ switch (ot_mode) {
+ case 1: { // Disable ligatures.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 0;
+ mono_fc->set_opentype_features(ftrs);
+ } break;
+ case 2: { // Custom.
+ Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(",");
+ Dictionary ftrs;
+ for (int i = 0; i < subtag.size(); i++) {
+ Vector<String> subtag_a = subtag[i].split("=");
+ if (subtag_a.size() == 2) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
+ } else if (subtag_a.size() == 1) {
+ ftrs[TS->name_to_tag(subtag_a[0])] = 1;
+ }
+ }
+ mono_fc->set_opentype_features(ftrs);
+ } break;
+ default: { // Default.
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 1;
+ mono_fc->set_opentype_features(ftrs);
+ } break;
+ }
+
+ {
+ // Disable contextual alternates (coding ligatures).
+ Dictionary ftrs;
+ ftrs[TS->name_to_tag("calt")] = 0;
+ mono_other_fc->set_opentype_features(ftrs);
+ }
+
+ Ref<FontVariation> italic_fc = default_fc->duplicate();
+ italic_fc->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
- /* Noto Sans */
-
- Ref<FontData> DefaultFont = load_cached_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> DefaultFontMSDF = load_cached_internal_font(_font_NotoSans_Regular, _font_NotoSans_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
- Ref<FontData> DefaultFontBold = load_cached_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> DefaultFontBoldMSDF = load_cached_internal_font(_font_NotoSans_Bold, _font_NotoSans_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning, true);
- Ref<FontData> FontArabic = load_cached_internal_font(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontArabicBold = load_cached_internal_font(_font_NotoNaskhArabicUI_Bold, _font_NotoNaskhArabicUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontBengali = load_cached_internal_font(_font_NotoSansBengaliUI_Regular, _font_NotoSansBengaliUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontBengaliBold = load_cached_internal_font(_font_NotoSansBengaliUI_Bold, _font_NotoSansBengaliUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontDevanagari = load_cached_internal_font(_font_NotoSansDevanagariUI_Regular, _font_NotoSansDevanagariUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontDevanagariBold = load_cached_internal_font(_font_NotoSansDevanagariUI_Bold, _font_NotoSansDevanagariUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontGeorgian = load_cached_internal_font(_font_NotoSansGeorgian_Regular, _font_NotoSansGeorgian_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontGeorgianBold = load_cached_internal_font(_font_NotoSansGeorgian_Bold, _font_NotoSansGeorgian_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontHebrew = load_cached_internal_font(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontHebrewBold = load_cached_internal_font(_font_NotoSansHebrew_Bold, _font_NotoSansHebrew_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontMalayalam = load_cached_internal_font(_font_NotoSansMalayalamUI_Regular, _font_NotoSansMalayalamUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontMalayalamBold = load_cached_internal_font(_font_NotoSansMalayalamUI_Bold, _font_NotoSansMalayalamUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontOriya = load_cached_internal_font(_font_NotoSansOriyaUI_Regular, _font_NotoSansOriyaUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontOriyaBold = load_cached_internal_font(_font_NotoSansOriyaUI_Bold, _font_NotoSansOriyaUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontSinhala = load_cached_internal_font(_font_NotoSansSinhalaUI_Regular, _font_NotoSansSinhalaUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontSinhalaBold = load_cached_internal_font(_font_NotoSansSinhalaUI_Bold, _font_NotoSansSinhalaUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontTamil = load_cached_internal_font(_font_NotoSansTamilUI_Regular, _font_NotoSansTamilUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontTamilBold = load_cached_internal_font(_font_NotoSansTamilUI_Bold, _font_NotoSansTamilUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontTelugu = load_cached_internal_font(_font_NotoSansTeluguUI_Regular, _font_NotoSansTeluguUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontTeluguBold = load_cached_internal_font(_font_NotoSansTeluguUI_Bold, _font_NotoSansTeluguUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontThai = load_cached_internal_font(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontThaiBold = load_cached_internal_font(_font_NotoSansThaiUI_Bold, _font_NotoSansThaiUI_Bold_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
-
- Ref<FontData> DefaultFontSlanted = DefaultFont->duplicate();
- DefaultFontSlanted->set_transform(Transform2D(1.0, 0.3, 0.0, 1.0, 0.0, 0.0));
-
- /* Droid Sans */
-
- Ref<FontData> FontFallback = load_cached_internal_font(_font_DroidSansFallback, _font_DroidSansFallback_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Ref<FontData> FontJapanese = load_cached_internal_font(_font_DroidSansJapanese, _font_DroidSansJapanese_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
-
- Ref<FontData> FontFallbackBold = FontFallback->duplicate();
- FontFallbackBold->set_embolden(embolden_strength);
- Ref<FontData> FontJapaneseBold = FontJapanese->duplicate();
- FontJapaneseBold->set_embolden(embolden_strength);
-
- /* Hack */
-
- Ref<FontData> dfmono = load_cached_internal_font(_font_JetBrainsMono_Regular, _font_JetBrainsMono_Regular_size, font_hinting, font_antialiased, true, font_subpixel_positioning);
- Dictionary opentype_features;
- opentype_features["calt"] = 0;
- dfmono->set_opentype_feature_overrides(opentype_features); // Disable contextual alternates (coding ligatures).
-
- // Default font
- MAKE_DEFAULT_FONT(df, String());
- p_theme->set_default_font(df); // Default theme font
+ // Setup theme.
+
+ p_theme->set_default_font(default_fc); // Default theme font config.
p_theme->set_default_font_size(default_font_size);
- p_theme->set_font_size("main_size", "EditorFonts", default_font_size);
- p_theme->set_font("main", "EditorFonts", df);
+ // Main font.
- MAKE_DEFAULT_FONT_MSDF(df_msdf, String());
- p_theme->set_font("main_msdf", "EditorFonts", df_msdf);
+ p_theme->set_font("main", "EditorFonts", default_fc);
+ p_theme->set_font("main_msdf", "EditorFonts", default_fc_msdf);
+ p_theme->set_font_size("main_size", "EditorFonts", default_font_size);
- // Bold font
- MAKE_BOLD_FONT(df_bold, String());
- MAKE_SLANTED_FONT(df_italic, String());
+ p_theme->set_font("bold", "EditorFonts", bold_fc);
+ p_theme->set_font("main_bold_msdf", "EditorFonts", bold_fc_msdf);
p_theme->set_font_size("bold_size", "EditorFonts", default_font_size);
- p_theme->set_font("bold", "EditorFonts", df_bold);
- MAKE_BOLD_FONT_MSDF(df_bold_msdf, String());
- p_theme->set_font("main_bold_msdf", "EditorFonts", df_bold_msdf);
+ // Title font.
- // Title font
+ p_theme->set_font("title", "EditorFonts", bold_fc);
p_theme->set_font_size("title_size", "EditorFonts", default_font_size + 1 * EDSCALE);
- p_theme->set_font("title", "EditorFonts", df_bold);
+ p_theme->set_font("main_button_font", "EditorFonts", bold_fc);
p_theme->set_font_size("main_button_font_size", "EditorFonts", default_font_size + 1 * EDSCALE);
- p_theme->set_font("main_button_font", "EditorFonts", df_bold);
- p_theme->set_font("font", "Label", df);
+ p_theme->set_font("font", "Label", default_fc);
p_theme->set_type_variation("HeaderSmall", "Label");
- p_theme->set_font("font", "HeaderSmall", df_bold);
+ p_theme->set_font("font", "HeaderSmall", bold_fc);
p_theme->set_font_size("font_size", "HeaderSmall", default_font_size);
p_theme->set_type_variation("HeaderMedium", "Label");
- p_theme->set_font("font", "HeaderMedium", df_bold);
+ p_theme->set_font("font", "HeaderMedium", bold_fc);
p_theme->set_font_size("font_size", "HeaderMedium", default_font_size + 1 * EDSCALE);
p_theme->set_type_variation("HeaderLarge", "Label");
- p_theme->set_font("font", "HeaderLarge", df_bold);
+ p_theme->set_font("font", "HeaderLarge", bold_fc);
p_theme->set_font_size("font_size", "HeaderLarge", default_font_size + 3 * EDSCALE);
// Documentation fonts
- String code_font_custom_variations = EditorSettings::get_singleton()->get("interface/editor/code_font_custom_variations");
- MAKE_SOURCE_FONT(df_code, code_font_custom_variations);
p_theme->set_font_size("doc_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE);
- p_theme->set_font("doc", "EditorFonts", df);
- p_theme->set_font("doc_bold", "EditorFonts", df_bold);
- p_theme->set_font("doc_italic", "EditorFonts", df_italic);
+ p_theme->set_font("doc", "EditorFonts", default_fc);
+ p_theme->set_font("doc_bold", "EditorFonts", bold_fc);
+ p_theme->set_font("doc_italic", "EditorFonts", italic_fc);
p_theme->set_font_size("doc_title_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE);
- p_theme->set_font("doc_title", "EditorFonts", df_bold);
+ p_theme->set_font("doc_title", "EditorFonts", bold_fc);
p_theme->set_font_size("doc_source_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE);
- p_theme->set_font("doc_source", "EditorFonts", df_code);
+ p_theme->set_font("doc_source", "EditorFonts", mono_fc);
p_theme->set_font_size("doc_keyboard_size", "EditorFonts", (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE);
- p_theme->set_font("doc_keyboard", "EditorFonts", df_code);
+ p_theme->set_font("doc_keyboard", "EditorFonts", mono_fc);
// Ruler font
p_theme->set_font_size("rulers_size", "EditorFonts", 8 * EDSCALE);
- p_theme->set_font("rulers", "EditorFonts", df);
+ p_theme->set_font("rulers", "EditorFonts", default_fc);
// Rotation widget font
p_theme->set_font_size("rotation_control_size", "EditorFonts", 14 * EDSCALE);
- p_theme->set_font("rotation_control", "EditorFonts", df);
+ p_theme->set_font("rotation_control", "EditorFonts", default_fc);
// Code font
p_theme->set_font_size("source_size", "EditorFonts", int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE);
- p_theme->set_font("source", "EditorFonts", df_code);
+ p_theme->set_font("source", "EditorFonts", mono_fc);
p_theme->set_font_size("expression_size", "EditorFonts", (int(EDITOR_GET("interface/editor/code_font_size")) - 1) * EDSCALE);
- p_theme->set_font("expression", "EditorFonts", df_code);
+ p_theme->set_font("expression", "EditorFonts", mono_other_fc);
p_theme->set_font_size("output_source_size", "EditorFonts", int(EDITOR_GET("run/output/font_size")) * EDSCALE);
- p_theme->set_font("output_source", "EditorFonts", df_code);
+ p_theme->set_font("output_source", "EditorFonts", mono_other_fc);
p_theme->set_font_size("status_source_size", "EditorFonts", default_font_size);
- p_theme->set_font("status_source", "EditorFonts", df_code);
+ p_theme->set_font("status_source", "EditorFonts", mono_other_fc);
}
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index b4325f09c5..68141dd4a3 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -63,6 +63,8 @@ void EditorHelp::_update_theme() {
doc_bold_font = get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts"));
doc_title_font = get_theme_font(SNAME("doc_title"), SNAME("EditorFonts"));
doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts"));
+
+ doc_title_font_size = get_theme_font_size(SNAME("doc_title_size"), SNAME("EditorFonts"));
}
void EditorHelp::_search(bool p_search_previous) {
@@ -123,6 +125,9 @@ void EditorHelp::_class_desc_select(const String &p_select) {
} else if (tag == "constant") {
topic = "class_constant";
table = &this->constant_line;
+ } else if (tag == "annotation") {
+ topic = "class_annotation";
+ table = &this->annotation_line;
} else if (tag == "theme_item") {
topic = "theme_item";
table = &this->theme_property_line;
@@ -181,7 +186,7 @@ void EditorHelp::_class_desc_resized(bool p_force_update_theme) {
// 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;
+ real_t char_width = doc_code_font->get_char_size('x', 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 || p_force_update_theme) {
display_margin = new_display_margin;
@@ -272,7 +277,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
class_desc->add_text(" ");
}
- if (p_overview && !p_method.description.is_empty()) {
+ if (p_overview && !p_method.description.strip_edges().is_empty()) {
class_desc->push_meta("@method " + p_method.name);
}
@@ -280,7 +285,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
_add_text(p_method.name);
class_desc->pop();
- if (p_overview && !p_method.description.is_empty()) {
+ if (p_overview && !p_method.description.strip_edges().is_empty()) {
class_desc->pop(); //meta
}
@@ -362,8 +367,9 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
void EditorHelp::_update_method_list(const Vector<DocData::MethodDoc> p_methods, bool &r_method_descrpitons) {
Ref<Font> doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts"));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // title font size
+ class_desc->pop(); // title font
+ class_desc->pop(); // title color
class_desc->add_newline();
class_desc->push_font(doc_code_font);
@@ -409,7 +415,7 @@ void EditorHelp::_update_method_list(const Vector<DocData::MethodDoc> p_methods,
class_desc->pop(); //cell
}
- if (!m[i].description.is_empty() || m[i].errors_returned.size() > 0) {
+ if (!m[i].description.strip_edges().is_empty() || m[i].errors_returned.size() > 0) {
r_method_descrpitons = true;
}
@@ -431,8 +437,9 @@ void EditorHelp::_update_method_descriptions(const DocData::ClassDoc p_classdoc,
Ref<Font> doc_bold_font = get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts"));
Ref<Font> doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts"));
String link_color_text = title_color.to_html(false);
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // title font size
+ class_desc->pop(); // title font
+ class_desc->pop(); // title color
class_desc->add_newline();
class_desc->add_newline();
@@ -535,15 +542,17 @@ void EditorHelp::_update_doc() {
// Class name
section_line.push_back(Pair<String, int>(TTR("Top"), 0));
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->push_color(title_color);
class_desc->add_text(TTR("Class:") + " ");
class_desc->add_image(icon, icon->get_width(), icon->get_height());
class_desc->add_text(" ");
class_desc->push_color(headline_color);
_add_text(edited_class);
- class_desc->pop();
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // color
+ class_desc->pop(); // color
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
class_desc->add_newline();
// Inheritance tree
@@ -605,7 +614,7 @@ void EditorHelp::_update_doc() {
class_desc->add_newline();
// Brief description
- if (!cd.brief_description.is_empty()) {
+ if (!cd.brief_description.strip_edges().is_empty()) {
class_desc->push_color(text_color);
class_desc->push_font(doc_bold_font);
class_desc->push_indent(1);
@@ -619,14 +628,16 @@ void EditorHelp::_update_doc() {
}
// Class description
- if (!cd.description.is_empty()) {
+ if (!cd.description.strip_edges().is_empty()) {
section_line.push_back(Pair<String, int>(TTR("Description"), class_desc->get_paragraph_count() - 2));
description_line = class_desc->get_paragraph_count() - 2;
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Description"));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
class_desc->add_newline();
class_desc->add_newline();
@@ -646,9 +657,11 @@ void EditorHelp::_update_doc() {
if (cd.tutorials.size()) {
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Online Tutorials"));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
class_desc->push_indent(1);
class_desc->push_font(doc_code_font);
@@ -682,7 +695,7 @@ void EditorHelp::_update_doc() {
if (cd.is_script_doc) {
has_properties = false;
for (int i = 0; i < cd.properties.size(); i++) {
- if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.is_empty()) {
+ if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.strip_edges().is_empty()) {
continue;
}
has_properties = true;
@@ -694,9 +707,11 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Properties"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Properties"));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
class_desc->add_newline();
class_desc->push_font(doc_code_font);
@@ -706,7 +721,7 @@ void EditorHelp::_update_doc() {
for (int i = 0; i < cd.properties.size(); i++) {
// Ignore undocumented private.
- if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.is_empty()) {
+ if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.strip_edges().is_empty()) {
continue;
}
property_line[cd.properties[i].name] = class_desc->get_paragraph_count() - 2; //gets overridden if description
@@ -731,7 +746,7 @@ void EditorHelp::_update_doc() {
describe = true;
}
- if (!cd.properties[i].description.is_empty()) {
+ if (!cd.properties[i].description.strip_edges().is_empty()) {
describe = true;
}
@@ -844,7 +859,7 @@ void EditorHelp::_update_doc() {
}
}
// Ignore undocumented non virtual private.
- if (cd.methods[i].name.begins_with("_") && cd.methods[i].description.is_empty() && !cd.methods[i].qualifiers.contains("virtual")) {
+ if (cd.methods[i].name.begins_with("_") && cd.methods[i].description.strip_edges().is_empty() && !cd.methods[i].qualifiers.contains("virtual")) {
continue;
}
methods.push_back(cd.methods[i]);
@@ -858,6 +873,7 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Constructors"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Constructors"));
_update_method_list(cd.constructors, constructor_descriptions);
}
@@ -869,6 +885,7 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Methods"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Methods"));
_update_method_list(methods, method_descriptions);
}
@@ -881,6 +898,7 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Operators"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Operators"));
_update_method_list(cd.operators, operator_descriptions);
}
@@ -890,9 +908,11 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Theme Properties"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Theme Properties"));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
class_desc->add_newline();
class_desc->add_newline();
@@ -916,13 +936,15 @@ void EditorHelp::_update_doc() {
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
if (data_type_names.has(theme_data_type)) {
class_desc->add_text(data_type_names[theme_data_type]);
} else {
class_desc->add_text("");
}
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
class_desc->add_newline();
class_desc->add_newline();
@@ -957,7 +979,7 @@ void EditorHelp::_update_doc() {
class_desc->pop(); // monofont
// Theme item description.
- if (!cd.theme_properties[i].description.is_empty()) {
+ if (!cd.theme_properties[i].description.strip_edges().is_empty()) {
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
class_desc->push_indent(1);
@@ -984,9 +1006,11 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Signals"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Signals"));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
class_desc->add_newline();
class_desc->add_newline();
@@ -997,8 +1021,8 @@ void EditorHelp::_update_doc() {
signal_line[cd.signals[i].name] = class_desc->get_paragraph_count() - 2; // Gets overridden if description.
class_desc->push_font(doc_code_font); // monofont
- class_desc->push_color(headline_color);
_add_bulletpoint();
+ class_desc->push_color(headline_color);
_add_text(cd.signals[i].name);
class_desc->pop();
class_desc->push_color(symbol_color);
@@ -1027,7 +1051,7 @@ void EditorHelp::_update_doc() {
class_desc->add_text(")");
class_desc->pop();
class_desc->pop(); // end monofont
- if (!cd.signals[i].description.is_empty()) {
+ if (!cd.signals[i].description.strip_edges().is_empty()) {
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
class_desc->push_indent(1);
@@ -1058,7 +1082,7 @@ void EditorHelp::_update_doc() {
enums[cd.constants[i].enumeration].push_back(cd.constants[i]);
} else {
// Ignore undocumented private.
- if (cd.constants[i].name.begins_with("_") && cd.constants[i].description.is_empty()) {
+ if (cd.constants[i].name.begins_with("_") && cd.constants[i].description.strip_edges().is_empty()) {
continue;
}
constants.push_back(cd.constants[i]);
@@ -1070,9 +1094,11 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Enumerations"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Enumerations"));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
class_desc->push_indent(1);
class_desc->add_newline();
@@ -1082,7 +1108,11 @@ void EditorHelp::_update_doc() {
class_desc->push_font(doc_code_font);
class_desc->push_color(title_color);
- class_desc->add_text("enum ");
+ if (E.value.size() && E.value[0].is_bitfield) {
+ class_desc->add_text("flags ");
+ } else {
+ class_desc->add_text("enum ");
+ }
class_desc->pop();
String e = E.key;
if ((e.get_slice_count(".") > 1) && (e.get_slice(".", 0) == edited_class)) {
@@ -1128,8 +1158,8 @@ void EditorHelp::_update_doc() {
constant_line[enum_list[i].name] = class_desc->get_paragraph_count() - 2;
class_desc->push_font(doc_code_font);
- class_desc->push_color(headline_color);
_add_bulletpoint();
+ class_desc->push_color(headline_color);
_add_text(enum_list[i].name);
class_desc->pop();
class_desc->push_color(symbol_color);
@@ -1174,9 +1204,11 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Constants"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Constants"));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
class_desc->push_indent(1);
class_desc->add_newline();
@@ -1211,7 +1243,7 @@ void EditorHelp::_update_doc() {
class_desc->add_newline();
- if (!constants[i].description.is_empty()) {
+ if (!constants[i].description.strip_edges().is_empty()) {
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
_add_text(DTR(constants[i].description));
@@ -1230,14 +1262,122 @@ void EditorHelp::_update_doc() {
}
}
+ // Annotations
+ if (!cd.annotations.is_empty()) {
+ if (sort_methods) {
+ cd.annotations.sort();
+ }
+
+ section_line.push_back(Pair<String, int>(TTR("Annotations"), class_desc->get_paragraph_count() - 2));
+ class_desc->push_color(title_color);
+ class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
+ class_desc->add_text(TTR("Annotations"));
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
+
+ class_desc->add_newline();
+ class_desc->add_newline();
+
+ class_desc->push_indent(1);
+
+ for (int i = 0; i < cd.annotations.size(); i++) {
+ annotation_line[cd.annotations[i].name] = class_desc->get_paragraph_count() - 2; // Gets overridden if description.
+
+ class_desc->push_font(doc_code_font); // monofont
+ _add_bulletpoint();
+ class_desc->push_color(headline_color);
+ _add_text(cd.annotations[i].name);
+ class_desc->pop();
+
+ if (cd.annotations[i].arguments.size() > 0) {
+ class_desc->push_color(symbol_color);
+ class_desc->add_text("(");
+ class_desc->pop();
+ for (int j = 0; j < cd.annotations[i].arguments.size(); j++) {
+ class_desc->push_color(text_color);
+ if (j > 0) {
+ class_desc->add_text(", ");
+ }
+
+ _add_text(cd.annotations[i].arguments[j].name);
+ class_desc->add_text(": ");
+ _add_type(cd.annotations[i].arguments[j].type);
+ if (!cd.annotations[i].arguments[j].default_value.is_empty()) {
+ class_desc->push_color(symbol_color);
+ class_desc->add_text(" = ");
+ class_desc->pop();
+ _add_text(cd.annotations[i].arguments[j].default_value);
+ }
+
+ class_desc->pop();
+ }
+
+ if (cd.annotations[i].qualifiers.contains("vararg")) {
+ class_desc->push_color(text_color);
+ if (cd.annotations[i].arguments.size()) {
+ class_desc->add_text(", ");
+ }
+ class_desc->push_color(symbol_color);
+ class_desc->add_text("...");
+ class_desc->pop();
+ class_desc->pop();
+ }
+
+ class_desc->push_color(symbol_color);
+ class_desc->add_text(")");
+ class_desc->pop();
+ }
+
+ if (!cd.annotations[i].qualifiers.is_empty()) {
+ class_desc->push_color(qualifier_color);
+ class_desc->add_text(" ");
+ _add_text(cd.annotations[i].qualifiers);
+ class_desc->pop();
+ }
+
+ class_desc->pop(); // end monofont
+
+ if (!cd.annotations[i].description.strip_edges().is_empty()) {
+ class_desc->push_font(doc_font);
+ class_desc->push_color(comment_color);
+ class_desc->push_indent(1);
+ _add_text(DTR(cd.annotations[i].description));
+ class_desc->pop(); // indent
+ class_desc->pop();
+ class_desc->pop(); // font
+ } else {
+ class_desc->push_indent(1);
+ class_desc->add_image(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
+ class_desc->add_text(" ");
+ class_desc->push_color(comment_color);
+ if (cd.is_script_doc) {
+ class_desc->append_text(TTR("There is currently no description for this annotation."));
+ } else {
+ class_desc->append_text(TTR("There is currently no description for this annotation. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text));
+ }
+ class_desc->pop();
+ class_desc->pop(); // indent
+ }
+ class_desc->add_newline();
+ class_desc->add_newline();
+ }
+
+ class_desc->pop();
+ class_desc->add_newline();
+ }
+
// Property descriptions
if (property_descr) {
section_line.push_back(Pair<String, int>(TTR("Property Descriptions"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Property Descriptions"));
- class_desc->pop();
- class_desc->pop();
+ class_desc->pop(); // font size
+ class_desc->pop(); // font
+ class_desc->pop(); // color
class_desc->add_newline();
class_desc->add_newline();
@@ -1401,6 +1541,7 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Constructor Descriptions"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Constructor Descriptions"));
_update_method_descriptions(cd, cd.constructors, "constructor");
}
@@ -1410,6 +1551,7 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Method Descriptions"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Method Descriptions"));
_update_method_descriptions(cd, methods, "method");
}
@@ -1419,6 +1561,7 @@ void EditorHelp::_update_doc() {
section_line.push_back(Pair<String, int>(TTR("Operator Descriptions"), class_desc->get_paragraph_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
+ class_desc->push_font_size(doc_title_font_size);
class_desc->add_text(TTR("Operator Descriptions"));
_update_method_descriptions(cd, cd.operators, "operator");
}
@@ -1471,6 +1614,10 @@ void EditorHelp::_help_callback(const String &p_topic) {
if (constant_line.has(name)) {
line = constant_line[name];
}
+ } else if (what == "class_annotation") {
+ if (annotation_line.has(name)) {
+ line = annotation_line[name];
+ }
} else if (what == "class_global") {
if (constant_line.has(name)) {
line = constant_line[name];
@@ -1571,6 +1718,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
List<String> tag_stack;
bool code_tag = false;
+ bool codeblock_tag = false;
int pos = 0;
while (pos < bbcode.length()) {
@@ -1582,7 +1730,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
if (brk_pos > pos) {
String text = bbcode.substr(pos, brk_pos - pos);
- if (!code_tag) {
+ if (!code_tag && !codeblock_tag) {
text = text.replace("\n", "\n\n");
}
p_rt->add_text(text);
@@ -1596,7 +1744,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
if (brk_end == -1) {
String text = bbcode.substr(brk_pos, bbcode.length() - brk_pos);
- if (!code_tag) {
+ if (!code_tag && !codeblock_tag) {
text = text.replace("\n", "\n\n");
}
p_rt->add_text(text);
@@ -1620,12 +1768,20 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
if (tag != "/img") {
p_rt->pop();
if (code_tag) {
+ // Pop both color and background color.
+ p_rt->pop();
+ p_rt->pop();
+ } else if (codeblock_tag) {
+ // Pop color, cell and table.
+ p_rt->pop();
+ p_rt->pop();
p_rt->pop();
}
}
code_tag = false;
+ codeblock_tag = false;
- } else if (code_tag) {
+ } else if (code_tag || codeblock_tag) {
p_rt->add_text("[");
pos = brk_pos + 1;
@@ -1634,24 +1790,32 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
const String link_tag = tag.substr(0, tag_end);
const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" ");
+ // Use monospace font with translucent colored background color to make clickable references
+ // easier to distinguish from inline code and other text.
p_rt->push_font(doc_code_font);
p_rt->push_color(link_color);
+ p_rt->push_bgcolor(code_color * Color(1, 1, 1, 0.15));
p_rt->push_meta("@" + link_tag + " " + link_target);
p_rt->add_text(link_target + (tag.begins_with("method ") ? "()" : ""));
p_rt->pop();
p_rt->pop();
p_rt->pop();
+ p_rt->pop();
pos = brk_end + 1;
} else if (doc->class_list.has(tag)) {
// Class reference tag such as [Node2D] or [SceneTree].
+ // Use monospace font with translucent colored background color to make clickable references
+ // easier to distinguish from inline code and other text.
p_rt->push_font(doc_code_font);
p_rt->push_color(link_color);
+ p_rt->push_bgcolor(code_color * Color(1, 1, 1, 0.15));
p_rt->push_meta("#" + tag);
p_rt->add_text(tag);
p_rt->pop();
p_rt->pop();
p_rt->pop();
+ p_rt->pop();
pos = brk_end + 1;
} else if (tag == "b") {
@@ -1664,16 +1828,31 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
p_rt->push_font(doc_italic_font);
pos = brk_end + 1;
tag_stack.push_front(tag);
- } else if (tag == "code" || tag == "codeblock") {
- // Use monospace font.
+ } else if (tag == "code") {
+ // Use monospace font with translucent background color to make code easier to distinguish from other text.
p_rt->push_font(doc_code_font);
+ p_rt->push_bgcolor(Color(0.5, 0.5, 0.5, 0.15));
p_rt->push_color(code_color);
code_tag = true;
pos = brk_end + 1;
tag_stack.push_front(tag);
+ } else if (tag == "codeblock") {
+ // Use monospace font with translucent background color to make code easier to distinguish from other text.
+ // Use a single-column table with cell row background color instead of `[bgcolor]`.
+ // This makes the background color highlight cover the entire block, rather than individual lines.
+ p_rt->push_font(doc_code_font);
+ p_rt->push_table(1);
+ p_rt->push_cell();
+ p_rt->set_cell_row_background_color(Color(0.5, 0.5, 0.5, 0.15), Color(0.5, 0.5, 0.5, 0.15));
+ p_rt->set_cell_padding(Rect2(10 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE));
+ p_rt->push_color(code_color);
+ codeblock_tag = true;
+ pos = brk_end + 1;
+ tag_stack.push_front(tag);
} else if (tag == "kbd") {
- // Use keyboard font with custom color.
+ // Use keyboard font with custom color and background color.
p_rt->push_font(doc_kbd_font);
+ p_rt->push_bgcolor(Color(0.5, 0.5, 0.5, 0.15));
p_rt->push_color(kbd_color);
code_tag = true; // Though not strictly a code tag, logic is similar.
pos = brk_end + 1;
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 766a09f485..9f8da938f1 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -110,6 +110,7 @@ class EditorHelp : public VBoxContainer {
HashMap<String, int> property_line;
HashMap<String, int> theme_property_line;
HashMap<String, int> constant_line;
+ HashMap<String, int> annotation_line;
HashMap<String, int> enum_line;
HashMap<String, HashMap<String, int>> enum_values_line;
int description_line = 0;
@@ -140,6 +141,8 @@ class EditorHelp : public VBoxContainer {
Ref<Font> doc_title_font;
Ref<Font> doc_code_font;
+ int doc_title_font_size;
+
int scroll_to = -1;
void _update_theme();
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index f454ba2c41..c48b443a0b 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -185,7 +185,7 @@ EditorHelpSearch::EditorHelpSearch() {
set_title(TTR("Search Help"));
get_ok_button()->set_disabled(true);
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
// Split search and results area.
VBoxContainer *vbox = memnew(VBoxContainer);
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 2bf0cd2f20..1711b23547 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -39,6 +39,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/plugins/script_editor_plugin.h"
#include "multi_node_edit.h"
#include "scene/gui/center_container.h"
#include "scene/property_utils.h"
@@ -322,7 +323,7 @@ void EditorProperty::_notification(int p_what) {
Ref<Texture2D> pinned_icon = get_theme_icon(SNAME("Pin"), SNAME("EditorIcons"));
int margin_w = get_theme_constant(SNAME("hseparator"), SNAME("Tree")) * 2;
int total_icon_w = margin_w + pinned_icon->get_width();
- int text_w = font->get_string_size(label, font_size, rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT, text_limit - total_icon_w).x;
+ int text_w = font->get_string_size(label, rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT, text_limit - total_icon_w, font_size).x;
int y = (size.height - pinned_icon->get_height()) / 2;
if (rtl) {
draw_texture(pinned_icon, Vector2(size.width - ofs - text_w - total_icon_w, y), color);
@@ -410,6 +411,10 @@ StringName EditorProperty::get_edited_property() const {
return property;
}
+void EditorProperty::set_doc_path(const String &p_doc_path) {
+ doc_path = p_doc_path;
+}
+
void EditorProperty::update_property() {
GDVIRTUAL_CALL(_update_property);
}
@@ -906,6 +911,10 @@ void EditorProperty::menu_option(int p_option) {
emit_signal(SNAME("property_pinned"), property, !pinned);
update();
} break;
+ case MENU_OPEN_DOCUMENTATION: {
+ ScriptEditor::get_singleton()->goto_help(doc_path);
+ EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
+ } break;
}
}
@@ -985,20 +994,25 @@ void EditorProperty::_update_popup() {
add_child(menu);
menu->connect("id_pressed", callable_mp(this, &EditorProperty::menu_option));
}
- menu->add_shortcut(ED_GET_SHORTCUT("property_editor/copy_property"), MENU_COPY_PROPERTY);
- menu->add_shortcut(ED_GET_SHORTCUT("property_editor/paste_property"), MENU_PASTE_PROPERTY);
- menu->add_shortcut(ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH);
+ menu->add_icon_shortcut(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/copy_property"), MENU_COPY_PROPERTY);
+ menu->add_icon_shortcut(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/paste_property"), MENU_PASTE_PROPERTY);
+ menu->add_icon_shortcut(get_theme_icon(SNAME("CopyNodePath"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH);
menu->set_item_disabled(MENU_PASTE_PROPERTY, is_read_only());
if (!pin_hidden) {
menu->add_separator();
if (can_pin) {
- menu->add_check_item(TTR("Pin value"), MENU_PIN_VALUE);
+ menu->add_icon_check_item(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")), TTR("Pin Value"), MENU_PIN_VALUE);
menu->set_item_checked(menu->get_item_index(MENU_PIN_VALUE), pinned);
- menu->set_item_tooltip(menu->get_item_index(MENU_PIN_VALUE), TTR("Pinning a value forces it to be saved even if it's equal to the default."));
} else {
- menu->add_check_item(vformat(TTR("Pin value [Disabled because '%s' is editor-only]"), property), MENU_PIN_VALUE);
+ menu->add_icon_check_item(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")), vformat(TTR("Pin Value [Disabled because '%s' is editor-only]"), property), MENU_PIN_VALUE);
menu->set_item_disabled(menu->get_item_index(MENU_PIN_VALUE), true);
}
+ menu->set_item_tooltip(menu->get_item_index(MENU_PIN_VALUE), TTR("Pinning a value forces it to be saved even if it's equal to the default."));
+ }
+
+ if (!doc_path.is_empty()) {
+ menu->add_separator();
+ menu->add_icon_item(get_theme_icon(SNAME("Help"), SNAME("EditorIcons")), TTR("Open Documentation"), MENU_OPEN_DOCUMENTATION);
}
}
@@ -1087,7 +1101,7 @@ void EditorInspectorCategory::_notification(int p_what) {
int hs = get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
- int w = font->get_string_size(label, font_size).width;
+ int w = font->get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
if (icon.is_valid()) {
w += hs + icon->get_width();
}
@@ -2844,7 +2858,7 @@ void EditorInspector::update_tree() {
restart_request_props.insert(p.name);
}
- String doc_hint;
+ PropertyDocInfo doc_info;
if (use_doc_hints) {
// Build the doc hint, to use as tooltip.
@@ -2856,16 +2870,15 @@ void EditorInspector::update_tree() {
}
StringName propname = property_prefix + p.name;
- String descr;
bool found = false;
// Search for the property description in the cache.
- HashMap<StringName, HashMap<StringName, String>>::Iterator E = descr_cache.find(classname);
+ HashMap<StringName, HashMap<StringName, PropertyDocInfo>>::Iterator E = doc_info_cache.find(classname);
if (E) {
- HashMap<StringName, String>::Iterator F = E->value.find(propname);
+ HashMap<StringName, PropertyDocInfo>::Iterator F = E->value.find(propname);
if (F) {
found = true;
- descr = F->value;
+ doc_info = F->value;
}
}
@@ -2873,10 +2886,11 @@ void EditorInspector::update_tree() {
// Build the property description String and add it to the cache.
DocTools *dd = EditorHelp::get_doc_data();
HashMap<String, DocData::ClassDoc>::Iterator F = dd->class_list.find(classname);
- while (F && descr.is_empty()) {
+ while (F && doc_info.description.is_empty()) {
for (int i = 0; i < F->value.properties.size(); i++) {
if (F->value.properties[i].name == propname.operator String()) {
- descr = DTR(F->value.properties[i].description);
+ doc_info.description = DTR(F->value.properties[i].description);
+ doc_info.path = "class_property:" + F->value.name + ":" + F->value.properties[i].name;
break;
}
}
@@ -2885,7 +2899,8 @@ void EditorInspector::update_tree() {
if (slices.size() == 2 && slices[0].begins_with("theme_override_")) {
for (int i = 0; i < F->value.theme_properties.size(); i++) {
if (F->value.theme_properties[i].name == slices[1]) {
- descr = DTR(F->value.theme_properties[i].description);
+ doc_info.description = DTR(F->value.theme_properties[i].description);
+ doc_info.path = "class_theme_item:" + F->value.name + ":" + F->value.theme_properties[i].name;
break;
}
}
@@ -2897,10 +2912,9 @@ void EditorInspector::update_tree() {
break;
}
}
- descr_cache[classname][propname] = descr;
- }
- doc_hint = descr;
+ doc_info_cache[classname][propname] = doc_info;
+ }
}
Vector<EditorInspectorPlugin::AddedEditor> editors;
@@ -2983,11 +2997,12 @@ void EditorInspector::update_tree() {
ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed));
ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED);
ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), varray(), CONNECT_DEFERRED);
- if (!doc_hint.is_empty()) {
- ep->set_tooltip(property_prefix + p.name + "::" + doc_hint);
+ if (!doc_info.description.is_empty()) {
+ ep->set_tooltip(property_prefix + p.name + "::" + doc_info.description);
} else {
ep->set_tooltip(property_prefix + p.name);
}
+ ep->set_doc_path(doc_info.path);
ep->update_property();
ep->_update_pin_flags();
ep->update_revert_and_pin_status();
@@ -3429,6 +3444,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
if (editor_property_map.has(p_path)) {
for (EditorProperty *E : editor_property_map[p_path]) {
+ E->set_checked(p_checked);
E->update_property();
E->update_revert_and_pin_status();
E->update_cache();
@@ -3472,7 +3488,7 @@ void EditorInspector::_property_pinned(const String &p_path, bool p_pinned) {
void EditorInspector::_property_selected(const String &p_path, int p_focusable) {
property_selected = p_path;
property_focusable = p_focusable;
- //deselect the others
+ // Deselect the others.
for (const KeyValue<StringName, List<EditorProperty *>> &F : editor_property_map) {
if (F.key == property_selected) {
continue;
@@ -3780,7 +3796,7 @@ void EditorInspector::_show_add_meta_dialog() {
add_meta_type->add_icon_item(get_theme_icon(type, "EditorIcons"), type, i);
}
hbc->add_child(add_meta_type);
- add_meta_dialog->get_ok_button()->set_text(TTR("Add"));
+ add_meta_dialog->set_ok_button_text(TTR("Add"));
add_child(add_meta_dialog);
add_meta_dialog->register_text_enter(add_meta_name);
add_meta_dialog->connect("confirmed", callable_mp(this, &EditorInspector::_add_meta_confirm));
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index d70d06c48b..9542f102cb 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -62,6 +62,7 @@ public:
MENU_PASTE_PROPERTY,
MENU_COPY_PROPERTY_PATH,
MENU_PIN_VALUE,
+ MENU_OPEN_DOCUMENTATION,
};
private:
@@ -71,6 +72,7 @@ private:
Object *object = nullptr;
StringName property;
String property_path;
+ String doc_path;
int property_usage;
@@ -148,6 +150,8 @@ public:
Object *get_edited_object();
StringName get_edited_property() const;
+ void set_doc_path(const String &p_doc_path);
+
virtual void update_property();
void update_revert_and_pin_status();
@@ -439,7 +443,7 @@ class EditorInspector : public ScrollContainer {
VBoxContainer *main_vbox = nullptr;
- //map use to cache the instantiated editors
+ // Map used to cache the instantiated editors.
HashMap<StringName, List<EditorProperty *>> editor_property_map;
List<EditorInspectorSection *> sections;
HashSet<StringName> pending;
@@ -473,7 +477,12 @@ class EditorInspector : public ScrollContainer {
int property_focusable;
int update_scroll_request;
- HashMap<StringName, HashMap<StringName, String>> descr_cache;
+ struct PropertyDocInfo {
+ String description;
+ String path;
+ };
+
+ HashMap<StringName, HashMap<StringName, PropertyDocInfo>> doc_info_cache;
HashMap<StringName, String> class_descr_cache;
HashSet<StringName> restart_request_props;
diff --git a/editor/editor_locale_dialog.cpp b/editor/editor_locale_dialog.cpp
index abef0dc353..cd8150d235 100644
--- a/editor/editor_locale_dialog.cpp
+++ b/editor/editor_locale_dialog.cpp
@@ -552,5 +552,5 @@ EditorLocaleDialog::EditorLocaleDialog() {
add_child(vb);
_update_tree();
- get_ok_button()->set_text(TTR("Select"));
+ set_ok_button_text(TTR("Select"));
}
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index dbe44aee1b..f26f47dbc7 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -181,7 +181,7 @@ void EditorLog::clear() {
}
void EditorLog::_process_message(const String &p_msg, MessageType p_type) {
- if (messages.size() > 0 && messages[messages.size() - 1].text == p_msg) {
+ if (messages.size() > 0 && messages[messages.size() - 1].text == p_msg && messages[messages.size() - 1].type == p_type) {
// If previous message is the same as the new one, increase previous count rather than adding another
// instance to the messages list.
LogMessage &previous = messages.write[messages.size() - 1];
@@ -258,6 +258,8 @@ void EditorLog::_add_log_line(LogMessage &p_message, bool p_replace_previous) {
switch (p_message.type) {
case MSG_TYPE_STD: {
} break;
+ case MSG_TYPE_STD_RICH: {
+ } break;
case MSG_TYPE_ERROR: {
log->push_color(get_theme_color(SNAME("error_color"), SNAME("Editor")));
Ref<Texture2D> icon = get_theme_icon(SNAME("Error"), SNAME("EditorIcons"));
@@ -285,11 +287,15 @@ void EditorLog::_add_log_line(LogMessage &p_message, bool p_replace_previous) {
log->pop();
}
- log->add_text(p_message.text);
+ if (p_message.type == MSG_TYPE_STD_RICH) {
+ log->append_text(p_message.text);
+ } else {
+ log->add_text(p_message.text);
+ }
// Need to use pop() to exit out of the RichTextLabels current "push" stack.
- // We only "push" in the above switch when message type != STD, so only pop when that is the case.
- if (p_message.type != MSG_TYPE_STD) {
+ // We only "push" in the above switch when message type != STD and RICH, so only pop when that is the case.
+ if (p_message.type != MSG_TYPE_STD && p_message.type != MSG_TYPE_STD_RICH) {
log->pop();
}
@@ -342,6 +348,7 @@ EditorLog::EditorLog() {
// Log - Rich Text Label.
log = memnew(RichTextLabel);
+ log->set_use_bbcode(true);
log->set_scroll_follow(true);
log->set_selection_enabled(true);
log->set_focus_mode(FOCUS_CLICK);
@@ -418,6 +425,7 @@ EditorLog::EditorLog() {
std_filter->initialize_button(TTR("Toggle visibility of standard output messages."), callable_mp(this, &EditorLog::_set_filter_active));
vb_right->add_child(std_filter->toggle_button);
type_filter_map.insert(MSG_TYPE_STD, std_filter);
+ type_filter_map.insert(MSG_TYPE_STD_RICH, std_filter);
LogFilter *error_filter = memnew(LogFilter(MSG_TYPE_ERROR));
error_filter->initialize_button(TTR("Toggle visibility of errors."), callable_mp(this, &EditorLog::_set_filter_active));
@@ -451,6 +459,10 @@ void EditorLog::deinit() {
EditorLog::~EditorLog() {
for (const KeyValue<MessageType, LogFilter *> &E : type_filter_map) {
- memdelete(E.value);
+ // MSG_TYPE_STD_RICH is connected to the std_filter button, so we do this
+ // to avoid it from being deleted twice, causing a crash on closing.
+ if (E.key != MSG_TYPE_STD_RICH) {
+ memdelete(E.value);
+ }
}
}
diff --git a/editor/editor_log.h b/editor/editor_log.h
index de0368501c..653fba9524 100644
--- a/editor/editor_log.h
+++ b/editor/editor_log.h
@@ -48,6 +48,7 @@ public:
enum MessageType {
MSG_TYPE_STD,
MSG_TYPE_ERROR,
+ MSG_TYPE_STD_RICH,
MSG_TYPE_WARNING,
MSG_TYPE_EDITOR,
};
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index b4b82b1edf..29c56c4500 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -75,6 +75,7 @@
#include "editor/dependency_editor.h"
#include "editor/editor_about.h"
#include "editor/editor_audio_buses.h"
+#include "editor/editor_build_profile.h"
#include "editor/editor_command_palette.h"
#include "editor/editor_data.h"
#include "editor/editor_export.h"
@@ -134,6 +135,7 @@
#include "editor/plugins/audio_stream_editor_plugin.h"
#include "editor/plugins/audio_stream_randomizer_editor_plugin.h"
#include "editor/plugins/bit_map_editor_plugin.h"
+#include "editor/plugins/bone_map_editor_plugin.h"
#include "editor/plugins/camera_3d_editor_plugin.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "editor/plugins/collision_polygon_2d_editor_plugin.h"
@@ -145,7 +147,7 @@
#include "editor/plugins/debugger_editor_plugin.h"
#include "editor/plugins/editor_debugger_plugin.h"
#include "editor/plugins/editor_preview_plugins.h"
-#include "editor/plugins/font_editor_plugin.h"
+#include "editor/plugins/font_config_plugin.h"
#include "editor/plugins/gdextension_export_plugin.h"
#include "editor/plugins/gpu_particles_2d_editor_plugin.h"
#include "editor/plugins/gpu_particles_3d_editor_plugin.h"
@@ -164,7 +166,6 @@
#include "editor/plugins/navigation_polygon_editor_plugin.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "editor/plugins/occluder_instance_3d_editor_plugin.h"
-#include "editor/plugins/ot_features_plugin.h"
#include "editor/plugins/packed_scene_translation_parser_plugin.h"
#include "editor/plugins/path_2d_editor_plugin.h"
#include "editor/plugins/path_3d_editor_plugin.h"
@@ -186,7 +187,6 @@
#include "editor/plugins/sprite_frames_editor_plugin.h"
#include "editor/plugins/style_box_editor_plugin.h"
#include "editor/plugins/sub_viewport_preview_editor_plugin.h"
-#include "editor/plugins/text_control_editor_plugin.h"
#include "editor/plugins/text_editor.h"
#include "editor/plugins/texture_3d_editor_plugin.h"
#include "editor/plugins/texture_editor_plugin.h"
@@ -460,7 +460,7 @@ void EditorNode::shortcut_input(const Ref<InputEvent> &p_event) {
_editor_select(EDITOR_SCRIPT);
} else if (ED_IS_SHORTCUT("editor/editor_help", p_event)) {
emit_signal(SNAME("request_help_search"), "");
- } else if (ED_IS_SHORTCUT("editor/editor_assetlib", p_event) && StreamPeerSSL::is_available()) {
+ } else if (ED_IS_SHORTCUT("editor/editor_assetlib", p_event) && AssetLibraryEditorPlugin::is_available()) {
_editor_select(EDITOR_ASSETLIB);
} else if (ED_IS_SHORTCUT("editor/editor_next", p_event)) {
_editor_select_next();
@@ -513,10 +513,10 @@ void EditorNode::_update_from_settings() {
uint32_t directional_shadow_16_bits = GLOBAL_GET("rendering/shadows/directional_shadow/16_bits");
RS::get_singleton()->directional_shadow_atlas_set_size(directional_shadow_size, directional_shadow_16_bits);
- RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/shadows/soft_shadow_quality")));
- RS::get_singleton()->shadows_quality_set(shadows_quality);
- RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/directional_shadow/soft_shadow_quality")));
- RS::get_singleton()->directional_shadow_quality_set(directional_shadow_quality);
+ RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/positional_shadow/soft_shadow_filter_quality")));
+ RS::get_singleton()->positional_soft_shadow_filter_set_quality(shadows_quality);
+ RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/directional_shadow/soft_shadow_filter_quality")));
+ RS::get_singleton()->directional_soft_shadow_filter_set_quality(directional_shadow_quality);
float probe_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed");
RS::get_singleton()->lightmap_set_probe_capture_update_speed(probe_update_speed);
RS::EnvironmentSDFGIFramesToConverge frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(int(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_converge")));
@@ -1260,7 +1260,7 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String
// This serves no purpose and confused people.
continue;
}
- file->add_filter("*." + E + " ; " + E.to_upper());
+ file->add_filter("*." + E, E.to_upper());
preferred.push_back(E);
}
// Lowest priority extension.
@@ -2333,6 +2333,13 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
return;
}
+ play_button->set_pressed(false);
+ play_button->set_icon(gui_base->get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ play_scene_button->set_pressed(false);
+ play_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons")));
+ play_custom_scene_button->set_pressed(false);
+ play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons")));
+
String write_movie_file;
if (write_movie_button->is_pressed()) {
if (p_current && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->has_meta("movie_file")) {
@@ -2347,13 +2354,6 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
}
}
- play_button->set_pressed(false);
- play_button->set_icon(gui_base->get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
- play_scene_button->set_pressed(false);
- play_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons")));
- play_custom_scene_button->set_pressed(false);
- play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons")));
-
String run_filename;
if (p_current || (editor_data.get_edited_scene_root() && !p_custom.is_empty() && p_custom == editor_data.get_edited_scene_root()->get_scene_file_path())) {
@@ -2472,7 +2472,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions);
file->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
- file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
+ file->add_filter("*." + extensions[i], extensions[i].to_upper());
}
Node *scene = editor_data.get_edited_scene_root();
@@ -2542,10 +2542,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if (scene_root) {
String scene_filename = scene_root->get_scene_file_path();
if (p_option == FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT) {
- save_confirmation->get_ok_button()->set_text(TTR("Save & Reload"));
+ save_confirmation->set_ok_button_text(TTR("Save & Reload"));
save_confirmation->set_text(vformat(TTR("Save changes to '%s' before reloading?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene"));
} else {
- save_confirmation->get_ok_button()->set_text(TTR("Save & Quit"));
+ save_confirmation->set_ok_button_text(TTR("Save & Quit"));
save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene"));
}
save_confirmation->popup_centered();
@@ -2618,7 +2618,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
ResourceSaver::get_recognized_extensions(sd, &extensions);
file->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
- file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
+ file->add_filter("*." + extensions[i], extensions[i].to_upper());
}
if (!scene->get_scene_file_path().is_empty()) {
@@ -2661,7 +2661,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case FILE_EXTERNAL_OPEN_SCENE: {
if (unsaved_cache && !p_confirmed) {
- confirmation->get_ok_button()->set_text(TTR("Open"));
+ confirmation->set_ok_button_text(TTR("Open"));
confirmation->set_text(TTR("Current scene not saved. Open anyway?"));
confirmation->popup_centered();
break;
@@ -2717,7 +2717,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
if (unsaved_cache && !p_confirmed) {
- confirmation->get_ok_button()->set_text(TTR("Reload Saved Scene"));
+ confirmation->set_ok_button_text(TTR("Reload Saved Scene"));
confirmation->set_text(
TTR("The current scene has unsaved changes.\nReload the saved scene anyway? This action cannot be undone."));
confirmation->popup_centered();
@@ -2793,9 +2793,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case RUN_SETTINGS: {
project_settings_editor->popup_project_settings();
} break;
- case RUN_WRITE_MOVIE: {
- _update_write_movie_icon();
- } break;
case FILE_INSTALL_ANDROID_SOURCE: {
if (p_confirmed) {
export_template_manager->install_android_template();
@@ -2809,6 +2806,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
}
} break;
+ case TOOLS_BUILD_PROFILE_MANAGER: {
+ build_profile_manager->popup_centered_clamped(Size2(700, 800) * EDSCALE, 0.8);
+ } break;
case RUN_USER_DATA_FOLDER: {
// Ensure_user_data_dir() to prevent the edge case: "Open User Data Folder" won't work after the project was renamed in ProjectSettingsEditor unless the project is saved.
OS::get_singleton()->ensure_user_data_dir();
@@ -2842,10 +2842,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
i = _next_unsaved_scene(true, ++i);
}
if (p_option == RELOAD_CURRENT_PROJECT) {
- save_confirmation->get_ok_button()->set_text(TTR("Save & Reload"));
+ save_confirmation->set_ok_button_text(TTR("Save & Reload"));
save_confirmation->set_text(TTR("Save changes to the following scene(s) before reloading?") + unsaved_scenes);
} else {
- save_confirmation->get_ok_button()->set_text(TTR("Save & Quit"));
+ save_confirmation->set_ok_button_text(TTR("Save & Quit"));
save_confirmation->set_text((p_option == FILE_QUIT ? TTR("Save changes to the following scene(s) before quitting?") : TTR("Save changes to the following scene(s) before opening Project Manager?")) + unsaved_scenes);
}
save_confirmation->popup_centered();
@@ -2907,7 +2907,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions);
file->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
- file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
+ file->add_filter("*." + extensions[i], extensions[i].to_upper());
}
Node *scene = editor_data.get_edited_scene_root();
@@ -3592,6 +3592,13 @@ void EditorNode::set_current_scene(int p_idx) {
call_deferred(SNAME("_set_main_scene_state"), state, get_edited_scene()); // Do after everything else is done setting up.
}
+void EditorNode::setup_color_picker(ColorPicker *picker) {
+ int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
+ int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
+ picker->set_color_mode((ColorPicker::ColorModeType)default_color_mode);
+ picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
+}
+
bool EditorNode::is_scene_open(const String &p_path) {
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
if (editor_data.get_scene_path(i) == p_path) {
@@ -4047,10 +4054,8 @@ Ref<ImageTexture> EditorNode::_load_custom_class_icon(const String &p_path) cons
Ref<Image> img = memnew(Image);
Error err = ImageLoader::load_image(p_path, img);
if (err == OK) {
- Ref<ImageTexture> icon = memnew(ImageTexture);
img->resize(16 * EDSCALE, 16 * EDSCALE, Image::INTERPOLATE_LANCZOS);
- icon->create_from_image(img);
- return icon;
+ return ImageTexture::create_from_image(img);
}
}
return nullptr;
@@ -4278,14 +4283,14 @@ Error EditorNode::export_preset(const String &p_preset, const String &p_path, bo
void EditorNode::show_accept(const String &p_text, const String &p_title) {
current_menu_option = -1;
- accept->get_ok_button()->set_text(p_title);
+ accept->set_ok_button_text(p_title);
accept->set_text(p_text);
accept->popup_centered();
}
void EditorNode::show_save_accept(const String &p_text, const String &p_title) {
current_menu_option = -1;
- save_accept->get_ok_button()->set_text(p_title);
+ save_accept->set_ok_button_text(p_title);
save_accept->set_text(p_text);
save_accept->popup_centered();
}
@@ -4339,16 +4344,16 @@ void EditorNode::_dock_make_float() {
window->set_title(dock->get_name());
Panel *p = memnew(Panel);
p->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("PanelForeground"), SNAME("EditorStyles")));
- p->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ p->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
window->add_child(p);
MarginContainer *margin = memnew(MarginContainer);
- margin->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ margin->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
margin->add_theme_constant_override("margin_right", borders.width);
margin->add_theme_constant_override("margin_top", borders.height);
margin->add_theme_constant_override("margin_left", borders.width);
margin->add_theme_constant_override("margin_bottom", borders.height);
window->add_child(margin);
- dock->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ dock->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
margin->add_child(dock);
window->set_wrap_controls(true);
window->set_size(dock_size);
@@ -4595,8 +4600,14 @@ void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p
names += name;
}
+ String config_key = "dock_" + itos(i + 1);
+
+ if (p_layout->has_section_key(p_section, config_key)) {
+ p_layout->erase_section_key(p_section, config_key);
+ }
+
if (!names.is_empty()) {
- p_layout->set_value(p_section, "dock_" + itos(i + 1), names);
+ p_layout->set_value(p_section, config_key, names);
}
}
@@ -4957,22 +4968,14 @@ String EditorNode::get_run_playing_scene() const {
return run_filename;
}
-void EditorNode::_update_write_movie_icon() {
- if (write_movie_button->is_pressed()) {
- write_movie_button->set_icon(gui_base->get_theme_icon(SNAME("MainMovieWriteEnabled"), SNAME("EditorIcons")));
- } else {
- write_movie_button->set_icon(gui_base->get_theme_icon(SNAME("MainMovieWrite"), SNAME("EditorIcons")));
- }
-}
-
void EditorNode::_immediate_dialog_confirmed() {
immediate_dialog_confirmed = true;
}
bool EditorNode::immediate_confirmation_dialog(const String &p_text, const String &p_ok_text, const String &p_cancel_text) {
ConfirmationDialog *cd = memnew(ConfirmationDialog);
cd->set_text(p_text);
- cd->get_ok_button()->set_text(p_ok_text);
- cd->get_cancel_button()->set_text(p_cancel_text);
+ cd->set_ok_button_text(p_ok_text);
+ cd->set_cancel_button_text(p_cancel_text);
cd->connect("confirmed", callable_mp(singleton, &EditorNode::_immediate_dialog_confirmed));
singleton->gui_base->add_child(cd);
@@ -5034,14 +5037,14 @@ void EditorNode::_layout_menu_option(int p_id) {
case SETTINGS_LAYOUT_SAVE: {
current_menu_option = p_id;
layout_dialog->set_title(TTR("Save Layout"));
- layout_dialog->get_ok_button()->set_text(TTR("Save"));
+ layout_dialog->set_ok_button_text(TTR("Save"));
layout_dialog->popup_centered();
layout_dialog->set_name_line_enabled(true);
} break;
case SETTINGS_LAYOUT_DELETE: {
current_menu_option = p_id;
layout_dialog->set_title(TTR("Delete Layout"));
- layout_dialog->get_ok_button()->set_text(TTR("Delete"));
+ layout_dialog->set_ok_button_text(TTR("Delete"));
layout_dialog->popup_centered();
layout_dialog->set_name_line_enabled(false);
} break;
@@ -5083,7 +5086,7 @@ void EditorNode::_scene_tab_closed(int p_tab, int option) {
? saved_version != editor_data.get_undo_redo().get_version()
: editor_data.get_scene_version(p_tab) != 0;
if (unsaved) {
- save_confirmation->get_ok_button()->set_text(TTR("Save & Close"));
+ save_confirmation->set_ok_button_text(TTR("Save & Close"));
save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), !scene->get_scene_file_path().is_empty() ? scene->get_scene_file_path() : "unsaved scene"));
save_confirmation->popup_centered();
} else {
@@ -5405,9 +5408,7 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
Ref<Image> img = texture->get_image();
img = img->duplicate();
img->resize(48, 48); // meh
- Ref<ImageTexture> resized_pic = Ref<ImageTexture>(memnew(ImageTexture));
- resized_pic->create_from_image(img);
- preview = resized_pic;
+ preview = ImageTexture::create_from_image(img);
}
drag_preview->set_texture(preview);
@@ -5752,12 +5753,12 @@ void EditorNode::_feature_profile_changed() {
main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D));
main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT));
- if (StreamPeerSSL::is_available()) {
+ if (AssetLibraryEditorPlugin::is_available()) {
main_editor_buttons[EDITOR_ASSETLIB]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB));
}
if ((profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D) && singleton->main_editor_buttons[EDITOR_3D]->is_pressed()) ||
(profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT) && singleton->main_editor_buttons[EDITOR_SCRIPT]->is_pressed()) ||
- (StreamPeerSSL::is_available() && profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB) && singleton->main_editor_buttons[EDITOR_ASSETLIB]->is_pressed())) {
+ (AssetLibraryEditorPlugin::is_available() && profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB) && singleton->main_editor_buttons[EDITOR_ASSETLIB]->is_pressed())) {
_editor_select(EDITOR_2D);
}
} else {
@@ -5769,7 +5770,7 @@ void EditorNode::_feature_profile_changed() {
FileSystemDock::get_singleton()->set_visible(true);
main_editor_buttons[EDITOR_3D]->set_visible(true);
main_editor_buttons[EDITOR_SCRIPT]->set_visible(true);
- if (StreamPeerSSL::is_available()) {
+ if (AssetLibraryEditorPlugin::is_available()) {
main_editor_buttons[EDITOR_ASSETLIB]->set_visible(true);
}
}
@@ -5829,9 +5830,15 @@ static Node *_resource_get_edited_scene() {
return EditorNode::get_singleton()->get_edited_scene();
}
-void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_error) {
+void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_error, bool p_rich) {
EditorNode *en = static_cast<EditorNode *>(p_this);
- en->log->add_message(p_string, p_error ? EditorLog::MSG_TYPE_ERROR : EditorLog::MSG_TYPE_STD);
+ if (p_error) {
+ en->log->add_message(p_string, EditorLog::MSG_TYPE_ERROR);
+ } else if (p_rich) {
+ en->log->add_message(p_string, EditorLog::MSG_TYPE_STD_RICH);
+ } else {
+ en->log->add_message(p_string, EditorLog::MSG_TYPE_STD);
+ }
}
static void _execute_thread(void *p_ud) {
@@ -6123,7 +6130,9 @@ EditorNode::EditorNode() {
EDITOR_DEF_RST("interface/inspector/default_property_name_style", EditorPropertyNameProcessor::STYLE_CAPITALIZED);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_property_name_style", PROPERTY_HINT_ENUM, "Raw,Capitalized,Localized"));
EDITOR_DEF_RST("interface/inspector/default_float_step", 0.001);
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::FLOAT, "interface/inspector/default_float_step", PROPERTY_HINT_RANGE, "0,1,0"));
+ // The lowest value is equal to the minimum float step for 32-bit floats.
+ // The step must be set manually, as changing this setting should not change the step here.
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::FLOAT, "interface/inspector/default_float_step", PROPERTY_HINT_RANGE, "0.0000001,1,0.0000001"));
EDITOR_DEF_RST("interface/inspector/disable_folding", false);
EDITOR_DEF_RST("interface/inspector/auto_unfold_foreign_scenes", true);
EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false);
@@ -6131,7 +6140,7 @@ EditorNode::EditorNode() {
EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "Script,MeshLibrary");
EDITOR_DEF("interface/inspector/default_color_picker_mode", 0);
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW", PROPERTY_USAGE_DEFAULT));
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW,OKHSL", PROPERTY_USAGE_DEFAULT));
EDITOR_DEF("interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_OKHSL_CIRCLE);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle,OKHSL Circle", PROPERTY_USAGE_DEFAULT));
@@ -6144,11 +6153,11 @@ EditorNode::EditorNode() {
theme_base = memnew(Control);
add_child(theme_base);
- theme_base->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ theme_base->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
gui_base = memnew(Panel);
theme_base->add_child(gui_base);
- gui_base->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ gui_base->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
theme_base->set_theme(theme);
gui_base->set_theme(theme);
@@ -6166,7 +6175,7 @@ EditorNode::EditorNode() {
main_vbox = memnew(VBoxContainer);
gui_base->add_child(main_vbox);
- main_vbox->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 8);
+ main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 8);
main_vbox->add_theme_constant_override("separation", 8 * EDSCALE);
menu_hb = memnew(HBoxContainer);
@@ -6453,6 +6462,10 @@ EditorNode::EditorNode() {
feature_profile_manager = memnew(EditorFeatureProfileManager);
gui_base->add_child(feature_profile_manager);
+
+ build_profile_manager = memnew(EditorBuildProfileManager);
+ gui_base->add_child(build_profile_manager);
+
about = memnew(EditorAbout);
gui_base->add_child(about);
feature_profile_manager->connect("current_feature_profile_changed", callable_mp(this, &EditorNode::_feature_profile_changed));
@@ -6545,6 +6558,10 @@ EditorNode::EditorNode() {
p->add_item(TTR("Install Android Build Template..."), FILE_INSTALL_ANDROID_SOURCE);
p->add_item(TTR("Open User Data Folder"), RUN_USER_DATA_FOLDER);
+ p->add_separator();
+ p->add_item(TTR("Customize Engine Build Configuration..."), TOOLS_BUILD_PROFILE_MANAGER);
+ p->add_separator();
+
plugin_config_dialog = memnew(PluginConfigDialog);
plugin_config_dialog->connect("plugin_ready", callable_mp(this, &EditorNode::_on_plugin_ready));
gui_base->add_child(plugin_config_dialog);
@@ -6727,15 +6744,12 @@ EditorNode::EditorNode() {
write_movie_button->set_pressed(false);
write_movie_button->set_icon(gui_base->get_theme_icon(SNAME("MainMovieWrite"), SNAME("EditorIcons")));
write_movie_button->set_focus_mode(Control::FOCUS_NONE);
- write_movie_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(RUN_WRITE_MOVIE));
write_movie_button->set_tooltip(TTR("Enable Movie Maker mode.\nThe project will run at stable FPS and the visual and audio output will be recorded to a video file."));
- // Restore these values to something more useful so it ignores the theme
- write_movie_button->add_theme_color_override("icon_normal_color", Color(1, 1, 1, 0.4));
- write_movie_button->add_theme_color_override("icon_pressed_color", Color(1, 1, 1, 1));
- write_movie_button->add_theme_color_override("icon_hover_color", Color(1.2, 1.2, 1.2, 0.4));
- write_movie_button->add_theme_color_override("icon_hover_pressed_color", Color(1.2, 1.2, 1.2, 1));
- write_movie_button->add_theme_color_override("icon_focus_color", Color(1, 1, 1, 1));
- write_movie_button->add_theme_color_override("icon_disabled_color", Color(1, 1, 1, 0.4));
+
+ // This button behaves differently, so color it as such.
+ write_movie_button->add_theme_color_override("icon_normal_color", Color(1, 1, 1, 0.7));
+ write_movie_button->add_theme_color_override("icon_pressed_color", gui_base->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ write_movie_button->add_theme_color_override("icon_hover_color", Color(1, 1, 1, 0.9));
HBoxContainer *right_menu_hb = memnew(HBoxContainer);
menu_hb->add_child(right_menu_hb);
@@ -6782,7 +6796,7 @@ EditorNode::EditorNode() {
video_restart_dialog = memnew(ConfirmationDialog);
video_restart_dialog->set_text(TTR("Changing the video driver requires restarting the editor."));
- video_restart_dialog->get_ok_button()->set_text(TTR("Save & Restart"));
+ video_restart_dialog->set_ok_button_text(TTR("Save & Restart"));
video_restart_dialog->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(SET_RENDERING_DRIVER_SAVE_AND_RESTART));
gui_base->add_child(video_restart_dialog);
@@ -6951,7 +6965,7 @@ EditorNode::EditorNode() {
custom_build_manage_templates = memnew(ConfirmationDialog);
custom_build_manage_templates->set_text(TTR("Android build template is missing, please install relevant templates."));
- custom_build_manage_templates->get_ok_button()->set_text(TTR("Manage Templates"));
+ custom_build_manage_templates->set_ok_button_text(TTR("Manage Templates"));
custom_build_manage_templates->add_button(TTR("Install from file"))->connect("pressed", callable_mp(this, &EditorNode::_menu_option), varray(SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE));
custom_build_manage_templates->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(SETTINGS_MANAGE_EXPORT_TEMPLATES));
gui_base->add_child(custom_build_manage_templates);
@@ -6966,13 +6980,13 @@ EditorNode::EditorNode() {
install_android_build_template = memnew(ConfirmationDialog);
install_android_build_template->set_text(TTR("This will set up your project for custom Android builds by installing the source template to \"res://android/build\".\nYou can then apply modifications and build your own custom APK on export (adding modules, changing the AndroidManifest.xml, etc.).\nNote that in order to make custom builds instead of using pre-built APKs, the \"Use Custom Build\" option should be enabled in the Android export preset."));
- install_android_build_template->get_ok_button()->set_text(TTR("Install"));
+ install_android_build_template->set_ok_button_text(TTR("Install"));
install_android_build_template->connect("confirmed", callable_mp(this, &EditorNode::_menu_confirm_current));
gui_base->add_child(install_android_build_template);
remove_android_build_template = memnew(ConfirmationDialog);
remove_android_build_template->set_text(TTR("The Android build template is already installed in this project and it won't be overwritten.\nRemove the \"res://android/build\" directory manually before attempting this operation again."));
- remove_android_build_template->get_ok_button()->set_text(TTR("Show in File Manager"));
+ remove_android_build_template->set_ok_button_text(TTR("Show in File Manager"));
remove_android_build_template->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES));
gui_base->add_child(remove_android_build_template);
@@ -6983,7 +6997,7 @@ EditorNode::EditorNode() {
file_templates->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
file_templates->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
file_templates->clear_filters();
- file_templates->add_filter("*.tpz ; " + TTR("Template Package"));
+ file_templates->add_filter("*.tpz", TTR("Template Package"));
file = memnew(EditorFileDialog);
gui_base->add_child(file);
@@ -7047,7 +7061,7 @@ EditorNode::EditorNode() {
disk_changed->connect("confirmed", callable_mp(this, &EditorNode::_reload_modified_scenes));
disk_changed->connect("confirmed", callable_mp(this, &EditorNode::_reload_project_settings));
- disk_changed->get_ok_button()->set_text(TTR("Reload"));
+ disk_changed->set_ok_button_text(TTR("Reload"));
disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave");
disk_changed->connect("custom_action", callable_mp(this, &EditorNode::_resave_scenes));
@@ -7065,15 +7079,11 @@ EditorNode::EditorNode() {
ScriptTextEditor::register_editor(); // Register one for text scripts.
TextEditor::register_editor();
- // Asset Library can't work on Web editor for now as most assets are sourced
- // directly from GitHub which does not set CORS.
-#ifndef JAVASCRIPT_ENABLED
- if (StreamPeerSSL::is_available()) {
+ if (AssetLibraryEditorPlugin::is_available()) {
add_editor_plugin(memnew(AssetLibraryEditorPlugin));
} else {
- WARN_PRINT("Asset Library not available, as it requires SSL to work.");
+ print_verbose("Asset Library not available (due to using Web editor, or SSL support disabled).");
}
-#endif
// Add interface before adding plugins.
@@ -7082,64 +7092,66 @@ EditorNode::EditorNode() {
// More visually meaningful to have this later.
raise_bottom_panel_item(AnimationPlayerEditor::get_singleton());
- add_editor_plugin(memnew(ReplicationEditorPlugin));
add_editor_plugin(VersionControlEditorPlugin::get_singleton());
- add_editor_plugin(memnew(ShaderEditorPlugin));
- add_editor_plugin(memnew(ShaderFileEditorPlugin));
+ // This list is alphabetized, and plugins that depend on Node2D are in their own section below.
+ add_editor_plugin(memnew(AnimationTreeEditorPlugin));
+ add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
+ add_editor_plugin(memnew(AudioStreamEditorPlugin));
+ add_editor_plugin(memnew(AudioStreamRandomizerEditorPlugin));
+ add_editor_plugin(memnew(BitMapEditorPlugin));
+ add_editor_plugin(memnew(BoneMapEditorPlugin));
add_editor_plugin(memnew(Camera3DEditorPlugin));
- add_editor_plugin(memnew(ThemeEditorPlugin));
- add_editor_plugin(memnew(MultiMeshEditorPlugin));
+ add_editor_plugin(memnew(ControlEditorPlugin));
+ add_editor_plugin(memnew(CPUParticles3DEditorPlugin));
+ add_editor_plugin(memnew(CurveEditorPlugin));
+ add_editor_plugin(memnew(FontEditorPlugin));
+ add_editor_plugin(memnew(GPUParticles3DEditorPlugin));
+ add_editor_plugin(memnew(GPUParticlesCollisionSDF3DEditorPlugin));
+ add_editor_plugin(memnew(GradientEditorPlugin));
+ add_editor_plugin(memnew(GradientTexture2DEditorPlugin));
+ add_editor_plugin(memnew(InputEventEditorPlugin));
+ add_editor_plugin(memnew(LightmapGIEditorPlugin));
+ add_editor_plugin(memnew(MaterialEditorPlugin));
+ add_editor_plugin(memnew(MeshEditorPlugin));
add_editor_plugin(memnew(MeshInstance3DEditorPlugin));
- add_editor_plugin(memnew(AnimationTreeEditorPlugin));
add_editor_plugin(memnew(MeshLibraryEditorPlugin));
- add_editor_plugin(memnew(StyleBoxEditorPlugin));
- add_editor_plugin(memnew(Sprite2DEditorPlugin));
- add_editor_plugin(memnew(Skeleton2DEditorPlugin));
- add_editor_plugin(memnew(GPUParticles2DEditorPlugin));
- add_editor_plugin(memnew(GPUParticles3DEditorPlugin));
- add_editor_plugin(memnew(CPUParticles2DEditorPlugin));
- add_editor_plugin(memnew(CPUParticles3DEditorPlugin));
- add_editor_plugin(memnew(ResourcePreloaderEditorPlugin));
+ add_editor_plugin(memnew(MultiMeshEditorPlugin));
+ add_editor_plugin(memnew(OccluderInstance3DEditorPlugin));
+ add_editor_plugin(memnew(Path3DEditorPlugin));
+ add_editor_plugin(memnew(PhysicalBone3DEditorPlugin));
add_editor_plugin(memnew(Polygon3DEditorPlugin));
- add_editor_plugin(memnew(CollisionPolygon2DEditorPlugin));
- add_editor_plugin(memnew(TilesEditorPlugin));
+ add_editor_plugin(memnew(ReplicationEditorPlugin));
+ add_editor_plugin(memnew(ResourcePreloaderEditorPlugin));
+ add_editor_plugin(memnew(ShaderEditorPlugin));
+ add_editor_plugin(memnew(ShaderFileEditorPlugin));
+ add_editor_plugin(memnew(Skeleton3DEditorPlugin));
+ add_editor_plugin(memnew(SkeletonIK3DEditorPlugin));
add_editor_plugin(memnew(SpriteFramesEditorPlugin));
+ add_editor_plugin(memnew(StyleBoxEditorPlugin));
+ add_editor_plugin(memnew(SubViewportPreviewEditorPlugin));
+ add_editor_plugin(memnew(Texture3DEditorPlugin));
+ add_editor_plugin(memnew(TextureEditorPlugin));
+ add_editor_plugin(memnew(TextureLayeredEditorPlugin));
add_editor_plugin(memnew(TextureRegionEditorPlugin));
+ add_editor_plugin(memnew(ThemeEditorPlugin));
add_editor_plugin(memnew(VoxelGIEditorPlugin));
- add_editor_plugin(memnew(LightmapGIEditorPlugin));
- add_editor_plugin(memnew(OccluderInstance3DEditorPlugin));
- add_editor_plugin(memnew(Path2DEditorPlugin));
- add_editor_plugin(memnew(Path3DEditorPlugin));
- add_editor_plugin(memnew(Line2DEditorPlugin));
- add_editor_plugin(memnew(Polygon2DEditorPlugin));
+
+ // 2D
+ add_editor_plugin(memnew(CollisionPolygon2DEditorPlugin));
+ add_editor_plugin(memnew(CollisionShape2DEditorPlugin));
+ add_editor_plugin(memnew(CPUParticles2DEditorPlugin));
+ add_editor_plugin(memnew(GPUParticles2DEditorPlugin));
add_editor_plugin(memnew(LightOccluder2DEditorPlugin));
+ add_editor_plugin(memnew(Line2DEditorPlugin));
add_editor_plugin(memnew(NavigationPolygonEditorPlugin));
- add_editor_plugin(memnew(GradientEditorPlugin));
- add_editor_plugin(memnew(CollisionShape2DEditorPlugin));
- add_editor_plugin(memnew(CurveEditorPlugin));
- add_editor_plugin(memnew(FontEditorPlugin));
- add_editor_plugin(memnew(OpenTypeFeaturesEditorPlugin));
- add_editor_plugin(memnew(TextureEditorPlugin));
- add_editor_plugin(memnew(TextureLayeredEditorPlugin));
- add_editor_plugin(memnew(Texture3DEditorPlugin));
- add_editor_plugin(memnew(AudioStreamEditorPlugin));
- add_editor_plugin(memnew(AudioStreamRandomizerEditorPlugin));
- add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
- add_editor_plugin(memnew(Skeleton3DEditorPlugin));
- add_editor_plugin(memnew(SkeletonIK3DEditorPlugin));
- add_editor_plugin(memnew(PhysicalBone3DEditorPlugin));
- add_editor_plugin(memnew(MeshEditorPlugin));
- add_editor_plugin(memnew(MaterialEditorPlugin));
- add_editor_plugin(memnew(GPUParticlesCollisionSDF3DEditorPlugin));
- add_editor_plugin(memnew(InputEventEditorPlugin));
- add_editor_plugin(memnew(SubViewportPreviewEditorPlugin));
- add_editor_plugin(memnew(TextControlEditorPlugin));
- add_editor_plugin(memnew(ControlEditorPlugin));
- add_editor_plugin(memnew(GradientTexture2DEditorPlugin));
- add_editor_plugin(memnew(BitMapEditorPlugin));
+ add_editor_plugin(memnew(Path2DEditorPlugin));
+ add_editor_plugin(memnew(Polygon2DEditorPlugin));
add_editor_plugin(memnew(RayCast2DEditorPlugin));
+ add_editor_plugin(memnew(Skeleton2DEditorPlugin));
+ add_editor_plugin(memnew(Sprite2DEditorPlugin));
+ add_editor_plugin(memnew(TilesEditorPlugin));
for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) {
add_editor_plugin(EditorPlugins::create(i));
@@ -7197,6 +7209,7 @@ EditorNode::EditorNode() {
vshader_convert.instantiate();
resource_conversion_plugins.push_back(vshader_convert);
}
+
update_spinner_step_msec = OS::get_singleton()->get_ticks_msec();
update_spinner_step_frame = Engine::get_singleton()->get_frames_drawn();
@@ -7226,7 +7239,7 @@ EditorNode::EditorNode() {
set_process(true);
open_imported = memnew(ConfirmationDialog);
- open_imported->get_ok_button()->set_text(TTR("Open Anyway"));
+ open_imported->set_ok_button_text(TTR("Open Anyway"));
new_inherited_button = open_imported->add_button(TTR("New Inherited"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "inherit");
open_imported->connect("confirmed", callable_mp(this, &EditorNode::_open_imported));
open_imported->connect("custom_action", callable_mp(this, &EditorNode::_inherit_imported));
@@ -7267,7 +7280,7 @@ EditorNode::EditorNode() {
pick_main_scene = memnew(ConfirmationDialog);
gui_base->add_child(pick_main_scene);
- pick_main_scene->get_ok_button()->set_text(TTR("Select"));
+ pick_main_scene->set_ok_button_text(TTR("Select"));
pick_main_scene->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(SETTINGS_PICK_MAIN_SCENE));
select_current_scene_button = pick_main_scene->add_button(TTR("Select Current"), true, "select_current");
pick_main_scene->connect("custom_action", callable_mp(this, &EditorNode::_pick_main_scene_custom_action));
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 89f80baeb9..d33c7f5875 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -95,6 +95,7 @@ class TabContainer;
class TextureProgressBar;
class VSplitContainer;
class Window;
+class EditorBuildProfileManager;
class EditorNode : public Node {
GDCLASS(EditorNode, Node);
@@ -163,6 +164,7 @@ private:
EDIT_REDO,
EDIT_RELOAD_SAVED_SCENE,
TOOLS_ORPHAN_RESOURCES,
+ TOOLS_BUILD_PROFILE_MANAGER,
TOOLS_CUSTOM,
RESOURCE_SAVE,
RESOURCE_SAVE_AS,
@@ -173,7 +175,6 @@ private:
RUN_PLAY_CUSTOM_SCENE,
RUN_SETTINGS,
RUN_USER_DATA_FOLDER,
- RUN_WRITE_MOVIE,
RELOAD_CURRENT_PROJECT,
RUN_PROJECT_MANAGER,
RUN_VCS_METADATA,
@@ -378,6 +379,7 @@ private:
EditorFileDialog *file = nullptr;
ExportTemplateManager *export_template_manager = nullptr;
EditorFeatureProfileManager *feature_profile_manager = nullptr;
+ EditorBuildProfileManager *build_profile_manager = nullptr;
EditorFileDialog *file_templates = nullptr;
EditorFileDialog *file_export_lib = nullptr;
EditorFileDialog *file_script = nullptr;
@@ -505,7 +507,7 @@ private:
static void _load_error_notify(void *p_ud, const String &p_text);
static void _file_access_close_error_notify(const String &p_str);
- static void _print_handler(void *p_this, const String &p_string, bool p_error);
+ static void _print_handler(void *p_this, const String &p_string, bool p_error, bool p_rich);
static void _resource_saved(Ref<Resource> p_resource, const String &p_path);
static void _resource_loaded(Ref<Resource> p_resource, const String &p_path);
@@ -669,7 +671,6 @@ private:
void _pick_main_scene_custom_action(const String &p_custom_action_name);
void _immediate_dialog_confirmed();
- void _update_write_movie_icon();
void _select_default_main_screen_plugin();
void _bottom_panel_switch(bool p_enable, int p_idx);
@@ -785,6 +786,8 @@ public:
void set_current_version(uint64_t p_version);
void set_current_scene(int p_idx);
+ void setup_color_picker(ColorPicker *picker);
+
void request_instance_scene(const String &p_path);
void request_instantiate_scenes(const Vector<String> &p_files);
diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp
index 6453db3b0b..dc77b5fea9 100644
--- a/editor/editor_path.cpp
+++ b/editor/editor_path.cpp
@@ -198,7 +198,7 @@ EditorPath::EditorPath(EditorSelectionHistory *p_history) {
history = p_history;
MarginContainer *main_mc = memnew(MarginContainer);
- main_mc->set_anchors_and_offsets_preset(PRESET_WIDE);
+ main_mc->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
main_mc->add_theme_constant_override("margin_left", 4 * EDSCALE);
main_mc->add_theme_constant_override("margin_right", 6 * EDSCALE);
add_child(main_mc);
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 639846861b..d9c2a42114 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -133,8 +133,7 @@ Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh
Main::iteration();
Ref<Image> img = RS::get_singleton()->texture_2d_get(viewport_texture);
ERR_CONTINUE(!img.is_valid() || img->is_empty());
- Ref<ImageTexture> it(memnew(ImageTexture));
- it->create_from_image(img);
+ Ref<ImageTexture> it = ImageTexture::create_from_image(img);
RS::get_singleton()->free(inst);
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index e5105fdedc..808e11e337 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -836,7 +836,7 @@ EditorPropertyLayersGrid::EditorPropertyLayersGrid() {
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"));
+ rename_dialog->set_ok_button_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));
@@ -1304,7 +1304,7 @@ void EditorPropertyObjectID::update_property() {
ObjectID id = get_edited_object()->get(get_edited_property());
if (id.is_valid()) {
- edit->set_text(type + " ID: " + itos(id));
+ edit->set_text(type + " ID: " + uitos(id));
edit->set_disabled(false);
edit->set_icon(EditorNode::get_singleton()->get_class_icon(type));
} else {
@@ -1328,6 +1328,54 @@ EditorPropertyObjectID::EditorPropertyObjectID() {
edit->connect("pressed", callable_mp(this, &EditorPropertyObjectID::_edit_pressed));
}
+///////////////////// SIGNAL /////////////////////////
+
+void EditorPropertySignal::_edit_pressed() {
+ Signal signal = get_edited_object()->get(get_edited_property());
+ emit_signal(SNAME("object_id_selected"), get_edited_property(), signal.get_object_id());
+}
+
+void EditorPropertySignal::update_property() {
+ String type = base_type;
+
+ Signal signal = get_edited_object()->get(get_edited_property());
+
+ edit->set_text("Signal: " + signal.get_name());
+ edit->set_disabled(false);
+ edit->set_icon(get_theme_icon(SNAME("Signals"), SNAME("EditorIcons")));
+}
+
+void EditorPropertySignal::_bind_methods() {
+}
+
+EditorPropertySignal::EditorPropertySignal() {
+ edit = memnew(Button);
+ add_child(edit);
+ add_focusable(edit);
+ edit->connect("pressed", callable_mp(this, &EditorPropertySignal::_edit_pressed));
+}
+
+///////////////////// CALLABLE /////////////////////////
+
+void EditorPropertyCallable::update_property() {
+ String type = base_type;
+
+ Callable callable = get_edited_object()->get(get_edited_property());
+
+ edit->set_text("Callable");
+ edit->set_disabled(true);
+ edit->set_icon(get_theme_icon(SNAME("Callable"), SNAME("EditorIcons")));
+}
+
+void EditorPropertyCallable::_bind_methods() {
+}
+
+EditorPropertyCallable::EditorPropertyCallable() {
+ edit = memnew(Button);
+ add_child(edit);
+ add_focusable(edit);
+}
+
///////////////////// FLOAT /////////////////////////
void EditorPropertyFloat::_set_read_only(bool p_read_only) {
@@ -2959,19 +3007,6 @@ void EditorPropertyColor::_popup_closed() {
}
}
-void EditorPropertyColor::_picker_created() {
- // get default color picker mode from editor settings
- int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
- if (default_color_mode == 1) {
- picker->get_picker()->set_hsv_mode(true);
- } else if (default_color_mode == 2) {
- picker->get_picker()->set_raw_mode(true);
- }
-
- int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
- picker->get_picker()->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
-}
-
void EditorPropertyColor::_picker_opening() {
last_color = picker->get_pick_color();
}
@@ -3016,7 +3051,7 @@ EditorPropertyColor::EditorPropertyColor() {
picker->set_flat(true);
picker->connect("color_changed", callable_mp(this, &EditorPropertyColor::_color_changed));
picker->connect("popup_closed", callable_mp(this, &EditorPropertyColor::_popup_closed));
- picker->connect("picker_created", callable_mp(this, &EditorPropertyColor::_picker_created));
+ picker->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(picker->get_picker()));
picker->get_popup()->connect("about_to_popup", callable_mp(this, &EditorPropertyColor::_picker_opening));
}
@@ -3035,13 +3070,17 @@ String EditorPropertyNodePath::_get_meta_pointer_property() const {
Variant EditorPropertyNodePath::_get_cache_value(const StringName &p_prop, bool &r_valid) const {
if (p_prop == get_edited_property()) {
r_valid = true;
- return const_cast<EditorPropertyNodePath *>(this)->get_edited_object()->get(_get_meta_pointer_property(), &r_valid);
+ return const_cast<EditorPropertyNodePath *>(this)->get_edited_object()->get(pointer_mode ? StringName(_get_meta_pointer_property()) : get_edited_property(), &r_valid);
}
return Variant();
}
StringName EditorPropertyNodePath::_get_revert_property() const {
- return _get_meta_pointer_property();
+ if (pointer_mode) {
+ return _get_meta_pointer_property();
+ } else {
+ return get_edited_property();
+ }
}
void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
@@ -3123,7 +3162,25 @@ bool EditorPropertyNodePath::is_drop_valid(const Dictionary &p_drag_data) const
return false;
}
Array nodes = p_drag_data["nodes"];
- return nodes.size() == 1;
+ if (nodes.size() != 1) {
+ return false;
+ }
+
+ Node *dropped_node = get_tree()->get_edited_scene_root()->get_node(nodes[0]);
+ ERR_FAIL_NULL_V(dropped_node, false);
+
+ if (valid_types.is_empty()) {
+ // No type requirements specified so any type is valid.
+ return true;
+ }
+
+ for (const StringName &E : valid_types) {
+ if (dropped_node->is_class(E)) {
+ return true;
+ }
+ }
+
+ return false;
}
void EditorPropertyNodePath::update_property() {
@@ -3218,8 +3275,8 @@ EditorPropertyNodePath::EditorPropertyNodePath() {
void EditorPropertyRID::update_property() {
RID rid = get_edited_object()->get(get_edited_property());
if (rid.is_valid()) {
- int id = rid.get_id();
- label->set_text("RID: " + itos(id));
+ uint64_t id = rid.get_id();
+ label->set_text("RID: " + uitos(id));
} else {
label->set_text(TTR("Invalid RID"));
}
@@ -3998,6 +4055,14 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
}
} break;
+ case Variant::CALLABLE: {
+ EditorPropertyCallable *editor = memnew(EditorPropertyCallable);
+ return editor;
+ } break;
+ case Variant::SIGNAL: {
+ EditorPropertySignal *editor = memnew(EditorPropertySignal);
+ return editor;
+ } break;
case Variant::DICTIONARY: {
if (p_hint == PROPERTY_HINT_LOCALIZABLE_STRING) {
EditorPropertyLocalizableString *editor = memnew(EditorPropertyLocalizableString);
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 7cd6ea4f6b..7bec2d0013 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -389,6 +389,33 @@ public:
EditorPropertyObjectID();
};
+class EditorPropertySignal : public EditorProperty {
+ GDCLASS(EditorPropertySignal, EditorProperty);
+ Button *edit = nullptr;
+ String base_type;
+ void _edit_pressed();
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual void update_property() override;
+ EditorPropertySignal();
+};
+
+class EditorPropertyCallable : public EditorProperty {
+ GDCLASS(EditorPropertyCallable, EditorProperty);
+ Button *edit = nullptr;
+ String base_type;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual void update_property() override;
+ EditorPropertyCallable();
+};
+
class EditorPropertyFloat : public EditorProperty {
GDCLASS(EditorPropertyFloat, EditorProperty);
EditorSpinSlider *spin = nullptr;
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index f1a3fe0c57..0b9004bbc4 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -211,7 +211,14 @@ void EditorPropertyArray::update_property() {
String array_type_name = Variant::get_type_name(array_type);
if (array_type == Variant::ARRAY && subtype != Variant::NIL) {
- array_type_name = vformat("%s[%s]", array_type_name, Variant::get_type_name(subtype));
+ String type_name;
+ if (subtype == Variant::OBJECT && subtype_hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ type_name = subtype_hint_string;
+ } else {
+ type_name = Variant::get_type_name(subtype);
+ }
+
+ array_type_name = vformat("%s[%s]", array_type_name, type_name);
}
if (array.get_type() == Variant::NIL) {
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index 4d53ddb344..40e16bf717 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -254,7 +254,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
file_dialog->clear_filters();
for (const String &E : valid_extensions) {
- file_dialog->add_filter("*." + E + " ; " + E.to_upper());
+ file_dialog->add_filter("*." + E, E.to_upper());
}
file_dialog->popup_file_dialog();
@@ -534,8 +534,6 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, HashSet<Strin
p_vector->insert("Texture2D");
} else if (base == "ShaderMaterial") {
p_vector->insert("Shader");
- } else if (base == "Font") {
- p_vector->insert("FontData");
} else if (base == "Texture2D") {
p_vector->insert("Image");
}
@@ -675,22 +673,12 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_
break;
}
- if (at == "Font" && Ref<FontData>(dropped_resource).is_valid()) {
- Ref<Font> font = edited_resource;
- if (!font.is_valid()) {
- font.instantiate();
- }
- font->add_data(dropped_resource);
- dropped_resource = font;
- break;
- }
-
if (at == "Texture2D" && Ref<Image>(dropped_resource).is_valid()) {
Ref<ImageTexture> texture = edited_resource;
if (!texture.is_valid()) {
texture.instantiate();
}
- texture->create_from_image(dropped_resource);
+ texture->set_image(dropped_resource);
dropped_resource = texture;
break;
}
@@ -891,7 +879,7 @@ EditorResourcePicker::EditorResourcePicker() {
preview_rect = memnew(TextureRect);
preview_rect->set_ignore_texture_size(true);
- preview_rect->set_anchors_and_offsets_preset(PRESET_WIDE);
+ preview_rect->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
preview_rect->set_offset(SIDE_TOP, 1);
preview_rect->set_offset(SIDE_BOTTOM, -1);
preview_rect->set_offset(SIDE_RIGHT, -1);
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index dffb378408..b84e654d42 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -184,7 +184,7 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<
small_image = small_image->duplicate();
small_image->resize(small_thumbnail_size, small_thumbnail_size, Image::INTERPOLATE_CUBIC);
r_small_texture.instantiate();
- r_small_texture->create_from_image(small_image);
+ r_small_texture->set_image(small_image);
}
break;
@@ -300,14 +300,14 @@ void EditorResourcePreview::_iterate() {
cache_valid = false;
} else {
texture.instantiate();
- texture->create_from_image(img);
+ texture->set_image(img);
if (has_small_texture) {
if (small_img->load(cache_base + "_small.png") != OK) {
cache_valid = false;
} else {
small_texture.instantiate();
- small_texture->create_from_image(small_img);
+ small_texture->set_image(small_img);
}
}
}
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index 04a3bf2915..6ce8625daa 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -55,15 +55,20 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) {
args.push_back("--remote-debug");
args.push_back(EditorDebuggerNode::get_singleton()->get_server_uri());
- args.push_back("--allow_focus_steal_pid");
+ args.push_back("--editor-pid");
args.push_back(itos(OS::get_singleton()->get_process_id()));
bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisons", false);
+ bool debug_paths = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_paths", false);
bool debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false);
if (debug_collisions) {
args.push_back("--debug-collisions");
}
+ if (debug_paths) {
+ args.push_back("--debug-paths");
+ }
+
if (debug_navigation) {
args.push_back("--debug-navigation");
}
diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp
index 6ce9e5fa6f..854885c707 100644
--- a/editor/editor_run_native.cpp
+++ b/editor/editor_run_native.cpp
@@ -49,9 +49,7 @@ void EditorRunNative::_notification(int p_what) {
im->clear_mipmaps();
if (!im->is_empty()) {
im->resize(16 * EDSCALE, 16 * EDSCALE);
- Ref<ImageTexture> small_icon;
- small_icon.instantiate();
- small_icon->create_from_image(im);
+ Ref<ImageTexture> small_icon = ImageTexture::create_from_image(im);
MenuButton *mb = memnew(MenuButton);
mb->get_popup()->connect("id_pressed", callable_mp(this, &EditorRunNative::run_native), varray(i));
mb->connect("pressed", callable_mp(this, &EditorRunNative::run_native), varray(-1, i));
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index ad9c547693..40ca058406 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -414,7 +414,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("interface/editor/code_font_custom_opentype_features", "");
_initial_set("interface/editor/code_font_custom_variations", "");
_initial_set("interface/editor/font_antialiased", true);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_hinting", 0, "Auto (None),None,Light,Normal")
#else
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_hinting", 0, "Auto (Light),None,Light,Normal")
@@ -444,6 +444,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Inspector
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/inspector/max_array_dictionary_items_per_page", 20, "10,100,1")
+ EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/inspector/show_low_level_opentype_features", false, "")
// Theme
EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_ENUM, "interface/theme/preset", "Default", "Default,Breeze Dark,Godot 2,Gray,Light,Solarized (Dark),Solarized (Light),Custom")
@@ -763,6 +764,7 @@ void EditorSettings::_load_godot2_text_editor_theme() {
_initial_set("text_editor/theme/highlighting/completion_selected_color", Color(0.26, 0.26, 0.27));
_initial_set("text_editor/theme/highlighting/completion_existing_color", Color(0.87, 0.87, 0.87, 0.13));
_initial_set("text_editor/theme/highlighting/completion_scroll_color", Color(1, 1, 1, 0.29));
+ _initial_set("text_editor/theme/highlighting/completion_scroll_hovered_color", Color(1, 1, 1, 0.4));
_initial_set("text_editor/theme/highlighting/completion_font_color", Color(0.67, 0.67, 0.67));
_initial_set("text_editor/theme/highlighting/text_color", Color(0.67, 0.67, 0.67));
_initial_set("text_editor/theme/highlighting/line_number_color", Color(0.67, 0.67, 0.67, 0.4));
@@ -1103,8 +1105,8 @@ void EditorSettings::add_property_hint(const PropertyInfo &p_hint) {
// Editor data and config directories
// EditorPaths::create() is responsible for the creation of these directories.
-String EditorSettings::get_templates_dir() const {
- return EditorPaths::get_singleton()->get_data_dir().plus_file("templates");
+String EditorSettings::get_export_templates_dir() const {
+ return EditorPaths::get_singleton()->get_data_dir().plus_file("export_templates");
}
String EditorSettings::get_project_settings_dir() const {
@@ -1368,7 +1370,7 @@ String EditorSettings::get_editor_layouts_config() const {
}
float EditorSettings::get_auto_display_scale() const {
-#if defined(OSX_ENABLED) || defined(ANDROID_ENABLED)
+#if defined(MACOS_ENABLED) || defined(ANDROID_ENABLED)
return DisplayServer::get_singleton()->screen_get_max_scale();
#else
const int screen = DisplayServer::get_singleton()->window_get_current_screen();
@@ -1487,7 +1489,7 @@ void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, c
for (int i = 0; i < p_keycodes.size(); i++) {
Key keycode = (Key)p_keycodes[i];
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
if (keycode == Key::KEY_DELETE) {
keycode = KeyModifierMask::CMD | Key::BACKSPACE;
@@ -1517,7 +1519,7 @@ Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, cons
for (int i = 0; i < p_keycodes.size(); i++) {
Key keycode = (Key)p_keycodes[i];
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
if (keycode == Key::KEY_DELETE) {
keycode = KeyModifierMask::CMD | Key::BACKSPACE;
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 43f90f9258..56c73685bb 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -151,7 +151,7 @@ public:
Ref<Resource> get_resource_clipboard() const { return clipboard; }
String get_data_dir() const;
- String get_templates_dir() const;
+ String get_export_templates_dir() const;
String get_project_settings_dir() const;
String get_text_editor_themes_dir() const;
String get_script_templates_dir() const;
diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp
index 3eb7d7ffbd..08ff63551f 100644
--- a/editor/editor_settings_dialog.cpp
+++ b/editor/editor_settings_dialog.cpp
@@ -772,7 +772,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
timer->set_one_shot(true);
add_child(timer);
EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &EditorSettingsDialog::_settings_changed));
- get_ok_button()->set_text(TTR("Close"));
+ set_ok_button_text(TTR("Close"));
}
EditorSettingsDialog::~EditorSettingsDialog() {
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index f23f0cf758..20e9d7a3df 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -37,7 +37,7 @@
String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const {
if (grabber->is_visible()) {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
Key key = Key::META;
#else
Key key = Key::CTRL;
@@ -286,7 +286,7 @@ void EditorSpinSlider::_draw_spin_slider() {
int sep_base = 4 * EDSCALE;
int sep = sep_base + sb->get_offset().x; //make it have the same margin on both sides, looks better
- int label_width = font->get_string_size(label, font_size).width;
+ int label_width = font->get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
int number_width = size.width - sb->get_minimum_size().width - label_width - sep;
Ref<Texture2D> updown = get_theme_icon(is_read_only() ? SNAME("updown_disabled") : SNAME("updown"), SNAME("SpinBox"));
@@ -324,7 +324,10 @@ void EditorSpinSlider::_draw_spin_slider() {
int suffix_start = numstr.length();
RID num_rid = TS->create_shaped_text();
- TS->shaped_text_add_string(num_rid, numstr + U"\u2009" + suffix, font->get_rids(), font_size);
+ TS->shaped_text_add_string(num_rid, numstr + U"\u2009" + suffix, font->get_rids(), font_size, font->get_opentype_features());
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(num_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
+ }
float text_start = rtl ? Math::round(sb->get_offset().x) : Math::round(sb->get_offset().x + label_width + sep);
Vector2 text_ofs = rtl ? Vector2(text_start + (number_width - TS->shaped_text_get_width(num_rid)), vofs) : Vector2(text_start, vofs);
@@ -649,7 +652,7 @@ void EditorSpinSlider::_ensure_input_popup() {
value_input = memnew(LineEdit);
value_input_popup->add_child(value_input);
value_input_popup->set_wrap_controls(true);
- value_input->set_anchors_and_offsets_preset(PRESET_WIDE);
+ value_input->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
value_input_popup->connect("popup_hide", callable_mp(this, &EditorSpinSlider::_value_input_closed));
value_input->connect("text_submitted", callable_mp(this, &EditorSpinSlider::_value_input_submitted));
value_input->connect("focus_exited", callable_mp(this, &EditorSpinSlider::_value_focus_exited));
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 10412eac41..5d60baf202 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -97,7 +97,6 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
return p_texture;
}
- Ref<ImageTexture> texture(memnew(ImageTexture));
Ref<Image> img = p_texture->get_image();
ERR_FAIL_NULL_V(img, Ref<Texture2D>());
img = img->duplicate();
@@ -109,14 +108,12 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
img->flip_x();
}
- texture->create_from_image(img);
- return texture;
+ return ImageTexture::create_from_image(img);
}
#ifdef MODULE_SVG_ENABLED
// See also `generate_icon()` in `scene/resources/default_theme.cpp`.
static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0, Dictionary p_convert_colors = Dictionary()) {
- Ref<ImageTexture> icon = memnew(ImageTexture);
Ref<Image> img = memnew(Image);
// Upsample icon generation only if the editor scale isn't an integer multiplier.
@@ -129,9 +126,9 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color,
if (p_saturation != 1.0) {
img->adjust_bcs(1.0, 1.0, p_saturation);
}
- icon->create_from_image(img); // in this case filter really helps
- return icon;
+ // In this case filter really helps.
+ return ImageTexture::create_from_image(img);
}
#endif
@@ -280,6 +277,14 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
exceptions.insert("StatusWarning");
exceptions.insert("OverbrightIndicator");
exceptions.insert("GuiMiniCheckerboard");
+
+ // Prevents Code Editor icons from changing
+ exceptions.insert("GuiTab");
+ exceptions.insert("GuiSpace");
+ exceptions.insert("CodeFoldedRightArrow");
+ exceptions.insert("CodeFoldDownArrow");
+ exceptions.insert("TextEditorPlay");
+ exceptions.insert("Breakpoint");
}
// These ones should be converted even if we are using a dark theme.
@@ -1662,7 +1667,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const float mono_value = mono_color.r;
const Color alpha1 = Color(mono_value, mono_value, mono_value, 0.07);
const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.14);
- const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.7);
+ const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.27);
// editor main color
const Color main_color = dark_theme ? Color(0.34, 0.7, 1.0) : Color(0.02, 0.5, 1.0);
@@ -1683,6 +1688,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color completion_existing_color = alpha2;
// Same opacity as the scroll grabber editor icon.
const Color completion_scroll_color = Color(mono_value, mono_value, mono_value, 0.29);
+ const Color completion_scroll_hovered_color = Color(mono_value, mono_value, mono_value, 0.4);
const Color completion_font_color = font_color;
const Color text_color = font_color;
const Color line_number_color = dim_color;
@@ -1721,6 +1727,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
setting->set_initial_value("text_editor/theme/highlighting/completion_selected_color", completion_selected_color, true);
setting->set_initial_value("text_editor/theme/highlighting/completion_existing_color", completion_existing_color, true);
setting->set_initial_value("text_editor/theme/highlighting/completion_scroll_color", completion_scroll_color, true);
+ setting->set_initial_value("text_editor/theme/highlighting/completion_scroll_hovered_color", completion_scroll_hovered_color, true);
setting->set_initial_value("text_editor/theme/highlighting/completion_font_color", completion_font_color, true);
setting->set_initial_value("text_editor/theme/highlighting/text_color", text_color, true);
setting->set_initial_value("text_editor/theme/highlighting/line_number_color", line_number_color, true);
@@ -1750,22 +1757,27 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Now theme is loaded, apply it to CodeEdit.
theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), SNAME("EditorFonts")));
theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), SNAME("EditorFonts")));
+
Ref<StyleBoxFlat> code_edit_stylebox = make_flat_stylebox(EDITOR_GET("text_editor/theme/highlighting/background_color"), widget_default_margin.x, widget_default_margin.y, widget_default_margin.x, widget_default_margin.y, corner_radius);
theme->set_stylebox("normal", "CodeEdit", code_edit_stylebox);
theme->set_stylebox("read_only", "CodeEdit", code_edit_stylebox);
theme->set_stylebox("focus", "CodeEdit", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+
theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons")));
theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons")));
- theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons")));
- theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons")));
- theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("CodeFoldedRightArrow"), SNAME("EditorIcons")));
+ theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("CodeFoldDownArrow"), SNAME("EditorIcons")));
+ theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("TextEditorPlay"), SNAME("EditorIcons")));
theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), SNAME("EditorIcons")));
+
theme->set_constant("line_spacing", "CodeEdit", EDITOR_GET("text_editor/appearance/whitespace/line_spacing"));
+
theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0));
theme->set_color("completion_background_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_background_color"));
theme->set_color("completion_selected_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_selected_color"));
theme->set_color("completion_existing_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_existing_color"));
theme->set_color("completion_scroll_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_scroll_color"));
+ theme->set_color("completion_scroll_hovered_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_scroll_hovered_color"));
theme->set_color("completion_font_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_font_color"));
theme->set_color("font_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/text_color"));
theme->set_color("line_number_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/line_number_color"));
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index 4ca2e1fdbf..9f9b8374ce 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -46,7 +46,7 @@
void ExportTemplateManager::_update_template_status() {
// Fetch installed templates from the file system.
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir();
+ const String &templates_dir = EditorSettings::get_singleton()->get_export_templates_dir();
Error err = da->change_dir(templates_dir);
ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir + "'.");
@@ -439,7 +439,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_
}
Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(version);
+ String template_path = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(version);
Error err = d->make_dir_recursive(template_path);
if (err != OK) {
EditorNode::get_singleton()->show_warning(TTR("Error creating path for extracting templates:") + "\n" + template_path);
@@ -538,7 +538,7 @@ void ExportTemplateManager::_uninstall_template(const String &p_version) {
void ExportTemplateManager::_uninstall_template_confirmed() {
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir();
+ const String &templates_dir = EditorSettings::get_singleton()->get_export_templates_dir();
Error err = da->change_dir(templates_dir);
ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir + "'.");
@@ -616,7 +616,7 @@ void ExportTemplateManager::_installed_table_button_cbk(Object *p_item, int p_co
}
void ExportTemplateManager::_open_template_folder(const String &p_version) {
- const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir();
+ const String &templates_dir = EditorSettings::get_singleton()->get_export_templates_dir();
OS::get_singleton()->shell_open("file://" + templates_dir.plus_file(p_version));
}
@@ -640,12 +640,12 @@ void ExportTemplateManager::_hide_dialog() {
}
bool ExportTemplateManager::can_install_android_template() {
- const String templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG);
+ const String templates_dir = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG);
return FileAccess::exists(templates_dir.plus_file("android_source.zip"));
}
Error ExportTemplateManager::install_android_template() {
- const String &templates_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG);
+ const String &templates_path = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG);
const String &source_zip = templates_path.plus_file("android_source.zip");
ERR_FAIL_COND_V(!FileAccess::exists(source_zip), ERR_CANT_OPEN);
return install_android_template_from_file(source_zip);
@@ -810,7 +810,7 @@ void ExportTemplateManager::_bind_methods() {
ExportTemplateManager::ExportTemplateManager() {
set_title(TTR("Export Template Manager"));
set_hide_on_ok(false);
- get_ok_button()->set_text(TTR("Close"));
+ set_ok_button_text(TTR("Close"));
// Downloadable export templates are only available for stable and official alpha/beta/RC builds
// (which always have a number following their status, e.g. "alpha1").
@@ -990,7 +990,7 @@ ExportTemplateManager::ExportTemplateManager() {
install_file_dialog->set_title(TTR("Select Template File"));
install_file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM);
install_file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE);
- install_file_dialog->add_filter("*.tpz ; " + TTR("Godot Export Templates"));
+ install_file_dialog->add_filter("*.tpz", TTR("Godot Export Templates"));
install_file_dialog->connect("file_selected", callable_mp(this, &ExportTemplateManager::_install_file_selected), varray(false));
add_child(install_file_dialog);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 2d6ec0c63a..fe6e6044a4 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -3145,7 +3145,7 @@ FileSystemDock::FileSystemDock() {
add_child(remove_dialog);
move_dialog = memnew(EditorDirDialog);
- move_dialog->get_ok_button()->set_text(TTR("Move"));
+ move_dialog->set_ok_button_text(TTR("Move"));
add_child(move_dialog);
move_dialog->connect("dir_selected", callable_mp(this, &FileSystemDock::_move_operation_confirm), make_binds(false));
@@ -3155,13 +3155,13 @@ FileSystemDock::FileSystemDock() {
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"));
+ rename_dialog->set_ok_button_text(TTR("Rename"));
add_child(rename_dialog);
rename_dialog->register_text_enter(rename_dialog_text);
rename_dialog->connect("confirmed", callable_mp(this, &FileSystemDock::_rename_operation_confirm));
overwrite_dialog = memnew(ConfirmationDialog);
- overwrite_dialog->get_ok_button()->set_text(TTR("Overwrite"));
+ overwrite_dialog->set_ok_button_text(TTR("Overwrite"));
add_child(overwrite_dialog);
overwrite_dialog->connect("confirmed", callable_mp(this, &FileSystemDock::_move_with_overwrite));
@@ -3171,7 +3171,7 @@ FileSystemDock::FileSystemDock() {
duplicate_dialog_text = memnew(LineEdit);
duplicate_dialog_vb->add_margin_child(TTR("Name:"), duplicate_dialog_text);
- duplicate_dialog->get_ok_button()->set_text(TTR("Duplicate"));
+ duplicate_dialog->set_ok_button_text(TTR("Duplicate"));
add_child(duplicate_dialog);
duplicate_dialog->register_text_enter(duplicate_dialog_text);
duplicate_dialog->connect("confirmed", callable_mp(this, &FileSystemDock::_duplicate_operation_confirm));
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index e1c9689f73..81b71b5609 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -764,8 +764,8 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) {
int font_size = _results_display->get_theme_font_size(SNAME("font_size"));
Rect2 match_rect = rect;
- match_rect.position.x += font->get_string_size(item_text.left(r.begin_trimmed), font_size).x;
- match_rect.size.x = font->get_string_size(_search_text_label->get_text(), font_size).x;
+ match_rect.position.x += font->get_string_size(item_text.left(r.begin_trimmed), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x;
+ match_rect.size.x = font->get_string_size(_search_text_label->get_text(), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x;
match_rect.position.y += 1 * EDSCALE;
match_rect.size.y -= 2 * EDSCALE;
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 5dc81f623d..f1d08783ad 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -432,7 +432,7 @@ GroupDialog::GroupDialog() {
VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
- vbc->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ vbc->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
HBoxContainer *hbc = memnew(HBoxContainer);
vbc->add_child(hbc);
@@ -562,13 +562,13 @@ GroupDialog::GroupDialog() {
group_empty->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
group_empty->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
nodes_to_remove->add_child(group_empty);
- group_empty->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ group_empty->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
set_title(TTR("Group Editor"));
error = memnew(ConfirmationDialog);
add_child(error);
- error->get_ok_button()->set_text(TTR("Close"));
+ error->set_ok_button_text(TTR("Close"));
_add_group_text_changed("");
}
diff --git a/editor/icons/BoneMapHumanBody.svg b/editor/icons/BoneMapHumanBody.svg
new file mode 100644
index 0000000000..2c2c5db1f6
--- /dev/null
+++ b/editor/icons/BoneMapHumanBody.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 1024 1024" height="1024" viewBox="0 0 1024 1024" width="1024" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h1024v1024h-1024z" fill="#3f3f3f"/><path d="m926.5 217.162c-11.5-2-26.03 4.547-37.5 6.5-15.723 2.678-25.238 3.24-33.333 5.167-1.227.292-3.103.763-5.792.958 0 0-.019.16-.052.437-36.819.994-106.823-6.062-138.156-2.062-23.816 3.041-86.334-5.667-105.667-6-13.911-.239-59.292-4.583-71.75-2.5-.667-4.083-1.5-10.75.95-17.468 14.881-7.246 27.229-21.569 35.341-38.467.922 4.424 6.252 4.929 12.459-14.231 5.662-17.478 2.324-22.254-2.313-22.525.172-2.056.279-4.105.313-6.142.788-48.041-15-78.667-69-78.667s-69.787 30.626-69 78.667c.033 2.036.141 4.086.313 6.142-4.637.271-7.975 5.048-2.313 22.525 6.207 19.16 11.537 18.655 12.459 14.231 8.113 16.897 20.461 31.221 35.342 38.467 2.449 6.718 1.617 13.385.949 17.468-12.457-2.083-57.838 2.261-71.75 2.5-19.332.333-81.85 9.041-105.666 6-31.333-4-101.337 3.056-138.156 2.062-.033-.276-.053-.437-.053-.437-2.689-.195-4.564-.666-5.791-.958-8.096-1.927-17.611-2.489-33.334-5.167-11.469-1.953-26-8.5-37.5-6.5-3.367.586 6 9.834 15.5 12.334 13.635 3.588 25.25 10.666 36 13.166-2.25 3.75-15.59 7.063-23 12-5.336 3.557 6.5 6.5 12 5 20.842-5.684 22.973.389 37.514-9.019 30.078 4.078 102.537 20.514 122.154 14.186 12.457-4.018 100.332 7.083 142.332 5.833 6.039-.18 1.656 65.563 2 73.5 3 69-16.842 133.135-18.666 169.667-1.92 38.42-3.42 57.919 7.666 131.333 6.967 46.126-2.521 82.079-2 94 6 137 29 172 4 221-14 27.44 67.449 26.958 65 9-3.012-22.092-12.666-22.333-10.666-46.333 1.896-22.768 16.049-151.298 8.666-206.667-2-15 0-26 2-66 2.355-47.101 7-88 14-123 7 35 11.645 75.899 14 123 2 40 4 51 2 66-7.383 55.369 6.77 183.899 8.667 206.667 2 24-7.654 24.241-10.667 46.333-2.449 17.958 79 18.44 65-9-25-49-2-84 4-221 .522-11.921-8.966-47.874-2-94 11.086-73.414 9.586-92.913 7.667-131.333-1.824-36.532-21.667-100.667-18.667-169.667.345-7.938-4.039-73.68 2-73.5 42 1.25 129.876-9.852 142.333-5.833 19.616 6.328 92.076-10.107 122.153-14.186 14.541 9.407 16.673 3.335 37.514 9.019 5.5 1.5 17.336-1.443 12-5-7.409-4.937-20.75-8.25-23-12 10.75-2.5 22.366-9.578 36.001-13.166 9.5-2.5 18.866-11.748 15.499-12.334z" fill="#b2b2b2"/></svg>
diff --git a/editor/icons/BoneMapHumanFace.svg b/editor/icons/BoneMapHumanFace.svg
new file mode 100644
index 0000000000..6cb21140bc
--- /dev/null
+++ b/editor/icons/BoneMapHumanFace.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 1024 1024" height="1024" viewBox="0 0 1024 1024" width="1024" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h1024v1024h-1024z" fill="#3f3f3f"/><path d="m788.105 552.967c17.995-57.892 31.896-124.566 30.875-198.071-3.758-270.403-249.846-251.479-295.568-244.947-359.868 51.409-219.047 452.358-220.453 496.426-4.899 153.499 83.686 170.991 161.665 215.554 2.646 1.512 7.259 1.786 13.313 1.111 7.223 25.179 11.762 59.035 9.548 75.638-3.266 24.495 209.021 24.495 209.021 0 0-62.883 12.233-124.363 33.827-188.89 7.143-2.284 16.054-7.601 25.963-16.95 13.681-12.908 34.839-21.774 45.726-63.145 15.615-59.338 3.869-76.074-13.917-76.726z" fill="#b2b2b2"/></svg>
diff --git a/editor/icons/BoneMapHumanLeftHand.svg b/editor/icons/BoneMapHumanLeftHand.svg
new file mode 100644
index 0000000000..08c68bb4be
--- /dev/null
+++ b/editor/icons/BoneMapHumanLeftHand.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 1024 1024" height="1024" viewBox="0 0 1024 1024" width="1024" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h1024v1024h-1024z" fill="#3f3f3f"/><path d="m703.906 786.098c7.046-66.929 28.135-153.363 18.529-260.192-1.143-12.71-4.5-48.282-4.46-82.732.025-21.174-2.111-48.505-1.975-64.174.167-19.333-.428-41.584-.625-55.755-1.052-75.44-13.225-85.827-30.813-85.827-17.246 0-26.77 14.266-27.062 84.582-.061 14.42.5 51 .5 58.5 0 17.508-.333 34.167 0 53.5.447 25.955-4.279 68-9 68-3.902 0-8.099-39.299-9.575-76.999-.756-19.326-3.219-58.336-2.6-70.102 1.759-33.413.474-58.914 1.537-90.165 3.183-93.607-13.016-111.729-34.695-111.729-21.973 0-35.979 57.688-34.849 114.224.128 6.394-1.165 50.739.188 89.859.754 21.811-1.07 49.627-1.683 69.67-1.095 35.768-5.755 63.896-8.869 63.896-2.641 0-4.135-32.584-5.456-65.706-.859-21.557-4.468-58.477-3.664-83.616 1.886-59.012-1.139-110.226-1.063-121.501.635-94.955-14.66-123.101-36.052-123.101-21.476 0-37.188 30.192-36.6 123.343.067 10.53-2.62 99.926-1.759 121.816.865 21.992-2.773 65.062-3.517 84.818-1.299 34.521-6.49 63.947-9.124 63.947-3.281 0-10.794-25.638-11.724-60.965-.587-22.275 1.231-50.99.624-70.688-1.257-40.707-3.175-64.631-3.877-99.708-1.945-97.182-16.352-106.289-38.142-106.289-17.957 0-32.453 28.673-32.657 115.03-.065 27.702-2.429 62.626-.315 94.329.805 12.081-.622 42.512-1.875 73.894-.799 20.007-1.102 47.501-1.137 63.775-.17 78.595-26.712 133.424-36.555 131.308-30.333-6.521-51.648-43.918-71.219-117.307-10.551-39.566-36.667-71.149-69.9-77.813-25.9-5.193-19.783 46.161-1.319 125.293 8.65 37.068 27.909 86.227 39.566 122.655 31.653 98.917 125.574 188.563 160.903 228.546 17.146 19.403 236.894 19.403 264.59 0 11.525-8.07 43.087-101.557 45.724-126.616z" fill="#b2b2b2"/></svg>
diff --git a/editor/icons/BoneMapHumanRightHand.svg b/editor/icons/BoneMapHumanRightHand.svg
new file mode 100644
index 0000000000..4e40af35d8
--- /dev/null
+++ b/editor/icons/BoneMapHumanRightHand.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 1024 1024" height="1024" viewBox="0 0 1024 1024" width="1024" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h1024v1024h-1024z" fill="#3f3f3f"/><path d="m320.094 786.098c-7.046-66.929-28.135-153.363-18.529-260.192 1.143-12.71 4.5-48.282 4.46-82.732-.025-21.174 2.111-48.505 1.975-64.174-.167-19.333.428-41.584.625-55.755 1.052-75.44 13.225-85.827 30.813-85.827 17.246 0 26.77 14.266 27.062 84.582.061 14.42-.5 51-.5 58.5 0 17.508.333 34.167 0 53.5-.447 25.955 4.279 68 9 68 3.902 0 8.099-39.299 9.575-76.999.756-19.326 3.219-58.336 2.6-70.102-1.759-33.413-.474-58.914-1.537-90.165-3.183-93.607 13.016-111.729 34.695-111.729 21.973 0 35.979 57.688 34.849 114.224-.128 6.394 1.165 50.739-.188 89.859-.754 21.811 1.07 49.627 1.683 69.67 1.095 35.768 5.755 63.896 8.869 63.896 2.641 0 4.135-32.584 5.456-65.706.859-21.557 4.468-58.477 3.664-83.616-1.886-59.012 1.139-110.226 1.063-121.501-.635-94.955 14.66-123.101 36.052-123.101 21.476 0 37.188 30.192 36.6 123.343-.067 10.53 2.62 99.926 1.759 121.816-.865 21.992 2.773 65.062 3.517 84.818 1.299 34.521 6.49 63.947 9.124 63.947 3.281 0 10.794-25.638 11.724-60.965.587-22.275-1.231-50.99-.624-70.688 1.257-40.707 3.176-64.631 3.877-99.708 1.945-97.182 16.352-106.289 38.142-106.289 17.957 0 32.453 28.673 32.657 115.03.065 27.702 2.429 62.626.314 94.329-.805 12.081.622 42.512 1.875 73.894.799 20.007 1.102 47.501 1.137 63.775.171 78.595 26.713 133.424 36.556 131.308 30.333-6.521 51.648-43.918 71.219-117.307 10.551-39.566 36.667-71.149 69.9-77.813 25.9-5.193 19.783 46.161 1.318 125.293-8.649 37.068-27.909 86.227-39.566 122.655-31.652 98.917-125.573 188.563-160.902 228.546-17.146 19.403-236.894 19.403-264.59 0-11.525-8.07-43.087-101.557-45.724-126.616z" fill="#b2b2b2"/></svg>
diff --git a/editor/icons/BoneMapperHandle.svg b/editor/icons/BoneMapperHandle.svg
new file mode 100644
index 0000000000..8c7d7e1d70
--- /dev/null
+++ b/editor/icons/BoneMapperHandle.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 12 12" height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill-opacity=".2941" r="5"/><circle cx="6" cy="6" fill="#fff" r="4"/></svg>
diff --git a/editor/icons/BoneMapperHandleCircle.svg b/editor/icons/BoneMapperHandleCircle.svg
new file mode 100644
index 0000000000..ecf97669b8
--- /dev/null
+++ b/editor/icons/BoneMapperHandleCircle.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 12 12" height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#fff" r="3"/></svg>
diff --git a/editor/icons/BoneMapperHandleSelected.svg b/editor/icons/BoneMapperHandleSelected.svg
new file mode 100644
index 0000000000..729a443f6e
--- /dev/null
+++ b/editor/icons/BoneMapperHandleSelected.svg
@@ -0,0 +1 @@
+<svg enable-background="new -506.5 517.5 12 12" height="12" viewBox="-506.5 517.5 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="-500.5" cy="523.5" fill-opacity=".2941" r="5"/><g fill="#fff"><circle cx="-500.5" cy="523.5" r="4"/><path d="m-499.5 517.5h5v5h-1v-4h-4z"/><path d="m-494.5 524.5v5h-5v-1h4v-4z"/><path d="m-501.5 529.5h-5v-5h1v4h4z"/><path d="m-506.5 522.5v-5h5v1h-4v4z"/></g></svg>
diff --git a/editor/icons/CodeFoldDownArrow.svg b/editor/icons/CodeFoldDownArrow.svg
new file mode 100644
index 0000000000..0024a1256b
--- /dev/null
+++ b/editor/icons/CodeFoldDownArrow.svg
@@ -0,0 +1 @@
+<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-width="2"/></svg>
diff --git a/editor/icons/CodeFoldedRightArrow.svg b/editor/icons/CodeFoldedRightArrow.svg
new file mode 100644
index 0000000000..f2a4bd44e0
--- /dev/null
+++ b/editor/icons/CodeFoldedRightArrow.svg
@@ -0,0 +1 @@
+<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-width="2"/></svg>
diff --git a/editor/icons/ControlAlignWide.svg b/editor/icons/ControlAlignFullRect.svg
index 0099e04896..0099e04896 100644
--- a/editor/icons/ControlAlignWide.svg
+++ b/editor/icons/ControlAlignFullRect.svg
diff --git a/editor/icons/CopyNodePath.svg b/editor/icons/CopyNodePath.svg
index 1adec4ade3..12d03843e0 100644
--- a/editor/icons/CopyNodePath.svg
+++ b/editor/icons/CopyNodePath.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(0 -1036.4)"><circle cx="3" cy="1048.4"/><path d="m2 1c-.55226.0001-.99994.4477-1 1v12c.0000552.5523.44774.9999 1 1h12c.55226-.0001.99994-.4477 1-1v-8l-5-5zm1 2h6v3c0 .554.44599 1 1 1h3v6h-10zm3 5-2 4h2l2-4zm4 0-2 4h2l2-4z" fill-opacity=".78431" 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="#e0e0e0" transform="translate(0 -1036.4)"><circle cx="3" cy="1048.4"/><path d="m2 1c-.55226.0001-.99994.4477-1 1v12c.0000552.5523.44774.9999 1 1h12c.55226-.0001.99994-.4477 1-1v-8l-5-5zm1 2h6v3c0 .554.44599 1 1 1h3v6h-10zm3 5-2 4h2l2-4zm4 0-2 4h2l2-4z" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/Font.svg b/editor/icons/Font.svg
index 2c8d7cb43e..dda1aa577e 100644
--- a/editor/icons/Font.svg
+++ b/editor/icons/Font.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(0 -1036.4)"><path d="m1 1037.4h14v2h-14z"/><path d="m7 1037.4h2v14h-2z"/><path d="m5 1050.4h6v1h-6z"/><path d="m1037.4-2h4v1h-4z" transform="rotate(90)"/><path d="m1037.4-15h4v1h-4z" transform="rotate(90)"/><path d="m2 3v2a2 2 0 0 1 2-2z" transform="translate(0 1036.4)"/><path d="m12 3a2 2 0 0 1 2 2v-2z" transform="translate(0 1036.4)"/><path d="m5 1050.4a2 2 0 0 0 2-2v2z"/><path d="m11 1050.4a2 2 0 0 1 -2-2v2z"/></g></svg>
+<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="M1 1h14v2H1z"/><path d="M7 1h2v14H7z"/><path d="M5 14h6v1H5zM2 1v4H1V1zm13 0v4h-1V1zM2 3v2a2 2 0 0 1 2-2zm10 0a2 2 0 0 1 2 2V3zM5 14a2 2 0 0 0 2-2v2zm6 0a2 2 0 0 1-2-2v2z"/></g></svg>
diff --git a/editor/icons/FontData.svg b/editor/icons/FontData.svg
deleted file mode 100644
index 4cb6412081..0000000000
--- a/editor/icons/FontData.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 1h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1-1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2zm0 5v2h2v-2zm0 3v2h2v-2zm0 3v2h2v-2zm3 0v2h2v-2z" fill="#e0e0e0"/><path d="m4 5v2 1h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1-1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/FontFile.svg b/editor/icons/FontFile.svg
new file mode 100644
index 0000000000..4b94fd0d74
--- /dev/null
+++ b/editor/icons/FontFile.svg
@@ -0,0 +1 @@
+<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1.5 1v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V3h2a1 1 0 0 1 1 1h1V1h-6Z" fill="#e0e0e0"/><path d="M4.5 5v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V7h2a1 1 0 0 1 1 1h1V5h-6Z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/FontVariation.svg b/editor/icons/FontVariation.svg
new file mode 100644
index 0000000000..eaad049fce
--- /dev/null
+++ b/editor/icons/FontVariation.svg
@@ -0,0 +1 @@
+<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M2.437 1 1.379 4h1A.84 1.192 50 0 1 3.73 3h2L3.615 9a.84 1.192 50 0 1-1.352 1l-.353 1h4l.353-1a.84 1.192 50 0 1-.648-1l2.116-6h2a.84 1.192 50 0 1 .648 1h1l1.058-3h-6Z" fill="#e0e0e0"/><path d="m4.621 5-.705 2-.353 1h1a.84 1.192 49.998 0 1 1.353-1h2L5.8 13a.84 1.192 49.998 0 1-1.353 1l-.353 1h4l.353-1a.84 1.192 49.998 0 1-.647-1l2.116-6h2a.84 1.192 49.998 0 1 .647 1h1l.353-1 .705-2h-6Z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/LabelSettings.svg b/editor/icons/LabelSettings.svg
new file mode 100644
index 0000000000..4dc3b9e86e
--- /dev/null
+++ b/editor/icons/LabelSettings.svg
@@ -0,0 +1 @@
+<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M6 3a1 1 0 0 0-.707.293l-4 4a1 1 0 0 0 0 1.414l4 4A1 1 0 0 0 6 13h2.076a3.766 3.766 0 0 1-.058-.496c-.003-.058-.006-.115-.006-.174a2.606 2.606 0 0 1 .05-.508 3.212 3.212 0 0 1 .133-.496 5.104 5.104 0 0 1 .451-.982 8.303 8.303 0 0 1 .422-.656 14.41 14.41 0 0 1 .489-.667c.172-.223.351-.45.535-.68.163-.203.327-.408.492-.618a27.639 27.639 0 0 0 .732-.977 16.04 16.04 0 0 0 .465-.697c.075-.12.147-.242.219-.365a12.399 12.399 0 0 0 .684 1.062 27.555 27.555 0 0 0 .73.977c.165.21.331.415.494.619a43.298 43.298 0 0 1 .787 1.013c.082.111.16.222.237.332L15 9.79V4a1 1 0 0 0-1-1H6zM5 7a1 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:#8eef97;fill-opacity:1"/><path d="M9.184 13A2.99 2.99 0 0 0 12 15a2.99 2.99 0 0 0 2.816-2z" fill="#ff4596"/><path d="M9.23 11c-.136.326-.23.656-.23 1 0 .352.072.686.184 1h5.632c.112-.314.184-.648.184-1 0-.344-.094-.674-.23-1H9.23z" fill="#8045ff"/><path d="M10.564 9c-.552.69-1.058 1.342-1.334 2h5.54c-.276-.658-.782-1.31-1.335-2Z" fill="#45d7ff"/><path d="M12 7c-.43.746-.945 1.387-1.435 2h2.87c-.49-.613-1.005-1.254-1.435-2Z" fill="#45ffa2"/></svg>
diff --git a/editor/icons/MainMovieWriteEnabled.svg b/editor/icons/MainMovieWriteEnabled.svg
deleted file mode 100644
index b12ea38bed..0000000000
--- a/editor/icons/MainMovieWriteEnabled.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="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 4-1.535V14h.002a2 2 0 0 0 .266 1A2 2 0 0 0 14 16h1v-2h-.5a.5.5 0 0 1-.5-.5V8a6 6 0 0 0-6-6zm0 1a1 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-1zm3.441 2a1 1 0 0 1 .89.5 1 1 0 0 1-.366 1.365 1 1 0 0 1-1.367-.365 1 1 0 0 1 .367-1.365A1 1 0 0 1 11.44 5zm-6.953.002a1 1 0 0 1 .547.133A1 1 0 0 1 5.402 6.5a1 1 0 0 1-1.367.365A1 1 0 0 1 3.67 5.5a1 1 0 0 1 .818-.498zM4.512 9a1 1 0 0 1 .89.5 1 1 0 0 1-.367 1.365A1 1 0 0 1 3.67 10.5a1 1 0 0 1 .365-1.365A1 1 0 0 1 4.512 9zm6.904.002a1 1 0 0 1 .549.133 1 1 0 0 1 .365 1.365 1 1 0 0 1-1.365.365 1 1 0 0 1-.367-1.365 1 1 0 0 1 .818-.498zM8 11a1 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" fill="#e0e0e0" style="fill:#ee5353;fill-opacity:1"/></svg>
diff --git a/editor/icons/TextEditorPlay.svg b/editor/icons/TextEditorPlay.svg
new file mode 100644
index 0000000000..5a1d195530
--- /dev/null
+++ b/editor/icons/TextEditorPlay.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1048.4v-8l7 4z" fill="#e0e0e0" fill-rule="evenodd" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
diff --git a/editor/import/dynamic_font_import_settings.cpp b/editor/import/dynamic_font_import_settings.cpp
index f7fe334828..ee13a1a9c1 100644
--- a/editor/import/dynamic_font_import_settings.cpp
+++ b/editor/import/dynamic_font_import_settings.cpp
@@ -41,50 +41,44 @@
/* Settings data */
/*************************************************************************/
-class DynamicFontImportSettingsData : public RefCounted {
- GDCLASS(DynamicFontImportSettingsData, RefCounted)
- friend class DynamicFontImportSettings;
-
- HashMap<StringName, Variant> settings;
- HashMap<StringName, Variant> defaults;
- List<ResourceImporter::ImportOption> options;
- DynamicFontImportSettings *owner = nullptr;
-
- bool _set(const StringName &p_name, const Variant &p_value) {
- if (defaults.has(p_name) && defaults[p_name] == p_value) {
- settings.erase(p_name);
- } else {
- settings[p_name] = p_value;
- }
- return true;
+bool DynamicFontImportSettingsData::_set(const StringName &p_name, const Variant &p_value) {
+ if (defaults.has(p_name) && defaults[p_name] == p_value) {
+ settings.erase(p_name);
+ } else {
+ settings[p_name] = p_value;
}
+ return true;
+}
- bool _get(const StringName &p_name, Variant &r_ret) const {
- if (settings.has(p_name)) {
- r_ret = settings[p_name];
- return true;
- }
- if (defaults.has(p_name)) {
- r_ret = defaults[p_name];
- return true;
- }
- return false;
+bool DynamicFontImportSettingsData::_get(const StringName &p_name, Variant &r_ret) const {
+ if (settings.has(p_name)) {
+ r_ret = settings[p_name];
+ return true;
+ }
+ if (defaults.has(p_name)) {
+ r_ret = defaults[p_name];
+ return true;
}
+ return false;
+}
- void _get_property_list(List<PropertyInfo> *p_list) const {
- for (const List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
- if (owner && owner->import_settings_data.is_valid()) {
- if (owner->import_settings_data->get("multichannel_signed_distance_field") && (E->get().option.name == "size" || E->get().option.name == "outline_size" || E->get().option.name == "oversampling")) {
- continue;
- }
- if (!owner->import_settings_data->get("multichannel_signed_distance_field") && (E->get().option.name == "msdf_pixel_range" || E->get().option.name == "msdf_size")) {
- continue;
- }
+void DynamicFontImportSettingsData::_get_property_list(List<PropertyInfo> *p_list) const {
+ for (const List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
+ if (owner && owner->import_settings_data.is_valid()) {
+ if (owner->import_settings_data->get("multichannel_signed_distance_field") && (E->get().option.name == "size" || E->get().option.name == "outline_size" || E->get().option.name == "oversampling")) {
+ continue;
+ }
+ if (!owner->import_settings_data->get("multichannel_signed_distance_field") && (E->get().option.name == "msdf_pixel_range" || E->get().option.name == "msdf_size")) {
+ continue;
}
- p_list->push_back(E->get().option);
}
+ p_list->push_back(E->get().option);
}
-};
+}
+
+Ref<FontFile> DynamicFontImportSettingsData::get_font() const {
+ return fd;
+}
/*************************************************************************/
/* Glyph ranges */
@@ -454,58 +448,32 @@ void DynamicFontImportSettings::_add_glyph_range_item(int32_t p_start, int32_t p
void DynamicFontImportSettings::_main_prop_changed(const String &p_edited_property) {
// Update font preview.
- if (p_edited_property == "face_index") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_face_index(import_settings_data->get("face_index"));
- }
- } else if (p_edited_property == "antialiased") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_antialiased(import_settings_data->get("antialiased"));
- }
- } else if (p_edited_property == "generate_mipmaps") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_generate_mipmaps(import_settings_data->get("generate_mipmaps"));
- }
- } else if (p_edited_property == "multichannel_signed_distance_field") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_multichannel_signed_distance_field(import_settings_data->get("multichannel_signed_distance_field"));
- }
- _variation_selected();
- _variations_validate();
- } else if (p_edited_property == "msdf_pixel_range") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_msdf_pixel_range(import_settings_data->get("msdf_pixel_range"));
- }
- } else if (p_edited_property == "msdf_size") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_msdf_size(import_settings_data->get("msdf_size"));
- }
- } else if (p_edited_property == "force_autohinter") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_force_autohinter(import_settings_data->get("force_autohinter"));
- }
- } else if (p_edited_property == "hinting") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int());
- }
- } else if (p_edited_property == "subpixel_positioning") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int());
- }
- } else if (p_edited_property == "embolden") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_embolden(import_settings_data->get("embolden"));
- }
- } else if (p_edited_property == "transform") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_transform(import_settings_data->get("transform"));
- }
- } else if (p_edited_property == "oversampling") {
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_oversampling(import_settings_data->get("oversampling"));
+ if (font_preview.is_valid()) {
+ if (p_edited_property == "antialiased") {
+ font_preview->set_antialiased(import_settings_data->get("antialiased"));
+ } else if (p_edited_property == "generate_mipmaps") {
+ font_preview->set_generate_mipmaps(import_settings_data->get("generate_mipmaps"));
+ } else if (p_edited_property == "multichannel_signed_distance_field") {
+ font_preview->set_multichannel_signed_distance_field(import_settings_data->get("multichannel_signed_distance_field"));
+ _variation_selected();
+ _variations_validate();
+ } else if (p_edited_property == "msdf_pixel_range") {
+ font_preview->set_msdf_pixel_range(import_settings_data->get("msdf_pixel_range"));
+ } else if (p_edited_property == "msdf_size") {
+ font_preview->set_msdf_size(import_settings_data->get("msdf_size"));
+ } else if (p_edited_property == "force_autohinter") {
+ font_preview->set_force_autohinter(import_settings_data->get("force_autohinter"));
+ } else if (p_edited_property == "hinting") {
+ font_preview->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int());
+ } else if (p_edited_property == "subpixel_positioning") {
+ font_preview->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int());
+ } else if (p_edited_property == "oversampling") {
+ font_preview->set_oversampling(import_settings_data->get("oversampling"));
}
}
+
font_preview_label->add_theme_font_override("font", font_preview);
+ font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE);
font_preview_label->update();
}
@@ -534,6 +502,7 @@ void DynamicFontImportSettings::_variation_add() {
import_variation_data->options = options_variations;
inspector_vars->edit(import_variation_data.ptr());
import_variation_data->notify_property_list_changed();
+ import_variation_data->fd = font_main;
vars_item->set_metadata(0, import_variation_data);
@@ -548,6 +517,10 @@ void DynamicFontImportSettings::_variation_selected() {
inspector_vars->edit(import_variation_data.ptr());
import_variation_data->notify_property_list_changed();
+
+ label_glyphs->set_text(TTR("Preloaded glyphs: ") + itos(import_variation_data->selected_glyphs.size()));
+ _range_selected();
+ _change_text_opts();
}
}
@@ -611,63 +584,91 @@ void DynamicFontImportSettings::_variations_validate() {
}
/*************************************************************************/
-/* Page 3 callbacks: Text to select glyphs */
+/* Page 2.1 callbacks: Text to select glyphs */
/*************************************************************************/
void DynamicFontImportSettings::_change_text_opts() {
- Vector<String> ftr = ftr_edit->get_text().split(",");
- for (int i = 0; i < ftr.size(); i++) {
- Vector<String> tokens = ftr[i].split("=");
- if (tokens.size() == 2) {
- text_edit->set_opentype_feature(tokens[0], tokens[1].to_int());
- } else if (tokens.size() == 1) {
- text_edit->set_opentype_feature(tokens[0], 1);
- }
+ Ref<DynamicFontImportSettingsData> import_variation_data;
+
+ TreeItem *vars_item = vars_list->get_selected();
+ if (vars_item) {
+ import_variation_data = vars_item->get_metadata(0);
}
- text_edit->set_language(lang_edit->get_text());
+ if (import_variation_data.is_null()) {
+ return;
+ }
+
+ Ref<FontVariation> font_main_text;
+ font_main_text.instantiate();
+ font_main_text->set_base_font(font_main);
+ font_main_text->set_opentype_features(text_settings_data->get("opentype_features"));
+ font_main_text->set_variation_opentype(import_variation_data->get("variation_opentype"));
+ font_main_text->set_variation_embolden(import_variation_data->get("variation_embolden"));
+ font_main_text->set_variation_face_index(import_variation_data->get("variation_face_index"));
+ font_main_text->set_variation_transform(import_variation_data->get("variation_transform"));
+
+ text_edit->add_theme_font_override("font", font_main_text);
}
void DynamicFontImportSettings::_glyph_clear() {
- selected_glyphs.clear();
- label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size()));
+ Ref<DynamicFontImportSettingsData> import_variation_data;
+
+ TreeItem *vars_item = vars_list->get_selected();
+ if (vars_item) {
+ import_variation_data = vars_item->get_metadata(0);
+ }
+ if (import_variation_data.is_null()) {
+ return;
+ }
+
+ import_variation_data->selected_glyphs.clear();
+ label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size()));
_range_selected();
}
void DynamicFontImportSettings::_glyph_text_selected() {
- Dictionary ftrs;
- Vector<String> ftr = ftr_edit->get_text().split(",");
- for (int i = 0; i < ftr.size(); i++) {
- Vector<String> tokens = ftr[i].split("=");
- if (tokens.size() == 2) {
- ftrs[tokens[0]] = tokens[1].to_int();
- } else if (tokens.size() == 1) {
- ftrs[tokens[0]] = 1;
- }
- }
+ Ref<DynamicFontImportSettingsData> import_variation_data;
+ TreeItem *vars_item = vars_list->get_selected();
+ if (vars_item) {
+ import_variation_data = vars_item->get_metadata(0);
+ }
+ if (import_variation_data.is_null()) {
+ return;
+ }
RID text_rid = TS->create_shaped_text();
if (text_rid.is_valid()) {
- TS->shaped_text_add_string(text_rid, text_edit->get_text(), font_main->get_rids(), 16, ftrs, text_edit->get_language());
+ TS->shaped_text_add_string(text_rid, text_edit->get_text(), font_main->get_rids(), 16, text_settings_data->get("opentype_features"), text_settings_data->get("language"));
TS->shaped_text_shape(text_rid);
const Glyph *gl = TS->shaped_text_get_glyphs(text_rid);
const int gl_size = TS->shaped_text_get_glyph_count(text_rid);
for (int i = 0; i < gl_size; i++) {
if (gl[i].font_rid.is_valid() && gl[i].index != 0) {
- selected_glyphs.insert(gl[i].index);
+ import_variation_data->selected_glyphs.insert(gl[i].index);
}
}
TS->free_rid(text_rid);
- label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size()));
+ label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size()));
}
_range_selected();
}
/*************************************************************************/
-/* Page 4 callbacks: Character map */
+/* Page 2.2 callbacks: Character map */
/*************************************************************************/
void DynamicFontImportSettings::_glyph_selected() {
+ Ref<DynamicFontImportSettingsData> import_variation_data;
+
+ TreeItem *vars_item = vars_list->get_selected();
+ if (vars_item) {
+ import_variation_data = vars_item->get_metadata(0);
+ }
+ if (import_variation_data.is_null()) {
+ return;
+ }
+
TreeItem *item = glyph_table->get_selected();
ERR_FAIL_NULL(item);
@@ -685,7 +686,7 @@ void DynamicFontImportSettings::_glyph_selected() {
item->clear_custom_bg_color(glyph_table->get_selected_column());
}
}
- label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size()));
+ label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size()));
item = glyph_tree->get_selected();
ERR_FAIL_NULL(item);
@@ -698,7 +699,7 @@ void DynamicFontImportSettings::_glyph_selected() {
total_chars--;
}
- if (selected_chars.has(i)) {
+ if (import_variation_data->selected_chars.has(i)) {
selected_count++;
}
}
@@ -728,6 +729,16 @@ void DynamicFontImportSettings::_range_selected() {
}
void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
+ Ref<DynamicFontImportSettingsData> import_variation_data;
+
+ TreeItem *vars_item = vars_list->get_selected();
+ if (vars_item) {
+ import_variation_data = vars_item->get_metadata(0);
+ }
+ if (import_variation_data.is_null()) {
+ return;
+ }
+
glyph_table->clear();
TreeItem *root = glyph_table->create_item();
@@ -740,6 +751,8 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
TreeItem *item = nullptr;
int col = 0;
+ Ref<Font> font_main_big = font_main->duplicate();
+
for (int32_t c = p_start; c <= p_end; c++) {
if (col == 0) {
item = glyph_table->create_item(root);
@@ -752,7 +765,7 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
if (font_main->has_char(c)) {
item->set_text(col + 1, String::chr(c));
item->set_custom_color(col + 1, Color(1, 1, 1));
- if (selected_chars.has(c) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, c)))) {
+ if (import_variation_data->selected_chars.has(c) || import_variation_data->selected_glyphs.has(font_main->get_glyph_index(16, c))) {
item->set_custom_color(col + 1, fcol);
item->set_custom_bg_color(col + 1, scol);
} else {
@@ -765,7 +778,8 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
item->set_metadata(col + 1, c);
item->set_text_alignment(col + 1, HORIZONTAL_ALIGNMENT_CENTER);
item->set_selectable(col + 1, true);
- item->set_custom_font(col + 1, font_main);
+
+ item->set_custom_font(col + 1, font_main_big);
item->set_custom_font_size(col + 1, get_theme_font_size(SNAME("font_size")) * 2);
col++;
@@ -773,41 +787,61 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
col = 0;
}
}
- label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size()));
+ label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size()));
}
bool DynamicFontImportSettings::_char_update(int32_t p_char) {
- if (selected_chars.has(p_char)) {
- selected_chars.erase(p_char);
+ Ref<DynamicFontImportSettingsData> import_variation_data;
+
+ TreeItem *vars_item = vars_list->get_selected();
+ if (vars_item) {
+ import_variation_data = vars_item->get_metadata(0);
+ }
+ if (import_variation_data.is_null()) {
return false;
- } else if (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, p_char))) {
- selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, p_char));
+ }
+
+ if (import_variation_data->selected_chars.has(p_char)) {
+ import_variation_data->selected_chars.erase(p_char);
+ return false;
+ } else if (font_main.is_valid() && font_main.is_valid() && import_variation_data->selected_glyphs.has(font_main->get_glyph_index(16, p_char))) {
+ import_variation_data->selected_glyphs.erase(font_main->get_glyph_index(16, p_char));
return false;
} else {
- selected_chars.insert(p_char);
+ import_variation_data->selected_chars.insert(p_char);
return true;
}
}
void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) {
+ Ref<DynamicFontImportSettingsData> import_variation_data;
+
+ TreeItem *vars_item = vars_list->get_selected();
+ if (vars_item) {
+ import_variation_data = vars_item->get_metadata(0);
+ }
+ if (import_variation_data.is_null()) {
+ return;
+ }
+
bool all_selected = true;
for (int32_t i = p_start; i <= p_end; i++) {
if (font_main->has_char(i)) {
- if (font_main->get_data(0).is_valid()) {
- all_selected = all_selected && (selected_chars.has(i) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, i))));
+ if (font_main.is_valid()) {
+ all_selected = all_selected && (import_variation_data->selected_chars.has(i) || import_variation_data->selected_glyphs.has(font_main->get_glyph_index(16, i)));
} else {
- all_selected = all_selected && selected_chars.has(i);
+ all_selected = all_selected && import_variation_data->selected_chars.has(i);
}
}
}
for (int32_t i = p_start; i <= p_end; i++) {
if (font_main->has_char(i)) {
if (!all_selected) {
- selected_chars.insert(i);
+ import_variation_data->selected_chars.insert(i);
} else {
- selected_chars.erase(i);
- if (font_main->get_data(0).is_valid()) {
- selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, i));
+ import_variation_data->selected_chars.erase(i);
+ if (font_main.is_valid()) {
+ import_variation_data->selected_glyphs.erase(font_main->get_glyph_index(16, i));
}
}
}
@@ -820,106 +854,6 @@ void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) {
}
/*************************************************************************/
-/* Page 5 callbacks: CMetadata override */
-/*************************************************************************/
-
-void DynamicFontImportSettings::_lang_add() {
- locale_select->popup_locale_dialog();
-}
-
-void DynamicFontImportSettings::_lang_add_item(const String &p_locale) {
- TreeItem *lang_item = lang_list->create_item(lang_list_root);
- ERR_FAIL_NULL(lang_item);
-
- lang_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- lang_item->set_editable(0, true);
- lang_item->set_checked(0, false);
- lang_item->set_text(1, p_locale);
- lang_item->set_editable(1, true);
- lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove"));
- lang_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
-}
-
-void DynamicFontImportSettings::_lang_remove(Object *p_item, int p_column, int p_id, MouseButton p_button) {
- if (p_button != MouseButton::LEFT) {
- return;
- }
-
- TreeItem *lang_item = (TreeItem *)p_item;
- ERR_FAIL_NULL(lang_item);
-
- lang_list_root->remove_child(lang_item);
- memdelete(lang_item);
-}
-
-void DynamicFontImportSettings::_ot_add() {
- menu_ot->set_position(ot_list->get_screen_transform().xform(ot_list->get_local_mouse_position()));
- menu_ot->set_size(Vector2(1, 1));
- menu_ot->popup();
-}
-
-void DynamicFontImportSettings::_ot_add_item(int p_option) {
- String name = TS->tag_to_name(p_option);
- for (TreeItem *ot_item = ot_list_root->get_first_child(); ot_item; ot_item = ot_item->get_next()) {
- if (ot_item->get_text(0) == name) {
- return;
- }
- }
- TreeItem *ot_item = ot_list->create_item(ot_list_root);
- ERR_FAIL_NULL(ot_item);
-
- ot_item->set_text(0, name);
- ot_item->set_editable(0, false);
- ot_item->set_text(1, "1");
- ot_item->set_editable(1, true);
- ot_item->add_button(2, ot_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove"));
- ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
-}
-
-void DynamicFontImportSettings::_ot_remove(Object *p_item, int p_column, int p_id, MouseButton p_button) {
- if (p_button != MouseButton::LEFT) {
- return;
- }
-
- TreeItem *ot_item = (TreeItem *)p_item;
- ERR_FAIL_NULL(ot_item);
-
- ot_list_root->remove_child(ot_item);
- memdelete(ot_item);
-}
-
-void DynamicFontImportSettings::_script_add() {
- menu_scripts->set_position(script_list->get_screen_position() + script_list->get_local_mouse_position());
- menu_scripts->reset_size();
- menu_scripts->popup();
-}
-
-void DynamicFontImportSettings::_script_add_item(int p_option) {
- TreeItem *script_item = script_list->create_item(script_list_root);
- ERR_FAIL_NULL(script_item);
-
- script_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- script_item->set_editable(0, true);
- script_item->set_checked(0, false);
- script_item->set_text(1, script_codes[p_option]);
- script_item->set_editable(1, true);
- script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove"));
- script_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
-}
-
-void DynamicFontImportSettings::_script_remove(Object *p_item, int p_column, int p_id, MouseButton p_button) {
- if (p_button != MouseButton::LEFT) {
- return;
- }
-
- TreeItem *script_item = (TreeItem *)p_item;
- ERR_FAIL_NULL(script_item);
-
- script_list_root->remove_child(script_item);
- memdelete(script_item);
-}
-
-/*************************************************************************/
/* Common */
/*************************************************************************/
@@ -938,10 +872,7 @@ void DynamicFontImportSettings::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- add_lang->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- add_script->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
add_var->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- add_ot->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
} break;
}
}
@@ -958,90 +889,40 @@ void DynamicFontImportSettings::_re_import() {
main_settings["force_autohinter"] = import_settings_data->get("force_autohinter");
main_settings["hinting"] = import_settings_data->get("hinting");
main_settings["subpixel_positioning"] = import_settings_data->get("subpixel_positioning");
- main_settings["embolden"] = import_settings_data->get("embolden");
- main_settings["transform"] = import_settings_data->get("transform");
main_settings["oversampling"] = import_settings_data->get("oversampling");
+ main_settings["fallbacks"] = import_settings_data->get("fallbacks");
main_settings["compress"] = import_settings_data->get("compress");
- Vector<String> variations;
+ Array configurations;
for (TreeItem *vars_item = vars_list_root->get_first_child(); vars_item; vars_item = vars_item->get_next()) {
- String variation;
Ref<DynamicFontImportSettingsData> import_variation_data = vars_item->get_metadata(0);
ERR_FAIL_NULL(import_variation_data);
- String name = vars_item->get_text(0);
- variation += ("name=" + name);
+ Dictionary preload_config;
+ preload_config["name"] = vars_item->get_text(0);
+
for (const KeyValue<StringName, Variant> &E : import_variation_data->settings) {
- if (!variation.is_empty()) {
- variation += ",";
- }
- variation += (String(E.key) + "=" + String(E.value));
- }
- variations.push_back(variation);
- }
- main_settings["preload/configurations"] = variations;
-
- Vector<String> langs_enabled;
- Vector<String> langs_disabled;
- for (TreeItem *lang_item = lang_list_root->get_first_child(); lang_item; lang_item = lang_item->get_next()) {
- bool selected = lang_item->is_checked(0);
- String name = lang_item->get_text(1);
- if (selected) {
- langs_enabled.push_back(name);
- } else {
- langs_disabled.push_back(name);
+ preload_config[E.key] = E.value;
}
- }
- main_settings["support_overrides/language_enabled"] = langs_enabled;
- main_settings["support_overrides/language_disabled"] = langs_disabled;
-
- Vector<String> scripts_enabled;
- Vector<String> scripts_disabled;
- for (TreeItem *script_item = script_list_root->get_first_child(); script_item; script_item = script_item->get_next()) {
- bool selected = script_item->is_checked(0);
- String name = script_item->get_text(1);
- if (selected) {
- scripts_enabled.push_back(name);
- } else {
- scripts_disabled.push_back(name);
- }
- }
- main_settings["support_overrides/script_enabled"] = scripts_enabled;
- main_settings["support_overrides/script_disabled"] = scripts_disabled;
-
- if (!selected_chars.is_empty()) {
- Vector<String> ranges;
- char32_t start = selected_chars.front()->get();
- for (RBSet<char32_t>::Element *E = selected_chars.front()->next(); E; E = E->next()) {
- if (E->prev() && ((E->prev()->get() + 1) != E->get())) {
- ranges.push_back(String("0x") + String::num_int64(start, 16) + String("-0x") + String::num_int64(E->prev()->get(), 16));
- start = E->get();
- }
+
+ Array chars;
+ for (const char32_t &E : import_variation_data->selected_chars) {
+ chars.push_back(E);
}
- ranges.push_back(String("0x") + String::num_int64(start, 16) + String("-0x") + String::num_int64(selected_chars.back()->get(), 16));
- main_settings["preload/char_ranges"] = ranges;
- }
+ preload_config["chars"] = chars;
- if (!selected_glyphs.is_empty()) {
- Vector<String> ranges;
- int32_t start = selected_glyphs.front()->get();
- for (RBSet<int32_t>::Element *E = selected_glyphs.front()->next(); E; E = E->next()) {
- if (E->prev() && ((E->prev()->get() + 1) != E->get())) {
- ranges.push_back(String("0x") + String::num_int64(start, 16) + String("-0x") + String::num_int64(E->prev()->get(), 16));
- start = E->get();
- }
+ Array glyphs;
+ for (const int32_t &E : import_variation_data->selected_glyphs) {
+ glyphs.push_back(E);
}
- ranges.push_back(String("0x") + String::num_int64(start, 16) + String("-0x") + String::num_int64(selected_glyphs.back()->get(), 16));
- main_settings["preload/glyph_ranges"] = ranges;
- }
+ preload_config["glyphs"] = glyphs;
- Dictionary ot_ov;
- for (TreeItem *ot_item = ot_list_root->get_first_child(); ot_item; ot_item = ot_item->get_next()) {
- String tag = ot_item->get_text(0);
- int32_t value = ot_item->get_text(1).to_int();
- ot_ov[tag] = value;
+ configurations.push_back(preload_config);
}
- main_settings["opentype_feature_overrides"] = ot_ov;
+ main_settings["preload"] = configurations;
+ main_settings["language_support"] = import_settings_data->get("language_support");
+ main_settings["script_support"] = import_settings_data->get("script_support");
+ main_settings["opentype_features"] = import_settings_data->get("opentype_features");
if (OS::get_singleton()->is_stdout_verbose()) {
print_line("Import settings:");
@@ -1058,33 +939,33 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
Vector<uint8_t> data = FileAccess::get_file_as_array(p_path);
// Load font for preview.
- Ref<FontData> dfont_prev;
- dfont_prev.instantiate();
- dfont_prev->set_data(data);
-
font_preview.instantiate();
- font_preview->add_data(dfont_prev);
+ font_preview->set_data(data);
+ String font_name = vformat("%s (%s)", font_preview->get_font_name(), font_preview->get_font_style_name());
String sample;
static const String sample_base = U"12漢字ԱբΑαÐбΑα×בابÜÜ’Þ€Þआআਆઆଆஆఆಆആආà¸à¸´àºàº´à¼€á€€á‚ áƒí•œê¸€áˆ€áŽ£áášáš áœ€áœ á€á áž€á  á¤á¥Ab😀";
for (int i = 0; i < sample_base.length(); i++) {
- if (dfont_prev->has_char(sample_base[i])) {
+ if (font_preview->has_char(sample_base[i])) {
sample += sample_base[i];
}
}
if (sample.is_empty()) {
- sample = dfont_prev->get_supported_chars().substr(0, 6);
+ sample = font_preview->get_supported_chars().substr(0, 6);
}
font_preview_label->set_text(sample);
- // Load second copy of font with MSDF disabled for the glyph table and metadata extraction.
- Ref<FontData> dfont_main;
- dfont_main.instantiate();
- dfont_main->set_data(data);
- dfont_main->set_multichannel_signed_distance_field(false);
+ Ref<Font> bold_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
+ if (bold_font.is_valid() && bold_font.is_valid()) {
+ font_name_label->add_theme_font_override("bold_font", bold_font);
+ }
+ font_name_label->set_text(font_name);
+ // Load second copy of font with MSDF disabled for the glyph table and metadata extraction.
font_main.instantiate();
- font_main->add_data(dfont_main);
+ font_main->set_data(data);
+ font_main->set_multichannel_signed_distance_field(false);
+
text_edit->add_theme_font_override("font", font_main);
base_path = p_path;
@@ -1092,35 +973,27 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
inspector_vars->edit(nullptr);
inspector_general->edit(nullptr);
- int gww = get_theme_font(SNAME("font"))->get_string_size("00000", get_theme_font_size(SNAME("font_size"))).x + 50;
+ text_settings_data.instantiate();
+ ERR_FAIL_NULL(text_settings_data);
+
+ text_settings_data->owner = this;
+
+ for (List<ResourceImporter::ImportOption>::Element *F = options_text.front(); F; F = F->next()) {
+ text_settings_data->defaults[F->get().option.name] = F->get().default_value;
+ }
+
+ text_settings_data->fd = font_main;
+ text_settings_data->options = options_text;
+
+ inspector_text->edit(text_settings_data.ptr());
+
+ int gww = get_theme_font(SNAME("font"))->get_string_size("00000").x + 50;
glyph_table->set_column_custom_minimum_width(0, gww);
glyph_table->clear();
vars_list->clear();
- lang_list->clear();
- script_list->clear();
- ot_list->clear();
-
- selected_chars.clear();
- selected_glyphs.clear();
- text_edit->set_text(String());
vars_list_root = vars_list->create_item();
- lang_list_root = lang_list->create_item();
- script_list_root = script_list->create_item();
- ot_list_root = ot_list->create_item();
-
- options_variations.clear();
- Dictionary var_list = dfont_main->get_supported_variation_list();
- for (int i = 0; i < var_list.size(); i++) {
- int32_t tag = var_list.get_key_at_index(i);
- Vector3i value = var_list.get_value_at_index(i);
- options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, TS->tag_to_name(tag), PROPERTY_HINT_RANGE, itos(value.x) + "," + itos(value.y) + ",1"), value.z));
- }
- options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "0,127,1"), 16));
- options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1"), 0));
- options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "extra_spacing_glyph"), 0));
- options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "extra_spacing_space"), 0));
import_settings_data->defaults.clear();
for (List<ResourceImporter::ImportOption>::Element *E = options_general.front(); E; E = E->next()) {
@@ -1139,157 +1012,58 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
for (List<String>::Element *E = keys.front(); E; E = E->next()) {
String key = E->get();
print_verbose(String(" ") + key + " == " + String(config->get_value("params", key)));
- if (key == "preload/char_ranges") {
- Vector<String> ranges = config->get_value("params", key);
- for (int i = 0; i < ranges.size(); i++) {
- int32_t start, end;
- Vector<String> tokens = ranges[i].split("-");
- if (tokens.size() == 2) {
- if (!ResourceImporterDynamicFont::_decode_range(tokens[0], start) || !ResourceImporterDynamicFont::_decode_range(tokens[1], end)) {
- WARN_PRINT("Invalid range: \"" + ranges[i] + "\"");
- continue;
- }
- } else if (tokens.size() == 1) {
- if (!ResourceImporterDynamicFont::_decode_range(tokens[0], start)) {
- WARN_PRINT("Invalid range: \"" + ranges[i] + "\"");
- continue;
- }
- end = start;
- } else {
- WARN_PRINT("Invalid range: \"" + ranges[i] + "\"");
- continue;
- }
- for (int32_t j = start; j <= end; j++) {
- selected_chars.insert(j);
- }
- }
- } else if (key == "preload/glyph_ranges") {
- Vector<String> ranges = config->get_value("params", key);
- for (int i = 0; i < ranges.size(); i++) {
- int32_t start, end;
- Vector<String> tokens = ranges[i].split("-");
- if (tokens.size() == 2) {
- if (!ResourceImporterDynamicFont::_decode_range(tokens[0], start) || !ResourceImporterDynamicFont::_decode_range(tokens[1], end)) {
- WARN_PRINT("Invalid range: \"" + ranges[i] + "\"");
- continue;
- }
- } else if (tokens.size() == 1) {
- if (!ResourceImporterDynamicFont::_decode_range(tokens[0], start)) {
- WARN_PRINT("Invalid range: \"" + ranges[i] + "\"");
- continue;
- }
- end = start;
- } else {
- WARN_PRINT("Invalid range: \"" + ranges[i] + "\"");
- continue;
- }
- for (int32_t j = start; j <= end; j++) {
- selected_glyphs.insert(j);
- }
- }
- } else if (key == "preload/configurations") {
- Vector<String> variations = config->get_value("params", key);
- for (int i = 0; i < variations.size(); i++) {
+ if (key == "preload") {
+ Array preload_configurations = config->get_value("params", key);
+ for (int i = 0; i < preload_configurations.size(); i++) {
+ Dictionary preload_config = preload_configurations[i];
+
+ Dictionary variation = preload_config.has("variation_opentype") ? preload_config["variation_opentype"].operator Dictionary() : Dictionary();
+ double embolden = preload_config.has("variation_embolden") ? preload_config["variation_embolden"].operator double() : 0;
+ int face_index = preload_config.has("variation_face_index") ? preload_config["variation_face_index"].operator int() : 0;
+ Transform2D transform = preload_config.has("variation_transform") ? preload_config["variation_transform"].operator Transform2D() : Transform2D();
+ Vector2i size = preload_config.has("size") ? preload_config["size"].operator Vector2i() : Vector2i(16, 0);
+ String cfg_name = preload_config.has("name") ? preload_config["name"].operator String() : vformat("Configuration %d", i);
+
TreeItem *vars_item = vars_list->create_item(vars_list_root);
ERR_FAIL_NULL(vars_item);
- vars_item->set_text(0, TTR("Configuration") + " " + itos(i));
+ vars_item->set_text(0, cfg_name);
vars_item->set_editable(0, true);
vars_item->add_button(1, vars_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation"));
vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75));
Ref<DynamicFontImportSettingsData> import_variation_data_custom;
import_variation_data_custom.instantiate();
- import_variation_data_custom->owner = this;
ERR_FAIL_NULL(import_variation_data_custom);
+ import_variation_data_custom->owner = this;
for (List<ResourceImporter::ImportOption>::Element *F = options_variations.front(); F; F = F->next()) {
import_variation_data_custom->defaults[F->get().option.name] = F->get().default_value;
}
- import_variation_data_custom->options = options_variations;
+ import_variation_data_custom->fd = font_main;
+ import_variation_data_custom->options = options_variations;
vars_item->set_metadata(0, import_variation_data_custom);
- Vector<String> variation_tags = variations[i].split(",");
- for (int j = 0; j < variation_tags.size(); j++) {
- Vector<String> tokens = variation_tags[j].split("=");
- if (tokens[0] == "name") {
- vars_item->set_text(0, tokens[1]);
- } else if (tokens[0] == "size" || tokens[0] == "outline_size" || tokens[0] == "extra_spacing_space" || tokens[0] == "extra_spacing_glyph") {
- import_variation_data_custom->set(tokens[0], tokens[1].to_int());
- } else {
- import_variation_data_custom->set(tokens[0], tokens[1].to_float());
- }
+
+ import_variation_data_custom->set("size", size.x);
+ import_variation_data_custom->set("outline_size", size.y);
+ import_variation_data_custom->set("variation_opentype", variation);
+ import_variation_data_custom->set("variation_embolden", embolden);
+ import_variation_data_custom->set("variation_face_index", face_index);
+ import_variation_data_custom->set("variation_transform", transform);
+
+ Array chars = preload_config["chars"];
+ for (int j = 0; j < chars.size(); j++) {
+ char32_t c = chars[j].operator int();
+ import_variation_data_custom->selected_chars.insert(c);
}
- }
- } else if (key == "support_overrides/language_enabled") {
- PackedStringArray _langs = config->get_value("params", key);
- for (int i = 0; i < _langs.size(); i++) {
- TreeItem *lang_item = lang_list->create_item(lang_list_root);
- ERR_FAIL_NULL(lang_item);
-
- lang_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- lang_item->set_editable(0, true);
- lang_item->set_checked(0, true);
- lang_item->set_text(1, _langs[i]);
- lang_item->set_editable(1, true);
- lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove"));
- }
- } else if (key == "support_overrides/language_disabled") {
- PackedStringArray _langs = config->get_value("params", key);
- for (int i = 0; i < _langs.size(); i++) {
- TreeItem *lang_item = lang_list->create_item(lang_list_root);
- ERR_FAIL_NULL(lang_item);
-
- lang_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- lang_item->set_editable(0, true);
- lang_item->set_checked(0, false);
- lang_item->set_text(1, _langs[i]);
- lang_item->set_editable(1, true);
- lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove"));
- }
- } else if (key == "support_overrides/script_enabled") {
- PackedStringArray _scripts = config->get_value("params", key);
- for (int i = 0; i < _scripts.size(); i++) {
- TreeItem *script_item = script_list->create_item(script_list_root);
- ERR_FAIL_NULL(script_item);
-
- script_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- script_item->set_editable(0, true);
- script_item->set_checked(0, true);
- script_item->set_text(1, _scripts[i]);
- script_item->set_editable(1, true);
- script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove"));
- }
- } else if (key == "support_overrides/script_disabled") {
- PackedStringArray _scripts = config->get_value("params", key);
- for (int i = 0; i < _scripts.size(); i++) {
- TreeItem *script_item = script_list->create_item(script_list_root);
- ERR_FAIL_NULL(script_item);
-
- script_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- script_item->set_editable(0, true);
- script_item->set_checked(0, false);
- script_item->set_text(1, _scripts[i]);
- script_item->set_editable(1, true);
- script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove"));
- }
- } else if (key == "opentype_feature_overrides") {
- Dictionary features = config->get_value("params", key);
- for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) {
- TreeItem *ot_item = ot_list->create_item(ot_list_root);
- ERR_FAIL_NULL(ot_item);
- int32_t value = features[*ftr];
- if (ftr->get_type() == Variant::STRING) {
- ot_item->set_text(0, *ftr);
- } else {
- ot_item->set_text(0, TS->tag_to_name(*ftr));
+
+ Array glyphs = preload_config["glyphs"];
+ for (int j = 0; j < glyphs.size(); j++) {
+ int32_t c = glyphs[j];
+ import_variation_data_custom->selected_glyphs.insert(c);
}
- ot_item->set_editable(0, false);
- ot_item->set_text(1, itos(value));
- ot_item->set_editable(1, true);
- ot_item->add_button(2, ot_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove"));
- ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
}
} else {
Variant value = config->get_value("params", key);
@@ -1297,61 +1071,26 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
}
}
}
- label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(selected_glyphs.size()));
+ import_settings_data->fd = font_main;
import_settings_data->options = options_general;
inspector_general->edit(import_settings_data.ptr());
import_settings_data->notify_property_list_changed();
- if (font_preview->get_data_count() > 0) {
- font_preview->get_data(0)->set_face_index(import_settings_data->get("face_index"));
- font_preview->get_data(0)->set_antialiased(import_settings_data->get("antialiased"));
- font_preview->get_data(0)->set_multichannel_signed_distance_field(import_settings_data->get("multichannel_signed_distance_field"));
- font_preview->get_data(0)->set_msdf_pixel_range(import_settings_data->get("msdf_pixel_range"));
- font_preview->get_data(0)->set_msdf_size(import_settings_data->get("msdf_size"));
- font_preview->get_data(0)->set_force_autohinter(import_settings_data->get("force_autohinter"));
- font_preview->get_data(0)->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int());
- font_preview->get_data(0)->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int());
- font_preview->get_data(0)->set_embolden(import_settings_data->get("embolden"));
- font_preview->get_data(0)->set_transform(import_settings_data->get("transform"));
- font_preview->get_data(0)->set_oversampling(import_settings_data->get("oversampling"));
+ if (font_preview.is_valid()) {
+ font_preview->set_antialiased(import_settings_data->get("antialiased"));
+ font_preview->set_multichannel_signed_distance_field(import_settings_data->get("multichannel_signed_distance_field"));
+ font_preview->set_msdf_pixel_range(import_settings_data->get("msdf_pixel_range"));
+ font_preview->set_msdf_size(import_settings_data->get("msdf_size"));
+ font_preview->set_force_autohinter(import_settings_data->get("force_autohinter"));
+ font_preview->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int());
+ font_preview->set_subpixel_positioning((TextServer::SubpixelPositioning)import_settings_data->get("subpixel_positioning").operator int());
+ font_preview->set_oversampling(import_settings_data->get("oversampling"));
}
font_preview_label->add_theme_font_override("font", font_preview);
+ font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE);
font_preview_label->update();
- menu_ot->clear();
- menu_ot_ss->clear();
- menu_ot_cv->clear();
- menu_ot_cu->clear();
- bool have_ss = false;
- bool have_cv = false;
- bool have_cu = false;
- Dictionary features = font_preview->get_feature_list();
- for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) {
- String ftr_name = TS->tag_to_name(*ftr);
- if (ftr_name.begins_with("stylistic_set_")) {
- menu_ot_ss->add_item(ftr_name.capitalize(), (int32_t)*ftr);
- have_ss = true;
- } else if (ftr_name.begins_with("character_variant_")) {
- menu_ot_cv->add_item(ftr_name.capitalize(), (int32_t)*ftr);
- have_cv = true;
- } else if (ftr_name.begins_with("custom_")) {
- menu_ot_cu->add_item(ftr_name.replace("custom_", ""), (int32_t)*ftr);
- have_cu = true;
- } else {
- menu_ot->add_item(ftr_name.capitalize(), (int32_t)*ftr);
- }
- }
- if (have_ss) {
- menu_ot->add_submenu_item(RTR("Stylistic Sets"), "SSMenu");
- }
- if (have_cv) {
- menu_ot->add_submenu_item(RTR("Character Variants"), "CVMenu");
- }
- if (have_cu) {
- menu_ot->add_submenu_item(RTR("Custom"), "CUMenu");
- }
-
_variations_validate();
popup_centered_ratio();
@@ -1366,7 +1105,8 @@ DynamicFontImportSettings *DynamicFontImportSettings::get_singleton() {
DynamicFontImportSettings::DynamicFontImportSettings() {
singleton = this;
- options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "face_index"), 0));
+ options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));
+
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "antialiased"), true));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "generate_mipmaps"), false));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
@@ -1375,44 +1115,29 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), 1));
- options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_RANGE, "-2,2,0.01"), 0.f));
- options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::TRANSFORM2D, "transform"), Transform2D()));
options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0));
- options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "compress", PROPERTY_HINT_NONE, ""), false));
-
- // Popup menus
-
- locale_select = memnew(EditorLocaleDialog);
- locale_select->connect("locale_selected", callable_mp(this, &DynamicFontImportSettings::_lang_add_item));
- add_child(locale_select);
- menu_scripts = memnew(PopupMenu);
- menu_scripts->set_name("Script");
- script_codes = TranslationServer::get_singleton()->get_all_scripts();
- for (int i = 0; i < script_codes.size(); i++) {
- menu_scripts->add_item(TranslationServer::get_singleton()->get_script_name(script_codes[i]) + " (" + script_codes[i] + ")", i);
- }
- add_child(menu_scripts);
- menu_scripts->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_script_add_item));
+ options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Metadata Overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));
+ options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "language_support"), Dictionary()));
+ options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "script_support"), Dictionary()));
+ options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_features"), Dictionary()));
- menu_ot = memnew(PopupMenu);
- add_child(menu_ot);
- menu_ot->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+ options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Fallbacks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));
+ options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array()));
- menu_ot_cv = memnew(PopupMenu);
- menu_ot_cv->set_name("CVMenu");
- menu_ot->add_child(menu_ot_cv);
- menu_ot_cv->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+ options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Compress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));
+ options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "compress", PROPERTY_HINT_NONE, ""), false));
- menu_ot_ss = memnew(PopupMenu);
- menu_ot_ss->set_name("SSMenu");
- menu_ot->add_child(menu_ot_ss);
- menu_ot_ss->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+ options_text.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_features"), Dictionary()));
+ options_text.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), ""));
- menu_ot_cu = memnew(PopupMenu);
- menu_ot_cu->set_name("CUMenu");
- menu_ot->add_child(menu_ot_cu);
- menu_ot_cu->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+ options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "0,127,1"), 16));
+ options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1"), 0));
+ options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Variation", PROPERTY_HINT_NONE, "variation", PROPERTY_USAGE_GROUP), Variant()));
+ options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "variation_opentype"), Dictionary()));
+ options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "variation_embolden", PROPERTY_HINT_RANGE, "-2,2,0.01"), 0));
+ options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "variation_face_index"), 0));
+ options_variations.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::TRANSFORM2D, "variation_transform"), Transform2D()));
Color warn_color = (EditorNode::get_singleton()) ? EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")) : Color(1, 1, 0);
@@ -1442,7 +1167,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
main_pages->add_child(page1_vb);
page1_description = memnew(Label);
- page1_description->set_text(TTR("Select font rendering options:"));
+ page1_description->set_text(TTR("Select font rendering options, fallback font, and metadata override:"));
page1_description->set_h_size_flags(Control::SIZE_EXPAND_FILL);
page1_vb->add_child(page1_description);
@@ -1451,15 +1176,25 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
page1_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
page1_vb->add_child(page1_hb);
+ VBoxContainer *page1_lbl_vb = memnew(VBoxContainer);
+ page1_lbl_vb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ page1_lbl_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ page1_hb->add_child(page1_lbl_vb);
+
+ font_name_label = memnew(Label);
+ font_name_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ font_name_label->set_clip_text(true);
+ font_name_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ page1_lbl_vb->add_child(font_name_label);
+
font_preview_label = memnew(Label);
- font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE);
font_preview_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
font_preview_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
font_preview_label->set_autowrap_mode(TextServer::AUTOWRAP_ARBITRARY);
font_preview_label->set_clip_text(true);
font_preview_label->set_v_size_flags(Control::SIZE_EXPAND_FILL);
font_preview_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- page1_hb->add_child(font_preview_label);
+ page1_lbl_vb->add_child(font_preview_label);
inspector_general = memnew(EditorInspector);
inspector_general->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -1469,11 +1204,11 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
// Page 2 layout: Configurations
VBoxContainer *page2_vb = memnew(VBoxContainer);
- page2_vb->set_name(TTR("Sizes and Variations"));
+ page2_vb->set_name(TTR("Pre-render configurations"));
main_pages->add_child(page2_vb);
page2_description = memnew(Label);
- page2_description->set_text(TTR("Add font size, variation coordinates, and extra spacing combinations to pre-render:"));
+ page2_description->set_text(TTR("Add font size, and variation coordinates, and select glyphs to pre-render:"));
page2_description->set_h_size_flags(Control::SIZE_EXPAND_FILL);
page2_description->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
page2_vb->add_child(page2_description);
@@ -1517,48 +1252,44 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
inspector_vars = memnew(EditorInspector);
inspector_vars->set_v_size_flags(Control::SIZE_EXPAND_FILL);
inspector_vars->connect("property_edited", callable_mp(this, &DynamicFontImportSettings::_variation_changed));
- page2_hb->add_child(inspector_vars);
-
- // Page 3 layout: Text to select glyphs
- VBoxContainer *page3_vb = memnew(VBoxContainer);
- page3_vb->set_name(TTR("Glyphs from the Text"));
- main_pages->add_child(page3_vb);
+ page2_side_vb->add_child(inspector_vars);
- page3_description = memnew(Label);
- page3_description->set_text(TTR("Enter a text to shape and add all required glyphs to pre-render list:"));
- page3_description->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- page3_description->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
- page3_vb->add_child(page3_description);
+ preload_pages = memnew(TabContainer);
+ preload_pages->set_tab_alignment(TabBar::ALIGNMENT_CENTER);
+ preload_pages->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ preload_pages->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ page2_hb->add_child(preload_pages);
- HBoxContainer *ot_hb = memnew(HBoxContainer);
- page3_vb->add_child(ot_hb);
- ot_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ // Page 2.1 layout: Text to select glyphs
+ VBoxContainer *page2_1_vb = memnew(VBoxContainer);
+ page2_1_vb->set_name(TTR("Glyphs from the Text"));
+ preload_pages->add_child(page2_1_vb);
- Label *label_ed_ftr = memnew(Label);
- ot_hb->add_child(label_ed_ftr);
- label_ed_ftr->set_text(TTR("OpenType features:"));
+ page2_1_description = memnew(Label);
+ page2_1_description->set_text(TTR("Enter a text to shape and add all required glyphs to pre-render list:"));
+ page2_1_description->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ page2_1_description->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
+ page2_1_vb->add_child(page2_1_description);
- ftr_edit = memnew(LineEdit);
- ot_hb->add_child(ftr_edit);
- ftr_edit->connect("text_changed", callable_mp(this, &DynamicFontImportSettings::_change_text_opts));
- ftr_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ HSplitContainer *page2_1_hb = memnew(HSplitContainer);
+ page2_1_vb->add_child(page2_1_hb);
+ page2_1_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ page2_1_hb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- Label *label_ed_lang = memnew(Label);
- ot_hb->add_child(label_ed_lang);
- label_ed_lang->set_text(TTR("Text language:"));
+ inspector_text = memnew(EditorInspector);
- lang_edit = memnew(LineEdit);
- ot_hb->add_child(lang_edit);
- lang_edit->connect("text_changed", callable_mp(this, &DynamicFontImportSettings::_change_text_opts));
- lang_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ inspector_text->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ inspector_text->set_custom_minimum_size(Size2(300 * EDSCALE, 250 * EDSCALE));
+ inspector_text->connect("property_edited", callable_mp(this, &DynamicFontImportSettings::_change_text_opts));
+ page2_1_hb->add_child(inspector_text);
text_edit = memnew(TextEdit);
- page3_vb->add_child(text_edit);
+ page2_1_hb->add_child(text_edit);
text_edit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
text_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
HBoxContainer *text_hb = memnew(HBoxContainer);
- page3_vb->add_child(text_hb);
+ page2_1_vb->add_child(text_hb);
text_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
label_glyphs = memnew(Label);
@@ -1576,21 +1307,21 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
btn_clear->set_text(TTR("Clear glyph list"));
btn_clear->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_glyph_clear));
- // Page 4 layout: Character map
- VBoxContainer *page4_vb = memnew(VBoxContainer);
- page4_vb->set_name(TTR("Glyphs from the Character Map"));
- main_pages->add_child(page4_vb);
+ // Page 2.2 layout: Character map
+ VBoxContainer *page2_2_vb = memnew(VBoxContainer);
+ page2_2_vb->set_name(TTR("Glyphs from the Character Map"));
+ preload_pages->add_child(page2_2_vb);
- page4_description = memnew(Label);
- page4_description->set_text(TTR("Add or remove additional glyphs from the character map to pre-render list:\nNote: Some stylistic alternatives and glyph variants do not have one-to-one correspondence to character, and not shown in this map, use \"Glyphs from the text\" to add these."));
- page4_description->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- page4_description->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
- page4_vb->add_child(page4_description);
+ page2_2_description = memnew(Label);
+ page2_2_description->set_text(TTR("Add or remove glyphs from the character map to pre-render list:\nNote: Some stylistic alternatives and glyph variants do not have one-to-one correspondence to character, and not shown in this map, use \"Glyphs from the text\" tab to add these."));
+ page2_2_description->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ page2_2_description->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
+ page2_2_vb->add_child(page2_2_description);
HSplitContainer *glyphs_split = memnew(HSplitContainer);
glyphs_split->set_v_size_flags(Control::SIZE_EXPAND_FILL);
glyphs_split->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- page4_vb->add_child(glyphs_split);
+ page2_2_vb->add_child(glyphs_split);
glyph_table = memnew(Tree);
glyphs_split->add_child(glyph_table);
@@ -1627,106 +1358,11 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
_add_glyph_range_item(unicode_ranges[i].start, unicode_ranges[i].end, unicode_ranges[i].name);
}
- // Page 4 layout: Metadata override
- VBoxContainer *page5_vb = memnew(VBoxContainer);
- page5_vb->set_name(TTR("Metadata Override"));
- main_pages->add_child(page5_vb);
-
- page5_description = memnew(Label);
- page5_description->set_text(TTR("Add or remove language and script support overrides, to control fallback font selection order:"));
- page5_description->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- page5_description->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
- page5_vb->add_child(page5_description);
-
- HBoxContainer *hb_lang = memnew(HBoxContainer);
- page5_vb->add_child(hb_lang);
-
- label_langs = memnew(Label);
- label_langs->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
- label_langs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- label_langs->set_text(TTR("Language support overrides"));
- hb_lang->add_child(label_langs);
-
- add_lang = memnew(Button);
- hb_lang->add_child(add_lang);
- add_lang->set_tooltip(TTR("Add language override"));
- add_lang->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- add_lang->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_lang_add));
-
- lang_list = memnew(Tree);
- page5_vb->add_child(lang_list);
- lang_list->set_hide_root(true);
- lang_list->set_columns(3);
- lang_list->set_column_expand(0, false); // Check
- lang_list->set_column_custom_minimum_width(0, 50 * EDSCALE);
- lang_list->set_column_expand(1, true);
- lang_list->set_column_custom_minimum_width(1, 80 * EDSCALE);
- lang_list->set_column_expand(2, false);
- lang_list->set_column_custom_minimum_width(2, 50 * EDSCALE);
- lang_list->connect("button_clicked", callable_mp(this, &DynamicFontImportSettings::_lang_remove));
- lang_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
-
- HBoxContainer *hb_script = memnew(HBoxContainer);
- page5_vb->add_child(hb_script);
-
- label_script = memnew(Label);
- label_script->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
- label_script->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- label_script->set_text(TTR("Script support overrides"));
- hb_script->add_child(label_script);
-
- add_script = memnew(Button);
- hb_script->add_child(add_script);
- add_script->set_tooltip(TTR("Add script override"));
- add_script->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- add_script->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_script_add));
-
- script_list = memnew(Tree);
- page5_vb->add_child(script_list);
- script_list->set_hide_root(true);
- script_list->set_columns(3);
- script_list->set_column_expand(0, false);
- script_list->set_column_custom_minimum_width(0, 50 * EDSCALE);
- script_list->set_column_expand(1, true);
- script_list->set_column_custom_minimum_width(1, 80 * EDSCALE);
- script_list->set_column_expand(2, false);
- script_list->set_column_custom_minimum_width(2, 50 * EDSCALE);
- script_list->connect("button_clicked", callable_mp(this, &DynamicFontImportSettings::_script_remove));
- script_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
-
- HBoxContainer *hb_ot = memnew(HBoxContainer);
- page5_vb->add_child(hb_ot);
-
- label_ot = memnew(Label);
- label_ot->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
- label_ot->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- label_ot->set_text(TTR("OpenType feature overrides"));
- hb_ot->add_child(label_ot);
-
- add_ot = memnew(Button);
- hb_ot->add_child(add_ot);
- add_ot->set_tooltip(TTR("Add feature override"));
- add_ot->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- add_ot->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add));
-
- ot_list = memnew(Tree);
- page5_vb->add_child(ot_list);
- ot_list->set_hide_root(true);
- ot_list->set_columns(3);
- ot_list->set_column_expand(0, true);
- ot_list->set_column_custom_minimum_width(0, 80 * EDSCALE);
- ot_list->set_column_expand(1, true);
- ot_list->set_column_custom_minimum_width(1, 80 * EDSCALE);
- ot_list->set_column_expand(2, false);
- ot_list->set_column_custom_minimum_width(2, 50 * EDSCALE);
- ot_list->connect("button_clicked", callable_mp(this, &DynamicFontImportSettings::_ot_remove));
- ot_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
-
// Common
import_settings_data.instantiate();
import_settings_data->owner = this;
- get_ok_button()->set_text(TTR("Reimport"));
- get_cancel_button()->set_text(TTR("Close"));
+ set_ok_button_text(TTR("Reimport"));
+ set_cancel_button_text(TTR("Close"));
}
diff --git a/editor/import/dynamic_font_import_settings.h b/editor/import/dynamic_font_import_settings.h
index ba75c98057..a1f763b445 100644
--- a/editor/import/dynamic_font_import_settings.h
+++ b/editor/import/dynamic_font_import_settings.h
@@ -45,7 +45,30 @@
#include "scene/resources/font.h"
#include "servers/text_server.h"
-class DynamicFontImportSettingsData;
+class DynamicFontImportSettings;
+
+class DynamicFontImportSettingsData : public RefCounted {
+ GDCLASS(DynamicFontImportSettingsData, RefCounted)
+ friend class DynamicFontImportSettings;
+
+ HashMap<StringName, Variant> settings;
+ HashMap<StringName, Variant> defaults;
+ List<ResourceImporter::ImportOption> options;
+ DynamicFontImportSettings *owner = nullptr;
+
+ HashSet<char32_t> selected_chars;
+ HashSet<int32_t> selected_glyphs;
+
+ Ref<FontFile> fd;
+
+public:
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
+ Ref<FontFile> get_font() const;
+};
+
class EditorFileDialog;
class EditorInspector;
class EditorLocaleDialog;
@@ -67,21 +90,19 @@ class DynamicFontImportSettings : public ConfirmationDialog {
List<ResourceImporter::ImportOption> options_variations;
List<ResourceImporter::ImportOption> options_general;
- EditorLocaleDialog *locale_select = nullptr;
- Vector<String> script_codes;
-
// Root layout
Label *label_warn = nullptr;
TabContainer *main_pages = nullptr;
// Page 1 layout: Rendering Options
Label *page1_description = nullptr;
+ Label *font_name_label = nullptr;
Label *font_preview_label = nullptr;
EditorInspector *inspector_general = nullptr;
void _main_prop_changed(const String &p_edited_property);
- // Page 2 layout: Configurations
+ // Page 2 layout: Preload Configurations
Label *page2_description = nullptr;
Label *label_vars = nullptr;
Button *add_var = nullptr;
@@ -95,19 +116,23 @@ class DynamicFontImportSettings : public ConfirmationDialog {
void _variation_changed(const String &p_edited_property);
void _variations_validate();
- // Page 3 layout: Text to select glyphs
- Label *page3_description = nullptr;
+ TabContainer *preload_pages = nullptr;
+
+ // Page 2.1 layout: Text to select glyphs
+ Label *page2_1_description = nullptr;
Label *label_glyphs = nullptr;
TextEdit *text_edit = nullptr;
- LineEdit *ftr_edit = nullptr;
- LineEdit *lang_edit = nullptr;
+ EditorInspector *inspector_text = nullptr;
+
+ List<ResourceImporter::ImportOption> options_text;
+ Ref<DynamicFontImportSettingsData> text_settings_data;
void _change_text_opts();
void _glyph_text_selected();
void _glyph_clear();
- // Page 4 layout: Character map
- Label *page4_description = nullptr;
+ // Page 2.2 layout: Character map
+ Label *page2_2_description = nullptr;
Tree *glyph_table = nullptr;
Tree *glyph_tree = nullptr;
TreeItem *glyph_root = nullptr;
@@ -119,51 +144,12 @@ class DynamicFontImportSettings : public ConfirmationDialog {
bool _char_update(int32_t p_char);
void _range_update(int32_t p_start, int32_t p_end);
- // Page 5 layout: Metadata override
- Label *page5_description = nullptr;
- Button *add_lang = nullptr;
- Button *add_script = nullptr;
- Button *add_ot = nullptr;
-
- PopupMenu *menu_scripts = nullptr;
- PopupMenu *menu_ot = nullptr;
- PopupMenu *menu_ot_ss = nullptr;
- PopupMenu *menu_ot_cv = nullptr;
- PopupMenu *menu_ot_cu = nullptr;
-
- Tree *lang_list = nullptr;
- TreeItem *lang_list_root = nullptr;
- Label *label_langs = nullptr;
-
- Tree *script_list = nullptr;
- TreeItem *script_list_root = nullptr;
- Label *label_script = nullptr;
-
- Tree *ot_list = nullptr;
- TreeItem *ot_list_root = nullptr;
- Label *label_ot = nullptr;
-
- void _lang_add();
- void _lang_add_item(const String &p_locale);
- void _lang_remove(Object *p_item, int p_column, int p_id, MouseButton p_button);
-
- void _script_add();
- void _script_add_item(int p_option);
- void _script_remove(Object *p_item, int p_column, int p_id, MouseButton p_button);
-
- void _ot_add();
- void _ot_add_item(int p_option);
- void _ot_remove(Object *p_item, int p_column, int p_id, MouseButton p_button);
-
// Common
void _add_glyph_range_item(int32_t p_start, int32_t p_end, const String &p_name);
- Ref<Font> font_preview;
- Ref<Font> font_main;
-
- RBSet<char32_t> selected_chars;
- RBSet<int32_t> selected_glyphs;
+ Ref<FontFile> font_preview;
+ Ref<FontFile> font_main;
void _re_import();
diff --git a/editor/import/post_import_plugin_skeleton_renamer.cpp b/editor/import/post_import_plugin_skeleton_renamer.cpp
new file mode 100644
index 0000000000..bf84348ac3
--- /dev/null
+++ b/editor/import/post_import_plugin_skeleton_renamer.cpp
@@ -0,0 +1,178 @@
+/*************************************************************************/
+/* post_import_plugin_skeleton_renamer.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "post_import_plugin_skeleton_renamer.h"
+
+#include "editor/import/scene_import_settings.h"
+#include "scene/3d/importer_mesh_instance_3d.h"
+#include "scene/3d/skeleton_3d.h"
+#include "scene/animation/animation_player.h"
+#include "scene/resources/bone_map.h"
+
+void PostImportPluginSkeletonRenamer::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) {
+ if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) {
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/bone_renamer/rename_bones"), true));
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/bone_renamer/unique_node/make_unique"), true));
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::STRING, "retarget/bone_renamer/unique_node/skeleton_name"), "GeneralSkeleton"));
+ }
+}
+
+void PostImportPluginSkeletonRenamer::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) {
+ if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) {
+ // Prepare objects.
+ Object *map = p_options["retarget/bone_map"].get_validated_object();
+ if (!map || !bool(p_options["retarget/bone_renamer/rename_bones"])) {
+ return;
+ }
+ BoneMap *bone_map = Object::cast_to<BoneMap>(map);
+ Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node);
+
+ // Rename bones in Skeleton3D.
+ {
+ int len = skeleton->get_bone_count();
+ for (int i = 0; i < len; i++) {
+ StringName bn = bone_map->find_profile_bone_name(skeleton->get_bone_name(i));
+ if (bn) {
+ skeleton->set_bone_name(i, bn);
+ }
+ }
+ }
+
+ // Rename bones in Skin.
+ {
+ TypedArray<Node> nodes = p_base_scene->find_children("*", "ImporterMeshInstance3D");
+ while (nodes.size()) {
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(nodes.pop_back());
+ Ref<Skin> skin = mi->get_skin();
+ if (skin.is_valid()) {
+ Node *node = mi->get_node(mi->get_skeleton_path());
+ if (node) {
+ Skeleton3D *mesh_skeleton = Object::cast_to<Skeleton3D>(node);
+ if (mesh_skeleton && node == skeleton) {
+ int len = skin->get_bind_count();
+ for (int i = 0; i < len; i++) {
+ StringName bn = bone_map->find_profile_bone_name(skin->get_bind_name(i));
+ if (bn) {
+ skin->set_bind_name(i, bn);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Rename bones in AnimationPlayer.
+ {
+ TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer");
+ while (nodes.size()) {
+ AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back());
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (const StringName &name : anims) {
+ Ref<Animation> anim = ap->get_animation(name);
+ int len = anim->get_track_count();
+ for (int i = 0; i < len; i++) {
+ if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) {
+ continue;
+ }
+ String track_path = String(anim->track_get_path(i).get_concatenated_names());
+ Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path));
+ if (node) {
+ Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node);
+ if (track_skeleton && track_skeleton == skeleton) {
+ StringName bn = bone_map->find_profile_bone_name(anim->track_get_path(i).get_subname(0));
+ if (bn) {
+ anim->track_set_path(i, track_path + ":" + bn);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Rename bones in all Nodes by calling method.
+ {
+ Vector<Variant> vargs;
+ vargs.push_back(p_base_scene);
+ vargs.push_back(skeleton);
+ vargs.push_back(bone_map);
+ const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * vargs.size());
+ const Variant *args = vargs.ptr();
+ uint32_t argcount = vargs.size();
+ for (uint32_t i = 0; i < argcount; i++) {
+ argptrs[i] = &args[i];
+ }
+
+ TypedArray<Node> nodes = p_base_scene->find_children("*");
+ while (nodes.size()) {
+ Node *nd = Object::cast_to<Node>(nodes.pop_back());
+ Callable::CallError ce;
+ nd->callp("_notify_skeleton_bones_renamed", argptrs, argcount, ce);
+ }
+ }
+
+ // Make unique skeleton.
+ if (bool(p_options["retarget/bone_renamer/unique_node/make_unique"])) {
+ String unique_name = String(p_options["retarget/bone_renamer/unique_node/skeleton_name"]);
+ ERR_FAIL_COND_MSG(unique_name == String(), "Skeleton unique name cannot be empty.");
+
+ TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer");
+ while (nodes.size()) {
+ AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back());
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (const StringName &name : anims) {
+ Ref<Animation> anim = ap->get_animation(name);
+ int track_len = anim->get_track_count();
+ for (int i = 0; i < track_len; i++) {
+ if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) {
+ continue;
+ }
+ String track_path = String(anim->track_get_path(i).get_concatenated_names());
+ Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path));
+ if (node) {
+ Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node);
+ if (track_skeleton && track_skeleton == skeleton) {
+ anim->track_set_path(i, String("%") + unique_name + String(":") + anim->track_get_path(i).get_concatenated_subnames());
+ }
+ }
+ }
+ }
+ }
+ skeleton->set_name(unique_name);
+ skeleton->set_unique_name_in_owner(true);
+ }
+ }
+}
+
+PostImportPluginSkeletonRenamer::PostImportPluginSkeletonRenamer() {
+}
diff --git a/editor/import/post_import_plugin_skeleton_renamer.h b/editor/import/post_import_plugin_skeleton_renamer.h
new file mode 100644
index 0000000000..73cbabd1c5
--- /dev/null
+++ b/editor/import/post_import_plugin_skeleton_renamer.h
@@ -0,0 +1,46 @@
+/*************************************************************************/
+/* post_import_plugin_skeleton_renamer.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef POST_IMPORT_PLUGIN_SKELETON_RENAMER_H
+#define POST_IMPORT_PLUGIN_SKELETON_RENAMER_H
+
+#include "resource_importer_scene.h"
+
+class PostImportPluginSkeletonRenamer : public EditorScenePostImportPlugin {
+ GDCLASS(PostImportPluginSkeletonRenamer, EditorScenePostImportPlugin);
+
+public:
+ virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) override;
+ virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) override;
+
+ PostImportPluginSkeletonRenamer();
+};
+
+#endif // POST_IMPORT_PLUGIN_SKELETON_RENAMER_H
diff --git a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp
new file mode 100644
index 0000000000..01e145e766
--- /dev/null
+++ b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp
@@ -0,0 +1,418 @@
+/*************************************************************************/
+/* post_import_plugin_skeleton_rest_fixer.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "post_import_plugin_skeleton_rest_fixer.h"
+
+#include "editor/import/scene_import_settings.h"
+#include "scene/3d/importer_mesh_instance_3d.h"
+#include "scene/3d/skeleton_3d.h"
+#include "scene/animation/animation_player.h"
+#include "scene/resources/animation.h"
+#include "scene/resources/bone_map.h"
+
+void PostImportPluginSkeletonRestFixer::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) {
+ if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) {
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/overwrite_axis"), true));
+
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/fix_silhouette/enable"), false));
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "retarget/rest_fixer/fix_silhouette/threshold"), 15));
+
+ // TODO: PostImportPlugin need to be implemented such as validate_option(PropertyInfo &property, const Dictionary &p_options).
+ // get_internal_option_visibility() is not sufficient because it can only retrieve options implemented in the core and can only read option values.
+ // r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::ARRAY, "retarget/rest_fixer/filter", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::STRING_NAME, PROPERTY_HINT_ENUM, "Hips,Spine,Chest")), Array()));
+ r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::ARRAY, "retarget/rest_fixer/fix_silhouette/filter", PROPERTY_HINT_ARRAY_TYPE, "StringName"), Array()));
+ }
+}
+
+void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) {
+ if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) {
+ // Prepare objects.
+ Object *map = p_options["retarget/bone_map"].get_validated_object();
+ if (!map) {
+ return;
+ }
+ BoneMap *bone_map = Object::cast_to<BoneMap>(map);
+ Ref<SkeletonProfile> profile = bone_map->get_profile();
+ if (!profile.is_valid()) {
+ return;
+ }
+ Skeleton3D *src_skeleton = Object::cast_to<Skeleton3D>(p_node);
+ if (!src_skeleton) {
+ return;
+ }
+ bool is_renamed = bool(p_options["retarget/bone_renamer/rename_bones"]);
+ Array filter = p_options["retarget/rest_fixer/fix_silhouette/filter"];
+ bool is_rest_changed = false;
+
+ // Build profile skeleton.
+ Skeleton3D *prof_skeleton = memnew(Skeleton3D);
+ {
+ int prof_bone_len = profile->get_bone_size();
+ // Add single bones.
+ for (int i = 0; i < prof_bone_len; i++) {
+ prof_skeleton->add_bone(profile->get_bone_name(i));
+ prof_skeleton->set_bone_rest(i, profile->get_reference_pose(i));
+ }
+ // Set parents.
+ for (int i = 0; i < prof_bone_len; i++) {
+ int parent = profile->find_bone(profile->get_bone_parent(i));
+ if (parent >= 0) {
+ prof_skeleton->set_bone_parent(i, parent);
+ }
+ }
+ }
+
+ // Complement Rotation track for compatibility between different rests.
+ {
+ TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer");
+ while (nodes.size()) {
+ AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back());
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (const StringName &name : anims) {
+ Ref<Animation> anim = ap->get_animation(name);
+ int track_len = anim->get_track_count();
+
+ // Detect does the animation have skeleton's TRS track.
+ String track_path;
+ bool found_skeleton = false;
+ for (int i = 0; i < track_len; i++) {
+ if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) {
+ continue;
+ }
+ track_path = String(anim->track_get_path(i).get_concatenated_names());
+ Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path));
+ if (node) {
+ Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node);
+ if (track_skeleton && track_skeleton == src_skeleton) {
+ found_skeleton = true;
+ break;
+ }
+ }
+ }
+
+ if (found_skeleton) {
+ // Search and insert rot track if it doesn't exist.
+ for (int prof_idx = 0; prof_idx < prof_skeleton->get_bone_count(); prof_idx++) {
+ String bone_name = is_renamed ? prof_skeleton->get_bone_name(prof_idx) : String(bone_map->get_skeleton_bone_name(prof_skeleton->get_bone_name(prof_idx)));
+ if (bone_name == String()) {
+ continue;
+ }
+ int src_idx = src_skeleton->find_bone(bone_name);
+ if (src_idx == -1) {
+ continue;
+ }
+ String insert_path = track_path + ":" + bone_name;
+ int rot_track = anim->find_track(insert_path, Animation::TYPE_ROTATION_3D);
+ if (rot_track == -1) {
+ int track = anim->add_track(Animation::TYPE_ROTATION_3D);
+ anim->track_set_path(track, insert_path);
+ anim->rotation_track_insert_key(track, 0, src_skeleton->get_bone_rest(src_idx).basis.get_rotation_quaternion());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Fix silhouette.
+ Vector<Transform3D> silhouette_diff; // Transform values to be ignored when overwrite axis.
+ silhouette_diff.resize(src_skeleton->get_bone_count());
+ Transform3D *silhouette_diff_w = silhouette_diff.ptrw();
+ if (bool(p_options["retarget/rest_fixer/fix_silhouette/enable"])) {
+ LocalVector<Transform3D> old_skeleton_global_rest;
+ for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
+ old_skeleton_global_rest.push_back(src_skeleton->get_bone_global_rest(i));
+ }
+
+ Vector<int> bones_to_process = prof_skeleton->get_parentless_bones();
+ while (bones_to_process.size() > 0) {
+ int prof_idx = bones_to_process[0];
+ bones_to_process.erase(prof_idx);
+ Vector<int> prof_children = prof_skeleton->get_bone_children(prof_idx);
+ for (int i = 0; i < prof_children.size(); i++) {
+ bones_to_process.push_back(prof_children[i]);
+ }
+
+ // Calc virtual/looking direction with origins.
+ bool is_filtered = false;
+ for (int i = 0; i < filter.size(); i++) {
+ if (String(filter[i]) == prof_skeleton->get_bone_name(prof_idx)) {
+ is_filtered = true;
+ break;
+ }
+ }
+ if (is_filtered) {
+ continue;
+ }
+
+ int src_idx = src_skeleton->find_bone(is_renamed ? prof_skeleton->get_bone_name(prof_idx) : String(bone_map->get_skeleton_bone_name(prof_skeleton->get_bone_name(prof_idx))));
+ if (src_idx < 0 || profile->get_tail_direction(prof_idx) == SkeletonProfile::TAIL_DIRECTION_END) {
+ continue;
+ }
+ Vector3 prof_tail;
+ Vector3 src_tail;
+ if (profile->get_tail_direction(prof_idx) == SkeletonProfile::TAIL_DIRECTION_AVERAGE_CHILDREN) {
+ PackedInt32Array prof_bone_children = prof_skeleton->get_bone_children(prof_idx);
+ int children_size = prof_bone_children.size();
+ if (children_size == 0) {
+ continue;
+ }
+ bool exist_all_children = true;
+ for (int i = 0; i < children_size; i++) {
+ int prof_child_idx = prof_bone_children[i];
+ int src_child_idx = src_skeleton->find_bone(is_renamed ? prof_skeleton->get_bone_name(prof_child_idx) : String(bone_map->get_skeleton_bone_name(prof_skeleton->get_bone_name(prof_child_idx))));
+ if (src_child_idx < 0) {
+ exist_all_children = false;
+ break;
+ }
+ prof_tail = prof_tail + prof_skeleton->get_bone_global_rest(prof_child_idx).origin;
+ src_tail = src_tail + src_skeleton->get_bone_global_rest(src_child_idx).origin;
+ }
+ if (!exist_all_children) {
+ continue;
+ }
+ prof_tail = prof_tail / children_size;
+ src_tail = src_tail / children_size;
+ }
+ if (profile->get_tail_direction(prof_idx) == SkeletonProfile::TAIL_DIRECTION_SPECIFIC_CHILD) {
+ int prof_tail_idx = prof_skeleton->find_bone(profile->get_bone_tail(prof_idx));
+ if (prof_tail_idx < 0) {
+ continue;
+ }
+ int src_tail_idx = src_skeleton->find_bone(is_renamed ? prof_skeleton->get_bone_name(prof_tail_idx) : String(bone_map->get_skeleton_bone_name(prof_skeleton->get_bone_name(prof_tail_idx))));
+ if (src_tail_idx < 0) {
+ continue;
+ }
+ prof_tail = prof_skeleton->get_bone_global_rest(prof_tail_idx).origin;
+ src_tail = src_skeleton->get_bone_global_rest(src_tail_idx).origin;
+ }
+
+ Vector3 prof_head = prof_skeleton->get_bone_global_rest(prof_idx).origin;
+ Vector3 src_head = src_skeleton->get_bone_global_rest(src_idx).origin;
+
+ Vector3 prof_dir = prof_tail - prof_head;
+ Vector3 src_dir = src_tail - src_head;
+
+ // Rotate rest.
+ if (Math::abs(Math::rad2deg(src_dir.angle_to(prof_dir))) > float(p_options["retarget/rest_fixer/fix_silhouette/threshold"])) {
+ // Get rotation difference.
+ Vector3 up_vec; // Need to rotate other than roll axis.
+ switch (Vector3(abs(src_dir.x), abs(src_dir.y), abs(src_dir.z)).min_axis_index()) {
+ case Vector3::AXIS_X: {
+ up_vec = Vector3(1, 0, 0);
+ } break;
+ case Vector3::AXIS_Y: {
+ up_vec = Vector3(0, 1, 0);
+ } break;
+ case Vector3::AXIS_Z: {
+ up_vec = Vector3(0, 0, 1);
+ } break;
+ }
+ Basis src_b;
+ src_b = src_b.looking_at(src_dir, up_vec);
+ Basis prof_b;
+ prof_b = src_b.looking_at(prof_dir, up_vec);
+ if (prof_b.is_equal_approx(Basis())) {
+ continue; // May not need to rotate.
+ }
+ Basis diff_b = prof_b * src_b.inverse();
+
+ // Apply rotation difference as global transform to skeleton.
+ Basis src_pg;
+ int src_parent = src_skeleton->get_bone_parent(src_idx);
+ if (src_parent >= 0) {
+ src_pg = src_skeleton->get_bone_global_rest(src_parent).basis;
+ }
+ Transform3D fixed_rest = Transform3D(src_pg.inverse() * diff_b * src_pg * src_skeleton->get_bone_rest(src_idx).basis, src_skeleton->get_bone_rest(src_idx).origin);
+ src_skeleton->set_bone_rest(src_idx, fixed_rest);
+ }
+ }
+
+ // For skin modification in overwrite rest.
+ for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
+ silhouette_diff_w[i] = old_skeleton_global_rest[i] * src_skeleton->get_bone_global_rest(i).inverse();
+ }
+
+ is_rest_changed = true;
+ }
+
+ // Overwrite axis.
+ if (bool(p_options["retarget/rest_fixer/overwrite_axis"])) {
+ LocalVector<Transform3D> old_skeleton_rest;
+ LocalVector<Transform3D> old_skeleton_global_rest;
+ for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
+ old_skeleton_rest.push_back(src_skeleton->get_bone_rest(i));
+ old_skeleton_global_rest.push_back(src_skeleton->get_bone_global_rest(i));
+ }
+
+ Vector<Basis> diffs;
+ diffs.resize(src_skeleton->get_bone_count());
+ Basis *diffs_w = diffs.ptrw();
+
+ Vector<int> bones_to_process = src_skeleton->get_parentless_bones();
+ while (bones_to_process.size() > 0) {
+ int src_idx = bones_to_process[0];
+ bones_to_process.erase(src_idx);
+ Vector<int> src_children = src_skeleton->get_bone_children(src_idx);
+ for (int i = 0; i < src_children.size(); i++) {
+ bones_to_process.push_back(src_children[i]);
+ }
+
+ Basis tgt_rot;
+ StringName src_bone_name = is_renamed ? StringName(src_skeleton->get_bone_name(src_idx)) : bone_map->find_profile_bone_name(src_skeleton->get_bone_name(src_idx));
+ if (src_bone_name != StringName()) {
+ Basis src_pg;
+ int src_parent_idx = src_skeleton->get_bone_parent(src_idx);
+ if (src_parent_idx >= 0) {
+ src_pg = src_skeleton->get_bone_global_rest(src_parent_idx).basis;
+ }
+
+ int prof_idx = profile->find_bone(src_bone_name);
+ if (prof_idx >= 0) {
+ tgt_rot = src_pg.inverse() * prof_skeleton->get_bone_global_rest(prof_idx).basis; // Mapped bone uses reference pose.
+ }
+ /*
+ // If there is rest-relative animation, this logic may be work fine, but currently not so...
+ } else {
+ // tgt_rot = src_pg.inverse() * old_skeleton_global_rest[src_idx].basis; // Non-Mapped bone keeps global rest.
+ }
+ */
+ }
+
+ if (src_skeleton->get_bone_parent(src_idx) >= 0) {
+ diffs_w[src_idx] = tgt_rot.inverse() * diffs[src_skeleton->get_bone_parent(src_idx)] * src_skeleton->get_bone_rest(src_idx).basis;
+ } else {
+ diffs_w[src_idx] = tgt_rot.inverse() * src_skeleton->get_bone_rest(src_idx).basis;
+ }
+
+ Basis diff;
+ if (src_skeleton->get_bone_parent(src_idx) >= 0) {
+ diff = diffs[src_skeleton->get_bone_parent(src_idx)];
+ }
+ src_skeleton->set_bone_rest(src_idx, Transform3D(tgt_rot, diff.xform(src_skeleton->get_bone_rest(src_idx).origin)));
+ }
+
+ // Fix skin.
+ {
+ TypedArray<Node> nodes = p_base_scene->find_children("*", "ImporterMeshInstance3D");
+ while (nodes.size()) {
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(nodes.pop_back());
+ Ref<Skin> skin = mi->get_skin();
+ if (skin.is_valid()) {
+ Node *node = mi->get_node(mi->get_skeleton_path());
+ if (node) {
+ Skeleton3D *mesh_skeleton = Object::cast_to<Skeleton3D>(node);
+ if (mesh_skeleton && node == src_skeleton) {
+ int skin_len = skin->get_bind_count();
+ for (int i = 0; i < skin_len; i++) {
+ StringName bn = skin->get_bind_name(i);
+ int bone_idx = src_skeleton->find_bone(bn);
+ if (bone_idx >= 0) {
+ Transform3D new_rest = silhouette_diff[i] * src_skeleton->get_bone_global_rest(bone_idx);
+ skin->set_bind_pose(i, new_rest.inverse());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Fix animation.
+ {
+ TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer");
+ while (nodes.size()) {
+ AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back());
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (const StringName &name : anims) {
+ Ref<Animation> anim = ap->get_animation(name);
+ int track_len = anim->get_track_count();
+ for (int i = 0; i < track_len; i++) {
+ if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_ROTATION_3D) {
+ continue;
+ }
+
+ if (anim->track_is_compressed(i)) {
+ continue; // TODO: Adopt to compressed track.
+ }
+
+ String track_path = String(anim->track_get_path(i).get_concatenated_names());
+ Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path));
+ if (node) {
+ Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node);
+ if (track_skeleton && track_skeleton == src_skeleton) {
+ StringName bn = anim->track_get_path(i).get_subname(0);
+ if (bn) {
+ int bone_idx = src_skeleton->find_bone(bn);
+
+ Quaternion old_rest = old_skeleton_rest[bone_idx].basis.get_rotation_quaternion();
+ Quaternion new_rest = src_skeleton->get_bone_rest(bone_idx).basis.get_rotation_quaternion();
+ Quaternion old_pg;
+ Quaternion new_pg;
+ int parent_idx = src_skeleton->get_bone_parent(bone_idx);
+ if (parent_idx >= 0) {
+ old_pg = old_skeleton_global_rest[parent_idx].basis.get_rotation_quaternion();
+ new_pg = src_skeleton->get_bone_global_rest(parent_idx).basis.get_rotation_quaternion();
+ }
+
+ int key_len = anim->track_get_key_count(i);
+ for (int j = 0; j < key_len; j++) {
+ Quaternion qt = static_cast<Quaternion>(anim->track_get_key_value(i, j));
+ anim->track_set_key_value(i, j, new_pg.inverse() * old_pg * qt * old_rest.inverse() * old_pg.inverse() * new_pg * new_rest);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ is_rest_changed = true;
+ }
+
+ // Init skeleton pose to new rest.
+ if (is_rest_changed) {
+ for (int i = 0; i < src_skeleton->get_bone_count(); i++) {
+ Transform3D fixed_rest = src_skeleton->get_bone_rest(i);
+ src_skeleton->set_bone_pose_position(i, fixed_rest.origin);
+ src_skeleton->set_bone_pose_rotation(i, fixed_rest.basis.get_rotation_quaternion());
+ src_skeleton->set_bone_pose_scale(i, fixed_rest.basis.get_scale());
+ }
+ }
+
+ memdelete(prof_skeleton);
+ }
+}
+
+PostImportPluginSkeletonRestFixer::PostImportPluginSkeletonRestFixer() {
+}
diff --git a/editor/import/post_import_plugin_skeleton_rest_fixer.h b/editor/import/post_import_plugin_skeleton_rest_fixer.h
new file mode 100644
index 0000000000..11e9d08e88
--- /dev/null
+++ b/editor/import/post_import_plugin_skeleton_rest_fixer.h
@@ -0,0 +1,46 @@
+/*************************************************************************/
+/* post_import_plugin_skeleton_rest_fixer.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef POST_IMPORT_PLUGIN_SKELETON_REST_FIXER_H
+#define POST_IMPORT_PLUGIN_SKELETON_REST_FIXER_H
+
+#include "resource_importer_scene.h"
+
+class PostImportPluginSkeletonRestFixer : public EditorScenePostImportPlugin {
+ GDCLASS(PostImportPluginSkeletonRestFixer, EditorScenePostImportPlugin);
+
+public:
+ virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) override;
+ virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) override;
+
+ PostImportPluginSkeletonRestFixer();
+};
+
+#endif // POST_IMPORT_PLUGIN_SKELETON_REST_FIXER_H
diff --git a/editor/import/resource_importer_bmfont.cpp b/editor/import/resource_importer_bmfont.cpp
index 8a40b113b9..987ca4b911 100644
--- a/editor/import/resource_importer_bmfont.cpp
+++ b/editor/import/resource_importer_bmfont.cpp
@@ -52,7 +52,7 @@ String ResourceImporterBMFont::get_save_extension() const {
}
String ResourceImporterBMFont::get_resource_type() const {
- return "FontData";
+ return "FontFile";
}
bool ResourceImporterBMFont::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
@@ -60,19 +60,25 @@ bool ResourceImporterBMFont::get_option_visibility(const String &p_path, const S
}
void ResourceImporterBMFont::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
+ r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array()));
+
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
}
Error ResourceImporterBMFont::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
print_verbose("Importing BMFont font from: " + p_source_file);
- Ref<FontData> font;
+ Array fallbacks = p_options["fallbacks"];
+
+ Ref<FontFile> font;
font.instantiate();
Error err = font->load_bitmap_font(p_source_file);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load font to file \"" + p_source_file + "\".");
- int flg = ResourceSaver::SaverFlags::FLAG_BUNDLE_RESOURCES | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
+ font->set_fallbacks(fallbacks);
+
+ int flg = 0;
if ((bool)p_options["compress"]) {
flg |= ResourceSaver::SaverFlags::FLAG_COMPRESS;
}
diff --git a/editor/import/resource_importer_dynamic_font.cpp b/editor/import/resource_importer_dynamic_font.cpp
index a92b0fe280..f1a70ff30a 100644
--- a/editor/import/resource_importer_dynamic_font.cpp
+++ b/editor/import/resource_importer_dynamic_font.cpp
@@ -66,7 +66,7 @@ String ResourceImporterDynamicFont::get_save_extension() const {
}
String ResourceImporterDynamicFont::get_resource_type() const {
- return "FontData";
+ return "FontFile";
}
bool ResourceImporterDynamicFont::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
@@ -103,7 +103,7 @@ String ResourceImporterDynamicFont::get_preset_name(int p_idx) const {
void ResourceImporterDynamicFont::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
bool msdf = p_preset == PRESET_MSDF;
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "face_index"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "antialiased"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate_mipmaps"), false));
@@ -114,63 +114,19 @@ void ResourceImporterDynamicFont::get_import_options(const String &p_path, List<
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), 1));
- r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_RANGE, "-2,2,0.01"), 0.f));
- r_options->push_back(ImportOption(PropertyInfo(Variant::TRANSFORM2D, "transform"), Transform2D()));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides"), Dictionary()));
-
- r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/char_ranges"), Vector<String>()));
- r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/glyph_ranges"), Vector<String>()));
- r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/configurations"), Vector<String>()));
-
- r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "support_overrides/language_enabled"), Vector<String>()));
- r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "support_overrides/language_disabled"), Vector<String>()));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Fallbacks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array()));
- r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "support_overrides/script_enabled"), Vector<String>()));
- r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "support_overrides/script_disabled"), Vector<String>()));
-}
+ r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Compress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant()));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
-bool ResourceImporterDynamicFont::_decode_variation(const String &p_token, Dictionary &r_variations, Vector2i &r_size, String &r_name, Vector2i &r_spacing) {
- Vector<String> tokens = p_token.split("=");
- if (tokens.size() == 2) {
- if (tokens[0] == "name") {
- r_name = tokens[1];
- } else if (tokens[0] == "size") {
- r_size.x = tokens[1].to_int();
- } else if (tokens[0] == "outline_size") {
- r_size.y = tokens[1].to_int();
- } else if (tokens[0] == "spacing_space") {
- r_spacing.x = tokens[1].to_int();
- } else if (tokens[0] == "spacing_glyph") {
- r_spacing.y = tokens[1].to_int();
- } else {
- r_variations[tokens[0]] = tokens[1].to_float();
- }
- return true;
- } else {
- WARN_PRINT("Invalid variation: '" + p_token + "'.");
- return false;
- }
-}
-
-bool ResourceImporterDynamicFont::_decode_range(const String &p_token, int32_t &r_pos) {
- if (p_token.begins_with("U+") || p_token.begins_with("u+") || p_token.begins_with("0x")) {
- // Unicode character hex index.
- r_pos = p_token.substr(2).hex_to_int();
- return true;
- } else if (p_token.length() == 3 && p_token[0] == '\'' && p_token[2] == '\'') {
- // Unicode character.
- r_pos = p_token.unicode_at(1);
- return true;
- } else if (p_token.is_numeric()) {
- // Unicode character decimal index.
- r_pos = p_token.to_int();
- return true;
- } else {
- return false;
- }
+ // Hide from the main UI, only for advanced import dialog.
+ r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "preload", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), Array()));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "language_support", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), Dictionary()));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "script_support", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), Dictionary()));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_features", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), Dictionary()));
}
bool ResourceImporterDynamicFont::has_advanced_options() const {
@@ -183,30 +139,26 @@ void ResourceImporterDynamicFont::show_advanced_options(const String &p_path) {
Error ResourceImporterDynamicFont::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
print_verbose("Importing dynamic font from: " + p_source_file);
- int face_index = p_options["face_index"];
-
bool antialiased = p_options["antialiased"];
bool generate_mipmaps = p_options["generate_mipmaps"];
bool msdf = p_options["multichannel_signed_distance_field"];
int px_range = p_options["msdf_pixel_range"];
int px_size = p_options["msdf_size"];
- Dictionary ot_ov = p_options["opentype_feature_overrides"];
+ Dictionary ot_ov = p_options["opentype_features"];
bool autohinter = p_options["force_autohinter"];
int hinting = p_options["hinting"];
int subpixel_positioning = p_options["subpixel_positioning"];
real_t oversampling = p_options["oversampling"];
- real_t embolden = p_options["embolden"];
- Transform2D transform = p_options["transform"];
+ Array fallbacks = p_options["fallbacks"];
// Load base font data.
Vector<uint8_t> data = FileAccess::get_file_as_array(p_source_file);
// Create font.
- Ref<FontData> font;
+ Ref<FontFile> font;
font.instantiate();
font->set_data(data);
- font->set_face_index(face_index);
font->set_antialiased(antialiased);
font->set_generate_mipmaps(generate_mipmaps);
font->set_multichannel_signed_distance_field(msdf);
@@ -216,105 +168,52 @@ Error ResourceImporterDynamicFont::import(const String &p_source_file, const Str
font->set_fixed_size(0);
font->set_force_autohinter(autohinter);
font->set_subpixel_positioning((TextServer::SubpixelPositioning)subpixel_positioning);
- font->set_embolden(embolden);
- font->set_transform(transform);
font->set_hinting((TextServer::Hinting)hinting);
font->set_oversampling(oversampling);
+ font->set_fallbacks(fallbacks);
- Vector<String> lang_en = p_options["support_overrides/language_enabled"];
- for (int i = 0; i < lang_en.size(); i++) {
- font->set_language_support_override(lang_en[i], true);
+ Dictionary langs = p_options["language_support"];
+ for (int i = 0; i < langs.size(); i++) {
+ String key = langs.get_key_at_index(i);
+ bool enabled = langs.get_value_at_index(i);
+ font->set_language_support_override(key, enabled);
}
- Vector<String> lang_dis = p_options["support_overrides/language_disabled"];
- for (int i = 0; i < lang_dis.size(); i++) {
- font->set_language_support_override(lang_dis[i], false);
+ Dictionary scripts = p_options["script_support"];
+ for (int i = 0; i < scripts.size(); i++) {
+ String key = scripts.get_key_at_index(i);
+ bool enabled = scripts.get_value_at_index(i);
+ font->set_script_support_override(key, enabled);
}
- Vector<String> scr_en = p_options["support_overrides/script_enabled"];
- for (int i = 0; i < scr_en.size(); i++) {
- font->set_script_support_override(scr_en[i], true);
- }
+ Array preload_configurations = p_options["preload"];
- Vector<String> scr_dis = p_options["support_overrides/script_disabled"];
- for (int i = 0; i < scr_dis.size(); i++) {
- font->set_script_support_override(scr_dis[i], false);
- }
+ for (int i = 0; i < preload_configurations.size(); i++) {
+ Dictionary preload_config = preload_configurations[i];
- Vector<String> variations = p_options["preload/configurations"];
- Vector<String> char_ranges = p_options["preload/char_ranges"];
- Vector<String> gl_ranges = p_options["preload/glyph_ranges"];
-
- for (int i = 0; i < variations.size(); i++) {
- String name;
- Dictionary var;
- Vector2i size = Vector2(16, 0);
- Vector2i spacing;
-
- Vector<String> variation_tags = variations[i].split(",");
- for (int j = 0; j < variation_tags.size(); j++) {
- if (!_decode_variation(variation_tags[j], var, size, name, spacing)) {
- WARN_PRINT(vformat(TTR("Invalid variation: \"%s\""), variations[i]));
- continue;
- }
- }
- RID conf = font->find_cache(var);
-
- for (int j = 0; j < char_ranges.size(); j++) {
- int32_t start, end;
- Vector<String> tokens = char_ranges[j].split("-");
- if (tokens.size() == 2) {
- if (!_decode_range(tokens[0], start) || !_decode_range(tokens[1], end)) {
- WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), char_ranges[j]));
- continue;
- }
- } else if (tokens.size() == 1) {
- if (!_decode_range(tokens[0], start)) {
- WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), char_ranges[j]));
- continue;
- }
- end = start;
- } else {
- WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), char_ranges[j]));
- continue;
- }
-
- // Preload character ranges for each variations / sizes.
- print_verbose(vformat(TTR("Pre-rendering range U+%s...%s from configuration \"%s\" (%d / %d)..."), String::num_int64(start, 16), String::num_int64(end, 16), name, i + 1, variations.size()));
- TS->font_render_range(conf, size, start, end);
- }
+ Dictionary variation = preload_config.has("variation_opentype") ? preload_config["variation_opentype"].operator Dictionary() : Dictionary();
+ double embolden = preload_config.has("variation_embolden") ? preload_config["variation_embolden"].operator double() : 0;
+ int face_index = preload_config.has("variation_face_index") ? preload_config["variation_face_index"].operator int() : 0;
+ Transform2D transform = preload_config.has("variation_transform") ? preload_config["variation_transform"].operator Transform2D() : Transform2D();
+ Vector2i size = preload_config.has("size") ? preload_config["size"].operator Vector2i() : Vector2i(16, 0);
+ String name = preload_config.has("name") ? preload_config["name"].operator String() : vformat("Configuration %d", i);
- for (int j = 0; j < gl_ranges.size(); j++) {
- int32_t start, end;
- Vector<String> tokens = gl_ranges[j].split("-");
- if (tokens.size() == 2) {
- if (!_decode_range(tokens[0], start) || !_decode_range(tokens[1], end)) {
- WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), gl_ranges[j]));
- continue;
- }
- } else if (tokens.size() == 1) {
- if (!_decode_range(tokens[0], start)) {
- WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), gl_ranges[j]));
- continue;
- }
- end = start;
- } else {
- WARN_PRINT(vformat(TTR("Invalid range: \"%s\""), gl_ranges[j]));
- continue;
- }
-
- // Preload glyph range for each variations / sizes.
- print_verbose(vformat(TTR("Pre-rendering glyph range 0x%s...%s from configuration \"%s\" (%d / %d)..."), String::num_int64(start, 16), String::num_int64(end, 16), name, i + 1, variations.size()));
- for (int32_t k = start; k <= end; k++) {
- TS->font_render_glyph(conf, size, k);
- }
+ RID conf_rid = font->find_variation(variation, face_index, embolden, transform);
+
+ Array chars = preload_config["chars"];
+ for (int j = 0; j < chars.size(); j++) {
+ char32_t c = chars[j].operator int();
+ TS->font_render_range(conf_rid, size, c, c);
}
- TS->font_set_spacing(conf, size.x, TextServer::SPACING_SPACE, spacing.x);
- TS->font_set_spacing(conf, size.x, TextServer::SPACING_GLYPH, spacing.y);
+ Array glyphs = preload_config["glyphs"];
+ for (int j = 0; j < glyphs.size(); j++) {
+ int32_t c = glyphs[j];
+ TS->font_render_glyph(conf_rid, size, c);
+ }
}
- int flg = ResourceSaver::SaverFlags::FLAG_BUNDLE_RESOURCES | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
+ int flg = 0;
if ((bool)p_options["compress"]) {
flg |= ResourceSaver::SaverFlags::FLAG_COMPRESS;
}
diff --git a/editor/import/resource_importer_dynamic_font.h b/editor/import/resource_importer_dynamic_font.h
index c0b6c094b0..a05c8bab05 100644
--- a/editor/import/resource_importer_dynamic_font.h
+++ b/editor/import/resource_importer_dynamic_font.h
@@ -43,9 +43,6 @@ class ResourceImporterDynamicFont : public ResourceImporter {
};
public:
- static bool _decode_range(const String &p_token, int32_t &r_pos);
- static bool _decode_variation(const String &p_token, Dictionary &r_variations, Vector2i &r_size, String &r_name, Vector2i &r_spacing);
-
virtual String get_importer_name() const override;
virtual String get_visible_name() const override;
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp
index 30c349d0f2..ea84d4c883 100644
--- a/editor/import/resource_importer_imagefont.cpp
+++ b/editor/import/resource_importer_imagefont.cpp
@@ -52,7 +52,7 @@ String ResourceImporterImageFont::get_save_extension() const {
}
String ResourceImporterImageFont::get_resource_type() const {
- return "FontData";
+ return "FontFile";
}
bool ResourceImporterImageFont::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
@@ -64,6 +64,9 @@ void ResourceImporterImageFont::get_import_options(const String &p_path, List<Im
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "columns"), 1));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "rows"), 1));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "font_size"), 14));
+
+ r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array()));
+
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
}
@@ -92,8 +95,9 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin
int rows = p_options["rows"];
int base_size = p_options["font_size"];
Vector<String> ranges = p_options["character_ranges"];
+ Array fallbacks = p_options["fallbacks"];
- Ref<FontData> font;
+ Ref<FontFile> font;
font.instantiate();
font->set_antialiased(false);
font->set_generate_mipmaps(false);
@@ -103,6 +107,7 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin
font->set_force_autohinter(false);
font->set_hinting(TextServer::HINTING_NONE);
font->set_oversampling(1.0f);
+ font->set_fallbacks(fallbacks);
Ref<Image> img;
img.instantiate();
@@ -145,10 +150,10 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin
ERR_FAIL_COND_V_MSG(pos >= count, ERR_CANT_CREATE, "Too many characters in range.");
}
}
- font->set_ascent(0, base_size, 0.5 * chr_height);
- font->set_descent(0, base_size, 0.5 * chr_height);
+ font->set_cache_ascent(0, base_size, 0.5 * chr_height);
+ font->set_cache_descent(0, base_size, 0.5 * chr_height);
- int flg = ResourceSaver::SaverFlags::FLAG_BUNDLE_RESOURCES | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
+ int flg = 0;
if ((bool)p_options["compress"]) {
flg |= ResourceSaver::SaverFlags::FLAG_COMPRESS;
}
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index bacd09592e..a5dfd67d18 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -367,7 +367,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
for (int j = 0; j < hslices; j++) {
int x = slice_w * j;
int y = slice_h * i;
- Ref<Image> slice = image->get_rect(Rect2(x, y, slice_w, slice_h));
+ Ref<Image> slice = image->get_rect(Rect2i(x, y, slice_w, slice_h));
ERR_CONTINUE(slice.is_null() || slice->is_empty());
if (slice->get_width() != slice_w || slice->get_height() != slice_h) {
slice->resize(slice_w, slice_h);
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 171ef5bf4c..860269bfcb 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -144,11 +144,11 @@ Variant EditorScenePostImportPlugin::get_option_value(const StringName &p_name)
ERR_FAIL_COND_V_MSG(current_options == nullptr && current_options_dict == nullptr, Variant(), "get_option_value called from a function where option values are not available.");
ERR_FAIL_COND_V_MSG(current_options && !current_options->has(p_name), Variant(), "get_option_value called with unexisting option argument: " + String(p_name));
ERR_FAIL_COND_V_MSG(current_options_dict && !current_options_dict->has(p_name), Variant(), "get_option_value called with unexisting option argument: " + String(p_name));
- if (current_options) {
- (*current_options)[p_name];
+ if (current_options && current_options->has(p_name)) {
+ return (*current_options)[p_name];
}
- if (current_options_dict) {
- (*current_options_dict)[p_name];
+ if (current_options_dict && current_options_dict->has(p_name)) {
+ return (*current_options_dict)[p_name];
}
return Variant();
}
@@ -232,6 +232,7 @@ void EditorScenePostImportPlugin::_bind_methods() {
BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MATERIAL);
BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_ANIMATION);
BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE);
+ BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE);
BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MAX);
}
@@ -766,6 +767,27 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
}
{
+ //make sure this is unique
+ node_settings = node_settings.duplicate(true);
+ //fill node settings for this node with default values
+ List<ImportOption> iopts;
+ if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
+ get_internal_import_options(INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE, &iopts);
+ } else if (Object::cast_to<AnimationPlayer>(p_node)) {
+ get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts);
+ } else if (Object::cast_to<Skeleton3D>(p_node)) {
+ get_internal_import_options(INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE, &iopts);
+ } else {
+ get_internal_import_options(INTERNAL_IMPORT_CATEGORY_NODE, &iopts);
+ }
+ for (const ImportOption &E : iopts) {
+ if (!node_settings.has(E.option.name)) {
+ node_settings[E.option.name] = E.default_value;
+ }
+ }
+ }
+
+ {
ObjectID node_id = p_node->get_instance_id();
for (int i = 0; i < post_importer_plugins.size(); i++) {
post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_NODE, p_root, p_node, Ref<Resource>(), node_settings);
@@ -785,6 +807,16 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
}
}
+ if (Object::cast_to<Skeleton3D>(p_node)) {
+ ObjectID node_id = p_node->get_instance_id();
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE, p_root, p_node, Ref<Resource>(), node_settings);
+ if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue
+ break;
+ }
+ }
+ }
+
if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
@@ -799,6 +831,16 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
if (!mat_id.is_empty() && p_material_data.has(mat_id)) {
Dictionary matdata = p_material_data[mat_id];
+ {
+ //fill node settings for this node with default values
+ List<ImportOption> iopts;
+ get_internal_import_options(INTERNAL_IMPORT_CATEGORY_MATERIAL, &iopts);
+ for (const ImportOption &E : iopts) {
+ if (!matdata.has(E.option.name)) {
+ matdata[E.option.name] = E.default_value;
+ }
+ }
+ }
for (int j = 0; j < post_importer_plugins.size(); j++) {
post_importer_plugins.write[j]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MATERIAL, p_root, p_node, mat, matdata);
@@ -966,19 +1008,6 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
if (Object::cast_to<AnimationPlayer>(p_node)) {
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
- {
- //make sure this is unique
- node_settings = node_settings.duplicate(true);
- //fill node settings for this node with default values
- List<ImportOption> iopts;
- get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts);
- for (const ImportOption &E : iopts) {
- if (!node_settings.has(E.option.name)) {
- node_settings[E.option.name] = E.default_value;
- }
- }
- }
-
for (int i = 0; i < post_importer_plugins.size(); i++) {
post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, p_root, p_node, Ref<Resource>(), node_settings);
}
@@ -1385,6 +1414,10 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"), false));
}
} break;
+ case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::OBJECT, "retarget/bone_map", PROPERTY_HINT_RESOURCE_TYPE, "BoneMap", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Variant()));
+ } break;
default: {
}
}
@@ -1499,6 +1532,12 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor
}
}
} break;
+ case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
+ const bool use_retarget = p_options["retarget/bone_map"].get_validated_object() != nullptr;
+ if (p_option != "retarget/bone_map" && p_option.begins_with("retarget/")) {
+ return use_retarget;
+ }
+ } break;
default: {
}
}
@@ -1534,6 +1573,8 @@ bool ResourceImporterScene::get_internal_option_update_view_required(InternalImp
} break;
case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: {
} break;
+ case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
+ } break;
default: {
}
}
@@ -1622,6 +1663,16 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
if (!mesh_id.is_empty() && p_mesh_data.has(mesh_id)) {
Dictionary mesh_settings = p_mesh_data[mesh_id];
+ {
+ //fill node settings for this node with default values
+ List<ImportOption> iopts;
+ get_internal_import_options(INTERNAL_IMPORT_CATEGORY_MESH, &iopts);
+ for (const ImportOption &E : iopts) {
+ if (!mesh_settings.has(E.option.name)) {
+ mesh_settings[E.option.name] = E.default_value;
+ }
+ }
+ }
if (mesh_settings.has("generate/shadow_meshes")) {
int shadow_meshes = mesh_settings["generate/shadow_meshes"];
@@ -1921,7 +1972,7 @@ void ResourceImporterScene::_optimize_track_usage(AnimationPlayer *p_player, Ani
}
}
-Node *ResourceImporterScene::pre_import(const String &p_source_file) {
+Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashMap<StringName, Variant> &p_options) {
Ref<EditorSceneFormatImporter> importer;
String ext = p_source_file.get_extension().to_lower();
@@ -1946,8 +1997,13 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file) {
ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
+ int bake_fps = 30;
+ if (p_options.has(SNAME("animation/fps"))) {
+ bake_fps = p_options[SNAME("animation/fps")];
+ }
+
Error err = OK;
- Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, HashMap<StringName, Variant>(), 15, nullptr, &err);
+ Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, p_options, bake_fps, nullptr, &err);
if (!scene || err != OK) {
return nullptr;
}
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 16cf3d651d..b77c1dccb4 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -106,6 +106,7 @@ public:
INTERNAL_IMPORT_CATEGORY_MATERIAL,
INTERNAL_IMPORT_CATEGORY_ANIMATION,
INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE,
+ INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE,
INTERNAL_IMPORT_CATEGORY_MAX
};
@@ -259,6 +260,7 @@ public:
INTERNAL_IMPORT_CATEGORY_MATERIAL = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MATERIAL,
INTERNAL_IMPORT_CATEGORY_ANIMATION = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION,
INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE,
+ INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE,
INTERNAL_IMPORT_CATEGORY_MAX = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MAX
};
@@ -279,7 +281,7 @@ public:
void _optimize_animations(AnimationPlayer *anim, float p_max_lin_error, float p_max_ang_error, float p_max_angle);
void _compress_animations(AnimationPlayer *anim, int p_page_size_kb);
- Node *pre_import(const String &p_source_file);
+ Node *pre_import(const String &p_source_file, const HashMap<StringName, Variant> &p_options);
virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
virtual bool has_advanced_options() const override;
diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp
index e5fe99890e..93afb3381e 100644
--- a/editor/import/resource_importer_texture_atlas.cpp
+++ b/editor/import/resource_importer_texture_atlas.cpp
@@ -88,13 +88,7 @@ Error ResourceImporterTextureAtlas::import(const String &p_source_file, const St
//use an xpm because it's size independent, the editor images are vector and size dependent
//it's a simple hack
Ref<Image> broken = memnew(Image((const char **)atlas_import_failed_xpm));
- Ref<ImageTexture> broken_texture;
- broken_texture.instantiate();
- broken_texture->create_from_image(broken);
-
- String target_file = p_save_path + ".tex";
-
- ResourceSaver::save(target_file, broken_texture);
+ ResourceSaver::save(p_save_path + ".tex", ImageTexture::create_from_image(broken));
return OK;
}
@@ -218,7 +212,7 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
EditorAtlasPacker::Chart chart;
- Rect2 used_rect = Rect2(Vector2(), image->get_size());
+ Rect2i used_rect = Rect2i(Vector2i(), image->get_size());
if (trim_alpha_border_from_region) {
// Clip a region from the image.
used_rect = image->get_used_rect();
@@ -226,9 +220,9 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
pack_data.region = used_rect;
chart.vertices.push_back(used_rect.position);
- chart.vertices.push_back(used_rect.position + Vector2(used_rect.size.x, 0));
- chart.vertices.push_back(used_rect.position + Vector2(used_rect.size.x, used_rect.size.y));
- chart.vertices.push_back(used_rect.position + Vector2(0, used_rect.size.y));
+ chart.vertices.push_back(used_rect.position + Vector2i(used_rect.size.x, 0));
+ chart.vertices.push_back(used_rect.position + Vector2i(used_rect.size.x, used_rect.size.y));
+ chart.vertices.push_back(used_rect.position + Vector2i(0, used_rect.size.y));
EditorAtlasPacker::Chart::Face f;
f.vertex[0] = 0;
f.vertex[1] = 1;
@@ -308,9 +302,7 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
Ref<Texture2D> cache;
cache = ResourceCache::get_ref(p_group_file);
if (!cache.is_valid()) {
- Ref<ImageTexture> res_cache;
- res_cache.instantiate();
- res_cache->create_from_image(new_atlas);
+ Ref<ImageTexture> res_cache = ImageTexture::create_from_image(new_atlas);
res_cache->set_path(p_group_file);
cache = res_cache;
}
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index 362940dc17..f0ba1eb7a1 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -162,7 +162,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
//Consider revision for engine version 3.0
compression_code = file->get_16();
if (compression_code != 1 && compression_code != 3) {
- ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Format not supported for WAVE file (not PCM). Save WAVE files as uncompressed PCM instead.");
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Format not supported for WAVE file (not PCM). Save WAVE files as uncompressed PCM or IEEE float instead.");
}
format_channels = file->get_16();
@@ -180,6 +180,10 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Invalid amount of bits in the sample (should be one of 8, 16, 24 or 32).");
}
+ if (compression_code == 3 && format_bits % 32) {
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Invalid amount of bits in the IEEE float sample (should be 32 or 64).");
+ }
+
/* Don't need anything else, continue */
format_found = true;
}
@@ -208,36 +212,46 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
data.resize(frames * format_channels);
- if (format_bits == 8) {
- for (int i = 0; i < frames * format_channels; i++) {
- // 8 bit samples are UNSIGNED
+ if (compression_code == 1) {
+ if (format_bits == 8) {
+ for (int i = 0; i < frames * format_channels; i++) {
+ // 8 bit samples are UNSIGNED
- data.write[i] = int8_t(file->get_8() - 128) / 128.f;
- }
- } else if (format_bits == 32 && compression_code == 3) {
- for (int i = 0; i < frames * format_channels; i++) {
- //32 bit IEEE Float
+ data.write[i] = int8_t(file->get_8() - 128) / 128.f;
+ }
+ } else if (format_bits == 16) {
+ for (int i = 0; i < frames * format_channels; i++) {
+ //16 bit SIGNED
- data.write[i] = file->get_float();
- }
- } else if (format_bits == 16) {
- for (int i = 0; i < frames * format_channels; i++) {
- //16 bit SIGNED
+ data.write[i] = int16_t(file->get_16()) / 32768.f;
+ }
+ } else {
+ for (int i = 0; i < frames * format_channels; i++) {
+ //16+ bits samples are SIGNED
+ // if sample is > 16 bits, just read extra bytes
+
+ uint32_t s = 0;
+ for (int b = 0; b < (format_bits >> 3); b++) {
+ s |= ((uint32_t)file->get_8()) << (b * 8);
+ }
+ s <<= (32 - format_bits);
- data.write[i] = int16_t(file->get_16()) / 32768.f;
+ data.write[i] = (int32_t(s) >> 16) / 32768.f;
+ }
}
- } else {
- for (int i = 0; i < frames * format_channels; i++) {
- //16+ bits samples are SIGNED
- // if sample is > 16 bits, just read extra bytes
-
- uint32_t s = 0;
- for (int b = 0; b < (format_bits >> 3); b++) {
- s |= ((uint32_t)file->get_8()) << (b * 8);
+ } else if (compression_code == 3) {
+ if (format_bits == 32) {
+ for (int i = 0; i < frames * format_channels; i++) {
+ //32 bit IEEE Float
+
+ data.write[i] = file->get_float();
}
- s <<= (32 - format_bits);
+ } else if (format_bits == 64) {
+ for (int i = 0; i < frames * format_channels; i++) {
+ //64 bit IEEE Float
- data.write[i] = (int32_t(s) >> 16) / 32768.f;
+ data.write[i] = file->get_double();
+ }
}
}
diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp
index 99d1658405..0e2967dc42 100644
--- a/editor/import/scene_import_settings.cpp
+++ b/editor/import/scene_import_settings.cpp
@@ -135,6 +135,12 @@ void SceneImportSettings::_fill_material(Tree *p_tree, const Ref<Material> &p_ma
String import_id;
bool has_import_id = false;
+ bool created = false;
+ if (!material_set.has(p_material)) {
+ material_set.insert(p_material);
+ created = true;
+ }
+
if (p_material->has_meta("import_id")) {
import_id = p_material->get_meta("import_id");
has_import_id = true;
@@ -142,7 +148,7 @@ void SceneImportSettings::_fill_material(Tree *p_tree, const Ref<Material> &p_ma
import_id = p_material->get_name();
has_import_id = true;
} else {
- import_id = "@MATERIAL:" + itos(material_set.size());
+ import_id = "@MATERIAL:" + itos(material_set.size() - 1);
}
if (!material_map.has(import_id)) {
@@ -160,14 +166,12 @@ void SceneImportSettings::_fill_material(Tree *p_tree, const Ref<Material> &p_ma
Ref<Texture2D> icon = get_theme_icon(SNAME("StandardMaterial3D"), SNAME("EditorIcons"));
TreeItem *item = p_tree->create_item(p_parent);
- item->set_text(0, p_material->get_name());
- item->set_icon(0, icon);
-
- bool created = false;
- if (!material_set.has(p_material)) {
- material_set.insert(p_material);
- created = true;
+ if (p_material->get_name().is_empty()) {
+ item->set_text(0, TTR("<Unnamed Material>"));
+ } else {
+ item->set_text(0, p_material->get_name());
}
+ item->set_icon(0, icon);
item->set_meta("type", "Material");
item->set_meta("import_id", import_id);
@@ -339,6 +343,8 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) {
category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE;
} else if (Object::cast_to<AnimationPlayer>(p_node)) {
category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE;
+ } else if (Object::cast_to<Skeleton3D>(p_node)) {
+ category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE;
} else {
category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_NODE;
}
@@ -536,12 +542,6 @@ void SceneImportSettings::open_settings(const String &p_path, bool p_for_animati
scene_import_settings_data->settings = nullptr;
scene_import_settings_data->path = p_path;
- scene = ResourceImporterScene::get_scene_singleton()->pre_import(p_path); // Use the scene singleton here because we want to see the full thing.
- if (scene == nullptr) {
- EditorNode::get_singleton()->show_warning(TTR("Error opening scene"));
- return;
- }
-
// Visibility
data_mode->set_tab_hidden(1, p_for_animation);
data_mode->set_tab_hidden(2, p_for_animation);
@@ -587,6 +587,12 @@ void SceneImportSettings::open_settings(const String &p_path, bool p_for_animati
}
}
+ scene = ResourceImporterScene::get_scene_singleton()->pre_import(p_path, defaults); // Use the scene singleton here because we want to see the full thing.
+ if (scene == nullptr) {
+ EditorNode::get_singleton()->show_warning(TTR("Error opening scene"));
+ return;
+ }
+
first_aabb = true;
_update_scene();
@@ -604,6 +610,9 @@ void SceneImportSettings::open_settings(const String &p_path, bool p_for_animati
_update_view_gizmos();
_update_camera();
+ // Start with the root item (Scene) selected.
+ scene_tree->get_root()->select(0);
+
if (p_for_animation) {
set_title(vformat(TTR("Advanced Import Settings for AnimationLibrary '%s'"), base_path.get_file()));
} else {
@@ -617,6 +626,13 @@ SceneImportSettings *SceneImportSettings::get_singleton() {
return singleton;
}
+Node *SceneImportSettings::get_selected_node() {
+ if (selected_id == "") {
+ return nullptr;
+ }
+ return node_map[selected_id].node;
+}
+
void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) {
selecting = true;
scene_import_settings_data->hide_options = false;
@@ -657,6 +673,8 @@ void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) {
scene_import_settings_data->hide_options = editing_animation;
} else if (Object::cast_to<AnimationPlayer>(nd.node)) {
scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE;
+ } else if (Object::cast_to<Skeleton3D>(nd.node)) {
+ scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE;
} else {
scene_import_settings_data->category = ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_NODE;
scene_import_settings_data->hide_options = editing_animation;
@@ -1041,7 +1059,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
}
external_paths->set_title(TTR("Extract Materials to Resource Files"));
- external_paths->get_ok_button()->set_text(TTR("Extract"));
+ external_paths->set_ok_button_text(TTR("Extract"));
} break;
case ACTION_CHOOSE_MESH_SAVE_PATHS: {
for (const KeyValue<String, MeshData> &E : mesh_map) {
@@ -1094,7 +1112,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
}
external_paths->set_title(TTR("Set paths to save meshes as resource files on Reimport"));
- external_paths->get_ok_button()->set_text(TTR("Set Paths"));
+ external_paths->set_ok_button_text(TTR("Set Paths"));
} break;
case ACTION_CHOOSE_ANIMATION_SAVE_PATHS: {
for (const KeyValue<String, AnimationData> &E : animation_map) {
@@ -1140,7 +1158,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
}
external_paths->set_title(TTR("Set paths to save animations as resource files on Reimport"));
- external_paths->get_ok_button()->set_text(TTR("Set Paths"));
+ external_paths->set_ok_button_text(TTR("Set Paths"));
} break;
}
@@ -1329,8 +1347,8 @@ SceneImportSettings::SceneImportSettings() {
scene_import_settings_data = memnew(SceneImportSettingsData);
- get_ok_button()->set_text(TTR("Reimport"));
- get_cancel_button()->set_text(TTR("Close"));
+ set_ok_button_text(TTR("Reimport"));
+ set_cancel_button_text(TTR("Close"));
external_paths = memnew(ConfirmationDialog);
add_child(external_paths);
@@ -1364,8 +1382,8 @@ SceneImportSettings::SceneImportSettings() {
item_save_path = memnew(EditorFileDialog);
item_save_path->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
- item_save_path->add_filter("*.tres; " + TTR("Text Resource"));
- item_save_path->add_filter("*.res; " + TTR("Binary Resource"));
+ item_save_path->add_filter("*.tres", TTR("Text Resource"));
+ item_save_path->add_filter("*.res", TTR("Binary Resource"));
add_child(item_save_path);
item_save_path->connect("file_selected", callable_mp(this, &SceneImportSettings::_save_path_changed));
diff --git a/editor/import/scene_import_settings.h b/editor/import/scene_import_settings.h
index 81d13166ab..b5cf82f64b 100644
--- a/editor/import/scene_import_settings.h
+++ b/editor/import/scene_import_settings.h
@@ -201,6 +201,7 @@ public:
void update_view();
void open_settings(const String &p_path, bool p_for_animation = false);
static SceneImportSettings *get_singleton();
+ Node *get_selected_node();
SceneImportSettings();
~SceneImportSettings();
};
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 6bb71ff491..f9e5885f9d 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -671,7 +671,7 @@ ImportDock::ImportDock() {
advanced->connect("pressed", callable_mp(this, &ImportDock::_advanced_options));
reimport_confirm = memnew(ConfirmationDialog);
- reimport_confirm->get_ok_button()->set_text(TTR("Save Scenes, Re-Import, and Restart"));
+ reimport_confirm->set_ok_button_text(TTR("Save Scenes, Re-Import, and Restart"));
content->add_child(reimport_confirm);
reimport_confirm->connect("confirmed", callable_mp(this, &ImportDock::_reimport_and_restart));
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index ad92911810..a509cf3d8f 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -219,12 +219,12 @@ void InspectorDock::_load_resource(const String &p_type) {
load_resource_dialog->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
- load_resource_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
+ load_resource_dialog->add_filter("*." + extensions[i], extensions[i].to_upper());
}
const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false);
for (int i = 0; i < textfile_ext.size(); i++) {
- load_resource_dialog->add_filter("*." + textfile_ext[i] + " ; " + textfile_ext[i].to_upper());
+ load_resource_dialog->add_filter("*." + textfile_ext[i], textfile_ext[i].to_upper());
}
load_resource_dialog->popup_file_dialog();
diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp
index 77e4905341..7061204832 100644
--- a/editor/plugin_config_dialog.cpp
+++ b/editor/plugin_config_dialog.cpp
@@ -200,7 +200,7 @@ void PluginConfigDialog::config(const String &p_config_path) {
_on_required_text_changed("");
get_ok_button()->set_disabled(!_edit_mode);
- get_ok_button()->set_text(_edit_mode ? TTR("Update") : TTR("Create"));
+ set_ok_button_text(_edit_mode ? TTR("Update") : TTR("Create"));
}
void PluginConfigDialog::_bind_methods() {
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index ad6d8e6379..a5ca55f6df 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -565,7 +565,7 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
String num = String::num(vertex.vertex);
- Size2 num_size = font->get_string_size(num, font_size);
+ Size2 num_size = font->get_string_size(num, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
p_overlay->draw_string(font, point - num_size * 0.5, num, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5));
}
}
@@ -733,7 +733,7 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) {
create_resource = memnew(ConfirmationDialog);
add_child(create_resource);
- create_resource->get_ok_button()->set_text(TTR("Create"));
+ create_resource->set_ok_button_text(TTR("Create"));
}
void AbstractPolygon2DEditorPlugin::edit(Object *p_object) {
diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp
index 2e4dcab203..d397c6da67 100644
--- a/editor/plugins/animation_blend_space_1d_editor.cpp
+++ b/editor/plugins/animation_blend_space_1d_editor.cpp
@@ -215,7 +215,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
blend_space_draw->draw_rect(Rect2(Point2(), s), color, false);
}
- blend_space_draw->draw_line(Point2(1, s.height - 1), Point2(s.width - 1, s.height - 1), linecolor);
+ blend_space_draw->draw_line(Point2(1, s.height - 1), Point2(s.width - 1, s.height - 1), linecolor, Math::round(EDSCALE));
if (blend_space->get_min_space() < 0) {
float point = 0.0;
@@ -224,9 +224,9 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
float x = point;
- blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor);
+ blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor, Math::round(EDSCALE));
blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height(font_size) + font->get_ascent(font_size)), "0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, linecolor);
- blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft);
+ blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft, Math::round(EDSCALE));
}
if (snap->is_pressed()) {
@@ -240,7 +240,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
int idx = int(v / blend_space->get_snap());
if (i > 0 && prev_idx != idx) {
- blend_space_draw->draw_line(Point2(i, 0), Point2(i, s.height), linecolor_soft);
+ blend_space_draw->draw_line(Point2(i, 0), Point2(i, s.height), linecolor_soft, Math::round(EDSCALE));
}
prev_idx = idx;
@@ -297,10 +297,10 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
float mind = 5 * EDSCALE;
float maxd = 15 * EDSCALE;
- blend_space_draw->draw_line(gui_point + Vector2(mind, 0), gui_point + Vector2(maxd, 0), color, 2);
- blend_space_draw->draw_line(gui_point + Vector2(-mind, 0), gui_point + Vector2(-maxd, 0), color, 2);
- blend_space_draw->draw_line(gui_point + Vector2(0, mind), gui_point + Vector2(0, maxd), color, 2);
- blend_space_draw->draw_line(gui_point + Vector2(0, -mind), gui_point + Vector2(0, -maxd), color, 2);
+ blend_space_draw->draw_line(gui_point + Vector2(mind, 0), gui_point + Vector2(maxd, 0), color, Math::round(2 * EDSCALE));
+ blend_space_draw->draw_line(gui_point + Vector2(-mind, 0), gui_point + Vector2(-maxd, 0), color, Math::round(2 * EDSCALE));
+ blend_space_draw->draw_line(gui_point + Vector2(0, mind), gui_point + Vector2(0, maxd), color, Math::round(2 * EDSCALE));
+ blend_space_draw->draw_line(gui_point + Vector2(0, -mind), gui_point + Vector2(0, -maxd), color, Math::round(2 * EDSCALE));
}
}
@@ -314,6 +314,8 @@ void AnimationNodeBlendSpace1DEditor::_update_space() {
max_value->set_value(blend_space->get_max_space());
min_value->set_value(blend_space->get_min_space());
+ sync->set_pressed(blend_space->is_using_sync());
+
label_value->set_text(blend_space->get_value_label());
snap_value->set_value(blend_space->get_snap());
@@ -329,13 +331,15 @@ void AnimationNodeBlendSpace1DEditor::_config_changed(double) {
}
updating = true;
- undo_redo->create_action(TTR("Change BlendSpace1D Limits"));
+ undo_redo->create_action(TTR("Change BlendSpace1D Config"));
undo_redo->add_do_method(blend_space.ptr(), "set_max_space", max_value->get_value());
undo_redo->add_undo_method(blend_space.ptr(), "set_max_space", blend_space->get_max_space());
undo_redo->add_do_method(blend_space.ptr(), "set_min_space", min_value->get_value());
undo_redo->add_undo_method(blend_space.ptr(), "set_min_space", blend_space->get_min_space());
undo_redo->add_do_method(blend_space.ptr(), "set_snap", snap_value->get_value());
undo_redo->add_undo_method(blend_space.ptr(), "set_snap", blend_space->get_snap());
+ undo_redo->add_do_method(blend_space.ptr(), "set_use_sync", sync->is_pressed());
+ undo_redo->add_undo_method(blend_space.ptr(), "set_use_sync", blend_space->is_using_sync());
undo_redo->add_do_method(this, "_update_space");
undo_redo->add_undo_method(this, "_update_space");
undo_redo->commit_action();
@@ -650,6 +654,12 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
snap_value->set_step(0.01);
snap_value->set_max(1000);
+ top_hb->add_child(memnew(VSeparator));
+ top_hb->add_child(memnew(Label(TTR("Sync:"))));
+ sync = memnew(CheckBox);
+ top_hb->add_child(sync);
+ sync->connect("toggled", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_config_changed));
+
edit_hb = memnew(HBoxContainer);
top_hb->add_child(edit_hb);
edit_hb->add_child(memnew(VSeparator));
diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h
index 2f7dee65fc..3488b4bf30 100644
--- a/editor/plugins/animation_blend_space_1d_editor.h
+++ b/editor/plugins/animation_blend_space_1d_editor.h
@@ -61,6 +61,8 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin {
SpinBox *max_value = nullptr;
SpinBox *min_value = nullptr;
+ CheckBox *sync = nullptr;
+
HBoxContainer *edit_hb = nullptr;
SpinBox *edit_value = nullptr;
Button *open_editor = nullptr;
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 86addde87b..51aaa4f010 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -407,22 +407,22 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
blend_space_draw->draw_rect(Rect2(Point2(), s), color, false);
}
- blend_space_draw->draw_line(Point2(1, 0), Point2(1, s.height - 1), linecolor);
- blend_space_draw->draw_line(Point2(1, s.height - 1), Point2(s.width - 1, s.height - 1), linecolor);
+ blend_space_draw->draw_line(Point2(1, 0), Point2(1, s.height - 1), linecolor, Math::round(EDSCALE));
+ blend_space_draw->draw_line(Point2(1, s.height - 1), Point2(s.width - 1, s.height - 1), linecolor, Math::round(EDSCALE));
- blend_space_draw->draw_line(Point2(0, 0), Point2(5 * EDSCALE, 0), linecolor);
+ blend_space_draw->draw_line(Point2(0, 0), Point2(5 * EDSCALE, 0), linecolor, Math::round(EDSCALE));
if (blend_space->get_min_space().y < 0) {
int y = (blend_space->get_max_space().y / (blend_space->get_max_space().y - blend_space->get_min_space().y)) * s.height;
- blend_space_draw->draw_line(Point2(0, y), Point2(5 * EDSCALE, y), linecolor);
+ blend_space_draw->draw_line(Point2(0, y), Point2(5 * EDSCALE, y), linecolor, Math::round(EDSCALE));
blend_space_draw->draw_string(font, Point2(2 * EDSCALE, y - font->get_height(font_size) + font->get_ascent(font_size)), "0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, linecolor);
- blend_space_draw->draw_line(Point2(5 * EDSCALE, y), Point2(s.width, y), linecolor_soft);
+ blend_space_draw->draw_line(Point2(5 * EDSCALE, y), Point2(s.width, y), linecolor_soft, Math::round(EDSCALE));
}
if (blend_space->get_min_space().x < 0) {
int x = (-blend_space->get_min_space().x / (blend_space->get_max_space().x - blend_space->get_min_space().x)) * s.width;
- blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor);
+ blend_space_draw->draw_line(Point2(x, s.height - 1), Point2(x, s.height - 5 * EDSCALE), linecolor, Math::round(EDSCALE));
blend_space_draw->draw_string(font, Point2(x + 2 * EDSCALE, s.height - 2 * EDSCALE - font->get_height(font_size) + font->get_ascent(font_size)), "0", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, linecolor);
- blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft);
+ blend_space_draw->draw_line(Point2(x, s.height - 5 * EDSCALE), Point2(x, 0), linecolor_soft, Math::round(EDSCALE));
}
if (snap->is_pressed()) {
@@ -435,7 +435,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
int idx = int(v / blend_space->get_snap().x);
if (i > 0 && prev_idx != idx) {
- blend_space_draw->draw_line(Point2(i, 0), Point2(i, s.height), linecolor_soft);
+ blend_space_draw->draw_line(Point2(i, 0), Point2(i, s.height), linecolor_soft, Math::round(EDSCALE));
}
prev_idx = idx;
@@ -449,7 +449,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
int idx = int(v / blend_space->get_snap().y);
if (i > 0 && prev_idx != idx) {
- blend_space_draw->draw_line(Point2(0, i), Point2(s.width, i), linecolor_soft);
+ blend_space_draw->draw_line(Point2(0, i), Point2(s.width, i), linecolor_soft, Math::round(EDSCALE));
}
prev_idx = idx;
@@ -478,7 +478,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
}
for (int j = 0; j < 3; j++) {
- blend_space_draw->draw_line(points[j], points[(j + 1) % 3], linecolor, 1);
+ blend_space_draw->draw_line(points[j], points[(j + 1) % 3], linecolor, Math::round(EDSCALE), true);
}
Color color;
@@ -533,9 +533,9 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
}
for (int i = 0; i < points.size() - 1; i++) {
- blend_space_draw->draw_line(points[i], points[i + 1], linecolor, 2);
+ blend_space_draw->draw_line(points[i], points[i + 1], linecolor, Math::round(2 * EDSCALE), true);
}
- blend_space_draw->draw_line(points[points.size() - 1], blend_space_draw->get_local_mouse_position(), linecolor, 2);
+ blend_space_draw->draw_line(points[points.size() - 1], blend_space_draw->get_local_mouse_position(), linecolor, Math::round(2 * EDSCALE), true);
}
///draw cursor position
@@ -564,15 +564,15 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
Color lcol = color;
lcol.a *= 0.4;
- blend_space_draw->draw_line(point, closest, lcol, 2);
+ blend_space_draw->draw_line(point, closest, lcol, Math::round(2 * EDSCALE), true);
}
float mind = 5 * EDSCALE;
float maxd = 15 * EDSCALE;
- blend_space_draw->draw_line(point + Vector2(mind, 0), point + Vector2(maxd, 0), color, 2);
- blend_space_draw->draw_line(point + Vector2(-mind, 0), point + Vector2(-maxd, 0), color, 2);
- blend_space_draw->draw_line(point + Vector2(0, mind), point + Vector2(0, maxd), color, 2);
- blend_space_draw->draw_line(point + Vector2(0, -mind), point + Vector2(0, -maxd), color, 2);
+ blend_space_draw->draw_line(point + Vector2(mind, 0), point + Vector2(maxd, 0), color, Math::round(2 * EDSCALE));
+ blend_space_draw->draw_line(point + Vector2(-mind, 0), point + Vector2(-maxd, 0), color, Math::round(2 * EDSCALE));
+ blend_space_draw->draw_line(point + Vector2(0, mind), point + Vector2(0, maxd), color, Math::round(2 * EDSCALE));
+ blend_space_draw->draw_line(point + Vector2(0, -mind), point + Vector2(0, -maxd), color, Math::round(2 * EDSCALE));
}
}
@@ -595,6 +595,7 @@ void AnimationNodeBlendSpace2DEditor::_update_space() {
auto_triangles->set_pressed(blend_space->get_auto_triangles());
+ sync->set_pressed(blend_space->is_using_sync());
interpolation->select(blend_space->get_blend_mode());
max_x_value->set_value(blend_space->get_max_space().x);
@@ -620,13 +621,15 @@ void AnimationNodeBlendSpace2DEditor::_config_changed(double) {
}
updating = true;
- undo_redo->create_action(TTR("Change BlendSpace2D Limits"));
+ undo_redo->create_action(TTR("Change BlendSpace2D Config"));
undo_redo->add_do_method(blend_space.ptr(), "set_max_space", Vector2(max_x_value->get_value(), max_y_value->get_value()));
undo_redo->add_undo_method(blend_space.ptr(), "set_max_space", blend_space->get_max_space());
undo_redo->add_do_method(blend_space.ptr(), "set_min_space", Vector2(min_x_value->get_value(), min_y_value->get_value()));
undo_redo->add_undo_method(blend_space.ptr(), "set_min_space", blend_space->get_min_space());
undo_redo->add_do_method(blend_space.ptr(), "set_snap", Vector2(snap_x->get_value(), snap_y->get_value()));
undo_redo->add_undo_method(blend_space.ptr(), "set_snap", blend_space->get_snap());
+ undo_redo->add_do_method(blend_space.ptr(), "set_use_sync", sync->is_pressed());
+ undo_redo->add_undo_method(blend_space.ptr(), "set_use_sync", blend_space->is_using_sync());
undo_redo->add_do_method(blend_space.ptr(), "set_blend_mode", interpolation->get_selected());
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_mode", blend_space->get_blend_mode());
undo_redo->add_do_method(this, "_update_space");
@@ -899,6 +902,13 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
top_hb->add_child(memnew(VSeparator));
+ top_hb->add_child(memnew(Label(TTR("Sync:"))));
+ sync = memnew(CheckBox);
+ top_hb->add_child(sync);
+ sync->connect("toggled", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_config_changed));
+
+ top_hb->add_child(memnew(VSeparator));
+
top_hb->add_child(memnew(Label(TTR("Blend:"))));
interpolation = memnew(OptionButton);
top_hb->add_child(interpolation);
diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h
index db54e84254..88b9072599 100644
--- a/editor/plugins/animation_blend_space_2d_editor.h
+++ b/editor/plugins/animation_blend_space_2d_editor.h
@@ -55,6 +55,7 @@ class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
Button *snap = nullptr;
SpinBox *snap_x = nullptr;
SpinBox *snap_y = nullptr;
+ CheckBox *sync = nullptr;
OptionButton *interpolation = nullptr;
Button *auto_triangles = nullptr;
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index e5ca5d66e8..f493c4515c 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -132,10 +132,10 @@ void AnimationPlayerEditor::_notification(int p_what) {
Size2 icon_size = autoplay_img->get_size();
autoplay_reset_img.instantiate();
autoplay_reset_img->create(icon_size.x * 2, icon_size.y, false, autoplay_img->get_format());
- autoplay_reset_img->blit_rect(autoplay_img, Rect2(Point2(), icon_size), Point2());
- autoplay_reset_img->blit_rect(reset_img, Rect2(Point2(), icon_size), Point2(icon_size.x, 0));
+ autoplay_reset_img->blit_rect(autoplay_img, Rect2i(Point2i(), icon_size), Point2i());
+ autoplay_reset_img->blit_rect(reset_img, Rect2i(Point2i(), icon_size), Point2i(icon_size.x, 0));
autoplay_reset_icon.instantiate();
- autoplay_reset_icon->create_from_image(autoplay_reset_img);
+ autoplay_reset_icon->set_image(autoplay_reset_img);
}
stop->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
@@ -1688,7 +1688,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug
name_dialog->register_text_enter(name);
error_dialog = memnew(ConfirmationDialog);
- error_dialog->get_ok_button()->set_text(TTR("Close"));
+ error_dialog->set_ok_button_text(TTR("Close"));
error_dialog->set_title(TTR("Error!"));
add_child(error_dialog);
@@ -1696,7 +1696,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug
blend_editor.dialog = memnew(AcceptDialog);
add_child(blend_editor.dialog);
- blend_editor.dialog->get_ok_button()->set_text(TTR("Close"));
+ blend_editor.dialog->set_ok_button_text(TTR("Close"));
blend_editor.dialog->set_hide_on_ok(true);
VBoxContainer *blend_vb = memnew(VBoxContainer);
blend_editor.dialog->add_child(blend_vb);
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index 00cc5a6ca0..1258b9a03c 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -1224,7 +1224,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
Ref<StyleBox> sb = selected_nodes.has(E) ? style_selected : style;
Size2 s = sb->get_minimum_size();
- int strsize = font->get_string_size(name, font_size).width;
+ int strsize = font->get_string_size(name, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
s.width += strsize;
s.height += MAX(font->get_height(font_size), play->get_height());
s.width += sep + play->get_width();
@@ -1379,7 +1379,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
Ref<AnimationNode> anode = state_machine->get_node(name);
bool needs_editor = AnimationTreeEditor::get_singleton()->can_edit(anode);
Ref<StyleBox> sb = selected_nodes.has(name) ? style_selected : style;
- int strsize = font->get_string_size(name, font_size).width;
+ int strsize = font->get_string_size(name, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
NodeRect &nr = node_rects.write[i];
Vector2 offset = nr.node.position;
@@ -1969,7 +1969,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
state_machine_play_pos = memnew(Control);
state_machine_draw->add_child(state_machine_play_pos);
state_machine_play_pos->set_mouse_filter(MOUSE_FILTER_PASS); //pass all to parent
- state_machine_play_pos->set_anchors_and_offsets_preset(PRESET_WIDE);
+ state_machine_play_pos->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
state_machine_play_pos->connect("draw", callable_mp(this, &AnimationNodeStateMachineEditor::_state_machine_pos_draw));
v_scroll = memnew(VScrollBar);
@@ -2022,7 +2022,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
add_child(name_edit_popup);
name_edit = memnew(LineEdit);
name_edit_popup->add_child(name_edit);
- name_edit->set_anchors_and_offsets_preset(PRESET_WIDE);
+ name_edit->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
name_edit->connect("text_submitted", callable_mp(this, &AnimationNodeStateMachineEditor::_name_edited));
name_edit->connect("focus_exited", callable_mp(this, &AnimationNodeStateMachineEditor::_name_edited_focus_out));
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 249b3a6d6a..bb393c652d 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "core/input/input.h"
#include "core/io/json.h"
+#include "core/io/stream_peer_ssl.h"
#include "core/os/keyboard.h"
#include "core/version.h"
#include "editor/editor_file_dialog.h"
@@ -160,18 +161,13 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
Ref<Image> overlay = previews->get_theme_icon(SNAME("PlayOverlay"), SNAME("EditorIcons"))->get_image();
Ref<Image> thumbnail = p_image->get_image();
thumbnail = thumbnail->duplicate();
- Point2 overlay_pos = Point2((thumbnail->get_width() - overlay->get_width()) / 2, (thumbnail->get_height() - overlay->get_height()) / 2);
+ Point2i overlay_pos = Point2i((thumbnail->get_width() - overlay->get_width()) / 2, (thumbnail->get_height() - overlay->get_height()) / 2);
// Overlay and thumbnail need the same format for `blend_rect` to work.
thumbnail->convert(Image::FORMAT_RGBA8);
-
thumbnail->blend_rect(overlay, overlay->get_used_rect(), overlay_pos);
+ preview_images[i].button->set_icon(ImageTexture::create_from_image(thumbnail));
- Ref<ImageTexture> tex;
- tex.instantiate();
- tex->create_from_image(thumbnail);
-
- preview_images[i].button->set_icon(tex);
// Make it clearer that clicking it will open an external link
preview_images[i].button->set_default_cursor_shape(Control::CURSOR_POINTING_HAND);
} else {
@@ -290,12 +286,15 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
hbox->add_child(previews_vbox);
previews_vbox->add_theme_constant_override("separation", 15 * EDSCALE);
previews_vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ previews_vbox->set_h_size_flags(Control::SIZE_EXPAND_FILL);
preview = memnew(TextureRect);
previews_vbox->add_child(preview);
preview->set_ignore_texture_size(true);
preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
preview->set_custom_minimum_size(Size2(640 * EDSCALE, 345 * EDSCALE));
+ preview->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ preview->set_h_size_flags(Control::SIZE_EXPAND_FILL);
previews_bg = memnew(PanelContainer);
previews_vbox->add_child(previews_bg);
@@ -308,8 +307,8 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
preview_hb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
previews->add_child(preview_hb);
- get_ok_button()->set_text(TTR("Download"));
- get_cancel_button()->set_text(TTR("Close"));
+ set_ok_button_text(TTR("Download"));
+ set_cancel_button_text(TTR("Close"));
}
///////////////////////////////////////////////////////////////////////////////////
@@ -620,6 +619,10 @@ void EditorAssetLibrary::_notification(int p_what) {
} break;
+ case NOTIFICATION_RESIZED: {
+ _update_asset_items_columns();
+ } break;
+
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
_update_repository_options();
setup_http_request(request);
@@ -782,9 +785,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PackedB
} break;
}
- Ref<ImageTexture> tex;
- tex.instantiate();
- tex->create_from_image(image);
+ Ref<ImageTexture> tex = ImageTexture::create_from_image(image);
obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, tex);
image_set = true;
@@ -1209,7 +1210,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
library_vb->add_child(asset_top_page);
asset_items = memnew(GridContainer);
- asset_items->set_columns(2);
+ _update_asset_items_columns();
asset_items->add_theme_constant_override("h_separation", 10 * EDSCALE);
asset_items->add_theme_constant_override("v_separation", 10 * EDSCALE);
@@ -1292,14 +1293,14 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
EditorAssetLibraryItemDownload *download_item = _get_asset_in_progress(description->get_asset_id());
if (download_item) {
if (download_item->can_install()) {
- description->get_ok_button()->set_text(TTR("Install"));
+ description->set_ok_button_text(TTR("Install"));
description->get_ok_button()->set_disabled(false);
} else {
- description->get_ok_button()->set_text(TTR("Downloading..."));
+ description->set_ok_button_text(TTR("Downloading..."));
description->get_ok_button()->set_disabled(true);
}
} else {
- description->get_ok_button()->set_text(TTR("Download"));
+ description->set_ok_button_text(TTR("Download"));
description->get_ok_button()->set_disabled(false);
}
@@ -1375,12 +1376,17 @@ void EditorAssetLibrary::_install_external_asset(String p_zip_path, String p_tit
emit_signal(SNAME("install_asset"), p_zip_path, p_title);
}
-void EditorAssetLibrary::disable_community_support() {
- support->get_popup()->set_item_checked(SUPPORT_COMMUNITY, false);
+void EditorAssetLibrary::_update_asset_items_columns() {
+ int new_columns = get_size().x / (450.0 * EDSCALE);
+ new_columns = MAX(1, new_columns);
+
+ if (new_columns != asset_items->get_columns()) {
+ asset_items->set_columns(new_columns);
+ }
}
-void EditorAssetLibrary::set_columns(const int p_columns) {
- asset_items->set_columns(p_columns);
+void EditorAssetLibrary::disable_community_support() {
+ support->get_popup()->set_item_checked(SUPPORT_COMMUNITY, false);
}
void EditorAssetLibrary::_bind_methods() {
@@ -1538,7 +1544,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
library_vb->add_child(asset_top_page);
asset_items = memnew(GridContainer);
- asset_items->set_columns(2);
+ _update_asset_items_columns();
asset_items->add_theme_constant_override("h_separation", 10 * EDSCALE);
asset_items->add_theme_constant_override("v_separation", 10 * EDSCALE);
@@ -1578,7 +1584,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
asset_open = memnew(EditorFileDialog);
asset_open->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
- asset_open->add_filter("*.zip ; " + TTR("Assets ZIP File"));
+ asset_open->add_filter("*.zip", TTR("Assets ZIP File"));
asset_open->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
add_child(asset_open);
asset_open->connect("file_selected", callable_mp(this, &EditorAssetLibrary::_asset_file_selected));
@@ -1588,6 +1594,16 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
///////
+bool AssetLibraryEditorPlugin::is_available() {
+#ifdef JAVASCRIPT_ENABLED
+ // Asset Library can't work on Web editor for now as most assets are sourced
+ // directly from GitHub which does not set CORS.
+ return false;
+#else
+ return StreamPeerSSL::is_available();
+#endif
+}
+
void AssetLibraryEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
addon_library->show();
@@ -1600,7 +1616,7 @@ AssetLibraryEditorPlugin::AssetLibraryEditorPlugin() {
addon_library = memnew(EditorAssetLibrary);
addon_library->set_v_size_flags(Control::SIZE_EXPAND_FILL);
EditorNode::get_singleton()->get_main_control()->add_child(addon_library);
- addon_library->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ addon_library->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
addon_library->hide();
}
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index e09700b646..e02662b8db 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -301,6 +301,8 @@ class EditorAssetLibrary : public PanelContainer {
void _install_external_asset(String p_zip_path, String p_title);
+ void _update_asset_items_columns();
+
friend class EditorAssetLibraryItemDescription;
friend class EditorAssetLibraryItem;
@@ -311,7 +313,6 @@ protected:
public:
void disable_community_support();
- void set_columns(int p_columns);
EditorAssetLibrary(bool p_templates_only = false);
};
@@ -322,6 +323,8 @@ class AssetLibraryEditorPlugin : public EditorPlugin {
EditorAssetLibrary *addon_library = nullptr;
public:
+ static bool is_available();
+
virtual String get_name() const override { return "AssetLib"; }
bool has_main_screen() const override { return true; }
virtual void edit(Object *p_object) override {}
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
index a60e49ca9d..9b874ada45 100644
--- a/editor/plugins/audio_stream_editor_plugin.cpp
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -213,7 +213,7 @@ AudioStreamEditor::AudioStreamEditor() {
add_child(_player);
VBoxContainer *vbox = memnew(VBoxContainer);
- vbox->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_MINSIZE, 0);
+ vbox->set_anchors_and_offsets_preset(PRESET_FULL_RECT, PRESET_MODE_MINSIZE, 0);
add_child(vbox);
_preview = memnew(ColorRect);
@@ -222,7 +222,7 @@ AudioStreamEditor::AudioStreamEditor() {
vbox->add_child(_preview);
_indicator = memnew(Control);
- _indicator->set_anchors_and_offsets_preset(PRESET_WIDE);
+ _indicator->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
_indicator->connect("draw", callable_mp(this, &AudioStreamEditor::_draw_indicator));
_indicator->connect("gui_input", callable_mp(this, &AudioStreamEditor::_on_input_indicator));
_preview->add_child(_indicator);
diff --git a/editor/plugins/bit_map_editor_plugin.cpp b/editor/plugins/bit_map_editor_plugin.cpp
index 9003c4480b..657c5a36b6 100644
--- a/editor/plugins/bit_map_editor_plugin.cpp
+++ b/editor/plugins/bit_map_editor_plugin.cpp
@@ -33,11 +33,7 @@
#include "editor/editor_scale.h"
void BitMapEditor::setup(const Ref<BitMap> &p_bitmap) {
- Ref<ImageTexture> texture;
- texture.instantiate();
- texture->create_from_image(p_bitmap->convert_to_image());
- texture_rect->set_texture(texture);
-
+ texture_rect->set_texture(ImageTexture::create_from_image(p_bitmap->convert_to_image()));
size_label->set_text(vformat(String::utf8("%s×%s"), p_bitmap->get_size().width, p_bitmap->get_size().height));
}
diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp
new file mode 100644
index 0000000000..967a95be9d
--- /dev/null
+++ b/editor/plugins/bone_map_editor_plugin.cpp
@@ -0,0 +1,454 @@
+/*************************************************************************/
+/* bone_map_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "bone_map_editor_plugin.h"
+
+#include "editor/editor_scale.h"
+#include "editor/import/post_import_plugin_skeleton_renamer.h"
+#include "editor/import/post_import_plugin_skeleton_rest_fixer.h"
+#include "editor/import/scene_import_settings.h"
+
+void BoneMapperButton::fetch_textures() {
+ if (selected) {
+ set_normal_texture(get_theme_icon(SNAME("BoneMapperHandleSelected"), SNAME("EditorIcons")));
+ } else {
+ set_normal_texture(get_theme_icon(SNAME("BoneMapperHandle"), SNAME("EditorIcons")));
+ }
+ set_offset(SIDE_LEFT, 0);
+ set_offset(SIDE_RIGHT, 0);
+ set_offset(SIDE_TOP, 0);
+ set_offset(SIDE_BOTTOM, 0);
+
+ circle = memnew(TextureRect);
+ circle->set_texture(get_theme_icon(SNAME("BoneMapperHandleCircle"), SNAME("EditorIcons")));
+ add_child(circle);
+ set_state(BONE_MAP_STATE_UNSET);
+}
+
+StringName BoneMapperButton::get_profile_bone_name() const {
+ return profile_bone_name;
+}
+
+void BoneMapperButton::set_state(BoneMapState p_state) {
+ switch (p_state) {
+ case BONE_MAP_STATE_UNSET: {
+ circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/unset"));
+ } break;
+ case BONE_MAP_STATE_SET: {
+ circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/set"));
+ } break;
+ case BONE_MAP_STATE_ERROR: {
+ circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/error"));
+ } break;
+ default: {
+ } break;
+ }
+}
+
+bool BoneMapperButton::is_require() const {
+ return require;
+}
+
+void BoneMapperButton::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ fetch_textures();
+ } break;
+ }
+}
+
+BoneMapperButton::BoneMapperButton(const StringName p_profile_bone_name, bool p_require, bool p_selected) {
+ profile_bone_name = p_profile_bone_name;
+ require = p_require;
+ selected = p_selected;
+}
+
+BoneMapperButton::~BoneMapperButton() {
+}
+
+void BoneMapperItem::create_editor() {
+ skeleton_bone_selector = memnew(EditorPropertyTextEnum);
+ skeleton_bone_selector->setup(skeleton_bone_names, false, true);
+ skeleton_bone_selector->set_label(profile_bone_name);
+ skeleton_bone_selector->set_selectable(false);
+ skeleton_bone_selector->set_object_and_property(bone_map.ptr(), "bone_map/" + String(profile_bone_name));
+ skeleton_bone_selector->update_property();
+ skeleton_bone_selector->connect("property_changed", callable_mp(this, &BoneMapperItem::_value_changed));
+ add_child(skeleton_bone_selector);
+}
+
+void BoneMapperItem::_update_property() {
+ if (skeleton_bone_selector->get_edited_object() && skeleton_bone_selector->get_edited_property()) {
+ skeleton_bone_selector->update_property();
+ }
+}
+
+void BoneMapperItem::_value_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
+ bone_map->set(p_property, p_value);
+}
+
+void BoneMapperItem::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ create_editor();
+ bone_map->connect("bone_map_updated", callable_mp(this, &BoneMapperItem::_update_property));
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ if (!bone_map.is_null() && bone_map->is_connected("bone_map_updated", callable_mp(this, &BoneMapperItem::_update_property))) {
+ bone_map->disconnect("bone_map_updated", callable_mp(this, &BoneMapperItem::_update_property));
+ }
+ } break;
+ }
+}
+
+void BoneMapperItem::_bind_methods() {
+}
+
+BoneMapperItem::BoneMapperItem(Ref<BoneMap> &p_bone_map, PackedStringArray p_skeleton_bone_names, const StringName &p_profile_bone_name) {
+ bone_map = p_bone_map;
+ skeleton_bone_names = p_skeleton_bone_names;
+ profile_bone_name = p_profile_bone_name;
+}
+
+BoneMapperItem::~BoneMapperItem() {
+}
+
+void BoneMapper::create_editor() {
+ profile_group_selector = memnew(EditorPropertyEnum);
+ profile_group_selector->set_label("Group");
+ profile_group_selector->set_selectable(false);
+ profile_group_selector->set_object_and_property(this, "current_group_idx");
+ profile_group_selector->update_property();
+ profile_group_selector->connect("property_changed", callable_mp(this, &BoneMapper::_value_changed));
+ add_child(profile_group_selector);
+
+ bone_mapper_field = memnew(AspectRatioContainer);
+ bone_mapper_field->set_stretch_mode(AspectRatioContainer::STRETCH_FIT);
+ bone_mapper_field->set_custom_minimum_size(Vector2(0, 256.0) * EDSCALE);
+ bone_mapper_field->set_h_size_flags(Control::SIZE_FILL);
+ add_child(bone_mapper_field);
+
+ profile_bg = memnew(ColorRect);
+ profile_bg->set_color(Color(0, 0, 0, 1));
+ profile_bg->set_h_size_flags(Control::SIZE_FILL);
+ profile_bg->set_v_size_flags(Control::SIZE_FILL);
+ bone_mapper_field->add_child(profile_bg);
+
+ profile_texture = memnew(TextureRect);
+ profile_texture->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
+ profile_texture->set_ignore_texture_size(true);
+ profile_texture->set_h_size_flags(Control::SIZE_FILL);
+ profile_texture->set_v_size_flags(Control::SIZE_FILL);
+ bone_mapper_field->add_child(profile_texture);
+
+ mapper_item_vbox = memnew(VBoxContainer);
+ add_child(mapper_item_vbox);
+
+ separator = memnew(HSeparator);
+ add_child(separator);
+
+ recreate_items();
+}
+
+void BoneMapper::update_group_idx() {
+ if (!bone_map->get_profile().is_valid()) {
+ return;
+ }
+
+ PackedStringArray group_names;
+ int len = bone_map->get_profile()->get_group_size();
+ for (int i = 0; i < len; i++) {
+ group_names.push_back(bone_map->get_profile()->get_group_name(i));
+ }
+ if (current_group_idx >= len) {
+ current_group_idx = 0;
+ }
+ if (len > 0) {
+ profile_group_selector->setup(group_names);
+ profile_group_selector->update_property();
+ profile_group_selector->set_read_only(false);
+ }
+}
+
+void BoneMapper::set_current_group_idx(int p_group_idx) {
+ current_group_idx = p_group_idx;
+ recreate_editor();
+}
+
+int BoneMapper::get_current_group_idx() const {
+ return current_group_idx;
+}
+
+void BoneMapper::set_current_bone_idx(int p_bone_idx) {
+ current_bone_idx = p_bone_idx;
+ recreate_editor();
+}
+
+int BoneMapper::get_current_bone_idx() const {
+ return current_bone_idx;
+}
+
+void BoneMapper::recreate_editor() {
+ // Clear buttons.
+ int len = bone_mapper_buttons.size();
+ for (int i = 0; i < len; i++) {
+ profile_texture->remove_child(bone_mapper_buttons[i]);
+ memdelete(bone_mapper_buttons[i]);
+ }
+ bone_mapper_buttons.clear();
+
+ // Organize mapper items.
+ len = bone_mapper_items.size();
+ for (int i = 0; i < len; i++) {
+ bone_mapper_items[i]->set_visible(current_bone_idx == i);
+ }
+
+ Ref<SkeletonProfile> profile = bone_map->get_profile();
+ if (profile.is_valid()) {
+ SkeletonProfileHumanoid *hmn = Object::cast_to<SkeletonProfileHumanoid>(profile.ptr());
+ if (hmn) {
+ StringName hmn_group_name = profile->get_group_name(current_group_idx);
+ if (hmn_group_name == "Body") {
+ profile_texture->set_texture(get_theme_icon(SNAME("BoneMapHumanBody"), SNAME("EditorIcons")));
+ } else if (hmn_group_name == "Face") {
+ profile_texture->set_texture(get_theme_icon(SNAME("BoneMapHumanFace"), SNAME("EditorIcons")));
+ } else if (hmn_group_name == "LeftHand") {
+ profile_texture->set_texture(get_theme_icon(SNAME("BoneMapHumanLeftHand"), SNAME("EditorIcons")));
+ } else if (hmn_group_name == "RightHand") {
+ profile_texture->set_texture(get_theme_icon(SNAME("BoneMapHumanRightHand"), SNAME("EditorIcons")));
+ }
+ } else {
+ profile_texture->set_texture(profile->get_texture(current_group_idx));
+ }
+ } else {
+ profile_texture->set_texture(Ref<Texture2D>());
+ }
+
+ if (!profile.is_valid()) {
+ return;
+ }
+
+ for (int i = 0; i < len; i++) {
+ if (profile->get_group(i) == profile->get_group_name(current_group_idx)) {
+ BoneMapperButton *mb = memnew(BoneMapperButton(profile->get_bone_name(i), profile->is_require(i), current_bone_idx == i));
+ mb->connect("pressed", callable_mp(this, &BoneMapper::set_current_bone_idx), varray(i), CONNECT_DEFERRED);
+ mb->set_h_grow_direction(GROW_DIRECTION_BOTH);
+ mb->set_v_grow_direction(GROW_DIRECTION_BOTH);
+ Vector2 vc = profile->get_handle_offset(i);
+ bone_mapper_buttons.push_back(mb);
+ profile_texture->add_child(mb);
+ mb->set_anchor(SIDE_LEFT, vc.x);
+ mb->set_anchor(SIDE_RIGHT, vc.x);
+ mb->set_anchor(SIDE_TOP, vc.y);
+ mb->set_anchor(SIDE_BOTTOM, vc.y);
+ }
+ }
+
+ _update_state();
+}
+
+void BoneMapper::clear_items() {
+ // Clear items.
+ int len = bone_mapper_items.size();
+ for (int i = 0; i < len; i++) {
+ mapper_item_vbox->remove_child(bone_mapper_items[i]);
+ memdelete(bone_mapper_items[i]);
+ }
+ bone_mapper_items.clear();
+}
+
+void BoneMapper::recreate_items() {
+ clear_items();
+ // Create items by profile.
+ Ref<SkeletonProfile> profile = bone_map->get_profile();
+ if (profile.is_valid()) {
+ PackedStringArray skeleton_bone_names;
+ int len = skeleton->get_bone_count();
+ for (int i = 0; i < len; i++) {
+ skeleton_bone_names.push_back(skeleton->get_bone_name(i));
+ }
+
+ len = profile->get_bone_size();
+ for (int i = 0; i < len; i++) {
+ StringName bn = profile->get_bone_name(i);
+ bone_mapper_items.append(memnew(BoneMapperItem(bone_map, skeleton_bone_names, bn)));
+ mapper_item_vbox->add_child(bone_mapper_items[i]);
+ }
+ }
+
+ update_group_idx();
+ recreate_editor();
+}
+
+void BoneMapper::_update_state() {
+ int len = bone_mapper_buttons.size();
+ for (int i = 0; i < len; i++) {
+ StringName sbn = bone_map->get_skeleton_bone_name(bone_mapper_buttons[i]->get_profile_bone_name());
+ if (skeleton->find_bone(sbn) >= 0) {
+ if (bone_map->get_skeleton_bone_name_count(sbn) == 1) {
+ bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_SET);
+ } else {
+ bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_ERROR);
+ }
+ } else {
+ if (bone_mapper_buttons[i]->is_require()) {
+ bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_ERROR);
+ } else {
+ bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_UNSET);
+ }
+ }
+ }
+}
+
+void BoneMapper::_value_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
+ set(p_property, p_value);
+ recreate_editor();
+}
+
+void BoneMapper::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_current_group_idx", "current_group_idx"), &BoneMapper::set_current_group_idx);
+ ClassDB::bind_method(D_METHOD("get_current_group_idx"), &BoneMapper::get_current_group_idx);
+ ClassDB::bind_method(D_METHOD("set_current_bone_idx", "current_bone_idx"), &BoneMapper::set_current_bone_idx);
+ ClassDB::bind_method(D_METHOD("get_current_bone_idx"), &BoneMapper::get_current_bone_idx);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "current_group_idx"), "set_current_group_idx", "get_current_group_idx");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "current_bone_idx"), "set_current_bone_idx", "get_current_bone_idx");
+}
+
+void BoneMapper::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ create_editor();
+ bone_map->connect("bone_map_updated", callable_mp(this, &BoneMapper::_update_state));
+ bone_map->connect("profile_updated", callable_mp(this, &BoneMapper::recreate_items));
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ clear_items();
+ if (!bone_map.is_null()) {
+ if (bone_map->is_connected("bone_map_updated", callable_mp(this, &BoneMapper::_update_state))) {
+ bone_map->disconnect("bone_map_updated", callable_mp(this, &BoneMapper::_update_state));
+ }
+ if (bone_map->is_connected("profile_updated", callable_mp(this, &BoneMapper::recreate_items))) {
+ bone_map->disconnect("profile_updated", callable_mp(this, &BoneMapper::recreate_items));
+ }
+ }
+ }
+ }
+}
+
+BoneMapper::BoneMapper(Skeleton3D *p_skeleton, Ref<BoneMap> &p_bone_map) {
+ skeleton = p_skeleton;
+ bone_map = p_bone_map;
+}
+
+BoneMapper::~BoneMapper() {
+}
+
+void BoneMapEditor::create_editors() {
+ if (!skeleton) {
+ return;
+ }
+ bone_mapper = memnew(BoneMapper(skeleton, bone_map));
+ add_child(bone_mapper);
+}
+
+void BoneMapEditor::fetch_objects() {
+ // Hackey... but it may be the easist way to get a selected object from "ImporterScene".
+ SceneImportSettings *si = SceneImportSettings::get_singleton();
+ if (!si) {
+ return;
+ }
+ Node *selected = si->get_selected_node();
+ if (selected) {
+ Skeleton3D *sk = Object::cast_to<Skeleton3D>(selected);
+ if (!sk) {
+ return;
+ }
+ skeleton = sk;
+ } else {
+ // Editor should not exist.
+ skeleton = nullptr;
+ }
+}
+
+void BoneMapEditor::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ fetch_objects();
+ create_editors();
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ if (!bone_mapper) {
+ return;
+ }
+ remove_child(bone_mapper);
+ bone_mapper->queue_delete();
+ } break;
+ }
+}
+
+BoneMapEditor::BoneMapEditor(Ref<BoneMap> &p_bone_map) {
+ bone_map = p_bone_map;
+}
+
+BoneMapEditor::~BoneMapEditor() {
+}
+
+bool EditorInspectorPluginBoneMap::can_handle(Object *p_object) {
+ return Object::cast_to<BoneMap>(p_object) != nullptr;
+}
+
+void EditorInspectorPluginBoneMap::parse_begin(Object *p_object) {
+ BoneMap *bm = Object::cast_to<BoneMap>(p_object);
+ if (!bm) {
+ return;
+ }
+ Ref<BoneMap> r(bm);
+ editor = memnew(BoneMapEditor(r));
+ add_custom_control(editor);
+}
+
+BoneMapEditorPlugin::BoneMapEditorPlugin() {
+ // Register properties in editor settings.
+ EDITOR_DEF("editors/bone_mapper/handle_colors/set", Color(0.1, 0.6, 0.25));
+ EDITOR_DEF("editors/bone_mapper/handle_colors/error", Color(0.8, 0.2, 0.2));
+ EDITOR_DEF("editors/bone_mapper/handle_colors/unset", Color(0.3, 0.3, 0.3));
+
+ Ref<EditorInspectorPluginBoneMap> inspector_plugin;
+ inspector_plugin.instantiate();
+ add_inspector_plugin(inspector_plugin);
+
+ Ref<PostImportPluginSkeletonRenamer> post_import_plugin_renamer;
+ post_import_plugin_renamer.instantiate();
+ add_scene_post_import_plugin(post_import_plugin_renamer);
+
+ Ref<PostImportPluginSkeletonRestFixer> post_import_plugin_rest_fixer;
+ post_import_plugin_rest_fixer.instantiate();
+ add_scene_post_import_plugin(post_import_plugin_rest_fixer);
+}
diff --git a/editor/plugins/bone_map_editor_plugin.h b/editor/plugins/bone_map_editor_plugin.h
new file mode 100644
index 0000000000..e1ea6b4060
--- /dev/null
+++ b/editor/plugins/bone_map_editor_plugin.h
@@ -0,0 +1,179 @@
+/*************************************************************************/
+/* bone_map_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef BONE_MAP_EDITOR_H
+#define BONE_MAP_EDITOR_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "editor/editor_properties.h"
+#include "scene/3d/skeleton_3d.h"
+#include "scene/gui/color_rect.h"
+#include "scene/gui/dialogs.h"
+#include "scene/resources/bone_map.h"
+#include "scene/resources/texture.h"
+
+class BoneMapperButton : public TextureButton {
+ GDCLASS(BoneMapperButton, TextureButton);
+
+public:
+ enum BoneMapState {
+ BONE_MAP_STATE_UNSET,
+ BONE_MAP_STATE_SET,
+ BONE_MAP_STATE_ERROR
+ };
+
+private:
+ StringName profile_bone_name;
+ bool selected = false;
+ bool require = false;
+
+ TextureRect *circle;
+
+ void fetch_textures();
+
+protected:
+ void _notification(int p_what);
+
+public:
+ StringName get_profile_bone_name() const;
+ void set_state(BoneMapState p_state);
+
+ bool is_require() const;
+
+ BoneMapperButton(const StringName p_profile_bone_name, bool p_require, bool p_selected);
+ ~BoneMapperButton();
+};
+
+class BoneMapperItem : public VBoxContainer {
+ GDCLASS(BoneMapperItem, VBoxContainer);
+
+ int button_id = -1;
+ StringName profile_bone_name;
+
+ PackedStringArray skeleton_bone_names;
+ Ref<BoneMap> bone_map;
+
+ EditorPropertyTextEnum *skeleton_bone_selector;
+
+ void _update_property();
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+ virtual void _value_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing);
+ virtual void create_editor();
+
+public:
+ void assign_button_id(int p_button_id);
+
+ BoneMapperItem(Ref<BoneMap> &p_bone_map, PackedStringArray p_skeleton_bone_names, const StringName &p_profile_bone_name = StringName());
+ ~BoneMapperItem();
+};
+
+class BoneMapper : public VBoxContainer {
+ GDCLASS(BoneMapper, VBoxContainer);
+
+ Skeleton3D *skeleton;
+ Ref<BoneMap> bone_map;
+
+ Vector<BoneMapperItem *> bone_mapper_items;
+
+ VBoxContainer *mapper_item_vbox;
+ HSeparator *separator;
+
+ int current_group_idx = 0;
+ int current_bone_idx = -1;
+
+ AspectRatioContainer *bone_mapper_field;
+ EditorPropertyEnum *profile_group_selector;
+ ColorRect *profile_bg;
+ TextureRect *profile_texture;
+ Vector<BoneMapperButton *> bone_mapper_buttons;
+
+ void create_editor();
+ void recreate_editor();
+ void clear_items();
+ void recreate_items();
+ void update_group_idx();
+ void _update_state();
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+ virtual void _value_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing);
+
+public:
+ void set_current_group_idx(int p_group_idx);
+ int get_current_group_idx() const;
+ void set_current_bone_idx(int p_bone_idx);
+ int get_current_bone_idx() const;
+
+ BoneMapper(Skeleton3D *p_skeleton, Ref<BoneMap> &p_bone_map);
+ ~BoneMapper();
+};
+
+class BoneMapEditor : public VBoxContainer {
+ GDCLASS(BoneMapEditor, VBoxContainer);
+
+ Skeleton3D *skeleton;
+ Ref<BoneMap> bone_map;
+ BoneMapper *bone_mapper;
+
+ void fetch_objects();
+ void clear_editors();
+ void create_editors();
+
+protected:
+ void _notification(int p_what);
+
+public:
+ BoneMapEditor(Ref<BoneMap> &p_bone_map);
+ ~BoneMapEditor();
+};
+
+class EditorInspectorPluginBoneMap : public EditorInspectorPlugin {
+ GDCLASS(EditorInspectorPluginBoneMap, EditorInspectorPlugin);
+ BoneMapEditor *editor;
+
+public:
+ virtual bool can_handle(Object *p_object) override;
+ virtual void parse_begin(Object *p_object) override;
+};
+
+class BoneMapEditorPlugin : public EditorPlugin {
+ GDCLASS(BoneMapEditorPlugin, EditorPlugin);
+
+public:
+ virtual String get_name() const override { return "BoneMap"; }
+ BoneMapEditorPlugin();
+};
+
+#endif // BONE_MAP_EDITOR_H
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index dea4aaded7..82772178e0 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -50,6 +50,7 @@
#include "scene/2d/skeleton_2d.h"
#include "scene/2d/sprite_2d.h"
#include "scene/2d/touch_screen_button.h"
+#include "scene/gui/flow_container.h"
#include "scene/gui/grid_container.h"
#include "scene/gui/nine_patch_rect.h"
#include "scene/gui/subviewport_container.h"
@@ -813,9 +814,17 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2
}
void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones) {
+ original_transform = Transform2D();
+ bool transform_stored = false;
+
for (CanvasItem *canvas_item : p_canvas_items) {
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
if (se) {
+ if (!transform_stored) {
+ original_transform = canvas_item->get_global_transform();
+ transform_stored = true;
+ }
+
se->undo_state = canvas_item->_edit_get_state();
se->pre_drag_xform = canvas_item->get_global_transform_with_canvas();
if (canvas_item->_edit_use_rect()) {
@@ -1193,7 +1202,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve
}
snap_target[0] = SNAP_TARGET_NONE;
snap_target[1] = SNAP_TARGET_NONE;
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -1361,14 +1370,14 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
drag_selection[0]->get_name(),
drag_selection[0]->_edit_get_pivot().x,
drag_selection[0]->_edit_get_pivot().y));
- drag_type = DRAG_NONE;
+ _reset_drag();
return true;
}
// Cancel a drag
if (b.is_valid() && b->get_button_index() == MouseButton::RIGHT && b->is_pressed()) {
_restore_canvas_item_state(drag_selection);
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -1444,14 +1453,14 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) {
_insert_animation_keys(false, true, false, true);
}
- drag_type = DRAG_NONE;
+ _reset_drag();
return true;
}
// Cancel a drag
if (b.is_valid() && b->get_button_index() == MouseButton::RIGHT && b->is_pressed()) {
_restore_canvas_item_state(drag_selection);
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -1606,14 +1615,14 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) {
_commit_canvas_item_state(
drag_selection,
vformat(TTR("Move CanvasItem \"%s\" Anchor"), drag_selection[0]->get_name()));
- drag_type = DRAG_NONE;
+ _reset_drag();
return true;
}
// Cancel a drag
if (b.is_valid() && b->get_button_index() == MouseButton::RIGHT && b->is_pressed()) {
_restore_canvas_item_state(drag_selection);
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -1812,7 +1821,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
snap_target[0] = SNAP_TARGET_NONE;
snap_target[1] = SNAP_TARGET_NONE;
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -1822,7 +1831,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
_restore_canvas_item_state(drag_selection);
snap_target[0] = SNAP_TARGET_NONE;
snap_target[1] = SNAP_TARGET_NONE;
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -1951,7 +1960,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
_insert_animation_keys(false, false, true, true);
}
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -1959,7 +1968,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
// Cancel a drag
if (b.is_valid() && b->get_button_index() == MouseButton::RIGHT && b->is_pressed()) {
_restore_canvas_item_state(drag_selection);
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -2084,7 +2093,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
snap_target[0] = SNAP_TARGET_NONE;
snap_target[1] = SNAP_TARGET_NONE;
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -2094,7 +2103,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
_restore_canvas_item_state(drag_selection, true);
snap_target[0] = SNAP_TARGET_NONE;
snap_target[1] = SNAP_TARGET_NONE;
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -2201,7 +2210,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
drag_selection[0]->_edit_get_position().y),
true);
}
- drag_type = DRAG_NONE;
+ _reset_drag();
}
viewport->update();
return true;
@@ -2273,7 +2282,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
}
selection_menu_additive_selection = b->is_shift_pressed();
- selection_menu->set_position(get_screen_position() + b->get_position());
+ selection_menu->set_position(viewport->get_screen_transform().xform(b->get_position()));
selection_menu->reset_size();
selection_menu->popup();
return true;
@@ -2352,7 +2361,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
if (drag_type == DRAG_QUEUED) {
if (b.is_valid() && !b->is_pressed()) {
- drag_type = DRAG_NONE;
+ _reset_drag();
return true;
}
if (m.is_valid()) {
@@ -2403,14 +2412,14 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
}
}
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
if (b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::RIGHT) {
// Cancel box selection
- drag_type = DRAG_NONE;
+ _reset_drag();
viewport->update();
return true;
}
@@ -2669,7 +2678,7 @@ void CanvasItemEditor::_draw_text_at_position(Point2 p_position, String p_string
color.a = 0.8;
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- Size2 text_size = font->get_string_size(p_string, font_size);
+ Size2 text_size = font->get_string_size(p_string, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
switch (p_side) {
case SIDE_LEFT:
p_position += Vector2(-text_size.x - 5, text_size.y / 2);
@@ -2741,16 +2750,18 @@ void CanvasItemEditor::_draw_guides() {
String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).x)));
Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
- Size2 text_size = font->get_string_size(str, font_size);
- viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color, outline_size, outline_color);
+ Size2 text_size = font->get_string_size(str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
+ viewport->draw_string_outline(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color, Math::round(EDSCALE));
}
if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) {
String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).y)));
Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
- Size2 text_size = font->get_string_size(str, font_size);
- viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color, outline_size, outline_color);
+ Size2 text_size = font->get_string_size(str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
+ viewport->draw_string_outline(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
viewport->draw_line(Point2(0, dragged_guide_pos.y), Point2(viewport->get_size().x, dragged_guide_pos.y), guide_color, Math::round(EDSCALE));
}
}
@@ -2962,13 +2973,15 @@ void CanvasItemEditor::_draw_ruler_tool() {
text_pos.y = CLAMP(text_pos.y, text_height * 1.5, viewport->get_rect().size.y - text_height * 1.5);
if (begin.is_equal_approx(end)) {
- viewport->draw_string(font, text_pos, (String)ruler_tool_origin, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, text_pos, (String)ruler_tool_origin, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, text_pos, (String)ruler_tool_origin, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
Ref<Texture2D> position_icon = get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons"));
viewport->draw_texture(get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons")), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2);
return;
}
- viewport->draw_string(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
bool draw_secondary_lines = !(Math::is_equal_approx(begin.y, corner.y) || Math::is_equal_approx(end.x, corner.x));
@@ -2986,16 +2999,19 @@ void CanvasItemEditor::_draw_ruler_tool() {
Point2 text_pos2 = text_pos;
text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2);
- viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color);
Point2 v_angle_text_pos = Point2();
v_angle_text_pos.x = CLAMP(begin.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width);
v_angle_text_pos.y = begin.y < end.y ? MIN(text_pos2.y - 2 * text_height, begin.y - text_height * 0.5) : MAX(text_pos2.y + text_height * 3, begin.y + text_height * 1.5);
- viewport->draw_string(font, v_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), vertical_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, v_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), vertical_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, v_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), vertical_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color);
text_pos2 = text_pos;
text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y - text_height / 2) : MAX(text_pos.y + text_height * 2, end.y - text_height / 2);
- viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color);
Point2 h_angle_text_pos = Point2();
h_angle_text_pos.x = CLAMP(end.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width);
@@ -3012,7 +3028,8 @@ void CanvasItemEditor::_draw_ruler_tool() {
h_angle_text_pos.y = MIN(text_pos.y - height_multiplier * text_height, MIN(end.y - text_height * 0.5, text_pos2.y - height_multiplier * text_height));
}
}
- viewport->draw_string(font, h_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), horizontal_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, h_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), horizontal_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, h_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), horizontal_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color);
// Angle arcs
int arc_point_count = 8;
@@ -3047,17 +3064,21 @@ void CanvasItemEditor::_draw_ruler_tool() {
text_pos.y = CLAMP(text_pos.y, text_height * 2.5, viewport->get_rect().size.y - text_height / 2);
if (draw_secondary_lines) {
- viewport->draw_string(font, text_pos, TS->format_number(vformat("%.2f " + TTR("units"), (length_vector / grid_step).length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, text_pos, TS->format_number(vformat("%.2f " + TTR("units"), (length_vector / grid_step).length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, text_pos, TS->format_number(vformat("%.2f " + TTR("units"), (length_vector / grid_step).length())), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
Point2 text_pos2 = text_pos;
text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2);
- viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.y / grid_step.y))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.y / grid_step.y))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.y / grid_step.y))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color);
text_pos2 = text_pos;
text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y + text_height / 2) : MAX(text_pos.y + text_height * 2, end.y + text_height / 2);
- viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.x / grid_step.x))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.x / grid_step.x))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, text_pos2, TS->format_number(vformat("%d " + TTR("units"), roundf(length_vector.x / grid_step.x))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color);
} else {
- viewport->draw_string(font, text_pos, TS->format_number(vformat("%d " + TTR("units"), roundf((length_vector / grid_step).length()))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color, outline_size, outline_color);
+ viewport->draw_string_outline(font, text_pos, TS->format_number(vformat("%d " + TTR("units"), roundf((length_vector / grid_step).length()))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color);
+ viewport->draw_string(font, text_pos, TS->format_number(vformat("%d " + TTR("units"), roundf((length_vector / grid_step).length()))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
}
}
} else {
@@ -3603,7 +3624,7 @@ void CanvasItemEditor::_draw_hover() {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- Size2 node_name_size = font->get_string_size(node_name, font_size);
+ Size2 node_name_size = font->get_string_size(node_name, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
Size2 item_size = Size2(node_icon->get_size().x + 4 + node_name_size.x, MAX(node_icon->get_size().y, node_name_size.y - 3));
Point2 pos = transform.xform(hovering_results[i].position) - Point2(0, item_size.y) + (Point2(node_icon->get_size().x, -node_icon->get_size().y) / 4);
@@ -3624,6 +3645,67 @@ void CanvasItemEditor::_draw_hover() {
}
}
+void CanvasItemEditor::_draw_transform_message() {
+ if (drag_type == DRAG_NONE || drag_selection.is_empty() || !drag_selection.front()->get()) {
+ return;
+ }
+ String transform_message;
+ Transform2D current_transform = drag_selection.front()->get()->get_global_transform();
+
+ double snap = EDITOR_GET("interface/inspector/default_float_step");
+ int snap_step_decimals = Math::range_step_decimals(snap);
+#define FORMAT(value) (TS->format_number(String::num(value, snap_step_decimals)))
+
+ switch (drag_type) {
+ case DRAG_MOVE:
+ case DRAG_MOVE_X:
+ case DRAG_MOVE_Y: {
+ Vector2 delta = current_transform.get_origin() - original_transform.get_origin();
+ if (drag_type == DRAG_MOVE) {
+ transform_message = TTR("Moving:") + " (" + FORMAT(delta.x) + ", " + FORMAT(delta.y) + ") px";
+ } else if (drag_type == DRAG_MOVE_X) {
+ transform_message = TTR("Moving:") + " " + FORMAT(delta.x) + " px";
+ } else if (drag_type == DRAG_MOVE_Y) {
+ transform_message = TTR("Moving:") + " " + FORMAT(delta.y) + " px";
+ }
+ } break;
+
+ case DRAG_ROTATE: {
+ real_t delta = Math::rad2deg(current_transform.get_rotation() - original_transform.get_rotation());
+ transform_message = TTR("Rotating:") + " " + FORMAT(delta) + String::utf8(" °");
+ } break;
+
+ case DRAG_SCALE_X:
+ case DRAG_SCALE_Y:
+ case DRAG_SCALE_BOTH: {
+ Vector2 original_scale = (Math::is_zero_approx(original_transform.get_scale().x) || Math::is_zero_approx(original_transform.get_scale().y)) ? Vector2(CMP_EPSILON, CMP_EPSILON) : original_transform.get_scale();
+ Vector2 delta = current_transform.get_scale() / original_scale;
+ if (drag_type == DRAG_SCALE_BOTH) {
+ transform_message = TTR("Scaling:") + String::utf8(" ×(") + FORMAT(delta.x) + ", " + FORMAT(delta.y) + ")";
+ } else if (drag_type == DRAG_SCALE_X) {
+ transform_message = TTR("Scaling:") + String::utf8(" ×") + FORMAT(delta.x);
+ } else if (drag_type == DRAG_SCALE_Y) {
+ transform_message = TTR("Scaling:") + String::utf8(" ×") + FORMAT(delta.y);
+ }
+ } break;
+
+ default:
+ break;
+ }
+#undef FORMAT
+
+ if (transform_message.is_empty()) {
+ return;
+ }
+
+ Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
+ int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
+ Point2 msgpos = Point2(RULER_WIDTH + 5 * EDSCALE, viewport->get_size().y - 20 * EDSCALE);
+ viewport->draw_string(font, msgpos + Point2(1, 1), transform_message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
+ viewport->draw_string(font, msgpos + Point2(-1, -1), transform_message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(0, 0, 0, 0.8));
+ viewport->draw_string(font, msgpos, transform_message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 1));
+}
+
void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
ERR_FAIL_COND(!p_node);
@@ -3735,6 +3817,7 @@ void CanvasItemEditor::_draw_viewport() {
_draw_smart_snapping();
_draw_focus();
_draw_hover();
+ _draw_transform_message();
}
void CanvasItemEditor::update_viewport() {
@@ -3779,7 +3862,7 @@ void CanvasItemEditor::_update_editor_settings() {
key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55));
animation_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- context_menu_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles")));
+ context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles")));
panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
pan_speed = int(EditorSettings::get_singleton()->get("editors/panning/2d_editor_pan_speed"));
@@ -3899,7 +3982,7 @@ void CanvasItemEditor::_notification(int p_what) {
void CanvasItemEditor::_selection_changed() {
if (!selected_from_canvas) {
- drag_type = DRAG_NONE;
+ _reset_drag();
}
selected_from_canvas = false;
}
@@ -3907,7 +3990,7 @@ void CanvasItemEditor::_selection_changed() {
void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
Array selection = editor_selection->get_selected_nodes();
if (selection.size() != 1 || Object::cast_to<Node>(selection[0]) != p_canvas_item) {
- drag_type = DRAG_NONE;
+ _reset_drag();
// Clear the selection
editor_selection->clear(); //_clear_canvas_items();
@@ -4619,6 +4702,11 @@ void CanvasItemEditor::_focus_selection(int p_op) {
}
}
+void CanvasItemEditor::_reset_drag() {
+ drag_type = DRAG_NONE;
+ drag_selection.clear();
+}
+
void CanvasItemEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_override_camera_button", "game_running"), &CanvasItemEditor::_update_override_camera_button);
ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data);
@@ -4839,11 +4927,11 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
ERR_FAIL_COND(!p_control);
- hbc_context_menu->add_child(p_control);
+ context_menu_hbox->add_child(p_control);
}
void CanvasItemEditor::remove_control_from_menu_panel(Control *p_control) {
- hbc_context_menu->remove_child(p_control);
+ context_menu_hbox->remove_child(p_control);
}
void CanvasItemEditor::add_control_to_left_panel(Control *p_control) {
@@ -4892,9 +4980,14 @@ CanvasItemEditor::CanvasItemEditor() {
EditorNode::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true));
EditorNode::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false));
- hb = memnew(HBoxContainer);
- add_child(hb);
- hb->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ // A fluid container for all toolbars.
+ HFlowContainer *main_flow = memnew(HFlowContainer);
+ add_child(main_flow);
+
+ // Main toolbars.
+ HBoxContainer *main_menu_hbox = memnew(HBoxContainer);
+ main_menu_hbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
+ main_flow->add_child(main_menu_hbox);
bottom_split = memnew(VSplitContainer);
add_child(bottom_split);
@@ -4919,7 +5012,7 @@ CanvasItemEditor::CanvasItemEditor() {
SubViewportContainer *scene_tree = memnew(SubViewportContainer);
viewport_scrollable->add_child(scene_tree);
scene_tree->set_stretch(true);
- scene_tree->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ scene_tree->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
scene_tree->add_child(EditorNode::get_singleton()->get_scene_root());
controls_vb = memnew(VBoxContainer);
@@ -4949,7 +5042,7 @@ CanvasItemEditor::CanvasItemEditor() {
viewport = memnew(CanvasItemEditorViewport(this));
viewport_scrollable->add_child(viewport);
viewport->set_mouse_filter(MOUSE_FILTER_PASS);
- viewport->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ viewport->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
viewport->set_clip_contents(true);
viewport->set_focus_mode(FOCUS_ALL);
viewport->connect("draw", callable_mp(this, &CanvasItemEditor::_draw_viewport));
@@ -4972,12 +5065,12 @@ CanvasItemEditor::CanvasItemEditor() {
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
Control *margin_left = memnew(Control);
- hb->add_child(margin_left);
+ main_menu_hbox->add_child(margin_left);
margin_left->set_custom_minimum_size(Size2(2, 0) * EDSCALE);
select_button = memnew(Button);
select_button->set_flat(true);
- hb->add_child(select_button);
+ main_menu_hbox->add_child(select_button);
select_button->set_toggle_mode(true);
select_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_SELECT));
select_button->set_pressed(true);
@@ -4985,11 +5078,11 @@ CanvasItemEditor::CanvasItemEditor() {
select_button->set_shortcut_context(this);
select_button->set_tooltip(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Alt+Drag: Scale selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("RMB: Add node at position clicked."));
- hb->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
move_button = memnew(Button);
move_button->set_flat(true);
- hb->add_child(move_button);
+ main_menu_hbox->add_child(move_button);
move_button->set_toggle_mode(true);
move_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_MOVE));
move_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/move_mode", TTR("Move Mode"), Key::W));
@@ -4998,7 +5091,7 @@ CanvasItemEditor::CanvasItemEditor() {
rotate_button = memnew(Button);
rotate_button->set_flat(true);
- hb->add_child(rotate_button);
+ main_menu_hbox->add_child(rotate_button);
rotate_button->set_toggle_mode(true);
rotate_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_ROTATE));
rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode", TTR("Rotate Mode"), Key::E));
@@ -5007,32 +5100,32 @@ CanvasItemEditor::CanvasItemEditor() {
scale_button = memnew(Button);
scale_button->set_flat(true);
- hb->add_child(scale_button);
+ main_menu_hbox->add_child(scale_button);
scale_button->set_toggle_mode(true);
scale_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_SCALE));
scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), Key::S));
scale_button->set_shortcut_context(this);
scale_button->set_tooltip(TTR("Shift: Scale proportionally."));
- hb->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
list_select_button = memnew(Button);
list_select_button->set_flat(true);
- hb->add_child(list_select_button);
+ main_menu_hbox->add_child(list_select_button);
list_select_button->set_toggle_mode(true);
list_select_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_LIST_SELECT));
list_select_button->set_tooltip(TTR("Show list of selectable nodes at position clicked."));
pivot_button = memnew(Button);
pivot_button->set_flat(true);
- hb->add_child(pivot_button);
+ main_menu_hbox->add_child(pivot_button);
pivot_button->set_toggle_mode(true);
pivot_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_EDIT_PIVOT));
pivot_button->set_tooltip(TTR("Click to change object's rotation pivot."));
pan_button = memnew(Button);
pan_button->set_flat(true);
- hb->add_child(pan_button);
+ main_menu_hbox->add_child(pan_button);
pan_button->set_toggle_mode(true);
pan_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_PAN));
pan_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/pan_mode", TTR("Pan Mode"), Key::G));
@@ -5041,18 +5134,18 @@ CanvasItemEditor::CanvasItemEditor() {
ruler_button = memnew(Button);
ruler_button->set_flat(true);
- hb->add_child(ruler_button);
+ main_menu_hbox->add_child(ruler_button);
ruler_button->set_toggle_mode(true);
ruler_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_RULER));
ruler_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/ruler_mode", TTR("Ruler Mode"), Key::R));
ruler_button->set_shortcut_context(this);
ruler_button->set_tooltip(TTR("Ruler Mode"));
- hb->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
smart_snap_button = memnew(Button);
smart_snap_button->set_flat(true);
- hb->add_child(smart_snap_button);
+ main_menu_hbox->add_child(smart_snap_button);
smart_snap_button->set_toggle_mode(true);
smart_snap_button->connect("toggled", callable_mp(this, &CanvasItemEditor::_button_toggle_smart_snap));
smart_snap_button->set_tooltip(TTR("Toggle smart snapping."));
@@ -5061,7 +5154,7 @@ CanvasItemEditor::CanvasItemEditor() {
grid_snap_button = memnew(Button);
grid_snap_button->set_flat(true);
- hb->add_child(grid_snap_button);
+ main_menu_hbox->add_child(grid_snap_button);
grid_snap_button->set_toggle_mode(true);
grid_snap_button->connect("toggled", callable_mp(this, &CanvasItemEditor::_button_toggle_grid_snap));
grid_snap_button->set_tooltip(TTR("Toggle grid snapping."));
@@ -5070,7 +5163,7 @@ CanvasItemEditor::CanvasItemEditor() {
snap_config_menu = memnew(MenuButton);
snap_config_menu->set_shortcut_context(this);
- hb->add_child(snap_config_menu);
+ main_menu_hbox->add_child(snap_config_menu);
snap_config_menu->set_h_size_flags(SIZE_SHRINK_END);
snap_config_menu->set_tooltip(TTR("Snapping Options"));
snap_config_menu->set_switch_on_hover(true);
@@ -5099,11 +5192,11 @@ CanvasItemEditor::CanvasItemEditor() {
smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_other_nodes", TTR("Snap to Other Nodes")), SNAP_USE_OTHER_NODES);
smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_guides", TTR("Snap to Guides")), SNAP_USE_GUIDES);
- hb->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
lock_button = memnew(Button);
lock_button->set_flat(true);
- hb->add_child(lock_button);
+ main_menu_hbox->add_child(lock_button);
lock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(LOCK_SELECTED));
lock_button->set_tooltip(TTR("Lock selected node, preventing selection and movement."));
@@ -5112,7 +5205,7 @@ CanvasItemEditor::CanvasItemEditor() {
unlock_button = memnew(Button);
unlock_button->set_flat(true);
- hb->add_child(unlock_button);
+ main_menu_hbox->add_child(unlock_button);
unlock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(UNLOCK_SELECTED));
unlock_button->set_tooltip(TTR("Unlock selected node, allowing selection and movement."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
@@ -5120,7 +5213,7 @@ CanvasItemEditor::CanvasItemEditor() {
group_button = memnew(Button);
group_button->set_flat(true);
- hb->add_child(group_button);
+ main_menu_hbox->add_child(group_button);
group_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(GROUP_SELECTED));
group_button->set_tooltip(TTR("Makes sure the object's children are not selectable."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
@@ -5128,17 +5221,17 @@ CanvasItemEditor::CanvasItemEditor() {
ungroup_button = memnew(Button);
ungroup_button->set_flat(true);
- hb->add_child(ungroup_button);
+ main_menu_hbox->add_child(ungroup_button);
ungroup_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(UNGROUP_SELECTED));
ungroup_button->set_tooltip(TTR("Restores the object's children's ability to be selected."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
ungroup_button->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G));
- hb->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
skeleton_menu = memnew(MenuButton);
skeleton_menu->set_shortcut_context(this);
- hb->add_child(skeleton_menu);
+ main_menu_hbox->add_child(skeleton_menu);
skeleton_menu->set_tooltip(TTR("Skeleton Options"));
skeleton_menu->set_switch_on_hover(true);
@@ -5149,24 +5242,24 @@ CanvasItemEditor::CanvasItemEditor() {
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bone2D Node(s) from Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::B), SKELETON_MAKE_BONES);
p->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_popup_callback));
- hb->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
override_camera_button = memnew(Button);
override_camera_button->set_flat(true);
- hb->add_child(override_camera_button);
+ main_menu_hbox->add_child(override_camera_button);
override_camera_button->connect("toggled", callable_mp(this, &CanvasItemEditor::_button_override_camera));
override_camera_button->set_toggle_mode(true);
override_camera_button->set_disabled(true);
_update_override_camera_button(false);
- hb->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
view_menu = memnew(MenuButton);
// TRANSLATORS: Noun, name of the 2D/3D View menus.
view_menu->set_text(TTR("View"));
view_menu->set_switch_on_hover(true);
view_menu->set_shortcut_context(this);
- hb->add_child(view_menu);
+ main_menu_hbox->add_child(view_menu);
view_menu->get_popup()->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_popup_callback));
p = view_menu->get_popup();
@@ -5199,16 +5292,17 @@ CanvasItemEditor::CanvasItemEditor() {
p->add_separator();
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale"), KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::P), PREVIEW_CANVAS_SCALE);
- hb->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
- context_menu_container = memnew(PanelContainer);
- hbc_context_menu = memnew(HBoxContainer);
- context_menu_container->add_child(hbc_context_menu);
- hb->add_child(context_menu_container);
+ // Contextual toolbars.
+ context_menu_panel = memnew(PanelContainer);
+ context_menu_hbox = memnew(HBoxContainer);
+ context_menu_panel->add_child(context_menu_hbox);
+ main_flow->add_child(context_menu_panel);
// Animation controls.
animation_hb = memnew(HBoxContainer);
- hbc_context_menu->add_child(animation_hb);
+ context_menu_hbox->add_child(animation_hb);
animation_hb->add_child(memnew(VSeparator));
animation_hb->hide();
@@ -5282,7 +5376,7 @@ CanvasItemEditor::CanvasItemEditor() {
add_child(selection_menu);
selection_menu->set_min_size(Vector2(100, 0));
selection_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_selection_result_pressed));
- selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide));
+ selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide), varray(), CONNECT_DEFERRED);
add_node_menu = memnew(PopupMenu);
add_child(add_node_menu);
@@ -5338,7 +5432,7 @@ CanvasItemEditorPlugin::CanvasItemEditorPlugin() {
canvas_item_editor = memnew(CanvasItemEditor);
canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
EditorNode::get_singleton()->get_main_control()->add_child(canvas_item_editor);
- canvas_item_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ canvas_item_editor->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
canvas_item_editor->hide();
}
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index c20a054800..18c898521d 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -188,11 +188,10 @@ private:
HScrollBar *h_scroll = nullptr;
VScrollBar *v_scroll = nullptr;
- HBoxContainer *hb = nullptr;
// Used for secondary menu items which are displayed depending on the currently selected node
// (such as MeshInstance's "Mesh" menu).
- PanelContainer *context_menu_container = nullptr;
- HBoxContainer *hbc_context_menu = nullptr;
+ PanelContainer *context_menu_panel = nullptr;
+ HBoxContainer *context_menu_hbox = nullptr;
Transform2D transform;
GridVisibility grid_visibility = GRID_VISIBILITY_SHOW_WHEN_SNAPPING;
@@ -347,6 +346,7 @@ private:
bool is_hovering_v_guide = false;
bool updating_value_dialog = false;
+ Transform2D original_transform;
Point2 box_selecting_to;
@@ -433,6 +433,7 @@ private:
void _draw_invisible_nodes_positions(Node *p_node, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
void _draw_locks_and_groups(Node *p_node, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
void _draw_hover();
+ void _draw_transform_message();
void _draw_viewport();
@@ -453,8 +454,8 @@ private:
void _update_cursor();
void _selection_changed();
-
void _focus_selection(int p_op);
+ void _reset_drag();
SnapTarget snap_target[2];
Transform2D snap_transform;
@@ -501,8 +502,6 @@ protected:
static void _bind_methods();
- HBoxContainer *get_panel_hb() { return hb; }
-
static CanvasItemEditor *singleton;
public:
diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp
index 3adaf8f601..ec038174fc 100644
--- a/editor/plugins/control_editor_plugin.cpp
+++ b/editor/plugins/control_editor_plugin.cpp
@@ -173,7 +173,7 @@ void EditorPropertyAnchorsPreset::setup(const Vector<String> &p_options) {
Vector<String> split_after;
split_after.append("Custom");
- split_after.append("PresetWide");
+ split_after.append("PresetFullRect");
split_after.append("PresetBottomLeft");
split_after.append("PresetCenter");
@@ -181,24 +181,18 @@ void EditorPropertyAnchorsPreset::setup(const Vector<String> &p_options) {
Vector<String> text_split = p_options[i].split(":");
int64_t current_val = text_split[1].to_int();
- String humanized_name = text_split[0];
- if (humanized_name.begins_with("Preset")) {
- if (humanized_name == "PresetWide") {
- humanized_name = "Full Rect";
- } else {
- humanized_name = humanized_name.trim_prefix("Preset");
- humanized_name = humanized_name.capitalize();
- }
-
- String icon_name = text_split[0].trim_prefix("Preset");
- icon_name = "ControlAlign" + icon_name;
+ String option_name = text_split[0];
+ if (option_name.begins_with("Preset")) {
+ String preset_name = option_name.trim_prefix("Preset");
+ String humanized_name = preset_name.capitalize();
+ String icon_name = "ControlAlign" + preset_name;
options->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(icon_name, "EditorIcons"), humanized_name);
} else {
- options->add_item(humanized_name);
+ options->add_item(option_name);
}
options->set_item_metadata(j, current_val);
- if (split_after.has(text_split[0])) {
+ if (split_after.has(option_name)) {
options->add_separator();
j++;
}
@@ -479,7 +473,7 @@ void ControlEditorToolbar::_set_anchors_and_offsets_preset(Control::LayoutPreset
case PRESET_BOTTOM_WIDE:
case PRESET_VCENTER_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_MINSIZE);
break;
}
@@ -689,8 +683,8 @@ void ControlEditorToolbar::_popup_callback(int p_op) {
case ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE: {
_set_anchors_and_offsets_preset(PRESET_HCENTER_WIDE);
} break;
- case ANCHORS_AND_OFFSETS_PRESET_WIDE: {
- _set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ case ANCHORS_AND_OFFSETS_PRESET_FULL_RECT: {
+ _set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
} break;
case ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO: {
_set_anchors_and_offsets_to_keep_ratio();
@@ -741,8 +735,8 @@ void ControlEditorToolbar::_popup_callback(int p_op) {
case ANCHORS_PRESET_HCENTER_WIDE: {
_set_anchors_preset(PRESET_HCENTER_WIDE);
} break;
- case ANCHORS_PRESET_WIDE: {
- _set_anchors_preset(Control::PRESET_WIDE);
+ case ANCHORS_PRESET_FULL_RECT: {
+ _set_anchors_preset(Control::PRESET_FULL_RECT);
} break;
case CONTAINERS_H_PRESET_FILL: {
@@ -840,7 +834,7 @@ void ControlEditorToolbar::_notification(int p_what) {
p->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("VCenter Wide"), ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE);
p->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("HCenter Wide"), ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE);
p->add_separator();
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignWide"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_AND_OFFSETS_PRESET_WIDE);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignFullRect"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_AND_OFFSETS_PRESET_FULL_RECT);
p->add_icon_item(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")), TTR("Keep Current Ratio"), ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO);
p->set_item_tooltip(19, TTR("Adjust anchors and offsets to match the current rect size."));
@@ -867,7 +861,7 @@ void ControlEditorToolbar::_notification(int p_what) {
anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("VCenter Wide"), ANCHORS_PRESET_VCENTER_WIDE);
anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("HCenter Wide"), ANCHORS_PRESET_HCENTER_WIDE);
anchors_popup->add_separator();
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignWide"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_PRESET_WIDE);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignFullRect"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_PRESET_FULL_RECT);
anchor_mode_button->set_icon(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")));
diff --git a/editor/plugins/control_editor_plugin.h b/editor/plugins/control_editor_plugin.h
index 96451f7dcf..d3f1d3acbb 100644
--- a/editor/plugins/control_editor_plugin.h
+++ b/editor/plugins/control_editor_plugin.h
@@ -147,7 +147,7 @@ class ControlEditorToolbar : public HBoxContainer {
ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE,
ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE,
ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE,
- ANCHORS_AND_OFFSETS_PRESET_WIDE,
+ ANCHORS_AND_OFFSETS_PRESET_FULL_RECT,
ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO,
@@ -166,7 +166,7 @@ class ControlEditorToolbar : public HBoxContainer {
ANCHORS_PRESET_BOTTOM_WIDE,
ANCHORS_PRESET_VCENTER_WIDE,
ANCHORS_PRESET_HCENTER_WIDE,
- ANCHORS_PRESET_WIDE,
+ ANCHORS_PRESET_FULL_RECT,
// Offsets Presets are not currently in use.
OFFSETS_PRESET_TOP_LEFT,
@@ -184,7 +184,7 @@ class ControlEditorToolbar : public HBoxContainer {
OFFSETS_PRESET_BOTTOM_WIDE,
OFFSETS_PRESET_VCENTER_WIDE,
OFFSETS_PRESET_HCENTER_WIDE,
- OFFSETS_PRESET_WIDE,
+ OFFSETS_PRESET_FULL_RECT,
CONTAINERS_H_PRESET_FILL,
CONTAINERS_H_PRESET_FILL_EXPAND,
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index 79025041d3..a7c3c32120 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -257,7 +257,7 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin() {
List<String> ext;
ImageLoader::get_recognized_extensions(&ext);
for (const String &E : ext) {
- file->add_filter("*." + E + "; " + E.to_upper());
+ file->add_filter("*." + E, E.to_upper());
}
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
toolbar->add_child(file);
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 6d1a86765a..66e58339ed 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -751,12 +751,13 @@ void CurveEditor::_draw() {
// Help text
+ float width = view_size.x - 60 * EDSCALE;
if (_selected_point > 0 && _selected_point + 1 < curve.get_point_count()) {
text_color.a *= 0.4;
- draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HORIZONTAL_ALIGNMENT_LEFT, width, -1, font_size, text_color);
} else if (curve.get_point_count() == 0) {
text_color.a *= 0.4;
- draw_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color);
+ draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HORIZONTAL_ALIGNMENT_LEFT, width, -1, font_size, text_color);
}
}
@@ -840,9 +841,5 @@ Ref<Texture2D> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, cons
prev_y = y;
}
-
- Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
-
- ptex->create_from_image(img_ref);
- return ptex;
+ return ImageTexture::create_from_image(img_ref);
}
diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp
index 8ea50c4529..5c90d70982 100644
--- a/editor/plugins/debugger_editor_plugin.cpp
+++ b/editor/plugins/debugger_editor_plugin.cpp
@@ -72,6 +72,9 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(MenuButton *p_debug_menu) {
p->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISONS);
p->set_item_tooltip(-1,
TTR("When this option is enabled, collision shapes and raycast nodes (for 2D and 3D) will be visible in the running project."));
+ p->add_check_shortcut(ED_SHORTCUT("editor/visible_paths", TTR("Visible Paths")), RUN_DEBUG_PATHS);
+ p->set_item_tooltip(-1,
+ TTR("When this option is enabled, curve resources used by path nodes will be visible in the running project."));
p->add_check_shortcut(ED_SHORTCUT("editor/visible_navigation", TTR("Visible Navigation")), RUN_DEBUG_NAVIGATION);
p->set_item_tooltip(-1,
TTR("When this option is enabled, navigation meshes and polygons will be visible in the running project."));
@@ -153,6 +156,12 @@ void DebuggerEditorPlugin::_menu_option(int p_option) {
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_collisons", !ischecked);
} break;
+ case RUN_DEBUG_PATHS: {
+ bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_PATHS));
+ debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_PATHS), !ischecked);
+ EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_paths", !ischecked);
+
+ } break;
case RUN_DEBUG_NAVIGATION: {
bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION));
debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION), !ischecked);
@@ -182,6 +191,7 @@ void DebuggerEditorPlugin::_update_debug_options() {
bool check_deploy_remote = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_deploy_remote_debug", false);
bool check_file_server = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_file_server", false);
bool check_debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisons", false);
+ bool check_debug_paths = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_paths", false);
bool check_debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false);
bool check_live_debug = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_live_debug", true);
bool check_reload_scripts = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_reload_scripts", true);
@@ -196,6 +206,9 @@ void DebuggerEditorPlugin::_update_debug_options() {
if (check_debug_collisions) {
_menu_option(RUN_DEBUG_COLLISONS);
}
+ if (check_debug_paths) {
+ _menu_option(RUN_DEBUG_PATHS);
+ }
if (check_debug_navigation) {
_menu_option(RUN_DEBUG_NAVIGATION);
}
diff --git a/editor/plugins/debugger_editor_plugin.h b/editor/plugins/debugger_editor_plugin.h
index 10e1a27933..fb963385cd 100644
--- a/editor/plugins/debugger_editor_plugin.h
+++ b/editor/plugins/debugger_editor_plugin.h
@@ -49,6 +49,7 @@ private:
RUN_FILE_SERVER,
RUN_LIVE_DEBUG,
RUN_DEBUG_COLLISONS,
+ RUN_DEBUG_PATHS,
RUN_DEBUG_NAVIGATION,
RUN_DEPLOY_REMOTE_DEBUG,
RUN_RELOAD_SCRIPTS,
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index bb0cfcba25..478f4264e5 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -127,13 +127,9 @@ Ref<Texture2D> EditorTexturePreviewPlugin::generate(const Ref<Resource> &p_from,
}
Vector2i new_size_i(MAX(1, (int)new_size.x), MAX(1, (int)new_size.y));
img->resize(new_size_i.x, new_size_i.y, Image::INTERPOLATE_CUBIC);
-
post_process_preview(img);
- Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
-
- ptex->create_from_image(img);
- return ptex;
+ return ImageTexture::create_from_image(img);
}
EditorTexturePreviewPlugin::EditorTexturePreviewPlugin() {
@@ -171,14 +167,9 @@ Ref<Texture2D> EditorImagePreviewPlugin::generate(const Ref<Resource> &p_from, c
new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
}
img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
-
post_process_preview(img);
- Ref<ImageTexture> ptex;
- ptex.instantiate();
-
- ptex->create_from_image(img);
- return ptex;
+ return ImageTexture::create_from_image(img);
}
EditorImagePreviewPlugin::EditorImagePreviewPlugin() {
@@ -239,13 +230,9 @@ Ref<Texture2D> EditorBitmapPreviewPlugin::generate(const Ref<Resource> &p_from,
new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
}
img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
-
post_process_preview(img);
- Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
-
- ptex->create_from_image(img);
- return ptex;
+ return ImageTexture::create_from_image(img);
}
bool EditorBitmapPreviewPlugin::generate_small_preview_automatically() const {
@@ -282,11 +269,8 @@ Ref<Texture2D> EditorPackedScenePreviewPlugin::generate_from_path(const String &
img.instantiate();
Error err = img->load(path);
if (err == OK) {
- Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
-
post_process_preview(img);
- ptex->create_from_image(img);
- return ptex;
+ return ImageTexture::create_from_image(img);
} else {
return Ref<Texture2D>();
@@ -336,9 +320,7 @@ Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const Ref<Resource> &p_from
int thumbnail_size = MAX(p_size.x, p_size.y);
img->resize(thumbnail_size, thumbnail_size, Image::INTERPOLATE_CUBIC);
post_process_preview(img);
- Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
- ptex->create_from_image(img);
- return ptex;
+ return ImageTexture::create_from_image(img);
}
return Ref<Texture2D>();
@@ -591,13 +573,8 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from,
}
}
}
-
post_process_preview(img);
-
- Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
-
- ptex->create_from_image(img);
- return ptex;
+ return ImageTexture::create_from_image(img);
}
EditorScriptPreviewPlugin::EditorScriptPreviewPlugin() {
@@ -676,12 +653,10 @@ Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const Ref<Resource> &p_f
//post_process_preview(img);
- Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
Ref<Image> image;
image.instantiate();
image->create(w, h, false, Image::FORMAT_RGB8, img);
- ptex->create_from_image(image);
- return ptex;
+ return ImageTexture::create_from_image(image);
}
EditorAudioStreamPreviewPlugin::EditorAudioStreamPreviewPlugin() {
@@ -746,12 +721,9 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const Ref<Resource> &p_from, co
new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
}
img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
-
post_process_preview(img);
- Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
- ptex->create_from_image(img);
- return ptex;
+ return ImageTexture::create_from_image(img);
}
EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() {
@@ -812,19 +784,12 @@ void EditorFontPreviewPlugin::_preview_done() {
}
bool EditorFontPreviewPlugin::handles(const String &p_type) const {
- return ClassDB::is_parent_class(p_type, "FontData") || ClassDB::is_parent_class(p_type, "Font");
+ return ClassDB::is_parent_class(p_type, "Font");
}
Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const {
- Ref<Resource> res = ResourceLoader::load(p_path);
- ERR_FAIL_COND_V(res.is_null(), Ref<Texture2D>());
- Ref<Font> sampled_font;
- if (res->is_class("Font")) {
- sampled_font = res->duplicate();
- } else if (res->is_class("FontData")) {
- sampled_font.instantiate();
- sampled_font->add_data(res->duplicate());
- }
+ Ref<Font> sampled_font = ResourceLoader::load(p_path);
+ ERR_FAIL_COND_V(sampled_font.is_null(), Ref<Texture2D>());
String sample;
static const String sample_base = U"12漢字ԱբΑαÐбΑα×בابÜÜ’Þ€Þआআਆઆଆஆఆಆആආà¸à¸´àºàº´à¼€á€€á‚ áƒí•œê¸€áˆ€áŽ£áášáš áœ€áœ á€á áž€á  á¤á¥Ab😀";
@@ -836,18 +801,16 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path,
if (sample.is_empty()) {
sample = sampled_font->get_supported_chars().substr(0, 6);
}
- Vector2 size = sampled_font->get_string_size(sample, 50);
+ Vector2 size = sampled_font->get_string_size(sample, HORIZONTAL_ALIGNMENT_LEFT, -1, 50);
Vector2 pos;
pos.x = 64 - size.x / 2;
pos.y = 80;
- Ref<Font> font = sampled_font;
-
const Color c = GLOBAL_GET("rendering/environment/defaults/default_clear_color");
const float fg = c.get_luminance() < 0.5 ? 1.0 : 0.0;
- font->draw_string(canvas_item, pos, sample, HORIZONTAL_ALIGNMENT_LEFT, -1.f, 50, Color(fg, fg, fg));
+ sampled_font->draw_string(canvas_item, pos, sample, HORIZONTAL_ALIGNMENT_LEFT, -1.f, 50, Color(fg, fg, fg));
RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
@@ -868,13 +831,9 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path,
new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
}
img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
-
post_process_preview(img);
- Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
- ptex->create_from_image(img);
-
- return ptex;
+ return ImageTexture::create_from_image(img);
}
Ref<Texture2D> EditorFontPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size) const {
@@ -924,11 +883,7 @@ Ref<Texture2D> EditorGradientPreviewPlugin::generate(const Ref<Resource> &p_from
ptex.instantiate();
ptex->set_width(p_size.width * GRADIENT_PREVIEW_TEXTURE_SCALE_FACTOR * EDSCALE);
ptex->set_gradient(gradient);
-
- Ref<ImageTexture> itex;
- itex.instantiate();
- itex->create_from_image(ptex->get_image());
- return itex;
+ return ImageTexture::create_from_image(ptex->get_image());
}
return Ref<Texture2D>();
}
diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp
new file mode 100644
index 0000000000..848fb5887d
--- /dev/null
+++ b/editor/plugins/font_config_plugin.cpp
@@ -0,0 +1,979 @@
+/*************************************************************************/
+/* font_config_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "font_config_plugin.h"
+
+#include "editor/editor_scale.h"
+#include "editor/import/dynamic_font_import_settings.h"
+
+/*************************************************************************/
+/* EditorPropertyFontMetaObject */
+/*************************************************************************/
+
+bool EditorPropertyFontMetaObject::_set(const StringName &p_name, const Variant &p_value) {
+ String name = p_name;
+
+ if (name.begins_with("keys")) {
+ String key = name.get_slicec('/', 1);
+ dict[key] = p_value;
+ return true;
+ }
+
+ return false;
+}
+
+bool EditorPropertyFontMetaObject::_get(const StringName &p_name, Variant &r_ret) const {
+ String name = p_name;
+
+ if (name.begins_with("keys")) {
+ String key = name.get_slicec('/', 1);
+ r_ret = dict[key];
+ return true;
+ }
+
+ return false;
+}
+
+void EditorPropertyFontMetaObject::_bind_methods() {
+}
+
+void EditorPropertyFontMetaObject::set_dict(const Dictionary &p_dict) {
+ dict = p_dict;
+}
+
+Dictionary EditorPropertyFontMetaObject::get_dict() {
+ return dict;
+}
+
+/*************************************************************************/
+/* EditorPropertyFontOTObject */
+/*************************************************************************/
+
+bool EditorPropertyFontOTObject::_set(const StringName &p_name, const Variant &p_value) {
+ String name = p_name;
+
+ if (name.begins_with("keys")) {
+ int key = name.get_slicec('/', 1).to_int();
+ dict[key] = p_value;
+ return true;
+ }
+
+ return false;
+}
+
+bool EditorPropertyFontOTObject::_get(const StringName &p_name, Variant &r_ret) const {
+ String name = p_name;
+
+ if (name.begins_with("keys")) {
+ int key = name.get_slicec('/', 1).to_int();
+ r_ret = dict[key];
+ return true;
+ }
+
+ return false;
+}
+
+void EditorPropertyFontOTObject::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &EditorPropertyFontOTObject::property_can_revert);
+ ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &EditorPropertyFontOTObject::property_get_revert);
+}
+
+void EditorPropertyFontOTObject::set_dict(const Dictionary &p_dict) {
+ dict = p_dict;
+}
+
+Dictionary EditorPropertyFontOTObject::get_dict() {
+ return dict;
+}
+
+void EditorPropertyFontOTObject::set_defaults(const Dictionary &p_dict) {
+ defaults_dict = p_dict;
+}
+
+Dictionary EditorPropertyFontOTObject::get_defaults() {
+ return defaults_dict;
+}
+
+bool EditorPropertyFontOTObject::property_can_revert(const String &p_name) {
+ String name = p_name;
+
+ if (name.begins_with("keys")) {
+ int key = name.get_slicec('/', 1).to_int();
+ if (defaults_dict.has(key) && dict.has(key)) {
+ int value = dict[key];
+ Vector3i range = defaults_dict[key];
+ return range.z != value;
+ }
+ }
+
+ return false;
+}
+
+Variant EditorPropertyFontOTObject::property_get_revert(const String &p_name) {
+ String name = p_name;
+
+ if (name.begins_with("keys")) {
+ int key = name.get_slicec('/', 1).to_int();
+ if (defaults_dict.has(key)) {
+ Vector3i range = defaults_dict[key];
+ return range.z;
+ }
+ }
+
+ return Variant();
+}
+
+/*************************************************************************/
+/* EditorPropertyFontMetaOverride */
+/*************************************************************************/
+
+void EditorPropertyFontMetaOverride::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ if (Object::cast_to<Button>(button_add)) {
+ button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ }
+ } break;
+ }
+}
+
+void EditorPropertyFontMetaOverride::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
+ if (p_property.begins_with("keys")) {
+ Dictionary dict = object->get_dict();
+ String key = p_property.get_slice("/", 1);
+ dict[key] = (bool)p_value;
+
+ emit_changed(get_edited_property(), dict, "", true);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ }
+}
+
+void EditorPropertyFontMetaOverride::_remove(Object *p_button, const String &p_key) {
+ Dictionary dict = object->get_dict();
+
+ dict.erase(p_key);
+
+ emit_changed(get_edited_property(), dict, "", false);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ update_property();
+}
+
+void EditorPropertyFontMetaOverride::_add_menu() {
+ if (script_editor) {
+ Size2 size = get_size();
+ menu->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y));
+ menu->reset_size();
+ menu->popup();
+ } else {
+ locale_select->popup_locale_dialog();
+ }
+}
+
+void EditorPropertyFontMetaOverride::_add_script(int p_option) {
+ Dictionary dict = object->get_dict();
+
+ dict[script_codes[p_option]] = true;
+
+ emit_changed(get_edited_property(), dict, "", false);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ update_property();
+}
+
+void EditorPropertyFontMetaOverride::_add_lang(const String &p_locale) {
+ Dictionary dict = object->get_dict();
+
+ dict[p_locale] = true;
+
+ emit_changed(get_edited_property(), dict, "", false);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ update_property();
+}
+
+void EditorPropertyFontMetaOverride::_object_id_selected(const StringName &p_property, ObjectID p_id) {
+ emit_signal(SNAME("object_id_selected"), p_property, p_id);
+}
+
+void EditorPropertyFontMetaOverride::update_property() {
+ Variant updated_val = get_edited_object()->get(get_edited_property());
+
+ Dictionary dict = updated_val;
+
+ edit->set_text(vformat(TTR("Overrides (%d)"), dict.size()));
+
+ bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
+ if (edit->is_pressed() != unfolded) {
+ edit->set_pressed(unfolded);
+ }
+
+ if (unfolded) {
+ updating = true;
+
+ if (!container) {
+ container = memnew(MarginContainer);
+ container->set_theme_type_variation("MarginContainer4px");
+ add_child(container);
+ set_bottom_editor(container);
+
+ VBoxContainer *vbox = memnew(VBoxContainer);
+ vbox->set_v_size_flags(SIZE_EXPAND_FILL);
+ container->add_child(vbox);
+
+ property_vbox = memnew(VBoxContainer);
+ property_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
+ vbox->add_child(property_vbox);
+
+ paginator = memnew(EditorPaginator);
+ paginator->connect("page_changed", callable_mp(this, &EditorPropertyFontMetaOverride::_page_changed));
+ vbox->add_child(paginator);
+ } else {
+ // Queue children for deletion, deleting immediately might cause errors.
+ for (int i = property_vbox->get_child_count() - 1; i >= 0; i--) {
+ property_vbox->get_child(i)->queue_delete();
+ }
+ button_add = nullptr;
+ }
+
+ int size = dict.size();
+
+ int max_page = MAX(0, size - 1) / page_length;
+ page_index = MIN(page_index, max_page);
+
+ paginator->update(page_index, max_page);
+ paginator->set_visible(max_page > 0);
+
+ int offset = page_index * page_length;
+
+ int amount = MIN(size - offset, page_length);
+
+ dict = dict.duplicate();
+ object->set_dict(dict);
+
+ for (int i = 0; i < amount; i++) {
+ String name = dict.get_key_at_index(i);
+ EditorProperty *prop = memnew(EditorPropertyCheck);
+ prop->set_object_and_property(object.ptr(), "keys/" + name);
+
+ if (script_editor) {
+ prop->set_label(TranslationServer::get_singleton()->get_script_name(name));
+ } else {
+ prop->set_label(TranslationServer::get_singleton()->get_locale_name(name));
+ }
+ prop->set_tooltip(name);
+ prop->set_selectable(false);
+
+ prop->connect("property_changed", callable_mp(this, &EditorPropertyFontMetaOverride::_property_changed));
+ prop->connect("object_id_selected", callable_mp(this, &EditorPropertyFontMetaOverride::_object_id_selected));
+
+ HBoxContainer *hbox = memnew(HBoxContainer);
+ property_vbox->add_child(hbox);
+ hbox->add_child(prop);
+ prop->set_h_size_flags(SIZE_EXPAND_FILL);
+ Button *remove = memnew(Button);
+ remove->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ hbox->add_child(remove);
+ remove->connect("pressed", callable_mp(this, &EditorPropertyFontMetaOverride::_remove), varray(remove, name));
+
+ prop->update_property();
+ }
+
+ if (script_editor) {
+ button_add = EditorInspector::create_inspector_action_button(TTR("Add Script"));
+ } else {
+ button_add = EditorInspector::create_inspector_action_button(TTR("Add Locale"));
+ }
+ button_add->connect("pressed", callable_mp(this, &EditorPropertyFontMetaOverride::_add_menu));
+ property_vbox->add_child(button_add);
+
+ updating = false;
+ } else {
+ if (container) {
+ set_bottom_editor(nullptr);
+ memdelete(container);
+ button_add = nullptr;
+ container = nullptr;
+ }
+ }
+}
+
+void EditorPropertyFontMetaOverride::_edit_pressed() {
+ Variant prop_val = get_edited_object()->get(get_edited_property());
+ if (prop_val.get_type() == Variant::NIL) {
+ Callable::CallError ce;
+ Variant::construct(Variant::DICTIONARY, prop_val, nullptr, 0, ce);
+ get_edited_object()->set(get_edited_property(), prop_val);
+ }
+
+ get_edited_object()->editor_set_section_unfold(get_edited_property(), edit->is_pressed());
+ update_property();
+}
+
+void EditorPropertyFontMetaOverride::_page_changed(int p_page) {
+ if (updating) {
+ return;
+ }
+ page_index = p_page;
+ update_property();
+}
+
+EditorPropertyFontMetaOverride::EditorPropertyFontMetaOverride(bool p_script) {
+ script_editor = p_script;
+
+ object.instantiate();
+ page_length = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
+
+ edit = memnew(Button);
+ edit->set_h_size_flags(SIZE_EXPAND_FILL);
+ edit->set_clip_text(true);
+ edit->connect("pressed", callable_mp(this, &EditorPropertyFontMetaOverride::_edit_pressed));
+ edit->set_toggle_mode(true);
+ add_child(edit);
+ add_focusable(edit);
+
+ menu = memnew(PopupMenu);
+ if (script_editor) {
+ script_codes = TranslationServer::get_singleton()->get_all_scripts();
+ for (int i = 0; i < script_codes.size(); i++) {
+ menu->add_item(TranslationServer::get_singleton()->get_script_name(script_codes[i]) + " (" + script_codes[i] + ")", i);
+ }
+ }
+ add_child(menu);
+ menu->connect("id_pressed", callable_mp(this, &EditorPropertyFontMetaOverride::_add_script));
+
+ locale_select = memnew(EditorLocaleDialog);
+ locale_select->connect("locale_selected", callable_mp(this, &EditorPropertyFontMetaOverride::_add_lang));
+ add_child(locale_select);
+}
+
+/*************************************************************************/
+/* EditorPropertyOTVariation */
+/*************************************************************************/
+
+void EditorPropertyOTVariation::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ } break;
+ }
+}
+
+void EditorPropertyOTVariation::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
+ if (p_property.begins_with("keys")) {
+ Dictionary dict = object->get_dict();
+ Dictionary defaults_dict = object->get_defaults();
+ int key = p_property.get_slice("/", 1).to_int();
+ dict[key] = (int)p_value;
+ if (defaults_dict.has(key)) {
+ Vector3i range = defaults_dict[key];
+ if (range.z == (int)p_value) {
+ dict.erase(key);
+ }
+ }
+
+ emit_changed(get_edited_property(), dict, "", true);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ }
+}
+
+void EditorPropertyOTVariation::_object_id_selected(const StringName &p_property, ObjectID p_id) {
+ emit_signal(SNAME("object_id_selected"), p_property, p_id);
+}
+
+void EditorPropertyOTVariation::update_property() {
+ Variant updated_val = get_edited_object()->get(get_edited_property());
+
+ Dictionary dict = updated_val;
+
+ Ref<Font> fd;
+ if (Object::cast_to<Font>(get_edited_object()) != nullptr) {
+ fd = get_edited_object();
+ } else if (Object::cast_to<DynamicFontImportSettingsData>(get_edited_object()) != nullptr) {
+ Ref<DynamicFontImportSettingsData> imp = Object::cast_to<DynamicFontImportSettingsData>(get_edited_object());
+ fd = imp->get_font();
+ }
+
+ Dictionary supported = (fd.is_valid()) ? fd->get_supported_variation_list() : Dictionary();
+
+ edit->set_text(vformat(TTR("Variation Coordinates (%d)"), supported.size()));
+
+ bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
+ if (edit->is_pressed() != unfolded) {
+ edit->set_pressed(unfolded);
+ }
+
+ if (unfolded) {
+ updating = true;
+
+ if (!container) {
+ container = memnew(MarginContainer);
+ container->set_theme_type_variation("MarginContainer4px");
+ add_child(container);
+ set_bottom_editor(container);
+
+ VBoxContainer *vbox = memnew(VBoxContainer);
+ vbox->set_v_size_flags(SIZE_EXPAND_FILL);
+ container->add_child(vbox);
+
+ property_vbox = memnew(VBoxContainer);
+ property_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
+ vbox->add_child(property_vbox);
+
+ paginator = memnew(EditorPaginator);
+ paginator->connect("page_changed", callable_mp(this, &EditorPropertyOTVariation::_page_changed));
+ vbox->add_child(paginator);
+ } else {
+ // Queue children for deletion, deleting immediately might cause errors.
+ for (int i = property_vbox->get_child_count() - 1; i >= 0; i--) {
+ property_vbox->get_child(i)->queue_delete();
+ }
+ }
+
+ int size = supported.size();
+
+ int max_page = MAX(0, size - 1) / page_length;
+ page_index = MIN(page_index, max_page);
+
+ paginator->update(page_index, max_page);
+ paginator->set_visible(max_page > 0);
+
+ int offset = page_index * page_length;
+
+ int amount = MIN(size - offset, page_length);
+
+ dict = dict.duplicate();
+ object->set_dict(dict);
+ object->set_defaults(supported);
+
+ for (int i = 0; i < amount; i++) {
+ int name_tag = supported.get_key_at_index(i);
+ Vector3i range = supported.get_value_at_index(i);
+
+ EditorPropertyInteger *prop = memnew(EditorPropertyInteger);
+ prop->setup(range.x, range.y, 1, false, false);
+ prop->set_object_and_property(object.ptr(), "keys/" + itos(name_tag));
+
+ String name = TS->tag_to_name(name_tag);
+ prop->set_label(name.capitalize());
+ prop->set_tooltip(name);
+ prop->set_selectable(false);
+
+ prop->connect("property_changed", callable_mp(this, &EditorPropertyOTVariation::_property_changed));
+ prop->connect("object_id_selected", callable_mp(this, &EditorPropertyOTVariation::_object_id_selected));
+
+ property_vbox->add_child(prop);
+
+ prop->update_property();
+ }
+
+ updating = false;
+ } else {
+ if (container) {
+ set_bottom_editor(nullptr);
+ memdelete(container);
+ container = nullptr;
+ }
+ }
+}
+
+void EditorPropertyOTVariation::_edit_pressed() {
+ Variant prop_val = get_edited_object()->get(get_edited_property());
+ if (prop_val.get_type() == Variant::NIL) {
+ Callable::CallError ce;
+ Variant::construct(Variant::DICTIONARY, prop_val, nullptr, 0, ce);
+ get_edited_object()->set(get_edited_property(), prop_val);
+ }
+
+ get_edited_object()->editor_set_section_unfold(get_edited_property(), edit->is_pressed());
+ update_property();
+}
+
+void EditorPropertyOTVariation::_page_changed(int p_page) {
+ if (updating) {
+ return;
+ }
+ page_index = p_page;
+ update_property();
+}
+
+EditorPropertyOTVariation::EditorPropertyOTVariation() {
+ object.instantiate();
+ page_length = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
+
+ edit = memnew(Button);
+ edit->set_h_size_flags(SIZE_EXPAND_FILL);
+ edit->set_clip_text(true);
+ edit->connect("pressed", callable_mp(this, &EditorPropertyOTVariation::_edit_pressed));
+ edit->set_toggle_mode(true);
+ add_child(edit);
+ add_focusable(edit);
+}
+
+/*************************************************************************/
+/* EditorPropertyOTFeatures */
+/*************************************************************************/
+
+void EditorPropertyOTFeatures::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ if (Object::cast_to<Button>(button_add)) {
+ button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ }
+ } break;
+ }
+}
+
+void EditorPropertyOTFeatures::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
+ if (p_property.begins_with("keys")) {
+ Dictionary dict = object->get_dict();
+ int key = p_property.get_slice("/", 1).to_int();
+ dict[key] = (int)p_value;
+
+ emit_changed(get_edited_property(), dict, "", true);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ }
+}
+
+void EditorPropertyOTFeatures::_remove(Object *p_button, int p_key) {
+ Dictionary dict = object->get_dict();
+
+ dict.erase(p_key);
+
+ emit_changed(get_edited_property(), dict, "", false);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ update_property();
+}
+
+void EditorPropertyOTFeatures::_add_menu() {
+ Size2 size = get_size();
+ menu->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y));
+ menu->reset_size();
+ menu->popup();
+}
+
+void EditorPropertyOTFeatures::_add_feature(int p_option) {
+ Dictionary dict = object->get_dict();
+
+ dict[p_option] = 1;
+
+ emit_changed(get_edited_property(), dict, "", false);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ update_property();
+}
+
+void EditorPropertyOTFeatures::_object_id_selected(const StringName &p_property, ObjectID p_id) {
+ emit_signal(SNAME("object_id_selected"), p_property, p_id);
+}
+
+void EditorPropertyOTFeatures::update_property() {
+ Variant updated_val = get_edited_object()->get(get_edited_property());
+
+ Dictionary dict = updated_val;
+
+ Ref<Font> fd;
+ if (Object::cast_to<FontVariation>(get_edited_object()) != nullptr) {
+ fd = get_edited_object();
+ } else if (Object::cast_to<DynamicFontImportSettingsData>(get_edited_object()) != nullptr) {
+ Ref<DynamicFontImportSettingsData> imp = Object::cast_to<DynamicFontImportSettingsData>(get_edited_object());
+ fd = imp->get_font();
+ }
+
+ Dictionary supported;
+ if (fd.is_valid()) {
+ supported = fd->get_supported_feature_list();
+ }
+
+ edit->set_text(vformat(TTR("Features (%d of %d set)"), dict.size(), supported.size()));
+
+ bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
+ if (edit->is_pressed() != unfolded) {
+ edit->set_pressed(unfolded);
+ }
+
+ if (unfolded) {
+ updating = true;
+
+ if (!container) {
+ container = memnew(MarginContainer);
+ container->set_theme_type_variation("MarginContainer4px");
+ add_child(container);
+ set_bottom_editor(container);
+
+ VBoxContainer *vbox = memnew(VBoxContainer);
+ vbox->set_v_size_flags(SIZE_EXPAND_FILL);
+ container->add_child(vbox);
+
+ property_vbox = memnew(VBoxContainer);
+ property_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
+ vbox->add_child(property_vbox);
+
+ paginator = memnew(EditorPaginator);
+ paginator->connect("page_changed", callable_mp(this, &EditorPropertyOTFeatures::_page_changed));
+ vbox->add_child(paginator);
+ } else {
+ // Queue children for deletion, deleting immediately might cause errors.
+ for (int i = property_vbox->get_child_count() - 1; i >= 0; i--) {
+ property_vbox->get_child(i)->queue_delete();
+ }
+ button_add = nullptr;
+ }
+
+ // Update add menu items.
+ menu->clear();
+ bool have_sub[FGRP_MAX];
+ for (int i = 0; i < FGRP_MAX; i++) {
+ menu_sub[i]->clear();
+ have_sub[i] = false;
+ }
+
+ bool show_hidden = EDITOR_GET("interface/inspector/show_low_level_opentype_features");
+
+ for (int i = 0; i < supported.size(); i++) {
+ int name_tag = supported.get_key_at_index(i);
+ Dictionary info = supported.get_value_at_index(i);
+ bool hidden = info["hidden"].operator bool();
+ String name = TS->tag_to_name(name_tag);
+ FeatureGroups grp = FGRP_MAX;
+
+ if (hidden && !show_hidden) {
+ continue;
+ }
+
+ if (name.begins_with("stylistic_set_")) {
+ grp = FGRP_STYLISTIC_SET;
+ } else if (name.begins_with("character_variant_")) {
+ grp = FGRP_CHARACTER_VARIANT;
+ } else if (name.ends_with("_capitals")) {
+ grp = FGRP_CAPITLS;
+ } else if (name.ends_with("_ligatures")) {
+ grp = FGRP_LIGATURES;
+ } else if (name.ends_with("_alternates")) {
+ grp = FGRP_ALTERNATES;
+ } else if (name.ends_with("_kanji_forms") || name.begins_with("jis") || name == "simplified_forms" || name == "traditional_name_forms" || name == "traditional_forms") {
+ grp = FGRP_EAL;
+ } else if (name.ends_with("_widths")) {
+ grp = FGRP_EAW;
+ } else if (name == "tabular_figures" || name == "proportional_figures") {
+ grp = FGRP_NUMAL;
+ } else if (name.begins_with("custom_")) {
+ grp = FGRP_CUSTOM;
+ }
+ String disp_name = name.capitalize();
+ if (info.has("label")) {
+ disp_name = vformat("%s (%s)", disp_name, info["label"].operator String());
+ }
+
+ if (grp == FGRP_MAX) {
+ menu->add_item(disp_name, name_tag);
+ } else {
+ menu_sub[grp]->add_item(disp_name, name_tag);
+ have_sub[grp] = true;
+ }
+ }
+ for (int i = 0; i < FGRP_MAX; i++) {
+ if (have_sub[i]) {
+ menu->add_submenu_item(RTR(group_names[i]), "FTRMenu_" + itos(i));
+ }
+ }
+
+ int size = dict.size();
+
+ int max_page = MAX(0, size - 1) / page_length;
+ page_index = MIN(page_index, max_page);
+
+ paginator->update(page_index, max_page);
+ paginator->set_visible(max_page > 0);
+
+ int offset = page_index * page_length;
+
+ int amount = MIN(size - offset, page_length);
+
+ dict = dict.duplicate();
+ object->set_dict(dict);
+
+ for (int i = 0; i < amount; i++) {
+ int name_tag = dict.get_key_at_index(i);
+
+ if (supported.has(name_tag)) {
+ Dictionary info = supported[name_tag];
+ Variant::Type vtype = Variant::Type(info["type"].operator int());
+ bool hidden = info["hidden"].operator bool();
+ if (hidden && !show_hidden) {
+ continue;
+ }
+
+ EditorProperty *prop = nullptr;
+ switch (vtype) {
+ case Variant::NIL: {
+ prop = memnew(EditorPropertyNil);
+ } break;
+ case Variant::BOOL: {
+ prop = memnew(EditorPropertyCheck);
+ } break;
+ case Variant::INT: {
+ EditorPropertyInteger *editor = memnew(EditorPropertyInteger);
+ editor->setup(0, 255, 1, false, false);
+ prop = editor;
+ } break;
+ default: {
+ ERR_CONTINUE_MSG(true, vformat("Unsupported OT feature data type %s", Variant::get_type_name(vtype)));
+ }
+ }
+ prop->set_object_and_property(object.ptr(), "keys/" + itos(name_tag));
+
+ String name = TS->tag_to_name(name_tag);
+ String disp_name = name.capitalize();
+ if (info.has("label")) {
+ disp_name = vformat("%s (%s)", disp_name, info["label"].operator String());
+ }
+ prop->set_label(disp_name);
+ prop->set_tooltip(name);
+ prop->set_selectable(false);
+
+ prop->connect("property_changed", callable_mp(this, &EditorPropertyOTFeatures::_property_changed));
+ prop->connect("object_id_selected", callable_mp(this, &EditorPropertyOTFeatures::_object_id_selected));
+
+ HBoxContainer *hbox = memnew(HBoxContainer);
+ property_vbox->add_child(hbox);
+ hbox->add_child(prop);
+ prop->set_h_size_flags(SIZE_EXPAND_FILL);
+ Button *remove = memnew(Button);
+ remove->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ hbox->add_child(remove);
+ remove->connect("pressed", callable_mp(this, &EditorPropertyOTFeatures::_remove), varray(remove, name_tag));
+
+ prop->update_property();
+ }
+ }
+
+ button_add = EditorInspector::create_inspector_action_button(TTR("Add Feature"));
+ button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add->connect("pressed", callable_mp(this, &EditorPropertyOTFeatures::_add_menu));
+ property_vbox->add_child(button_add);
+
+ updating = false;
+ } else {
+ if (container) {
+ set_bottom_editor(nullptr);
+ memdelete(container);
+ button_add = nullptr;
+ container = nullptr;
+ }
+ }
+}
+
+void EditorPropertyOTFeatures::_edit_pressed() {
+ Variant prop_val = get_edited_object()->get(get_edited_property());
+ if (prop_val.get_type() == Variant::NIL) {
+ Callable::CallError ce;
+ Variant::construct(Variant::DICTIONARY, prop_val, nullptr, 0, ce);
+ get_edited_object()->set(get_edited_property(), prop_val);
+ }
+
+ get_edited_object()->editor_set_section_unfold(get_edited_property(), edit->is_pressed());
+ update_property();
+}
+
+void EditorPropertyOTFeatures::_page_changed(int p_page) {
+ if (updating) {
+ return;
+ }
+ page_index = p_page;
+ update_property();
+}
+
+EditorPropertyOTFeatures::EditorPropertyOTFeatures() {
+ object.instantiate();
+ page_length = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
+
+ edit = memnew(Button);
+ edit->set_h_size_flags(SIZE_EXPAND_FILL);
+ edit->set_clip_text(true);
+ edit->connect("pressed", callable_mp(this, &EditorPropertyOTFeatures::_edit_pressed));
+ edit->set_toggle_mode(true);
+ add_child(edit);
+ add_focusable(edit);
+
+ menu = memnew(PopupMenu);
+ add_child(menu);
+ menu->connect("id_pressed", callable_mp(this, &EditorPropertyOTFeatures::_add_feature));
+
+ for (int i = 0; i < FGRP_MAX; i++) {
+ menu_sub[i] = memnew(PopupMenu);
+ menu_sub[i]->set_name("FTRMenu_" + itos(i));
+ menu->add_child(menu_sub[i]);
+ menu_sub[i]->connect("id_pressed", callable_mp(this, &EditorPropertyOTFeatures::_add_feature));
+ }
+
+ group_names[FGRP_STYLISTIC_SET] = "Stylistic Sets";
+ group_names[FGRP_CHARACTER_VARIANT] = "Character Variants";
+ group_names[FGRP_CAPITLS] = "Capitals";
+ group_names[FGRP_LIGATURES] = "Ligatures";
+ group_names[FGRP_ALTERNATES] = "Alternates";
+ group_names[FGRP_EAL] = "East Asian Language";
+ group_names[FGRP_EAW] = "East Asian Widths";
+ group_names[FGRP_NUMAL] = "Numeral Alignment";
+ group_names[FGRP_CUSTOM] = "Custom";
+}
+
+/*************************************************************************/
+/* EditorInspectorPluginFontVariation */
+/*************************************************************************/
+
+bool EditorInspectorPluginFontVariation::can_handle(Object *p_object) {
+ return (Object::cast_to<FontVariation>(p_object) != nullptr) || (Object::cast_to<DynamicFontImportSettingsData>(p_object) != nullptr);
+}
+
+bool EditorInspectorPluginFontVariation::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
+ if (p_path == "variation_opentype") {
+ add_property_editor(p_path, memnew(EditorPropertyOTVariation));
+ return true;
+ } else if (p_path == "opentype_features") {
+ add_property_editor(p_path, memnew(EditorPropertyOTFeatures));
+ return true;
+ } else if (p_path == "language_support") {
+ add_property_editor(p_path, memnew(EditorPropertyFontMetaOverride(false)));
+ return true;
+ } else if (p_path == "script_support") {
+ add_property_editor(p_path, memnew(EditorPropertyFontMetaOverride(true)));
+ return true;
+ }
+ return false;
+}
+
+/*************************************************************************/
+/* FontPreview */
+/*************************************************************************/
+
+void FontPreview::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ // Draw font name (style).
+ Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
+ int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
+ Color text_color = get_theme_color(SNAME("font_color"), SNAME("Label"));
+ font->draw_string(get_canvas_item(), Point2(0, font->get_height(font_size) + 2 * EDSCALE), name, HORIZONTAL_ALIGNMENT_CENTER, get_size().x, font_size, text_color);
+
+ // Draw font preview.
+ Vector2 pos = Vector2(0, font->get_height(font_size)) + (get_size() - Vector2(0, font->get_height(font_size)) - line->get_size()) / 2;
+ line->draw(get_canvas_item(), pos, text_color);
+
+ // Draw font baseline.
+ Color line_color = text_color;
+ line_color.a *= 0.6;
+ draw_line(Vector2(0, pos.y + line->get_line_ascent()), Vector2(pos.x - 5, pos.y + line->get_line_ascent()), line_color);
+ draw_line(Vector2(pos.x + line->get_size().x + 5, pos.y + line->get_line_ascent()), Vector2(get_size().x, pos.y + line->get_line_ascent()), line_color);
+ } break;
+ }
+}
+
+void FontPreview::_bind_methods() {}
+
+Size2 FontPreview::get_minimum_size() const {
+ return Vector2(64, 64) * EDSCALE;
+}
+
+void FontPreview::set_data(const Ref<Font> &p_f) {
+ line->clear();
+ if (p_f.is_valid()) {
+ name = vformat("%s (%s)", p_f->get_font_name(), p_f->get_font_style_name());
+ if (p_f->is_class("FontVariation")) {
+ name += " " + TTR(" - Variation");
+ }
+ String sample;
+ static const String sample_base = U"12漢字ԱբΑαÐбΑα×בابÜÜ’Þ€Þआআਆઆଆஆఆಆആආà¸à¸´àºàº´à¼€á€€á‚ áƒí•œê¸€áˆ€áŽ£áášáš áœ€áœ á€á áž€á  á¤á¥Ab😀";
+ for (int i = 0; i < sample_base.length(); i++) {
+ if (p_f->has_char(sample_base[i])) {
+ sample += sample_base[i];
+ }
+ }
+ if (sample.is_empty()) {
+ sample = p_f->get_supported_chars().substr(0, 6);
+ }
+ line->add_string(sample, p_f, 50);
+ }
+
+ update();
+}
+
+FontPreview::FontPreview() {
+ line.instantiate();
+}
+
+/*************************************************************************/
+/* EditorInspectorPluginFontPreview */
+/*************************************************************************/
+
+bool EditorInspectorPluginFontPreview::can_handle(Object *p_object) {
+ return Object::cast_to<Font>(p_object) != nullptr;
+}
+
+void EditorInspectorPluginFontPreview::parse_begin(Object *p_object) {
+ Font *fd = Object::cast_to<Font>(p_object);
+ ERR_FAIL_COND(!fd);
+
+ FontPreview *editor = memnew(FontPreview);
+ editor->set_data(fd);
+ add_custom_control(editor);
+}
+
+bool EditorInspectorPluginFontPreview::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
+ return false;
+}
+
+/*************************************************************************/
+/* FontEditorPlugin */
+/*************************************************************************/
+
+FontEditorPlugin::FontEditorPlugin() {
+ Ref<EditorInspectorPluginFontVariation> fc_plugin;
+ fc_plugin.instantiate();
+ EditorInspector::add_inspector_plugin(fc_plugin);
+
+ Ref<EditorInspectorPluginFontPreview> fp_plugin;
+ fp_plugin.instantiate();
+ EditorInspector::add_inspector_plugin(fp_plugin);
+}
diff --git a/editor/plugins/font_config_plugin.h b/editor/plugins/font_config_plugin.h
new file mode 100644
index 0000000000..9b7ee55870
--- /dev/null
+++ b/editor/plugins/font_config_plugin.h
@@ -0,0 +1,261 @@
+/*************************************************************************/
+/* font_config_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OT_FEATURES_PLUGIN_H
+#define OT_FEATURES_PLUGIN_H
+
+#include "core/io/marshalls.h"
+#include "editor/editor_plugin.h"
+#include "editor/editor_properties.h"
+
+/*************************************************************************/
+
+class EditorPropertyFontMetaObject : public RefCounted {
+ GDCLASS(EditorPropertyFontMetaObject, RefCounted);
+
+ Dictionary dict;
+
+protected:
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ static void _bind_methods();
+
+public:
+ void set_dict(const Dictionary &p_dict);
+ Dictionary get_dict();
+
+ EditorPropertyFontMetaObject(){};
+};
+
+/*************************************************************************/
+
+class EditorPropertyFontOTObject : public RefCounted {
+ GDCLASS(EditorPropertyFontOTObject, RefCounted);
+
+ Dictionary dict;
+ Dictionary defaults_dict;
+
+protected:
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ static void _bind_methods();
+
+public:
+ void set_dict(const Dictionary &p_dict);
+ Dictionary get_dict();
+
+ void set_defaults(const Dictionary &p_dict);
+ Dictionary get_defaults();
+
+ bool property_can_revert(const String &p_name);
+ Variant property_get_revert(const String &p_name);
+
+ EditorPropertyFontOTObject(){};
+};
+
+/*************************************************************************/
+
+class EditorPropertyFontMetaOverride : public EditorProperty {
+ GDCLASS(EditorPropertyFontMetaOverride, EditorProperty);
+
+ Ref<EditorPropertyFontMetaObject> object;
+
+ MarginContainer *container = nullptr;
+ VBoxContainer *property_vbox = nullptr;
+
+ Button *button_add = nullptr;
+ Button *edit = nullptr;
+ PopupMenu *menu = nullptr;
+ EditorLocaleDialog *locale_select = nullptr;
+
+ Vector<String> script_codes;
+
+ bool script_editor = false;
+ bool updating = false;
+ int page_length = 20;
+ int page_index = 0;
+ EditorPaginator *paginator = nullptr;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods(){};
+
+ void _edit_pressed();
+ void _page_changed(int p_page);
+ void _property_changed(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false);
+ void _remove(Object *p_button, const String &p_key);
+ void _add_menu();
+ void _add_script(int p_option);
+ void _add_lang(const String &p_locale);
+ void _object_id_selected(const StringName &p_property, ObjectID p_id);
+
+public:
+ virtual void update_property() override;
+
+ EditorPropertyFontMetaOverride(bool p_script);
+};
+
+/*************************************************************************/
+
+class EditorPropertyOTVariation : public EditorProperty {
+ GDCLASS(EditorPropertyOTVariation, EditorProperty);
+
+ Ref<EditorPropertyFontOTObject> object;
+
+ MarginContainer *container = nullptr;
+ VBoxContainer *property_vbox = nullptr;
+
+ Button *edit = nullptr;
+
+ bool updating = false;
+ int page_length = 20;
+ int page_index = 0;
+ EditorPaginator *paginator = nullptr;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods(){};
+
+ void _edit_pressed();
+ void _page_changed(int p_page);
+ void _property_changed(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false);
+ void _object_id_selected(const StringName &p_property, ObjectID p_id);
+
+public:
+ virtual void update_property() override;
+
+ EditorPropertyOTVariation();
+};
+
+/*************************************************************************/
+
+class EditorPropertyOTFeatures : public EditorProperty {
+ GDCLASS(EditorPropertyOTFeatures, EditorProperty);
+
+ enum FeatureGroups {
+ FGRP_STYLISTIC_SET,
+ FGRP_CHARACTER_VARIANT,
+ FGRP_CAPITLS,
+ FGRP_LIGATURES,
+ FGRP_ALTERNATES,
+ FGRP_EAL,
+ FGRP_EAW,
+ FGRP_NUMAL,
+ FGRP_CUSTOM,
+ FGRP_MAX,
+ };
+
+ Ref<EditorPropertyFontOTObject> object;
+
+ MarginContainer *container = nullptr;
+ VBoxContainer *property_vbox = nullptr;
+
+ Button *button_add = nullptr;
+ Button *edit = nullptr;
+ PopupMenu *menu = nullptr;
+ PopupMenu *menu_sub[FGRP_MAX];
+ String group_names[FGRP_MAX];
+
+ bool updating = false;
+ int page_length = 20;
+ int page_index = 0;
+ EditorPaginator *paginator = nullptr;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods(){};
+
+ void _edit_pressed();
+ void _page_changed(int p_page);
+ void _property_changed(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false);
+ void _remove(Object *p_button, int p_key);
+ void _add_menu();
+ void _add_feature(int p_option);
+ void _object_id_selected(const StringName &p_property, ObjectID p_id);
+
+public:
+ virtual void update_property() override;
+
+ EditorPropertyOTFeatures();
+};
+
+/*************************************************************************/
+
+class EditorInspectorPluginFontVariation : public EditorInspectorPlugin {
+ GDCLASS(EditorInspectorPluginFontVariation, EditorInspectorPlugin);
+
+public:
+ virtual bool can_handle(Object *p_object) override;
+ virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false) override;
+};
+
+/*************************************************************************/
+
+class FontPreview : public Control {
+ GDCLASS(FontPreview, Control);
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+ String name;
+ Ref<TextLine> line;
+
+public:
+ virtual Size2 get_minimum_size() const override;
+
+ void set_data(const Ref<Font> &p_f);
+
+ FontPreview();
+};
+
+/*************************************************************************/
+
+class EditorInspectorPluginFontPreview : public EditorInspectorPlugin {
+ GDCLASS(EditorInspectorPluginFontPreview, EditorInspectorPlugin);
+
+public:
+ virtual bool can_handle(Object *p_object) override;
+ virtual void parse_begin(Object *p_object) override;
+ virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false) override;
+};
+
+/*************************************************************************/
+
+class FontEditorPlugin : public EditorPlugin {
+ GDCLASS(FontEditorPlugin, EditorPlugin);
+
+public:
+ FontEditorPlugin();
+
+ virtual String get_name() const override { return "Font"; }
+};
+
+#endif // OT_FEATURES_PLUGIN_H
diff --git a/editor/plugins/font_editor_plugin.cpp b/editor/plugins/font_editor_plugin.cpp
deleted file mode 100644
index b9de621bcb..0000000000
--- a/editor/plugins/font_editor_plugin.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*************************************************************************/
-/* font_editor_plugin.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "font_editor_plugin.h"
-
-#include "editor/editor_scale.h"
-
-void FontDataPreview::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_DRAW: {
- Color text_color = get_theme_color(SNAME("font_color"), SNAME("Label"));
- Color line_color = text_color;
- line_color.a *= 0.6;
- Vector2 pos = (get_size() - line->get_size()) / 2;
- line->draw(get_canvas_item(), pos, text_color);
- draw_line(Vector2(0, pos.y + line->get_line_ascent()), Vector2(pos.x - 5, pos.y + line->get_line_ascent()), line_color);
- draw_line(Vector2(pos.x + line->get_size().x + 5, pos.y + line->get_line_ascent()), Vector2(get_size().x, pos.y + line->get_line_ascent()), line_color);
- } break;
- }
-}
-
-void FontDataPreview::_bind_methods() {}
-
-Size2 FontDataPreview::get_minimum_size() const {
- return Vector2(64, 64) * EDSCALE;
-}
-
-void FontDataPreview::set_data(const Ref<FontData> &p_data) {
- Ref<Font> f = memnew(Font);
- f->add_data(p_data);
-
- line->clear();
- if (p_data.is_valid()) {
- String sample;
- static const String sample_base = U"12漢字ԱբΑαÐбΑα×בابÜÜ’Þ€Þआআਆઆଆஆఆಆആආà¸à¸´àºàº´à¼€á€€á‚ áƒí•œê¸€áˆ€áŽ£áášáš áœ€áœ á€á áž€á  á¤á¥Ab😀";
- for (int i = 0; i < sample_base.length(); i++) {
- if (p_data->has_char(sample_base[i])) {
- sample += sample_base[i];
- }
- }
- if (sample.is_empty()) {
- sample = p_data->get_supported_chars().substr(0, 6);
- }
- line->add_string(sample, f, 72);
- }
-
- update();
-}
-
-FontDataPreview::FontDataPreview() {
- line.instantiate();
-}
-
-/*************************************************************************/
-
-bool EditorInspectorPluginFont::can_handle(Object *p_object) {
- return Object::cast_to<FontData>(p_object) != nullptr;
-}
-
-void EditorInspectorPluginFont::parse_begin(Object *p_object) {
- FontData *fd = Object::cast_to<FontData>(p_object);
- ERR_FAIL_COND(!fd);
-
- FontDataPreview *editor = memnew(FontDataPreview);
- editor->set_data(fd);
- add_custom_control(editor);
-}
-
-bool EditorInspectorPluginFont::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
- return false;
-}
-
-/*************************************************************************/
-
-FontEditorPlugin::FontEditorPlugin() {
- Ref<EditorInspectorPluginFont> fd_plugin;
- fd_plugin.instantiate();
- EditorInspector::add_inspector_plugin(fd_plugin);
-}
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
index 72caa15e9c..8e6687c836 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
@@ -299,12 +299,7 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
img.instantiate();
img->create(w, h, false, Image::FORMAT_RGF, texdata);
-
- Ref<ImageTexture> imgt;
- imgt.instantiate();
- imgt->create_from_image(img);
-
- pm->set_emission_point_texture(imgt);
+ pm->set_emission_point_texture(ImageTexture::create_from_image(img));
pm->set_emission_point_count(vpc);
if (capture_colors) {
@@ -320,10 +315,7 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
img.instantiate();
img->create(w, h, false, Image::FORMAT_RGBA8, colordata);
-
- imgt.instantiate();
- imgt->create_from_image(img);
- pm->set_emission_color_texture(imgt);
+ pm->set_emission_color_texture(ImageTexture::create_from_image(img));
}
if (valid_normals.size()) {
@@ -343,10 +335,7 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
img.instantiate();
img->create(w, h, false, Image::FORMAT_RGF, normdata);
-
- imgt.instantiate();
- imgt->create_from_image(img);
- pm->set_emission_normal_texture(imgt);
+ pm->set_emission_normal_texture(ImageTexture::create_from_image(img));
} else {
pm->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_POINTS);
@@ -391,7 +380,7 @@ GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin() {
List<String> ext;
ImageLoader::get_recognized_extensions(&ext);
for (const String &E : ext) {
- file->add_filter("*." + E + "; " + E.to_upper());
+ file->add_filter("*." + E, E.to_upper());
}
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
toolbar->add_child(file);
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
index fa971679e6..6750f1aa9c 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
@@ -215,7 +215,7 @@ GPUParticles3DEditorBase::GPUParticles3DEditorBase() {
emission_fill->add_item(TTR("Volume"));
emd_vb->add_margin_child(TTR("Emission Source:"), emission_fill);
- emission_dialog->get_ok_button()->set_text(TTR("Create"));
+ emission_dialog->set_ok_button_text(TTR("Create"));
emission_dialog->connect("confirmed", callable_mp(this, &GPUParticles3DEditorBase::_generate_emission_points));
emission_tree_dialog = memnew(SceneTreeDialog);
@@ -363,10 +363,7 @@ void GPUParticles3DEditor::_generate_emission_points() {
}
Ref<Image> image = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img));
-
- Ref<ImageTexture> tex;
- tex.instantiate();
- tex->create_from_image(image);
+ Ref<ImageTexture> tex = ImageTexture::create_from_image(image);
Ref<ParticlesMaterial> material = node->get_process_material();
ERR_FAIL_COND(material.is_null());
@@ -392,12 +389,7 @@ void GPUParticles3DEditor::_generate_emission_points() {
}
Ref<Image> image2 = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img2));
-
- Ref<ImageTexture> tex2;
- tex2.instantiate();
- tex2->create_from_image(image2);
-
- material->set_emission_normal_texture(tex2);
+ material->set_emission_normal_texture(ImageTexture::create_from_image(image2));
} else {
material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_POINTS);
material->set_emission_point_count(point_count);
diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp
index 1386f03662..5c7047a81f 100644
--- a/editor/plugins/gradient_editor_plugin.cpp
+++ b/editor/plugins/gradient_editor_plugin.cpp
@@ -85,6 +85,7 @@ void GradientEditor::reverse_gradient() {
}
GradientEditor::GradientEditor() {
+ GradientEdit::get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(GradientEdit::get_picker()));
editing = false;
}
diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.cpp b/editor/plugins/gradient_texture_2d_editor_plugin.cpp
index e97c611e96..df45d6c290 100644
--- a/editor/plugins/gradient_texture_2d_editor_plugin.cpp
+++ b/editor/plugins/gradient_texture_2d_editor_plugin.cpp
@@ -117,17 +117,15 @@ void GradientTexture2DEditorRect::_notification(int p_what) {
const Ref<Texture2D> fill_to_icon = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
handle_size = fill_from_icon->get_size();
- const int MAX_HEIGHT = 250 * EDSCALE;
Size2 rect_size = get_size();
// Get the size and position to draw the texture and handles at.
- size = Size2(texture->get_width() * MAX_HEIGHT / texture->get_height(), MAX_HEIGHT);
+ size = Size2(texture->get_width() * rect_size.height / texture->get_height(), rect_size.height);
if (size.width > rect_size.width) {
size.width = rect_size.width;
- size.height = texture->get_height() * rect_size.width / texture->get_width();
+ size.height = texture->get_height() * size.width / texture->get_width();
}
- offset = Point2(Math::round((rect_size.width - size.width) / 2), 0) + handle_size / 2;
- set_custom_minimum_size(Size2(0, size.height));
+ offset = ((rect_size - size + handle_size) / 2).round();
size -= handle_size;
checkerboard->set_rect(Rect2(offset, size));
@@ -183,6 +181,8 @@ GradientTexture2DEditorRect::GradientTexture2DEditorRect() {
checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE);
checkerboard->set_draw_behind_parent(true);
add_child(checkerboard);
+
+ set_custom_minimum_size(Size2(0, 250 * EDSCALE));
}
///////////////////////
diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp
index aef97f059a..8413c5e875 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.cpp
+++ b/editor/plugins/lightmap_gi_editor_plugin.cpp
@@ -138,7 +138,7 @@ LightmapGIEditorPlugin::LightmapGIEditorPlugin() {
file_dialog = memnew(EditorFileDialog);
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
- file_dialog->add_filter("*.lmbake ; " + TTR("LightMap Bake"));
+ file_dialog->add_filter("*.lmbake", TTR("LightMap Bake"));
file_dialog->set_title(TTR("Select lightmap bake file:"));
file_dialog->connect("file_selected", callable_mp(this, &LightmapGIEditorPlugin::_bake_select_file));
bake->add_child(file_dialog);
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index eb004568d0..34db75f118 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -130,7 +130,7 @@ MaterialEditor::MaterialEditor() {
layout_2d = memnew(HBoxContainer);
layout_2d->set_alignment(BoxContainer::ALIGNMENT_CENTER);
add_child(layout_2d);
- layout_2d->set_anchors_and_offsets_preset(PRESET_WIDE);
+ layout_2d->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
rect_instance = memnew(ColorRect);
layout_2d->add_child(rect_instance);
@@ -143,7 +143,7 @@ MaterialEditor::MaterialEditor() {
vc = memnew(SubViewportContainer);
vc->set_stretch(true);
add_child(vc);
- vc->set_anchors_and_offsets_preset(PRESET_WIDE);
+ vc->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
viewport = memnew(SubViewport);
Ref<World3D> world_3d;
world_3d.instantiate();
@@ -190,7 +190,7 @@ MaterialEditor::MaterialEditor() {
layout_3d = memnew(HBoxContainer);
add_child(layout_3d);
- layout_3d->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 2);
+ layout_3d->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 2);
VBoxContainer *vb_shape = memnew(VBoxContainer);
layout_3d->add_child(vb_shape);
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index 7029768479..b23395fea2 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -137,7 +137,7 @@ MeshEditor::MeshEditor() {
HBoxContainer *hb = memnew(HBoxContainer);
add_child(hb);
- hb->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 2);
+ hb->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 2);
hb->add_spacer();
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index d1f858315c..5fb885ad1f 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -519,7 +519,7 @@ MeshInstance3DEditor::MeshInstance3DEditor() {
outline_dialog = memnew(ConfirmationDialog);
outline_dialog->set_title(TTR("Create Outline Mesh"));
- outline_dialog->get_ok_button()->set_text(TTR("Create"));
+ outline_dialog->set_ok_button_text(TTR("Create"));
VBoxContainer *outline_dialog_vbc = memnew(VBoxContainer);
outline_dialog->add_child(outline_dialog_vbc);
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index 914ccb54c1..72bfc05270 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -263,7 +263,7 @@ MeshLibraryEditor::MeshLibraryEditor() {
file->clear_filters();
file->set_title(TTR("Import Scene"));
for (int i = 0; i < extensions.size(); i++) {
- file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
+ file->add_filter("*." + extensions[i], extensions[i].to_upper());
}
add_child(file);
file->connect("file_selected", callable_mp(this, &MeshLibraryEditor::_import_scene_cbk));
@@ -288,7 +288,7 @@ MeshLibraryEditor::MeshLibraryEditor() {
cd_remove->get_ok_button()->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_remove_confirm));
cd_update = memnew(ConfirmationDialog);
add_child(cd_update);
- cd_update->get_ok_button()->set_text(TTR("Apply without Transforms"));
+ cd_update->set_ok_button_text(TTR("Apply without Transforms"));
cd_update->get_ok_button()->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm), varray(false));
cd_update->add_button(TTR("Apply with Transforms"))->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm), varray(true));
}
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index 0fab3aed0d..7207390922 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -347,7 +347,7 @@ MultiMeshEditor::MultiMeshEditor() {
populate_amount->set_value(128);
vbc->add_margin_child(TTR("Amount:"), populate_amount);
- populate_dialog->get_ok_button()->set_text(TTR("Populate"));
+ populate_dialog->set_ok_button_text(TTR("Populate"));
populate_dialog->get_ok_button()->connect("pressed", callable_mp(this, &MultiMeshEditor::_populate));
std = memnew(SceneTreeDialog);
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 64aeb9f2a8..77cf1f0064 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -245,6 +245,7 @@ void EditorNode3DGizmo::Instance::create_instance(Node3D *p_base, bool p_hidden)
int layer = p_hidden ? 0 : 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER;
RS::get_singleton()->instance_set_layer_mask(instance, layer); //gizmos are 26
RS::get_singleton()->instance_geometry_set_flag(instance, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(instance, RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
}
void EditorNode3DGizmo::add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p_material, const Transform3D &p_xform, const Ref<SkinReference> &p_skin_reference) {
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 815d0a2425..df17e2747f 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -52,6 +52,7 @@
#include "scene/3d/visual_instance_3d.h"
#include "scene/3d/world_environment.h"
#include "scene/gui/center_container.h"
+#include "scene/gui/flow_container.h"
#include "scene/gui/subviewport_container.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/surface_tool.h"
@@ -145,7 +146,7 @@ void ViewportRotationControl::_draw_axis(const Axis2D &p_axis) {
// Draw the axis letter for the positive axes.
const String axis_name = direction == 0 ? "X" : (direction == 1 ? "Y" : "Z");
- draw_char(get_theme_font(SNAME("rotation_control"), SNAME("EditorFonts")), p_axis.screen_point + Vector2i(Math::round(-4.0 * EDSCALE), Math::round(5.0 * EDSCALE)), axis_name, "", get_theme_font_size(SNAME("rotation_control_size"), SNAME("EditorFonts")), Color(0.0, 0.0, 0.0, alpha));
+ draw_char(get_theme_font(SNAME("rotation_control"), SNAME("EditorFonts")), p_axis.screen_point + Vector2i(Math::round(-4.0 * EDSCALE), Math::round(5.0 * EDSCALE)), axis_name, get_theme_font_size(SNAME("rotation_control_size"), SNAME("EditorFonts")), Color(0.0, 0.0, 0.0, alpha));
} else {
// Draw an outline around the negative axes.
draw_circle(p_axis.screen_point, AXIS_CIRCLE_RADIUS, c);
@@ -2379,19 +2380,19 @@ void Node3DEditorPlugin::edited_scene_changed() {
void Node3DEditorViewport::_project_settings_changed() {
//update shadow atlas if changed
- int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/size");
- bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/16_bits");
- int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_0_subdiv");
- int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_1_subdiv");
- int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_2_subdiv");
- int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_3_subdiv");
-
- viewport->set_shadow_atlas_size(shadowmap_size);
- viewport->set_shadow_atlas_16_bits(shadowmap_16_bits);
- viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
- viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
- viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
- viewport->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
+ int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_size");
+ bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_16_bits");
+ int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_quadrant_0_subdiv");
+ int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_quadrant_1_subdiv");
+ int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_quadrant_2_subdiv");
+ int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_quadrant_3_subdiv");
+
+ viewport->set_positional_shadow_atlas_size(shadowmap_size);
+ viewport->set_positional_shadow_atlas_16_bits(shadowmap_16_bits);
+ viewport->set_positional_shadow_atlas_quadrant_subdiv(0, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q0));
+ viewport->set_positional_shadow_atlas_quadrant_subdiv(1, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q1));
+ viewport->set_positional_shadow_atlas_quadrant_subdiv(2, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q2));
+ viewport->set_positional_shadow_atlas_quadrant_subdiv(3, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q3));
_update_shrink();
@@ -2725,7 +2726,8 @@ static void draw_indicator_bar(Control &p_surface, real_t p_fill, const Ref<Text
p_surface.draw_texture(p_icon, icon_pos, p_color);
// Draw text below the bar (for speed/zoom information).
- p_surface.draw_string(p_font, Vector2(icon_pos.x, icon_pos.y + icon_size.y + 16 * EDSCALE), p_text, HORIZONTAL_ALIGNMENT_LEFT, -1.f, p_font_size, p_color, Math::round(2 * EDSCALE), Color(0, 0, 0));
+ p_surface.draw_string_outline(p_font, Vector2(icon_pos.x, icon_pos.y + icon_size.y + 16 * EDSCALE), p_text, HORIZONTAL_ALIGNMENT_LEFT, -1.f, p_font_size, Math::round(2 * EDSCALE), Color(0, 0, 0));
+ p_surface.draw_string(p_font, Vector2(icon_pos.x, icon_pos.y + icon_size.y + 16 * EDSCALE), p_text, HORIZONTAL_ALIGNMENT_LEFT, -1.f, p_font_size, p_color);
}
void Node3DEditorViewport::_draw() {
@@ -3251,6 +3253,7 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(move_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(move_gizmo_instance[i], layer);
RS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i], RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
move_plane_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(move_plane_gizmo_instance[i], spatial_editor->get_move_plane_gizmo(i)->get_rid());
@@ -3259,6 +3262,7 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(move_plane_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(move_plane_gizmo_instance[i], layer);
RS::get_singleton()->instance_geometry_set_flag(move_plane_gizmo_instance[i], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(move_plane_gizmo_instance[i], RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
rotate_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(rotate_gizmo_instance[i], spatial_editor->get_rotate_gizmo(i)->get_rid());
@@ -3267,6 +3271,7 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(rotate_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[i], layer);
RS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i], RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
scale_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(scale_gizmo_instance[i], spatial_editor->get_scale_gizmo(i)->get_rid());
@@ -3275,6 +3280,7 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(scale_gizmo_instance[i], layer);
RS::get_singleton()->instance_geometry_set_flag(scale_gizmo_instance[i], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(scale_gizmo_instance[i], RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
scale_plane_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(scale_plane_gizmo_instance[i], spatial_editor->get_scale_plane_gizmo(i)->get_rid());
@@ -3283,6 +3289,7 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_plane_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(scale_plane_gizmo_instance[i], layer);
RS::get_singleton()->instance_geometry_set_flag(scale_plane_gizmo_instance[i], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(scale_plane_gizmo_instance[i], RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
axis_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(axis_gizmo_instance[i], spatial_editor->get_axis_gizmo(i)->get_rid());
@@ -3290,6 +3297,8 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
RS::get_singleton()->instance_set_visible(axis_gizmo_instance[i], true);
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(axis_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(axis_gizmo_instance[i], layer);
+ RS::get_singleton()->instance_geometry_set_flag(axis_gizmo_instance[i], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(axis_gizmo_instance[i], RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
}
// Rotation white outline
@@ -3300,6 +3309,7 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(rotate_gizmo_instance[3], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[3], layer);
RS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[3], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[3], RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
}
void Node3DEditorViewport::_finish_gizmo_instances() {
@@ -4485,7 +4495,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
subviewport_container = c;
c->set_stretch(true);
add_child(c);
- c->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ c->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
viewport = memnew(SubViewport);
viewport->set_disable_input(true);
@@ -4493,7 +4503,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
surface = memnew(Control);
surface->set_drag_forwarding(this);
add_child(surface);
- surface->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ surface->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
surface->set_clip_contents(true);
camera = memnew(Camera3D);
camera->set_disable_gizmos(true);
@@ -4514,6 +4524,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
vbox->add_child(view_menu);
display_submenu = memnew(PopupMenu);
+ view_menu->get_popup()->set_hide_on_checkable_item_selection(false);
view_menu->get_popup()->add_child(display_submenu);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/top_view"), VIEW_TOP);
@@ -4537,6 +4548,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_lighting", TTR("Display Lighting")), VIEW_DISPLAY_LIGHTING);
view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_unshaded", TTR("Display Unshaded")), VIEW_DISPLAY_SHADELESS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), true);
+ display_submenu->set_hide_on_checkable_item_selection(false);
display_submenu->add_radio_check_item(TTR("Directional Shadow Splits"), VIEW_DISPLAY_DEBUG_PSSM_SPLITS);
display_submenu->add_separator();
display_submenu->add_radio_check_item(TTR("Normal Buffer"), VIEW_DISPLAY_NORMAL_BUFFER);
@@ -4692,7 +4704,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
frame_time_gradient->add_point(0.5, Color());
top_right_vbox = memnew(VBoxContainer);
- top_right_vbox->set_anchors_and_offsets_preset(PRESET_TOP_RIGHT, PRESET_MODE_MINSIZE, 2.0 * EDSCALE);
+ top_right_vbox->set_anchors_and_offsets_preset(PRESET_TOP_RIGHT, PRESET_MODE_MINSIZE, 10.0 * EDSCALE);
top_right_vbox->set_h_grow_direction(GROW_DIRECTION_BEGIN);
// Make sure frame time labels don't touch the viewport's edge.
top_right_vbox->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
@@ -5188,7 +5200,9 @@ Object *Node3DEditor::_get_editor_data(Object *p_what) {
RS::get_singleton()->instance_set_layer_mask(si->sbox_instance, 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER);
RS::get_singleton()->instance_set_layer_mask(si->sbox_instance_offset, 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER);
RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance, RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance_offset, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance_offset, RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
si->sbox_instance_xray = RenderingServer::get_singleton()->instance_create2(
selection_box_xray->get_rid(),
sp->get_world_3d()->get_scenario());
@@ -5206,7 +5220,9 @@ Object *Node3DEditor::_get_editor_data(Object *p_what) {
RS::get_singleton()->instance_set_layer_mask(si->sbox_instance_xray, 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER);
RS::get_singleton()->instance_set_layer_mask(si->sbox_instance_xray_offset, 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER);
RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance_xray, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance_xray, RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance_xray_offset, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(si->sbox_instance_xray_offset, RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
return si;
}
@@ -5993,6 +6009,7 @@ void fragment() {
origin_instance = RenderingServer::get_singleton()->instance_create2(origin, get_tree()->get_root()->get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_layer_mask(origin_instance, 1 << Node3DEditorViewport::GIZMO_GRID_LAYER);
RS::get_singleton()->instance_geometry_set_flag(origin_instance, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(origin_instance, RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
RenderingServer::get_singleton()->instance_geometry_set_cast_shadows_setting(origin_instance, RS::SHADOW_CASTING_SETTING_OFF);
}
@@ -6603,6 +6620,7 @@ void Node3DEditor::_init_grid() {
RenderingServer::get_singleton()->instance_geometry_set_cast_shadows_setting(grid_instance[c], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(grid_instance[c], 1 << Node3DEditorViewport::GIZMO_GRID_LAYER);
RS::get_singleton()->instance_geometry_set_flag(grid_instance[c], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+ RS::get_singleton()->instance_geometry_set_flag(grid_instance[c], RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
}
}
@@ -6966,7 +6984,7 @@ void Node3DEditor::_update_theme() {
environ_sky_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor"))));
environ_ground_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor"))));
- context_menu_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles")));
+ context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles")));
}
void Node3DEditor::_notification(int p_what) {
@@ -7055,11 +7073,11 @@ Vector<int> Node3DEditor::get_subgizmo_selection() {
}
void Node3DEditor::add_control_to_menu_panel(Control *p_control) {
- hbc_context_menu->add_child(p_control);
+ context_menu_hbox->add_child(p_control);
}
void Node3DEditor::remove_control_from_menu_panel(Control *p_control) {
- hbc_context_menu->remove_child(p_control);
+ context_menu_hbox->remove_child(p_control);
}
void Node3DEditor::set_can_preview(Camera3D *p_preview) {
@@ -7216,7 +7234,7 @@ void Node3DEditor::_toggle_maximize_view(Object *p_viewport) {
if (!maximized) {
for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
if (i == (uint32_t)index) {
- viewports[i]->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ viewports[i]->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
} else {
viewports[i]->hide();
}
@@ -7512,8 +7530,13 @@ Node3DEditor::Node3DEditor() {
camera_override_viewport_id = 0;
- hbc_menu = memnew(HBoxContainer);
- vbc->add_child(hbc_menu);
+ // A fluid container for all toolbars.
+ HFlowContainer *main_flow = memnew(HFlowContainer);
+ vbc->add_child(main_flow);
+
+ // Main toolbars.
+ HBoxContainer *main_menu_hbox = memnew(HBoxContainer);
+ main_flow->add_child(main_menu_hbox);
Vector<Variant> button_binds;
button_binds.resize(1);
@@ -7523,11 +7546,11 @@ Node3DEditor::Node3DEditor() {
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
Control *margin_left = memnew(Control);
- hbc_menu->add_child(margin_left);
+ main_menu_hbox->add_child(margin_left);
margin_left->set_custom_minimum_size(Size2(2, 0) * EDSCALE);
tool_button[TOOL_MODE_SELECT] = memnew(Button);
- hbc_menu->add_child(tool_button[TOOL_MODE_SELECT]);
+ main_menu_hbox->add_child(tool_button[TOOL_MODE_SELECT]);
tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true);
tool_button[TOOL_MODE_SELECT]->set_flat(true);
tool_button[TOOL_MODE_SELECT]->set_pressed(true);
@@ -7536,10 +7559,10 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), Key::Q));
tool_button[TOOL_MODE_SELECT]->set_shortcut_context(this);
tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked."));
- hbc_menu->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
tool_button[TOOL_MODE_MOVE] = memnew(Button);
- hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]);
+ main_menu_hbox->add_child(tool_button[TOOL_MODE_MOVE]);
tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true);
tool_button[TOOL_MODE_MOVE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_MOVE;
@@ -7548,7 +7571,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_MODE_MOVE]->set_shortcut_context(this);
tool_button[TOOL_MODE_ROTATE] = memnew(Button);
- hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]);
+ main_menu_hbox->add_child(tool_button[TOOL_MODE_ROTATE]);
tool_button[TOOL_MODE_ROTATE]->set_toggle_mode(true);
tool_button[TOOL_MODE_ROTATE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_ROTATE;
@@ -7557,7 +7580,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_MODE_ROTATE]->set_shortcut_context(this);
tool_button[TOOL_MODE_SCALE] = memnew(Button);
- hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]);
+ main_menu_hbox->add_child(tool_button[TOOL_MODE_SCALE]);
tool_button[TOOL_MODE_SCALE]->set_toggle_mode(true);
tool_button[TOOL_MODE_SCALE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_SCALE;
@@ -7565,10 +7588,10 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_MODE_SCALE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_scale", TTR("Scale Mode"), Key::R));
tool_button[TOOL_MODE_SCALE]->set_shortcut_context(this);
- hbc_menu->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
tool_button[TOOL_MODE_LIST_SELECT] = memnew(Button);
- hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]);
+ main_menu_hbox->add_child(tool_button[TOOL_MODE_LIST_SELECT]);
tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true);
tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true);
button_binds.write[0] = MENU_TOOL_LIST_SELECT;
@@ -7576,7 +7599,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show list of selectable nodes at position clicked."));
tool_button[TOOL_LOCK_SELECTED] = memnew(Button);
- hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]);
+ main_menu_hbox->add_child(tool_button[TOOL_LOCK_SELECTED]);
tool_button[TOOL_LOCK_SELECTED]->set_flat(true);
button_binds.write[0] = MENU_LOCK_SELECTED;
tool_button[TOOL_LOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds);
@@ -7585,7 +7608,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_LOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KeyModifierMask::CMD | Key::L));
tool_button[TOOL_UNLOCK_SELECTED] = memnew(Button);
- hbc_menu->add_child(tool_button[TOOL_UNLOCK_SELECTED]);
+ main_menu_hbox->add_child(tool_button[TOOL_UNLOCK_SELECTED]);
tool_button[TOOL_UNLOCK_SELECTED]->set_flat(true);
button_binds.write[0] = MENU_UNLOCK_SELECTED;
tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds);
@@ -7594,7 +7617,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_UNLOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::L));
tool_button[TOOL_GROUP_SELECTED] = memnew(Button);
- hbc_menu->add_child(tool_button[TOOL_GROUP_SELECTED]);
+ main_menu_hbox->add_child(tool_button[TOOL_GROUP_SELECTED]);
tool_button[TOOL_GROUP_SELECTED]->set_flat(true);
button_binds.write[0] = MENU_GROUP_SELECTED;
tool_button[TOOL_GROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds);
@@ -7603,7 +7626,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_GROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD | Key::G));
tool_button[TOOL_UNGROUP_SELECTED] = memnew(Button);
- hbc_menu->add_child(tool_button[TOOL_UNGROUP_SELECTED]);
+ main_menu_hbox->add_child(tool_button[TOOL_UNGROUP_SELECTED]);
tool_button[TOOL_UNGROUP_SELECTED]->set_flat(true);
button_binds.write[0] = MENU_UNGROUP_SELECTED;
tool_button[TOOL_UNGROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds);
@@ -7611,10 +7634,10 @@ Node3DEditor::Node3DEditor() {
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
tool_button[TOOL_UNGROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G));
- hbc_menu->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
tool_option_button[TOOL_OPT_LOCAL_COORDS] = memnew(Button);
- hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]);
+ main_menu_hbox->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]);
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_toggle_mode(true);
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true);
button_binds.write[0] = MENU_TOOL_LOCAL_COORDS;
@@ -7623,7 +7646,7 @@ Node3DEditor::Node3DEditor() {
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_shortcut_context(this);
tool_option_button[TOOL_OPT_USE_SNAP] = memnew(Button);
- hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]);
+ main_menu_hbox->add_child(tool_option_button[TOOL_OPT_USE_SNAP]);
tool_option_button[TOOL_OPT_USE_SNAP]->set_toggle_mode(true);
tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true);
button_binds.write[0] = MENU_TOOL_USE_SNAP;
@@ -7631,10 +7654,10 @@ Node3DEditor::Node3DEditor() {
tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut(ED_SHORTCUT("spatial_editor/snap", TTR("Use Snap"), Key::Y));
tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut_context(this);
- hbc_menu->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
tool_option_button[TOOL_OPT_OVERRIDE_CAMERA] = memnew(Button);
- hbc_menu->add_child(tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]);
+ main_menu_hbox->add_child(tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]);
tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_toggle_mode(true);
tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_flat(true);
tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_disabled(true);
@@ -7642,7 +7665,7 @@ Node3DEditor::Node3DEditor() {
tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->connect("toggled", callable_mp(this, &Node3DEditor::_menu_item_toggled), button_binds);
_update_camera_override_button(false);
- hbc_menu->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
sun_button = memnew(Button);
sun_button->set_tooltip(TTR("Toggle preview sunlight.\nIf a DirectionalLight3D node is added to the scene, preview sunlight is disabled."));
sun_button->set_toggle_mode(true);
@@ -7650,7 +7673,7 @@ Node3DEditor::Node3DEditor() {
sun_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED);
sun_button->set_disabled(true);
- hbc_menu->add_child(sun_button);
+ main_menu_hbox->add_child(sun_button);
environ_button = memnew(Button);
environ_button->set_tooltip(TTR("Toggle preview environment.\nIf a WorldEnvironment node is added to the scene, preview environment is disabled."));
@@ -7659,16 +7682,16 @@ Node3DEditor::Node3DEditor() {
environ_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED);
environ_button->set_disabled(true);
- hbc_menu->add_child(environ_button);
+ main_menu_hbox->add_child(environ_button);
sun_environ_settings = memnew(Button);
sun_environ_settings->set_tooltip(TTR("Edit Sun and Environment settings."));
sun_environ_settings->set_flat(true);
sun_environ_settings->connect("pressed", callable_mp(this, &Node3DEditor::_sun_environ_settings_pressed));
- hbc_menu->add_child(sun_environ_settings);
+ main_menu_hbox->add_child(sun_environ_settings);
- hbc_menu->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
// Drag and drop support;
preview_node = memnew(Node3D);
@@ -7702,7 +7725,7 @@ Node3DEditor::Node3DEditor() {
transform_menu->set_text(TTR("Transform"));
transform_menu->set_switch_on_hover(true);
transform_menu->set_shortcut_context(this);
- hbc_menu->add_child(transform_menu);
+ main_menu_hbox->add_child(transform_menu);
p = transform_menu->get_popup();
p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap Object to Floor"), Key::PAGEDOWN), MENU_SNAP_TO_FLOOR);
@@ -7718,14 +7741,14 @@ Node3DEditor::Node3DEditor() {
view_menu->set_text(TTR("View"));
view_menu->set_switch_on_hover(true);
view_menu->set_shortcut_context(this);
- hbc_menu->add_child(view_menu);
+ main_menu_hbox->add_child(view_menu);
- hbc_menu->add_child(memnew(VSeparator));
+ main_menu_hbox->add_child(memnew(VSeparator));
- context_menu_container = memnew(PanelContainer);
- hbc_context_menu = memnew(HBoxContainer);
- context_menu_container->add_child(hbc_context_menu);
- hbc_menu->add_child(context_menu_container);
+ context_menu_panel = memnew(PanelContainer);
+ context_menu_hbox = memnew(HBoxContainer);
+ context_menu_panel->add_child(context_menu_hbox);
+ main_flow->add_child(context_menu_panel);
// Get the view menu popup and have it stay open when a checkable item is selected
p = view_menu->get_popup();
@@ -8005,6 +8028,7 @@ void fragment() {
sun_color->set_edit_alpha(false);
sun_vb->add_margin_child(TTR("Sun Color"), sun_color);
sun_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
+ sun_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(sun_color->get_picker()));
sun_energy = memnew(EditorSpinSlider);
sun_vb->add_margin_child(TTR("Sun Energy"), sun_energy);
@@ -8050,10 +8074,12 @@ void fragment() {
environ_sky_color = memnew(ColorPickerButton);
environ_sky_color->set_edit_alpha(false);
environ_sky_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
+ environ_sky_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(environ_sky_color->get_picker()));
environ_vb->add_margin_child(TTR("Sky Color"), environ_sky_color);
environ_ground_color = memnew(ColorPickerButton);
environ_ground_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
environ_ground_color->set_edit_alpha(false);
+ environ_ground_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(environ_ground_color->get_picker()));
environ_vb->add_margin_child(TTR("Ground Color"), environ_ground_color);
environ_energy = memnew(EditorSpinSlider);
environ_energy->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 8a602be08b..c98022bcf7 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -664,11 +664,10 @@ private:
void _menu_gizmo_toggled(int p_option);
void _update_camera_override_button(bool p_game_running);
void _update_camera_override_viewport(Object *p_viewport);
- HBoxContainer *hbc_menu = nullptr;
// Used for secondary menu items which are displayed depending on the currently selected node
// (such as MeshInstance's "Mesh" menu).
- PanelContainer *context_menu_container = nullptr;
- HBoxContainer *hbc_context_menu = nullptr;
+ PanelContainer *context_menu_panel = nullptr;
+ HBoxContainer *context_menu_hbox = nullptr;
void _generate_selection_boxes();
UndoRedo *undo_redo = nullptr;
diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.cpp b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
index d5fc51aea4..365f74d7a3 100644
--- a/editor/plugins/occluder_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
@@ -113,7 +113,7 @@ OccluderInstance3DEditorPlugin::OccluderInstance3DEditorPlugin() {
file_dialog = memnew(EditorFileDialog);
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
- file_dialog->add_filter("*.occ ; Occluder3D");
+ file_dialog->add_filter("*.occ", "Occluder3D");
file_dialog->set_title(TTR("Select occluder bake file:"));
file_dialog->connect("file_selected", callable_mp(this, &OccluderInstance3DEditorPlugin::_bake_select_file));
bake->add_child(file_dialog);
diff --git a/editor/plugins/ot_features_plugin.cpp b/editor/plugins/ot_features_plugin.cpp
deleted file mode 100644
index f8526fb715..0000000000
--- a/editor/plugins/ot_features_plugin.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*************************************************************************/
-/* ot_features_plugin.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "ot_features_plugin.h"
-
-#include "scene/3d/label_3d.h"
-#include "scene/resources/primitive_meshes.h"
-
-void OpenTypeFeaturesEditor::_value_changed(double val) {
- if (setting) {
- return;
- }
-
- emit_changed(get_edited_property(), spin->get_value());
-}
-
-void OpenTypeFeaturesEditor::update_property() {
- double val = get_edited_object()->get(get_edited_property());
- setting = true;
- spin->set_value(val);
- setting = false;
-}
-
-void OpenTypeFeaturesEditor::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE:
- case NOTIFICATION_THEME_CHANGED: {
- Color base = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
-
- button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- button->set_size(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))->get_size());
- spin->add_theme_color_override("label_color", base);
- } break;
- }
-}
-
-void OpenTypeFeaturesEditor::_remove_feature() {
- get_edited_object()->set(get_edited_property(), -1);
-}
-
-void OpenTypeFeaturesEditor::_bind_methods() {
-}
-
-OpenTypeFeaturesEditor::OpenTypeFeaturesEditor() {
- HBoxContainer *bc = memnew(HBoxContainer);
- add_child(bc);
-
- spin = memnew(EditorSpinSlider);
- spin->set_flat(true);
- bc->add_child(spin);
- add_focusable(spin);
- spin->connect("value_changed", callable_mp(this, &OpenTypeFeaturesEditor::_value_changed));
- spin->set_h_size_flags(SIZE_EXPAND_FILL);
-
- spin->set_min(0);
- spin->set_max(65536);
- spin->set_step(1);
- spin->set_hide_slider(false);
- spin->set_allow_greater(false);
- spin->set_allow_lesser(false);
-
- button = memnew(Button);
- button->set_tooltip(RTR("Remove feature"));
- button->set_flat(true);
- bc->add_child(button);
-
- button->connect("pressed", callable_mp(this, &OpenTypeFeaturesEditor::_remove_feature));
-
- setting = false;
-}
-
-/*************************************************************************/
-
-void OpenTypeFeaturesAdd::_add_feature(int p_option) {
- edited_object->set("opentype_features/" + TS->tag_to_name(p_option), 1);
-}
-
-void OpenTypeFeaturesAdd::_features_menu() {
- Size2 size = get_size();
- menu->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y));
- menu->reset_size();
- menu->popup();
-}
-
-void OpenTypeFeaturesAdd::setup(Object *p_object) {
- edited_object = p_object;
-
- menu->clear();
- menu_ss->clear();
- menu_cv->clear();
- menu_cu->clear();
- bool have_ss = false;
- bool have_cv = false;
- bool have_cu = false;
-
- Ref<Font> font;
-
- Control *ctrl = Object::cast_to<Control>(edited_object);
- if (ctrl != nullptr) {
- font = ctrl->get_theme_font(SNAME("font"));
- }
- Label3D *l3d = Object::cast_to<Label3D>(edited_object);
- if (l3d != nullptr) {
- font = l3d->_get_font_or_default();
- }
- TextMesh *tm = Object::cast_to<TextMesh>(edited_object);
- if (tm != nullptr) {
- font = tm->_get_font_or_default();
- }
-
- if (font.is_null()) {
- return;
- }
-
- Dictionary features = font->get_feature_list();
-
- for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) {
- String ftr_name = TS->tag_to_name(*ftr);
- if (ftr_name.begins_with("stylistic_set_")) {
- menu_ss->add_item(ftr_name.capitalize(), (int32_t)*ftr);
- have_ss = true;
- } else if (ftr_name.begins_with("character_variant_")) {
- menu_cv->add_item(ftr_name.capitalize(), (int32_t)*ftr);
- have_cv = true;
- } else if (ftr_name.begins_with("custom_")) {
- menu_cu->add_item(ftr_name.replace("custom_", ""), (int32_t)*ftr);
- have_cu = true;
- } else {
- menu->add_item(ftr_name.capitalize(), (int32_t)*ftr);
- }
- }
- if (have_ss) {
- menu->add_submenu_item(RTR("Stylistic Sets"), "SSMenu");
- }
- if (have_cv) {
- menu->add_submenu_item(RTR("Character Variants"), "CVMenu");
- }
- if (have_cu) {
- menu->add_submenu_item(RTR("Custom"), "CUMenu");
- }
-}
-
-void OpenTypeFeaturesAdd::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- connect("pressed", callable_mp(this, &OpenTypeFeaturesAdd::_features_menu));
- [[fallthrough]];
- }
- case NOTIFICATION_THEME_CHANGED: {
- set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- } break;
- }
-}
-
-void OpenTypeFeaturesAdd::_bind_methods() {
-}
-
-OpenTypeFeaturesAdd::OpenTypeFeaturesAdd() {
- set_text(TTR("Add Feature..."));
-
- menu = memnew(PopupMenu);
- add_child(menu);
-
- menu_cv = memnew(PopupMenu);
- menu_cv->set_name("CVMenu");
- menu->add_child(menu_cv);
-
- menu_ss = memnew(PopupMenu);
- menu_ss->set_name("SSMenu");
- menu->add_child(menu_ss);
-
- menu_cu = memnew(PopupMenu);
- menu_cu->set_name("CUMenu");
- menu->add_child(menu_cu);
-
- menu->connect("id_pressed", callable_mp(this, &OpenTypeFeaturesAdd::_add_feature));
- menu_cv->connect("id_pressed", callable_mp(this, &OpenTypeFeaturesAdd::_add_feature));
- menu_ss->connect("id_pressed", callable_mp(this, &OpenTypeFeaturesAdd::_add_feature));
- menu_cu->connect("id_pressed", callable_mp(this, &OpenTypeFeaturesAdd::_add_feature));
-}
-
-/*************************************************************************/
-
-bool EditorInspectorPluginOpenTypeFeatures::can_handle(Object *p_object) {
- return (Object::cast_to<Control>(p_object) != nullptr) || (Object::cast_to<Label3D>(p_object) != nullptr) || (Object::cast_to<TextMesh>(p_object) != nullptr);
-}
-
-bool EditorInspectorPluginOpenTypeFeatures::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
- if (p_path == "opentype_features/_new") {
- OpenTypeFeaturesAdd *editor = memnew(OpenTypeFeaturesAdd);
- editor->setup(p_object);
- add_custom_control(editor);
- return true;
- } else if (p_path.begins_with("opentype_features")) {
- OpenTypeFeaturesEditor *editor = memnew(OpenTypeFeaturesEditor);
- add_property_editor(p_path, editor);
- return true;
- }
- return false;
-}
-
-/*************************************************************************/
-
-OpenTypeFeaturesEditorPlugin::OpenTypeFeaturesEditorPlugin() {
- Ref<EditorInspectorPluginOpenTypeFeatures> ftr_plugin;
- ftr_plugin.instantiate();
- EditorInspector::add_inspector_plugin(ftr_plugin);
-}
diff --git a/editor/plugins/ot_features_plugin.h b/editor/plugins/ot_features_plugin.h
deleted file mode 100644
index 6639148080..0000000000
--- a/editor/plugins/ot_features_plugin.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*************************************************************************/
-/* ot_features_plugin.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef OT_FEATURES_PLUGIN_H
-#define OT_FEATURES_PLUGIN_H
-
-#include "editor/editor_plugin.h"
-#include "editor/editor_properties.h"
-
-/*************************************************************************/
-
-class OpenTypeFeaturesEditor : public EditorProperty {
- GDCLASS(OpenTypeFeaturesEditor, EditorProperty);
- EditorSpinSlider *spin = nullptr;
- bool setting = true;
- void _value_changed(double p_val);
- Button *button = nullptr;
-
- void _remove_feature();
-
-protected:
- void _notification(int p_what);
- static void _bind_methods();
-
-public:
- virtual void update_property() override;
- OpenTypeFeaturesEditor();
-};
-
-/*************************************************************************/
-
-class OpenTypeFeaturesAdd : public Button {
- GDCLASS(OpenTypeFeaturesAdd, Button);
-
- Object *edited_object = nullptr;
- PopupMenu *menu = nullptr;
- PopupMenu *menu_ss = nullptr;
- PopupMenu *menu_cv = nullptr;
- PopupMenu *menu_cu = nullptr;
-
- void _add_feature(int p_option);
- void _features_menu();
-
-protected:
- void _notification(int p_what);
- static void _bind_methods();
-
-public:
- void setup(Object *p_object);
-
- OpenTypeFeaturesAdd();
-};
-
-/*************************************************************************/
-
-class EditorInspectorPluginOpenTypeFeatures : public EditorInspectorPlugin {
- GDCLASS(EditorInspectorPluginOpenTypeFeatures, EditorInspectorPlugin);
-
-public:
- virtual bool can_handle(Object *p_object) override;
- virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false) override;
-};
-
-/*************************************************************************/
-
-class OpenTypeFeaturesEditorPlugin : public EditorPlugin {
- GDCLASS(OpenTypeFeaturesEditorPlugin, EditorPlugin);
-
-public:
- OpenTypeFeaturesEditorPlugin();
-
- virtual String get_name() const override { return "OpenTypeFeatures"; }
-};
-
-#endif // OT_FEATURES_PLUGIN_H
diff --git a/editor/plugins/replication_editor_plugin.cpp b/editor/plugins/replication_editor_plugin.cpp
index 72fe3c5f20..3e06a6739f 100644
--- a/editor/plugins/replication_editor_plugin.cpp
+++ b/editor/plugins/replication_editor_plugin.cpp
@@ -171,7 +171,7 @@ ReplicationEditor::ReplicationEditor() {
add_child(delete_dialog);
error_dialog = memnew(AcceptDialog);
- error_dialog->get_ok_button()->set_text(TTR("Close"));
+ error_dialog->set_ok_button_text(TTR("Close"));
error_dialog->set_title(TTR("Error!"));
add_child(error_dialog);
@@ -242,7 +242,7 @@ ReplicationEditor::ReplicationEditor() {
drop_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
drop_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
tree->add_child(drop_label);
- drop_label->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ drop_label->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
tree->set_drag_forwarding(this);
}
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index 79fc304242..4e528ef066 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -57,7 +57,7 @@ void ResourcePreloaderEditor::_files_load_request(const Vector<String> &p_paths)
dialog->set_text(TTR("ERROR: Couldn't load resource!"));
dialog->set_title(TTR("Error!"));
//dialog->get_cancel()->set_text("Close");
- dialog->get_ok_button()->set_text(TTR("Close"));
+ dialog->set_ok_button_text(TTR("Close"));
dialog->popup_centered();
return; ///beh should show an error i guess
}
@@ -139,7 +139,7 @@ void ResourcePreloaderEditor::_paste_pressed() {
if (!r.is_valid()) {
dialog->set_text(TTR("Resource clipboard is empty!"));
dialog->set_title(TTR("Error!"));
- dialog->get_ok_button()->set_text(TTR("Close"));
+ dialog->set_ok_button_text(TTR("Close"));
dialog->popup_centered();
return; ///beh should show an error i guess
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 6ab2366a44..f4d42ff456 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -377,7 +377,7 @@ ScriptEditorQuickOpen::ScriptEditorQuickOpen() {
search_box->connect("gui_input", callable_mp(this, &ScriptEditorQuickOpen::_sbox_input));
search_options = memnew(Tree);
vbc->add_margin_child(TTR("Matches:"), search_options, true);
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
get_ok_button()->set_disabled(true);
register_text_enter(search_box);
set_hide_on_ok(false);
@@ -1188,7 +1188,7 @@ void ScriptEditor::_menu_option(int p_option) {
file_dialog->clear_filters();
for (const String &E : textfile_extensions) {
- file_dialog->add_filter("*." + E + " ; " + E.to_upper());
+ file_dialog->add_filter("*." + E, E.to_upper());
}
file_dialog->popup_file_dialog();
file_dialog->set_title(TTR("New Text File..."));
@@ -1203,11 +1203,11 @@ void ScriptEditor::_menu_option(int p_option) {
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
file_dialog->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
- file_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
+ file_dialog->add_filter("*." + extensions[i], extensions[i].to_upper());
}
for (const String &E : textfile_extensions) {
- file_dialog->add_filter("*." + E + " ; " + E.to_upper());
+ file_dialog->add_filter("*." + E, E.to_upper());
}
file_dialog->popup_file_dialog();
@@ -3883,7 +3883,7 @@ ScriptEditor::ScriptEditor() {
tab_container->connect("tab_changed", callable_mp(this, &ScriptEditor::_tab_changed));
erase_tab_confirm = memnew(ConfirmationDialog);
- erase_tab_confirm->get_ok_button()->set_text(TTR("Save"));
+ erase_tab_confirm->set_ok_button_text(TTR("Save"));
erase_tab_confirm->add_button(TTR("Discard"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard");
erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab), varray(true));
erase_tab_confirm->connect("custom_action", callable_mp(this, &ScriptEditor::_close_discard_current_tab));
@@ -3916,7 +3916,7 @@ ScriptEditor::ScriptEditor() {
disk_changed_list->set_v_size_flags(SIZE_EXPAND_FILL);
disk_changed->connect("confirmed", callable_mp(this, &ScriptEditor::_reload_scripts));
- disk_changed->get_ok_button()->set_text(TTR("Reload"));
+ disk_changed->set_ok_button_text(TTR("Reload"));
disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave");
disk_changed->connect("custom_action", callable_mp(this, &ScriptEditor::_resave_scripts));
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 7d4ffd1a25..14e3eb5402 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -886,6 +886,9 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
emit_signal(SNAME("go_to_help"), "class_enum:" + result.class_name + ":" + result.class_member);
} break;
+ case ScriptLanguage::LOOKUP_RESULT_CLASS_ANNOTATION: {
+ emit_signal(SNAME("go_to_help"), "class_annotation:" + result.class_name + ":" + result.class_member);
+ } break;
case ScriptLanguage::LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE: {
emit_signal(SNAME("go_to_help"), "class_global:" + result.class_name + ":" + result.class_member);
} break;
@@ -1417,7 +1420,9 @@ Control *ScriptTextEditor::get_edit_menu() {
}
void ScriptTextEditor::clear_edit_menu() {
- memdelete(edit_hb);
+ if (editor_enabled) {
+ memdelete(edit_hb);
+ }
}
void ScriptTextEditor::set_find_replace_bar(FindReplaceBar *p_bar) {
@@ -1818,7 +1823,7 @@ void ScriptTextEditor::_enable_code_editor() {
VSplitContainer *editor_box = memnew(VSplitContainer);
add_child(editor_box);
- editor_box->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ editor_box->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
editor_box->set_v_size_flags(SIZE_EXPAND_FILL);
editor_box->add_child(code_editor);
@@ -1857,20 +1862,10 @@ void ScriptTextEditor::_enable_code_editor() {
color_picker = memnew(ColorPicker);
color_picker->set_deferred_mode(true);
color_picker->connect("color_changed", callable_mp(this, &ScriptTextEditor::_color_changed));
+ color_panel->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(color_picker));
color_panel->add_child(color_picker);
- // get default color picker mode from editor settings
- int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
- if (default_color_mode == 1) {
- color_picker->set_hsv_mode(true);
- } else if (default_color_mode == 2) {
- color_picker->set_raw_mode(true);
- }
-
- int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
- color_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
-
quick_open = memnew(ScriptEditorQuickOpen);
quick_open->connect("goto_line", callable_mp(this, &ScriptTextEditor::_goto_line));
add_child(quick_open);
@@ -1959,7 +1954,7 @@ void ScriptTextEditor::_enable_code_editor() {
ScriptTextEditor::ScriptTextEditor() {
code_editor = memnew(CodeTextEditor);
code_editor->add_theme_constant_override("separation", 2);
- code_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ code_editor->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
code_editor->set_code_complete_func(_code_complete_scripts, this);
code_editor->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 04b407ce65..70b8c3aaa7 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -706,7 +706,7 @@ ShaderEditor::ShaderEditor() {
shader_editor = memnew(ShaderTextEditor);
shader_editor->set_v_size_flags(SIZE_EXPAND_FILL);
shader_editor->add_theme_constant_override("separation", 0);
- shader_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ shader_editor->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
shader_editor->connect("show_warnings_panel", callable_mp(this, &ShaderEditor::_show_warnings_panel));
shader_editor->connect("script_changed", callable_mp(this, &ShaderEditor::apply_shaders));
@@ -797,7 +797,7 @@ ShaderEditor::ShaderEditor() {
VSplitContainer *editor_box = memnew(VSplitContainer);
main_container->add_child(editor_box);
- editor_box->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ editor_box->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
editor_box->set_v_size_flags(SIZE_EXPAND_FILL);
editor_box->add_child(shader_editor);
@@ -830,7 +830,7 @@ ShaderEditor::ShaderEditor() {
vbc->add_child(dl);
disk_changed->connect("confirmed", callable_mp(this, &ShaderEditor::_reload_shader_from_disk));
- disk_changed->get_ok_button()->set_text(TTR("Reload"));
+ disk_changed->set_ok_button_text(TTR("Reload"));
disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave");
disk_changed->connect("custom_action", callable_mp(this, &ShaderEditor::save_external_data));
@@ -889,12 +889,12 @@ void ShaderEditorPlugin::edit(Object *p_object) {
Ref<VisualShader> vs = es.shader;
if (vs.is_valid()) {
es.visual_shader_editor = memnew(VisualShaderEditor);
- es.visual_shader_editor->edit(vs.ptr());
shader_tabs->add_child(es.visual_shader_editor);
+ es.visual_shader_editor->edit(vs.ptr());
} else {
es.shader_editor = memnew(ShaderEditor);
- es.shader_editor->edit(s);
shader_tabs->add_child(es.shader_editor);
+ es.shader_editor->edit(s);
}
shader_tabs->set_current_tab(shader_tabs->get_tab_count() - 1);
edited_shaders.push_back(es);
@@ -923,6 +923,15 @@ ShaderEditor *ShaderEditorPlugin::get_shader_editor(const Ref<Shader> &p_for_sha
return nullptr;
}
+VisualShaderEditor *ShaderEditorPlugin::get_visual_shader_editor(const Ref<Shader> &p_for_shader) {
+ for (uint32_t i = 0; i < edited_shaders.size(); i++) {
+ if (edited_shaders[i].shader == p_for_shader) {
+ return edited_shaders[i].visual_shader_editor;
+ }
+ }
+ return nullptr;
+}
+
void ShaderEditorPlugin::save_external_data() {
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
if (edited_shaders[i].shader_editor) {
@@ -950,6 +959,7 @@ void ShaderEditorPlugin::_close_shader(int p_index) {
memdelete(c);
edited_shaders.remove_at(index);
_update_shader_list();
+ EditorNode::get_singleton()->get_undo_redo()->clear_history(); // To prevent undo on deleted graphs.
}
void ShaderEditorPlugin::_resource_saved(Object *obj) {
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index e1e815f939..2e0dbe0d60 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -209,6 +209,7 @@ public:
virtual void selected_notify() override;
ShaderEditor *get_shader_editor(const Ref<Shader> &p_for_shader);
+ VisualShaderEditor *get_visual_shader_editor(const Ref<Shader> &p_for_shader);
virtual void save_external_data() override;
virtual void apply_changes() override;
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 8845fe9eca..93e44c8ca0 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -42,6 +42,7 @@
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/resources/capsule_shape_3d.h"
+#include "scene/resources/skeleton_profile.h"
#include "scene/resources/sphere_shape_3d.h"
#include "scene/resources/surface_tool.h"
@@ -250,6 +251,10 @@ void Skeleton3DEditor::_on_click_skeleton_option(int p_skeleton_option) {
create_physical_skeleton();
break;
}
+ case SKELETON_OPTION_EXPORT_SKELETON_PROFILE: {
+ export_skeleton_profile();
+ break;
+ }
}
}
@@ -451,6 +456,73 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi
return physical_bone;
}
+void Skeleton3DEditor::export_skeleton_profile() {
+ file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
+ file_dialog->set_title(TTR("Export Skeleton Profile As..."));
+
+ List<String> exts;
+ ResourceLoader::get_recognized_extensions_for_type("SkeletonProfile", &exts);
+ file_dialog->clear_filters();
+ for (const String &K : exts) {
+ file_dialog->add_filter("*." + K);
+ }
+
+ file_dialog->popup_file_dialog();
+}
+
+void Skeleton3DEditor::_file_selected(const String &p_file) {
+ // Export SkeletonProfile.
+ Ref<SkeletonProfile> sp(memnew(SkeletonProfile));
+
+ // Build SkeletonProfile.
+ sp->set_group_size(1);
+
+ Vector<Vector2> handle_positions;
+ Vector2 position_max;
+ Vector2 position_min;
+
+ int len = skeleton->get_bone_count();
+ sp->set_bone_size(len);
+ for (int i = 0; i < len; i++) {
+ sp->set_bone_name(i, skeleton->get_bone_name(i));
+ int parent = skeleton->get_bone_parent(i);
+ if (parent >= 0) {
+ sp->set_bone_parent(i, skeleton->get_bone_name(parent));
+ }
+ sp->set_reference_pose(i, skeleton->get_bone_rest(i));
+
+ Transform3D grest = skeleton->get_bone_global_rest(i);
+ handle_positions.append(Vector2(grest.origin.x, grest.origin.y));
+ if (i == 0) {
+ position_max = Vector2(grest.origin.x, grest.origin.y);
+ position_min = Vector2(grest.origin.x, grest.origin.y);
+ } else {
+ position_max.x = MAX(grest.origin.x, position_max.x);
+ position_max.y = MAX(grest.origin.y, position_max.y);
+ position_min.x = MIN(grest.origin.x, position_min.x);
+ position_min.y = MIN(grest.origin.y, position_min.y);
+ }
+ }
+
+ // Layout handles provisionaly.
+ Vector2 bound = Vector2(position_max.x - position_min.x, position_max.y - position_min.y);
+ Vector2 center = Vector2((position_max.x + position_min.x) * 0.5, (position_max.y + position_min.y) * 0.5);
+ float nrm = MAX(bound.x, bound.y);
+ if (nrm > 0) {
+ for (int i = 0; i < len; i++) {
+ handle_positions.write[i] = (handle_positions[i] - center) / nrm * 0.9;
+ sp->set_handle_offset(i, Vector2(0.5 + handle_positions[i].x, 0.5 - handle_positions[i].y));
+ }
+ }
+
+ Error err = ResourceSaver::save(p_file, sp);
+
+ if (err != OK) {
+ EditorNode::get_singleton()->show_warning(vformat(TTR("Error saving file: %s"), p_file));
+ return;
+ }
+}
+
Variant Skeleton3DEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
TreeItem *selected = joint_tree->get_selected();
@@ -631,6 +703,11 @@ void Skeleton3DEditor::create_editors() {
Node3DEditor *ne = Node3DEditor::get_singleton();
AnimationTrackEditor *te = AnimationPlayerEditor::get_singleton()->get_track_editor();
+ // Create File dialog.
+ file_dialog = memnew(EditorFileDialog);
+ file_dialog->connect("file_selected", callable_mp(this, &Skeleton3DEditor::_file_selected));
+ add_child(file_dialog);
+
// Create Top Menu Bar.
separator = memnew(VSeparator);
ne->add_control_to_menu_panel(separator);
@@ -649,6 +726,7 @@ void Skeleton3DEditor::create_editors() {
p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/all_poses_to_rests", TTR("Apply all poses to rests")), SKELETON_OPTION_ALL_POSES_TO_RESTS);
p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/selected_poses_to_rests", TTR("Apply selected poses to rests")), SKELETON_OPTION_SELECTED_POSES_TO_RESTS);
p->add_item(TTR("Create physical skeleton"), SKELETON_OPTION_CREATE_PHYSICAL_SKELETON);
+ p->add_item(TTR("Export skeleton profile"), SKELETON_OPTION_EXPORT_SKELETON_PROFILE);
p->connect("id_pressed", callable_mp(this, &Skeleton3DEditor::_on_click_skeleton_option));
set_bone_options_enabled(false);
diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h
index 8f03e7c8db..975b54fa77 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.h
+++ b/editor/plugins/skeleton_3d_editor_plugin.h
@@ -101,6 +101,7 @@ class Skeleton3DEditor : public VBoxContainer {
SKELETON_OPTION_ALL_POSES_TO_RESTS,
SKELETON_OPTION_SELECTED_POSES_TO_RESTS,
SKELETON_OPTION_CREATE_PHYSICAL_SKELETON,
+ SKELETON_OPTION_EXPORT_SKELETON_PROFILE,
};
struct BoneInfo {
@@ -155,6 +156,8 @@ class Skeleton3DEditor : public VBoxContainer {
void create_physical_skeleton();
PhysicalBone3D *create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos);
+ void export_skeleton_profile();
+
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;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp
index ad817f9a41..3323d865c2 100644
--- a/editor/plugins/sprite_2d_editor_plugin.cpp
+++ b/editor/plugins/sprite_2d_editor_plugin.cpp
@@ -122,7 +122,7 @@ void Sprite2DEditor::_menu_option(int p_option) {
switch (p_option) {
case MENU_OPTION_CONVERT_TO_MESH_2D: {
- debug_uv_dialog->get_ok_button()->set_text(TTR("Create MeshInstance2D"));
+ debug_uv_dialog->set_ok_button_text(TTR("Create MeshInstance2D"));
debug_uv_dialog->set_title(TTR("MeshInstance2D Preview"));
_update_mesh_data();
@@ -131,7 +131,7 @@ void Sprite2DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CONVERT_TO_POLYGON_2D: {
- debug_uv_dialog->get_ok_button()->set_text(TTR("Create Polygon2D"));
+ debug_uv_dialog->set_ok_button_text(TTR("Create Polygon2D"));
debug_uv_dialog->set_title(TTR("Polygon2D Preview"));
_update_mesh_data();
@@ -139,7 +139,7 @@ void Sprite2DEditor::_menu_option(int p_option) {
debug_uv->update();
} break;
case MENU_OPTION_CREATE_COLLISION_POLY_2D: {
- debug_uv_dialog->get_ok_button()->set_text(TTR("Create CollisionPolygon2D"));
+ debug_uv_dialog->set_ok_button_text(TTR("Create CollisionPolygon2D"));
debug_uv_dialog->set_title(TTR("CollisionPolygon2D Preview"));
_update_mesh_data();
@@ -148,7 +148,7 @@ void Sprite2DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CREATE_LIGHT_OCCLUDER_2D: {
- debug_uv_dialog->get_ok_button()->set_text(TTR("Create LightOccluder2D"));
+ debug_uv_dialog->set_ok_button_text(TTR("Create LightOccluder2D"));
debug_uv_dialog->set_title(TTR("LightOccluder2D Preview"));
_update_mesh_data();
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 8a40ffbe38..0b6c0a9f0c 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -119,7 +119,7 @@ void SpriteFramesEditor::_sheet_preview_draw() {
if (frames_selected.size() == 0) {
split_sheet_dialog->get_ok_button()->set_disabled(true);
- split_sheet_dialog->get_ok_button()->set_text(TTR("No Frames Selected"));
+ split_sheet_dialog->set_ok_button_text(TTR("No Frames Selected"));
return;
}
@@ -140,7 +140,7 @@ void SpriteFramesEditor::_sheet_preview_draw() {
}
split_sheet_dialog->get_ok_button()->set_disabled(false);
- split_sheet_dialog->get_ok_button()->set_text(vformat(TTR("Add %d Frame(s)"), frames_selected.size()));
+ split_sheet_dialog->set_ok_button_text(vformat(TTR("Add %d Frame(s)"), frames_selected.size()));
}
void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) {
@@ -423,6 +423,7 @@ void SpriteFramesEditor::_notification(int p_what) {
zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
new_anim->set_icon(get_theme_icon(SNAME("New"), SNAME("EditorIcons")));
remove_anim->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ anim_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
split_sheet_zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons")));
split_sheet_zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons")));
split_sheet_zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons")));
@@ -449,7 +450,7 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_
dialog->set_title(TTR("Error!"));
//dialog->get_cancel()->set_text("Close");
- dialog->get_ok_button()->set_text(TTR("Close"));
+ dialog->set_ok_button_text(TTR("Close"));
dialog->popup_centered();
return; ///beh should show an error i guess
}
@@ -516,7 +517,7 @@ void SpriteFramesEditor::_paste_pressed() {
dialog->set_text(TTR("Resource clipboard is empty or not a texture!"));
dialog->set_title(TTR("Error!"));
//dialog->get_cancel()->set_text("Close");
- dialog->get_ok_button()->set_text(TTR("Close"));
+ dialog->set_ok_button_text(TTR("Close"));
dialog->popup_centered();
return; ///beh should show an error i guess
}
@@ -750,7 +751,7 @@ void SpriteFramesEditor::_animation_name_edited() {
undo_redo->add_do_method(this, "_update_library");
undo_redo->add_undo_method(this, "_update_library");
- edited_anim = new_name;
+ edited_anim = name;
undo_redo->commit_action();
}
@@ -816,6 +817,10 @@ void SpriteFramesEditor::_animation_remove_confirmed() {
undo_redo->commit_action();
}
+void SpriteFramesEditor::_animation_search_text_changed(const String &p_text) {
+ _update_library();
+}
+
void SpriteFramesEditor::_animation_loop_changed() {
if (updating) {
return;
@@ -900,14 +905,19 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
TreeItem *anim_root = animations->create_item();
List<StringName> anim_names;
-
frames->get_animation_list(&anim_names);
-
anim_names.sort_custom<StringName::AlphCompare>();
+ bool searching = anim_search_box->get_text().size();
+ String searched_string = searching ? anim_search_box->get_text().to_lower() : String();
+
for (const StringName &E : anim_names) {
String name = E;
+ if (searching && name.to_lower().find(searched_string) < 0) {
+ continue;
+ }
+
TreeItem *it = animations->create_item(anim_root);
it->set_metadata(0, name);
@@ -970,7 +980,6 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
anim_loop->set_pressed(frames->get_animation_loop(edited_anim));
updating = false;
- //player->add_resource("default",resource);
}
void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
@@ -1157,6 +1166,13 @@ SpriteFramesEditor::SpriteFramesEditor() {
hbc_animlist->add_child(remove_anim);
remove_anim->connect("pressed", callable_mp(this, &SpriteFramesEditor::_animation_remove));
+ anim_search_box = memnew(LineEdit);
+ hbc_animlist->add_child(anim_search_box);
+ anim_search_box->set_h_size_flags(SIZE_EXPAND_FILL);
+ anim_search_box->set_placeholder(TTR("Filter Animations"));
+ anim_search_box->set_clear_button_enabled(true);
+ anim_search_box->connect("text_changed", callable_mp(this, &SpriteFramesEditor::_animation_search_text_changed));
+
animations = memnew(Tree);
sub_vb->add_child(animations);
animations->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1448,6 +1464,10 @@ SpriteFramesEditor::SpriteFramesEditor() {
max_sheet_zoom = 16.0f * MAX(1.0f, EDSCALE);
min_sheet_zoom = 0.01f * MAX(1.0f, EDSCALE);
_zoom_reset();
+
+ // Ensure the anim search box is wide enough by default.
+ // Not by setting its minimum size so it can still be shrinked if desired.
+ set_split_offset(56 * EDSCALE);
}
void SpriteFramesEditorPlugin::edit(Object *p_object) {
diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h
index 3c8c5ef19d..6352259b73 100644
--- a/editor/plugins/sprite_frames_editor_plugin.h
+++ b/editor/plugins/sprite_frames_editor_plugin.h
@@ -37,6 +37,7 @@
#include "scene/gui/check_button.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/item_list.h"
+#include "scene/gui/line_edit.h"
#include "scene/gui/scroll_container.h"
#include "scene/gui/spin_box.h"
#include "scene/gui/split_container.h"
@@ -73,6 +74,7 @@ class SpriteFramesEditor : public HSplitContainer {
Button *new_anim = nullptr;
Button *remove_anim = nullptr;
+ LineEdit *anim_search_box = nullptr;
Tree *animations = nullptr;
SpinBox *anim_speed = nullptr;
@@ -137,6 +139,7 @@ class SpriteFramesEditor : public HSplitContainer {
void _animation_add();
void _animation_remove();
void _animation_remove_confirmed();
+ void _animation_search_text_changed(const String &p_text);
void _animation_loop_changed();
void _animation_fps_changed(double p_value);
diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp
index 1281ce0cfd..d4baff34e2 100644
--- a/editor/plugins/style_box_editor_plugin.cpp
+++ b/editor/plugins/style_box_editor_plugin.cpp
@@ -132,7 +132,7 @@ StyleBoxPreview::StyleBoxPreview() {
preview->set_clip_contents(true);
preview->connect("draw", callable_mp(this, &StyleBoxPreview::_redraw));
checkerboard->add_child(preview);
- preview->set_anchors_and_offsets_preset(PRESET_WIDE);
+ preview->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
add_margin_child(TTR("Preview:"), checkerboard);
grid_preview = memnew(TextureButton);
diff --git a/editor/plugins/text_control_editor_plugin.cpp b/editor/plugins/text_control_editor_plugin.cpp
deleted file mode 100644
index 2a5faba4a2..0000000000
--- a/editor/plugins/text_control_editor_plugin.cpp
+++ /dev/null
@@ -1,660 +0,0 @@
-/*************************************************************************/
-/* text_control_editor_plugin.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "text_control_editor_plugin.h"
-
-#include "editor/editor_node.h"
-#include "editor/editor_scale.h"
-#include "editor/multi_node_edit.h"
-
-void TextControlEditor::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- if (!EditorFileSystem::get_singleton()->is_connected("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts))) {
- EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts), make_binds(""));
- }
- [[fallthrough]];
- }
- case NOTIFICATION_THEME_CHANGED: {
- clear_formatting->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- } break;
-
- case NOTIFICATION_EXIT_TREE: {
- if (EditorFileSystem::get_singleton()->is_connected("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts))) {
- EditorFileSystem::get_singleton()->disconnect("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts));
- }
- } break;
- }
-}
-
-void TextControlEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_update_control"), &TextControlEditor::_update_control);
-}
-
-void TextControlEditor::_find_resources(EditorFileSystemDirectory *p_dir) {
- for (int i = 0; i < p_dir->get_subdir_count(); i++) {
- _find_resources(p_dir->get_subdir(i));
- }
-
- for (int i = 0; i < p_dir->get_file_count(); i++) {
- if (p_dir->get_file_type(i) == "FontData") {
- Ref<FontData> fd = ResourceLoader::load(p_dir->get_file_path(i));
- if (fd.is_valid()) {
- String name = fd->get_font_name();
- String sty = fd->get_font_style_name();
- if (sty.is_empty()) {
- sty = "Default";
- }
- fonts[name][sty] = p_dir->get_file_path(i);
- }
- }
- }
-}
-
-void TextControlEditor::_reload_fonts(const String &p_path) {
- fonts.clear();
- _find_resources(EditorFileSystem::get_singleton()->get_filesystem());
- _update_control();
-}
-
-void TextControlEditor::_update_fonts_menu() {
- font_list->clear();
- font_list->add_item(TTR("[Theme Default]"), FONT_INFO_THEME_DEFAULT);
- if (custom_font.is_valid()) {
- font_list->add_item(TTR("[Custom Font]"), FONT_INFO_USER_CUSTOM);
- }
-
- int id = FONT_INFO_ID;
- for (const KeyValue<String, HashMap<String, String>> &E : fonts) {
- font_list->add_item(E.key, id++);
- }
-
- if (font_list->get_item_count() > 1) {
- font_list->show();
- } else {
- font_list->hide();
- }
-}
-
-void TextControlEditor::_update_styles_menu() {
- font_style_list->clear();
- if ((font_list->get_selected_id() >= FONT_INFO_ID)) {
- const String &name = font_list->get_item_text(font_list->get_selected());
- for (KeyValue<String, String> &E : fonts[name]) {
- font_style_list->add_item(E.key);
- }
- } else if (font_list->get_selected() >= 0) {
- font_style_list->add_item("Default");
- }
-
- if (font_style_list->get_item_count() > 1) {
- font_style_list->show();
- } else {
- font_style_list->hide();
- }
-}
-
-void TextControlEditor::_update_control() {
- if (!edited_controls.is_empty()) {
- String font_selected;
- bool same_font = true;
- String style_selected;
- bool same_style = true;
- int font_size = 0;
- bool same_font_size = true;
- int outline_size = 0;
- bool same_outline_size = true;
- Color font_color = Color{ 1.0f, 1.0f, 1.0f };
- bool same_font_color = true;
- Color outline_color = Color{ 1.0f, 1.0f, 1.0f };
- bool same_outline_color = true;
-
- int count = edited_controls.size();
- for (int i = 0; i < count; ++i) {
- Control *edited_control = edited_controls[i];
-
- StringName edited_color;
- StringName edited_font;
- StringName edited_font_size;
-
- // Get override names.
- if (Object::cast_to<RichTextLabel>(edited_control)) {
- edited_color = SNAME("default_color");
- edited_font = SNAME("normal_font");
- edited_font_size = SNAME("normal_font_size");
- } else {
- edited_color = SNAME("font_color");
- edited_font = SNAME("font");
- edited_font_size = SNAME("font_size");
- }
-
- // Get font override.
- Ref<Font> font;
- if (edited_control->has_theme_font_override(edited_font)) {
- font = edited_control->get_theme_font(edited_font);
- }
-
- if (font.is_valid()) {
- if (font->get_data_count() != 1) {
- if (i > 0) {
- same_font = same_font && (custom_font == font);
- }
- custom_font = font;
-
- font_selected = TTR("[Custom Font]");
- same_style = false;
- } else {
- String name = font->get_data(0)->get_font_name();
- String style = font->get_data(0)->get_font_style_name();
- if (fonts.has(name) && fonts[name].has(style)) {
- if (i > 0) {
- same_font = same_font && (name == font_selected);
- same_style = same_style && (style == style_selected);
- }
- font_selected = name;
- style_selected = style;
- } else {
- if (i > 0) {
- same_font = same_font && (custom_font == font);
- }
- custom_font = font;
-
- font_selected = TTR("[Custom Font]");
- same_style = false;
- }
- }
- } else {
- if (i > 0) {
- same_font = same_font && (font_selected == TTR("[Theme Default]"));
- }
-
- font_selected = TTR("[Theme Default]");
- same_style = false;
- }
-
- int current_font_size = edited_control->get_theme_font_size(edited_font_size);
- int current_outline_size = edited_control->get_theme_constant(SNAME("outline_size"));
- Color current_font_color = edited_control->get_theme_color(edited_color);
- Color current_outline_color = edited_control->get_theme_color(SNAME("font_outline_color"));
- if (i > 0) {
- same_font_size = same_font_size && (font_size == current_font_size);
- same_outline_size = same_outline_size && (outline_size == current_outline_size);
- same_font_color = same_font_color && (font_color == current_font_color);
- same_outline_color = same_outline_color && (outline_color == current_outline_color);
- }
-
- font_size = current_font_size;
- outline_size = current_outline_size;
- font_color = current_font_color;
- outline_color = current_outline_color;
- }
- _update_fonts_menu();
- if (same_font) {
- for (int j = 0; j < font_list->get_item_count(); j++) {
- if (font_list->get_item_text(j) == font_selected) {
- font_list->select(j);
- break;
- }
- }
- } else {
- custom_font = Ref<Font>();
- font_list->select(-1);
- }
-
- _update_styles_menu();
- if (same_style) {
- for (int j = 0; j < font_style_list->get_item_count(); j++) {
- if (font_style_list->get_item_text(j) == style_selected) {
- font_style_list->select(j);
- break;
- }
- }
- } else {
- font_style_list->select(-1);
- }
-
- // Get other theme overrides.
- font_size_list->set_block_signals(true);
- if (same_font_size) {
- font_size_list->get_line_edit()->set_text(String::num_uint64(font_size));
- font_size_list->set_value(font_size);
- } else {
- font_size_list->get_line_edit()->set_text("");
- }
- font_size_list->set_block_signals(false);
-
- outline_size_list->set_block_signals(true);
- if (same_outline_size) {
- outline_size_list->get_line_edit()->set_text(String::num_uint64(outline_size));
- outline_size_list->set_value(outline_size);
- } else {
- outline_size_list->get_line_edit()->set_text("");
- }
- outline_size_list->set_block_signals(false);
-
- if (!same_font_color) {
- font_color = Color{ 1.0f, 1.0f, 1.0f };
- }
- font_color_picker->set_pick_color(font_color);
-
- if (!same_outline_color) {
- outline_color = Color{ 1.0f, 1.0f, 1.0f };
- }
- outline_color_picker->set_pick_color(outline_color);
- }
-}
-
-void TextControlEditor::_font_selected(int p_id) {
- _update_styles_menu();
- _set_font();
-}
-
-void TextControlEditor::_font_style_selected(int p_id) {
- _set_font();
-}
-
-void TextControlEditor::_set_font() {
- if (edited_controls.is_empty()) {
- return;
- }
-
- UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Set Font"));
-
- int count = edited_controls.size();
- for (int i = 0; i < count; ++i) {
- Control *edited_control = edited_controls[i];
-
- StringName edited_font;
- if (Object::cast_to<RichTextLabel>(edited_control)) {
- edited_font = SNAME("normal_font");
- } else {
- edited_font = SNAME("font");
- }
-
- if (font_list->get_selected_id() == FONT_INFO_THEME_DEFAULT) {
- // Remove font override.
- ur->add_do_method(edited_control, "remove_theme_font_override", edited_font);
- } else if (font_list->get_selected_id() == FONT_INFO_USER_CUSTOM) {
- // Restore "custom_font".
- ur->add_do_method(edited_control, "add_theme_font_override", edited_font, custom_font);
- } else if (font_list->get_selected() >= 0) {
- // Load new font resource using selected name and style.
- String name = font_list->get_item_text(font_list->get_selected());
- String style = font_style_list->get_item_text(font_style_list->get_selected());
- if (style.is_empty()) {
- style = "Default";
- }
- if (fonts.has(name)) {
- Ref<FontData> fd = ResourceLoader::load(fonts[name][style]);
- if (fd.is_valid()) {
- Ref<Font> font;
- font.instantiate();
- font->add_data(fd);
- ur->add_do_method(edited_control, "add_theme_font_override", edited_font, font);
- }
- }
- }
-
- if (edited_control->has_theme_font_override(edited_font)) {
- ur->add_undo_method(edited_control, "add_theme_font_override", edited_font, edited_control->get_theme_font(edited_font));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_font_override", edited_font);
- }
- }
-
- ur->add_do_method(this, "_update_control");
- ur->add_undo_method(this, "_update_control");
-
- ur->commit_action();
-}
-
-void TextControlEditor::_font_size_selected(double p_size) {
- if (edited_controls.is_empty()) {
- return;
- }
-
- UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Set Font Size"));
-
- int count = edited_controls.size();
- for (int i = 0; i < count; ++i) {
- Control *edited_control = edited_controls[i];
-
- StringName edited_font_size;
- if (Object::cast_to<RichTextLabel>(edited_control)) {
- edited_font_size = SNAME("normal_font_size");
- } else {
- edited_font_size = SNAME("font_size");
- }
-
- ur->add_do_method(edited_control, "add_theme_font_size_override", edited_font_size, p_size);
- if (edited_control->has_theme_font_size_override(edited_font_size)) {
- ur->add_undo_method(edited_control, "add_theme_font_size_override", edited_font_size, edited_control->get_theme_font_size(edited_font_size));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_font_size_override", edited_font_size);
- }
- }
-
- ur->add_do_method(this, "_update_control");
- ur->add_undo_method(this, "_update_control");
-
- ur->commit_action();
-}
-
-void TextControlEditor::_outline_size_selected(double p_size) {
- if (edited_controls.is_empty()) {
- return;
- }
-
- UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Set Font Outline Size"));
-
- int count = edited_controls.size();
- for (int i = 0; i < count; ++i) {
- Control *edited_control = edited_controls[i];
-
- ur->add_do_method(edited_control, "add_theme_constant_override", "outline_size", p_size);
- if (edited_control->has_theme_constant_override("outline_size")) {
- ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant(SNAME("outline_size")));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_constant_override", "outline_size");
- }
- }
-
- ur->add_do_method(this, "_update_control");
- ur->add_undo_method(this, "_update_control");
-
- ur->commit_action();
-}
-
-void TextControlEditor::_font_color_changed(const Color &p_color) {
- if (edited_controls.is_empty()) {
- return;
- }
-
- UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Set Font Color"), UndoRedo::MERGE_ENDS);
-
- int count = edited_controls.size();
- for (int i = 0; i < count; ++i) {
- Control *edited_control = edited_controls[i];
-
- StringName edited_color;
- if (Object::cast_to<RichTextLabel>(edited_control)) {
- edited_color = SNAME("default_color");
- } else {
- edited_color = SNAME("font_color");
- }
-
- ur->add_do_method(edited_control, "add_theme_color_override", edited_color, p_color);
- if (edited_control->has_theme_color_override(edited_color)) {
- ur->add_undo_method(edited_control, "add_theme_color_override", edited_color, edited_control->get_theme_color(edited_color));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_color_override", edited_color);
- }
- }
-
- ur->add_do_method(this, "_update_control");
- ur->add_undo_method(this, "_update_control");
-
- ur->commit_action();
-}
-
-void TextControlEditor::_outline_color_changed(const Color &p_color) {
- if (edited_controls.is_empty()) {
- return;
- }
-
- UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Set Font Outline Color"), UndoRedo::MERGE_ENDS);
-
- int count = edited_controls.size();
- for (int i = 0; i < count; ++i) {
- Control *edited_control = edited_controls[i];
-
- ur->add_do_method(edited_control, "add_theme_color_override", "font_outline_color", p_color);
- if (edited_control->has_theme_color_override("font_outline_color")) {
- ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color(SNAME("font_outline_color")));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_color_override", "font_outline_color");
- }
- }
-
- ur->add_do_method(this, "_update_control");
- ur->add_undo_method(this, "_update_control");
-
- ur->commit_action();
-}
-
-void TextControlEditor::_clear_formatting() {
- if (edited_controls.is_empty()) {
- return;
- }
-
- UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Clear Control Formatting"));
-
- int count = edited_controls.size();
- for (int i = 0; i < count; ++i) {
- Control *edited_control = edited_controls[i];
-
- StringName edited_color;
- StringName edited_font;
- StringName edited_font_size;
-
- // Get override names.
- if (Object::cast_to<RichTextLabel>(edited_control)) {
- edited_color = SNAME("default_color");
- edited_font = SNAME("normal_font");
- edited_font_size = SNAME("normal_font_size");
- } else {
- edited_color = SNAME("font_color");
- edited_font = SNAME("font");
- edited_font_size = SNAME("font_size");
- }
-
- ur->add_do_method(edited_control, "begin_bulk_theme_override");
- ur->add_undo_method(edited_control, "begin_bulk_theme_override");
-
- ur->add_do_method(edited_control, "remove_theme_font_override", edited_font);
- if (edited_control->has_theme_font_override(edited_font)) {
- ur->add_undo_method(edited_control, "add_theme_font_override", edited_font, edited_control->get_theme_font(edited_font));
- }
-
- ur->add_do_method(edited_control, "remove_theme_font_size_override", edited_font_size);
- if (edited_control->has_theme_font_size_override(edited_font_size)) {
- ur->add_undo_method(edited_control, "add_theme_font_size_override", edited_font_size, edited_control->get_theme_font_size(edited_font_size));
- }
-
- ur->add_do_method(edited_control, "remove_theme_color_override", edited_color);
- if (edited_control->has_theme_color_override(edited_color)) {
- ur->add_undo_method(edited_control, "add_theme_color_override", edited_color, edited_control->get_theme_color(edited_color));
- }
-
- ur->add_do_method(edited_control, "remove_theme_color_override", "font_outline_color");
- if (edited_control->has_theme_color_override("font_outline_color")) {
- ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color(SNAME("font_outline_color")));
- }
-
- ur->add_do_method(edited_control, "remove_theme_constant_override", "outline_size");
- if (edited_control->has_theme_constant_override("outline_size")) {
- ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant(SNAME("outline_size")));
- }
-
- ur->add_do_method(edited_control, "end_bulk_theme_override");
- ur->add_undo_method(edited_control, "end_bulk_theme_override");
- }
-
- ur->add_do_method(this, "_update_control");
- ur->add_undo_method(this, "_update_control");
-
- ur->commit_action();
-}
-
-void TextControlEditor::edit(Object *p_object) {
- Control *ctrl = Object::cast_to<Control>(p_object);
- MultiNodeEdit *multi_node = Object::cast_to<MultiNodeEdit>(p_object);
-
- edited_controls.clear();
- custom_font = Ref<Font>();
- if (ctrl) {
- edited_controls.append(ctrl);
- _update_control();
- } else if (multi_node && handles(multi_node)) {
- int count = multi_node->get_node_count();
- Node *scene = EditorNode::get_singleton()->get_edited_scene();
-
- for (int i = 0; i < count; ++i) {
- Control *child = Object::cast_to<Control>(scene->get_node(multi_node->get_node(i)));
- edited_controls.append(child);
- }
- _update_control();
- }
-}
-
-bool TextControlEditor::handles(Object *p_object) const {
- Control *ctrl = Object::cast_to<Control>(p_object);
- MultiNodeEdit *multi_node = Object::cast_to<MultiNodeEdit>(p_object);
-
- if (!ctrl && !multi_node) {
- return false;
- } else if (ctrl) {
- bool valid = false;
- ctrl->get("text", &valid);
- return valid;
- } else {
- bool valid = true;
- int count = multi_node->get_node_count();
- Node *scene = EditorNode::get_singleton()->get_edited_scene();
-
- for (int i = 0; i < count; ++i) {
- bool temp_valid = false;
- Control *child = Object::cast_to<Control>(scene->get_node(multi_node->get_node(i)));
- if (child) {
- child->get("text", &temp_valid);
- }
- valid = valid && temp_valid;
-
- if (!valid) {
- break;
- }
- }
-
- return valid;
- }
-}
-
-TextControlEditor::TextControlEditor() {
- add_child(memnew(VSeparator));
-
- font_list = memnew(OptionButton);
- font_list->set_flat(true);
- font_list->set_tooltip(TTR("Font"));
- add_child(font_list);
- font_list->connect("item_selected", callable_mp(this, &TextControlEditor::_font_selected));
-
- font_style_list = memnew(OptionButton);
- font_style_list->set_flat(true);
- font_style_list->set_tooltip(TTR("Font style"));
- font_style_list->set_toggle_mode(true);
- add_child(font_style_list);
- font_style_list->connect("item_selected", callable_mp(this, &TextControlEditor::_font_style_selected));
-
- font_size_list = memnew(SpinBox);
- font_size_list->set_tooltip(TTR("Font Size"));
- font_size_list->get_line_edit()->add_theme_constant_override("minimum_character_width", 2);
- font_size_list->set_min(6);
- font_size_list->set_step(1);
- font_size_list->set_max(96);
- font_size_list->get_line_edit()->set_flat(true);
- add_child(font_size_list);
- font_size_list->connect("value_changed", callable_mp(this, &TextControlEditor::_font_size_selected));
-
- font_color_picker = memnew(ColorPickerButton);
- font_color_picker->set_custom_minimum_size(Size2(20, 0) * EDSCALE);
- font_color_picker->set_flat(true);
- font_color_picker->set_tooltip(TTR("Text Color"));
- add_child(font_color_picker);
- font_color_picker->connect("color_changed", callable_mp(this, &TextControlEditor::_font_color_changed));
-
- add_child(memnew(VSeparator));
-
- outline_size_list = memnew(SpinBox);
- outline_size_list->set_tooltip(TTR("Outline Size"));
- outline_size_list->get_line_edit()->add_theme_constant_override("minimum_character_width", 2);
- outline_size_list->set_min(0);
- outline_size_list->set_step(1);
- outline_size_list->set_max(96);
- outline_size_list->get_line_edit()->set_flat(true);
- add_child(outline_size_list);
- outline_size_list->connect("value_changed", callable_mp(this, &TextControlEditor::_outline_size_selected));
-
- outline_color_picker = memnew(ColorPickerButton);
- outline_color_picker->set_custom_minimum_size(Size2(20, 0) * EDSCALE);
- outline_color_picker->set_flat(true);
- outline_color_picker->set_tooltip(TTR("Outline Color"));
- add_child(outline_color_picker);
- outline_color_picker->connect("color_changed", callable_mp(this, &TextControlEditor::_outline_color_changed));
-
- add_child(memnew(VSeparator));
-
- clear_formatting = memnew(Button);
- clear_formatting->set_flat(true);
- clear_formatting->set_tooltip(TTR("Clear Formatting"));
- add_child(clear_formatting);
- clear_formatting->connect("pressed", callable_mp(this, &TextControlEditor::_clear_formatting));
-}
-
-/*************************************************************************/
-
-void TextControlEditorPlugin::edit(Object *p_object) {
- text_ctl_editor->edit(p_object);
-}
-
-bool TextControlEditorPlugin::handles(Object *p_object) const {
- return text_ctl_editor->handles(p_object);
-}
-
-void TextControlEditorPlugin::make_visible(bool p_visible) {
- if (p_visible) {
- text_ctl_editor->show();
- } else {
- text_ctl_editor->hide();
- text_ctl_editor->edit(nullptr);
- }
-}
-
-TextControlEditorPlugin::TextControlEditorPlugin() {
- text_ctl_editor = memnew(TextControlEditor);
- CanvasItemEditor::get_singleton()->add_control_to_menu_panel(text_ctl_editor);
-
- text_ctl_editor->hide();
-}
diff --git a/editor/plugins/text_control_editor_plugin.h b/editor/plugins/text_control_editor_plugin.h
deleted file mode 100644
index cf069338b6..0000000000
--- a/editor/plugins/text_control_editor_plugin.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*************************************************************************/
-/* text_control_editor_plugin.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef TEXT_CONTROL_EDITOR_PLUGIN_H
-#define TEXT_CONTROL_EDITOR_PLUGIN_H
-
-#include "canvas_item_editor_plugin.h"
-#include "editor/editor_file_system.h"
-#include "editor/editor_inspector.h"
-#include "editor/editor_plugin.h"
-#include "scene/gui/color_picker.h"
-#include "scene/gui/color_rect.h"
-#include "scene/gui/menu_button.h"
-#include "scene/gui/option_button.h"
-#include "scene/gui/popup_menu.h"
-
-/*************************************************************************/
-
-class TextControlEditor : public HBoxContainer {
- GDCLASS(TextControlEditor, HBoxContainer);
-
- enum FontInfoID {
- FONT_INFO_THEME_DEFAULT = 0,
- FONT_INFO_USER_CUSTOM = 1,
- FONT_INFO_ID = 100,
- };
-
- HashMap<String, HashMap<String, String>> fonts;
-
- OptionButton *font_list = nullptr;
- SpinBox *font_size_list = nullptr;
- OptionButton *font_style_list = nullptr;
- ColorPickerButton *font_color_picker = nullptr;
- SpinBox *outline_size_list = nullptr;
- ColorPickerButton *outline_color_picker = nullptr;
- Button *clear_formatting = nullptr;
-
- Vector<Control *> edited_controls;
- Ref<Font> custom_font;
-
-protected:
- void _notification(int p_what);
- static void _bind_methods();
-
- void _find_resources(EditorFileSystemDirectory *p_dir);
- void _reload_fonts(const String &p_path);
-
- void _update_fonts_menu();
- void _update_styles_menu();
- void _update_control();
-
- void _font_selected(int p_id);
- void _font_style_selected(int p_id);
- void _set_font();
-
- void _font_size_selected(double p_size);
- void _outline_size_selected(double p_size);
-
- void _font_color_changed(const Color &p_color);
- void _outline_color_changed(const Color &p_color);
-
- void _clear_formatting();
-
-public:
- void edit(Object *p_object);
- bool handles(Object *p_object) const;
-
- TextControlEditor();
-};
-
-/*************************************************************************/
-
-class TextControlEditorPlugin : public EditorPlugin {
- GDCLASS(TextControlEditorPlugin, EditorPlugin);
-
- TextControlEditor *text_ctl_editor = nullptr;
-
-public:
- virtual String get_name() const override { return "TextControlFontEditor"; }
- bool has_main_screen() const override { return false; }
- virtual void edit(Object *p_object) override;
- virtual bool handles(Object *p_object) const override;
- virtual void make_visible(bool p_visible) override;
-
- TextControlEditorPlugin();
-};
-
-#endif // TEXT_CONTROL_EDITOR_PLUGIN_H
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 7ca65c073d..84caede081 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -524,7 +524,7 @@ TextEditor::TextEditor() {
code_editor->add_theme_constant_override("separation", 0);
code_editor->connect("load_theme_settings", callable_mp(this, &TextEditor::_load_theme_settings));
code_editor->connect("validate_script", callable_mp(this, &TextEditor::_validate_script));
- code_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ code_editor->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
code_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
code_editor->show_toggle_scripts_button();
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 15f03fd46d..f6b02d5f80 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -59,7 +59,7 @@ void TexturePreview::_notification(int p_what) {
}
void TexturePreview::_update_metadata_label_text() {
- Ref<Texture2D> texture = texture_display->get_texture();
+ const Ref<Texture2D> texture = texture_display->get_texture();
String format;
if (Object::cast_to<ImageTexture>(*texture)) {
@@ -70,7 +70,49 @@ void TexturePreview::_update_metadata_label_text() {
format = texture->get_class();
}
- metadata_label->set_text(vformat(String::utf8("%s×%s %s"), itos(texture->get_width()), itos(texture->get_height()), format));
+ const Ref<Image> image = texture->get_image();
+ if (image.is_valid()) {
+ const int mipmaps = image->get_mipmap_count();
+ // Avoid signed integer overflow that could occur with huge texture sizes by casting everything to uint64_t.
+ uint64_t memory = uint64_t(image->get_width()) * uint64_t(image->get_height()) * uint64_t(Image::get_format_pixel_size(image->get_format()));
+ // Handle VRAM-compressed formats that are stored with 4 bpp.
+ memory >>= Image::get_format_pixel_rshift(image->get_format());
+
+ float mipmaps_multiplier = 1.0;
+ float mipmap_increase = 0.25;
+ for (int i = 0; i < mipmaps; i++) {
+ // Each mip adds 25% memory usage of the previous one.
+ // With a complete mipmap chain, memory usage increases by ~33%.
+ mipmaps_multiplier += mipmap_increase;
+ mipmap_increase *= 0.25;
+ }
+ memory *= mipmaps_multiplier;
+
+ if (mipmaps >= 1) {
+ metadata_label->set_text(
+ vformat(String::utf8("%d×%d %s\n") + TTR("%s Mipmaps") + "\n" + TTR("Memory: %s"),
+ texture->get_width(),
+ texture->get_height(),
+ format,
+ mipmaps,
+ String::humanize_size(memory)));
+ } else {
+ // "No Mipmaps" is easier to distinguish than "0 Mipmaps",
+ // especially since 0, 6, and 8 look quite close with the default code font.
+ metadata_label->set_text(
+ vformat(String::utf8("%d×%d %s\n") + TTR("No Mipmaps") + "\n" + TTR("Memory: %s"),
+ texture->get_width(),
+ texture->get_height(),
+ format,
+ String::humanize_size(memory)));
+ }
+ } else {
+ metadata_label->set_text(
+ vformat(String::utf8("%d×%d %s"),
+ texture->get_width(),
+ texture->get_height(),
+ format));
+ }
}
TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) {
@@ -82,7 +124,7 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) {
texture_display = memnew(TextureRect);
texture_display->set_texture(p_texture);
- texture_display->set_anchors_preset(TextureRect::PRESET_WIDE);
+ texture_display->set_anchors_preset(TextureRect::PRESET_FULL_RECT);
texture_display->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
texture_display->set_ignore_texture_size(true);
add_child(texture_display);
@@ -97,11 +139,9 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) {
metadata_label->add_theme_color_override("font_color", Color::named("white"));
metadata_label->add_theme_color_override("font_color_shadow", Color::named("black"));
- metadata_label->add_theme_font_size_override("font_size", 16 * EDSCALE);
+ metadata_label->add_theme_font_size_override("font_size", 14 * EDSCALE);
metadata_label->add_theme_color_override("font_outline_color", Color::named("black"));
- metadata_label->add_theme_constant_override("outline_size", 2 * EDSCALE);
-
- metadata_label->add_theme_constant_override("shadow_outline_size", 1);
+ metadata_label->add_theme_constant_override("outline_size", 8 * EDSCALE);
metadata_label->set_h_size_flags(Control::SIZE_SHRINK_END);
metadata_label->set_v_size_flags(Control::SIZE_SHRINK_END);
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 3f4f9a4f4d..dd98247428 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -989,7 +989,7 @@ Vector2 TextureRegionEditor::snap_point(Vector2 p_target) const {
}
TextureRegionEditor::TextureRegionEditor() {
- get_ok_button()->set_text(TTR("Close"));
+ set_ok_button_text(TTR("Close"));
VBoxContainer *vb = memnew(VBoxContainer);
add_child(vb);
node_sprite_2d = nullptr;
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index c7dc61b3a8..744ed1f1a2 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -70,9 +70,17 @@ void ThemeItemImportTree::_update_items_tree() {
for (const StringName &E : types) {
String type_name = (String)E;
+ Ref<Texture2D> type_icon;
+ if (E == "") {
+ type_icon = get_theme_icon(SNAME("NodeDisabled"), SNAME("EditorIcons"));
+ } else {
+ type_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled");
+ }
+
TreeItem *type_node = import_items_tree->create_item(root);
type_node->set_meta("_can_be_imported", false);
type_node->set_collapsed(true);
+ type_node->set_icon(0, type_icon);
type_node->set_text(0, type_name);
type_node->set_cell_mode(IMPORT_ITEM, TreeItem::CELL_MODE_CHECK);
type_node->set_checked(IMPORT_ITEM, false);
@@ -214,7 +222,7 @@ void ThemeItemImportTree::_update_items_tree() {
if (color_amount > 0) {
Array arr;
arr.push_back(color_amount);
- select_colors_label->set_text(TTRN("One color", "{num} colors", color_amount).format(arr, "{num}"));
+ select_colors_label->set_text(TTRN("1 color", "{num} colors", color_amount).format(arr, "{num}"));
select_all_colors_button->set_visible(true);
select_full_colors_button->set_visible(true);
deselect_all_colors_button->set_visible(true);
@@ -228,7 +236,7 @@ void ThemeItemImportTree::_update_items_tree() {
if (constant_amount > 0) {
Array arr;
arr.push_back(constant_amount);
- select_constants_label->set_text(TTRN("One constant", "{num} constants", constant_amount).format(arr, "{num}"));
+ select_constants_label->set_text(TTRN("1 constant", "{num} constants", constant_amount).format(arr, "{num}"));
select_all_constants_button->set_visible(true);
select_full_constants_button->set_visible(true);
deselect_all_constants_button->set_visible(true);
@@ -242,7 +250,7 @@ void ThemeItemImportTree::_update_items_tree() {
if (font_amount > 0) {
Array arr;
arr.push_back(font_amount);
- select_fonts_label->set_text(TTRN("One font", "{num} fonts", font_amount).format(arr, "{num}"));
+ select_fonts_label->set_text(TTRN("1 font", "{num} fonts", font_amount).format(arr, "{num}"));
select_all_fonts_button->set_visible(true);
select_full_fonts_button->set_visible(true);
deselect_all_fonts_button->set_visible(true);
@@ -256,7 +264,7 @@ void ThemeItemImportTree::_update_items_tree() {
if (font_size_amount > 0) {
Array arr;
arr.push_back(font_size_amount);
- select_font_sizes_label->set_text(TTRN("One font size", "{num} font sizes", font_size_amount).format(arr, "{num}"));
+ select_font_sizes_label->set_text(TTRN("1 font size", "{num} font sizes", font_size_amount).format(arr, "{num}"));
select_all_font_sizes_button->set_visible(true);
select_full_font_sizes_button->set_visible(true);
deselect_all_font_sizes_button->set_visible(true);
@@ -270,7 +278,7 @@ void ThemeItemImportTree::_update_items_tree() {
if (icon_amount > 0) {
Array arr;
arr.push_back(icon_amount);
- select_icons_label->set_text(TTRN("One icon", "{num} icons", icon_amount).format(arr, "{num}"));
+ select_icons_label->set_text(TTRN("1 icon", "{num} icons", icon_amount).format(arr, "{num}"));
select_all_icons_button->set_visible(true);
select_full_icons_button->set_visible(true);
deselect_all_icons_button->set_visible(true);
@@ -286,7 +294,7 @@ void ThemeItemImportTree::_update_items_tree() {
if (stylebox_amount > 0) {
Array arr;
arr.push_back(stylebox_amount);
- select_styleboxes_label->set_text(TTRN("One stylebox", "{num} styleboxes", stylebox_amount).format(arr, "{num}"));
+ select_styleboxes_label->set_text(TTRN("1 stylebox", "{num} styleboxes", stylebox_amount).format(arr, "{num}"));
select_all_styleboxes_button->set_visible(true);
select_full_styleboxes_button->set_visible(true);
deselect_all_styleboxes_button->set_visible(true);
@@ -1170,6 +1178,8 @@ ThemeItemImportTree::ThemeItemImportTree() {
import_add_selected_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_import_selected));
}
+///////////////////////
+
void ThemeItemEditorDialog::ok_pressed() {
if (import_default_theme_items->has_selected_items() || import_editor_theme_items->has_selected_items() || import_other_theme_items->has_selected_items()) {
confirm_closing_dialog->set_text(TTR("Import Items tab has some items selected. Selection will be lost upon closing this window.\nClose anyway?"));
@@ -1867,6 +1877,8 @@ void ThemeItemEditorDialog::_notification(int p_what) {
edit_items_remove_custom->set_icon(get_theme_icon(SNAME("ThemeRemoveCustomItems"), SNAME("EditorIcons")));
edit_items_remove_all->set_icon(get_theme_icon(SNAME("ThemeRemoveAllItems"), SNAME("EditorIcons")));
+ edit_add_type_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+
import_another_theme_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
} break;
}
@@ -1883,7 +1895,7 @@ void ThemeItemEditorDialog::set_edited_theme(const Ref<Theme> &p_theme) {
ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_editor) {
set_title(TTR("Manage Theme Items"));
- get_ok_button()->set_text(TTR("Close"));
+ set_ok_button_text(TTR("Close"));
set_hide_on_ok(false); // Closing may require a confirmation in some cases.
theme_type_editor = p_theme_type_editor;
@@ -1924,8 +1936,7 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito
edit_add_type_value->set_h_size_flags(Control::SIZE_EXPAND_FILL);
edit_add_type_value->connect("text_submitted", callable_mp(this, &ThemeItemEditorDialog::_add_theme_type));
edit_add_type_hb->add_child(edit_add_type_value);
- Button *edit_add_type_button = memnew(Button);
- edit_add_type_button->set_text(TTR("Add"));
+ edit_add_type_button = memnew(Button);
edit_add_type_hb->add_child(edit_add_type_button);
edit_add_type_button->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_add_theme_type), varray(""));
@@ -2017,7 +2028,7 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito
edit_items_tree->connect("button_clicked", callable_mp(this, &ThemeItemEditorDialog::_item_tree_button_pressed));
edit_items_message = memnew(Label);
- edit_items_message->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ edit_items_message->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
edit_items_message->set_mouse_filter(Control::MOUSE_FILTER_STOP);
edit_items_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
edit_items_message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
@@ -2080,7 +2091,7 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito
List<String> ext;
ResourceLoader::get_recognized_extensions_for_type("Theme", &ext);
for (const String &E : ext) {
- import_another_theme_dialog->add_filter(vformat("*.%s; %s", E, TTR("Theme Resource")));
+ import_another_theme_dialog->add_filter("*." + E, TTR("Theme Resource"));
}
import_another_file_hb->add_child(import_another_theme_dialog);
import_another_theme_dialog->connect("file_selected", callable_mp(this, &ThemeItemEditorDialog::_select_another_theme_cbk));
@@ -2099,6 +2110,8 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito
confirm_closing_dialog->connect("confirmed", callable_mp(this, &ThemeItemEditorDialog::_close_dialog));
}
+///////////////////////
+
void ThemeTypeDialog::_dialog_about_to_show() {
add_type_filter->set_text("");
add_type_filter->grab_focus();
@@ -2237,6 +2250,8 @@ ThemeTypeDialog::ThemeTypeDialog() {
add_child(add_type_confirmation);
}
+///////////////////////
+
VBoxContainer *ThemeTypeEditor::_create_item_list(Theme::DataType p_data_type) {
VBoxContainer *items_tab = memnew(VBoxContainer);
items_tab->set_custom_minimum_size(Size2(0, 160) * EDSCALE);
@@ -2477,6 +2492,7 @@ void ThemeTypeEditor::_update_type_items() {
if (E.value) {
item_editor->set_pick_color(edited_theme->get_color(E.key, edited_type));
item_editor->connect("color_changed", callable_mp(this, &ThemeTypeEditor::_color_item_changed), varray(E.key));
+ item_editor->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(item_editor->get_picker()));
} else {
item_editor->set_pick_color(Theme::get_default()->get_color(E.key, edited_type));
item_editor->set_disabled(true);
@@ -2733,7 +2749,7 @@ void ThemeTypeEditor::_list_type_selected(int p_index) {
void ThemeTypeEditor::_add_type_button_cbk() {
add_type_mode = ADD_THEME_TYPE;
add_type_dialog->set_title(TTR("Add Item Type"));
- add_type_dialog->get_ok_button()->set_text(TTR("Add Type"));
+ add_type_dialog->set_ok_button_text(TTR("Add Type"));
add_type_dialog->set_include_own_types(false);
add_type_dialog->popup_centered(Size2(560, 420) * EDSCALE);
}
@@ -2931,10 +2947,6 @@ void ThemeTypeEditor::_item_remove_cbk(int p_data_type, String p_item_name) {
ur->add_undo_method(*edited_theme, "set_font", p_item_name, edited_type, Ref<Font>());
}
} break;
- case Theme::DATA_TYPE_FONT_SIZE: {
- ur->add_do_method(*edited_theme, "clear_font_size", p_item_name, edited_type);
- ur->add_undo_method(*edited_theme, "set_font_size", p_item_name, edited_type, edited_theme->get_font_size(p_item_name, edited_type));
- } break;
case Theme::DATA_TYPE_ICON: {
ur->add_do_method(*edited_theme, "clear_icon", p_item_name, edited_type);
if (edited_theme->has_icon(p_item_name, edited_type)) {
@@ -3273,7 +3285,7 @@ void ThemeTypeEditor::_type_variation_changed(const String p_value) {
void ThemeTypeEditor::_add_type_variation_cbk() {
add_type_mode = ADD_VARIATION_BASE;
add_type_dialog->set_title(TTR("Set Variation Base Type"));
- add_type_dialog->get_ok_button()->set_text(TTR("Set Base Type"));
+ add_type_dialog->set_ok_button_text(TTR("Set Base Type"));
add_type_dialog->set_include_own_types(true);
add_type_dialog->popup_centered(Size2(560, 420) * EDSCALE);
}
@@ -3458,6 +3470,8 @@ ThemeTypeEditor::ThemeTypeEditor() {
add_child(update_debounce_timer);
}
+///////////////////////
+
void ThemeEditor::edit(const Ref<Theme> &p_theme) {
if (theme == p_theme) {
return;
@@ -3667,7 +3681,7 @@ ThemeEditor::ThemeEditor() {
List<String> ext;
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &ext);
for (const String &E : ext) {
- preview_scene_dialog->add_filter(vformat("*.%s; %s", E, TTR("Scene")));
+ preview_scene_dialog->add_filter("*." + E, TTR("Scene"));
}
main_hs->add_child(preview_scene_dialog);
preview_scene_dialog->connect("file_selected", callable_mp(this, &ThemeEditor::_preview_scene_dialog_cbk));
@@ -3676,6 +3690,8 @@ ThemeEditor::ThemeEditor() {
theme_type_editor->set_custom_minimum_size(Size2(280, 0) * EDSCALE);
}
+///////////////////////
+
void ThemeEditorPlugin::edit(Object *p_node) {
if (Object::cast_to<Theme>(p_node)) {
theme_editor->edit(Object::cast_to<Theme>(p_node));
@@ -3698,7 +3714,7 @@ bool ThemeEditorPlugin::handles(Object *p_node) const {
// If we are editing a theme already and this particular resource happens to belong to it,
// then we just keep editing it, despite not being able to directly handle it.
- // This only goes one layer deep, but if required this can be extended to support, say, FontData inside of Font.
+ // This only goes one layer deep, but if required this can be extended to support, say, Font inside of Font.
bool belongs_to_theme = false;
if (Object::cast_to<Font>(p_node)) {
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index 543113a5eb..9f89a047cb 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -198,6 +198,7 @@ class ThemeItemEditorDialog : public AcceptDialog {
Tree *edit_type_list = nullptr;
LineEdit *edit_add_type_value = nullptr;
+ Button *edit_add_type_button = nullptr;
String edited_item_type;
Button *edit_items_add_color = nullptr;
diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp
index a6e34cf5e0..0c7303dda4 100644
--- a/editor/plugins/theme_editor_preview.cpp
+++ b/editor/plugins/theme_editor_preview.cpp
@@ -126,7 +126,7 @@ void ThemeEditorPreview::_draw_picker_overlay() {
}
Rect2 highlight_label_rect = highlight_rect;
- highlight_label_rect.size = theme_cache.preview_picker_font->get_string_size(highlight_name, theme_cache.font_size);
+ highlight_label_rect.size = theme_cache.preview_picker_font->get_string_size(highlight_name, HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size);
int margin_top = theme_cache.preview_picker_label->get_margin(SIDE_TOP);
int margin_left = theme_cache.preview_picker_label->get_margin(SIDE_LEFT);
@@ -246,7 +246,7 @@ ThemeEditorPreview::ThemeEditorPreview() {
preview_root->set_h_size_flags(SIZE_EXPAND_FILL);
preview_bg = memnew(ColorRect);
- preview_bg->set_anchors_and_offsets_preset(PRESET_WIDE);
+ preview_bg->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
preview_bg->set_color(GLOBAL_GET("rendering/environment/defaults/default_clear_color"));
preview_root->add_child(preview_bg);
diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp
index e37878ff98..3fe6778f48 100644
--- a/editor/plugins/tiles/atlas_merging_dialog.cpp
+++ b/editor/plugins/tiles/atlas_merging_dialog.cpp
@@ -116,12 +116,8 @@ void AtlasMergingDialog::_generate_merged(Vector<Ref<TileSetAtlasSource>> p_atla
}
}
- Ref<ImageTexture> output_image_texture;
- output_image_texture.instantiate();
- output_image_texture->create_from_image(output_image);
-
merged->set_name(p_atlas_sources[0]->get_name());
- merged->set_texture(output_image_texture);
+ merged->set_texture(ImageTexture::create_from_image(output_image));
merged->set_texture_region_size(new_texture_region_size);
}
}
@@ -260,7 +256,7 @@ AtlasMergingDialog::AtlasMergingDialog() {
set_hide_on_ok(false);
// Ok buttons
- get_ok_button()->set_text(TTR("Merge (Keep original Atlases)"));
+ set_ok_button_text(TTR("Merge (Keep original Atlases)"));
get_ok_button()->set_disabled(true);
merge_button = add_button(TTR("Merge"), true, "merge");
merge_button->set_disabled(true);
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index 3073c8a7f2..f119ada810 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -544,7 +544,7 @@ TileAtlasView::TileAtlasView() {
Panel *panel = memnew(Panel);
panel->set_clip_contents(true);
panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
- panel->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ panel->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
panel->set_h_size_flags(SIZE_EXPAND_FILL);
panel->set_v_size_flags(SIZE_EXPAND_FILL);
add_child(panel);
@@ -613,32 +613,32 @@ TileAtlasView::TileAtlasView() {
background_left = memnew(Control);
background_left->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
- background_left->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ background_left->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
background_left->set_texture_repeat(TextureRepeat::TEXTURE_REPEAT_ENABLED);
background_left->connect("draw", callable_mp(this, &TileAtlasView::_draw_background_left));
base_tiles_root_control->add_child(background_left);
base_tiles_drawing_root = memnew(Control);
base_tiles_drawing_root->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
- base_tiles_drawing_root->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ base_tiles_drawing_root->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
base_tiles_drawing_root->set_texture_filter(TEXTURE_FILTER_NEAREST);
base_tiles_root_control->add_child(base_tiles_drawing_root);
base_tiles_draw = memnew(Control);
base_tiles_draw->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
- base_tiles_draw->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ base_tiles_draw->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
base_tiles_draw->connect("draw", callable_mp(this, &TileAtlasView::_draw_base_tiles));
base_tiles_drawing_root->add_child(base_tiles_draw);
base_tiles_texture_grid = memnew(Control);
base_tiles_texture_grid->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
- base_tiles_texture_grid->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ base_tiles_texture_grid->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
base_tiles_texture_grid->connect("draw", callable_mp(this, &TileAtlasView::_draw_base_tiles_texture_grid));
base_tiles_drawing_root->add_child(base_tiles_texture_grid);
base_tiles_shape_grid = memnew(Control);
base_tiles_shape_grid->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
- base_tiles_shape_grid->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ base_tiles_shape_grid->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
base_tiles_shape_grid->connect("draw", callable_mp(this, &TileAtlasView::_draw_base_tiles_shape_grid));
base_tiles_drawing_root->add_child(base_tiles_shape_grid);
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 468681c967..a00e1ed9e8 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -218,7 +218,7 @@ void GenericTilePolygonEditor::_base_control_draw() {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
String text = multiple_polygon_mode ? vformat("%d:%d", tinted_polygon_index, tinted_point_index) : vformat("%d", tinted_point_index);
- Size2 text_size = font->get_string_size(text, font_size);
+ Size2 text_size = font->get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
base_control->draw_string(font, xform.xform(polygons[tinted_polygon_index][tinted_point_index]) - text_size * 0.5, text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1.0, 1.0, 1.0, 0.5));
}
@@ -803,13 +803,13 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() {
add_child(root);
panel = memnew(Panel);
- panel->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ panel->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
root->add_child(panel);
base_control = memnew(Control);
base_control->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
- base_control->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ base_control->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
base_control->connect("draw", callable_mp(this, &GenericTilePolygonEditor::_base_control_draw));
base_control->connect("gui_input", callable_mp(this, &GenericTilePolygonEditor::_base_control_gui_input));
base_control->set_clip_contents(true);
@@ -1116,8 +1116,9 @@ void TileDataDefaultEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2
}
}
- Vector2 string_size = font->get_string_size(text, font_size);
- p_canvas_item->draw_string(font, p_transform.get_origin() + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, color, 1, Color(0, 0, 0, 1));
+ Vector2 string_size = font->get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
+ p_canvas_item->draw_string_outline(font, p_transform.get_origin() + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, 1, Color(0, 0, 0, 1));
+ p_canvas_item->draw_string(font, p_transform.get_origin() + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, color);
}
}
@@ -1727,8 +1728,9 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas
} else {
text = "-";
}
- Vector2 string_size = font->get_string_size(text, font_size);
- p_canvas_item->draw_string(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, color, 1, Color(0, 0, 0, 1));
+ Vector2 string_size = font->get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
+ p_canvas_item->draw_string_outline(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, 1, Color(0, 0, 0, 1));
+ p_canvas_item->draw_string(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, color);
}
}
}
@@ -1918,8 +1920,9 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til
} else {
text = "-";
}
- Vector2 string_size = font->get_string_size(text, font_size);
- p_canvas_item->draw_string(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, color, 1, Color(0, 0, 0, 1));
+ Vector2 string_size = font->get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size);
+ p_canvas_item->draw_string_outline(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, 1, Color(0, 0, 0, 1));
+ p_canvas_item->draw_string(font, p_transform.xform(position) + Vector2i(-string_size.x / 2, string_size.y / 2), text, HORIZONTAL_ALIGNMENT_CENTER, string_size.x, font_size, color);
}
}
}
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index d914b9c363..69a3d4e937 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -3212,7 +3212,7 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() {
terrains_tile_list->set_item_metadata(item_index, list_metadata_dict);
item_index = terrains_tile_list->add_icon_item(main_vbox_container->get_theme_icon(SNAME("TerrainPath"), SNAME("EditorIcons")));
- terrains_tile_list->set_item_tooltip(item_index, TTR("Path mode: paints a terrain, thens connects it to the previous tile painted withing the same stroke."));
+ terrains_tile_list->set_item_tooltip(item_index, TTR("Path mode: paints a terrain, thens connects it to the previous tile painted within the same stroke."));
list_metadata_dict = Dictionary();
list_metadata_dict["type"] = SELECTED_TYPE_PATH;
terrains_tile_list->set_item_metadata(item_index, list_metadata_dict);
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index 37ccc6ad45..20e548acba 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -2370,7 +2370,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
tile_data_editors_tree = memnew(Tree);
tile_data_editors_tree->set_hide_root(true);
- tile_data_editors_tree->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ tile_data_editors_tree->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
tile_data_editors_tree->set_h_scroll_enabled(false);
tile_data_editors_tree->set_v_scroll_enabled(false);
tile_data_editors_tree->connect("item_selected", callable_mp(this, &TileSetAtlasSourceEditor::_tile_data_editors_tree_selected));
@@ -2405,7 +2405,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
confirm_auto_create_tiles = memnew(AcceptDialog);
confirm_auto_create_tiles->set_title(TTR("Auto Create Tiles in Non-Transparent Texture Regions?"));
confirm_auto_create_tiles->set_text(TTR("The atlas's texture was modified.\nWould you like to automatically create tiles in the atlas?"));
- confirm_auto_create_tiles->get_ok_button()->set_text(TTR("Yes"));
+ confirm_auto_create_tiles->set_ok_button_text(TTR("Yes"));
confirm_auto_create_tiles->add_cancel_button()->set_text(TTR("No"));
confirm_auto_create_tiles->connect("confirmed", callable_mp(this, &TileSetAtlasSourceEditor::_auto_create_tiles));
add_child(confirm_auto_create_tiles);
@@ -2509,7 +2509,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
tile_atlas_view->add_control_over_atlas_tiles(tile_atlas_control);
tile_atlas_control_unscaled = memnew(Control);
- tile_atlas_control_unscaled->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ tile_atlas_control_unscaled->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
tile_atlas_control_unscaled->connect("draw", callable_mp(this, &TileSetAtlasSourceEditor::_tile_atlas_control_unscaled_draw));
tile_atlas_view->add_control_over_atlas_tiles(tile_atlas_control_unscaled, false);
tile_atlas_control_unscaled->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
@@ -2526,7 +2526,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
tile_atlas_view->add_control_over_alternative_tiles(alternative_tiles_control);
alternative_tiles_control_unscaled = memnew(Control);
- alternative_tiles_control_unscaled->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ alternative_tiles_control_unscaled->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
alternative_tiles_control_unscaled->connect("draw", callable_mp(this, &TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw));
tile_atlas_view->add_control_over_alternative_tiles(alternative_tiles_control_unscaled, false);
alternative_tiles_control_unscaled->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index 543304346e..419d0ffcfc 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -121,12 +121,9 @@ void TilesEditorPlugin::_thread() {
pattern_preview_done.wait();
Ref<Image> image = viewport->get_texture()->get_image();
- Ref<ImageTexture> image_texture;
- image_texture.instantiate();
- image_texture->create_from_image(image);
// Find the index for the given pattern. TODO: optimize.
- Variant args[] = { item.pattern, image_texture };
+ Variant args[] = { item.pattern, ImageTexture::create_from_image(image) };
const Variant *args_ptr[] = { &args[0], &args[1] };
Variant r;
Callable::CallError error;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 8c72a886ea..69a125a029 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_node.h"
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
+#include "editor/plugins/shader_editor_plugin.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"
@@ -72,6 +73,10 @@ const int MAX_FLOAT_CONST_DEFS = sizeof(float_constant_defs) / sizeof(FloatConst
///////////////////
+void VisualShaderNodePlugin::set_editor(VisualShaderEditor *p_editor) {
+ vseditor = p_editor;
+}
+
Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
Object *ret;
if (GDVIRTUAL_CALL(_create_editor, p_parent_resource, p_node, ret)) {
@@ -115,6 +120,10 @@ void VisualShaderGraphPlugin::_bind_methods() {
ClassDB::bind_method("update_curve_xyz", &VisualShaderGraphPlugin::update_curve_xyz);
}
+void VisualShaderGraphPlugin::set_editor(VisualShaderEditor *p_editor) {
+ editor = p_editor;
+}
+
void VisualShaderGraphPlugin::register_shader(VisualShader *p_shader) {
visual_shader = Ref<VisualShader>(p_shader);
}
@@ -186,10 +195,6 @@ void VisualShaderGraphPlugin::set_input_port_default_value(VisualShader::Type p_
switch (p_value.get_type()) {
case Variant::COLOR: {
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (!editor) {
- break;
- }
button->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
Callable ce = callable_mp(editor, &VisualShaderEditor::_draw_color_over_button);
@@ -337,10 +342,6 @@ void VisualShaderGraphPlugin::register_uniform_name(int p_node_id, LineEdit *p_u
}
void VisualShaderGraphPlugin::update_theme() {
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (!editor) {
- return;
- }
vector_expanded_color[0] = editor->get_theme_color(SNAME("axis_x_color"), SNAME("Editor")); // red
vector_expanded_color[1] = editor->get_theme_color(SNAME("axis_y_color"), SNAME("Editor")); // green
vector_expanded_color[2] = editor->get_theme_color(SNAME("axis_z_color"), SNAME("Editor")); // blue
@@ -351,10 +352,6 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
if (!visual_shader.is_valid() || p_type != visual_shader->get_shader_type()) {
return;
}
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (!editor) {
- return;
- }
GraphEdit *graph = editor->graph;
if (!graph) {
return;
@@ -474,6 +471,12 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
node->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
}
+ Ref<VisualShaderNodeUniformRef> uniform_ref = vsnode;
+ if (uniform_ref.is_valid()) {
+ uniform_ref->set_shader_rid(visual_shader->get_rid());
+ uniform_ref->update_uniform_type();
+ }
+
Ref<VisualShaderNodeUniform> uniform = vsnode;
HBoxContainer *hb = nullptr;
@@ -1035,10 +1038,6 @@ void VisualShaderGraphPlugin::remove_node(VisualShader::Type p_type, int p_id) {
}
void VisualShaderGraphPlugin::connect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (!editor) {
- return;
- }
GraphEdit *graph = editor->graph;
if (!graph) {
return;
@@ -1055,10 +1054,6 @@ void VisualShaderGraphPlugin::connect_nodes(VisualShader::Type p_type, int p_fro
}
void VisualShaderGraphPlugin::disconnect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (!editor) {
- return;
- }
GraphEdit *graph = editor->graph;
if (!graph) {
return;
@@ -1085,6 +1080,10 @@ VisualShaderGraphPlugin::~VisualShaderGraphPlugin() {
/////////////////
+Vector2 VisualShaderEditor::selection_center;
+List<VisualShaderEditor::CopyItem> VisualShaderEditor::copy_items_buffer;
+List<VisualShader::Connection> VisualShaderEditor::copy_connections_buffer;
+
void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
bool changed = false;
if (p_visual_shader) {
@@ -1602,7 +1601,7 @@ void VisualShaderEditor::_update_created_node(GraphNode *node) {
}
void VisualShaderEditor::_update_uniforms(bool p_update_refs) {
- VisualShaderNodeUniformRef::clear_uniforms();
+ VisualShaderNodeUniformRef::clear_uniforms(visual_shader->get_rid());
for (int t = 0; t < VisualShader::TYPE_MAX; t++) {
Vector<int> tnodes = visual_shader->get_node_list((VisualShader::Type)t);
@@ -1640,7 +1639,7 @@ void VisualShaderEditor::_update_uniforms(bool p_update_refs) {
} else {
uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_SAMPLER;
}
- VisualShaderNodeUniformRef::add_uniform(uniform->get_uniform_name(), uniform_type);
+ VisualShaderNodeUniformRef::add_uniform(visual_shader->get_rid(), uniform->get_uniform_name(), uniform_type);
}
}
}
@@ -2645,7 +2644,6 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri
_setup_node(vsn, p_ops);
}
VisualShaderNodeUniformRef *uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(vsn);
-
if (uniform_ref && to_node != -1 && to_slot != -1) {
VisualShaderNode::PortType input_port_type = visual_shader->get_node(type, to_node)->get_input_port_type(to_slot);
bool success = false;
@@ -4644,10 +4642,7 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_is_available", &VisualShaderEditor::_is_available);
}
-VisualShaderEditor *VisualShaderEditor::singleton = nullptr;
-
VisualShaderEditor::VisualShaderEditor() {
- singleton = this;
ShaderLanguage::get_keyword_list(&keyword_list);
graph = memnew(GraphEdit);
@@ -4911,7 +4906,7 @@ VisualShaderEditor::VisualShaderEditor() {
members_dialog->set_title(TTR("Create Shader Node"));
members_dialog->set_exclusive(false);
members_dialog->add_child(members_vb);
- members_dialog->get_ok_button()->set_text(TTR("Create"));
+ members_dialog->set_ok_button_text(TTR("Create"));
members_dialog->get_ok_button()->connect("pressed", callable_mp(this, &VisualShaderEditor::_member_create));
members_dialog->get_ok_button()->set_disabled(true);
members_dialog->connect("cancelled", callable_mp(this, &VisualShaderEditor::_member_cancel));
@@ -4922,7 +4917,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_varying_dialog = memnew(ConfirmationDialog);
add_varying_dialog->set_title(TTR("Create Shader Varying"));
add_varying_dialog->set_exclusive(false);
- add_varying_dialog->get_ok_button()->set_text(TTR("Create"));
+ add_varying_dialog->set_ok_button_text(TTR("Create"));
add_varying_dialog->get_ok_button()->connect("pressed", callable_mp(this, &VisualShaderEditor::_varying_create));
add_varying_dialog->get_ok_button()->set_disabled(true);
add_child(add_varying_dialog);
@@ -4966,7 +4961,7 @@ VisualShaderEditor::VisualShaderEditor() {
remove_varying_dialog = memnew(ConfirmationDialog);
remove_varying_dialog->set_title(TTR("Delete Shader Varying"));
remove_varying_dialog->set_exclusive(false);
- remove_varying_dialog->get_ok_button()->set_text(TTR("Delete"));
+ remove_varying_dialog->set_ok_button_text(TTR("Delete"));
remove_varying_dialog->get_ok_button()->connect("pressed", callable_mp(this, &VisualShaderEditor::_varying_deleted));
add_child(remove_varying_dialog);
@@ -5635,9 +5630,11 @@ VisualShaderEditor::VisualShaderEditor() {
Ref<VisualShaderNodePluginDefault> default_plugin;
default_plugin.instantiate();
+ default_plugin->set_editor(this);
add_plugin(default_plugin);
graph_plugin.instantiate();
+ graph_plugin->set_editor(this);
property_editor = memnew(CustomPropertyEditor);
add_child(property_editor);
@@ -5648,6 +5645,7 @@ VisualShaderEditor::VisualShaderEditor() {
class VisualShaderNodePluginInputEditor : public OptionButton {
GDCLASS(VisualShaderNodePluginInputEditor, OptionButton);
+ VisualShaderEditor *editor = nullptr;
Ref<VisualShaderNodeInput> input;
public:
@@ -5660,13 +5658,11 @@ public:
}
void _item_selected(int p_item) {
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (editor) {
- editor->call_deferred(SNAME("_input_select_item"), input, get_item_text(p_item));
- }
+ editor->call_deferred(SNAME("_input_select_item"), input, get_item_text(p_item));
}
- void setup(const Ref<VisualShaderNodeInput> &p_input) {
+ void setup(VisualShaderEditor *p_editor, const Ref<VisualShaderNodeInput> &p_input) {
+ editor = p_editor;
input = p_input;
Ref<Texture2D> type_icon[] = {
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
@@ -5699,6 +5695,7 @@ public:
class VisualShaderNodePluginVaryingEditor : public OptionButton {
GDCLASS(VisualShaderNodePluginVaryingEditor, OptionButton);
+ VisualShaderEditor *editor = nullptr;
Ref<VisualShaderNodeVarying> varying;
public:
@@ -5709,13 +5706,11 @@ public:
}
void _item_selected(int p_item) {
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (editor) {
- editor->call_deferred(SNAME("_varying_select_item"), varying, get_item_text(p_item));
- }
+ editor->call_deferred(SNAME("_varying_select_item"), varying, get_item_text(p_item));
}
- void setup(const Ref<VisualShaderNodeVarying> &p_varying, VisualShader::Type p_type) {
+ void setup(VisualShaderEditor *p_editor, const Ref<VisualShaderNodeVarying> &p_varying, VisualShader::Type p_type) {
+ editor = p_editor;
varying = p_varying;
Ref<Texture2D> type_icon[] = {
@@ -5776,6 +5771,7 @@ public:
class VisualShaderNodePluginUniformRefEditor : public OptionButton {
GDCLASS(VisualShaderNodePluginUniformRefEditor, OptionButton);
+ VisualShaderEditor *editor = nullptr;
Ref<VisualShaderNodeUniformRef> uniform_ref;
public:
@@ -5788,13 +5784,11 @@ public:
}
void _item_selected(int p_item) {
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (editor) {
- editor->call_deferred(SNAME("_uniform_select_item"), uniform_ref, get_item_text(p_item));
- }
+ editor->call_deferred(SNAME("_uniform_select_item"), uniform_ref, get_item_text(p_item));
}
- void setup(const Ref<VisualShaderNodeUniformRef> &p_uniform_ref) {
+ void setup(VisualShaderEditor *p_editor, const Ref<VisualShaderNodeUniformRef> &p_uniform_ref) {
+ editor = p_editor;
uniform_ref = p_uniform_ref;
Ref<Texture2D> type_icon[] = {
@@ -5828,6 +5822,7 @@ public:
class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer);
+ VisualShaderEditor *editor = nullptr;
Ref<Resource> parent_resource;
int node_id = 0;
VisualShader::Type shader_type;
@@ -5861,13 +5856,10 @@ public:
}
}
if (p_property != "constant") {
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (editor) {
- VisualShaderGraphPlugin *graph_plugin = editor->get_graph_plugin();
- if (graph_plugin) {
- undo_redo->add_do_method(graph_plugin, "update_node_deferred", shader_type, node_id);
- undo_redo->add_undo_method(graph_plugin, "update_node_deferred", shader_type, node_id);
- }
+ VisualShaderGraphPlugin *graph_plugin = editor->get_graph_plugin();
+ if (graph_plugin) {
+ undo_redo->add_do_method(graph_plugin, "update_node_deferred", shader_type, node_id);
+ undo_redo->add_undo_method(graph_plugin, "update_node_deferred", shader_type, node_id);
}
}
undo_redo->commit_action();
@@ -5903,7 +5895,8 @@ public:
}
}
- void setup(Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, const HashMap<StringName, String> &p_overrided_names, Ref<VisualShaderNode> p_node) {
+ void setup(VisualShaderEditor *p_editor, Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, const HashMap<StringName, String> &p_overrided_names, Ref<VisualShaderNode> p_node) {
+ editor = p_editor;
parent_resource = p_parent_resource;
updating = false;
node = p_node;
@@ -5956,19 +5949,19 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
if (p_shader.is_valid() && (p_node->is_class("VisualShaderNodeVaryingGetter") || p_node->is_class("VisualShaderNodeVaryingSetter"))) {
VisualShaderNodePluginVaryingEditor *editor = memnew(VisualShaderNodePluginVaryingEditor);
- editor->setup(p_node, p_shader->get_shader_type());
+ editor->setup(vseditor, p_node, p_shader->get_shader_type());
return editor;
}
if (p_node->is_class("VisualShaderNodeUniformRef")) {
VisualShaderNodePluginUniformRefEditor *editor = memnew(VisualShaderNodePluginUniformRefEditor);
- editor->setup(p_node);
+ editor->setup(vseditor, p_node);
return editor;
}
if (p_node->is_class("VisualShaderNodeInput")) {
VisualShaderNodePluginInputEditor *editor = memnew(VisualShaderNodePluginInputEditor);
- editor->setup(p_node);
+ editor->setup(vseditor, p_node);
return editor;
}
@@ -6023,22 +6016,22 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
properties.push_back(pinfo[i].name);
}
VisualShaderNodePluginDefaultEditor *editor = memnew(VisualShaderNodePluginDefaultEditor);
- editor->setup(p_parent_resource, editors, properties, p_node->get_editable_properties_names(), p_node);
+ editor->setup(vseditor, p_parent_resource, editors, properties, p_node->get_editable_properties_names(), p_node);
return editor;
}
void EditorPropertyShaderMode::_option_selected(int p_which) {
- VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
- if (!editor) {
+ Ref<VisualShader> visual_shader(Object::cast_to<VisualShader>(get_edited_object()));
+ if (visual_shader->get_mode() == p_which) {
return;
}
- //will not use this, instead will do all the logic setting manually
- //emit_signal(SNAME("property_changed"), get_edited_property(), p_which);
-
- Ref<VisualShader> visual_shader(Object::cast_to<VisualShader>(get_edited_object()));
-
- if (visual_shader->get_mode() == p_which) {
+ ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader"));
+ if (!shader_editor) {
+ return;
+ }
+ VisualShaderEditor *editor = shader_editor->get_visual_shader_editor(visual_shader);
+ if (!editor) {
return;
}
@@ -6145,10 +6138,10 @@ bool EditorInspectorShaderModePlugin::can_handle(Object *p_object) {
bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
if (p_path == "mode" && p_object->is_class("VisualShader") && p_type == Variant::INT) {
- EditorPropertyShaderMode *editor = memnew(EditorPropertyShaderMode);
+ EditorPropertyShaderMode *mode_editor = memnew(EditorPropertyShaderMode);
Vector<String> options = p_hint_text.split(",");
- editor->setup(options);
- add_property_editor(p_path, editor);
+ mode_editor->setup(options);
+ add_property_editor(p_path, mode_editor);
return true;
}
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index b8da266ed7..2feed6108a 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -42,15 +42,21 @@
#include "scene/gui/tree.h"
#include "scene/resources/visual_shader.h"
+class VisualShaderEditor;
+
class VisualShaderNodePlugin : public RefCounted {
GDCLASS(VisualShaderNodePlugin, RefCounted);
protected:
+ VisualShaderEditor *vseditor = nullptr;
+
+protected:
static void _bind_methods();
GDVIRTUAL2RC(Object *, _create_editor, Ref<Resource>, Ref<VisualShaderNode>)
public:
+ void set_editor(VisualShaderEditor *p_editor);
virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
};
@@ -58,6 +64,8 @@ class VisualShaderGraphPlugin : public RefCounted {
GDCLASS(VisualShaderGraphPlugin, RefCounted);
private:
+ VisualShaderEditor *editor = nullptr;
+
struct InputPort {
Button *default_input_button = nullptr;
};
@@ -91,6 +99,7 @@ protected:
static void _bind_methods();
public:
+ void set_editor(VisualShaderEditor *p_editor);
void register_shader(VisualShader *p_visual_shader);
void set_connections(const List<VisualShader::Connection> &p_connections);
void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node);
@@ -324,8 +333,6 @@ class VisualShaderEditor : public VBoxContainer {
void _update_preview();
String _get_description(int p_idx);
- static VisualShaderEditor *singleton;
-
struct DragOp {
VisualShader::Type type = VisualShader::Type::TYPE_MAX;
int node = 0;
@@ -403,9 +410,9 @@ class VisualShaderEditor : public VBoxContainer {
void _duplicate_nodes();
- Vector2 selection_center;
- List<CopyItem> copy_items_buffer;
- List<VisualShader::Connection> copy_connections_buffer;
+ static Vector2 selection_center;
+ static List<CopyItem> copy_items_buffer;
+ static List<VisualShader::Connection> copy_connections_buffer;
void _clear_copy_buffer();
void _copy_nodes(bool p_cut);
@@ -482,7 +489,6 @@ public:
void add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
void remove_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
- static VisualShaderEditor *get_singleton() { return singleton; }
VisualShaderGraphPlugin *get_graph_plugin() { return graph_plugin.ptr(); }
void clear_custom_types();
diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp
index ed13afc235..1c9afa8be8 100644
--- a/editor/progress_dialog.cpp
+++ b/editor/progress_dialog.cpp
@@ -50,7 +50,7 @@ void BackgroundProgress::_add_task(const String &p_task, const String &p_label,
Control *ec = memnew(Control);
ec->set_h_size_flags(SIZE_EXPAND_FILL);
ec->set_v_size_flags(SIZE_EXPAND_FILL);
- t.progress->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ t.progress->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
ec->add_child(t.progress);
ec->set_custom_minimum_size(Size2(80, 5) * EDSCALE);
t.hb->add_child(ec);
@@ -235,7 +235,7 @@ void ProgressDialog::_bind_methods() {
ProgressDialog::ProgressDialog() {
main = memnew(VBoxContainer);
add_child(main);
- main->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ main->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
set_exclusive(true);
last_progress_tick = 0;
singleton = this;
diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp
index dfe40f9d4f..6437e19404 100644
--- a/editor/project_converter_3_to_4.cpp
+++ b/editor/project_converter_3_to_4.cpp
@@ -110,6 +110,7 @@ static const char *enum_renames[][2] = {
{ "FORMAT_PVRTC2A", "FORMAT_PVRTC1_2A" }, // Image
{ "FORMAT_PVRTC4", "FORMAT_PVRTC1_4" }, // Image
{ "FORMAT_PVRTC4A", "FORMAT_PVRTC1_4A" }, // Image
+ { "FUNC_FRAC", "FUNC_FRACT" }, // VisualShaderNodeVectorFunc
{ "INSTANCE_LIGHTMAP_CAPTURE", "INSTANCE_LIGHTMAP" }, // RenderingServer
{ "JOINT_6DOF", "JOINT_TYPE_6DOF" }, // PhysicsServer3D
{ "JOINT_CONE_TWIST", "JOINT_TYPE_CONE_TWIST" }, // PhysicsServer3D
@@ -124,12 +125,14 @@ static const char *enum_renames[][2] = {
{ "MATH_RANDOM", "MATH_RANDI_RANGE" }, // VisualScriptBuiltinFunc
{ "MATH_STEPIFY", "MATH_STEP_DECIMALS" }, // VisualScriptBuiltinFunc
{ "MODE_CHARACTER", "MODE_DYNAMIC_LOCKED" }, // RigidBody2D, RigidBody3D
+ { "MODE_KINEMATIC", "FREEZE_MODE_KINEMATIC" }, // RigidDynamicBody
{ "MODE_OPEN_ANY", "FILE_MODE_OPEN_ANY" }, // FileDialog
{ "MODE_OPEN_DIR", "FILE_MODE_OPEN_DIR" }, // FileDialog
{ "MODE_OPEN_FILE", "FILE_MODE_OPEN_FILE" }, // FileDialog
{ "MODE_OPEN_FILES", "FILE_MODE_OPEN_FILES" }, // FileDialog
{ "MODE_RIGID", "MODE_DYNAMIC" }, // RigidBody2D, RigidBody3D
{ "MODE_SAVE_FILE", "FILE_MODE_SAVE_FILE" }, // FileDialog
+ { "MODE_STATIC", "FREEZE_MODE_STATIC" }, // RigidDynamicBody
{ "NOTIFICATION_APP_PAUSED", "NOTIFICATION_APPLICATION_PAUSED" }, // MainLoop
{ "NOTIFICATION_APP_RESUMED", "NOTIFICATION_APPLICATION_RESUMED" }, // MainLoop
{ "NOTIFICATION_PATH_CHANGED", "NOTIFICATION_PATH_RENAMED" }, //Node
@@ -208,7 +211,6 @@ static const char *gdscript_function_renames[][2] = {
// { "set_v_offset", "set_drag_vertical_offset" }, // Camera2D broke Camera3D, PathFollow3D, PathFollow2D
// {"get_points","get_points_id"},// Astar, broke Line2D, Convexpolygonshape
// {"get_v_scroll","get_v_scroll_bar"},//ItemList, broke TextView
- { "RenderingServer", "get_tab_alignment" }, // Tab
{ "_about_to_show", "_about_to_popup" }, // ColorPickerButton
{ "_get_configuration_warning", "_get_configuration_warnings" }, // Node
{ "_set_current", "set_current" }, // Camera2D
@@ -217,17 +219,20 @@ static const char *gdscript_function_renames[][2] = {
{ "_update_wrap_at", "_update_wrap_at_column" }, // TextEdit
{ "add_animation", "add_animation_library" }, // AnimationPlayer
{ "add_cancel", "add_cancel_button" }, // AcceptDialog
- { "add_central_force", "add_constant_central_force" }, //RigidDynamicBody2D
+ { "add_central_force", "apply_central_force" }, //RigidDynamicBody2D
{ "add_child_below_node", "add_sibling" }, // Node
{ "add_color_override", "add_theme_color_override" }, // Control
{ "add_constant_override", "add_theme_constant_override" }, // Control
{ "add_font_override", "add_theme_font_override" }, // Control
- { "add_force", "add_constant_force" }, //RigidDynamicBody2D
+ { "add_force", "apply_force" }, //RigidDynamicBody2D
{ "add_icon_override", "add_theme_icon_override" }, // Control
{ "add_scene_import_plugin", "add_scene_format_importer_plugin" }, //EditorPlugin
{ "add_stylebox_override", "add_theme_stylebox_override" }, // Control
- { "add_torque", "add_constant_torque" }, //RigidDynamicBody2D
+ { "add_torque", "apply_torque" }, //RigidDynamicBody2D
+ { "apply_changes", "_apply_changes" }, // EditorPlugin
{ "bind_child_node_to_bone", "set_bone_children" }, // Skeleton3D
+ { "body_add_force", "body_apply_force" }, // PhysicsServer2D
+ { "body_add_torque", "body_apply_torque" }, // PhysicsServer2D
{ "bumpmap_to_normalmap", "bump_map_to_normal_map" }, // Image
{ "can_be_hidden", "_can_be_hidden" }, // EditorNode3DGizmoPlugin
{ "can_drop_data_fw", "_can_drop_data_fw" }, // ScriptEditor
@@ -239,6 +244,7 @@ static const char *gdscript_function_renames[][2] = {
{ "clip_polyline_with_polygon_2d", "clip_polyline_with_polygon" }, //Geometry2D
{ "commit_handle", "_commit_handle" }, // EditorNode3DGizmo
{ "convex_hull_2d", "convex_hull" }, // Geometry2D
+ { "create_gizmo", "_create_gizmo" }, // EditorNode3DGizmoPlugin
{ "cursor_get_blink_speed", "get_caret_blink_speed" }, // TextEdit
{ "cursor_get_column", "get_caret_column" }, // TextEdit
{ "cursor_get_line", "get_caret_line" }, // TextEdit
@@ -251,8 +257,10 @@ static const char *gdscript_function_renames[][2] = {
{ "damped_string_joint_set_param", "damped_spring_joint_set_param" }, // PhysicsServer2D
{ "delete_char_at_cursor", "delete_char_at_caret" }, // LineEdit
{ "deselect_items", "deselect_all" }, // FileDialog
+ { "disable_plugin", "_disable_plugin" }, // EditorPlugin
{ "drop_data_fw", "_drop_data_fw" }, // ScriptEditor
{ "exclude_polygons_2d", "exclude_polygons" }, // Geometry2D
+ { "find_node", "find_child" }, // Node
{ "find_scancode_from_string", "find_keycode_from_string" }, // OS
{ "forward_canvas_draw_over_viewport", "_forward_canvas_draw_over_viewport" }, // EditorPlugin
{ "forward_canvas_force_draw_over_viewport", "_forward_canvas_force_draw_over_viewport" }, // EditorPlugin
@@ -287,7 +295,9 @@ static const char *gdscript_function_renames[][2] = {
{ "get_cull_mask_bit", "get_cull_mask_value" }, // Camera3D
{ "get_cursor_position", "get_caret_column" }, // LineEdit
{ "get_d", "get_distance" }, // LineShape2D
+ { "get_drag_data", "_get_drag_data" }, // Control
{ "get_drag_data_fw", "_get_drag_data_fw" }, // ScriptEditor
+ { "get_editor_description", "_get_editor_description" }, // Node
{ "get_editor_viewport", "get_viewport" }, // EditorPlugin
{ "get_enabled_focus_mode", "get_focus_mode" }, // BaseButton
{ "get_endian_swap", "is_big_endian" }, // File
@@ -327,6 +337,7 @@ static const char *gdscript_function_renames[][2] = {
{ "get_parameter_default_value", "_get_parameter_default_value" }, // AnimationNode
{ "get_parameter_list", "_get_parameter_list" }, // AnimationNode
{ "get_parent_spatial", "get_parent_node_3d" }, // Node3D
+ { "get_pause_mode", "get_process_mode" }, // Node
{ "get_physical_scancode", "get_physical_keycode" }, // InputEventKey
{ "get_physical_scancode_with_modifiers", "get_physical_keycode_with_modifiers" }, // InputEventKey
{ "get_plugin_icon", "_get_plugin_icon" }, // EditorPlugin
@@ -392,8 +403,10 @@ static const char *gdscript_function_renames[][2] = {
{ "is_a_parent_of", "is_ancestor_of" }, // Node
{ "is_commiting_action", "is_committing_action" }, // UndoRedo
{ "is_doubleclick", "is_double_click" }, // InputEventMouseButton
+ { "is_draw_red", "is_draw_warning" }, // EditorProperty
{ "is_h_drag_enabled", "is_drag_horizontal_enabled" }, // Camera2D
{ "is_handle_highlighted", "_is_handle_highlighted" }, // EditorNode3DGizmo, EditorNode3DGizmoPlugin
+ { "is_inverting_faces", "get_flip_faces" }, // CSGPrimitive3D
{ "is_network_master", "is_multiplayer_authority" }, // Node
{ "is_network_server", "is_server" }, // Multiplayer API
{ "is_normalmap", "is_normal_map" }, // NoiseTexture
@@ -415,6 +428,7 @@ static const char *gdscript_function_renames[][2] = {
{ "line_intersects_line_2d", "line_intersects_line" }, // Geometry2D
{ "load_from_globals", "load_from_project_settings" }, // InputMap
{ "make_convex_from_brothers", "make_convex_from_siblings" }, // CollisionShape3D
+ { "make_visible", "_make_visible" }, // EditorPlugin
{ "merge_polygons_2d", "merge_polygons" }, // Geometry2D
{ "mesh_surface_get_format", "mesh_surface_get_format_attribute_stride" }, // RenderingServer
{ "mesh_surface_update_region", "mesh_surface_update_attribute_region" }, // RenderingServer
@@ -438,6 +452,7 @@ static const char *gdscript_function_renames[][2] = {
{ "remove_color_override", "remove_theme_color_override" }, // Control
{ "remove_constant_override", "remove_theme_constant_override" }, // Control
{ "remove_font_override", "remove_theme_font_override" }, // Control
+ { "remove_icon_override", "remove_theme_icon_override" }, // Control
{ "remove_scene_import_plugin", "remove_scene_format_importer_plugin" }, //EditorPlugin
{ "remove_stylebox_override", "remove_theme_stylebox_override" }, // Control
{ "rename_animation", "rename_animation_library" }, // AnimationPlayer
@@ -465,6 +480,7 @@ static const char *gdscript_function_renames[][2] = {
{ "set_cursor_position", "set_caret_column" }, // LineEdit
{ "set_d", "set_distance" }, // WorldMarginShape2D
{ "set_doubleclick", "set_double_click" }, // InputEventMouseButton
+ { "set_draw_red", "set_draw_warning" }, // EditorProperty
{ "set_enabled_focus_mode", "set_focus_mode" }, // BaseButton
{ "set_endian_swap", "set_big_endian" }, // File
{ "set_expand_to_text_length", "set_expand_to_text_length_enabled" }, // LineEdit
@@ -477,6 +493,7 @@ static const char *gdscript_function_renames[][2] = {
{ "set_icon_align", "set_icon_alignment" }, // Button
{ "set_interior_ambient", "set_ambient_color" }, // ReflectionProbe
{ "set_interior_ambient_energy", "set_ambient_color_energy" }, // ReflectionProbe
+ { "set_invert_faces", "set_flip_faces" }, // CSGPrimitive3D
{ "set_is_initialized", "_is_initialized" }, // XRInterface
{ "set_is_primary", "set_primary" }, // XRInterface
{ "set_iterations_per_second", "set_physics_ticks_per_second" }, // Engine
@@ -487,6 +504,7 @@ static const char *gdscript_function_renames[][2] = {
{ "set_mid_height", "set_height" }, // CapsuleMesh
{ "set_network_master", "set_multiplayer_authority" }, // Node
{ "set_network_peer", "set_multiplayer_peer" }, // Multiplayer API
+ { "set_pause_mode", "set_process_mode" }, // Node
{ "set_physical_scancode", "set_physical_keycode" }, // InputEventKey
{ "set_refuse_new_network_connections", "set_refuse_new_connections" }, // Multiplayer API
{ "set_region", "set_region_enabled" }, // Sprite2D, Sprite broke AtlasTexture
@@ -1220,7 +1238,6 @@ static const char *class_renames[][2] = {
// { "Physics2DShapeQueryResult", "PhysicsShapeQueryResult2D" }, // Class is not visible in ClassDB
// { "PhysicsShapeQueryResult", "PhysicsShapeQueryResult3D" }, // Class is not visible in ClassDB
// { "NativeScript","NativeExtension"}, ??
- { "AStar", "AStar3D" },
{ "ARVRAnchor", "XRAnchor3D" },
{ "ARVRCamera", "XRCamera3D" },
{ "ARVRController", "XRController3D" },
@@ -1229,13 +1246,14 @@ static const char *class_renames[][2] = {
{ "ARVROrigin", "XROrigin3D" },
{ "ARVRPositionalTracker", "XRPositionalTracker" },
{ "ARVRServer", "XRServer" },
+ { "AStar", "AStar3D" },
{ "AnimatedSprite", "AnimatedSprite2D" },
{ "AnimationTreePlayer", "AnimationTree" },
{ "Area", "Area3D" }, // Be careful, this will be used everywhere
{ "AudioStreamRandomPitch", "AudioStreamRandomizer" },
{ "BakedLightmap", "LightmapGI" },
{ "BakedLightmapData", "LightmapGIData" },
- { "BitmapFont", "Font" },
+ { "BitmapFont", "FontFile" },
{ "BoneAttachment", "BoneAttachment3D" },
{ "BoxShape", "BoxShape3D" },
{ "CPUParticles", "CPUParticles3D" },
@@ -1261,8 +1279,8 @@ static const char *class_renames[][2] = {
{ "CubeMesh", "BoxMesh" },
{ "CylinderShape", "CylinderShape3D" },
{ "DirectionalLight", "DirectionalLight3D" },
- { "DynamicFont", "Font" },
- { "DynamicFontData", "FontData" },
+ { "DynamicFont", "FontFile" },
+ { "DynamicFontData", "FontFile" },
{ "EditorNavigationMeshGenerator", "NavigationMeshGenerator" },
{ "EditorSceneImporter", "EditorSceneFormatImporter" },
{ "EditorSceneImporterFBX", "EditorSceneFormatImporterFBX" },
@@ -1344,6 +1362,7 @@ static const char *class_renames[][2] = {
{ "ResourceInteractiveLoader", "ResourceLoader" },
{ "RigidBody", "RigidDynamicBody3D" },
{ "RigidBody2D", "RigidDynamicBody2D" },
+ { "SceneTreeTween", "Tween" },
{ "Shape", "Shape3D" }, // Be careful, this will be used everywhere
{ "ShortCut", "Shortcut" },
{ "Skeleton", "Skeleton3D" },
@@ -2045,6 +2064,7 @@ bool ProjectConverter3To4::test_conversion() {
valid = valid & test_conversion_single_additional("set_cell_item(a, b)", "set_cell_item(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
valid = valid & test_conversion_single_additional("get_cell_item_orientation(a, b,c)", "get_cell_item_orientation(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
valid = valid & test_conversion_single_additional("get_cell_item(a, b,c)", "get_cell_item(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
+ valid = valid & test_conversion_single_additional("map_to_world(a, b,c)", "map_to_world(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
valid = valid & test_conversion_single_additional("PackedStringArray(req_godot).join('.')", "'.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
valid = valid & test_conversion_single_additional("=PackedStringArray(req_godot).join('.')", "='.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
@@ -2054,6 +2074,9 @@ bool ProjectConverter3To4::test_conversion() {
valid = valid & test_conversion_single_additional("\t aa", "\taa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
valid = valid & test_conversion_single_additional(" \taa", " \taa", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
+ valid = valid & test_conversion_single_additional("apply_force(position, impulse)", "apply_force(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
+ valid = valid & test_conversion_single_additional("apply_impulse(position, impulse)", "apply_impulse(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename");
+
valid = valid & test_conversion_single_additional("AAA Color.white AF", "AAA Color.WHITE AF", &ProjectConverter3To4::rename_enums, "custom rename");
// Custom rule conversion
@@ -2186,7 +2209,7 @@ bool ProjectConverter3To4::test_array_names() {
// Callable is special class, to which normal classes may be renamed
if (!ClassDB::class_exists(StringName(new_class)) && new_class != "Callable") {
- ERR_PRINT(String("Class `") + new_class + "` doesn't exists in Godot 4.0, so cannot be used in convertion.");
+ ERR_PRINT(String("Class `") + new_class + "` doesn't exists in Godot 4.0, so cannot be used in conversion.");
valid = false; // This probably should be only a warning, but not 100% sure - this would need to be added to CI
}
current_index++;
@@ -2272,7 +2295,7 @@ bool ProjectConverter3To4::test_array_names() {
}
// Validate in one array if names don't do cyclic renames `Node` -> `Node2D` | `Node2D` -> `2DNode`
-// Also checks if in name contains spaces at the end or beggining
+// Also checks if in name contains spaces at the end or beginning
bool ProjectConverter3To4::test_single_array(const char *array[][2], bool ignore_second_check) {
bool valid = true;
int current_index = 0;
@@ -2993,14 +3016,39 @@ void ProjectConverter3To4::rename_gdscript_functions(String &file_content) {
}
}
}
-
- // TODO - add_surface_from_arrays - additional 4 argument
- // ENetMultiplayerPeer.create_client - additional argument
- // ENetMultiplayerPeer.create_server - additional argument
- // Translation.get_message (and similar)
- // TreeItem.move_after() - new argument
- // TreeItem.move_before() - new argument
- // UndoRedo.commit_action() - additional argument
+ // apply_impulse(A, B) -> apply_impulse(B, A)
+ if (line.find("apply_impulse(") != -1) {
+ int start = line.find("apply_impulse(");
+ int end = get_end_parenthess(line.substr(start)) + 1;
+ if (end > -1) {
+ Vector<String> parts = parse_arguments(line.substr(start, end));
+ if (parts.size() == 2) {
+ line = line.substr(0, start) + "apply_impulse(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start);
+ }
+ }
+ }
+ // apply_force(A, B) -> apply_force(B, A)
+ if (line.find("apply_force(") != -1) {
+ int start = line.find("apply_force(");
+ int end = get_end_parenthess(line.substr(start)) + 1;
+ if (end > -1) {
+ Vector<String> parts = parse_arguments(line.substr(start, end));
+ if (parts.size() == 2) {
+ line = line.substr(0, start) + "apply_force(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start);
+ }
+ }
+ }
+ // map_to_world(a, b, c) -> map_to_world(Vector3i(a, b, c))
+ if (line.find("map_to_world(") != -1) {
+ int start = line.find("map_to_world(");
+ int end = get_end_parenthess(line.substr(start)) + 1;
+ if (end > -1) {
+ Vector<String> parts = parse_arguments(line.substr(start, end));
+ if (parts.size() == 3) {
+ line = line.substr(0, start) + "map_to_world(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start);
+ }
+ }
+ }
}
// Collect vector to string
@@ -3398,13 +3446,39 @@ Vector<String> ProjectConverter3To4::check_for_rename_gdscript_functions(Vector<
}
}
- // TODO - add_surface_from_arrays - additional 4 argument
- // ENetMultiplayerPeer.create_client - additional argument
- // ENetMultiplayerPeer.create_server - additional argument
- // Translation.get_message (and similar)
- // TreeItem.move_after() - new argument
- // TreeItem.move_before() - new argument
- // UndoRedo.commit_action() - additional argument
+ // apply_impulse(A, B) -> apply_impulse(B, A)
+ if (line.find("apply_impulse(") != -1) {
+ int start = line.find("apply_impulse(");
+ int end = get_end_parenthess(line.substr(start)) + 1;
+ if (end > -1) {
+ Vector<String> parts = parse_arguments(line.substr(start, end));
+ if (parts.size() == 2) {
+ line = line.substr(0, start) + "apply_impulse(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start);
+ }
+ }
+ }
+ // apply_force(A, B) -> apply_force(B, A)
+ if (line.find("apply_force(") != -1) {
+ int start = line.find("apply_force(");
+ int end = get_end_parenthess(line.substr(start)) + 1;
+ if (end > -1) {
+ Vector<String> parts = parse_arguments(line.substr(start, end));
+ if (parts.size() == 2) {
+ line = line.substr(0, start) + "apply_force(" + parts[1] + ", " + parts[0] + ")" + line.substr(end + start);
+ }
+ }
+ }
+ // map_to_world(a, b, c) -> map_to_world(Vector3i(a, b, c))
+ if (line.find("map_to_world(") != -1) {
+ int start = line.find("get_cell_item_orientation(");
+ int end = get_end_parenthess(line.substr(start)) + 1;
+ if (end > -1) {
+ Vector<String> parts = parse_arguments(line.substr(start, end));
+ if (parts.size() == 3) {
+ line = line.substr(0, start) + "map_to_world(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start);
+ }
+ }
+ }
if (old_line != line) {
found_things.append(simple_line_formatter(current_line, old_line, line));
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 030337a4bc..209c997d58 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -366,16 +366,17 @@ void ProjectExportDialog::_update_feature_list() {
}
custom_feature_display->clear();
+ String text;
bool first = true;
for (const String &E : fset) {
- String f = E;
if (!first) {
- f += ", ";
+ text += ", ";
} else {
first = false;
}
- custom_feature_display->add_text(f);
+ text += E;
}
+ custom_feature_display->add_text(text);
}
void ProjectExportDialog::_custom_features_changed(const String &p_text) {
@@ -891,7 +892,7 @@ void ProjectExportDialog::_export_project() {
List<String> extension_list = platform->get_binary_extensions(current);
for (int i = 0; i < extension_list.size(); i++) {
// TRANSLATORS: This is the name of a project export file format. %s will be replaced by the platform name.
- export_project->add_filter(vformat("*.%s; %s", extension_list[i], vformat(TTR("%s Export"), platform->get_name())));
+ export_project->add_filter("*." + extension_list[i], vformat(TTR("%s Export"), platform->get_name()));
}
if (!current->get_export_path().is_empty()) {
@@ -1194,13 +1195,13 @@ ProjectExportDialog::ProjectExportDialog() {
delete_confirm = memnew(ConfirmationDialog);
add_child(delete_confirm);
- delete_confirm->get_ok_button()->set_text(TTR("Delete"));
+ delete_confirm->set_ok_button_text(TTR("Delete"));
delete_confirm->connect("confirmed", callable_mp(this, &ProjectExportDialog::_delete_preset_confirm));
// Export buttons, dialogs and errors.
- get_cancel_button()->set_text(TTR("Close"));
- get_ok_button()->set_text(TTR("Export PCK/ZIP..."));
+ set_cancel_button_text(TTR("Close"));
+ set_ok_button_text(TTR("Export PCK/ZIP..."));
export_button = add_button(TTR("Export Project..."), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "export");
export_button->connect("pressed", callable_mp(this, &ProjectExportDialog::_export_project));
// Disable initially before we select a valid preset
@@ -1221,8 +1222,8 @@ ProjectExportDialog::ProjectExportDialog() {
export_all_button->set_disabled(true);
export_pck_zip = memnew(EditorFileDialog);
- export_pck_zip->add_filter("*.zip ; " + TTR("ZIP File"));
- export_pck_zip->add_filter("*.pck ; " + TTR("Godot Project Pack"));
+ export_pck_zip->add_filter("*.zip", TTR("ZIP File"));
+ export_pck_zip->add_filter("*.pck", TTR("Godot Project Pack"));
export_pck_zip->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
export_pck_zip->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
add_child(export_pck_zip);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 2e7b6f7476..327ff6bb2d 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -362,8 +362,8 @@ private:
if (mode == MODE_IMPORT) {
fdialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
fdialog->clear_filters();
- fdialog->add_filter(vformat("project.godot ; %s %s", VERSION_NAME, TTR("Project")));
- fdialog->add_filter("*.zip ; " + TTR("ZIP File"));
+ fdialog->add_filter("project.godot", vformat("%s %s", VERSION_NAME, TTR("Project")));
+ fdialog->add_filter("*.zip", TTR("ZIP File"));
} else {
fdialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR);
}
@@ -681,7 +681,7 @@ public:
install_browse->hide();
set_title(TTR("Rename Project"));
- get_ok_button()->set_text(TTR("Rename"));
+ set_ok_button_text(TTR("Rename"));
name_container->show();
status_rect->hide();
msg->hide();
@@ -735,7 +735,7 @@ public:
if (mode == MODE_IMPORT) {
set_title(TTR("Import Existing Project"));
- get_ok_button()->set_text(TTR("Import & Edit"));
+ set_ok_button_text(TTR("Import & Edit"));
name_container->hide();
install_path_container->hide();
rasterizer_container->hide();
@@ -744,7 +744,7 @@ public:
} else if (mode == MODE_NEW) {
set_title(TTR("Create New Project"));
- get_ok_button()->set_text(TTR("Create & Edit"));
+ set_ok_button_text(TTR("Create & Edit"));
name_container->show();
install_path_container->hide();
rasterizer_container->show();
@@ -754,7 +754,7 @@ public:
} else if (mode == MODE_INSTALL) {
set_title(TTR("Install Project:") + " " + zip_title);
- get_ok_button()->set_text(TTR("Install & Edit"));
+ set_ok_button_text(TTR("Install & Edit"));
project_name->set_text(zip_title);
name_container->show();
install_path_container->hide();
@@ -1167,9 +1167,7 @@ void ProjectList::load_project_icon(int p_index) {
Error err = img->load(item.icon.replace_first("res://", item.path + "/"));
if (err == OK) {
img->resize(default_icon->get_width(), default_icon->get_height(), Image::INTERPOLATE_LANCZOS);
- Ref<ImageTexture> it = memnew(ImageTexture);
- it->create_from_image(img);
- icon = it;
+ icon = ImageTexture::create_from_image(img);
}
}
if (icon.is_null()) {
@@ -1895,7 +1893,6 @@ void ProjectManager::_notification(int p_what) {
}
if (asset_library) {
real_t size = get_size().x / EDSCALE;
- asset_library->set_columns(size < 1000 ? 1 : 2);
// Adjust names of tabs to fit the new size.
if (size < 650) {
local_projects_hb->set_name(TTR("Local"));
@@ -2001,7 +1998,7 @@ void ProjectManager::shortcut_input(const Ref<InputEvent> &p_ev) {
// Pressing Command + Q quits the Project Manager
// This is handled by the platform implementation on macOS,
// so only define the shortcut on other platforms
-#ifndef OSX_ENABLED
+#ifndef MACOS_ENABLED
if (k->get_keycode_with_modifiers() == (KeyModifierMask::CMD | Key::Q)) {
_dim_window();
get_tree()->quit();
@@ -2565,19 +2562,19 @@ ProjectManager::ProjectManager() {
EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
- set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
set_theme(create_custom_theme());
- set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
Panel *panel = memnew(Panel);
add_child(panel);
- panel->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ panel->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles")));
VBoxContainer *vb = memnew(VBoxContainer);
panel->add_child(vb);
- vb->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 8 * EDSCALE);
+ vb->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 8 * EDSCALE);
Control *center_box = memnew(Control);
center_box->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -2585,7 +2582,7 @@ ProjectManager::ProjectManager() {
tabs = memnew(TabContainer);
center_box->add_child(tabs);
- tabs->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ tabs->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
tabs->connect("tab_changed", callable_mp(this, &ProjectManager::_on_tab_changed));
local_projects_hb = memnew(HBoxContainer);
@@ -2792,25 +2789,21 @@ ProjectManager::ProjectManager() {
center_box->add_child(settings_hb);
}
- // Asset Library can't work on Web editor for now as most assets are sourced
- // directly from GitHub which does not set CORS.
-#ifndef JAVASCRIPT_ENABLED
- if (StreamPeerSSL::is_available()) {
+ if (AssetLibraryEditorPlugin::is_available()) {
asset_library = memnew(EditorAssetLibrary(true));
asset_library->set_name(TTR("Asset Library Projects"));
tabs->add_child(asset_library);
asset_library->connect("install_asset", callable_mp(this, &ProjectManager::_install_project));
} else {
- WARN_PRINT("Asset Library not available, as it requires SSL to work.");
+ print_verbose("Asset Library not available (due to using Web editor, or SSL support disabled).");
}
-#endif
{
// Dialogs
language_restart_ask = memnew(ConfirmationDialog);
- language_restart_ask->get_ok_button()->set_text(TTR("Restart Now"));
+ language_restart_ask->set_ok_button_text(TTR("Restart Now"));
language_restart_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_restart_confirm));
- language_restart_ask->get_cancel_button()->set_text(TTR("Continue"));
+ language_restart_ask->set_cancel_button_text(TTR("Continue"));
add_child(language_restart_ask);
scan_dir = memnew(EditorFileDialog);
@@ -2823,12 +2816,12 @@ ProjectManager::ProjectManager() {
scan_dir->connect("dir_selected", callable_mp(this, &ProjectManager::_scan_begin));
erase_missing_ask = memnew(ConfirmationDialog);
- erase_missing_ask->get_ok_button()->set_text(TTR("Remove All"));
+ erase_missing_ask->set_ok_button_text(TTR("Remove All"));
erase_missing_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_erase_missing_projects_confirm));
add_child(erase_missing_ask);
erase_ask = memnew(ConfirmationDialog);
- erase_ask->get_ok_button()->set_text(TTR("Remove"));
+ erase_ask->set_ok_button_text(TTR("Remove"));
erase_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_erase_project_confirm));
add_child(erase_ask);
@@ -2843,17 +2836,17 @@ ProjectManager::ProjectManager() {
erase_ask_vb->add_child(delete_project_contents);
multi_open_ask = memnew(ConfirmationDialog);
- multi_open_ask->get_ok_button()->set_text(TTR("Edit"));
+ multi_open_ask->set_ok_button_text(TTR("Edit"));
multi_open_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_open_selected_projects));
add_child(multi_open_ask);
multi_run_ask = memnew(ConfirmationDialog);
- multi_run_ask->get_ok_button()->set_text(TTR("Run"));
+ multi_run_ask->set_ok_button_text(TTR("Run"));
multi_run_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_run_project_confirm));
add_child(multi_run_ask);
multi_scan_ask = memnew(ConfirmationDialog);
- multi_scan_ask->get_ok_button()->set_text(TTR("Scan"));
+ multi_scan_ask->set_ok_button_text(TTR("Scan"));
add_child(multi_scan_ask);
ask_update_settings = memnew(ConfirmationDialog);
@@ -2875,7 +2868,7 @@ ProjectManager::ProjectManager() {
if (asset_library) {
open_templates = memnew(ConfirmationDialog);
open_templates->set_text(TTR("You currently don't have any projects.\nWould you like to explore official example projects in the Asset Library?"));
- open_templates->get_ok_button()->set_text(TTR("Open Asset Library"));
+ open_templates->set_ok_button_text(TTR("Open Asset Library"));
open_templates->connect("confirmed", callable_mp(this, &ProjectManager::_open_asset_library));
add_child(open_templates);
}
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 1524993bd0..49707355a0 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -685,7 +685,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
timer->set_one_shot(true);
add_child(timer);
- get_ok_button()->set_text(TTR("Close"));
+ set_ok_button_text(TTR("Close"));
set_hide_on_ok(true);
bool use_advanced = EditorSettings::get_singleton()->get_project_metadata("project_settings", "advanced_mode", false);
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index d936e821df..488a084903 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -145,7 +145,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
file->clear_filters();
for (const String &E : valid_extensions) {
- file->add_filter("*." + E + " ; " + E.to_upper());
+ file->add_filter("*." + E, E.to_upper());
}
file->popup_file_dialog();
@@ -828,17 +828,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
value_vbox->add_child(color_picker);
color_picker->hide();
color_picker->connect("color_changed", callable_mp(this, &CustomPropertyEditor::_color_changed));
-
- // get default color picker mode from editor settings
- int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
- if (default_color_mode == 1) {
- color_picker->set_hsv_mode(true);
- } else if (default_color_mode == 2) {
- color_picker->set_raw_mode(true);
- }
-
- int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
- color_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
+ color_picker->connect("show", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(color_picker));
}
color_picker->show();
@@ -1227,7 +1217,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
filter = "*." + extensions[i];
}
- file->add_filter(filter + " ; " + extensions[i].to_upper());
+ file->add_filter(filter, extensions[i].to_upper());
}
}
file->popup_file_dialog();
@@ -1311,7 +1301,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
ResourceLoader::get_recognized_extensions_for_type(type, &extensions);
file->clear_filters();
for (const String &E : extensions) {
- file->add_filter("*." + E + " ; " + E.to_upper());
+ file->add_filter("*." + E, E.to_upper());
}
file->popup_file_dialog();
@@ -1830,7 +1820,7 @@ CustomPropertyEditor::CustomPropertyEditor() {
text_edit = memnew(TextEdit);
value_vbox->add_child(text_edit);
- text_edit->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 5);
+ text_edit->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 5);
text_edit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
text_edit->set_offset(SIDE_BOTTOM, -30);
@@ -1886,12 +1876,12 @@ CustomPropertyEditor::CustomPropertyEditor() {
spinbox = memnew(SpinBox);
value_vbox->add_child(spinbox);
- spinbox->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 5);
+ spinbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 5);
spinbox->connect("value_changed", callable_mp(this, &CustomPropertyEditor::_range_modified));
slider = memnew(HSlider);
value_vbox->add_child(slider);
- slider->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 5);
+ slider->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 5);
slider->connect("value_changed", callable_mp(this, &CustomPropertyEditor::_range_modified));
action_hboxes = memnew(HBoxContainer);
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index c136eae1bc..841c3ff3b1 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -581,7 +581,7 @@ PropertySelector::PropertySelector() {
search_box->connect("gui_input", callable_mp(this, &PropertySelector::_sbox_input));
search_options = memnew(Tree);
vbc->add_margin_child(TTR("Matches:"), search_options, true);
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
get_ok_button()->set_disabled(true);
register_text_enter(search_box);
set_hide_on_ok(false);
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 4938699fc4..4f7f9fc78c 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -263,6 +263,6 @@ EditorQuickOpen::EditorQuickOpen() {
search_options->add_theme_constant_override("draw_guides", 1);
vbc->add_margin_child(TTR("Matches:"), search_options, true);
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
set_hide_on_ok(false);
}
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index a8278b9aab..255187e4ed 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -289,7 +289,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
// ---- Dialog related
set_min_size(Size2(383, 0));
- get_ok_button()->set_text(TTR("Rename"));
+ set_ok_button_text(TTR("Rename"));
Button *but_reset = add_button(TTR("Reset"));
eh.errfunc = _error_handler;
diff --git a/editor/reparent_dialog.cpp b/editor/reparent_dialog.cpp
index 5a8fe24518..75098b25b1 100644
--- a/editor/reparent_dialog.cpp
+++ b/editor/reparent_dialog.cpp
@@ -89,7 +89,7 @@ ReparentDialog::ReparentDialog() {
//cancel->connect("pressed", this,"_cancel");
- get_ok_button()->set_text(TTR("Reparent"));
+ set_ok_button_text(TTR("Reparent"));
}
ReparentDialog::~ReparentDialog() {
diff --git a/editor/scene_create_dialog.cpp b/editor/scene_create_dialog.cpp
index 64aea54c5f..94a5c07709 100644
--- a/editor/scene_create_dialog.cpp
+++ b/editor/scene_create_dialog.cpp
@@ -76,7 +76,7 @@ void SceneCreateDialog::accept_create() {
void SceneCreateDialog::browse_types() {
select_node_dialog->popup_create(true);
select_node_dialog->set_title(TTR("Pick Root Node Type"));
- select_node_dialog->get_ok_button()->set_text(TTR("Pick"));
+ select_node_dialog->set_ok_button_text(TTR("Pick"));
}
void SceneCreateDialog::on_type_picked() {
@@ -171,7 +171,7 @@ Node *SceneCreateDialog::create_scene_root() {
break;
case ROOT_USER_INTERFACE: {
Control *gui = memnew(Control);
- gui->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ gui->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
root = gui;
} break;
case ROOT_OTHER:
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 2e1090e6c0..8cf0f50db8 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -72,7 +72,7 @@ void SceneTreeDock::input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && (mb->get_button_index() == MouseButton::LEFT || mb->get_button_index() == MouseButton::RIGHT)) {
- if (mb->is_pressed() && scene_tree->get_rect().has_point(mb->get_position())) {
+ if (mb->is_pressed() && scene_tree->get_rect().has_point(scene_tree->get_local_mouse_position())) {
tree_clicked = true;
} else if (!mb->is_pressed()) {
tree_clicked = false;
@@ -910,7 +910,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
ResourceSaver::get_recognized_extensions(sd, &extensions);
new_scene_from_dialog->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
- new_scene_from_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
+ new_scene_from_dialog->add_filter("*." + extensions[i], extensions[i].to_upper());
}
String existing;
@@ -1122,7 +1122,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
case TOOL_CREATE_USER_INTERFACE: {
Control *node = memnew(Control);
- node->set_anchors_and_offsets_preset(PRESET_WIDE); //more useful for resizable UIs.
+ node->set_anchors_and_offsets_preset(PRESET_FULL_RECT); //more useful for resizable UIs.
new_node = node;
} break;
@@ -3535,7 +3535,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
clear_inherit_confirm = memnew(ConfirmationDialog);
clear_inherit_confirm->set_text(TTR("Clear Inheritance? (No Undo!)"));
- clear_inherit_confirm->get_ok_button()->set_text(TTR("Clear"));
+ clear_inherit_confirm->set_ok_button_text(TTR("Clear"));
add_child(clear_inherit_confirm);
set_process_input(true);
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 86fa9222c0..5e1f5ab750 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -1359,6 +1359,10 @@ void SceneTreeDialog::_select() {
}
}
+void SceneTreeDialog::_selected_changed() {
+ get_ok_button()->set_disabled(!tree->get_selected());
+}
+
void SceneTreeDialog::_filter_changed(const String &p_filter) {
tree->set_filter(p_filter);
}
@@ -1386,6 +1390,10 @@ SceneTreeDialog::SceneTreeDialog() {
tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tree->get_scene_tree()->connect("item_activated", callable_mp(this, &SceneTreeDialog::_select));
vbc->add_child(tree);
+
+ // Disable the OK button when no node is selected.
+ get_ok_button()->set_disabled(!tree->get_selected());
+ tree->connect("node_selected", callable_mp(this, &SceneTreeDialog::_selected_changed));
}
SceneTreeDialog::~SceneTreeDialog() {
diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h
index 5d4230059c..31a14e4667 100644
--- a/editor/scene_tree_editor.h
+++ b/editor/scene_tree_editor.h
@@ -176,6 +176,7 @@ class SceneTreeDialog : public ConfirmationDialog {
void _select();
void _cancel();
+ void _selected_changed();
void _filter_changed(const String &p_filter);
void _update_theme();
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index e8561de19c..f2eabdd208 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -481,7 +481,7 @@ void ScriptCreateDialog::_browse_path(bool browse_parent, bool p_save) {
if (p_save) {
file_browse->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
file_browse->set_title(TTR("Open Script / Choose Location"));
- file_browse->get_ok_button()->set_text(TTR("Open"));
+ file_browse->set_ok_button_text(TTR("Open"));
} else {
file_browse->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
file_browse->set_title(TTR("Open Script"));
@@ -528,7 +528,7 @@ void ScriptCreateDialog::_browse_class_in_tree() {
select_class->set_base_type(base_type);
select_class->popup_create(true);
select_class->set_title(vformat(TTR("Inherit %s"), base_type));
- select_class->get_ok_button()->set_text(TTR("Inherit"));
+ select_class->set_ok_button_text(TTR("Inherit"));
}
void ScriptCreateDialog::_path_changed(const String &p_path) {
@@ -750,7 +750,7 @@ void ScriptCreateDialog::_update_dialog() {
parent_browse_button->set_disabled(!is_new_file || !can_inherit_from_file);
template_inactive_message = "";
String button_text = is_new_file ? TTR("Create") : TTR("Load");
- get_ok_button()->set_text(button_text);
+ set_ok_button_text(button_text);
if (is_new_file) {
if (is_built_in) {
@@ -1088,7 +1088,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
file_browse->connect("file_selected", callable_mp(this, &ScriptCreateDialog::_file_selected));
file_browse->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
add_child(file_browse);
- get_ok_button()->set_text(TTR("Create"));
+ set_ok_button_text(TTR("Create"));
alert = memnew(AcceptDialog);
alert->get_label()->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
alert->get_label()->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp
index f70c46c8d8..28e1e9bf22 100644
--- a/editor/shader_create_dialog.cpp
+++ b/editor/shader_create_dialog.cpp
@@ -270,7 +270,7 @@ void ShaderCreateDialog::_built_in_toggled(bool p_enabled) {
void ShaderCreateDialog::_browse_path() {
file_browse->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
file_browse->set_title(TTR("Open Shader / Choose Location"));
- file_browse->get_ok_button()->set_text(TTR("Open"));
+ file_browse->set_ok_button_text(TTR("Open"));
file_browse->set_disable_overwrite_warning(true);
file_browse->clear_filters();
@@ -469,20 +469,20 @@ void ShaderCreateDialog::_update_dialog() {
builtin_warning_label->set_visible(is_built_in);
if (is_built_in) {
- get_ok_button()->set_text(TTR("Create"));
+ set_ok_button_text(TTR("Create"));
_msg_path_valid(true, TTR("Built-in shader (into scene file)."));
} else if (is_new_shader_created) {
- get_ok_button()->set_text(TTR("Create"));
+ set_ok_button_text(TTR("Create"));
if (is_path_valid) {
_msg_path_valid(true, TTR("Will create a new shader file."));
}
} else if (load_enabled) {
- get_ok_button()->set_text(TTR("Load"));
+ set_ok_button_text(TTR("Load"));
if (is_path_valid) {
_msg_path_valid(true, TTR("Will load an existing shader file."));
}
} else {
- get_ok_button()->set_text(TTR("Create"));
+ set_ok_button_text(TTR("Create"));
_msg_path_valid(false, TTR("Shader file already exists."));
shader_ok = false;
@@ -638,7 +638,7 @@ ShaderCreateDialog::ShaderCreateDialog() {
alert->get_label()->set_custom_minimum_size(Size2(325, 60) * EDSCALE);
add_child(alert);
- get_ok_button()->set_text(TTR("Create"));
+ set_ok_button_text(TTR("Create"));
set_hide_on_ok(false);
set_title(TTR("Create Shader"));
diff --git a/editor/translations/af.po b/editor/translations/af.po
index ae83779422..78dd7f2140 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -413,6 +413,11 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Aktiveer"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -468,6 +473,10 @@ msgid "Pressure"
msgstr "Herset Zoem"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5556,6 +5565,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Alle Seleksie"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8009,11 +8023,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -8033,11 +8056,6 @@ msgid "Animation name already exists!"
msgstr "AutoLaai '%s' bestaan reeds!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8185,10 +8203,6 @@ msgid "Pin AnimationPlayer"
msgstr "Animasie Zoem."
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18703,6 +18717,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Anim Dupliseer Sleutels"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18711,6 +18730,16 @@ msgstr ""
msgid "Export Format"
msgstr "Anim Verander Transform"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Afhanklikheid Bewerker"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Skrap"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18747,16 +18776,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Afhanklikheid Bewerker"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Skrap"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18994,12 +19013,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19008,17 +19027,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20645,7 +20684,7 @@ msgstr "Zoem In"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21346,34 +21385,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Wysig Seleksie Kurwe"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Konstant"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Installeer"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Aktiveer"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Aktiveer"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Aktiveer"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21414,7 +21475,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstant"
@@ -22513,6 +22574,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Skep Intekening"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -23370,6 +23438,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Anim Verander Transform"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24544,6 +24617,11 @@ msgstr "Skep Vouer"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Slegs Seleksie"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Aktiveer"
@@ -24928,16 +25006,17 @@ msgstr "Fokus Pad"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26640,6 +26719,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Verwyder Seleksie"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index a3fcece225..87266564f8 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -64,13 +64,15 @@
# ywmaa <ywmaa.personal@gmail.com>, 2022.
# Awab Najim <dev.djvan@gmail.com>, 2022.
# Abderrahim <abdoudido117@gmail.com>, 2022.
+# Jhon Smith <jhonsmaith3@gmail.com>, 2022.
+# Oo mohab oO <mohab9225@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-19 11:52+0000\n"
-"Last-Translator: Awab Najim <dev.djvan@gmail.com>\n"
+"PO-Revision-Date: 2022-07-09 21:11+0000\n"
+"Last-Translator: Oo mohab oO <mohab9225@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
"Language: ar\n"
@@ -307,9 +309,8 @@ msgid "Refuse New Network Connections"
msgstr "Ø±ÙØ¶ اتصالات الشبكة الجديدة"
#: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp
-#, fuzzy
msgid "Network Peer"
-msgstr "مل٠تعري٠الشبكة Network Profiler"
+msgstr "نظير الشبكة"
#: core/io/multiplayer_api.cpp scene/animation/animation_player.cpp
msgid "Root Node"
@@ -448,6 +449,11 @@ msgstr "المرجعية الذاتية (Meta)"
msgid "Command"
msgstr "Ù…ÙØªØ§Ø­ Command"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (Ùيزيائي)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -499,6 +505,10 @@ msgid "Pressure"
msgstr "الضغط"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "نسبي"
@@ -686,9 +696,8 @@ msgid "Main Run Args"
msgstr "معاملات المشهد الرئيس"
#: core/project_settings.cpp
-#, fuzzy
msgid "Scene Naming"
-msgstr "المسار للمشهد:"
+msgstr "تسمية المشهد"
#: core/project_settings.cpp
msgid "Search In File Extensions"
@@ -699,9 +708,8 @@ msgid "Script Templates Search Path"
msgstr "مسار البحث ÙÙŠ قوالب النص البرمجي"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Autoload On Startup"
-msgstr "التحميل التلقائي عند بدء التشغيل"
+msgstr "التحميل التلقائي للتحكم ÙÙŠ الإصدار عند بدء التشغيل"
#: core/project_settings.cpp
#, fuzzy
@@ -859,8 +867,9 @@ msgid "Formats"
msgstr "البنية (اللاحقة)"
#: core/project_settings.cpp
+#, fuzzy
msgid "Zstd"
-msgstr ""
+msgstr "Zstd"
#: core/project_settings.cpp
msgid "Long Distance Matching"
@@ -875,12 +884,14 @@ msgid "Window Log Size"
msgstr "حجم Ù†Ø§ÙØ°Ø© سجل"
#: core/project_settings.cpp
+#, fuzzy
msgid "Zlib"
-msgstr ""
+msgstr "Zlib"
#: core/project_settings.cpp
+#, fuzzy
msgid "Gzip"
-msgstr ""
+msgstr "Gzip"
#: core/project_settings.cpp platform/android/export/export.cpp
msgid "Android"
@@ -892,7 +903,7 @@ msgstr "وحدات"
#: core/register_core_types.cpp
msgid "TCP"
-msgstr ""
+msgstr "بروتوكول التحكم بالإرسال (TCP)"
#: core/register_core_types.cpp
msgid "Connect Timeout Seconds"
@@ -900,15 +911,15 @@ msgstr "Ù†ÙØ° وقت الإتصال"
#: core/register_core_types.cpp
msgid "Packet Peer Stream"
-msgstr ""
+msgstr "حزمة تيار الأقران"
#: core/register_core_types.cpp
msgid "Max Buffer (Power of 2)"
-msgstr ""
+msgstr "الحد الأقصى للمخزن المؤقت (قوة 2)"
#: core/register_core_types.cpp editor/editor_settings.cpp main/main.cpp
msgid "SSL"
-msgstr ""
+msgstr "SSL"
#: core/register_core_types.cpp main/main.cpp
msgid "Certificates"
@@ -981,17 +992,17 @@ msgstr "إكسي بايت (EiB)"
#: drivers/gles3/rasterizer_scene_gles3.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp modules/gltf/gltf_state.cpp
msgid "Buffers"
-msgstr ""
+msgstr "المخازن المؤقته"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
msgid "Canvas Polygon Buffer Size (KB)"
-msgstr ""
+msgstr "حجم المخزن المؤقت للوحة المضلعات (KB)"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
msgid "Canvas Polygon Index Buffer Size (KB)"
-msgstr ""
+msgstr "حجم Ùهرس المخزن المؤقت للوحة المضلعات (KB)"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp
@@ -1003,7 +1014,7 @@ msgstr ""
#: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp
#: servers/visual_server.cpp
msgid "2D"
-msgstr ""
+msgstr "2D"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
@@ -1020,7 +1031,7 @@ msgstr "إستخدام كبس البكسل"
#: drivers/gles2/rasterizer_scene_gles2.cpp
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Immediate Buffer Size (KB)"
-msgstr ""
+msgstr "حجم المخزن المؤقت الÙوري (KB)"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1031,15 +1042,15 @@ msgstr "طبخ (إعداد) خرائط الضوء"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
msgid "Use Bicubic Sampling"
-msgstr ""
+msgstr "استخدم طريقة Bicubic Sampling"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Renderable Elements"
-msgstr ""
+msgstr "الحد الأقصى للعناصر القابلة للعرض"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Renderable Lights"
-msgstr ""
+msgstr "الحجم الأقصى للأضواء القابلة للعرض"
#: drivers/gles3/rasterizer_scene_gles3.cpp
#, fuzzy
@@ -1048,11 +1059,11 @@ msgstr "Ù†ØµÙ Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Lights Per Object"
-msgstr ""
+msgstr "الحد الأقصى للأضواء لكل كائن"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Subsurface Scattering"
-msgstr ""
+msgstr "التشتت تحت السطح"
#: drivers/gles3/rasterizer_scene_gles3.cpp editor/animation_track_editor.cpp
#: editor/import/resource_importer_texture.cpp
@@ -1074,19 +1085,19 @@ msgstr "تزويد السطح"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Weight Samples"
-msgstr ""
+msgstr "عينات الوزن"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Voxel Cone Tracing"
-msgstr ""
+msgstr "تتبع مخروط Ùوكسل (Voxel)"
#: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp
msgid "High Quality"
-msgstr ""
+msgstr "جودة عالية"
#: drivers/gles3/rasterizer_storage_gles3.cpp
msgid "Blend Shape Max Buffer Size (KB)"
-msgstr ""
+msgstr "الحد الأقصى لحجم المخزن المؤقت لشكل المزج (كيلو بايت)"
#. TRANSLATORS: Adjective, refers to the mode for Bezier handles (Free, Balanced, Mirror).
#: editor/animation_bezier_editor.cpp
@@ -1197,7 +1208,7 @@ msgstr "الكمية:"
#: editor/animation_track_editor.cpp main/main.cpp
#: modules/mono/mono_gd/gd_mono.cpp
msgid "Args"
-msgstr ""
+msgstr "المعاملات (Args)"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp
@@ -1221,7 +1232,7 @@ msgstr "حدد المعامل"
#: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp
#: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp
msgid "Stream"
-msgstr ""
+msgstr "المجرى (Stream)"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -1657,7 +1668,7 @@ msgstr "دوال"
#: editor/animation_track_editor.cpp
msgid "Bezier"
-msgstr ""
+msgstr "منحنى بيزر (Bezier)"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2243,7 +2254,7 @@ msgstr "Ø¥ÙØªØ­"
#: editor/dependency_editor.cpp
msgid "Owners of: %s (Total: %d)"
-msgstr ""
+msgstr "مالكو: %s (المجموع: %d)"
#: editor/dependency_editor.cpp
msgid ""
@@ -2803,7 +2814,7 @@ msgstr "إختر"
#: editor/editor_export.cpp
msgid "Project export for platform:"
-msgstr ""
+msgstr "تصدير المشروع لمنصة:"
#: editor/editor_export.cpp
#, fuzzy
@@ -2933,11 +2944,11 @@ msgstr "تنسيق ثنائي"
#: editor/editor_export.cpp
msgid "64 Bits"
-msgstr ""
+msgstr "64 بت"
#: editor/editor_export.cpp
msgid "Embed PCK"
-msgstr ""
+msgstr "تضمين PCK"
#: editor/editor_export.cpp platform/osx/export/export.cpp
#, fuzzy
@@ -2946,19 +2957,19 @@ msgstr "منطقة النقش TextureRegion"
#: editor/editor_export.cpp
msgid "BPTC"
-msgstr ""
+msgstr "BPTC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "S3TC"
-msgstr ""
+msgstr "S3TC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "ETC"
-msgstr ""
+msgstr "ETC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "ETC2"
-msgstr ""
+msgstr "ETC2"
#: editor/editor_export.cpp
#, fuzzy
@@ -3009,7 +3020,7 @@ msgstr "لا يمكن Ù„Ù…ÙØµØ¯Ø±Ø§Øª 32-bit التي تتضمن PCK أن تكÙ
#: editor/editor_export.cpp
msgid "Convert Text Resources To Binary On Export"
-msgstr ""
+msgstr "تحويل الموارد النصية إلى صيغة ثنائية عند التصدير"
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -3331,7 +3342,7 @@ msgstr "أظهر Ø§Ù„Ù…Ù„ÙØ§Øª المخÙية"
#: editor/editor_file_dialog.cpp
msgid "Disable Overwrite Warning"
-msgstr ""
+msgstr "تعطيل تحذير الإستبدال"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
@@ -3432,7 +3443,7 @@ msgstr "إعادة إستيراد الأصول"
#: editor/editor_file_system.cpp
msgid "Reimport Missing Imported Files"
-msgstr ""
+msgstr "إعادة استيراد Ø§Ù„Ù…Ù„ÙØ§Øª المستوردة المÙقودة"
#: editor/editor_help.cpp scene/2d/camera_2d.cpp scene/gui/control.cpp
#: scene/gui/nine_patch_rect.cpp scene/resources/dynamic_font.cpp
@@ -3544,7 +3555,7 @@ msgstr "مساعدة"
#: editor/editor_help.cpp
msgid "Sort Functions Alphabetically"
-msgstr ""
+msgstr "ترتيب الدوال أبجديا"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -4323,6 +4334,8 @@ msgstr "%d مزيد من Ø§Ù„Ù…Ù„ÙØ§Øª"
msgid ""
"Unable to write to file '%s', file in use, locked or lacking permissions."
msgstr ""
+"غير قادر على الكتابة إلى المل٠'% s' ، المل٠قيد الاستخدام ، مؤمن أو ينقصه "
+"الأذونات."
#: editor/editor_node.cpp editor/editor_settings.cpp editor/scene_tree_dock.cpp
#: servers/arvr/arvr_interface.cpp
@@ -4342,11 +4355,11 @@ msgstr "إظهار الشبكة دوماً"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Resize If Many Tabs"
-msgstr ""
+msgstr "تغيير الحجم ÙÙŠ حالة وجود العديد من علامات التبويب"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Minimum Width"
-msgstr ""
+msgstr "الحد الأدنى للعرض"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Output"
@@ -4359,15 +4372,15 @@ msgstr "مسح Ø§Ù„Ù…ÙØ®Ø±Ø¬Ø§Øª"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Always Open Output On Play"
-msgstr ""
+msgstr "دائما Ø§ÙØªØ­ Ù†Ø§ÙØ°Ø© الإخراج أثناء التشغيل"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Always Close Output On Stop"
-msgstr ""
+msgstr "دائما أغلق Ù†Ø§ÙØ°Ø© الإخراج عند إيقا٠التشغيل"
#: editor/editor_node.cpp
msgid "Save On Focus Loss"
-msgstr ""
+msgstr "Ø­ÙØ¸ عند Ùقدان التركيز"
#: editor/editor_node.cpp editor/editor_settings.cpp
#, fuzzy
@@ -4405,7 +4418,7 @@ msgstr "عقدة التنقل الزمني"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Show Thumbnail On Hover"
-msgstr ""
+msgstr "إظهار الصورة المصغرة عند التمرير"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Inspector"
@@ -4418,7 +4431,7 @@ msgstr "مسار المشروع:"
#: editor/editor_node.cpp
msgid "Default Float Step"
-msgstr ""
+msgstr "خطوة الfloat Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©"
#: editor/editor_node.cpp scene/gui/tree.cpp
#, fuzzy
@@ -4427,15 +4440,15 @@ msgstr "زر معطّل"
#: editor/editor_node.cpp
msgid "Auto Unfold Foreign Scenes"
-msgstr ""
+msgstr "إكش٠المشاهد الأجنبية تلقائيا"
#: editor/editor_node.cpp
msgid "Horizontal Vector2 Editing"
-msgstr ""
+msgstr "تحرير Vector2 الأÙقي"
#: editor/editor_node.cpp
msgid "Horizontal Vector Types Editing"
-msgstr ""
+msgstr "تحرير أنواع المتجهات الأÙقية"
#: editor/editor_node.cpp
#, fuzzy
@@ -4449,7 +4462,7 @@ msgstr "Ø§ÙØªØ­ ÙÙŠ Ø§Ù„Ù…ÙØªØµÙØ­"
#: editor/editor_node.cpp
msgid "Default Color Picker Mode"
-msgstr ""
+msgstr "وضع منتقي الألوان Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
@@ -5079,6 +5092,12 @@ msgid ""
"functions called by that function.\n"
"Use this to find individual functions to optimize."
msgstr ""
+"شامل: يشمل الوقت من الدوال الأخرى التي تستدعيها هذه الدالة.\n"
+"استخدم هذا لتحديد الاختناقات (bottlenecks).\n"
+"\n"
+"ذاتي: احسب Ùقط الوقت المستغرق ÙÙŠ الدالة Ù†ÙØ³Ù‡Ø§ ØŒ وليس ÙÙŠ الدوال الأخرى التي "
+"تستدعيها تلك الدالة.\n"
+"استخدم هذا للعثور على دوال محددة لتحسينها."
#: editor/editor_profiler.cpp
msgid "Frame #:"
@@ -5095,7 +5114,7 @@ msgstr "Ù…Ùنقح الأخطاء"
#: editor/editor_profiler.cpp
msgid "Profiler Frame History Size"
-msgstr ""
+msgstr "حجم تاريخ إطار المحلل"
#: editor/editor_profiler.cpp
#, fuzzy
@@ -5309,23 +5328,23 @@ msgstr "إظهار الكل"
#: editor/editor_settings.cpp
msgid "Custom Display Scale"
-msgstr ""
+msgstr "مقياس العرض المخصص"
#: editor/editor_settings.cpp
msgid "Main Font Size"
-msgstr ""
+msgstr "حجم الخط الرئيسي"
#: editor/editor_settings.cpp
msgid "Code Font Size"
-msgstr ""
+msgstr "حجم خط الشÙÙØ±Ø©"
#: editor/editor_settings.cpp
msgid "Font Antialiased"
-msgstr ""
+msgstr "الخط Antialiased"
#: editor/editor_settings.cpp
msgid "Font Hinting"
-msgstr ""
+msgstr "تلميح الخط (Hinting)"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5334,7 +5353,7 @@ msgstr "المشهد الرئيس"
#: editor/editor_settings.cpp
msgid "Main Font Bold"
-msgstr ""
+msgstr "الخط الرئيسي غامق"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5343,15 +5362,15 @@ msgstr "Ø¥Ø¶Ø§ÙØ© نقطة العقدة"
#: editor/editor_settings.cpp
msgid "Dim Editor On Dialog Popup"
-msgstr ""
+msgstr "Ø§Ø®ÙØª المحرر عند انبثاق Ù†Ø§ÙØ°Ø© الحوار"
#: editor/editor_settings.cpp main/main.cpp
msgid "Low Processor Mode Sleep (µsec)"
-msgstr ""
+msgstr "وضع السكون Ø§Ù„Ù…Ù†Ø®ÙØ¶ للمعالج (µsec)"
#: editor/editor_settings.cpp
msgid "Unfocused Low Processor Mode Sleep (µsec)"
-msgstr ""
+msgstr "وضع السكون Ø§Ù„Ù…Ù†Ø®ÙØ¶ للمعالج غير المركّز (µsec)"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5360,11 +5379,11 @@ msgstr "وضع خالي من الإلهاء"
#: editor/editor_settings.cpp
msgid "Automatically Open Screenshots"
-msgstr ""
+msgstr "ÙØªØ­ لقطات الشاشة تلقائيًا"
#: editor/editor_settings.cpp
msgid "Max Array Dictionary Items Per Page"
-msgstr ""
+msgstr "الحد الأقصى لعناصر قاموس المصÙÙˆÙØ© ÙÙŠ كل ØµÙØ­Ø©"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp
@@ -5378,7 +5397,7 @@ msgstr "إعداد Ù…ÙØ³Ø¨Ù‚"
#: editor/editor_settings.cpp
msgid "Icon And Font Color"
-msgstr ""
+msgstr "لون الأيقونة والخط"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5392,11 +5411,11 @@ msgstr "اختر لوناً"
#: editor/editor_settings.cpp scene/resources/environment.cpp
msgid "Contrast"
-msgstr ""
+msgstr "التباين"
#: editor/editor_settings.cpp
msgid "Relationship Line Opacity"
-msgstr ""
+msgstr "عتامة خط العلاقة"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5410,7 +5429,7 @@ msgstr "البكسلات المحيطية (الحدودية)"
#: editor/editor_settings.cpp
msgid "Use Graph Node Headers"
-msgstr ""
+msgstr "استخدم رؤوس وحدات الرسم البياني"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5454,7 +5473,7 @@ msgstr "نسخ الموارد"
#: editor/editor_settings.cpp
msgid "Safe Save On Backup Then Rename"
-msgstr ""
+msgstr "Ø­ÙØ¸ آمن على النسخ الاحتياطي ثم إعادة التسمية"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5468,7 +5487,7 @@ msgstr "الصورة المصغرة..."
#: editor/editor_settings.cpp
msgid "Docks"
-msgstr ""
+msgstr "Ø§Ù„Ù†ÙˆØ§ÙØ° المثبتة (Docked)"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5477,7 +5496,7 @@ msgstr "تعديل شجرة المشهد"
#: editor/editor_settings.cpp
msgid "Start Create Dialog Fully Expanded"
-msgstr ""
+msgstr "بدء Ù†Ø§ÙØ°Ø© حوار الإنشاء موسعة بالكامل"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5491,7 +5510,7 @@ msgstr "محرر المجموعات"
#: editor/editor_settings.cpp
msgid "Auto Refresh Interval"
-msgstr ""
+msgstr "Ø§Ù„ÙØ§ØµÙ„ الزمني للتحديث التلقائي"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5506,7 +5525,7 @@ msgstr "مظهر المحرر/برنامج-جودوه"
#: editor/editor_settings.cpp scene/3d/label_3d.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Line Spacing"
-msgstr ""
+msgstr "تباعد الأسطر"
#: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp
#: modules/gdscript/editor/gdscript_highlighter.cpp
@@ -5521,15 +5540,15 @@ msgstr "Ù…ÙØ¹Ù„ّم التركيب Syntax"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Highlight All Occurrences"
-msgstr ""
+msgstr "قم بتمييز جميع التكرارات"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Highlight Current Line"
-msgstr ""
+msgstr "تمييز السطر الحالي"
#: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp
msgid "Highlight Type Safe Lines"
-msgstr ""
+msgstr "تمييز سطور الأنواع الآمنة"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5564,11 +5583,11 @@ msgstr "تنقل"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Smooth Scrolling"
-msgstr ""
+msgstr "التمرير السلس"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "V Scroll Speed"
-msgstr ""
+msgstr "سرعة التمرير العمودي"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5577,15 +5596,20 @@ msgstr "إظهار المركز"
#: editor/editor_settings.cpp
msgid "Minimap Width"
-msgstr ""
+msgstr "عرض الخريطة المصغرة"
#: editor/editor_settings.cpp
msgid "Mouse Extra Buttons Navigate History"
-msgstr ""
+msgstr "تنقل ÙÙŠ سجل أزرار الماوس الإضاÙية"
+
+#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "تحديد الملئ خريطة-الشبكة"
#: editor/editor_settings.cpp
msgid "Appearance"
-msgstr ""
+msgstr "المظهر"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
#, fuzzy
@@ -5599,7 +5623,7 @@ msgstr "رقم الخط:"
#: editor/editor_settings.cpp
msgid "Show Bookmark Gutter"
-msgstr ""
+msgstr "إظهار مزراب الإشارة المرجعية"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5608,27 +5632,27 @@ msgstr "تخطي نقاط التكسّر"
#: editor/editor_settings.cpp
msgid "Show Info Gutter"
-msgstr ""
+msgstr "إظهار معلومات المزراب"
#: editor/editor_settings.cpp
msgid "Code Folding"
-msgstr ""
+msgstr "طي الكود"
#: editor/editor_settings.cpp
msgid "Word Wrap"
-msgstr ""
+msgstr "Ø§Ù„ØªÙØ§Ù الكلمات"
#: editor/editor_settings.cpp
msgid "Show Line Length Guidelines"
-msgstr ""
+msgstr "إظهار إرشادات طول السطر"
#: editor/editor_settings.cpp
msgid "Line Length Guideline Soft Column"
-msgstr ""
+msgstr "عمود ناعم لتوجيه طول السطر"
#: editor/editor_settings.cpp
msgid "Line Length Guideline Hard Column"
-msgstr ""
+msgstr "عمود غامق لتوجيه طول السطر"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -5637,7 +5661,7 @@ msgstr "محرر النص البرمجي"
#: editor/editor_settings.cpp
msgid "Show Members Overview"
-msgstr ""
+msgstr "عرض نظرة عامة على الأعضاء"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -5651,19 +5675,19 @@ msgstr "تشذيب Ø§Ù„ÙØ±Ø§ØºØ§Øª البيضاء الزائدة"
#: editor/editor_settings.cpp
msgid "Autosave Interval Secs"
-msgstr ""
+msgstr "Ø§Ù„ÙØ§ØµÙ„ الزمني Ù„Ù„Ø­ÙØ¸ التلقائي بالثواني"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
msgid "Restore Scripts On Load"
-msgstr ""
+msgstr "استعادة البرامج النصية عند التحميل"
#: editor/editor_settings.cpp
msgid "Auto Reload And Parse Scripts On Save"
-msgstr ""
+msgstr "إعادة تحميل البرامج النصية تلقائيا وتحليلها عند Ø§Ù„Ø­ÙØ¸"
#: editor/editor_settings.cpp
msgid "Auto Reload Scripts On External Change"
-msgstr ""
+msgstr "إعادة تحميل البرامج النصية تلقائيا عند تغييرها من الخارج"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5672,27 +5696,27 @@ msgstr "اجبار ارتداد(احتياط) التظليل"
#: editor/editor_settings.cpp
msgid "Sort Members Outline Alphabetically"
-msgstr ""
+msgstr "ÙØ±Ø² الخطوط العريضة للأعضاء أبجدياً"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Cursor"
-msgstr ""
+msgstr "المؤشر"
#: editor/editor_settings.cpp
msgid "Scroll Past End Of File"
-msgstr ""
+msgstr "التمرير إلى ما بعد نهاية الملÙ"
#: editor/editor_settings.cpp
msgid "Block Caret"
-msgstr ""
+msgstr "علامة الإقحام"
#: editor/editor_settings.cpp
msgid "Caret Blink"
-msgstr ""
+msgstr "وميض علامة الإقحام"
#: editor/editor_settings.cpp
msgid "Caret Blink Speed"
-msgstr ""
+msgstr "سرعة وميض علامة الإقحام"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5708,23 +5732,23 @@ msgstr "نسخ Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
#: editor/editor_settings.cpp
msgid "Idle Parse Delay"
-msgstr ""
+msgstr "تأخير التحليل الخامل"
#: editor/editor_settings.cpp
msgid "Auto Brace Complete"
-msgstr ""
+msgstr "اكمال القوس التلقائي"
#: editor/editor_settings.cpp
msgid "Code Complete Delay"
-msgstr ""
+msgstr "تأخير الإكمال التلقائي للكود"
#: editor/editor_settings.cpp
msgid "Put Callhint Tooltip Below Current Line"
-msgstr ""
+msgstr "ضع تلميح أداة Callhint أسÙÙ„ السطر الحالي"
#: editor/editor_settings.cpp
msgid "Callhint Tooltip Offset"
-msgstr ""
+msgstr "إزاحة تلميح أداة Callhint"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5748,15 +5772,15 @@ msgstr "أظهر المساعدات"
#: editor/editor_settings.cpp
msgid "Help Font Size"
-msgstr ""
+msgstr "حجم خط المساعدة"
#: editor/editor_settings.cpp
msgid "Help Source Font Size"
-msgstr ""
+msgstr "حجم خط مصدر المساعدة"
#: editor/editor_settings.cpp
msgid "Help Title Font Size"
-msgstr ""
+msgstr "حجم خط عنوان المساعدة"
#: editor/editor_settings.cpp modules/gridmap/grid_map_editor_plugin.cpp
msgid "Grid Map"
@@ -5774,11 +5798,11 @@ msgstr "عرض"
#: editor/editor_settings.cpp
msgid "Primary Grid Color"
-msgstr ""
+msgstr "لون الشبكة الأساسي"
#: editor/editor_settings.cpp
msgid "Secondary Grid Color"
-msgstr ""
+msgstr "لون الشبكة الثانوي"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5815,7 +5839,7 @@ msgstr "نقطة"
#: scene/resources/particles_material.cpp servers/physics_2d_server.cpp
#: servers/physics_server.cpp
msgid "Shape"
-msgstr ""
+msgstr "شكل"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5829,15 +5853,15 @@ msgstr "خطوة الشبكة:"
#: editor/editor_settings.cpp
msgid "Grid Division Level Max"
-msgstr ""
+msgstr "الحد الأقصى لمستوى تقسيم الشبكة"
#: editor/editor_settings.cpp
msgid "Grid Division Level Min"
-msgstr ""
+msgstr "الحد الأدنى لمستوى تقسيم الشبكة"
#: editor/editor_settings.cpp
msgid "Grid Division Level Bias"
-msgstr ""
+msgstr "التحيز على مستوى تقسيم الشبكة"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5871,7 +5895,7 @@ msgstr "Ø§ÙØªØ±Ø§Ø¶ÙŠ"
#: editor/editor_settings.cpp
msgid "Lightmap Baking Number Of CPU Threads"
-msgstr ""
+msgstr "عدد خطوط المعالجة Ù„Ø­ÙØ¸ خرائط الإضاءة"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5895,11 +5919,11 @@ msgstr "تصغير"
#: editor/editor_settings.cpp
msgid "Emulate Numpad"
-msgstr ""
+msgstr "محاكاة لوحة Ù…ÙØ§ØªÙŠØ­ الأرقام"
#: editor/editor_settings.cpp
msgid "Emulate 3 Button Mouse"
-msgstr ""
+msgstr "محاكاة الماوس ذو الثلاثة أزرار"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5918,7 +5942,7 @@ msgstr "Ù…ÙØ¹Ø¯Ù‘Ù„"
#: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Warped Mouse Panning"
-msgstr ""
+msgstr "Ø§Ù„ØªÙØ§Ù الحركة بالماوس"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5927,11 +5951,11 @@ msgstr "وضع التنقل"
#: editor/editor_settings.cpp
msgid "Orbit Sensitivity"
-msgstr ""
+msgstr "حساسية التدوير"
#: editor/editor_settings.cpp
msgid "Orbit Inertia"
-msgstr ""
+msgstr "القصور الذاتي المداري"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5995,7 +6019,7 @@ msgstr "المحاذاة الذكية"
#: editor/editor_settings.cpp
msgid "Bone Width"
-msgstr ""
+msgstr "عرض العظام"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6014,11 +6038,11 @@ msgstr "عدل على الحساب الحالي:"
#: editor/editor_settings.cpp
msgid "Bone IK Color"
-msgstr ""
+msgstr "لون IK العظام"
#: editor/editor_settings.cpp
msgid "Bone Outline Color"
-msgstr ""
+msgstr "لون حدود العظام"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6027,19 +6051,19 @@ msgstr "حجم الخطوط:"
#: editor/editor_settings.cpp
msgid "Viewport Border Color"
-msgstr ""
+msgstr "لون حدود إطار العرض"
#: editor/editor_settings.cpp
msgid "Constrain Editor View"
-msgstr ""
+msgstr "تقييد عرض المحرر"
#: editor/editor_settings.cpp
msgid "Simple Panning"
-msgstr ""
+msgstr "التحريك البسيط"
#: editor/editor_settings.cpp
msgid "Scroll To Pan"
-msgstr ""
+msgstr "التمرير للتحريك"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6053,7 +6077,7 @@ msgstr "Ù…ÙØ­Ø±Ø± UV الخاص Ø¨Ø§Ù„Ù…ÙØ¶Ù„عات ثنائية Ø§Ù„Ø¨ÙØ¹Ø¯"
#: editor/editor_settings.cpp
msgid "Point Grab Radius"
-msgstr ""
+msgstr "قطر نقطة الإنتزاع"
#: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -6067,7 +6091,7 @@ msgstr "إعادة تسمية الرسم المتحرك"
#: editor/editor_settings.cpp
msgid "Default Create Bezier Tracks"
-msgstr ""
+msgstr "إنشاء مسارات Bezier Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠØ©"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6076,11 +6100,11 @@ msgstr "إنشاء مسار(ات) إعادة التعيين (RESET)"
#: editor/editor_settings.cpp
msgid "Onion Layers Past Color"
-msgstr ""
+msgstr "لون Onion Layers ÙÙŠ الماضي"
#: editor/editor_settings.cpp
msgid "Onion Layers Future Color"
-msgstr ""
+msgstr "لون Onion Layers ÙÙŠ المستقبل"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6089,11 +6113,11 @@ msgstr "محرر المجموعات"
#: editor/editor_settings.cpp
msgid "Minimap Opacity"
-msgstr ""
+msgstr "عتامة الخريطة المصغرة"
#: editor/editor_settings.cpp
msgid "Window Placement"
-msgstr ""
+msgstr "موضع Ø§Ù„Ù†Ø§ÙØ°Ø©"
#: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp
#: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp
@@ -6109,7 +6133,7 @@ msgstr "حدد موقع خروج الإنحناء"
#: editor/editor_settings.cpp platform/android/export/export_plugin.cpp
msgid "Screen"
-msgstr ""
+msgstr "شاشة"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6144,17 +6168,17 @@ msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
#: editor/editor_settings.cpp
msgid "HTTP Proxy"
-msgstr ""
+msgstr "وكيل (Proxy) HTTP"
#: editor/editor_settings.cpp
msgid "Host"
-msgstr ""
+msgstr "المضيÙ"
#: editor/editor_settings.cpp editor/fileserver/editor_file_server.cpp
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Port"
-msgstr ""
+msgstr "Ù…Ù†ÙØ°"
#. TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects.
#: editor/editor_settings.cpp
@@ -6169,15 +6193,15 @@ msgstr "إعادة تسمية مجلد:"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Symbol Color"
-msgstr ""
+msgstr "لون الرمز"
#: editor/editor_settings.cpp
msgid "Keyword Color"
-msgstr ""
+msgstr "لون الكلمة Ø§Ù„Ù…ÙØªØ§Ø­ÙŠØ©"
#: editor/editor_settings.cpp
msgid "Control Flow Keyword Color"
-msgstr ""
+msgstr "لون الكلمة Ø§Ù„Ù…ÙØªØ§Ø­ÙŠØ© لتدÙÙ‚ التحكم"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6186,15 +6210,15 @@ msgstr "النوع الأساسي"
#: editor/editor_settings.cpp
msgid "Engine Type Color"
-msgstr ""
+msgstr "لون نوع المحرك"
#: editor/editor_settings.cpp
msgid "User Type Color"
-msgstr ""
+msgstr "لون نوع المستخدم"
#: editor/editor_settings.cpp
msgid "Comment Color"
-msgstr ""
+msgstr "لون التعليق"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6220,15 +6244,15 @@ msgstr "إستيراد المحدد"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Existing Color"
-msgstr ""
+msgstr "لون الإكمال الموجود"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Scroll Color"
-msgstr ""
+msgstr "لون تمرير الإكمال"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Font Color"
-msgstr ""
+msgstr "لون خط الإكمال"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6247,7 +6271,7 @@ msgstr "رقم الخط:"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Caret Color"
-msgstr ""
+msgstr "لون علامة الإقحام"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -6266,7 +6290,7 @@ msgstr "المحدد Ùقط"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Brace Mismatch Color"
-msgstr ""
+msgstr "لون عدم تطابق الأقواس"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -6275,7 +6299,7 @@ msgstr "المشهد الحالي"
#: editor/editor_settings.cpp
msgid "Line Length Guideline Color"
-msgstr ""
+msgstr "لون إرشاد طول السطر"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -6284,7 +6308,7 @@ msgstr "Ù…ÙØ¹Ù„ّم التركيب Syntax"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Number Color"
-msgstr ""
+msgstr "لون الرقم"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -6313,11 +6337,11 @@ msgstr "نقاط التكسّر"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Executing Line Color"
-msgstr ""
+msgstr "لون سطر التنÙيذ"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Code Folding Color"
-msgstr ""
+msgstr "لون الكود القابل للطي"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6632,7 +6656,7 @@ msgstr ""
#: editor/fileserver/editor_file_server.cpp
msgid "File Server"
-msgstr ""
+msgstr "خادم Ø§Ù„Ù…Ù„ÙØ§Øª"
#: editor/fileserver/editor_file_server.cpp
#: editor/plugins/version_control_editor_plugin.cpp
@@ -6998,11 +7022,11 @@ msgstr "إدارة المجموعات"
#: editor/import/editor_import_collada.cpp
msgid "Collada"
-msgstr ""
+msgstr "كولادا (Collada)"
#: editor/import/editor_import_collada.cpp
msgid "Use Ambient"
-msgstr ""
+msgstr "استخدم Ambient"
#: editor/import/resource_importer_bitmask.cpp
#, fuzzy
@@ -7012,7 +7036,7 @@ msgstr "أنشئ مجلد"
#: editor/import/resource_importer_bitmask.cpp
#: servers/audio/effects/audio_effect_compressor.cpp
msgid "Threshold"
-msgstr ""
+msgstr "عتبة"
#: editor/import/resource_importer_csv_translation.cpp
#: editor/import/resource_importer_layered_texture.cpp
@@ -7025,7 +7049,7 @@ msgstr "مكونات"
#: editor/import/resource_importer_csv_translation.cpp
msgid "Delimiter"
-msgstr ""
+msgstr "محدد"
#: editor/import/resource_importer_layered_texture.cpp
#, fuzzy
@@ -7034,7 +7058,7 @@ msgstr "Ø§Ù„ÙˆØ¸ÙŠÙØ© البرمجية للون."
#: editor/import/resource_importer_layered_texture.cpp
msgid "No BPTC If RGB"
-msgstr ""
+msgstr "لا BPTC إذا RGB"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/2d/cpu_particles_2d.cpp
@@ -7048,7 +7072,7 @@ msgstr "أعلام"
#: editor/import/resource_importer_texture.cpp scene/animation/tween.cpp
#: scene/resources/texture.cpp
msgid "Repeat"
-msgstr ""
+msgstr "كرر"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/2d/light_2d.cpp
@@ -7066,12 +7090,12 @@ msgstr "الإشارات"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
msgid "Anisotropic"
-msgstr ""
+msgstr "تباين الخواص"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
msgid "sRGB"
-msgstr ""
+msgstr "sRGB (قياسي)"
#: editor/import/resource_importer_layered_texture.cpp
#, fuzzy
@@ -7192,7 +7216,7 @@ msgstr "تخزين الملÙ:"
#: editor/import/resource_importer_scene.cpp
msgid "Use Legacy Names"
-msgstr ""
+msgstr "استخدم الأسماء القديمة"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
#, fuzzy
@@ -7225,8 +7249,9 @@ msgid "Lightmap Texel Size"
msgstr "طبخ/تجهيز-خريطة-الاضاءة"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
+#, fuzzy
msgid "Skins"
-msgstr ""
+msgstr "سكينس (Skins)"
#: editor/import/resource_importer_scene.cpp
#, fuzzy
@@ -7240,7 +7265,7 @@ msgstr "Ø¥ÙØªØ­ ملÙ"
#: editor/import/resource_importer_scene.cpp
msgid "Store In Subdir"
-msgstr ""
+msgstr "خزن ÙÙŠ مجلد ÙØ±Ø¹ÙŠ"
#: editor/import/resource_importer_scene.cpp
#, fuzzy
@@ -7351,16 +7376,20 @@ msgid ""
"%s: Texture detected as used as a normal map in 3D. Enabling red-green "
"texture compression to reduce memory usage (blue channel is discarded)."
msgstr ""
+"%s: تم الكش٠عن نقش مستخدم كخريطة نورمال (NormalMap) ÙÙŠ 3D. تمكين ضغط نقش "
+"الأحمر والأخضر لتقليل استخدام الذاكرة (يتم تجاهل القناة الزرقاء)."
#: editor/import/resource_importer_texture.cpp
msgid ""
"%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap "
"generation and VRAM texture compression."
msgstr ""
+"%s: تم الكش٠عن نقش مستخدم ÙÙŠ 3D. تمكين المرشح والتكرار وتوليد خريطة-الرسمة-"
+"بدقات-متعددة (mipmap) وضغط نقش VRAM."
#: editor/import/resource_importer_texture.cpp
msgid "2D, Detect 3D"
-msgstr ""
+msgstr "2D، والكش٠عن 3D"
#: editor/import/resource_importer_texture.cpp
#, fuzzy
@@ -7369,7 +7398,7 @@ msgstr "البكسيلات الأساسية (Solid Pixels)"
#: editor/import/resource_importer_texture.cpp scene/resources/texture.cpp
msgid "Lossy Quality"
-msgstr ""
+msgstr "جودة ضائعة (Lossy)"
#: editor/import/resource_importer_texture.cpp
#, fuzzy
@@ -7378,14 +7407,14 @@ msgstr "تحديد الوضع"
#: editor/import/resource_importer_texture.cpp
msgid "BPTC LDR"
-msgstr ""
+msgstr "BPTC LDR"
#: editor/import/resource_importer_texture.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp
#: scene/2d/mesh_instance_2d.cpp scene/2d/multimesh_instance_2d.cpp
#: scene/2d/particles_2d.cpp scene/2d/sprite.cpp scene/resources/style_box.cpp
msgid "Normal Map"
-msgstr ""
+msgstr "خريطة عادية"
#: editor/import/resource_importer_texture.cpp
#, fuzzy
@@ -7394,7 +7423,7 @@ msgstr "المعالجة-اللاحقة Post-Process"
#: editor/import/resource_importer_texture.cpp
msgid "Fix Alpha Border"
-msgstr ""
+msgstr "إصلاح حدود Ø£Ù„ÙØ§"
#: editor/import/resource_importer_texture.cpp
#, fuzzy
@@ -7403,7 +7432,7 @@ msgstr "تعديل Ù…ÙØªØ¹Ø¯Ø¯ السطوح"
#: editor/import/resource_importer_texture.cpp
msgid "Hdr As Srgb"
-msgstr ""
+msgstr "Hdr As Srgb"
#: editor/import/resource_importer_texture.cpp
#, fuzzy
@@ -7421,7 +7450,7 @@ msgstr "الحد الأقصى للحجم"
#: editor/import/resource_importer_texture.cpp
msgid "Detect 3D"
-msgstr ""
+msgstr "كش٠3D"
#: editor/import/resource_importer_texture.cpp
#, fuzzy
@@ -7433,6 +7462,8 @@ msgid ""
"Warning, no suitable PC VRAM compression enabled in Project Settings. This "
"texture will not display correctly on PC."
msgstr ""
+"تحذير، لم يتم تمكين ضغط VRAM مناسب للكمبيوتر الشخصي ÙÙŠ إعدادات المشروع. لن "
+"يتم عرض هذا النقش بشكل صحيح على جهاز الكمبيوتر."
#: editor/import/resource_importer_texture_atlas.cpp
#, fuzzy
@@ -7451,7 +7482,7 @@ msgstr "تحديد منطقة البلاط"
#: editor/import/resource_importer_texture_atlas.cpp
msgid "Trim Alpha Border From Region"
-msgstr ""
+msgstr "تقليم حدود Ø£Ù„ÙØ§ من المنطقة"
#: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp
#, fuzzy
@@ -7460,12 +7491,12 @@ msgstr "أنشر بإجبار"
#: editor/import/resource_importer_wav.cpp
msgid "8 Bit"
-msgstr ""
+msgstr "8 بت"
#: editor/import/resource_importer_wav.cpp main/main.cpp
#: modules/mono/editor/csharp_project.cpp modules/mono/mono_gd/gd_mono.cpp
msgid "Mono"
-msgstr ""
+msgstr "احاديه"
#: editor/import/resource_importer_wav.cpp
#, fuzzy
@@ -7479,7 +7510,7 @@ msgstr "عقدة الخلط"
#: editor/import/resource_importer_wav.cpp
msgid "Trim"
-msgstr ""
+msgstr "تقليم"
#: editor/import/resource_importer_wav.cpp
#, fuzzy
@@ -7596,7 +7627,7 @@ msgstr "محلي"
#: editor/inspector_dock.cpp
msgid "Localization not available for current language."
-msgstr ""
+msgstr "الترجمة غير Ù…ØªÙˆÙØ±Ø© للغة الحالية."
#: editor/inspector_dock.cpp
msgid "Copy Properties"
@@ -8045,11 +8076,20 @@ msgid "New Anim"
msgstr "رسم متحرك جديدة"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "إنشاء رسوم متحركة جديدة"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "تغيير إسم الرسم المتحرك:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "إعادة تسمية الرسم المتحرك"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "مسح الرسم المتحرك؟"
@@ -8067,11 +8107,6 @@ msgid "Animation name already exists!"
msgstr "إسم الرسم المتحرك موجود Ø¨Ø§Ù„ÙØ¹Ù„!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "إعادة تسمية الرسم المتحرك"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "تكرار الرسم المتحرك"
@@ -8215,10 +8250,6 @@ msgid "Pin AnimationPlayer"
msgstr "تثبيت Ù…ÙØ´ØºÙ‘Ù„ الرسوميات المتحركة"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "إنشاء رسوم متحركة جديدة"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "إسم الرسم المتحرك:"
@@ -8473,7 +8504,7 @@ msgstr "الÙلترة..."
#: editor/plugins/asset_library_editor_plugin.cpp scene/main/http_request.cpp
msgid "Use Threads"
-msgstr ""
+msgstr "استخدم خطوط المعالجة"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Contents:"
@@ -8706,7 +8737,7 @@ msgstr "أختبار"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Failed to get repository configuration."
-msgstr ""
+msgstr "ÙØ´Ù„ الحصول على إعدادات الأرشيÙ."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -9273,7 +9304,7 @@ msgstr "المحاذاة الذكية"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Hide"
-msgstr ""
+msgstr "Ø§Ø®ÙØ§Ø¡"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -9657,7 +9688,7 @@ msgstr "الأيقونة"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "ID"
-msgstr ""
+msgstr "بطاقة تعريÙ"
#: editor/plugins/item_list_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -10733,11 +10764,11 @@ msgstr "توقÙ"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
msgid "Continue"
-msgstr "استمرار"
+msgstr "يكمل"
#: editor/plugins/script_editor_plugin.cpp
msgid "Keep Debugger Open"
-msgstr "إبقاء منÙقتح الأخطاء البرمجية Ù…ÙØªÙˆØ­Ø§Ù‹"
+msgstr "إبقاء المصحح Ù…ÙØªÙˆØ­Ù‹Ø§"
#: editor/plugins/script_editor_plugin.cpp
msgid "Debug with External Editor"
@@ -18829,6 +18860,11 @@ msgid "The package must have at least one '.' separator."
msgstr "يجب أن تتضمن الرزمة على الأقل واحد من الÙواصل '.' ."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "قص العÙقد"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18837,6 +18873,16 @@ msgstr ""
msgid "Export Format"
msgstr "مسار التصدير"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "حجم الخطوط:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "الهدÙ"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18880,16 +18926,6 @@ msgstr "ØªÙØ­Øµ النمذجة السابقة"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "حجم الخطوط:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "الهدÙ"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19149,7 +19185,7 @@ msgstr "يجب ØªÙØ¹ÙŠÙ„ \"Use Custom Build\" لإستخدام Ø§Ù„Ø¥Ø¶Ø§ÙØ§Øª
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" تكون صالحة Ùقط عندما يكون وضع ال \"Xr Mode\"هو \"Oculus "
@@ -19157,7 +19193,7 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" تكون صالحة Ùقط عندما يكون وضع ال \"Xr Mode\"هو \"Oculus "
"Mobile VR\"."
@@ -19171,22 +19207,43 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"يصبح خيار \"تصدير ABB\" صالحاً Ùقط عندما يتم اختيار \"استعمال تصدير مخصص "
"Custom Build\"."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"يصبح خيار \"تصدير ABB\" صالحاً Ùقط عندما يتم اختيار \"استعمال تصدير مخصص "
"Custom Build\"."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"إصدار \"حزمة التطوير البرمجية Ø§Ù„Ù…Ø³ØªÙ‡Ø¯ÙØ©\" يجب أن يكون أعلى من أو يساوي إصدار "
"\"Min Sdk\"."
@@ -20859,7 +20916,7 @@ msgstr "تكبير"
msgid "Custom Viewport"
msgstr "ساحة رؤية واحدة"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21631,11 +21688,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "تعديل الإتصال:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "الربط"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "اختر Ø§Ù„Ù…Ø³Ø§ÙØ©:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "اختر Ø§Ù„Ù…Ø³Ø§ÙØ©:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "إعدادات متقدمة"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "ØªÙØ¹ÙŠÙ„"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21653,16 +21742,6 @@ msgstr "القلب Ø£Ùقياً"
msgid "Max Speed"
msgstr "السرعة:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "اختر Ø§Ù„Ù…Ø³Ø§ÙØ©:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "ØªÙØ¹ÙŠÙ„"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21707,7 +21786,7 @@ msgstr "Ø§Ù„Ø³ÙØ±"
msgid "Rotation Degrees"
msgstr "ÙŠÙØ¯ÙŠØ± %s من الدرجات."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "ثابت"
@@ -22929,6 +23008,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "أجهض التحول."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23832,6 +23918,11 @@ msgstr ""
"قم بتغيير الحجم ÙÙŠ أشكال تصادم الأتباع (Children) بدلاً من ذلك."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Ø§Ù„Ø§Ø­ØªÙØ§Ø¸ بالتحوّل الشمولي Global"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25088,6 +25179,11 @@ msgstr "مجلد:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "المحدد Ùقط"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "ØªÙØ¹ÙŠÙ„"
@@ -25491,17 +25587,6 @@ msgid "Viewport Path"
msgstr "مسار التصدير"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"لم يتم تعيين Ù…Ù†ÙØ° العرض هذا كهد٠عرض. إذا كنت تنوي عرض محتوياته مباشرة على "
-"الشاشة ، اجعله تابعًا لعنصر تحكم حتى يتمكن من الحصول على الحجم. خلا٠ذلك ، "
-"اجعلها RenderTarget وقم بتعيين نسيجها الداخلي لبعض العقد لعرضها."
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -25509,6 +25594,15 @@ msgid ""
msgstr "ينبغي أن يكون حجم إطار العرض أكبر من 0 ليتم الإخراج البصري لأي شيء."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27264,6 +27358,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "توليد AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Ø§Ù„Ù…ÙØ¹Ø§Ø¯Ù„:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/az.po b/editor/translations/az.po
index 6e8dfbf1f3..cd3e8def9b 100644
--- a/editor/translations/az.po
+++ b/editor/translations/az.po
@@ -407,6 +407,11 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Siqnalları filtirlə"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -459,6 +464,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5396,6 +5405,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Ölçmə seçimi"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7731,11 +7745,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7753,11 +7776,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7900,10 +7918,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18002,6 +18016,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Funksiyalar:"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18010,6 +18029,14 @@ msgstr ""
msgid "Export Format"
msgstr "3D Transformasya izi"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr ""
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18046,14 +18073,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr ""
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18279,12 +18298,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18293,17 +18312,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19848,7 +19887,7 @@ msgstr "Yaxınlaşdır"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20521,35 +20560,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "ÆlaqÉ™ni redaktÉ™ edin:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Pathfinding"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Quraşdır"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Qabaqcıl"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
msgid "Avoidance Enabled"
msgstr "Siqnalları filtirlə"
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20588,7 +20648,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21650,6 +21710,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "3D Transformasya izi"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22492,6 +22559,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Animasiyanı Təmizləmə"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23617,6 +23689,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Yalnız Seçim"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Siqnalları filtirlə"
@@ -23983,16 +24060,17 @@ msgstr "Yol"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25610,6 +25688,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "%s növünü dəyişdirin"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 9370a48a79..06d16ebe96 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -431,6 +431,11 @@ msgstr "Мета"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Включване"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -487,6 +492,10 @@ msgid "Pressure"
msgstr "ÐатиÑк"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5480,6 +5489,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "ÐаÑтройки"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7889,11 +7903,20 @@ msgid "New Anim"
msgstr "Ðова анимациÑ"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Създаване на нова анимациÑ"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "ПромÑна на името на анимациÑта:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Преименуване на анимациÑта"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Изтриване на анимациÑта?"
@@ -7911,11 +7934,6 @@ msgid "Animation name already exists!"
msgstr "Вече ÑъщеÑтвува Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ñ Ñ‚Ð¾Ð²Ð° име!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Преименуване на анимациÑта"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Дублиране на анимациÑта"
@@ -8060,10 +8078,6 @@ msgid "Pin AnimationPlayer"
msgstr "Закачане на AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Създаване на нова анимациÑ"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Име на анимациÑта:"
@@ -18343,6 +18357,11 @@ msgid "The package must have at least one '.' separator."
msgstr "Пакетът трÑбва да има поне един разделител „.“ (точка)."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "ПерÑонализиран обект"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18351,6 +18370,16 @@ msgstr ""
msgid "Export Format"
msgstr "Път за изнаÑÑне"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Размер на контура:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Принудително изпращане"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18392,16 +18421,6 @@ msgstr "Предишен раздел"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Размер на контура:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Принудително изпращане"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18647,12 +18666,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18662,22 +18681,45 @@ msgstr ""
"ÑобÑтвена компилациÑ“."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"„Мин. верÑÐ¸Ñ Ð½Ð° SDK“ може да Ñе Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ Ñамо когато „Използване на ÑобÑтвена "
"компилациÑ“ е включено."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"„Целева верÑÐ¸Ñ Ð½Ð° SDK“ може да Ñе Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ Ñамо когато „Използване на "
"ÑобÑтвена компилациÑ“ е включено."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"„Целева верÑÐ¸Ñ Ð½Ð° SDK“ трÑбва да бъде по-голÑма или равна на „Мин. верÑÐ¸Ñ Ð½Ð° "
"SDK“."
@@ -20333,7 +20375,7 @@ msgstr "Приближаване"
msgid "Custom Viewport"
msgstr "1 прозорец за изглед"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21072,11 +21114,42 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Редактиране на Връзката:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "ОтÑтъп"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Изберете главна Ñцена"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Включване"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Включване"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21094,15 +21167,6 @@ msgstr "Хоризонтала:"
msgid "Max Speed"
msgstr "СкороÑÑ‚:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Включване"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21145,7 +21209,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr "ГрадуÑи на завъртане"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Глобална конÑтанта"
@@ -22294,6 +22358,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "КонÑтанта за транÑформациÑ."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23176,6 +23247,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "ИзчиÑтване на транÑформациÑта"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24372,6 +24448,11 @@ msgstr "Папка:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Само избраното"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Включване"
@@ -24769,16 +24850,17 @@ msgstr "Път за изнаÑÑне"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26510,6 +26592,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "ОтмеÑтване:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 265a7fb58a..c2ed1a7596 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -12,13 +12,14 @@
# Sagen Soren <sagensoren03@gmail.com>, 2020.
# Hasibul Hasan <d1hasib@yahoo.com>, 2020.
# saitama <atik.wowspace@gmail.com>, 2022.
+# Joysankar Majumdar <joymajumdar15828@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-12 13:19+0000\n"
-"Last-Translator: saitama <atik.wowspace@gmail.com>\n"
+"PO-Revision-Date: 2022-06-29 10:04+0000\n"
+"Last-Translator: Joysankar Majumdar <joymajumdar15828@gmail.com>\n"
"Language-Team: Bengali <https://hosted.weblate.org/projects/godot-engine/"
"godot/bn/>\n"
"Language: bn\n"
@@ -26,7 +27,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -234,9 +235,8 @@ msgid "Remote FS"
msgstr "অপসারণ করà§à¦¨"
#: core/io/file_access_network.cpp
-#, fuzzy
msgid "Page Size"
-msgstr "পাতা: "
+msgstr "পাতা"
#: core/io/file_access_network.cpp
msgid "Page Read Ahead"
@@ -421,6 +421,11 @@ msgstr ""
msgid "Command"
msgstr "সমà§à¦ªà§à¦°à¦¦à¦¾à§Ÿ"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "সà§à¦¥à¦¿à¦°/বদà§à¦§ ফà§à¦°à§‡à¦® %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -479,6 +484,10 @@ msgid "Pressure"
msgstr "পà§à¦°à¦¿à¦¸à§‡à¦Ÿ..."
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "আপেকà§à¦·à¦¿à¦• সà§à¦¨à§à¦¯à¦¾à¦ª"
@@ -5807,6 +5816,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অপসারণ করà§à¦¨"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8404,11 +8418,20 @@ msgid "New Anim"
msgstr "নতà§à¦¨ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "নতà§à¦¨ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ তৈরি করà§à¦¨"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° নাম পরিবরà§à¦¤à¦¨ করà§à¦¨:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Delete অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨?"
@@ -8428,11 +8451,6 @@ msgid "Animation name already exists!"
msgstr "ভà§à¦²: অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° নাম ইতিমধà§à¦¯à§‡à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ করà§à¦¨"
@@ -8584,10 +8602,6 @@ msgid "Pin AnimationPlayer"
msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨ করà§à¦¨"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "নতà§à¦¨ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ তৈরি করà§à¦¨"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° নাম:"
@@ -19778,6 +19792,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "নোড-সমূহ করà§à¦¤à¦¨/কাট করà§à¦¨"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -19786,6 +19805,16 @@ msgstr ""
msgid "Export Format"
msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿà§‡à¦° পà§à¦°à¦¿à¦¸à§‡à¦Ÿ:"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "পà§à¦°à¦¾à¦¨à§à¦¤à¦°à§‡à¦–ার আকার:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "টারà§à¦—েট"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -19827,16 +19856,6 @@ msgstr "পূরà§à¦¬à¦¬à¦°à§à¦¤à§€ ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸ পরà
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "পà§à¦°à¦¾à¦¨à§à¦¤à¦°à§‡à¦–ার আকার:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "টারà§à¦—েট"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -20083,12 +20102,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -20097,17 +20116,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -21776,7 +21815,7 @@ msgstr "সমà§à¦ªà§à¦°à¦¸à¦¾à¦°à¦¿à¦¤ করà§à¦¨ (জà§à¦®à§ ইন)"
msgid "Custom Viewport"
msgstr "১ টি Viewport"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -22526,11 +22565,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "সংযোগসমূহ সমà§à¦ªà¦¾à¦¦à¦¨ করà§à¦¨"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "যথেচà§à¦› ঘূরà§à¦£à¦¾à§Ÿà¦¨:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° সিদà§à¦§à¦¾à¦¨à§à¦¤à¦¸à¦®à§‚হ"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -22547,16 +22618,6 @@ msgstr ""
msgid "Max Speed"
msgstr "গতি (FPS):"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -22601,7 +22662,7 @@ msgstr "ভà§à¦°à¦®à¦£"
msgid "Rotation Degrees"
msgstr "%s ডিগà§à¦°à¦¿ ঘূরà§à¦£à¦¿à¦¤ হচà§à¦›à§‡à¥¤"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ"
@@ -23779,6 +23840,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "রà§à¦ªà¦¾à¦¨à§à¦¤à¦° নিষà§à¦«à¦²à¦¾ করা হয়েছে।"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -24667,6 +24735,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "সারà§à¦¬à¦œà¦¨à§€à¦¨ রূপানà§à¦¤à¦° রাখà§à¦¨"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25907,6 +25980,11 @@ msgstr "লাইন-ঠযান"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "শà§à¦§à§à¦®à¦¾à¦¤à§à¦° নিরà§à¦¬à¦¾à¦šà¦¿à¦¤à¦¸à¦®à§‚হ"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨"
@@ -26308,20 +26386,17 @@ msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿà§‡à¦° পà§à¦°à¦¿à¦¸à§‡à¦Ÿ:"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
-"à¦à¦‡ viewport টি render target হিসেবে নিরà§à¦§à¦¾à¦°à¦¨ করা নেই। আপনি যদি à¦à¦° বসà§à¦¤à§-সামগà§à¦°à§€ "
-"সরাসরি পরà§à¦¦à¦¾à§Ÿ দেখাতে চান, à¦à¦Ÿà¦¿à¦•ে যেকোনো Control à¦à¦° অংশভূত করà§à¦¨ যেনো à¦à¦Ÿà¦¿ à¦à¦•টি "
-"আকার ধারণ করতে পারে। অনà§à¦¯à¦¥à¦¾à§Ÿ, à¦à¦Ÿà¦¿à¦•ে à¦à¦•টি RenderTarget করà§à¦¨ à¦à¦¬à¦‚ à¦à¦° অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ "
-"দৃশà§à¦¯à¦¾à¦¬à¦²à¦¿à¦•ে (texture) দৃশà§à¦¯à¦®à¦¾à¦¨ করতে কোনো নোডে হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨à¥¤"
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -28087,6 +28162,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "AABB উৎপনà§à¦¨ করà§à¦¨"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "অফসেট/ভারসামà§à¦¯:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/br.po b/editor/translations/br.po
index 3d1ca48f3f..2d7b6fe900 100644
--- a/editor/translations/br.po
+++ b/editor/translations/br.po
@@ -397,6 +397,11 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Aktivañ ar Roudenn"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -449,6 +454,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5305,6 +5314,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7611,11 +7624,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7633,11 +7655,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7780,10 +7797,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17814,6 +17827,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Fonksionoù :"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17822,6 +17840,14 @@ msgstr ""
msgid "Export Format"
msgstr "Roudenn Treuzfurmadur 3D"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr ""
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17858,14 +17884,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr ""
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18088,12 +18106,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18102,17 +18120,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19639,7 +19677,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20303,35 +20341,55 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Tro Fiñvskeudenn"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Pathfinding"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Path Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Aktivañ ar Roudenn"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
msgid "Avoidance Enabled"
msgstr "Aktivañ ar Roudenn"
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20370,7 +20428,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21421,6 +21479,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Roudenn Treuzfurmadur 3D"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22256,6 +22321,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Tro Fiñvskeudenn"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23361,6 +23431,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Aktivañ ar Roudenn"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Aktivañ ar Roudenn"
@@ -23719,16 +23794,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25314,6 +25390,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 380a247ac7..67f0296b05 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -22,7 +22,7 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-19 11:52+0000\n"
+"PO-Revision-Date: 2022-07-09 21:11+0000\n"
"Last-Translator: Roger VC <rogervilarasau@gmail.com>\n"
"Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/"
"godot/ca/>\n"
@@ -67,7 +67,7 @@ msgstr "Mode de Baix Us del Processador"
#: core/bind/core_bind.cpp
msgid "Low Processor Usage Mode Sleep (µsec)"
-msgstr ""
+msgstr "Mode d'ús del processador baix en repòs (µseg)"
#: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp
msgid "Keep Screen On"
@@ -136,8 +136,9 @@ msgid "Size"
msgstr "Mida"
#: core/bind/core_bind.cpp
+#, fuzzy
msgid "Endian Swap"
-msgstr ""
+msgstr "Intercanvi d'endian"
#: core/bind/core_bind.cpp
msgid "Editor Hint"
@@ -161,9 +162,8 @@ msgid "Time Scale"
msgstr "Escala de Temps"
#: core/bind/core_bind.cpp main/main.cpp
-#, fuzzy
msgid "Physics Jitter Fix"
-msgstr "Fotograma de Física %"
+msgstr "Correcció de fluctuacions de física"
#: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Error"
@@ -246,25 +246,23 @@ msgstr "Connexió"
#: core/io/http_client.cpp
msgid "Read Chunk Size"
-msgstr ""
+msgstr "Llegeix la mida del fragment"
#: core/io/marshalls.cpp
msgid "Object ID"
msgstr "ID de l'Objecte"
#: core/io/multiplayer_api.cpp core/io/packet_peer.cpp
-#, fuzzy
msgid "Allow Object Decoding"
-msgstr "Activa l'Efecte Paper Ceba"
+msgstr "Permet la descodificació d'objectes"
#: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp
msgid "Refuse New Network Connections"
msgstr "Rebutja les noves connexions de xarxa"
#: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp
-#, fuzzy
msgid "Network Peer"
-msgstr "Perfilador de Xarxa"
+msgstr "Parell de xarxa"
#: core/io/multiplayer_api.cpp scene/animation/animation_player.cpp
msgid "Root Node"
@@ -275,13 +273,12 @@ msgid "Refuse New Connections"
msgstr "Rebutjar Noves Connexions"
#: core/io/networked_multiplayer_peer.cpp
-#, fuzzy
msgid "Transfer Mode"
-msgstr "Tipus de Transformació"
+msgstr "Mode de transferència"
#: core/io/packet_peer.cpp
msgid "Encode Buffer Max Size"
-msgstr ""
+msgstr "Mida màxima de la memòria intermèdia de codificació"
#: core/io/packet_peer.cpp
msgid "Input Buffer Max Size"
@@ -297,7 +294,7 @@ msgstr ""
#: core/io/stream_peer.cpp
msgid "Big Endian"
-msgstr ""
+msgstr "Endian gran"
#: core/io/stream_peer.cpp
msgid "Data Array"
@@ -373,14 +370,12 @@ msgid "Max Size (KB)"
msgstr "Mida màxima (KB)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "Mode de moviment"
+msgstr "Mode ratolí"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "Elimina l'Entrada"
+msgstr "Utilitza l'entrada acumulada"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -388,9 +383,8 @@ msgid "Device"
msgstr "Dispositiu"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Alt"
-msgstr "Tot"
+msgstr "Alt"
#: core/os/input_event.cpp
msgid "Shift"
@@ -409,6 +403,10 @@ msgstr "Meta"
msgid "Command"
msgstr "Comunitat"
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr "Físic"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -416,9 +414,8 @@ msgid "Pressed"
msgstr "Premut"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Scancode"
-msgstr "Explora"
+msgstr "Codi d'escaneig"
#: core/os/input_event.cpp
msgid "Physical Scancode"
@@ -463,6 +460,10 @@ msgid "Pressure"
msgstr "Configuracions prestablertes"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relatiu"
@@ -794,7 +795,7 @@ msgstr "Renderitzat"
#: scene/resources/multimesh.cpp servers/visual/visual_server_scene.cpp
#: servers/visual_server.cpp
msgid "Quality"
-msgstr ""
+msgstr "Qualitat"
#: core/project_settings.cpp scene/gui/file_dialog.cpp
#: scene/main/scene_tree.cpp scene/resources/navigation_mesh.cpp
@@ -803,8 +804,9 @@ msgid "Filters"
msgstr "Filtres"
#: core/project_settings.cpp scene/main/viewport.cpp
+#, fuzzy
msgid "Sharpen Intensity"
-msgstr ""
+msgstr "Intensitat d'agudització"
#: core/project_settings.cpp editor/editor_export.cpp editor/editor_node.cpp
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
@@ -829,9 +831,8 @@ msgid "Profiler"
msgstr "Perfilador"
#: core/project_settings.cpp
-#, fuzzy
msgid "Max Functions"
-msgstr "Reanomena Funció"
+msgstr "Funcions màximes"
#: core/project_settings.cpp scene/3d/vehicle_body.cpp
msgid "Compression"
@@ -843,39 +844,39 @@ msgstr "Formats"
#: core/project_settings.cpp
msgid "Zstd"
-msgstr ""
+msgstr "Zstd"
#: core/project_settings.cpp
msgid "Long Distance Matching"
-msgstr ""
+msgstr "Coincidència de llarga distància"
#: core/project_settings.cpp
msgid "Compression Level"
-msgstr ""
+msgstr "Nivell de compressió"
#: core/project_settings.cpp
msgid "Window Log Size"
-msgstr ""
+msgstr "Mida del registre de la finestra"
#: core/project_settings.cpp
msgid "Zlib"
-msgstr ""
+msgstr "Zlib"
#: core/project_settings.cpp
msgid "Gzip"
-msgstr ""
+msgstr "Gzip"
#: core/project_settings.cpp platform/android/export/export.cpp
msgid "Android"
-msgstr ""
+msgstr "Android"
#: core/project_settings.cpp
msgid "Modules"
-msgstr ""
+msgstr "Mòduls"
#: core/register_core_types.cpp
msgid "TCP"
-msgstr ""
+msgstr "TCP"
#: core/register_core_types.cpp
msgid "Connect Timeout Seconds"
@@ -887,11 +888,11 @@ msgstr ""
#: core/register_core_types.cpp
msgid "Max Buffer (Power of 2)"
-msgstr ""
+msgstr "Memòria intermèdia màxima (potència de 2)"
#: core/register_core_types.cpp editor/editor_settings.cpp main/main.cpp
msgid "SSL"
-msgstr ""
+msgstr "SSL"
#: core/register_core_types.cpp main/main.cpp
msgid "Certificates"
@@ -904,9 +905,8 @@ msgid "Resource"
msgstr "Recurs"
#: core/resource.cpp
-#, fuzzy
msgid "Local To Scene"
-msgstr "Tanca l'Escena"
+msgstr "Local a l'escena"
#: core/resource.cpp editor/dependency_editor.cpp
#: editor/editor_autoload_settings.cpp editor/plugins/path_editor_plugin.cpp
@@ -975,7 +975,7 @@ msgstr ""
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
msgid "Canvas Polygon Index Buffer Size (KB)"
-msgstr ""
+msgstr "Mida de la memòria intermèdia de l'índex del polígon de llenç (KB)"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp
@@ -987,7 +987,7 @@ msgstr ""
#: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp
#: servers/visual_server.cpp
msgid "2D"
-msgstr ""
+msgstr "2D"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
@@ -997,14 +997,13 @@ msgstr "Ajustament Intel·ligent"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
-#, fuzzy
msgid "Use GPU Pixel Snap"
-msgstr "Utilitzar ajustament amb els Píxels"
+msgstr "Utilitza l'ajust de píxels de la GPU"
#: drivers/gles2/rasterizer_scene_gles2.cpp
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Immediate Buffer Size (KB)"
-msgstr ""
+msgstr "Mida de la memòria intermèdia immediata (KB)"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1015,28 +1014,27 @@ msgstr "Precalcular Lightmaps"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
msgid "Use Bicubic Sampling"
-msgstr ""
+msgstr "Utilitza el mostreig bicúbic"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Renderable Elements"
-msgstr ""
+msgstr "Elements renderitzables màxims"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Renderable Lights"
-msgstr ""
+msgstr "Llums màximes renderitzables"
#: drivers/gles3/rasterizer_scene_gles3.cpp
-#, fuzzy
msgid "Max Renderable Reflections"
-msgstr "Centra la Selecció"
+msgstr "Reflexions màximes renderitzables"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Lights Per Object"
-msgstr ""
+msgstr "Llums màximes per objecte"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Subsurface Scattering"
-msgstr ""
+msgstr "Dispersió subsuperficial"
#: drivers/gles3/rasterizer_scene_gles3.cpp editor/animation_track_editor.cpp
#: editor/import/resource_importer_texture.cpp
@@ -1052,9 +1050,8 @@ msgid "Scale"
msgstr "Escala"
#: drivers/gles3/rasterizer_scene_gles3.cpp
-#, fuzzy
msgid "Follow Surface"
-msgstr "Omple la Superfície"
+msgstr "Segueix la superfície"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Weight Samples"
@@ -1062,11 +1059,11 @@ msgstr ""
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Voxel Cone Tracing"
-msgstr ""
+msgstr "Traçat del con Voxel"
#: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp
msgid "High Quality"
-msgstr ""
+msgstr "Alta qualitat"
#: drivers/gles3/rasterizer_storage_gles3.cpp
msgid "Blend Shape Max Buffer Size (KB)"
@@ -1144,9 +1141,8 @@ msgstr "Canviar crida d'animació"
#: editor/animation_track_editor.cpp scene/2d/animated_sprite.cpp
#: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Frame"
-msgstr "% del Fotograma"
+msgstr "Fotograma"
#: editor/animation_track_editor.cpp editor/editor_profiler.cpp
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
@@ -1157,9 +1153,8 @@ msgstr "Temps"
#: editor/animation_track_editor.cpp editor/import/resource_importer_scene.cpp
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Location"
-msgstr "Localització"
+msgstr "Ubicació"
#: editor/animation_track_editor.cpp modules/gltf/gltf_node.cpp
#: scene/2d/polygon_2d.cpp scene/2d/remote_transform_2d.cpp
@@ -1179,7 +1174,7 @@ msgstr "Quantitat d'arguments"
#: editor/animation_track_editor.cpp main/main.cpp
#: modules/mono/mono_gd/gd_mono.cpp
msgid "Args"
-msgstr ""
+msgstr "Args"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp
@@ -1343,9 +1338,8 @@ msgid "Position:"
msgstr "Posició:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rotation:"
-msgstr "Pas de la Rotació:"
+msgstr "Rotació:"
#: editor/animation_track_editor.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -1368,7 +1362,7 @@ msgstr "(No vàlid, tipus esperat: %s)"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Easing:"
-msgstr "Esmorteeix Entrada-Sortida"
+msgstr "Alleugeriment:"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -1386,19 +1380,16 @@ msgid "Stream:"
msgstr "Element de ràdio"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Start (s):"
-msgstr "Reinici (s):"
+msgstr "Inici (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "End (s):"
-msgstr "Fosa d'entrada (s):"
+msgstr "Final (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Clip:"
-msgstr "Animacions:"
+msgstr "Clip d'animació:"
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
@@ -1487,9 +1478,8 @@ msgid "Editors"
msgstr "Editors"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Confirm Insert Track"
-msgstr "Insereix una Pista i una Clau"
+msgstr "Confirmeu la inserció de pista"
#. TRANSLATORS: %s will be replaced by a phrase describing the target of track.
#: editor/animation_track_editor.cpp
@@ -1768,9 +1758,8 @@ msgid "Go to Previous Step"
msgstr "Anar al Pas Anterior"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Apply Reset"
-msgstr "Resetejar"
+msgstr "Aplica reinicialització"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
@@ -2231,7 +2220,7 @@ msgstr "Obre"
#: editor/dependency_editor.cpp
msgid "Owners of: %s (Total: %d)"
-msgstr ""
+msgstr "Propietaris de: %s (Total: %d)"
#: editor/dependency_editor.cpp
msgid ""
@@ -2425,10 +2414,10 @@ msgid "Licenses"
msgstr "Llicències"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Error opening asset file for \"%s\" (not in ZIP format)."
msgstr ""
-"S'ha produit un error en obrir el fitxer comprimit, no té el format ZIP."
+"S'ha produït un error en obrir el fitxer de recursos per a \"%s\" (no en "
+"format ZIP)."
#: editor/editor_asset_installer.cpp
msgid "%s (already exists)"
@@ -2451,9 +2440,8 @@ msgid "Uncompressing Assets"
msgstr "Descomprimint Recursos"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "The following files failed extraction from asset \"%s\":"
-msgstr "Ha fracassat l'extracció del paquet dels següents fitxers:"
+msgstr "Els fitxers següents no s'han pogut extraure del recurs \"%s\":"
#: editor/editor_asset_installer.cpp
msgid "(and %s more files)"
@@ -2473,9 +2461,8 @@ msgid "Install"
msgstr "Instal·la"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Asset Installer"
-msgstr "Instal·lador de paquets"
+msgstr "Instal·lador de recursos"
#: editor/editor_audio_buses.cpp
msgid "Speakers"
@@ -2645,9 +2632,8 @@ msgid "Create a new Bus Layout."
msgstr "Crea un nou Disseny de Bus."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Audio Bus Layout"
-msgstr "Obre un Disseny de Bus d'Àudio"
+msgstr "Disseny del bus d'àudio"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -2813,7 +2799,7 @@ msgstr "Completat amb èxit."
#: editor/editor_export.cpp
msgid "Failed."
-msgstr "Fallit:"
+msgstr "Ha fallat:"
#: editor/editor_export.cpp
msgid "Storing File:"
@@ -5616,6 +5602,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Elimina la Selecció del GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8100,11 +8091,20 @@ msgid "New Anim"
msgstr "Nova Animació"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Crea una Nova Animació"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Modifica el Nom de l'Animació:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Reanomena l'Animació"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Eliminar l'Animació?"
@@ -8122,11 +8122,6 @@ msgid "Animation name already exists!"
msgstr "El nom d'animació ja existeix!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Reanomena l'Animació"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplica l'Animació"
@@ -8271,10 +8266,6 @@ msgid "Pin AnimationPlayer"
msgstr "Fixar AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Crea una Nova Animació"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nom de l'Animació:"
@@ -19209,6 +19200,11 @@ msgid "The package must have at least one '.' separator."
msgstr "El paquet ha de tenir com a mínim un separador '. '."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Talla els Nodes"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -19217,6 +19213,16 @@ msgstr ""
msgid "Export Format"
msgstr "Camí d'exportació"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Mida del Contorn:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Objectiu"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -19259,16 +19265,6 @@ msgstr "Inspecciona la Instància anterior"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Mida del Contorn:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Objectiu"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19523,12 +19519,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19537,17 +19533,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -21234,7 +21250,7 @@ msgstr "Apropa"
msgid "Custom Viewport"
msgstr "1 Vista"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21992,11 +22008,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Editar Connexió:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Vinculació"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Trieu la distància:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Trieu la distància:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Avançat"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Activar"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -22014,16 +22062,6 @@ msgstr "Volteja Horitzontalment"
msgid "Max Speed"
msgstr "Velocitat (FPS):"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Trieu la distància:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Activar"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -22069,7 +22107,7 @@ msgstr "Viatge"
msgid "Rotation Degrees"
msgstr "Rotació de %s graus."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Constant"
@@ -23278,6 +23316,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "S'ha interromput la Transformació ."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -24176,6 +24221,11 @@ msgstr ""
"Modifica la mida de les Formes de Col. lisió Filles."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Manté la Transformació Global"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25432,6 +25482,11 @@ msgstr "Directori:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Selecció Només"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Activar"
@@ -25839,20 +25894,17 @@ msgstr "Camí d'exportació"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
-"La Vista (Viewport) no és la Destinació de Renderització (render target). "
-"Per mostrar-ne el contingut, especifiqueu-la com a filla d'un Control de "
-"forma per tal d'obtenir-ne la mida. Altrament, establiu-la com a Destinació "
-"de Renderització i assigneu-ne la textura interna a algun node."
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -27625,6 +27677,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Generant AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "òfset:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 9c3aea1d27..a166951396 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -452,6 +452,11 @@ msgstr ""
msgid "Command"
msgstr "Komunita"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fyzická Klávesa"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -511,6 +516,10 @@ msgid "Pressure"
msgstr "Profil"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Přichytávat relativně"
@@ -5667,6 +5676,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "GridMap Vyplnit výběr"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8136,11 +8150,20 @@ msgid "New Anim"
msgstr "Nová animace"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Vytvořit novou animaci"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Změnit název animace:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Přejmenovat animaci"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Smazat animaci?"
@@ -8158,11 +8181,6 @@ msgid "Animation name already exists!"
msgstr "Jméno animace už existuje!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Přejmenovat animaci"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplikovat animaci"
@@ -8306,10 +8324,6 @@ msgid "Pin AnimationPlayer"
msgstr "Připnout AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Vytvořit novou animaci"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Jméno animace:"
@@ -18952,6 +18966,11 @@ msgid "The package must have at least one '.' separator."
msgstr "BalíÄek musí mít alespoň jeden '.' oddÄ›lovaÄ."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Vyjmout uzly"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18960,6 +18979,16 @@ msgstr ""
msgid "Export Format"
msgstr "Exportovat cestu"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Velikost obrysu:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Cíl"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -19002,16 +19031,6 @@ msgstr "Zkontrolovat předchozí instanci"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Velikost obrysu:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Cíl"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19261,7 +19280,7 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" je platné pouze v případě, že \"Režim Xr\" má hodnotu "
@@ -19269,7 +19288,7 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" je platné pouze v případě, že \"Režim Xr\" má hodnotu "
"\"Oculus Mobile VR\"."
@@ -19283,22 +19302,42 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Export AAB\" je validní pouze v případě, že je povolena možnost \"Použít "
"vlastní sestavu\"."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Export AAB\" je validní pouze v případě, že je povolena možnost \"Použít "
"vlastní sestavu\"."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20968,7 +21007,7 @@ msgstr "Zvětšit"
msgid "Custom Viewport"
msgstr "1 výřez"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21727,11 +21766,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Upravit spojení:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Vazba"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Vybrat vzdálenost:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Vybrat vzdálenost:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "PokroÄilé"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Povolit"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21749,16 +21820,6 @@ msgstr "Převrátit horizontálně"
msgid "Max Speed"
msgstr "Rychlost:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Vybrat vzdálenost:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Povolit"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21803,7 +21864,7 @@ msgstr "Cestovat"
msgid "Rotation Degrees"
msgstr "Rotuji %s stupňů."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstantní"
@@ -23003,6 +23064,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformace zrušena."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23906,6 +23974,11 @@ msgstr ""
"Změňte velikost kolizních tvarů v uzlech potomků."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Zachovat globální transformaci"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25161,6 +25234,11 @@ msgstr "Složka:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Pouze výběr"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Povolit"
@@ -25566,18 +25644,6 @@ msgid "Viewport Path"
msgstr "Exportovat cestu"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Tento viewport není nastaven jako render target. Pokud chcete jeho obsah "
-"zobrazit přímo na obrazovku, musíte ho nastavit jako dítě uzlu Control, aby "
-"mohl získat velikost. Jinak ho nastavte jako render target a pÅ™iÅ™aÄte jeho "
-"vnitřní texturu nějakému uzlu k zobrazení."
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -25586,6 +25652,15 @@ msgstr ""
"Velikost pohledu musí být větší než 0, aby bylo možné cokoliv renderovat."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27355,6 +27430,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Generování AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Offset(Posun):"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/da.po b/editor/translations/da.po
index a90d207941..b4f7334278 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -423,6 +423,11 @@ msgstr ""
msgid "Command"
msgstr "Fællesskab"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fysik Frame %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -481,6 +486,10 @@ msgid "Pressure"
msgstr "Forudindstillet..."
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5720,6 +5729,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "GridMap Slet Markerede"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8233,11 +8247,20 @@ msgid "New Anim"
msgstr "Ny Animation"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Opret Ny Animation"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Ændre Animation Navn:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Omdøb animation"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Slet Animation?"
@@ -8257,11 +8280,6 @@ msgid "Animation name already exists!"
msgstr "FEJL: Animationsnavn eksisterer allerede!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Omdøb animation"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Lav en kopi af animation"
@@ -8409,10 +8427,6 @@ msgid "Pin AnimationPlayer"
msgstr "Fastgør AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Opret Ny Animation"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Animations Navn:"
@@ -19157,6 +19171,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Indsæt Node"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -19165,6 +19184,16 @@ msgstr ""
msgid "Export Format"
msgstr "Eksporter Projekt"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Skrifttype Størrelse:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Tidsskala Node"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -19203,16 +19232,6 @@ msgstr "Forrige fane"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Skrifttype Størrelse:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Tidsskala Node"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19458,12 +19477,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19472,17 +19491,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -21142,7 +21181,7 @@ msgstr "Zoom Ind"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21866,34 +21905,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Redigér Forbindelse:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Konstant"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Vælg en Main Scene"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Balanceret"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Aktivér"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Aktivér"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21937,7 +21998,7 @@ msgstr "Rejse"
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstant"
@@ -23078,6 +23139,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Opret Poly"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23954,6 +24022,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Anim Skift Transformering"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25158,6 +25231,11 @@ msgstr "Opret Mappe"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Kun Valgte"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Aktivér"
@@ -25553,20 +25631,17 @@ msgstr "Eksporter Projekt"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
-"Denne viewport er ikke angivet som render target. Hvis du har tænkt dig for "
-"at vise dens indhold direkte til skærmen, gør det til et barn af Control, så "
-"den kan opnå en størrelse. Ellers gør den til en RenderTarget og tildel dens "
-"indre textur til en node så den kan vises."
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -27298,6 +27373,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Fjern Template"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/de.po b/editor/translations/de.po
index 795dbd5328..64b8268adb 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -87,7 +87,7 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-03 02:51+0000\n"
+"PO-Revision-Date: 2022-07-09 21:11+0000\n"
"Last-Translator: So Wieso <sowieso@dukun.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
@@ -96,7 +96,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -387,9 +387,8 @@ msgid "Not enough bytes for decoding bytes, or invalid format."
msgstr "Nicht genügend Bytes zur Dekodierung oder ungültiges Format."
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid input %d (not passed) in expression"
-msgstr "Ungültige Eingabe %i (nicht übergeben) im Ausdruck"
+msgstr "Ungültige Eingabe %d (nicht übergeben) im Ausdruck"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
@@ -434,14 +433,12 @@ msgid "Max Size (KB)"
msgstr "Maximalgröße (KB)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "Bewegungsmodus"
+msgstr "Mausmodus"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "Eingang löschen"
+msgstr "Kumulierte Eingabe verwenden"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -468,6 +465,10 @@ msgstr "Meta"
msgid "Command"
msgstr "Befehl"
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr "Physisch"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -519,6 +520,11 @@ msgid "Pressure"
msgstr "Druck"
#: core/os/input_event.cpp
+#, fuzzy
+msgid "Pen Inverted"
+msgstr "Umkehren"
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relativ"
@@ -718,14 +724,12 @@ msgid "Script Templates Search Path"
msgstr "Suchpfad für Skriptvorlagen"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Autoload On Startup"
-msgstr "Autoladen beim Start"
+msgstr "Automatisches Laden der Versionskontrolle beim Start"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Plugin Name"
-msgstr "Versionsverwaltung"
+msgstr "Name des Plugins zur Versionskontrolle"
#: core/project_settings.cpp scene/2d/collision_object_2d.cpp
#: scene/3d/collision_object.cpp scene/gui/control.cpp
@@ -1358,19 +1362,16 @@ msgid "Remove this track."
msgstr "Diese Spur entfernen."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Time (s):"
-msgstr "Zeit (s): "
+msgstr "Zeit (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Position:"
-msgstr "Position"
+msgstr "Position:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rotation:"
-msgstr "Rotation"
+msgstr "Rotation:"
#: editor/animation_track_editor.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -1387,44 +1388,36 @@ msgid "Type:"
msgstr "Typ:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "(Invalid, expected type: %s)"
-msgstr "Ungültige Exportvorlage:"
+msgstr "(Ungültig, erwarteter Typ: %s)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Easing:"
-msgstr "Glätten Ein-Aus"
+msgstr "Glätten:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "In-Handle:"
-msgstr "Eingehender Handle"
+msgstr "Eingehender Handle:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Out-Handle:"
-msgstr "Ausgehender Handle"
+msgstr "Ausgehender Handle:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Stream:"
-msgstr "Stream"
+msgstr "Stream:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Start (s):"
-msgstr "Neu starten (s):"
+msgstr "Start (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "End (s):"
-msgstr "Einblenden (s):"
+msgstr "Ende (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Clip:"
-msgstr "Animationen:"
+msgstr "Animations-Clip:"
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
@@ -1639,9 +1632,8 @@ msgid "Add Method Track Key"
msgstr "Methodenaufrufsspurschlüssel hinzufügen"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Method not found in object:"
-msgstr "Methode nicht im Objekt gefunden: "
+msgstr "Methode nicht in Objekt gefunden:"
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
@@ -2254,7 +2246,7 @@ msgstr "Öffnen"
#: editor/dependency_editor.cpp
msgid "Owners of: %s (Total: %d)"
-msgstr ""
+msgstr "Besitzer von: %s (Insgesamt: %d)"
#: editor/dependency_editor.cpp
msgid ""
@@ -2615,9 +2607,8 @@ msgid "There is no '%s' file."
msgstr "Datei ‚%s‘ existiert nicht."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Layout:"
-msgstr "Layout"
+msgstr "Layout:"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
@@ -2820,22 +2811,19 @@ msgstr "Wählen"
#: editor/editor_export.cpp
msgid "Project export for platform:"
-msgstr ""
+msgstr "Projektexport für Plattform:"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed with errors."
-msgstr "Dateipfade vervollständigen"
+msgstr "Fertiggestellt mit Fehlern."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed successfully."
-msgstr "Paket wurde erfolgreich installiert!"
+msgstr "Erfolgreich fertiggestellt."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed."
-msgstr "Fehlgeschlagen:"
+msgstr "Fehlgeschlagen."
#: editor/editor_export.cpp
msgid "Storing File:"
@@ -2850,29 +2838,24 @@ msgid "Packing"
msgstr "Packe"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save PCK"
-msgstr "Speichern unter"
+msgstr "PCK speichern"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Cannot create file \"%s\"."
-msgstr "Ordner konnte nicht erstellt werden."
+msgstr "Datei „%s“ konnte nicht erstellt werden."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to export project files."
-msgstr "Projektdateien konnten nicht exportiert werden"
+msgstr "Projektdateien konnten nicht exportiert werden."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Can't open file to read from path \"%s\"."
-msgstr "Datei kann nicht zum Schreiben geöffnet werden:"
+msgstr "Datei im Pfad „%s“kann nicht zum Lesen geöffnet werden."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save ZIP"
-msgstr "Speichern unter"
+msgstr "ZIP speichern"
#: editor/editor_export.cpp
msgid ""
@@ -2993,30 +2976,25 @@ msgid "Custom release template not found."
msgstr "Selbst konfigurierte Release-Exportvorlage nicht gefunden."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Prepare Template"
-msgstr "Vorlagen verwalten"
+msgstr "Vorlage vorbereiten"
#: editor/editor_export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "The given export path doesn't exist."
-msgstr "Der angegebene Export-Pfad existiert nicht:"
+msgstr "Der angegebene Export-Pfad existiert nicht."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
-#, fuzzy
msgid "Template file not found: \"%s\"."
-msgstr "Vorlagendatei nicht gefunden:"
+msgstr "Vorlagendatei nicht gefunden: „%s“."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to copy export template."
-msgstr "Ungültige Exportvorlage:"
+msgstr "Fehler beim Kopieren der Exportvorlage."
#: editor/editor_export.cpp platform/windows/export/export.cpp
#: platform/x11/export/export.cpp
-#, fuzzy
msgid "PCK Embedding"
-msgstr "Versatz"
+msgstr "PCK-Einbettung"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
@@ -5206,9 +5184,8 @@ msgid "Size:"
msgstr "Größe:"
#: editor/editor_properties_array_dict.cpp
-#, fuzzy
msgid "Page:"
-msgstr "Seite: "
+msgstr "Seite:"
#: editor/editor_properties_array_dict.cpp
#: editor/plugins/theme_editor_plugin.cpp
@@ -5304,9 +5281,8 @@ msgstr ""
"Im Exportmenü kann eine Vorlage als ausführbar erstellt oder markiert werden."
#: editor/editor_run_native.cpp
-#, fuzzy
msgid "Project Run"
-msgstr "Projekt"
+msgstr "Projektdurchlauf"
#: editor/editor_run_script.cpp
msgid "Write your logic in the _run() method."
@@ -5588,6 +5564,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr "Extramaustasten blättern durch Verlauf"
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr "Auswahl ziehen und fallen lassen"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "Aussehen"
@@ -7210,9 +7190,8 @@ msgid "Generating Lightmaps"
msgstr "Generiere Lightmaps"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Generating for Mesh:"
-msgstr "Generierung für Mesh: "
+msgstr "Generierung für Mesh:"
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
@@ -7245,12 +7224,17 @@ msgid ""
"%s: Texture detected as used as a normal map in 3D. Enabling red-green "
"texture compression to reduce memory usage (blue channel is discarded)."
msgstr ""
+"%s: Verwendung der Textur als Normalen-Map in 3D festgestellt. Rot-Grün-"
+"Texturkompression wurde aktiviert um Speicherverbrauch zu reduzieren (der "
+"blaue Kanal wird verworfen)."
#: editor/import/resource_importer_texture.cpp
msgid ""
"%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap "
"generation and VRAM texture compression."
msgstr ""
+"%s: Verwendung der Textur in 3D festgestellt. Filter, Wiederholung, Mipmap-"
+"Erzeugung und VRAM-Texturkompression wurden aktiviert."
#: editor/import/resource_importer_texture.cpp
msgid "2D, Detect 3D"
@@ -7931,11 +7915,20 @@ msgid "New Anim"
msgstr "Neue Animation"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Neue Animation erstellen"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Animationsname ändern:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Animation umbenennen"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Animation löschen?"
@@ -7953,11 +7946,6 @@ msgid "Animation name already exists!"
msgstr "Animationsname existiert bereits!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Animation umbenennen"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Animation duplizieren"
@@ -8100,10 +8088,6 @@ msgid "Pin AnimationPlayer"
msgstr "Animationsspieler anheften"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Neue Animation erstellen"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Animationsname:"
@@ -8219,9 +8203,8 @@ msgid "Set the end animation. This is useful for sub-transitions."
msgstr "End-Animation festlegen. Hilfreich bei Sub-Transitionen."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition:"
-msgstr "Übergang: "
+msgstr "Übergang:"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Play Mode:"
@@ -9989,9 +9972,8 @@ msgid "Volume"
msgstr "Volumen"
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Emission Source:"
-msgstr "Emissionsquelle: "
+msgstr "Emissionsquelle:"
#: editor/plugins/particles_editor_plugin.cpp
msgid "A processor material of type 'ParticlesMaterial' is required."
@@ -11087,15 +11069,13 @@ msgstr "Verschiebung"
#. TRANSLATORS: Refers to changing the scale of a node in the 3D editor.
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Scaling:"
-msgstr "Skalierung: "
+msgstr "Skalierung:"
#. TRANSLATORS: Refers to changing the position of a node in the 3D editor.
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Translating:"
-msgstr "Verschiebe: "
+msgstr "Verschiebung:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotating %s degrees."
@@ -11609,9 +11589,8 @@ msgid "Invalid geometry, can't replace by mesh."
msgstr "Ungültige Geometrie, Mesh kann nicht ersetzt werden."
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to MeshInstance2D"
-msgstr "Zu Mesh2D umwandeln"
+msgstr "Zu MeshInstance2D umwandeln"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
@@ -11642,19 +11621,16 @@ msgid "Sprite"
msgstr "Bild"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Simplification:"
-msgstr "Vereinfachung: "
+msgstr "Vereinfachung:"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Shrink (Pixels):"
-msgstr "Schrumpfen (Pixel): "
+msgstr "Schrumpfen (Pixel):"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Grow (Pixels):"
-msgstr "Wachsen (Pixel): "
+msgstr "Wachsen (Pixel):"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Update Preview"
@@ -14250,9 +14226,8 @@ msgid "Export templates for this platform are missing:"
msgstr "Export-Templates für diese Systeme fehlen:"
#: editor/project_export.cpp
-#, fuzzy
msgid "Project Export"
-msgstr "Projektgründer"
+msgstr "Projektexport"
#: editor/project_export.cpp
msgid "Manage Export Templates"
@@ -15811,9 +15786,8 @@ msgid "Attach Node Script"
msgstr "Node-Skript hinzufügen"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Remote %s:"
-msgstr "Fern "
+msgstr "Fern %s:"
#: editor/script_editor_debugger.cpp
msgid "Bytes:"
@@ -16788,9 +16762,8 @@ msgid "Disabled GDNative Singleton"
msgstr "GDNative Singleton wurde deaktiviert"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Libraries:"
-msgstr "Bibliotheken: "
+msgstr "Bibliotheken:"
#: modules/gdnative/nativescript/nativescript.cpp
msgid "Class Name"
@@ -17211,17 +17184,15 @@ msgid "Mask"
msgstr "Maske"
#: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp
-#, fuzzy
msgid "Bake Navigation"
-msgstr "Navigation"
+msgstr "Navigation backen"
#: modules/gridmap/grid_map.cpp scene/2d/navigation_2d.cpp
#: scene/2d/navigation_agent_2d.cpp scene/2d/navigation_polygon.cpp
#: scene/2d/tile_map.cpp scene/3d/navigation.cpp scene/3d/navigation_agent.cpp
#: scene/3d/navigation_mesh_instance.cpp
-#, fuzzy
msgid "Navigation Layers"
-msgstr "Navigationsgefühl"
+msgstr "Navigationsschichten"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Next Plane"
@@ -17626,9 +17597,8 @@ msgstr ""
"sein! Bitte entsprechendes Node anpassen."
#: modules/visual_script/visual_script.cpp
-#, fuzzy
msgid "Node returned an invalid sequence output:"
-msgstr "Node gab ungültige Sequenzausgabe zurück: "
+msgstr "Node gab ungültige Sequenzausgabe zurück:"
#: modules/visual_script/visual_script.cpp
msgid "Found sequence bit but not the node in the stack, report bug!"
@@ -17637,9 +17607,8 @@ msgstr ""
"melden Sie den Bug!"
#: modules/visual_script/visual_script.cpp
-#, fuzzy
msgid "Stack overflow with stack depth:"
-msgstr "Stack-Overflow mit Stack-Tiefe: "
+msgstr "Stack-Overflow mit Stack-Tiefe:"
#: modules/visual_script/visual_script.cpp
msgid "Visual Script"
@@ -18008,18 +17977,16 @@ msgid "for (elem) in (input):"
msgstr "for (Element) in (Eingabe):"
#: modules/visual_script/visual_script_flow_control.cpp
-#, fuzzy
msgid "Input type not iterable:"
-msgstr "Eingabetyp nicht wiederholbar: "
+msgstr "Eingabetyp nicht iterierbar:"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Iterator became invalid"
msgstr "Iterator wurde ungültig"
#: modules/visual_script/visual_script_flow_control.cpp
-#, fuzzy
msgid "Iterator became invalid:"
-msgstr "Iterator wurde ungültig: "
+msgstr "Iterator wurde ungültig:"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Sequence"
@@ -18170,14 +18137,12 @@ msgid "Operator"
msgstr "Operator"
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "Invalid argument of type:"
-msgstr ": Ungültiger Parameter vom Typ: "
+msgstr "Ungültiges Argument vom Typ:"
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "Invalid arguments:"
-msgstr ": Ungültige Parameter: "
+msgstr "Ungültige Argumente:"
#: modules/visual_script/visual_script_nodes.cpp
msgid "a if cond, else b"
@@ -18188,14 +18153,12 @@ msgid "Var Name"
msgstr "Variablenname"
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "VariableGet not found in script:"
-msgstr "VariableGet nicht im Skript gefunden: "
+msgstr "VariableGet nicht im Skript gefunden:"
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "VariableSet not found in script:"
-msgstr "VariableSet nicht im Skript gefunden: "
+msgstr "VariableSet nicht im Skript gefunden:"
#: modules/visual_script/visual_script_nodes.cpp
msgid "Preload"
@@ -18489,6 +18452,10 @@ msgid "The package must have at least one '.' separator."
msgstr "Das Paket muss mindestens einen Punkt-Unterteiler ‚.‘ haben."
#: platform/android/export/export_plugin.cpp
+msgid "Custom Build"
+msgstr "Eigener Build"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr "Einen Build verwenden"
@@ -18496,6 +18463,14 @@ msgstr "Einen Build verwenden"
msgid "Export Format"
msgstr "Exportformat"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr "Min SDK"
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr "Ziel SDK"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr "Architekturen"
@@ -18532,14 +18507,6 @@ msgstr "Vorherige Installation löschen"
msgid "Code"
msgstr "Code"
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr "Min SDK"
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr "Ziel SDK"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr "Packet"
@@ -18779,16 +18746,16 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
-"„Hand Tracking“ ist nur gültig wenn „Xr Mode“ als „Occulus Mobile VrApi“ "
-"oder „OpenXR“ gesetzt wurde."
+"„Hand Tracking“ ist nur gültig wenn „XR Mode“ als „Oculus Mobile VrApi“ oder "
+"„OpenXR“ gesetzt wurde."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
-"„Passthrough“ ist nur gültig wenn „Xr Mode“ als „OpenXR“ gesetzt wurde."
+"„Passthrough“ ist nur gültig wenn „XR Mode“ als „OpenXR“ gesetzt wurde."
#: platform/android/export/export_plugin.cpp
msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
@@ -18796,39 +18763,64 @@ msgstr "„Export AAB“ ist nur gültig wenn „Use Custom Build“ aktiviert i
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
-"Das „Min Sdk“ zu ändern ist nur möglich wenn „Use Custom Build“ aktiviert "
+"Das „Min SDK“ zu überschreiben ist nur möglich wenn „Use Custom Build“ "
+"aktiviert ist."
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+"„Min SDK“ sollte eine gültige Ganzzahl sein, war aber „%s“, was ungültig ist."
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+"„Min SDK“ kann nicht niedriger als %d sein, der Version, die die Godot-"
+"Bibliothek benötigt."
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+"„Target SDK“ kann nur überschrieben werden wenn „Use Custom Build“ aktiviert "
"ist."
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
-"Das „Target Sdk“ zu ändern ist nur möglich wenn „Use Custom Build“ aktiviert "
+"„Taret SDK“ sollte eine gültige Ganzzahl sein, war aber „%s“, was ungültig "
"ist."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+"„Target SDK“ %d ist höher als die Standardversion %d. Diese Kombination "
+"könnte funktionieren, wurde aber nicht getestet und könnte gegebenenfalls "
+"instabil sein."
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
-"Die Version des „Target Sdk“ muss größer gleich der des „Min Sdk“ sein."
+"Die „Target SDK“-Version muss größer gleich der „Min SDK“-Version sein."
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Code Signing"
-msgstr "Codesignierendes DMG"
+msgstr "Code-Signieren"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"'apksigner' could not be found. Please check that the command is available "
"in the Android SDK build-tools directory. The resulting %s is unsigned."
msgstr ""
-"‚apksigner‘ konnte nicht gefunden werden.\n"
-"Ist das Programm im Android SDK build-tools-Verzeichnis vorhanden?\n"
-"Das resultierende %s ist nicht signiert."
+"‚apksigner‘ konnte nicht gefunden werden. Ist die Anwendung im Android-SDK "
+"build-tools-Verzeichnis vorhanden? Das resultierende %s ist nicht signiert."
#: platform/android/export/export_plugin.cpp
msgid "Signing debug %s..."
@@ -18843,9 +18835,8 @@ msgid "Could not find keystore, unable to export."
msgstr "Keystore konnte nicht gefunden werden, Export fehlgeschlagen."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not start apksigner executable."
-msgstr "Unterprozess konnte nicht gestartet werden!"
+msgstr "Apksigner-Anwendung konnte nicht gestartet werden."
#: platform/android/export/export_plugin.cpp
msgid "'apksigner' returned with error #%d"
@@ -18879,9 +18870,8 @@ msgstr ""
"Ungültiger Dateiname. Android APKs benötigen .apk als Dateinamenendung."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Unsupported export format!"
-msgstr "Nicht unterstütztes Exportformat!\n"
+msgstr "Nicht unterstütztes Exportformat!"
#: platform/android/export/export_plugin.cpp
msgid ""
@@ -18893,28 +18883,24 @@ msgstr ""
"Menü benötigt."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Android build version mismatch: Template installed: %s, Godot version: %s. "
"Please reinstall Android build template from 'Project' menu."
msgstr ""
-"Android-Build-Versionsinkompatibilität:\n"
-" Installierte Vorlage: %s\n"
-" Godot-Version: %s\n"
-"Bitte Android-Build-Vorlage im ‚Projekt‘-Menü neu installieren."
+"Android-Build-Versionsinkompatibilität: Installierte Vorlage: %s, Godot-"
+"Version: %s. Bitte Android-Build-Vorlage über das ‚Projekt‘-Menü neu "
+"installieren."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Unable to overwrite res://android/build/res/*.xml files with project name."
msgstr ""
-"Kann res://android/build/res/*.xml Dateien nicht mit Projektnamen "
-"überschreiben"
+"res://android/build/res/*.xml-Dateien können nicht mit Projektnamen "
+"überschrieben werden."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not export project files to gradle project."
-msgstr "Konnte Projektdateien nicht als Gradle-Projekt exportieren\n"
+msgstr "Projektdateien konnten nicht als Gradle-Projekt exportiert werden."
#: platform/android/export/export_plugin.cpp
msgid "Could not write expansion package file!"
@@ -18925,15 +18911,13 @@ msgid "Building Android Project (gradle)"
msgstr "Baue Android-Projekt (gradle)"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Building of Android project failed, check output for the error. "
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
"Bauen des Android-Projekts fehlgeschlagen, Fehlerdetails befinden ich in der "
-"Textausgabe.\n"
-"Alternativ befindet sich die Android-Build-Dokumentation auf docs."
-"godotengine.org."
+"Textausgabe. Alternativ befindet sich die Android-Build-Dokumentation auf "
+"docs.godotengine.org."
#: platform/android/export/export_plugin.cpp
msgid "Moving output"
@@ -18948,31 +18932,25 @@ msgstr ""
"im Gradle Projektverzeichnis erscheinen."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Package not found: \"%s\"."
-msgstr "Paket nicht gefunden: %s"
+msgstr "Paket nicht gefunden: „%s“."
#: platform/android/export/export_plugin.cpp
msgid "Creating APK..."
msgstr "Erzeuge APK…"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not find template APK to export: \"%s\"."
-msgstr ""
-"Konnte keine APK-Vorlage zum Exportieren finden:\n"
-"%s"
+msgstr "Keine APK-Vorlage zum Exportieren gefunden: „%s“."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Missing libraries in the export template for the selected architectures: %s. "
"Please build a template with all required libraries, or uncheck the missing "
"architectures in the export preset."
msgstr ""
"Fehlende Bibliotheken in Exportvorlage für die ausgewählten Architekturen: "
-"%s.\n"
-"Es muss entweder eine Exportvorlage mit den allen benötigten Bibliotheken "
+"%s. Es muss entweder eine Exportvorlage mit allen benötigten Bibliotheken "
"gebaut werden oder die angegebenen Architekturen müssen abgewählt werden."
#: platform/android/export/export_plugin.cpp
@@ -18980,9 +18958,8 @@ msgid "Adding files..."
msgstr "Füge Dateien hinzu…"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not export project files."
-msgstr "Projektdateien konnten nicht exportiert werden"
+msgstr "Projektdateien konnten nicht exportiert werden."
#: platform/android/export/export_plugin.cpp
msgid "Aligning APK..."
@@ -19207,14 +19184,12 @@ msgstr "Eigene Hintergrundfarbe"
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Prepare Templates"
-msgstr "Vorlagen verwalten"
+msgstr "Vorlagen vorbereiten"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Export template not found."
-msgstr "Selbst konfigurierte Release-Exportvorlage nicht gefunden."
+msgstr "Exportvorlage wurde nicht gefunden."
#: platform/iphone/export/export.cpp
msgid "App Store Team ID not specified - cannot configure the project."
@@ -19238,33 +19213,28 @@ msgid "Run exported HTML in the system's default browser."
msgstr "Führe exportiertes HTML im Standard-Browser des Betriebssystems aus."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not open template for export: \"%s\"."
-msgstr "Konnte Vorlage nicht zum Export öffnen:"
+msgstr "Vorlage zum Export konnte nicht geöffnet werden: „%s“."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Invalid export template: \"%s\"."
-msgstr "Ungültige Exportvorlage:"
+msgstr "Ungültige Exportvorlage: „%s“."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not write file: \"%s\"."
-msgstr "Konnte Datei nicht schreiben:"
+msgstr "Datei konnte nicht geschrieben werden: „%s“."
#: platform/javascript/export/export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Icon Creation"
-msgstr "Symbolbildbegrenzung"
+msgstr "Symbolbilderzeugung"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not read file: \"%s\"."
-msgstr "Konnte Datei nicht lesen:"
+msgstr "Datei konnte nicht gelesen werden: „%s“."
#: platform/javascript/export/export.cpp
msgid "PWA"
-msgstr ""
+msgstr "PWA"
#: platform/javascript/export/export.cpp
msgid "Variant"
@@ -19335,19 +19305,16 @@ msgid "Icon 512 X 512"
msgstr "Symbol 512 X 512"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not read HTML shell: \"%s\"."
-msgstr "Konnte HTML-Shell nicht lesen:"
+msgstr "HTML-Shell konnte nicht gelesen werden „%s“."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not create HTTP server directory: %s."
-msgstr "Konnte HTTP-Server-Verzeichnis nicht erstellen:"
+msgstr "HTTP-Server-Verzeichnis konnte nicht erstellt werden: %s."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Error starting HTTP server: %d."
-msgstr "Fehler beim Starten des HTTP-Servers:"
+msgstr "Fehler beim Starten des HTTP-Servers: %d."
#: platform/javascript/export/export.cpp
msgid "Web"
@@ -19611,32 +19578,28 @@ msgid "Apple Team ID"
msgstr "Apple-Team-ID"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not open icon file \"%s\"."
-msgstr "Projektdateien konnten nicht exportiert werden"
+msgstr "Symbolbilddatei „%s“ konnte nicht geöffnet werden."
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not start xcrun executable."
-msgstr "Unterprozess konnte nicht gestartet werden!"
+msgstr "Xcrun-Anwendung konnte nicht gestartet werden."
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Notarization failed."
-msgstr "Beglaubigung"
+msgstr "Beglaubigung fehlgeschlagen."
#: platform/osx/export/export.cpp
msgid "Notarization request UUID: \"%s\""
-msgstr ""
+msgstr "Beglaubigungsanfrage-UUID: „%s“"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid ""
"The notarization process generally takes less than an hour. When the process "
"is completed, you'll receive an email."
msgstr ""
-"Hinweis: Der Beglaubigungsprozess dauert gewöhnlich weniger als eine Stunde. "
-"Nach Ablauf wird eine Bestätigungsmail versandt."
+"Der Beglaubigungsprozess dauert gewöhnlich weniger als eine Stunde. Nach "
+"Ablauf wird eine Bestätigungsmail versandt."
#: platform/osx/export/export.cpp
msgid ""
@@ -19655,81 +19618,75 @@ msgstr ""
"Anwendung geheftet werden (optional):"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Timestamping is not compatible with ad-hoc signature, and was disabled!"
msgstr ""
-"Zeitstempel sind nicht mit Ad-hoc-Signaturen kompatibel, und werden "
+"Zeitstempel sind nicht mit Ad-hoc-Signaturen kompatibel, und wurden "
"deaktiviert!"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid ""
"Hardened Runtime is not compatible with ad-hoc signature, and was disabled!"
msgstr ""
"Die abgehärtete Laufzeitumgebung ist nicht mit Ad-hoc-Signaturen kompatibel, "
-"und wird deaktiviert!"
+"und wurde deaktiviert!"
#: platform/osx/export/export.cpp
msgid "Built-in CodeSign failed with error \"%s\"."
-msgstr ""
+msgstr "Eingebettetes CodeSign fehlgeschlagen mit Fehler „%s“."
#: platform/osx/export/export.cpp
msgid "Built-in CodeSign require regex module."
-msgstr ""
+msgstr "Eingebettetes CodeSign benötigt Regex-Modul."
#: platform/osx/export/export.cpp
msgid ""
"Could not start codesign executable, make sure Xcode command line tools are "
"installed."
msgstr ""
+"Codesign-Anwendung konnte nicht gestartet werden. Wurden die Xcode-"
+"Kommandozeilen-Hilfsprogramme installiert?"
#: platform/osx/export/export.cpp platform/windows/export/export.cpp
msgid "No identity found."
msgstr "Keine Identität gefunden."
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Cannot sign file %s."
-msgstr "Fehler beim Speichern von Datei: %s"
+msgstr "Datei %s konnte nicht signiert werden."
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Relative symlinks are not supported, exported \"%s\" might be broken!"
msgstr ""
-"Relative symbolische Links werden von diesem Betriebssystem nicht "
-"unterstützt, das exportierte Projekt könnte fehlerhaft sein!"
+"Relative symbolische Links werden nicht unterstützt, exportiertes „%s“ "
+"könnte fehlerhaft sein!"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "DMG Creation"
-msgstr "Richtung"
+msgstr "DMG-Erzeugung"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not start hdiutil executable."
-msgstr "Unterprozess konnte nicht gestartet werden!"
+msgstr "Hdiutil-Anwendung konnte nicht gestartet werden."
#: platform/osx/export/export.cpp
msgid "`hdiutil create` failed - file exists."
-msgstr ""
+msgstr "„hdiutil create“ ist fehlgeschlagen - Datei existiert bereits."
#: platform/osx/export/export.cpp
msgid "`hdiutil create` failed."
-msgstr ""
+msgstr "„hdiutil create“ ist fehlgeschlagen."
#: platform/osx/export/export.cpp
msgid "Creating app bundle"
msgstr "Erzeuge App-Bundle"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not find template app to export: \"%s\"."
-msgstr "Es konnte keine Vorlagen-App zum Exportieren gefunden werden:"
+msgstr "Es konnte keine Vorlagen-App zum Exportieren gefunden werden: „%s“."
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Invalid export format."
-msgstr "Ungültige Exportvorlage:"
+msgstr "Ungültiges Exportformat."
#: platform/osx/export/export.cpp
msgid ""
@@ -19740,12 +19697,11 @@ msgstr ""
"unterstützt, das exportierte Projekt könnte fehlerhaft sein!"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid ""
"Requested template binary \"%s\" not found. It might be missing from your "
"template archive."
msgstr ""
-"Benötigte Vorlagen-Binary ‚%s‘ nicht gefunden. Es könnte im Vorlagen-Archiv "
+"Benötigte Vorlagen-Binary „%s“ nicht gefunden. Es könnte im Vorlagen-Archiv "
"fehlen."
#: platform/osx/export/export.cpp
@@ -19789,14 +19745,12 @@ msgid "Sending archive for notarization"
msgstr "Sende Archiv zur Beglaubigung"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "ZIP Creation"
-msgstr "Projektion"
+msgstr "ZIP-Erstellung"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not open file to read from path \"%s\"."
-msgstr "Konnte Projektdateien nicht als Gradle-Projekt exportieren\n"
+msgstr "Datei im Pfad „%s“ konnte nicht zum Lesen geöffnet werden."
#: platform/osx/export/export.cpp
msgid "Invalid bundle identifier:"
@@ -20126,9 +20080,8 @@ msgid "Debug Algorithm"
msgstr "Debug-Algorithmus"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Failed to rename temporary file \"%s\"."
-msgstr "Temporäre Datei kann nicht entfernt werden:"
+msgstr "Temporäre Datei „%s“ konnte nicht umbenannt werden."
#: platform/windows/export/export.cpp
msgid "Identity Type"
@@ -20171,76 +20124,68 @@ msgid "Trademarks"
msgstr "Handelsmarken"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Resources Modification"
-msgstr "Pushnachrichten"
+msgstr "Ressourcen-Modifikationen"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Could not find rcedit executable at \"%s\"."
-msgstr "Keystore konnte nicht gefunden werden, Export fehlgeschlagen."
+msgstr "Anwendung rcedit konnte nicht gefunden werden in „%s“."
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Could not find wine executable at \"%s\"."
-msgstr "Keystore konnte nicht gefunden werden, Export fehlgeschlagen."
+msgstr "Anwendung wine konnte nicht gefunden werden in „%s“."
#: platform/windows/export/export.cpp
-#, fuzzy
msgid ""
"Could not start rcedit executable, configure rcedit path in the Editor "
"Settings (Export > Windows > Rcedit)."
msgstr ""
-"Das Rcedit-Werkzeug muss in den Editoreinstellungen (Export > Windows > "
-"Rcedit) festgelegt werden um Icon- oder Anwendungsinformation festlegen zu "
-"können."
+"Anwendung rcedit konnte nicht gestartet werden. Bitte rcedit-Pfad in "
+"Editoreinstellungen festlegen (Export > Windows > Rcedit)."
#: platform/windows/export/export.cpp
msgid ""
"rcedit failed to modify executable:\n"
"%s"
msgstr ""
+"Modifikation der Anwendung durch rcedit fehlgeschlagen:\n"
+"%s"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Could not find signtool executable at \"%s\"."
-msgstr "Keystore konnte nicht gefunden werden, Export fehlgeschlagen."
+msgstr "Anwendung signtool konnte nicht gefunden werden in: „%s“."
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Could not find osslsigncode executable at \"%s\"."
-msgstr "Keystore konnte nicht gefunden werden, Export fehlgeschlagen."
+msgstr "Anwendung osslsigncode konnte nicht gefunden werden in: „%s“."
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Invalid identity type."
-msgstr "Identitäts-Typ"
+msgstr "Ungültiger Identitäts-Typ."
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Invalid timestamp server."
-msgstr "Ungültiger Name."
+msgstr "Ungültiger Zeitstempelserver."
#: platform/windows/export/export.cpp
-#, fuzzy
msgid ""
"Could not start signtool executable, configure signtool path in the Editor "
"Settings (Export > Windows > Signtool)."
msgstr ""
-"Das Rcedit-Werkzeug muss in den Editoreinstellungen (Export > Windows > "
-"Rcedit) festgelegt werden um Icon- oder Anwendungsinformation festlegen zu "
-"können."
+"Anwendung signtool konnte nicht gestartet werden. Bitte signtool-Pfad in "
+"Editoreinstellungen festlegen (Export > Windows > Signtool)."
#: platform/windows/export/export.cpp
msgid ""
"Signtool failed to sign executable:\n"
"%s"
msgstr ""
+"Signieren der Anwendung durch Signtool ist fehlgeschlagen:\n"
+"%s"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Failed to remove temporary file \"%s\"."
-msgstr "Temporäre Datei kann nicht entfernt werden:"
+msgstr "Fehler beim entfernen temporärer Datei „%s“."
#: platform/windows/export/export.cpp
msgid ""
@@ -20265,20 +20210,19 @@ msgstr "Ungültige Produktversion:"
#: platform/windows/export/export.cpp
msgid "Windows executables cannot be >= 4 GiB."
-msgstr ""
+msgstr "Windows-Anwendungen können nicht größer als 4 GiB sein."
#: platform/windows/export/export.cpp platform/x11/export/export.cpp
-#, fuzzy
msgid "Failed to open executable file \"%s\"."
-msgstr "Ungültige ausführbare Datei."
+msgstr "Fehler beim Öffnen von ausführbarer Datei „%s“."
#: platform/windows/export/export.cpp platform/x11/export/export.cpp
msgid "Executable file header corrupted."
-msgstr ""
+msgstr "Header von ausführbarer Datei beschädigt."
#: platform/windows/export/export.cpp platform/x11/export/export.cpp
msgid "Executable \"pck\" section not found."
-msgstr ""
+msgstr "„pck“-Sektor von ausführbarer Datei nicht gefunden."
#: platform/windows/export/export.cpp
msgid "Windows"
@@ -20299,6 +20243,8 @@ msgstr "Wine"
#: platform/x11/export/export.cpp
msgid "32-bit executables cannot have embedded data >= 4 GiB."
msgstr ""
+"32-bit-Anwendungen können keine eingebetteten Daten größer als 4 GiB "
+"beinhalten."
#: scene/2d/animated_sprite.cpp scene/3d/sprite_3d.cpp
#: scene/resources/texture.cpp
@@ -20453,7 +20399,7 @@ msgstr "Vergrößerung"
msgid "Custom Viewport"
msgstr "Eigenes Ansichtsfenster"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -21141,11 +21087,41 @@ msgstr "Zellen Größe"
msgid "Edge Connection Margin"
msgstr "Kantenverbindungsbegrenzung"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+"‚Navigation2D‘ und ‚Navigation2D.get_simple_path()‘ sind veraltet und werden "
+"in einer zukünftigen Version entfernt. Als Ersatz ist ‚Navigation2DServer."
+"map_get_path()‘ zu verwenden."
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Pathfinding"
+msgstr "Pfadfinden"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Desired Distance"
+msgstr "Gewünschte Pfaddistanz"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr "Gewünschte Zieldistanz"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr "Max Pfad-Distanz"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Avoidance"
+msgstr "Vermeiden"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Avoidance Enabled"
+msgstr "Vermeiden aktiviert"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr "Nachbardistanz"
@@ -21161,14 +21137,6 @@ msgstr "Zeithorizont"
msgid "Max Speed"
msgstr "Max Geschw"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr "Max Pfad-Distanz"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Avoidance Enabled"
-msgstr "Vermeiden aktiviert"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21200,21 +21168,19 @@ msgid "Navpoly"
msgstr "Navpolygon"
#: scene/2d/navigation_polygon.cpp scene/3d/navigation_mesh_instance.cpp
-#, fuzzy
msgid "Enter Cost"
-msgstr "Mitte unten"
+msgstr "Eintrittskosten"
#: scene/2d/navigation_polygon.cpp scene/3d/navigation_mesh_instance.cpp
-#, fuzzy
msgid "Travel Cost"
-msgstr "Reisen"
+msgstr "Reisekosten"
#: scene/2d/node_2d.cpp scene/2d/polygon_2d.cpp scene/3d/spatial.cpp
#: scene/main/canvas_layer.cpp
msgid "Rotation Degrees"
msgstr "Rotationswinkel"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr "Globale Rotation"
@@ -22300,6 +22266,16 @@ msgstr "Software-Skinning"
msgid "Transform Normals"
msgstr "Normalen transformieren"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+"‚Navigation‘ und ‚Navigation.get_simple_path()‘ sind veraltet und werden in "
+"einer zukünftigen Version entfernt. Als Ersatz ist ‚NavigationServer."
+"map_get_path()‘ zu verwenden."
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr "Hoch-Vektor"
@@ -23133,6 +23109,11 @@ msgstr ""
"geändert werden."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Globales Transform"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr "Matrix"
@@ -24240,6 +24221,10 @@ msgid "Fold Gutter"
msgstr "Einklappenspalte"
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr "Ziehen-und-Fallenlassen-Auswahl aktiviert"
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr "Verstecken aktiviert"
@@ -24600,19 +24585,6 @@ msgstr "Ansichtsfensterpfad"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Dieser Viewport ist nicht als Render-Ziel eingestellt. Soll sein Inhalt "
-"direkt auf dem Bildschirm angezeigt werden, muss er als Unterobjekt eines "
-"Controls eingehängt werden um dessen Größe zu erben. Andernfalls sollte die "
-"Eigenschaft ‚Render Target‘ des Viewports aktiviert und seine Textur "
-"irgendeinem Node zum Anzeigen zugewiesen werden."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -24620,6 +24592,20 @@ msgstr ""
"betragen um überhaupt irgendetwas rendern zu können."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+"In diesem Ansichtsfenster ist HDR aktiv, jedoch wurde dessen Nutzung auf 2D "
+"oder 2D-No-Sampling eingestellt.\n"
+"HDR wird nur in Ansichtsfenstern deren Nutzung auf 3D oder 3D-No-Effects "
+"eingestellt sind unterstützt.\n"
+"HDR wird für dieses Ansichtsfenster deaktiviert."
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr "ARVR"
@@ -24756,14 +24742,12 @@ msgid "3D Physics"
msgstr "3D-Physik"
#: scene/register_scene_types.cpp
-#, fuzzy
msgid "2D Navigation"
-msgstr "Navigation"
+msgstr "2D-Navigation"
#: scene/register_scene_types.cpp
-#, fuzzy
msgid "3D Navigation"
-msgstr "Navigation"
+msgstr "3D-Navigation"
#: scene/register_scene_types.cpp
msgid "Use hiDPI"
@@ -26049,14 +26033,12 @@ msgid "Visible Instance Count"
msgstr "Sichtbare Instanzen Anzahl"
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Sampling"
-msgstr "Skalierung: "
+msgstr "Abtastung"
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Partition Type"
-msgstr "Probeneinteilunstyp"
+msgstr "Einteilungstyp"
#: scene/resources/navigation_mesh.cpp
msgid "Parsed Geometry Type"
@@ -26071,14 +26053,12 @@ msgid "Source Group Name"
msgstr "Quellen-Gruppenname"
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Cells"
-msgstr "Zelle"
+msgstr "Zellen"
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Agents"
-msgstr "Agent"
+msgstr "Agenten"
#: scene/resources/navigation_mesh.cpp
msgid "Max Climb"
@@ -26089,18 +26069,16 @@ msgid "Max Slope"
msgstr "Maximale Neigung"
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Regions"
-msgstr "Bereich"
+msgstr "Bereiche"
#: scene/resources/navigation_mesh.cpp
msgid "Merge Size"
msgstr "Größe der Zusammenführung"
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Edges"
-msgstr "Kante"
+msgstr "Kanten"
#: scene/resources/navigation_mesh.cpp
msgid "Max Error"
@@ -26111,7 +26089,6 @@ msgid "Verts Per Poly"
msgstr "Vert per Poly"
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Details"
msgstr "Details"
@@ -26132,9 +26109,16 @@ msgid "Ledge Spans"
msgstr "Vorsprünge"
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Walkable Low Height Spans"
-msgstr "Ablaufbare Abstände niedriger Höhe aussortiern"
+msgstr "Ablaufbare Abstände niedriger Höhe"
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr "Backe AABB"
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr "Backe AABB-Versatz"
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
@@ -26493,9 +26477,8 @@ msgid "Scenario"
msgstr "Szenario"
#: scene/resources/world.cpp scene/resources/world_2d.cpp
-#, fuzzy
msgid "Navigation Map"
-msgstr "Navigation"
+msgstr "Navigationskarte"
#: scene/resources/world.cpp scene/resources/world_2d.cpp
msgid "Direct Space State"
@@ -26514,24 +26497,20 @@ msgid "Default Angular Damp"
msgstr "Standard Winkeldämpfung"
#: scene/resources/world.cpp
-#, fuzzy
msgid "Default Map Up"
-msgstr "Standard Gleitkommaschritte"
+msgstr "Standard Kartenhoch"
#: scene/resources/world.cpp scene/resources/world_2d.cpp
-#, fuzzy
msgid "Default Cell Size"
-msgstr "Zellen Größe"
+msgstr "Standardzellgröße"
#: scene/resources/world.cpp scene/resources/world_2d.cpp
-#, fuzzy
msgid "Default Cell Height"
-msgstr "Zellenhöhe"
+msgstr "Standardzellhöhe"
#: scene/resources/world.cpp scene/resources/world_2d.cpp
-#, fuzzy
msgid "Default Edge Connection Margin"
-msgstr "Kantenverbindungsbegrenzung"
+msgstr "Standard Kantenverbinungsabstand"
#: scene/resources/world_2d.cpp
msgid "Canvas"
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 169d40ebd7..231863615b 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -380,6 +380,10 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr ""
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -431,6 +435,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5244,6 +5252,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7522,11 +7534,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7544,11 +7565,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7691,10 +7707,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17666,6 +17678,10 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+msgid "Custom Build"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17673,6 +17689,14 @@ msgstr ""
msgid "Export Format"
msgstr ""
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr ""
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17709,14 +17733,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr ""
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -17934,12 +17950,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -17948,17 +17964,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19460,7 +19496,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20114,32 +20150,51 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr ""
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Pathfinding"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Desired Distance"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Avoidance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Avoidance Enabled"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Avoidance Enabled"
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp
@@ -20180,7 +20235,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21204,6 +21259,13 @@ msgstr ""
msgid "Transform Normals"
msgstr ""
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -21988,6 +22050,10 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+msgid "Global Translation"
+msgstr ""
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23056,6 +23122,10 @@ msgid "Fold Gutter"
msgstr ""
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr ""
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr ""
@@ -23407,16 +23477,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -24926,6 +24997,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index a3f5e815e1..8511b4fdd2 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -411,6 +411,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (Φυσικό)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -464,6 +469,10 @@ msgid "Pressure"
msgstr "Πίεση"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Σχετικό"
@@ -5649,6 +5658,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "GridMap Γέμισμα Επιλογής"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8154,11 +8168,20 @@ msgid "New Anim"
msgstr "Îέα κίνηση"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "ΔημιουÏγία νέας κίνησης"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Αλλαγή ονόματος κίνησης:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Μετονομασία κίνησης"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "ΔιαγÏαφή κίνησης;"
@@ -8176,11 +8199,6 @@ msgid "Animation name already exists!"
msgstr "Ήδη υπαÏκτό όνομα κίνησης!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Μετονομασία κίνησης"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "ΑναπαÏαγωγή κίνησης"
@@ -8324,10 +8342,6 @@ msgid "Pin AnimationPlayer"
msgstr "ΚαÏφίτσωμα AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "ΔημιουÏγία νέας κίνησης"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Όνομα κίνησης:"
@@ -19116,6 +19130,11 @@ msgid "The package must have at least one '.' separator."
msgstr "Το πακέτο Ï€Ïέπει να έχει τουλάχιστον έναν '.' διαχωÏιστή."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Αποκοπή κόμβων"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -19124,6 +19143,16 @@ msgstr ""
msgid "Export Format"
msgstr "ΔιαδÏομή Εξαγωγής"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Μέγεθος πεÏιγÏάμματος:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Στόχος"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -19166,16 +19195,6 @@ msgstr "ΕπιθεώÏηση του Ï€ÏοηγοÏμενου στιγμιοτÏÏ
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Μέγεθος πεÏιγÏάμματος:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Στόχος"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19437,7 +19456,7 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"Το «Hand Tracking» είναι έγκυÏο μόνο όταν το «Xr Mode» είναι «Oculus Mobile "
@@ -19445,7 +19464,7 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"Το «Hand Tracking» είναι έγκυÏο μόνο όταν το «Xr Mode» είναι «Oculus Mobile "
"VR»."
@@ -19456,17 +19475,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -21143,7 +21182,7 @@ msgstr "Μεγέθυνση"
msgid "Custom Viewport"
msgstr "1 Οπτική γωνία"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21905,11 +21944,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "ΕπεξεÏγασία ΣÏνδεσης:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Δεσμός"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Επιλογή απόστασης:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Επιλογή απόστασης:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Για Ï€ÏοχωÏημένους"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "ΕνεÏγοποίηση"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21927,16 +21998,6 @@ msgstr "ΑναστÏοφή ΟÏιζόντια"
msgid "Max Speed"
msgstr "ΤαχÏτητα:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Επιλογή απόστασης:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "ΕνεÏγοποίηση"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21981,7 +22042,7 @@ msgstr "Ταξίδι"
msgid "Rotation Degrees"
msgstr "ΠεÏιστÏοφή %s μοίÏες."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "ΣταθεÏή"
@@ -23195,6 +23256,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Ο μετασχηματισμός ματαιώθηκε."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -24099,6 +24167,11 @@ msgstr ""
"Αλλάξτε μέγεθος στα σχήματα σÏγκÏουσης των παιδιών."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "ΔιατήÏηση παγκόσμιου μετασχηματισμοÏ"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25357,6 +25430,11 @@ msgstr "Φάκελος:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Μόνο στην επιλογή"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "ΕνεÏγοποίηση"
@@ -25762,18 +25840,6 @@ msgid "Viewport Path"
msgstr "ΔιαδÏομή Εξαγωγής"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Το Viewport δεν έχει οÏισθεί ως στόχος απόδοσης. Αν σκοπεÏετε να δείχνει τα "
-"πεÏιεχόμενα του, κάντε το να κληÏονομεί ένα Control, ώστε να αποκτήσει "
-"μέγεθος. Αλλιώς, κάντε το ένα RenderTarget και οÏίστε το internal texture σε "
-"έναν κόμβο για απεικόνιση."
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -25783,6 +25849,15 @@ msgstr ""
"απόδοση."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27551,6 +27626,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "ΔημιουÏία AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Μετατόπιση:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/en_Shaw.po b/editor/translations/en_Shaw.po
index 14388e1c66..d69ca8d97f 100644
--- a/editor/translations/en_Shaw.po
+++ b/editor/translations/en_Shaw.po
@@ -391,6 +391,11 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "ð‘‘ð‘ªð‘œð‘©ð‘¤ ð‘‘ð‘®ð‘¨ð‘’ ð‘¦ð‘¯ð‘±ð‘šð‘©ð‘¤ð‘›"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -442,6 +447,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5271,6 +5280,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7568,11 +7581,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7590,11 +7612,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7737,10 +7754,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17739,6 +17752,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "ð‘“ð‘³ð‘™ð‘’ð‘–ð‘©ð‘¯ð‘Ÿ:"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17747,6 +17765,14 @@ msgstr ""
msgid "Export Format"
msgstr "3-ð‘› ð‘‘ð‘®ð‘¨ð‘¯ð‘•ð‘“ð‘¹ð‘¥ ð‘‘ð‘®ð‘¨ð‘’"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr ""
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17783,14 +17809,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr ""
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18012,12 +18030,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18026,17 +18044,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19556,7 +19594,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20216,35 +20254,55 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "ð‘“ð‘³ð‘™ð‘’ð‘–ð‘©ð‘¯ð‘Ÿ:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Pathfinding"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Path Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "ð‘‘ð‘ªð‘œð‘©ð‘¤ ð‘‘ð‘®ð‘¨ð‘’ ð‘¦ð‘¯ð‘±ð‘šð‘©ð‘¤ð‘›"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
msgid "Avoidance Enabled"
msgstr "ð‘‘ð‘ªð‘œð‘©ð‘¤ ð‘‘ð‘®ð‘¨ð‘’ ð‘¦ð‘¯ð‘±ð‘šð‘©ð‘¤ð‘›"
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20283,7 +20341,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21328,6 +21386,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "3-ð‘› ð‘‘ð‘®ð‘¨ð‘¯ð‘•ð‘“ð‘¹ð‘¥ ð‘‘ð‘®ð‘¨ð‘’"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22157,6 +22222,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "ð‘“ð‘³ð‘™ð‘’ð‘–ð‘©ð‘¯ð‘Ÿ:"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23251,6 +23321,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "ð‘‘ð‘ªð‘œð‘©ð‘¤ ð‘‘ð‘®ð‘¨ð‘’ ð‘¦ð‘¯ð‘±ð‘šð‘©ð‘¤ð‘›"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "ð‘‘ð‘ªð‘œð‘©ð‘¤ ð‘‘ð‘®ð‘¨ð‘’ ð‘¦ð‘¯ð‘±ð‘šð‘©ð‘¤ð‘›"
@@ -23608,16 +23683,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25192,6 +25268,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index 46e8f898ce..3b651b3e97 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -431,6 +431,11 @@ msgstr ""
msgid "Command"
msgstr "Komunumo"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fiziko-kadro %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -488,6 +493,10 @@ msgid "Pressure"
msgstr "AntaÅ­agordo"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Kapti relative"
@@ -5642,6 +5651,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Enkadrigi elekton"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8126,11 +8140,21 @@ msgid "New Anim"
msgstr "Nova animacio"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Krei novan animacion"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "ÅœanÄi nomon de animacio:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+#, fuzzy
+msgid "Rename Animation"
+msgstr "Renomi animaĵon"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Forigi animacion?"
@@ -8148,12 +8172,6 @@ msgid "Animation name already exists!"
msgstr "Nomo de animacio jam ekzistas!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
-msgid "Rename Animation"
-msgstr "Renomi animaĵon"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplikati animacion"
@@ -8296,10 +8314,6 @@ msgid "Pin AnimationPlayer"
msgstr "Fiksi AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Krei novan animacion"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nomo de animacio:"
@@ -18811,6 +18825,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Eltondi nodo(j)n"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18819,6 +18838,16 @@ msgstr ""
msgid "Export Format"
msgstr "Formo"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Grando de konturo:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Celo"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18858,16 +18887,6 @@ msgstr "Inspekti antaÅ­an ekzemplon"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Grando de konturo:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Celo"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19113,12 +19132,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19127,17 +19146,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20786,7 +20825,7 @@ msgstr "Zomi"
msgid "Custom Viewport"
msgstr "Montri vidujon"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21504,34 +21543,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Redakti Konekton:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Alglui animacion"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Elektu ĉefan scenon"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Altnivela"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Åœaltita"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Åœaltita"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21575,7 +21636,7 @@ msgstr "VojaÄa"
msgid "Rotation Degrees"
msgstr "Rotacia paÅo:"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstanto"
@@ -22708,6 +22769,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformo"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23590,6 +23658,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Transformo"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24803,6 +24876,11 @@ msgstr "Dosierujo:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Nur Elektaro"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Åœaltita"
@@ -25205,16 +25283,17 @@ msgstr "Fokusi al dosierindiko"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26965,6 +27044,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Krada deÅovo:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/es.po b/editor/translations/es.po
index d419b78e4b..3c21955a46 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -79,13 +79,15 @@
# losfroger <emilioranita@gmail.com>, 2022.
# Ventura Pérez García <vetu@protonmail.com>, 2022.
# David Martínez <goddrinksjava@gmail.com>, 2022.
+# Nagamine-j <jimmy.kochi@unmsm.edu.pe>, 2022.
+# Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-19 11:52+0000\n"
-"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
+"PO-Revision-Date: 2022-06-29 10:04+0000\n"
+"Last-Translator: Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -387,9 +389,8 @@ msgstr ""
"inválido."
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid input %d (not passed) in expression"
-msgstr "Entrada inválida %i (no aprobada) en la expresión"
+msgstr "Entrada inválida %d (no aprobada) en la expresión"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
@@ -433,14 +434,12 @@ msgid "Max Size (KB)"
msgstr "Tamaño Máximo (KB)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "Modo de Movimiento"
+msgstr "Modo de Mouse"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "Eliminar entrada"
+msgstr "Usar entrada acumulada"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -467,6 +466,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (Física)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -487,7 +491,7 @@ msgstr "Unicode"
#: core/os/input_event.cpp
msgid "Echo"
-msgstr "Echo"
+msgstr "Eco"
#: core/os/input_event.cpp scene/gui/base_button.cpp
msgid "Button Mask"
@@ -511,13 +515,17 @@ msgstr "Dobleclick"
#: core/os/input_event.cpp
msgid "Tilt"
-msgstr "Tilt"
+msgstr "Inclinar"
#: core/os/input_event.cpp
msgid "Pressure"
msgstr "Presionado"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relativo"
@@ -590,11 +598,11 @@ msgstr "Valor del Controlador"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
#: platform/windows/export/export.cpp
msgid "Application"
-msgstr "Aplicación"
+msgstr "Aplicação"
#: core/project_settings.cpp main/main.cpp
msgid "Config"
-msgstr "Configurar"
+msgstr "Configuração"
#: core/project_settings.cpp
msgid "Project Settings Override"
@@ -2749,7 +2757,7 @@ msgstr "Nombre del Nodo:"
#: editor/editor_autoload_settings.cpp
msgid "Global Variable"
-msgstr "Variable"
+msgstr "Variable global"
#: editor/editor_data.cpp
msgid "Paste Params"
@@ -2810,16 +2818,15 @@ msgstr "Elegir"
#: editor/editor_export.cpp
msgid "Project export for platform:"
-msgstr ""
+msgstr "Exportar proyecto para la plataforma:"
#: editor/editor_export.cpp
msgid "Completed with errors."
msgstr "Completado con errores."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed successfully."
-msgstr "Completado con éxito."
+msgstr "Completado exitosamente."
#: editor/editor_export.cpp
msgid "Failed."
@@ -2839,14 +2846,12 @@ msgid "Packing"
msgstr "Empaquetando"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save PCK"
-msgstr "Guardar Como"
+msgstr "Guardar como PCK"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Cannot create file \"%s\"."
-msgstr "No se pudo crear la carpeta."
+msgstr "No se pudo crear el archivo \"%s\"."
#: editor/editor_export.cpp
msgid "Failed to export project files."
@@ -2857,9 +2862,8 @@ msgid "Can't open file to read from path \"%s\"."
msgstr "No se puede abrir el archivo a leer de la ruta \"%s\"."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save ZIP"
-msgstr "Guardar Como"
+msgstr "Guardar como ZIP"
#: editor/editor_export.cpp
msgid ""
@@ -5566,6 +5570,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr "Botones Extra del Ratón Navegar por el Historial"
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Seleccionar GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "Apariencia"
@@ -7968,11 +7977,20 @@ msgid "New Anim"
msgstr "Nueva Animación"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Crear Animación Nueva"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Cambiar nombre de animación:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Renombrar Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "¿Eliminar Animación?"
@@ -7990,11 +8008,6 @@ msgid "Animation name already exists!"
msgstr "¡El nombre de animación ya existe!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Renombrar Animación"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplicar Animación"
@@ -8140,10 +8153,6 @@ msgid "Pin AnimationPlayer"
msgstr "Fijar AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Crear Animación Nueva"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nombre de Animación:"
@@ -18702,6 +18711,11 @@ msgid "The package must have at least one '.' separator."
msgstr "El paquete debe tener al menos un '.' como separador."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "CustomNode"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18710,6 +18724,15 @@ msgstr ""
msgid "Export Format"
msgstr "Ruta de Exportación"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr "SDK Mínimo"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Objetivo de FPS"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18753,15 +18776,6 @@ msgstr "Inspeccionar Instancia Anterior"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr "SDK Mínimo"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Objetivo de FPS"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19018,15 +19032,17 @@ msgid "\"Use Custom Build\" must be enabled to use the plugins."
msgstr "\"Use Custom Build\" debe estar activado para usar los plugins."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" solo es válido cuando \"Xr Mode\" es \"Oculus Mobile "
"VrApi\" u \"OpenXR\"."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr "\"Passthrough\" solo es válido cuando \"Xr Mode\" es \"OpenXR\"."
#: platform/android/export/export_plugin.cpp
@@ -19035,22 +19051,45 @@ msgstr ""
"\"Export AAB\" sólo es válido cuando \"Use Custom Build\" está activado."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Cambiar el \"Min Sdk\" solo es válido cuando \"Use Custom Build\" está "
"activado."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Cambiar el \"Target Sdk\" solo es válido cuando \"Use Custom Build\" está "
"activado."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"La versión de \"Target Sdk\" debe ser mayor o igual que la versión de \"Min "
"Sdk\"."
@@ -20760,7 +20799,7 @@ msgstr "Acercar Zoom"
msgid "Custom Viewport"
msgstr "1 Viewport"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21517,11 +21556,42 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Margen de Conexión de Bordes"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Vinculación"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Distancia de la Ruta U"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr "Distancia Máxima de Ruta"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Avanzado"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Activar"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21538,15 +21608,6 @@ msgstr "Voltear Horizontalmente"
msgid "Max Speed"
msgstr "Velocidad Máxima"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr "Distancia Máxima de Ruta"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Activar"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21593,7 +21654,7 @@ msgstr "Viaje"
msgid "Rotation Degrees"
msgstr "Grados de Rotación"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Constante Global"
@@ -22787,6 +22848,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformar Normales"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23706,6 +23774,11 @@ msgstr ""
"En su lugar, cambia el tamaño en las formas de colisión de los hijos."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Mantener transformación global"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24927,6 +25000,11 @@ msgstr "Plegar Gutter"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Sólo selección"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Activar"
@@ -25328,19 +25406,6 @@ msgstr "Ruta de Exportación"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Esta ventanilla no está configurada como destino de representación. Si "
-"quiere que su contenido se muestre directamente en la pantalla, hágalo un "
-"elemento secundario de un control para que pueda recibir dimensiones. O "
-"bien, conviértalo en un RenderTarget y asigne su textura interna a algún "
-"nodo para que se muestre."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25348,6 +25413,15 @@ msgstr ""
"dimensiones para renderizar cualquier cosa."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27073,6 +27147,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Generando AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Desplazamiento Base"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index c79bf0828f..de1187f08f 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -25,8 +25,8 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-16 18:57+0000\n"
-"Last-Translator: emnrx <emanuelermancia@gmail.com>\n"
+"PO-Revision-Date: 2022-06-21 15:56+0000\n"
+"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n"
"Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/"
"godot-engine/godot/es_AR/>\n"
"Language: es_AR\n"
@@ -34,7 +34,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -50,7 +50,7 @@ msgstr "Escena Actual"
#: core/bind/core_bind.cpp
msgid "Exit Code"
-msgstr ""
+msgstr "Código de Salida"
#: core/bind/core_bind.cpp
msgid "V-Sync Enabled"
@@ -116,7 +116,7 @@ msgstr "Minimizada"
#: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp
#: scene/gui/graph_node.cpp
msgid "Resizable"
-msgstr ""
+msgstr "Redimensionable"
#: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp
#: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp
@@ -143,9 +143,8 @@ msgid "Endian Swap"
msgstr ""
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Editor Hint"
-msgstr "Editor"
+msgstr "Sugerencia del Editor"
#: core/bind/core_bind.cpp
msgid "Print Error Messages"
@@ -156,27 +155,24 @@ msgid "Iterations Per Second"
msgstr "Iteraciones Por Segundo"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Target FPS"
-msgstr "Objetivo"
+msgstr "Objetivo de FPS"
#: core/bind/core_bind.cpp
msgid "Time Scale"
msgstr "Escala de Tiempo"
#: core/bind/core_bind.cpp main/main.cpp
-#, fuzzy
msgid "Physics Jitter Fix"
-msgstr "Frames de Física %"
+msgstr "Corrección de Fluctuaciones(Jitter) de Física"
#: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Error"
msgstr "Error"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Error String"
-msgstr "Error al Guardar"
+msgstr "String de Error"
#: core/bind/core_bind.cpp
msgid "Error Line"
@@ -207,7 +203,7 @@ msgstr "Cola de comando"
#: core/command_queue_mt.cpp
msgid "Multithreading Queue Size (KB)"
-msgstr ""
+msgstr "Tamaño de la Cola de Multithreading (KB)"
#: core/func_ref.cpp modules/visual_script/visual_script_builtin_funcs.cpp
#: modules/visual_script/visual_script_func_nodes.cpp
@@ -218,23 +214,20 @@ msgstr "Función"
#: core/image.cpp core/packed_data_container.cpp scene/2d/polygon_2d.cpp
#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-#, fuzzy
msgid "Data"
-msgstr "Con Data"
+msgstr "Datos"
#: core/io/file_access_network.cpp core/register_core_types.cpp
#: editor/editor_file_dialog.cpp editor/editor_settings.cpp main/main.cpp
#: modules/gdscript/language_server/gdscript_language_server.cpp
#: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h
#: scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Network"
-msgstr "Profiler de Red"
+msgstr "Red"
#: core/io/file_access_network.cpp
-#, fuzzy
msgid "Remote FS"
-msgstr "Remoto "
+msgstr "FS Remoto"
#: core/io/file_access_network.cpp
msgid "Page Size"
@@ -246,7 +239,7 @@ msgstr ""
#: core/io/http_client.cpp
msgid "Blocking Mode Enabled"
-msgstr ""
+msgstr "Modo Bloqueante Activado"
#: core/io/http_client.cpp
msgid "Connection"
@@ -420,6 +413,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Comunidad"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (Física)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -449,7 +447,6 @@ msgid "Button Mask"
msgstr "Máscara de Botón"
#: core/os/input_event.cpp scene/2d/node_2d.cpp scene/gui/control.cpp
-#, fuzzy
msgid "Global Position"
msgstr "Posición Global"
@@ -476,6 +473,11 @@ msgstr "Preset"
#: core/os/input_event.cpp
#, fuzzy
+msgid "Pen Inverted"
+msgstr "Invertir"
+
+#: core/os/input_event.cpp
+#, fuzzy
msgid "Relative"
msgstr "Ajuste Relativo"
@@ -5638,6 +5640,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Selección de GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8128,11 +8135,20 @@ msgid "New Anim"
msgstr "Nueva Animación"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Crear Nueva Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Cambiar Nombre de Animación:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Renombrar Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Eliminar Animación?"
@@ -8150,11 +8166,6 @@ msgid "Animation name already exists!"
msgstr "El nombre de animación ya existe!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Renombrar Animación"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplicar Animación"
@@ -8300,10 +8311,6 @@ msgid "Pin AnimationPlayer"
msgstr "Fijar AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Crear Nueva Animación"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nombre de Animación:"
@@ -18909,6 +18916,11 @@ msgid "The package must have at least one '.' separator."
msgstr "El paquete debe tener al menos un '.' como separador."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "CustomNode"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18917,6 +18929,16 @@ msgstr ""
msgid "Export Format"
msgstr "Ruta de Exportación"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Tamaño de Outline:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Objetivo"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18960,16 +18982,6 @@ msgstr "Inspeccionar Instancia Previa"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Tamaño de Outline:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Objetivo"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19221,15 +19233,17 @@ msgid "\"Use Custom Build\" must be enabled to use the plugins."
msgstr "\"Use Custom Build\" debe estar activado para usar los plugins."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" sólo es válido cuando \"Xr Mode\" es \"Oculus Mobile "
"VrApi\" o \"OpenXR\"."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr "\"Passthrough\" sólo es válido cuando \"Xr Mode\" es \"OpenXR\"."
#: platform/android/export/export_plugin.cpp
@@ -19238,22 +19252,45 @@ msgstr ""
"\"Export AAB\" sólo es válido cuando \"Use Custom Build\" está activado."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Cambiar el \"Min Sdk\" sólo es válido cuando \"Use Custom Build\" está "
"activado."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Cambiar el \"Target Sdk\" sólo es válido cuando \"Use Custom Build\" está "
"activado."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"La versión de \"Target Sdk\" debe ser mayor o igual a la versión de \"Min "
"Sdk\"."
@@ -20992,7 +21029,7 @@ msgstr "Zoom In"
msgid "Custom Viewport"
msgstr "1 Viewport"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21761,11 +21798,43 @@ msgstr "Tamaño de Celda"
msgid "Edge Connection Margin"
msgstr "Editar Conexión:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Binding"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Elegir Instancia:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Elegir Instancia:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Avanzado"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Activar"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21782,16 +21851,6 @@ msgstr "Espejar Horizontalmente"
msgid "Max Speed"
msgstr "Velocidad Máxima"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Elegir Instancia:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Activar"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21836,7 +21895,7 @@ msgstr "Viaje"
msgid "Rotation Degrees"
msgstr "Rotando %s grados."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Constante Global"
@@ -23022,6 +23081,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformación Abortada."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23934,6 +24000,11 @@ msgstr ""
"En su lugar, cambiá el tamaño de los collision shapes hijos."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Mantener Transformación Global"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr "Matriz"
@@ -25179,6 +25250,11 @@ msgstr "Carpeta:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Solo Selección"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Activar"
@@ -25591,18 +25667,6 @@ msgstr "Ruta de Exportación"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Este viewport no está seteado como render target. Si tienes intención de que "
-"muestre contenidos directo a la pantalla, haz un hijo de un Control para que "
-"pueda obtener un tamaño. Alternativamente, haz un RenderTarget y asigna su "
-"textura interna a algún otro nodo para mostrar."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25610,6 +25674,15 @@ msgstr ""
"dimensiones para renderizar cualquier cosa."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27379,6 +27452,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Generando AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Offset:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/et.po b/editor/translations/et.po
index ca2105aa20..b355c9c343 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -417,6 +417,11 @@ msgstr ""
msgid "Command"
msgstr "Kogukond"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Luba"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -472,6 +477,10 @@ msgid "Pressure"
msgstr "Eelseadistus"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5473,6 +5482,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Kopeeri valik"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7854,11 +7868,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Kustuta animatsioon?"
@@ -7876,11 +7899,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8023,10 +8041,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18297,6 +18311,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Kustuta sõlm(ed)"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18305,6 +18324,16 @@ msgstr ""
msgid "Export Format"
msgstr "Formaat"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Suurus: "
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Ressursi tee"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18343,16 +18372,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Suurus: "
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Ressursi tee"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18591,12 +18610,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18605,17 +18624,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20238,7 +20277,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr "1 vaateaken"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -20942,34 +20981,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Ühenda"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Kombinatsioon"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Paigalda"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Täpsem"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Luba"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Luba"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21011,7 +21072,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstant"
@@ -22113,6 +22174,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "3D muundus rada"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -22977,6 +23045,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Tõlked"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24151,6 +24224,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Vali see kaust"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Luba"
@@ -24537,14 +24615,6 @@ msgid "Viewport Path"
msgstr "1 vaateaken"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -24552,6 +24622,15 @@ msgid ""
msgstr "Vaateakne suurus peab olema suurem kui 0, et kuvada."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -26252,6 +26331,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Muuda tüüpi"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
index cfbf2945ff..fc753e6cb9 100644
--- a/editor/translations/eu.po
+++ b/editor/translations/eu.po
@@ -394,6 +394,11 @@ msgstr ""
msgid "Command"
msgstr "Komunitatea"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Gaitu atxikitzea"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -446,6 +451,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Atxikitze erlatiboa"
@@ -5380,6 +5389,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7749,11 +7762,20 @@ msgid "New Anim"
msgstr "Animazio berria"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Aldatu animazioaren izena:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Aldatu izena animazioari"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Ezabatu animazioa?"
@@ -7771,11 +7793,6 @@ msgid "Animation name already exists!"
msgstr "Animazio izena existitzen da jada!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Aldatu izena animazioari"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Bikoiztu animazioa"
@@ -7918,10 +7935,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18122,6 +18135,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Kendu elementu guztiak"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18130,6 +18148,15 @@ msgstr ""
msgid "Export Format"
msgstr "Esportatu"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Blend4 nodoa"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18167,15 +18194,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Blend4 nodoa"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18413,12 +18431,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18427,17 +18445,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20032,7 +20070,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -20720,34 +20758,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Edukiak:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Itsatsi animazioa"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Instalatu"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Gaitu atxikitzea"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Gaitu atxikitzea"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Gaitu atxikitzea"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -20788,7 +20848,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstantea"
@@ -21877,6 +21937,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "3D Transformazioaren pista"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22727,6 +22794,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Translazio atzikitzea:"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23868,6 +23940,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Hautatu karpeta hau"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Gaitu atxikitzea"
@@ -24247,16 +24324,17 @@ msgstr "Kopiatu bidea"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25932,6 +26010,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Kide mota"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index 43d79c6ede..f43848b065 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -25,13 +25,14 @@
# Alireza Khodabande <alirezakhodabande74@gmail.com>, 2021.
# Seyed Fazel Alavi <fazel8195@gmail.com>, 2022.
# Giga hertz <gigahertzyt@gmail.com>, 2022.
+# Aryan Azadeh <aryan@azadeh.email>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-04-03 13:13+0000\n"
-"Last-Translator: Giga hertz <gigahertzyt@gmail.com>\n"
+"PO-Revision-Date: 2022-06-20 06:44+0000\n"
+"Last-Translator: Aryan Azadeh <aryan@azadeh.email>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot/fa/>\n"
"Language: fa\n"
@@ -39,7 +40,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.12-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -440,6 +441,11 @@ msgstr ""
msgid "Command"
msgstr "جامعه"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "روشن"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -497,6 +503,10 @@ msgid "Pressure"
msgstr "بازنشانی بزرگنمایی"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "GDNative"
@@ -694,7 +704,7 @@ msgstr "طرح پیش ÙØ±Ø¶ اتوبوس را بارگیری کنید."
#: editor/editor_settings.cpp editor/script_create_dialog.cpp
#: scene/2d/camera_2d.cpp scene/3d/light.cpp scene/main/node.cpp
msgid "Editor"
-msgstr "ویرایشگر"
+msgstr "ÙˆÛŒØ±Ø§ÛŒÙØ´Ú¯ÙŽØ±"
#: core/project_settings.cpp
msgid "Main Run Args"
@@ -4733,7 +4743,7 @@ msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr "جامعه"
+msgstr "اَنجÙÙ…ÙŽÙ†"
#: editor/editor_node.cpp
#, fuzzy
@@ -5534,6 +5544,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "انتخاب شده را حذ٠کن"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8034,11 +8049,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "تغییر نام انیمیشن"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "انیمیشن حذ٠شود؟"
@@ -8058,11 +8082,6 @@ msgid "Animation name already exists!"
msgstr "بارگذاری خودکار '%s' هم اکنون موجود است!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "تغییر نام انیمیشن"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8211,10 +8230,6 @@ msgid "Pin AnimationPlayer"
msgstr "تغییر نام انیمیشن"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -10732,7 +10747,7 @@ msgstr "زبانه قبلی"
#: editor/plugins/script_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "File"
-msgstr ""
+msgstr "پَروَندÙÙ‡"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -11360,7 +11375,7 @@ msgstr "خصوصیات"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "FPS: %d (%s ms)"
-msgstr ""
+msgstr "FPS: %d (%s ms)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View."
@@ -15207,7 +15222,7 @@ msgstr "تنظیمات پروژه (پروژه.گودات)"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
-msgstr "عمومی"
+msgstr "Ù‡ÙŽÙ…Ùگان"
#: editor/project_settings_editor.cpp
msgid "Override For..."
@@ -19005,6 +19020,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "ساختن گره"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -19013,6 +19033,16 @@ msgstr ""
msgid "Export Format"
msgstr "صدور پروژه"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "باز کردن و اجرای یک اسکریپت"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "گره تغییر والد"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -19051,16 +19081,6 @@ msgstr "زبانه قبلی"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "باز کردن و اجرای یک اسکریپت"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "گره تغییر والد"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19305,12 +19325,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19319,17 +19339,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20979,7 +21019,7 @@ msgstr "بزرگنمایی"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21704,34 +21744,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "ویرایش اتصال:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "ثابت"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "نصب کردن"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Ù¾ÛŒØ´Ø±ÙØªÙ‡"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "روشن"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "روشن"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21774,7 +21836,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "ثابت"
@@ -22918,6 +22980,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "انتخاب شده را تغییر مقیاس بده"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -23792,6 +23861,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "انتقال را در انیمیشن تغییر بده"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24992,6 +25066,11 @@ msgstr "ساختن پوشه"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "تنها در قسمت انتخاب شده"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "روشن"
@@ -25388,20 +25467,17 @@ msgstr "صدور پروژه"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
-"این viewport به صورت render target تنظیم نیست. اگر قصد دارید که محتویاتش را "
-"به صورت مستقیم در ØµÙØ­Ù‡â€ŒÙ†Ù…ایش نمایش دهد، آن را یک ÙØ±Ø²Ù†Ø¯ یک Control قرار دهید "
-"تا بتواند یک اندازه بگیرد. در غیر اینصورت، آن را یک RenderTarget قرار دهید و "
-"Ø¨Ø§ÙØª داخلی آن را برای نمایش به تعدادی گره تخصیص دهید."
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -27128,6 +27204,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "حذ٠قالب"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index 7c69731934..b83c7d11fa 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -437,6 +437,11 @@ msgstr ""
msgid "Command"
msgstr "Yhteisö"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (fyysinen)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -496,6 +501,10 @@ msgid "Pressure"
msgstr "Esiasetukset"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Suhteellinen tarttuminen"
@@ -5662,6 +5671,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Ruudukon valinta"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8143,11 +8157,20 @@ msgid "New Anim"
msgstr "Uusi animaatio"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Luo uusi animaatio"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Vaihda animaation nimi:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Nimeä animaatio uudelleen"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Poista animaatio?"
@@ -8165,11 +8188,6 @@ msgid "Animation name already exists!"
msgstr "Samanniminen animaatio on jo olemassa!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Nimeä animaatio uudelleen"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Monista animaatio"
@@ -8313,10 +8331,6 @@ msgid "Pin AnimationPlayer"
msgstr "Kiinnitä AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Luo uusi animaatio"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Animaation nimi:"
@@ -18902,6 +18916,11 @@ msgid "The package must have at least one '.' separator."
msgstr "Paketilla on oltava ainakin yksi '.' erotinmerkki."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Mukautettu solmu"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18910,6 +18929,16 @@ msgstr ""
msgid "Export Format"
msgstr "Vientipolku"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Ääriviivojen koko:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Kohde"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18953,16 +18982,6 @@ msgstr "Tarkastele edellistä ilmentymää"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Ääriviivojen koko:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Kohde"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19216,15 +19235,17 @@ msgstr ""
"käyttää."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" on käyttökelpoinen ainoastaan kun \"Xr Mode\" asetuksen "
"arvo on \"Oculus Mobile VrAPI\" tai \"OpenXR\"."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"\"Passthrough\" on käyttökelpoinen ainoastaan kun \"Xr Mode\" asetuksen arvo "
"on \"OpenXR\"."
@@ -19236,22 +19257,45 @@ msgstr ""
"päällä."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Min Sdk\" vaihtaminen on mahdollista vain, kun \"Use Custom Build\" asetus "
"on päällä."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Target Sdk\" vaihtaminen on mahdollista vain, kun \"Use Custom Build\" "
"asetus on päällä."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"\"Target Sdk\" versionumeron on oltava suurempi tai yhtä suuri kuin \"Min "
"Sdk\" versionumeron."
@@ -20991,7 +21035,7 @@ msgstr "Lähennä"
msgid "Custom Viewport"
msgstr "1 näyttöruutu"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21757,11 +21801,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Muokkaa yhteyttä:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Sidonta"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Poimintaetäisyys:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Poimintaetäisyys:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Edistyneet"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Ota käyttöön"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21779,16 +21855,6 @@ msgstr "Käännä vaakasuorasti"
msgid "Max Speed"
msgstr "Nopeus:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Poimintaetäisyys:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Ota käyttöön"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21837,7 +21903,7 @@ msgstr "Matkaa"
msgid "Rotation Degrees"
msgstr "Kierto %s astetta."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Globaali vakio"
@@ -23051,6 +23117,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Muunnos keskeytetty."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23980,6 +24053,11 @@ msgstr ""
"Muuta kokoa sen sijaan alisolmujen törmäysmuodoissa."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Pidä globaali muunnos"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25241,6 +25319,11 @@ msgstr "Kansio:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Pelkkä valinta"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Ota käyttöön"
@@ -25653,18 +25736,6 @@ msgstr "Vientipolku"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Tätä näyttöikkunaa ei ole asetettu renderöitäväksi. Jos haluat sen näyttävän "
-"sisältöä suoraan näytölle, tee sitä Control solmun alisolmu, jotta se voi "
-"saada koon. Muutoin tee siitä RenderTarget ja aseta sen sisäinen tekstuuri "
-"johonkin solmuun näkyväksi."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25672,6 +25743,15 @@ msgstr ""
"kummassakin suunnassa, jotta mitään renderöidään."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27441,6 +27521,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Luodaan AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Siirtymä:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index 19cb3febb0..c4e02900d7 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -392,6 +392,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Pisika"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -443,6 +448,10 @@ msgid "Pressure"
msgstr "Presyur"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relatibo"
@@ -5297,6 +5306,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7616,11 +7629,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7638,11 +7660,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7785,10 +7802,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17868,6 +17881,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Ilipat Ang Mga Bezier Points"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17876,6 +17894,14 @@ msgstr ""
msgid "Export Format"
msgstr "3D Transform Track"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr ""
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17912,14 +17938,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr ""
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18143,12 +18161,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18157,17 +18175,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19706,7 +19744,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20375,35 +20413,55 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Ikabit"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Pathfinding"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Path Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Binuksan ang V-Sync"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
msgid "Avoidance Enabled"
msgstr "Binuksan ang V-Sync"
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20442,7 +20500,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21496,6 +21554,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "3D Transform Track"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22307,6 +22372,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "3D Transform Track"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23408,6 +23478,10 @@ msgid "Fold Gutter"
msgstr ""
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr ""
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr ""
@@ -23768,16 +23842,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25361,6 +25436,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 6b077ba5e4..e4f5a2feff 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -32,7 +32,7 @@
# Przemyslaw Gasinski <gasinski.przemek@protonmail.ch>, 2017.
# rafeu <duchainer@gmail.com>, 2016-2017.
# rawida <rawida@tempinbox.com>, 2018.
-# Rémi Verschelde <rverschelde@gmail.com>, 2016-2017.
+# Rémi Verschelde <akien@godotengine.org>, 2016-2022.
# Robin Arys <robinarys@hotmail.com>, 2017.
# Roger BR <drai_kin@hotmail.com>, 2016.
# salty64 <cedric.arrabie@univ-pau.fr>, 2018, 2020, 2021.
@@ -49,7 +49,6 @@
# Brice Lobet <tempo.data@gmail.com>, 2018.
# Florent Wijanto <f_wijanto@hotmail.com>, 2018.
# Olivier gareau <olivier.gareau@protonmail.com>, 2018.
-# Rémi Verschelde <akien@godotengine.org>, 2018, 2019, 2020, 2021.
# Rémi Bintein <reminus5@hotmail.fr>, 2018, 2019.
# Sylvain Corsini <sylvain.corsini@gmail.com>, 2018.
# Caye Pierre <pierrecaye@laposte.net>, 2019.
@@ -66,7 +65,7 @@
# Fabrice <fabricecipolla@gmail.com>, 2019.
# Romain Paquet <titou.paquet@gmail.com>, 2019.
# Xavier Sellier <contact@binogure-studio.com>, 2019.
-# Sofiane <Sofiane-77@caramail.fr>, 2019, 2021.
+# Sofiane <Sofiane-77@caramail.fr>, 2019, 2021, 2022.
# Camille Mohr-Daurat <pouleyketchoup@gmail.com>, 2019.
# Pierre Stempin <pierre.stempin@gmail.com>, 2019.
# Pierre Caye <pierrecaye@laposte.net>, 2020, 2021, 2022.
@@ -97,13 +96,18 @@
# Zachary Dionne <zachary.dionne.01@gmail.com>, 2022.
# Fares Setbel <fares.setbels@gmail.com>, 2022.
# Nathan Hamy <hamynathan92@gmail.com>, 2022.
+# HOUA <ninjacowzx@gmail.com>, 2022.
+# DinosaurHorseSword <ewenlandry@mailfence.com>, 2022.
+# Arnaud Lier <arnaud@ric-rac.org>, 2022.
+# Jérémie Guegain <mirejai@orange.fr>, 2022.
+# cwulveryck <cwulveryck@online.fr>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-05-31 22:33+0000\n"
-"Last-Translator: Maxime Leroy <lisacintosh@gmail.com>\n"
+"PO-Revision-Date: 2022-07-16 06:20+0000\n"
+"Last-Translator: cwulveryck <cwulveryck@online.fr>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -111,7 +115,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.14-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -142,9 +146,8 @@ msgid "Delta Smoothing"
msgstr "Lissage de Delta"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Low Processor Usage Mode"
-msgstr "Mode d'utilisation du processeur bas en ressources"
+msgstr "Mode d'Utilisation Faible du Processeur"
#: core/bind/core_bind.cpp
msgid "Low Processor Usage Mode Sleep (µsec)"
@@ -281,9 +284,8 @@ msgid "Command Queue"
msgstr "File d’Attente de Commandes"
#: core/command_queue_mt.cpp
-#, fuzzy
msgid "Multithreading Queue Size (KB)"
-msgstr "Taille de la file du Multi-tache (KB)"
+msgstr "Taille de la fille d'attente Multi-Tache (KB)"
#: core/func_ref.cpp modules/visual_script/visual_script_builtin_funcs.cpp
#: modules/visual_script/visual_script_func_nodes.cpp
@@ -314,20 +316,22 @@ msgid "Page Size"
msgstr "Taille de page"
#: core/io/file_access_network.cpp
+#, fuzzy
msgid "Page Read Ahead"
-msgstr ""
+msgstr "Page lue devant"
#: core/io/http_client.cpp
msgid "Blocking Mode Enabled"
-msgstr ""
+msgstr "Mode De Blocage Activé"
#: core/io/http_client.cpp
msgid "Connection"
msgstr "Connexion"
#: core/io/http_client.cpp
+#, fuzzy
msgid "Read Chunk Size"
-msgstr ""
+msgstr "Lire la taille du tronçon"
#: core/io/marshalls.cpp
msgid "Object ID"
@@ -359,15 +363,15 @@ msgstr "Mode de Transfert"
#: core/io/packet_peer.cpp
msgid "Encode Buffer Max Size"
-msgstr ""
+msgstr "Taille maximale du tampon d'encodage"
#: core/io/packet_peer.cpp
msgid "Input Buffer Max Size"
-msgstr ""
+msgstr "Taille maximale du tampon d'entrée"
#: core/io/packet_peer.cpp
msgid "Output Buffer Max Size"
-msgstr ""
+msgstr "Taille maximale du tampon de sortie"
#: core/io/packet_peer.cpp
msgid "Stream Peer"
@@ -375,15 +379,15 @@ msgstr ""
#: core/io/stream_peer.cpp
msgid "Big Endian"
-msgstr ""
+msgstr "Gros-boutiste"
#: core/io/stream_peer.cpp
msgid "Data Array"
-msgstr ""
+msgstr "Tableau de données"
#: core/io/stream_peer_ssl.cpp
msgid "Blocking Handshake"
-msgstr ""
+msgstr "Blocage de la poignée de main"
#: core/io/udp_server.cpp
msgid "Max Pending Connections"
@@ -444,21 +448,19 @@ msgstr "État"
#: core/message_queue.cpp
msgid "Message Queue"
-msgstr ""
+msgstr "File d'Attente de Message"
#: core/message_queue.cpp
msgid "Max Size (KB)"
msgstr "Taille Maximale (KB)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "Mode déplacement"
+msgstr "Mode De Déplacement Souris"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "Supprimer l'entrée"
+msgstr "Utiliser l'entrée accumulée"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -479,12 +481,17 @@ msgstr "Contrôle"
#: core/os/input_event.cpp
msgid "Meta"
-msgstr ""
+msgstr "Méta"
#: core/os/input_event.cpp
msgid "Command"
msgstr "Commande"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (physique)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -492,14 +499,12 @@ msgid "Pressed"
msgstr "Pressé"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Scancode"
msgstr "Scancode"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Physical Scancode"
-msgstr "Touche physique"
+msgstr "Code de Scan Physique"
#: core/os/input_event.cpp
msgid "Unicode"
@@ -507,12 +512,11 @@ msgstr "Unicode"
#: core/os/input_event.cpp
msgid "Echo"
-msgstr ""
+msgstr "Écho"
#: core/os/input_event.cpp scene/gui/base_button.cpp
-#, fuzzy
msgid "Button Mask"
-msgstr "Bouton"
+msgstr "Masque Bouton"
#: core/os/input_event.cpp scene/2d/node_2d.cpp scene/gui/control.cpp
msgid "Global Position"
@@ -531,7 +535,6 @@ msgid "Doubleclick"
msgstr "Double clique"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Tilt"
msgstr "Inclinaison"
@@ -540,6 +543,11 @@ msgid "Pressure"
msgstr "Pression"
#: core/os/input_event.cpp
+#, fuzzy
+msgid "Pen Inverted"
+msgstr "Inverser"
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relatif"
@@ -572,7 +580,7 @@ msgstr "Action"
#: core/os/input_event.cpp scene/resources/environment.cpp
#: scene/resources/material.cpp
msgid "Strength"
-msgstr ""
+msgstr "Force"
#: core/os/input_event.cpp
msgid "Delta"
@@ -606,7 +614,7 @@ msgstr "Numéro du contrôleur"
#: core/os/input_event.cpp
msgid "Controller Value"
-msgstr ""
+msgstr "Valeur du controller"
#: core/project_settings.cpp editor/editor_node.cpp main/main.cpp
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
@@ -619,9 +627,8 @@ msgid "Config"
msgstr "Config"
#: core/project_settings.cpp
-#, fuzzy
msgid "Project Settings Override"
-msgstr "Paramètres du projet..."
+msgstr "Remplacement Des Paramètres du Projet"
#: core/project_settings.cpp core/resource.cpp
#: editor/animation_track_editor.cpp editor/editor_autoload_settings.cpp
@@ -663,9 +670,8 @@ msgid "Disable stderr"
msgstr "Désactiver stderr"
#: core/project_settings.cpp
-#, fuzzy
msgid "Use Hidden Project Data Directory"
-msgstr "Utiliser un Répertoire de Données du Projet Caché"
+msgstr "Utiliser un Répertoire Caché Pour Les Données du Projet"
#: core/project_settings.cpp
msgid "Use Custom User Dir"
@@ -678,15 +684,14 @@ msgstr "Nom du Répertoire Utilisateur Personnalisé"
#: core/project_settings.cpp main/main.cpp
#: platform/javascript/export/export.cpp platform/osx/export/export.cpp
#: platform/uwp/os_uwp.cpp
-#, fuzzy
msgid "Display"
-msgstr "Tout afficher"
+msgstr "Affichage"
#: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp
#: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp
#: scene/3d/label_3d.cpp scene/gui/text_edit.cpp scene/resources/texture.cpp
msgid "Width"
-msgstr ""
+msgstr "Largeur"
#: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp
#: modules/gltf/gltf_node.cpp modules/opensimplex/noise_texture.cpp
@@ -694,23 +699,20 @@ msgstr ""
#: scene/resources/capsule_shape_2d.cpp scene/resources/cylinder_shape.cpp
#: scene/resources/font.cpp scene/resources/navigation_mesh.cpp
#: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp
-#, fuzzy
msgid "Height"
-msgstr "Lumière"
+msgstr "Hauteur"
#: core/project_settings.cpp
msgid "Always On Top"
-msgstr ""
+msgstr "Toujours Au Dessus"
#: core/project_settings.cpp
-#, fuzzy
msgid "Test Width"
-msgstr "Étendu à Gauche"
+msgstr "Tester la Largeur"
#: core/project_settings.cpp
-#, fuzzy
msgid "Test Height"
-msgstr "En période de test"
+msgstr "Tester la Hauteur"
#: core/project_settings.cpp editor/animation_track_editor.cpp
#: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp
@@ -734,27 +736,24 @@ msgid "Main Run Args"
msgstr "Arguments de la scène principale :"
#: core/project_settings.cpp
-#, fuzzy
msgid "Scene Naming"
-msgstr "Chemin de la scène :"
+msgstr "Noms de scènes"
#: core/project_settings.cpp
msgid "Search In File Extensions"
-msgstr ""
+msgstr "Rechercher dans les extensions de fichiers"
#: core/project_settings.cpp
msgid "Script Templates Search Path"
-msgstr ""
+msgstr "Chemin où chercher les modèles de scripts"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Autoload On Startup"
-msgstr "Système de contrôle de version"
+msgstr "Chargement automatique de la version de contrôle au démarrage"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Plugin Name"
-msgstr "Contrôle de version"
+msgstr "Nom de l'extension de version de contrôle"
#: core/project_settings.cpp scene/2d/collision_object_2d.cpp
#: scene/3d/collision_object.cpp scene/gui/control.cpp
@@ -763,64 +762,56 @@ msgstr "Entrée"
#: core/project_settings.cpp
msgid "UI Accept"
-msgstr ""
+msgstr "Accepter"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Select"
msgstr "Sélectionner"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Cancel"
msgstr "Annuler"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Focus Next"
-msgstr "Focaliser le chemin"
+msgstr "Focus suivant"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Focus Prev"
-msgstr "Focaliser le chemin"
+msgstr "Focus précédent"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Left"
-msgstr "En haut à gauche"
+msgstr "Gauche"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Right"
-msgstr "En haut à droite"
+msgstr "Droite"
#: core/project_settings.cpp
msgid "UI Up"
-msgstr ""
+msgstr "Haut"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Down"
-msgstr "Descendre"
+msgstr "Bas"
#: core/project_settings.cpp
#, fuzzy
msgid "UI Page Up"
-msgstr "Page :"
+msgstr "Page Haut"
#: core/project_settings.cpp
msgid "UI Page Down"
-msgstr ""
+msgstr "Page Bas"
#: core/project_settings.cpp
msgid "UI Home"
-msgstr ""
+msgstr "Accueil Interface Utilisateur"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI End"
-msgstr "À la fin"
+msgstr "Fin"
#: core/project_settings.cpp main/main.cpp modules/bullet/register_types.cpp
#: modules/bullet/space_bullet.cpp scene/2d/physics_body_2d.cpp
@@ -846,7 +837,7 @@ msgstr "3D"
#: core/project_settings.cpp
#, fuzzy
msgid "Smooth Trimesh Collision"
-msgstr "Créer une collision Trimesh"
+msgstr "Collision Lisse Trimesh"
#: core/project_settings.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles2/rasterizer_scene_gles2.cpp
@@ -878,7 +869,7 @@ msgstr "Filtres"
#: core/project_settings.cpp scene/main/viewport.cpp
msgid "Sharpen Intensity"
-msgstr ""
+msgstr "Augmenter l'intensité"
#: core/project_settings.cpp editor/editor_export.cpp editor/editor_node.cpp
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
@@ -903,9 +894,8 @@ msgid "Profiler"
msgstr "Profileur"
#: core/project_settings.cpp
-#, fuzzy
msgid "Max Functions"
-msgstr "Faire fonction"
+msgstr "Nombre maximum de fonctions"
#: core/project_settings.cpp scene/3d/vehicle_body.cpp
msgid "Compression"
@@ -917,19 +907,20 @@ msgstr "Formats"
#: core/project_settings.cpp
msgid "Zstd"
-msgstr ""
+msgstr "Zstd"
#: core/project_settings.cpp
msgid "Long Distance Matching"
-msgstr ""
+msgstr "Appairement longue distance"
#: core/project_settings.cpp
msgid "Compression Level"
msgstr "Niveau de Compression"
#: core/project_settings.cpp
+#, fuzzy
msgid "Window Log Size"
-msgstr ""
+msgstr "Taille de la fenêtre du journal"
#: core/project_settings.cpp
msgid "Zlib"
@@ -945,24 +936,24 @@ msgstr "Android"
#: core/project_settings.cpp
msgid "Modules"
-msgstr ""
+msgstr "Modules"
#: core/register_core_types.cpp
msgid "TCP"
msgstr "TCP"
#: core/register_core_types.cpp
-#, fuzzy
msgid "Connect Timeout Seconds"
-msgstr "Connexions à la méthode :"
+msgstr "Délai d'expiration de la connexion en secondes"
#: core/register_core_types.cpp
msgid "Packet Peer Stream"
msgstr ""
#: core/register_core_types.cpp
+#, fuzzy
msgid "Max Buffer (Power of 2)"
-msgstr ""
+msgstr "Tampon Max (puissance de 2)"
#: core/register_core_types.cpp editor/editor_settings.cpp main/main.cpp
msgid "SSL"
@@ -1002,8 +993,9 @@ msgid "Test"
msgstr "Test"
#: core/translation.cpp scene/resources/font.cpp
+#, fuzzy
msgid "Fallback"
-msgstr ""
+msgstr "Repli"
#: core/ustring.cpp scene/resources/segment_shape_2d.cpp
msgid "B"
@@ -1039,7 +1031,7 @@ msgstr "Eio"
#: drivers/gles3/rasterizer_scene_gles3.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp modules/gltf/gltf_state.cpp
msgid "Buffers"
-msgstr ""
+msgstr "Tampons"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
@@ -1061,7 +1053,7 @@ msgstr ""
#: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp
#: servers/visual_server.cpp
msgid "2D"
-msgstr ""
+msgstr "2D"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
@@ -1078,7 +1070,7 @@ msgstr "Aligner au pixel près"
#: drivers/gles2/rasterizer_scene_gles2.cpp
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Immediate Buffer Size (KB)"
-msgstr ""
+msgstr "Taille du tampon immédiat (Ko)"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1089,28 +1081,28 @@ msgstr "Précalculer les lightmaps"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
msgid "Use Bicubic Sampling"
-msgstr ""
+msgstr "Utiliser l’échantillonnage bicubique"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Renderable Elements"
-msgstr ""
+msgstr "Maximum d'éléments pouvant être rendus"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Renderable Lights"
-msgstr ""
+msgstr "Maximum de lumières pouvant être rendues"
#: drivers/gles3/rasterizer_scene_gles3.cpp
-#, fuzzy
msgid "Max Renderable Reflections"
-msgstr "Centrer sur la sélection"
+msgstr "Nombre maximum de reflets pouvant être rendus"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Lights Per Object"
-msgstr ""
+msgstr "Maximum de lumières par objet"
#: drivers/gles3/rasterizer_scene_gles3.cpp
+#, fuzzy
msgid "Subsurface Scattering"
-msgstr ""
+msgstr "Transluminescence"
#: drivers/gles3/rasterizer_scene_gles3.cpp editor/animation_track_editor.cpp
#: editor/import/resource_importer_texture.cpp
@@ -1126,13 +1118,13 @@ msgid "Scale"
msgstr "Mode mise à l'échelle"
#: drivers/gles3/rasterizer_scene_gles3.cpp
-#, fuzzy
msgid "Follow Surface"
-msgstr "Remplir la surface"
+msgstr "Suivre la surface"
#: drivers/gles3/rasterizer_scene_gles3.cpp
+#, fuzzy
msgid "Weight Samples"
-msgstr ""
+msgstr "Échantillons de poids"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Voxel Cone Tracing"
@@ -1218,9 +1210,8 @@ msgstr "Changer l’appel de l’animation"
#: editor/animation_track_editor.cpp scene/2d/animated_sprite.cpp
#: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Frame"
-msgstr "Image %"
+msgstr "Trame"
#: editor/animation_track_editor.cpp editor/editor_profiler.cpp
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
@@ -1246,14 +1237,13 @@ msgid "Value"
msgstr "Valeur"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Arg Count"
-msgstr "Compte"
+msgstr "Nombre d'arguments"
#: editor/animation_track_editor.cpp main/main.cpp
#: modules/mono/mono_gd/gd_mono.cpp
msgid "Args"
-msgstr ""
+msgstr "Args"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp
@@ -1277,17 +1267,16 @@ msgstr "Définir la poignée"
#: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp
#: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp
msgid "Stream"
-msgstr ""
+msgstr "Flux"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Start Offset"
-msgstr "Décalage du Pivot"
+msgstr "Décalage du Départ"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "End Offset"
-msgstr "Décalage :"
+msgstr "Décalage à la fin"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/import/resource_importer_scene.cpp
@@ -1437,9 +1426,8 @@ msgid "Type:"
msgstr "Type :"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "(Invalid, expected type: %s)"
-msgstr "Modèle d'exportation non valide :"
+msgstr "(Invalide, type attendu : %s)"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -1457,9 +1445,8 @@ msgid "Out-Handle:"
msgstr "Définir la poignée"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Stream:"
-msgstr "Item radio"
+msgstr "Flux :"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -1714,7 +1701,7 @@ msgstr "Méthodes"
#: editor/animation_track_editor.cpp
msgid "Bezier"
-msgstr ""
+msgstr "Bezier"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2308,7 +2295,7 @@ msgstr "Ouvrir"
#: editor/dependency_editor.cpp
msgid "Owners of: %s (Total: %d)"
-msgstr ""
+msgstr "Possesseur de : %s (Total : %d)"
#: editor/dependency_editor.cpp
msgid ""
@@ -2876,22 +2863,19 @@ msgstr "Choisir"
#: editor/editor_export.cpp
msgid "Project export for platform:"
-msgstr ""
+msgstr "Exportation du projet pour la plateforme :"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed with errors."
-msgstr "Copier le chemin du nœud"
+msgstr "Terminé avec des erreurs."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed successfully."
-msgstr "Paquetage installé avec succès !"
+msgstr "Terminé avec succès."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed."
-msgstr "Échec :"
+msgstr "Échec."
#: editor/editor_export.cpp
msgid "Storing File:"
@@ -2906,29 +2890,24 @@ msgid "Packing"
msgstr "Empaquetage"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save PCK"
-msgstr "Enregistrer sous"
+msgstr "Enregistrer PCK"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Cannot create file \"%s\"."
-msgstr "Impossible de créer le dossier."
+msgstr "Impossible de créer le fichier \"%s\"."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to export project files."
-msgstr "Impossible d'exporter les fichiers du projet"
+msgstr "Impossible d'exporter les fichiers du projet."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Can't open file to read from path \"%s\"."
-msgstr "Impossible d'ouvrir le fichier pour écriture :"
+msgstr "Impossible d'ouvrir le fichier en lecture depuis le chemin \"%s\"."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save ZIP"
-msgstr "Enregistrer sous"
+msgstr "Enregistrer le ZIP"
#: editor/editor_export.cpp
msgid ""
@@ -3008,29 +2987,29 @@ msgid "64 Bits"
msgstr "64 Bits"
#: editor/editor_export.cpp
+#, fuzzy
msgid "Embed PCK"
-msgstr ""
+msgstr "PCK Intégré"
#: editor/editor_export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Texture Format"
-msgstr "RegionDeTexture"
+msgstr "Format de la texture"
#: editor/editor_export.cpp
msgid "BPTC"
-msgstr ""
+msgstr "BPTC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "S3TC"
-msgstr ""
+msgstr "S3TC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "ETC"
-msgstr ""
+msgstr "ETC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "ETC2"
-msgstr ""
+msgstr "ETC2"
#: editor/editor_export.cpp
msgid "No BPTC Fallbacks"
@@ -3054,25 +3033,22 @@ msgid "Prepare Template"
msgstr "Gérer les modèles"
#: editor/editor_export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "The given export path doesn't exist."
-msgstr "Le chemin de l'exportation donné n'existe pas :"
+msgstr "Le chemin de l'exportation donné n'existe pas."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
-#, fuzzy
msgid "Template file not found: \"%s\"."
-msgstr "Fichier modèle introuvable :"
+msgstr "Fichier modèle introuvable : \"%s\"."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to copy export template."
-msgstr "Modèle d'exportation non valide :"
+msgstr "La copie du modèle d'exportation a échoué."
#: editor/editor_export.cpp platform/windows/export/export.cpp
#: platform/x11/export/export.cpp
#, fuzzy
msgid "PCK Embedding"
-msgstr "Remplissage(Padding)"
+msgstr "Intégration du PCK"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
@@ -3080,7 +3056,7 @@ msgstr "Le PCK inclus dans un export 32-bits ne peut dépasser 4 Go."
#: editor/editor_export.cpp
msgid "Convert Text Resources To Binary On Export"
-msgstr ""
+msgstr "Convertir les ressources textuelles en binaire lors de l'exportation"
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -3406,8 +3382,9 @@ msgid "Show Hidden Files"
msgstr "Afficher les fichiers cachés"
#: editor/editor_file_dialog.cpp
+#, fuzzy
msgid "Disable Overwrite Warning"
-msgstr ""
+msgstr "Désactiver l'avertissement de réécriture"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
@@ -3510,7 +3487,7 @@ msgstr "Ré-importation des assets"
#: editor/editor_file_system.cpp
msgid "Reimport Missing Imported Files"
-msgstr ""
+msgstr "Réimporter les fichiers importés manquants"
#: editor/editor_help.cpp scene/2d/camera_2d.cpp scene/gui/control.cpp
#: scene/gui/nine_patch_rect.cpp scene/resources/dynamic_font.cpp
@@ -3621,7 +3598,7 @@ msgstr "Aide"
#: editor/editor_help.cpp
msgid "Sort Functions Alphabetically"
-msgstr ""
+msgstr "Trier les fonctions par ordre alphabétique"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -4104,7 +4081,8 @@ msgstr "Sauvegarder & Recharger"
#: editor/editor_node.cpp
#, fuzzy
msgid "Save changes to '%s' before reloading?"
-msgstr "Sauvegarder les modifications effectuées à « %s » avant de quitter ?"
+msgstr ""
+"Sauvegarder les modifications effectuées dans « %s » avant de recharger ?"
#: editor/editor_node.cpp
msgid "Save & Close"
@@ -4423,6 +4401,8 @@ msgstr "%d fichiers supplémentaires"
msgid ""
"Unable to write to file '%s', file in use, locked or lacking permissions."
msgstr ""
+"Impossible d'écrire dans le fichier '%s', le fichier est peut être utilisé, "
+"verrouillé ou vous n'avez pas les permissions pour écrire dessus."
#: editor/editor_node.cpp editor/editor_settings.cpp editor/scene_tree_dock.cpp
#: servers/arvr/arvr_interface.cpp
@@ -4435,53 +4415,49 @@ msgid "Scene Tabs"
msgstr "Basculer entre onglets de scène"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Always Show Close Button"
-msgstr "Toujours afficher la grille"
+msgstr "Toujours afficher le bouton fermer"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Resize If Many Tabs"
-msgstr ""
+msgstr "Redimensionner si plusieurs onglets"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Minimum Width"
-msgstr ""
+msgstr "Largeur Minimum"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Output"
msgstr "Sortie"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Always Clear Output On Play"
-msgstr "Effacer la sortie"
+msgstr "Toujours nettoyer la sortie lors du lancement"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Always Open Output On Play"
-msgstr ""
+msgstr "Toujours afficher la sortie lors du lancement"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Always Close Output On Stop"
-msgstr ""
+msgstr "Toujours fermer la sortie à l'arrêt"
#: editor/editor_node.cpp
msgid "Save On Focus Loss"
-msgstr ""
+msgstr "Enregistrer lorsque le focus est perdu"
#: editor/editor_node.cpp editor/editor_settings.cpp
#, fuzzy
msgid "Save Each Scene On Quit"
-msgstr "Sauvegarder la branche comme scène"
+msgstr "Enregistrer toutes les scènes à la fermeture"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Quit Confirmation"
-msgstr "Voir information"
+msgstr "Confirmer avant de quitter"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Show Update Spinner"
-msgstr "Cacher l'indicateur d'activité"
+msgstr "Afficher l'indicateur d'activité"
#: editor/editor_node.cpp
msgid "Update Continuously"
@@ -4500,11 +4476,11 @@ msgstr "Localisation"
#: editor/editor_node.cpp
#, fuzzy
msgid "Restore Scenes On Load"
-msgstr "Le nœud de la scène"
+msgstr "Restaurer les scènes au chargement"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Show Thumbnail On Hover"
-msgstr ""
+msgstr "Afficher l’aperçu au survol"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Inspector"
@@ -4513,11 +4489,11 @@ msgstr "Inspecteur"
#: editor/editor_node.cpp
#, fuzzy
msgid "Default Property Name Style"
-msgstr "Chemin du projet :"
+msgstr "Style par défaut des noms de propriétés"
#: editor/editor_node.cpp
msgid "Default Float Step"
-msgstr ""
+msgstr "Pas par défaut des flottant"
#: editor/editor_node.cpp scene/gui/tree.cpp
#, fuzzy
@@ -4525,30 +4501,32 @@ msgid "Disable Folding"
msgstr "Bouton désactivé"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Auto Unfold Foreign Scenes"
-msgstr ""
+msgstr "Déplier automatiquement les scènes étrangères"
#: editor/editor_node.cpp
msgid "Horizontal Vector2 Editing"
-msgstr ""
+msgstr "Édition horizontale de Vector2"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Horizontal Vector Types Editing"
-msgstr ""
+msgstr "Édition de Types de Vecteur Horizontal"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Resources In Current Inspector"
-msgstr "Ouvrir dans l'Inspecteur"
+msgstr "Ouvrir les ressources dans l'inspecteur actuel"
#: editor/editor_node.cpp
#, fuzzy
msgid "Resources To Open In New Inspector"
-msgstr "Ouvrir dans l'Inspecteur"
+msgstr "Ressources à ouvrir dans un nouvel inspecteur"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Default Color Picker Mode"
-msgstr ""
+msgstr "Mode par défaut du sélectionneur de couleur"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
@@ -5208,8 +5186,9 @@ msgid "Debugger"
msgstr "Débogueur"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Profiler Frame History Size"
-msgstr ""
+msgstr "Taille de l'historique de la trame du profileur"
#: editor/editor_profiler.cpp
#, fuzzy
@@ -5347,20 +5326,17 @@ msgstr "Nouveau %s"
#: modules/visual_script/visual_script_func_nodes.cpp
#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_yield_nodes.cpp
-#, fuzzy
msgid "Base Type"
-msgstr "Changer le type de base"
+msgstr "Type de base"
#: editor/editor_resource_picker.cpp
-#, fuzzy
msgid "Edited Resource"
-msgstr "Ajouter une ressource"
+msgstr "Ressource modifiée"
#: editor/editor_resource_picker.cpp scene/gui/line_edit.cpp
#: scene/gui/slider.cpp scene/gui/spin_box.cpp
-#, fuzzy
msgid "Editable"
-msgstr "Élément modifiable"
+msgstr "Modifiable"
#: editor/editor_resource_picker.cpp editor/property_editor.cpp
msgid "New Script"
@@ -5384,9 +5360,8 @@ msgstr ""
"Ajoutez un préréglage exécutable dans le menu d'exportation."
#: editor/editor_run_native.cpp
-#, fuzzy
msgid "Project Run"
-msgstr "Projet"
+msgstr "Exécution du projet"
#: editor/editor_run_script.cpp
msgid "Write your logic in the _run() method."
@@ -5413,34 +5388,34 @@ msgid "Did you forget the '_run' method?"
msgstr "Avez-vous oublié la méthode « _run » ?"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Editor Language"
-msgstr "Disposition de l'éditeur"
+msgstr "Langue de l'Éditeur"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Display Scale"
-msgstr "Tout afficher"
+msgstr "Échelle de l'affichage"
#: editor/editor_settings.cpp
msgid "Custom Display Scale"
-msgstr ""
+msgstr "Échelle personnalisé de l'affichage"
#: editor/editor_settings.cpp
msgid "Main Font Size"
-msgstr ""
+msgstr "Taille de la police principale"
#: editor/editor_settings.cpp
msgid "Code Font Size"
-msgstr ""
+msgstr "Taille de la police du code"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Font Antialiased"
-msgstr ""
+msgstr "Anticrénelage appliqué sur la police"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Font Hinting"
-msgstr ""
+msgstr "Indication de police"
#: editor/editor_settings.cpp
msgid "Main Font"
@@ -5448,7 +5423,7 @@ msgstr "Police Principale"
#: editor/editor_settings.cpp
msgid "Main Font Bold"
-msgstr ""
+msgstr "Principale police grasse"
#: editor/editor_settings.cpp
msgid "Code Font"
@@ -5456,11 +5431,12 @@ msgstr "Police du Code"
#: editor/editor_settings.cpp
msgid "Dim Editor On Dialog Popup"
-msgstr ""
+msgstr "Assombrir l'éditeur à l'ouverture d'un dialogue"
#: editor/editor_settings.cpp main/main.cpp
+#, fuzzy
msgid "Low Processor Mode Sleep (µsec)"
-msgstr ""
+msgstr "Mode de faible latence Processeur"
#: editor/editor_settings.cpp
msgid "Unfocused Low Processor Mode Sleep (µsec)"
@@ -5473,7 +5449,7 @@ msgstr "Mode Sans Distraction"
#: editor/editor_settings.cpp
msgid "Automatically Open Screenshots"
-msgstr ""
+msgstr "Ouvrir automatiquement les captures d'écran"
#: editor/editor_settings.cpp
msgid "Max Array Dictionary Items Per Page"
@@ -5491,7 +5467,7 @@ msgstr "Préréglage"
#: editor/editor_settings.cpp
msgid "Icon And Font Color"
-msgstr ""
+msgstr "Couleur de police et d'icône"
#: editor/editor_settings.cpp
msgid "Base Color"
@@ -5504,7 +5480,7 @@ msgstr "Prélever une couleur"
#: editor/editor_settings.cpp scene/resources/environment.cpp
msgid "Contrast"
-msgstr ""
+msgstr "Contraste"
#: editor/editor_settings.cpp
msgid "Relationship Line Opacity"
@@ -5521,8 +5497,9 @@ msgid "Border Size"
msgstr "Pixels de bordure"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Use Graph Node Headers"
-msgstr ""
+msgstr "Utiliser les en-tête de noeud Graph"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5558,13 +5535,13 @@ msgid "On Save"
msgstr "Enregistrer"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Compress Binary Resources"
-msgstr "Copier la ressource"
+msgstr "Compresser les ressources binaires"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Safe Save On Backup Then Rename"
-msgstr ""
+msgstr "Sauvegarde sécurisée lors de l'archivage puis renommer"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5584,8 +5561,9 @@ msgid "Scene Tree"
msgstr "une arborescence, arbre des scènes"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Start Create Dialog Fully Expanded"
-msgstr ""
+msgstr "Lancer le dialogue de Création totalement expandu"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5598,7 +5576,7 @@ msgstr "Éditeur de Propriétés"
#: editor/editor_settings.cpp
msgid "Auto Refresh Interval"
-msgstr ""
+msgstr "Intervalle d’autorafraîchissement"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5612,8 +5590,9 @@ msgstr "Thème de l'éditeur"
#: editor/editor_settings.cpp scene/3d/label_3d.cpp
#: scene/resources/default_theme/default_theme.cpp
+#, fuzzy
msgid "Line Spacing"
-msgstr ""
+msgstr "Espace entre les lignes"
#: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp
#: modules/gdscript/editor/gdscript_highlighter.cpp
@@ -5628,15 +5607,16 @@ msgstr "Coloration syntaxique"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Highlight All Occurrences"
-msgstr ""
+msgstr "Mettre en évidence toutes les occurrences"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Highlight Current Line"
-msgstr ""
+msgstr "Mettre en évidence la ligne actuelle"
#: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp
+#, fuzzy
msgid "Highlight Type Safe Lines"
-msgstr ""
+msgstr "Surligner les lignes Typées"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5653,9 +5633,8 @@ msgid "Convert Indent On Save"
msgstr "Convertir indentations en espaces"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
-#, fuzzy
msgid "Draw Tabs"
-msgstr "Appels de dessin :"
+msgstr "Montrer les tabulations"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
#, fuzzy
@@ -5671,11 +5650,11 @@ msgstr "Navigation"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Smooth Scrolling"
-msgstr ""
+msgstr "Défilement Doux"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "V Scroll Speed"
-msgstr ""
+msgstr "Vitesse du défilement vertical"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5684,15 +5663,20 @@ msgstr "Afficher l'origine"
#: editor/editor_settings.cpp
msgid "Minimap Width"
-msgstr ""
+msgstr "Largeur de la mini-carte"
#: editor/editor_settings.cpp
msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Sélection de la GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
-msgstr ""
+msgstr "Apparence"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Show Line Numbers"
@@ -5705,7 +5689,7 @@ msgstr "Numéro de ligne :"
#: editor/editor_settings.cpp
msgid "Show Bookmark Gutter"
-msgstr ""
+msgstr "Montrer le bandeau de marque-page"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5713,12 +5697,13 @@ msgid "Show Breakpoint Gutter"
msgstr "Passer les points d'arrêt"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Show Info Gutter"
-msgstr ""
+msgstr "Montrer le bandeau d'information"
#: editor/editor_settings.cpp
msgid "Code Folding"
-msgstr ""
+msgstr "Rétrécir le code"
#: editor/editor_settings.cpp
msgid "Word Wrap"
@@ -5741,8 +5726,9 @@ msgid "Script List"
msgstr "Liste des Scripts"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Show Members Overview"
-msgstr ""
+msgstr "Montrer l'ensemble des Membres"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
msgid "Files"
@@ -5754,16 +5740,19 @@ msgid "Trim Trailing Whitespace On Save"
msgstr "Supprimer les espaces de fin de ligne"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Autosave Interval Secs"
-msgstr ""
+msgstr "Intervalle entre les auto-sauvegarde (en secondes)"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
+#, fuzzy
msgid "Restore Scripts On Load"
-msgstr ""
+msgstr "Restaurer les scripts lors du chargement"
#: editor/editor_settings.cpp
msgid "Auto Reload And Parse Scripts On Save"
msgstr ""
+"Recharger et parcourir les scripts automatiquement lors de la sauvegarde"
#: editor/editor_settings.cpp
msgid "Auto Reload Scripts On External Change"
@@ -5780,23 +5769,23 @@ msgstr ""
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Cursor"
-msgstr ""
+msgstr "Curseur"
#: editor/editor_settings.cpp
msgid "Scroll Past End Of File"
-msgstr ""
+msgstr "Défiler au-delà de la fin du fichier"
#: editor/editor_settings.cpp
msgid "Block Caret"
-msgstr ""
+msgstr "Caret bloc"
#: editor/editor_settings.cpp
msgid "Caret Blink"
-msgstr ""
+msgstr "Clignotement du caret"
#: editor/editor_settings.cpp
msgid "Caret Blink Speed"
-msgstr ""
+msgstr "Vitesse du clignotement du caret"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5815,11 +5804,11 @@ msgstr ""
#: editor/editor_settings.cpp
msgid "Auto Brace Complete"
-msgstr ""
+msgstr "Complétion automatique des accolades"
#: editor/editor_settings.cpp
msgid "Code Complete Delay"
-msgstr ""
+msgstr "Délai d'auto-complétion du code"
#: editor/editor_settings.cpp
msgid "Put Callhint Tooltip Below Current Line"
@@ -5858,8 +5847,9 @@ msgid "Help Source Font Size"
msgstr "Taille de la police de l'aide de la source"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Help Title Font Size"
-msgstr ""
+msgstr "Taille de la police du titre Aide"
#: editor/editor_settings.cpp modules/gridmap/grid_map_editor_plugin.cpp
msgid "Grid Map"
@@ -5876,11 +5866,11 @@ msgstr "Aperçu de la taille"
#: editor/editor_settings.cpp
msgid "Primary Grid Color"
-msgstr ""
+msgstr "Couleur de la grille principale"
#: editor/editor_settings.cpp
msgid "Secondary Grid Color"
-msgstr ""
+msgstr "Couleur de la grille secondaire"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5917,7 +5907,7 @@ msgstr "Point"
#: scene/resources/particles_material.cpp servers/physics_2d_server.cpp
#: servers/physics_server.cpp
msgid "Shape"
-msgstr ""
+msgstr "Forme"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5930,11 +5920,11 @@ msgstr "Taille de la Grille"
#: editor/editor_settings.cpp
msgid "Grid Division Level Max"
-msgstr ""
+msgstr "Niveau maximal de division de la grille"
#: editor/editor_settings.cpp
msgid "Grid Division Level Min"
-msgstr ""
+msgstr "Niveau minimal de division de la grille"
#: editor/editor_settings.cpp
msgid "Grid Division Level Bias"
@@ -5971,7 +5961,7 @@ msgstr "Défaut"
#: editor/editor_settings.cpp
msgid "Lightmap Baking Number Of CPU Threads"
-msgstr ""
+msgstr "Nombre de fils CPU pour calculer les cartes de lumières"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5994,11 +5984,11 @@ msgstr "Style de Zoom"
#: editor/editor_settings.cpp
msgid "Emulate Numpad"
-msgstr ""
+msgstr "Émuler un pavé numérique"
#: editor/editor_settings.cpp
msgid "Emulate 3 Button Mouse"
-msgstr ""
+msgstr "Émuler souris à 3 boutons"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6011,9 +6001,8 @@ msgid "Pan Modifier"
msgstr "Mode navigation"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Zoom Modifier"
-msgstr "Modifié"
+msgstr "Multiplicateur de Zoom"
#: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Warped Mouse Panning"
@@ -6091,7 +6080,7 @@ msgstr "Magnétisme intelligent"
#: editor/editor_settings.cpp
msgid "Bone Width"
-msgstr ""
+msgstr "Largeur des os"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6113,8 +6102,9 @@ msgid "Bone IK Color"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Bone Outline Color"
-msgstr ""
+msgstr "Couleur de bordure de l'Os"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6122,12 +6112,14 @@ msgid "Bone Outline Size"
msgstr "Taille du contour :"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Viewport Border Color"
-msgstr ""
+msgstr "Couleur de bordure de la fenêtre d'affichage"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Constrain Editor View"
-msgstr ""
+msgstr "Restreindre la fenêtre d'Éditeur"
#: editor/editor_settings.cpp
msgid "Simple Panning"
@@ -6171,12 +6163,14 @@ msgid "Default Create Reset Tracks"
msgstr "Créer des pistes RESET"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Onion Layers Past Color"
-msgstr ""
+msgstr "Couleur de couche Oignon précedente"
#: editor/editor_settings.cpp
+#, fuzzy
msgid "Onion Layers Future Color"
-msgstr ""
+msgstr "Couleur de la couche d'Oignon suivante"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6185,11 +6179,11 @@ msgstr "Editeur de groupe"
#: editor/editor_settings.cpp
msgid "Minimap Opacity"
-msgstr ""
+msgstr "Opacité de la mini-carte"
#: editor/editor_settings.cpp
msgid "Window Placement"
-msgstr ""
+msgstr "Placement de la fenêtre"
#: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp
#: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp
@@ -6204,7 +6198,7 @@ msgstr "Définir la position de sortie de la courbe"
#: editor/editor_settings.cpp platform/android/export/export_plugin.cpp
msgid "Screen"
-msgstr ""
+msgstr "Écran"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6237,17 +6231,17 @@ msgstr "Paramètres de l'éditeur"
#: editor/editor_settings.cpp
msgid "HTTP Proxy"
-msgstr ""
+msgstr "Proxy HTTP"
#: editor/editor_settings.cpp
msgid "Host"
-msgstr ""
+msgstr "Hôte"
#: editor/editor_settings.cpp editor/fileserver/editor_file_server.cpp
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Port"
-msgstr ""
+msgstr "Port"
#. TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects.
#: editor/editor_settings.cpp
@@ -6265,7 +6259,7 @@ msgstr ""
#: editor/editor_settings.cpp
msgid "Keyword Color"
-msgstr ""
+msgstr "Couleur des mots-clés"
#: editor/editor_settings.cpp
msgid "Control Flow Keyword Color"
@@ -6286,7 +6280,7 @@ msgstr ""
#: editor/editor_settings.cpp
msgid "Comment Color"
-msgstr ""
+msgstr "Couleur des commentaires"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6336,7 +6330,7 @@ msgstr "Numéro de ligne :"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Caret Color"
-msgstr ""
+msgstr "Couleur du caret"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -6371,7 +6365,7 @@ msgstr "Coloration syntaxique"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Number Color"
-msgstr ""
+msgstr "Couleur des nombres"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -6399,8 +6393,9 @@ msgid "Breakpoint Color"
msgstr "Point d'arrêts"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
+#, fuzzy
msgid "Executing Line Color"
-msgstr ""
+msgstr "Couleur de la ligne d’exécution"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Code Folding Color"
@@ -6727,8 +6722,9 @@ msgstr ""
"téléchargement est terminé."
#: editor/fileserver/editor_file_server.cpp
+#, fuzzy
msgid "File Server"
-msgstr ""
+msgstr "Serveur de fichiers"
#: editor/fileserver/editor_file_server.cpp
#: editor/plugins/version_control_editor_plugin.cpp
@@ -7101,7 +7097,7 @@ msgstr "Gérer les groupes"
#: editor/import/editor_import_collada.cpp
msgid "Collada"
-msgstr ""
+msgstr "Collada"
#: editor/import/editor_import_collada.cpp
msgid "Use Ambient"
@@ -7135,7 +7131,7 @@ msgstr "Correction de Couleur"
#: editor/import/resource_importer_layered_texture.cpp
msgid "No BPTC If RGB"
-msgstr ""
+msgstr "Pas de BPTC si RVB"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/2d/cpu_particles_2d.cpp
@@ -7143,13 +7139,13 @@ msgstr ""
#: scene/resources/material.cpp scene/resources/particles_material.cpp
#: scene/resources/texture.cpp scene/resources/visual_shader.cpp
msgid "Flags"
-msgstr ""
+msgstr "Paramètres"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/animation/tween.cpp
#: scene/resources/texture.cpp
msgid "Repeat"
-msgstr ""
+msgstr "Répéter"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/2d/light_2d.cpp
@@ -7159,24 +7155,24 @@ msgstr "Filtre"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Mipmaps"
-msgstr "Signaux"
+msgstr "Mipmaps"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
+#, fuzzy
msgid "Anisotropic"
-msgstr ""
+msgstr "Anisotropie"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
msgid "sRGB"
-msgstr ""
+msgstr "sRGB"
#: editor/import/resource_importer_layered_texture.cpp
#, fuzzy
msgid "Slices"
-msgstr "Coupe automatique"
+msgstr "Coupures"
#: editor/import/resource_importer_layered_texture.cpp
#: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp
@@ -7193,30 +7189,26 @@ msgid "Vertical"
msgstr "Vertical"
#: editor/import/resource_importer_obj.cpp
-#, fuzzy
msgid "Generate Tangents"
-msgstr "Générer des points"
+msgstr "Générer les tangentes"
#: editor/import/resource_importer_obj.cpp
-#, fuzzy
msgid "Scale Mesh"
-msgstr "Mode mise à l'échelle"
+msgstr "Échelle du maillage"
#: editor/import/resource_importer_obj.cpp
-#, fuzzy
msgid "Offset Mesh"
-msgstr "Décalage :"
+msgstr "Décalage du maillage"
#: editor/import/resource_importer_obj.cpp
#: editor/import/resource_importer_scene.cpp
#, fuzzy
msgid "Octahedral Compression"
-msgstr "Expression"
+msgstr "Compression Octaédrique"
#: editor/import/resource_importer_obj.cpp
-#, fuzzy
msgid "Optimize Mesh Flags"
-msgstr "Optimiser les drapeaux de Mesh"
+msgstr "Optimiser les paramètres du maillage"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Single Scene"
@@ -7272,9 +7264,8 @@ msgid "Root Name"
msgstr "Nom de la Racine"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Root Scale"
-msgstr "Mode mise à l'échelle"
+msgstr "Échelle de la racine"
#: editor/import/resource_importer_scene.cpp
msgid "Custom Script"
@@ -7285,17 +7276,17 @@ msgid "Storage"
msgstr "Stockage"
#: editor/import/resource_importer_scene.cpp
+#, fuzzy
msgid "Use Legacy Names"
-msgstr ""
+msgstr "Utiliser des noms classiques"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
msgid "Materials"
msgstr "Matériaux"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Keep On Reimport"
-msgstr "Réimporter"
+msgstr "Conserver à la réimportation"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
msgid "Meshes"
@@ -7309,12 +7300,11 @@ msgstr "Modifier la tangente de courbes"
#: editor/import/resource_importer_scene.cpp
#, fuzzy
msgid "Light Baking"
-msgstr "Précalculer les lightmaps"
+msgstr "Pré-calculer les cartes de lumières"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Lightmap Texel Size"
-msgstr "LightMap Bake"
+msgstr "Taille des Texels dans la carte de lumières"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
msgid "Skins"
@@ -7326,13 +7316,13 @@ msgid "Use Named Skins"
msgstr "Utiliser le magnétisme d'échelle"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "External Files"
-msgstr "Ouvrir un fichier"
+msgstr "Fichiers externes"
#: editor/import/resource_importer_scene.cpp
+#, fuzzy
msgid "Store In Subdir"
-msgstr ""
+msgstr "Stocker dans un sous-dossier"
#: editor/import/resource_importer_scene.cpp
#, fuzzy
@@ -7340,14 +7330,12 @@ msgid "Filter Script"
msgstr "Filtrer les scripts"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Keep Custom Tracks"
-msgstr "Transformation"
+msgstr "Conserver les pistes personnalisées"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Optimizer"
-msgstr "Optimiser"
+msgstr "Optimiseur"
#: editor/import/resource_importer_scene.cpp
#: editor/plugins/item_list_editor_plugin.cpp main/main.cpp
@@ -7361,9 +7349,8 @@ msgstr "Optimiser"
#: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp
#: scene/gui/rich_text_label.cpp scene/resources/curve.cpp
#: scene/resources/environment.cpp scene/resources/material.cpp
-#, fuzzy
msgid "Enabled"
-msgstr "Activer"
+msgstr "Activé"
#: editor/import/resource_importer_scene.cpp
msgid "Max Linear Error"
@@ -7441,30 +7428,34 @@ msgid ""
"%s: Texture detected as used as a normal map in 3D. Enabling red-green "
"texture compression to reduce memory usage (blue channel is discarded)."
msgstr ""
+"%s : La texture a été utilisé comme carte de normales dans la 3D. Activation "
+"de la compression rouge-verte pour réduire l'utilisation de la mémoire (le "
+"canal bleu est désactivé)."
#: editor/import/resource_importer_texture.cpp
msgid ""
"%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap "
"generation and VRAM texture compression."
msgstr ""
+"%s : La texture a été détecter comme étant utilisé dans la 3D. Activation du "
+"filtrage, de la répétition, de la génération de mipmap et de la compression "
+"de la texture dans la mémoire vidéo."
#: editor/import/resource_importer_texture.cpp
msgid "2D, Detect 3D"
-msgstr ""
+msgstr "2D, Détecter la 3D"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "2D Pixel"
-msgstr "Pixels pleins"
+msgstr "Pixel 2D"
#: editor/import/resource_importer_texture.cpp scene/resources/texture.cpp
msgid "Lossy Quality"
-msgstr ""
+msgstr "Mauvaise qualité"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "HDR Mode"
-msgstr "Mode sélection"
+msgstr "Mode HDR"
#: editor/import/resource_importer_texture.cpp
msgid "BPTC LDR"
@@ -7475,16 +7466,15 @@ msgstr ""
#: scene/2d/mesh_instance_2d.cpp scene/2d/multimesh_instance_2d.cpp
#: scene/2d/particles_2d.cpp scene/2d/sprite.cpp scene/resources/style_box.cpp
msgid "Normal Map"
-msgstr ""
+msgstr "Carte de normales"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Process"
-msgstr "Post-traitement"
+msgstr "Processus"
#: editor/import/resource_importer_texture.cpp
msgid "Fix Alpha Border"
-msgstr ""
+msgstr "Corriger la bordure alpha"
#: editor/import/resource_importer_texture.cpp
#, fuzzy
@@ -7493,37 +7483,36 @@ msgstr "Modifier le polygone"
#: editor/import/resource_importer_texture.cpp
msgid "Hdr As Srgb"
-msgstr ""
+msgstr "Hdr en tant que Srgb"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Invert Color"
-msgstr "Vertex"
+msgstr "Inverser la couleur"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Normal Map Invert Y"
-msgstr "Échelle aléatoire :"
+msgstr "Inverser l'axe Y de la carte de normales"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Size Limit"
-msgstr "Limites"
+msgstr "Limite de taille"
#: editor/import/resource_importer_texture.cpp
msgid "Detect 3D"
-msgstr ""
+msgstr "Détecter la 3D"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "SVG"
-msgstr "HSV"
+msgstr "SVG"
#: editor/import/resource_importer_texture.cpp
msgid ""
"Warning, no suitable PC VRAM compression enabled in Project Settings. This "
"texture will not display correctly on PC."
msgstr ""
+"Attention, aucune compression de la mémoire vidéo qui aille sur PC n'est "
+"activé dans les paramètres du projet. Cette texture ne s'affichera pas "
+"correctement sur PC."
#: editor/import/resource_importer_texture_atlas.cpp
msgid "Atlas File"
@@ -7543,55 +7532,48 @@ msgid "Trim Alpha Border From Region"
msgstr ""
#: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp
-#, fuzzy
msgid "Force"
-msgstr "Force-pousser"
+msgstr "Force"
#: editor/import/resource_importer_wav.cpp
msgid "8 Bit"
-msgstr ""
+msgstr "8 Bit"
#: editor/import/resource_importer_wav.cpp main/main.cpp
#: modules/mono/editor/csharp_project.cpp modules/mono/mono_gd/gd_mono.cpp
msgid "Mono"
-msgstr ""
+msgstr "Mono"
#: editor/import/resource_importer_wav.cpp
-#, fuzzy
msgid "Max Rate"
-msgstr "Mélanger le nœud"
+msgstr "Taux maximal"
#: editor/import/resource_importer_wav.cpp
-#, fuzzy
msgid "Max Rate Hz"
-msgstr "Mélanger le nœud"
+msgstr "Taux maximal en Hz"
#: editor/import/resource_importer_wav.cpp
msgid "Trim"
msgstr ""
#: editor/import/resource_importer_wav.cpp
-#, fuzzy
msgid "Normalize"
-msgstr "Format"
+msgstr "Normaliser"
#: editor/import/resource_importer_wav.cpp
#: scene/resources/audio_stream_sample.cpp
-#, fuzzy
msgid "Loop Mode"
-msgstr "Mode déplacement"
+msgstr "Mode de bouclage"
#: editor/import/resource_importer_wav.cpp
#: scene/resources/audio_stream_sample.cpp
-#, fuzzy
msgid "Loop Begin"
-msgstr "Mode déplacement"
+msgstr "Début de la boucle"
#: editor/import/resource_importer_wav.cpp
#: scene/resources/audio_stream_sample.cpp
-#, fuzzy
msgid "Loop End"
-msgstr "Mode déplacement"
+msgstr "Fin de la boucle"
#: editor/import_defaults_editor.cpp
msgid "Select Importer"
@@ -7672,9 +7654,8 @@ msgid "Failed to load resource."
msgstr "Impossible de charger la ressource."
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Property Name Style"
-msgstr "Nom du projet :"
+msgstr "Style des noms de propriétés"
#: editor/inspector_dock.cpp scene/gui/color_picker.cpp
msgid "Raw"
@@ -7686,13 +7667,12 @@ msgid "Capitalized"
msgstr "Majuscule à chaque mot"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Localized"
-msgstr "Localisation"
+msgstr "Traduit"
#: editor/inspector_dock.cpp
msgid "Localization not available for current language."
-msgstr ""
+msgstr "La traduction n'est pas disponible pour la langue actuel."
#: editor/inspector_dock.cpp
msgid "Copy Properties"
@@ -8146,11 +8126,20 @@ msgid "New Anim"
msgstr "Nouvelle animation"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Créer une nouvelle animation"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Modifier le nom de l'animation :"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Renommer l'animation"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Supprimer l'animation ?"
@@ -8168,11 +8157,6 @@ msgid "Animation name already exists!"
msgstr "Ce nom d'animation existe déjà !"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Renommer l'animation"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Dupliquer l'animation"
@@ -8239,9 +8223,8 @@ msgid "New"
msgstr "Nouveau"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Paste As Reference"
-msgstr "Référence de classe %s"
+msgstr "Collé en tant que référence"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Edit Transitions..."
@@ -8317,10 +8300,6 @@ msgid "Pin AnimationPlayer"
msgstr "Épingler AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Créer une nouvelle animation"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nom de l'animation :"
@@ -8575,7 +8554,7 @@ msgstr "Filtres…"
#: editor/plugins/asset_library_editor_plugin.cpp scene/main/http_request.cpp
msgid "Use Threads"
-msgstr ""
+msgstr "Utiliser le multitâche"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Contents:"
@@ -8738,25 +8717,21 @@ msgid "Loading..."
msgstr "Chargement..."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgctxt "Pagination"
msgid "First"
msgstr "Premier"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgctxt "Pagination"
msgid "Previous"
msgstr "Précédent"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgctxt "Pagination"
msgid "Next"
msgstr "Suivant"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgctxt "Pagination"
msgid "Last"
msgstr "Dernier"
@@ -8807,7 +8782,7 @@ msgstr "En période de test"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Failed to get repository configuration."
-msgstr ""
+msgstr "N'a pas réussi à récupérer la configuration du dépôt."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -9374,23 +9349,20 @@ msgid "View"
msgstr "Affichage"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Show"
-msgstr "Afficher la grille"
+msgstr "Afficher"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Show When Snapping"
-msgstr "Magnétisme intelligent"
+msgstr "Afficher lors de la magnétisation"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Hide"
-msgstr ""
+msgstr "Cacher"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Grid"
-msgstr "Basculer le mode"
+msgstr "Activer/Désactiver la grille"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -9742,16 +9714,16 @@ msgstr "Dégradé édité"
#: editor/plugins/gradient_texture_2d_editor_plugin.cpp
msgid "Swap GradientTexture2D Fill Points"
-msgstr ""
+msgstr "Échanger les points de remplissage du GradientTexture2D"
#: editor/plugins/gradient_texture_2d_editor_plugin.cpp
+#, fuzzy
msgid "Swap Gradient Fill Points"
-msgstr ""
+msgstr "Échanger les points de remplissage du dégradé"
#: editor/plugins/gradient_texture_2d_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Grid Snap"
-msgstr "Basculer le mode"
+msgstr "Activer/Désactiver le magnétisme de la grille"
#: editor/plugins/item_list_editor_plugin.cpp editor/project_export.cpp
#: scene/3d/label_3d.cpp scene/gui/button.cpp scene/gui/dialogs.cpp
@@ -9770,13 +9742,12 @@ msgstr "Icône"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "ID"
-msgstr ""
+msgstr "ID"
#: editor/plugins/item_list_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Separator"
-msgstr "Séparation :"
+msgstr "Séparateur"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item %d"
@@ -9896,7 +9867,7 @@ msgstr "Créer le contour"
#: scene/resources/multimesh.cpp scene/resources/primitive_meshes.cpp
#: scene/resources/texture.cpp
msgid "Mesh"
-msgstr "Maillages"
+msgstr "Mesh"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -10020,7 +9991,6 @@ msgstr ""
"%s"
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid "MeshLibrary"
msgstr "Librairie de maillages"
@@ -10583,7 +10553,7 @@ msgstr "Synchroniser les os avec le polygone"
#: editor/plugins/ray_cast_2d_editor_plugin.cpp
msgid "Set cast_to"
-msgstr ""
+msgstr "Définir cast_to"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ERROR: Couldn't load resource!"
@@ -10914,21 +10884,19 @@ msgstr "Résultats de recherche"
#: editor/plugins/script_editor_plugin.cpp
msgid "Open Dominant Script On Scene Change"
-msgstr ""
+msgstr "Ouvrir le script principal lors du changement de scène"
#: editor/plugins/script_editor_plugin.cpp
msgid "External"
-msgstr ""
+msgstr "Externe"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Use External Editor"
-msgstr "Déboguer avec un éditeur externe"
+msgstr "Utiliser un éditeur externe"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Exec Path"
-msgstr "Chemin d'exportation"
+msgstr "Chemin d'exécution"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -10937,7 +10905,7 @@ msgstr "Sélectionner le fichier de modèles"
#: editor/plugins/script_editor_plugin.cpp
msgid "Highlight Current Script"
-msgstr ""
+msgstr "Mettre en évidence le script actuel"
#: editor/plugins/script_editor_plugin.cpp
msgid "Script Temperature History Size"
@@ -10953,18 +10921,16 @@ msgid "Group Help Pages"
msgstr "Groupe sélectionné"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Sort Scripts By"
-msgstr "Créer un script"
+msgstr "Trier les scripts par"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "List Script Names As"
-msgstr "Nom du script :"
+msgstr "Lister les noms de scripts en tant que"
#: editor/plugins/script_editor_plugin.cpp
msgid "Exec Flags"
-msgstr ""
+msgstr "Paramètres d'exécution"
#: editor/plugins/script_editor_plugin.cpp
msgid "Clear Recent Scripts"
@@ -11485,10 +11451,11 @@ msgid "(Not in GLES2)"
msgstr "(Non disponible dans GLES2)"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid ""
"Debug draw modes are only available when using the GLES3 renderer, not GLES2."
-msgstr "Non disponible quand le moteur de rendu GLES2 est utilisé."
+msgstr ""
+"Les modes de rendu de débogage ne sont disponibles qu'avec le moteur GLES3, "
+"et pas GLES2."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Left"
@@ -11791,9 +11758,8 @@ msgid "Manipulator Gizmo Opacity"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Show Viewport Rotation Gizmo"
-msgstr "Verrouiller la rotation de la vue"
+msgstr "Afficher le manipulateur de rotation dans le viewport"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unnamed Gizmo"
@@ -11846,9 +11812,8 @@ msgid "Invalid geometry, can't replace by mesh."
msgstr "Géométrie invalide, impossible de remplacer par un maillage."
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to MeshInstance2D"
-msgstr "Convertir en Mesh2D"
+msgstr "Convertir en MeshInstance2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
@@ -12252,9 +12217,8 @@ msgstr ""
"Fermer tout de même ?"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Remove Type"
-msgstr "Supprimer la tuile"
+msgstr "Supprimer le type"
#: editor/plugins/theme_editor_plugin.cpp
msgid ""
@@ -12299,14 +12263,12 @@ msgstr ""
"thème."
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Add Theme Type"
-msgstr "Ajouter un item de type"
+msgstr "Ajouter un type de thème"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Remove Theme Type"
-msgstr "Retirer le dépôt distant"
+msgstr "Supprimer un type de thème"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add Color Item"
@@ -12425,7 +12387,7 @@ msgstr "Sélectionnez une autre ressource Theme :"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
msgid "Theme Resource"
-msgstr "Renommer une ressource"
+msgstr "Ressource de Thème"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Another Theme"
@@ -12486,7 +12448,6 @@ msgid "Set Variation Base Type"
msgstr "Définir type de variable"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Set Base Type"
msgstr "Changer le type de base"
@@ -12512,10 +12473,13 @@ msgid "Select the variation base type from a list of available types."
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
+#, fuzzy
msgid ""
"A type associated with a built-in class cannot be marked as a variation of "
"another type."
msgstr ""
+"Un type affilié à une classe intégré ne peut pas être marqué comme une "
+"variante d'un autre type."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme:"
@@ -12756,14 +12720,13 @@ msgid "Clear Transform"
msgstr "Supprimer la transformation"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Tile Map"
-msgstr "Peindre sur la TileMap"
+msgstr "Carte de Tuiles"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Palette Min Width"
-msgstr ""
+msgstr "Largeur minimale de la palette"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -12771,19 +12734,16 @@ msgid "Palette Item H Separation"
msgstr "Séparateur nommé"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Show Tile Names"
-msgstr "Afficher toutes les langues"
+msgstr "Afficher les noms des tuiles"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Show Tile Ids"
-msgstr "Afficher les règles"
+msgstr "Afficher les IDs des tuiles"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Sort Tiles By Name"
-msgstr "Trier les fichiers"
+msgstr "Trier les tuiles par nom"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -12792,19 +12752,16 @@ msgstr "Remplissage du seau"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Editor Side"
-msgstr "Éditeur"
+msgstr "Coté Éditeur"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Display Grid"
-msgstr "Affichage des surimpressions"
+msgstr "Afficher la grille"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Axis Color"
-msgstr "Prélever une couleur"
+msgstr "Couleur des axes"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Add Texture(s) to TileSet."
@@ -13143,7 +13100,6 @@ msgid "This property can't be changed."
msgstr "Cette propriété ne peut être changée."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Snap Options"
msgstr "Options de magnétisme"
@@ -13168,14 +13124,12 @@ msgstr "Pas"
#: editor/plugins/tile_set_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Separation"
-msgstr "Séparation :"
+msgstr "Séparation"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Selected Tile"
-msgstr "Sélectionner"
+msgstr "Tuile sélectionné"
#: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp
#: scene/2d/light_2d.cpp scene/2d/line_2d.cpp scene/2d/mesh_instance_2d.cpp
@@ -13184,9 +13138,8 @@ msgstr "Sélectionner"
#: scene/gui/nine_patch_rect.cpp scene/gui/texture_rect.cpp
#: scene/resources/material.cpp scene/resources/sky.cpp
#: scene/resources/style_box.cpp scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Texture"
-msgstr "Texte"
+msgstr "Texture"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -13201,9 +13154,8 @@ msgstr "Matériau"
#: editor/plugins/tile_set_editor_plugin.cpp scene/2d/canvas_item.cpp
#: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/style_box.cpp
-#, fuzzy
msgid "Modulate"
-msgstr "Peupler"
+msgstr "Moduler"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -13216,39 +13168,32 @@ msgid "Autotile Bitmask Mode"
msgstr "Mode Bitmask"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Subtile Size"
-msgstr "Taille de Contour"
+msgstr "Taille des sous-tuiles"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Subtile Spacing"
-msgstr "Bouclage de l’animation"
+msgstr "Espacement des sous-tuiles"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Occluder Offset"
-msgstr "Créer un polygone occulteur"
+msgstr "Décalage de l’occulteur"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Navigation Offset"
-msgstr "Mode Navigation"
+msgstr "Décalage de la navigation"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Shape Offset"
-msgstr "Décalage :"
+msgstr "Décalage de la forme"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Shape Transform"
-msgstr "Transformation"
+msgstr "Transformation de la forme"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Selected Collision"
-msgstr "Collision"
+msgstr "Collision sélectionné"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -13261,9 +13206,8 @@ msgid "Selected Collision One Way Margin"
msgstr "Mode collision"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Selected Navigation"
-msgstr "Navigation visible"
+msgstr "Navigation sélectionnée"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -14368,11 +14312,13 @@ msgstr "Exécutable"
#: editor/project_export.cpp
msgid "Export the project for all the presets defined."
-msgstr ""
+msgstr "Exporter le projet pour tous les préréglages définis."
#: editor/project_export.cpp
msgid "All presets must have an export path defined for Export All to work."
msgstr ""
+"Tous les préréglages doivent avoir un chemin d'exportation défini pour "
+"pouvoir tous les exportés."
#: editor/project_export.cpp
msgid "Delete preset '%s'?"
@@ -14485,53 +14431,48 @@ msgid ""
"Note: Encryption key needs to be stored in the binary,\n"
"you need to build the export templates from source."
msgstr ""
+"Note : La clé de cryptage doit être stocké dans le binaire,\n"
+"vous devez compiler les modèles d'exportation depuis les sources."
#: editor/project_export.cpp
-#, fuzzy
msgid "More Info..."
-msgstr "Déplacer vers…"
+msgstr "Plus d'informations..."
#: editor/project_export.cpp
-#, fuzzy
msgid "Export PCK/Zip..."
msgstr "Exporter le PCK/ZIP"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export Project..."
-msgstr "Exporter le projet"
+msgstr "Exporter le projet..."
#: editor/project_export.cpp
msgid "Export All"
msgstr "Tout exporter"
#: editor/project_export.cpp
-#, fuzzy
msgid "Choose an export mode:"
-msgstr "Veuillez choisir un dossier vide."
+msgstr "Choisissez un mode d'exportation :"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export All..."
-msgstr "Tout exporter"
+msgstr "Tout exporter..."
#: editor/project_export.cpp editor/project_manager.cpp
msgid "ZIP File"
msgstr "Fichier ZIP"
#: editor/project_export.cpp
-#, fuzzy
msgid "Godot Project Pack"
-msgstr "Archive Godot"
+msgstr "Pack de Projet Godot"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing:"
msgstr "Modèles d'exportation manquants pour cette plateforme :"
#: editor/project_export.cpp
-#, fuzzy
msgid "Project Export"
-msgstr "Fondateurs du projet"
+msgstr "Exportation du projet"
#: editor/project_export.cpp
msgid "Manage Export Templates"
@@ -14849,7 +14790,6 @@ msgstr ""
#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
-#, fuzzy
msgctxt "Application"
msgid "Project Manager"
msgstr "Gestionnaire de projets"
@@ -15658,17 +15598,15 @@ msgstr "Rendre local"
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
msgid "Another node already uses this unique name in the scene."
-msgstr ""
+msgstr "Un autre Nœud utilise ce nom unique dans la scène."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Enable Scene Unique Name"
-msgstr "Nom unique"
+msgstr "Activer le nom unique de la scène"
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Disable Scene Unique Name"
-msgstr "Nom unique"
+msgstr "Désactiver le nom unique de la scène"
#: editor/scene_tree_dock.cpp
msgid "New Scene Root"
@@ -15847,7 +15785,7 @@ msgstr "Effacer l'héritage ? (Pas de retour en arrière !)"
#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Show Scene Tree Root Selection"
-msgstr "Centrer sur la sélection"
+msgstr "Afficher la sélection de la racine de l'arborescence"
#: editor/scene_tree_dock.cpp
msgid "Derive Script Globals By Name"
@@ -15884,6 +15822,9 @@ msgid ""
"with the '%s' prefix in a node path.\n"
"Click to disable this."
msgstr ""
+"Ce Nœud est accessible de n'importe où dans la scène en le préfixant de '%s' "
+"dans un chemin de Nœud.\n"
+"Cliquer pour désactiver cela."
#: editor/scene_tree_editor.cpp
msgid ""
@@ -16170,9 +16111,8 @@ msgid "Stack Frames"
msgstr "Pile des appels"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Filter stack variables"
-msgstr "Filtrer les tuiles"
+msgstr "Filtrer les variables de la pile"
#: editor/script_editor_debugger.cpp
msgid "Auto Switch To Remote Scene Tree"
@@ -16180,7 +16120,7 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Remote Scene Tree Refresh Interval"
-msgstr ""
+msgstr "Intervalle de rafraîchissement de l'arborescence distante"
#: editor/script_editor_debugger.cpp
msgid "Remote Inspect Refresh Interval"
@@ -16282,8 +16222,9 @@ msgid "Change Light Radius"
msgstr "Changer le rayon d'une lumière"
#: editor/spatial_editor_gizmos.cpp
+#, fuzzy
msgid "Stream Player 3D"
-msgstr ""
+msgstr "Émetteur de flux sonore 3D"
#: editor/spatial_editor_gizmos.cpp
msgid "Change AudioStreamPlayer3D Emission Angle"
@@ -16293,7 +16234,7 @@ msgstr "Changer l'angle d'émission AudioStreamPlayer3D"
#: platform/osx/export/export.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Camera"
-msgstr ""
+msgstr "Caméra"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Camera FOV"
@@ -16305,7 +16246,7 @@ msgstr "Changer la taille d'une caméra"
#: editor/spatial_editor_gizmos.cpp
msgid "Visibility Notifier"
-msgstr ""
+msgstr "Notifiant de visibilité"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Notifier AABB"
@@ -16316,18 +16257,16 @@ msgid "Change Particles AABB"
msgstr "Changer particules AABB"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Reflection Probe"
-msgstr "Sélectionnez une propriété"
+msgstr "Sonde de Réflexion"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Probe Extents"
msgstr "Changer les ampleurs de la sonde"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "GI Probe"
-msgstr "Créer sonde IG (Illumination Globale)"
+msgstr "Sonde GI"
#: editor/spatial_editor_gizmos.cpp
#, fuzzy
@@ -16363,14 +16302,12 @@ msgid "Change Ray Shape Length"
msgstr "Changer la longueur d'une forme en rayon"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Navigation Edge"
-msgstr "Mode Navigation"
+msgstr "Bord de la Navigation"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Navigation Edge Disabled"
-msgstr "Mode Navigation"
+msgstr "Bord de la Navigation Désactivé"
#: editor/spatial_editor_gizmos.cpp
#, fuzzy
@@ -16392,7 +16329,7 @@ msgstr ""
#: editor/spatial_editor_gizmos.cpp
msgid "Room Edge"
-msgstr ""
+msgstr "Bord de la pièce"
#: editor/spatial_editor_gizmos.cpp
msgid "Room Overlap"
@@ -16403,13 +16340,12 @@ msgid "Set Room Point Position"
msgstr "Définir la position du point de la pièce"
#: editor/spatial_editor_gizmos.cpp scene/3d/portal.cpp
-#, fuzzy
msgid "Portal Margin"
-msgstr "Définir la marge"
+msgstr "Marge du portail"
#: editor/spatial_editor_gizmos.cpp
msgid "Portal Edge"
-msgstr ""
+msgstr "Bords du portail"
#: editor/spatial_editor_gizmos.cpp
msgid "Portal Arrow"
@@ -16421,18 +16357,16 @@ msgstr "Définir la position du point du Portal"
#: editor/spatial_editor_gizmos.cpp
msgid "Portal Front"
-msgstr ""
+msgstr "Avant du Portail"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Portal Back"
-msgstr "Retourner"
+msgstr "Arrière du Portail"
#: editor/spatial_editor_gizmos.cpp scene/2d/light_occluder_2d.cpp
#: scene/2d/tile_map.cpp
-#, fuzzy
msgid "Occluder"
-msgstr "Mode Occlusion"
+msgstr "Occulteur"
#: editor/spatial_editor_gizmos.cpp
msgid "Set Occluder Sphere Radius"
@@ -16483,39 +16417,36 @@ msgid "BVH Collision Margin"
msgstr "Mode collision"
#: main/main.cpp
-#, fuzzy
msgid "Crash Handler"
-msgstr "Définir la poignée"
+msgstr "Gestionnaire de Crash"
#: main/main.cpp
-#, fuzzy
msgid "Multithreaded Server"
-msgstr "Ensemble multi-nœud"
+msgstr "Serveur à tâches parallèles"
#: main/main.cpp
msgid "RID Pool Prealloc"
msgstr ""
#: main/main.cpp
-#, fuzzy
msgid "Debugger stdout"
-msgstr "Débogueur"
+msgstr "Sortie standard du débogueur"
#: main/main.cpp
msgid "Max Chars Per Second"
-msgstr ""
+msgstr "Maximum de Caractères par seconde"
#: main/main.cpp
msgid "Max Messages Per Frame"
-msgstr ""
+msgstr "Maximum de messages par image"
#: main/main.cpp
msgid "Max Errors Per Second"
-msgstr ""
+msgstr "Maximum d'erreurs par seconde"
#: main/main.cpp
msgid "Max Warnings Per Second"
-msgstr ""
+msgstr "Maximum d'avertissements par secondes"
#: main/main.cpp
msgid "Flush stdout On Print"
@@ -16523,38 +16454,35 @@ msgstr ""
#: main/main.cpp servers/visual_server.cpp
msgid "Logging"
-msgstr ""
+msgstr "Journalisation"
#: main/main.cpp
msgid "File Logging"
-msgstr ""
+msgstr "Journalisation dans un fichier"
#: main/main.cpp
-#, fuzzy
msgid "Enable File Logging"
-msgstr "Activer le filtrage"
+msgstr "Activer la journalisation dans un fichier"
#: main/main.cpp
-#, fuzzy
msgid "Log Path"
-msgstr "Copier le chemin"
+msgstr "Chemin du Journal"
#: main/main.cpp
msgid "Max Log Files"
-msgstr ""
+msgstr "Maximum de fichiers journaux"
#: main/main.cpp
msgid "Driver"
-msgstr ""
+msgstr "Pilote"
#: main/main.cpp
-#, fuzzy
msgid "Driver Name"
-msgstr "Nom du script :"
+msgstr "Nom du Pilote"
#: main/main.cpp
msgid "Fallback To GLES2"
-msgstr ""
+msgstr "Se replier sur GLES2"
#: main/main.cpp
msgid "Use Nvidia Rect Flicker Workaround"
@@ -16569,45 +16497,40 @@ msgid "Allow hiDPI"
msgstr ""
#: main/main.cpp
-#, fuzzy
msgid "V-Sync"
-msgstr "Synchroniser"
+msgstr "Synchronisation Vertical"
#: main/main.cpp
-#, fuzzy
msgid "Use V-Sync"
-msgstr "Utiliser l’aimantation"
+msgstr "Utiliser la Synchronisation Vertical"
#: main/main.cpp
msgid "Per Pixel Transparency"
-msgstr ""
+msgstr "Transparence par pixel"
#: main/main.cpp
msgid "Allowed"
-msgstr ""
+msgstr "Autorisé"
#: main/main.cpp
msgid "Intended Usage"
-msgstr ""
+msgstr "Usage prévu"
#: main/main.cpp
-#, fuzzy
msgid "Framebuffer Allocation"
-msgstr "Encadrer la sélection"
+msgstr "Allocation du tampon d'image (Framebuffer)"
#: main/main.cpp platform/uwp/os_uwp.cpp
-#, fuzzy
msgid "Energy Saving"
-msgstr "Erreur d'enregistrement"
+msgstr "Économie d'Énergie"
#: main/main.cpp
msgid "Threads"
-msgstr ""
+msgstr "Tâches Parallèles"
#: main/main.cpp servers/physics_2d/physics_2d_server_wrap_mt.h
-#, fuzzy
msgid "Thread Model"
-msgstr "Basculer le mode"
+msgstr "Modèle de Parallélisme"
#: main/main.cpp
msgid "Thread Safe BVH"
@@ -16619,25 +16542,21 @@ msgstr ""
#: main/main.cpp platform/javascript/export/export.cpp
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Orientation"
-msgstr "Documentation en ligne"
+msgstr "Orientation"
#: main/main.cpp scene/gui/scroll_container.cpp scene/gui/text_edit.cpp
#: scene/main/scene_tree.cpp scene/register_scene_types.cpp
-#, fuzzy
msgid "Common"
-msgstr "Communauté"
+msgstr "Commun"
#: main/main.cpp
-#, fuzzy
msgid "Physics FPS"
-msgstr "Image physique %"
+msgstr "TPS de la physique"
#: main/main.cpp
-#, fuzzy
msgid "Force FPS"
-msgstr "Force-pousser"
+msgstr "Forces les trames par seconde"
#: main/main.cpp
msgid "Enable Pause Aware Picking"
@@ -16655,7 +16574,7 @@ msgstr ""
#: main/main.cpp
msgid "stdout"
-msgstr ""
+msgstr "Sortie Standard"
#: main/main.cpp
msgid "Print FPS"
@@ -16663,26 +16582,23 @@ msgstr ""
#: main/main.cpp
msgid "Verbose stdout"
-msgstr ""
+msgstr "Détailler La Sortie Standard"
#: main/main.cpp scene/main/scene_tree.cpp scene/resources/multimesh.cpp
-#, fuzzy
msgid "Physics Interpolation"
-msgstr "Mode d’interpolation"
+msgstr "Interpolation de la physique"
#: main/main.cpp
-#, fuzzy
msgid "Enable Warnings"
-msgstr "Activer le filtrage"
+msgstr "Activer les avertissements"
#: main/main.cpp
-#, fuzzy
msgid "Frame Delay Msec"
-msgstr "Encadrer la sélection"
+msgstr "Délai des trames en millisecondes"
#: main/main.cpp
msgid "Low Processor Mode"
-msgstr ""
+msgstr "Mode Processeur Faible"
#: main/main.cpp
msgid "Delta Sync After Draw"
@@ -16690,21 +16606,19 @@ msgstr ""
#: main/main.cpp
msgid "iOS"
-msgstr ""
+msgstr "iOS"
#: main/main.cpp
msgid "Hide Home Indicator"
-msgstr ""
+msgstr "Masquer l'indicateur d’accueil"
#: main/main.cpp
-#, fuzzy
msgid "Input Devices"
-msgstr "Tous les périphérique"
+msgstr "Périphériques d'entrée"
#: main/main.cpp
-#, fuzzy
msgid "Pointing"
-msgstr "Point"
+msgstr "Pointage"
#: main/main.cpp
msgid "Touch Delay"
@@ -16712,12 +16626,11 @@ msgstr ""
#: main/main.cpp servers/visual_server.cpp
msgid "GLES3"
-msgstr ""
+msgstr "GLES3"
#: main/main.cpp servers/visual_server.cpp
-#, fuzzy
msgid "Shaders"
-msgstr "Ombrage"
+msgstr "Shaders"
#: main/main.cpp
#, fuzzy
@@ -16727,49 +16640,44 @@ msgstr "Forcer les replis du shader"
#: main/main.cpp scene/3d/baked_lightmap.cpp scene/3d/camera.cpp
#: scene/3d/world_environment.cpp scene/main/scene_tree.cpp
#: scene/resources/world.cpp
-#, fuzzy
msgid "Environment"
-msgstr "Voir environnement"
+msgstr "Environnement"
#: main/main.cpp
msgid "Default Clear Color"
-msgstr ""
+msgstr "Couleur d'effacement par défaut"
#: main/main.cpp
msgid "Boot Splash"
-msgstr ""
+msgstr "Écran de démarrage"
#: main/main.cpp
-#, fuzzy
msgid "Show Image"
-msgstr "Afficher les os"
+msgstr "Afficher l'image"
#: main/main.cpp
msgid "Image"
-msgstr ""
+msgstr "Image"
#: main/main.cpp
msgid "Fullsize"
-msgstr ""
+msgstr "Pleine taille"
#: main/main.cpp scene/resources/dynamic_font.cpp
-#, fuzzy
msgid "Use Filter"
-msgstr "Filtre :"
+msgstr "Utiliser le filtrage"
#: main/main.cpp scene/resources/style_box.cpp
-#, fuzzy
msgid "BG Color"
-msgstr "Couleurs"
+msgstr "Couleur d'arrière-plan"
#: main/main.cpp
-#, fuzzy
msgid "macOS Native Icon"
-msgstr "Définir l'icône de la tuile"
+msgstr "Icône native de macOS"
#: main/main.cpp
msgid "Windows Native Icon"
-msgstr ""
+msgstr "Icône native de Windows"
#: main/main.cpp
msgid "Buffering"
@@ -16781,30 +16689,27 @@ msgstr ""
#: main/main.cpp
msgid "Emulate Touch From Mouse"
-msgstr ""
+msgstr "Émuler le toucher tactile avec la souris"
#: main/main.cpp
msgid "Emulate Mouse From Touch"
-msgstr ""
+msgstr "Émuler la souris avec le toucher tactile"
#: main/main.cpp
-#, fuzzy
msgid "Mouse Cursor"
-msgstr "Bouton de souris"
+msgstr "Curseur de la souris"
#: main/main.cpp
-#, fuzzy
msgid "Custom Image"
-msgstr "Nœud Personnalisé"
+msgstr "Image personnalisée"
#: main/main.cpp
msgid "Custom Image Hotspot"
msgstr ""
#: main/main.cpp
-#, fuzzy
msgid "Tooltip Position Offset"
-msgstr "Décalage de la rotation :"
+msgstr "Décalage de la position des info-bulles"
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
#, fuzzy
@@ -16812,9 +16717,8 @@ msgid "Debugger Agent"
msgstr "Débogueur"
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
-#, fuzzy
msgid "Wait For Debugger"
-msgstr "Débogueur"
+msgstr "Attendre le débogueur"
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
msgid "Wait Timeout"
@@ -16829,28 +16733,25 @@ msgid "Unhandled Exception Policy"
msgstr ""
#: main/main.cpp
-#, fuzzy
msgid "Main Loop Type"
-msgstr "Rechercher le type de nœud"
+msgstr "Type de boucle principale"
#: main/main.cpp scene/gui/texture_progress.cpp
#: scene/gui/viewport_container.cpp
-#, fuzzy
msgid "Stretch"
-msgstr "Actualiser"
+msgstr "Étirement"
#: main/main.cpp
-#, fuzzy
msgid "Aspect"
-msgstr "Inspecteur"
+msgstr "Aspect"
#: main/main.cpp
msgid "Shrink"
-msgstr ""
+msgstr "Rétrécissement"
#: main/main.cpp scene/main/scene_tree.cpp
msgid "Auto Accept Quit"
-msgstr ""
+msgstr "Accepter automatiquement la fermeture"
#: main/main.cpp scene/main/scene_tree.cpp
#, fuzzy
@@ -16864,7 +16765,7 @@ msgstr "Aimanter aux flancs du nœud"
#: main/main.cpp
msgid "Dynamic Fonts"
-msgstr ""
+msgstr "Polices Dynamiques"
#: main/main.cpp
msgid "Use Oversampling"
@@ -16901,7 +16802,7 @@ msgstr "Options"
#: modules/csg/csg_shape.cpp
msgid "Calculate Tangents"
-msgstr ""
+msgstr "Calculer les Tangentes"
#: modules/csg/csg_shape.cpp
#, fuzzy
@@ -17007,9 +16908,8 @@ msgid "Path Simplify Angle"
msgstr ""
#: modules/csg/csg_shape.cpp
-#, fuzzy
msgid "Path Rotation"
-msgstr "Rotation aléatoire :"
+msgstr "Rotation du chemin"
#: modules/csg/csg_shape.cpp
#, fuzzy
@@ -17032,24 +16932,20 @@ msgid "Path Joined"
msgstr "Rotation aléatoire :"
#: modules/enet/networked_multiplayer_enet.cpp
-#, fuzzy
msgid "Compression Mode"
-msgstr "Mode collision"
+msgstr "Mode de compression"
#: modules/enet/networked_multiplayer_enet.cpp
-#, fuzzy
msgid "Transfer Channel"
-msgstr "Modification de la transformation"
+msgstr "Canal de transfert"
#: modules/enet/networked_multiplayer_enet.cpp
-#, fuzzy
msgid "Channel Count"
-msgstr "Instance"
+msgstr "Nombre de canaux"
#: modules/enet/networked_multiplayer_enet.cpp
-#, fuzzy
msgid "Always Ordered"
-msgstr "Toujours afficher la grille"
+msgstr "Toujours ordonnée"
#: modules/enet/networked_multiplayer_enet.cpp
msgid "Server Relay"
@@ -17057,24 +16953,23 @@ msgstr ""
#: modules/enet/networked_multiplayer_enet.cpp
msgid "DTLS Verify"
-msgstr ""
+msgstr "Vérification DTLS"
#: modules/enet/networked_multiplayer_enet.cpp
msgid "DTLS Hostname"
-msgstr ""
+msgstr "Nom de l'hôte DTLS"
#: modules/enet/networked_multiplayer_enet.cpp
-#, fuzzy
msgid "Use DTLS"
-msgstr "Utiliser l’aimantation"
+msgstr "Utiliser DTLS"
#: modules/fbx/editor_scene_importer_fbx.cpp
msgid "FBX"
-msgstr ""
+msgstr "FBX"
#: modules/fbx/editor_scene_importer_fbx.cpp
msgid "Use FBX"
-msgstr ""
+msgstr "Utiliser FBX"
#: modules/gdnative/gdnative.cpp
msgid "Config File"
@@ -17087,19 +16982,16 @@ msgstr "Charger une ressource"
#: modules/gdnative/gdnative.cpp
#: modules/visual_script/visual_script_func_nodes.cpp
-#, fuzzy
msgid "Singleton"
-msgstr "Squelette"
+msgstr "Singleton"
#: modules/gdnative/gdnative.cpp
-#, fuzzy
msgid "Symbol Prefix"
-msgstr "Préfixe :"
+msgstr "Préfixe du symbole"
#: modules/gdnative/gdnative.cpp
-#, fuzzy
msgid "Reloadable"
-msgstr "Recharger"
+msgstr "Rechargeable"
#: modules/gdnative/gdnative.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
@@ -17160,14 +17052,12 @@ msgid "Class Name"
msgstr "Nom de la Classe"
#: modules/gdnative/nativescript/nativescript.cpp
-#, fuzzy
msgid "Script Class"
-msgstr "Nom du script :"
+msgstr "Classe de Script"
#: modules/gdnative/nativescript/nativescript.cpp
-#, fuzzy
msgid "Icon Path"
-msgstr "Focaliser le chemin"
+msgstr "Chemin de l'icône"
#: modules/gdnative/register_types.cpp
msgid "GDNative"
@@ -17175,34 +17065,32 @@ msgstr "GDNative"
#: modules/gdscript/editor/gdscript_highlighter.cpp
#: modules/gdscript/gdscript.cpp
-#, fuzzy
msgid "GDScript"
-msgstr "Script"
+msgstr "GDScript"
#: modules/gdscript/editor/gdscript_highlighter.cpp
msgid "Function Definition Color"
-msgstr ""
+msgstr "Couleur de définition de fonction"
#: modules/gdscript/editor/gdscript_highlighter.cpp
-#, fuzzy
msgid "Node Path Color"
-msgstr "Copier le chemin du nœud"
+msgstr "Couleur des chemins de nœud"
#: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp
msgid "Max Call Stack"
-msgstr ""
+msgstr "Maximum de la pile d'appel"
#: modules/gdscript/gdscript.cpp
msgid "Treat Warnings As Errors"
-msgstr ""
+msgstr "Traiter les avertissements comme des erreurs"
#: modules/gdscript/gdscript.cpp
msgid "Exclude Addons"
-msgstr ""
+msgstr "Exclure les extensions"
#: modules/gdscript/gdscript.cpp
msgid "Autocomplete Setters And Getters"
-msgstr ""
+msgstr "Auto-compléter les setters et les getters"
#: modules/gdscript/gdscript_functions.cpp
msgid "Step argument is zero!"
@@ -17249,17 +17137,16 @@ msgid "Language Server"
msgstr "Serveur de Langues"
#: modules/gdscript/language_server/gdscript_language_server.cpp
-#, fuzzy
msgid "Enable Smart Resolve"
-msgstr "Impossible à résoudre"
+msgstr "Activer la résolution intelligente"
#: modules/gdscript/language_server/gdscript_language_server.cpp
msgid "Show Native Symbols In Editor"
-msgstr ""
+msgstr "Afficher les symboles natifs dans l'éditeur"
#: modules/gdscript/language_server/gdscript_language_server.cpp
msgid "Use Thread"
-msgstr ""
+msgstr "Utiliser le parallélisme"
#: modules/gltf/editor_scene_exporter_gltf_plugin.cpp
msgid "Export Mesh GLTF2"
@@ -17270,37 +17157,32 @@ msgid "Export GLTF..."
msgstr "Exporter en GLTF..."
#: modules/gltf/gltf_accessor.cpp
-#, fuzzy
msgid "Buffer View"
-msgstr "Vue de derrière"
+msgstr "Vue du tampon"
#: modules/gltf/gltf_accessor.cpp modules/gltf/gltf_buffer_view.cpp
msgid "Byte Offset"
msgstr "Décalage d’Octet"
#: modules/gltf/gltf_accessor.cpp
-#, fuzzy
msgid "Component Type"
-msgstr "Composants"
+msgstr "Type de composant"
#: modules/gltf/gltf_accessor.cpp
-#, fuzzy
msgid "Normalized"
-msgstr "Format"
+msgstr "Normalisé"
#: modules/gltf/gltf_accessor.cpp
msgid "Count"
msgstr "Compte"
#: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Min"
-msgstr "Mio"
+msgstr "Min"
#: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Max"
-msgstr "Mixer"
+msgstr "Max"
#: modules/gltf/gltf_accessor.cpp
#, fuzzy
@@ -17329,14 +17211,12 @@ msgid "Sparse Values Byte Offset"
msgstr ""
#: modules/gltf/gltf_buffer_view.cpp
-#, fuzzy
msgid "Buffer"
-msgstr "Vue de derrière"
+msgstr "Tampon"
#: modules/gltf/gltf_buffer_view.cpp
-#, fuzzy
msgid "Byte Length"
-msgstr "Thème par défaut"
+msgstr "Longueur de byte"
#: modules/gltf/gltf_buffer_view.cpp
msgid "Byte Stride"
@@ -17368,19 +17248,17 @@ msgstr "Linéaire"
#: scene/resources/environment.cpp scene/resources/material.cpp
#: scene/resources/particles_material.cpp scene/resources/sky.cpp
#: scene/resources/style_box.cpp
-#, fuzzy
msgid "Color"
-msgstr "Couleurs"
+msgstr "Couleur"
#: modules/gltf/gltf_light.cpp scene/3d/reflection_probe.cpp
#: scene/resources/environment.cpp
msgid "Intensity"
-msgstr ""
+msgstr "Intensité"
#: modules/gltf/gltf_light.cpp scene/2d/light_2d.cpp scene/3d/light.cpp
-#, fuzzy
msgid "Range"
-msgstr "Changer"
+msgstr "Plage"
#: modules/gltf/gltf_light.cpp
msgid "Inner Cone Angle"
@@ -17401,9 +17279,8 @@ msgid "Instance Materials"
msgstr "Changements de matériau :"
#: modules/gltf/gltf_node.cpp scene/3d/skeleton.cpp
-#, fuzzy
msgid "Parent"
-msgstr "Re-parenter"
+msgstr "Parent"
#: modules/gltf/gltf_node.cpp
#, fuzzy
@@ -17430,12 +17307,13 @@ msgid "Joints"
msgstr "Point"
#: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp
+#, fuzzy
msgid "Roots"
-msgstr ""
+msgstr "Racines"
#: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_state.cpp
msgid "Unique Names"
-msgstr ""
+msgstr "Noms Uniques"
#: modules/gltf/gltf_skeleton.cpp
#, fuzzy
@@ -17474,16 +17352,18 @@ msgid "Godot Skin"
msgstr ""
#: modules/gltf/gltf_spec_gloss.cpp
+#, fuzzy
msgid "Diffuse Img"
-msgstr ""
+msgstr "Image Diffuse"
#: modules/gltf/gltf_spec_gloss.cpp
+#, fuzzy
msgid "Diffuse Factor"
-msgstr ""
+msgstr "Facteur de diffusion"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Gloss Factor"
-msgstr ""
+msgstr "Facteur de brillance"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Specular Factor"
@@ -17542,11 +17422,11 @@ msgstr "Fonctionnalités"
#: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp
msgid "Images"
-msgstr ""
+msgstr "Images"
#: modules/gltf/gltf_state.cpp
msgid "Cameras"
-msgstr ""
+msgstr "Caméras"
#: modules/gltf/gltf_state.cpp servers/visual_server.cpp
#, fuzzy
@@ -17593,7 +17473,7 @@ msgstr "Précalculer les lightmaps"
#: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp
msgid "Cell"
-msgstr ""
+msgstr "Cellule"
#: modules/gridmap/grid_map.cpp
#, fuzzy
@@ -17619,7 +17499,7 @@ msgstr "Centre"
#: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp
#: scene/resources/material.cpp
msgid "Mask"
-msgstr ""
+msgstr "Masque"
#: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp
#, fuzzy
@@ -17798,19 +17678,19 @@ msgstr "Précalculer les lightmaps"
#: modules/lightmapper_cpu/register_types.cpp
msgid "Low Quality Ray Count"
-msgstr ""
+msgstr "Nombre de rayons de basse qualité"
#: modules/lightmapper_cpu/register_types.cpp
msgid "Medium Quality Ray Count"
-msgstr ""
+msgstr "Nombre de rayons de qualité moyenne"
#: modules/lightmapper_cpu/register_types.cpp
msgid "High Quality Ray Count"
-msgstr ""
+msgstr "Nombre de rayons de haute qualité"
#: modules/lightmapper_cpu/register_types.cpp
msgid "Ultra Quality Ray Count"
-msgstr ""
+msgstr "Nombre de rayons de qualité extrême"
#: modules/minimp3/audio_stream_mp3.cpp
#: modules/minimp3/resource_importer_mp3.cpp
@@ -17820,17 +17700,17 @@ msgid "Loop Offset"
msgstr "Décalage de Boucle"
#: modules/mobile_vr/mobile_vr_interface.cpp
+#, fuzzy
msgid "Eye Height"
-msgstr ""
+msgstr "Hauteur de l’œil"
#: modules/mobile_vr/mobile_vr_interface.cpp
msgid "IOD"
msgstr ""
#: modules/mobile_vr/mobile_vr_interface.cpp
-#, fuzzy
msgid "Display Width"
-msgstr "Affichage en fil de fer"
+msgstr "Afficher la largeur"
#: modules/mobile_vr/mobile_vr_interface.cpp
#, fuzzy
@@ -17858,9 +17738,8 @@ msgid "Build Solution"
msgstr "Compiler la solution"
#: modules/mono/editor/csharp_project.cpp
-#, fuzzy
msgid "Auto Update Project"
-msgstr "Projet sans titre"
+msgstr "Mettre à jour le projet automatiquement"
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
@@ -17938,17 +17817,17 @@ msgid "Seamless"
msgstr ""
#: modules/opensimplex/noise_texture.cpp
-#, fuzzy
msgid "As Normal Map"
-msgstr "Échelle aléatoire :"
+msgstr "En tant que carte de normales"
#: modules/opensimplex/noise_texture.cpp
+#, fuzzy
msgid "Bump Strength"
-msgstr ""
+msgstr "Force du bossage"
#: modules/opensimplex/noise_texture.cpp
msgid "Noise"
-msgstr ""
+msgstr "Bruit"
#: modules/opensimplex/noise_texture.cpp
#, fuzzy
@@ -17956,12 +17835,13 @@ msgid "Noise Offset"
msgstr "Décalage de la grille :"
#: modules/opensimplex/open_simplex_noise.cpp
+#, fuzzy
msgid "Octaves"
-msgstr ""
+msgstr "Octaves"
#: modules/opensimplex/open_simplex_noise.cpp
msgid "Period"
-msgstr ""
+msgstr "Période"
#: modules/opensimplex/open_simplex_noise.cpp
#, fuzzy
@@ -17973,8 +17853,9 @@ msgid "Lacunarity"
msgstr ""
#: modules/regex/regex.cpp
+#, fuzzy
msgid "Subject"
-msgstr ""
+msgstr "Sujet"
#: modules/regex/regex.cpp
#, fuzzy
@@ -17996,7 +17877,7 @@ msgstr ""
#: modules/upnp/upnp.cpp
msgid "Discover IPv6"
-msgstr ""
+msgstr "Découvrir IPv6"
#: modules/upnp/upnp_device.cpp
#, fuzzy
@@ -18696,7 +18577,7 @@ msgstr "Sous-appel"
#: modules/visual_script/visual_script_nodes.cpp scene/gui/graph_node.cpp
msgid "Title"
-msgstr ""
+msgstr "Titre"
#: modules/visual_script/visual_script_nodes.cpp
msgid "Construct %s"
@@ -18766,19 +18647,20 @@ msgstr "Mode prioritaire"
#: modules/webrtc/webrtc_data_channel.h
msgid "WebRTC"
-msgstr ""
+msgstr "WebRTC"
#: modules/webrtc/webrtc_data_channel.h
+#, fuzzy
msgid "Max Channel In Buffer (KB)"
-msgstr ""
+msgstr "Maximum de canal dans le tampon (Ko)"
#: modules/websocket/websocket_client.cpp
msgid "Verify SSL"
-msgstr ""
+msgstr "Vérifier la SSL"
#: modules/websocket/websocket_client.cpp
msgid "Trusted SSL Certificate"
-msgstr ""
+msgstr "Certificat SSL Fiable"
#: modules/websocket/websocket_macros.h
#, fuzzy
@@ -18791,8 +18673,9 @@ msgid "Max In Buffer (KB)"
msgstr "Taille Maximale (KB)"
#: modules/websocket/websocket_macros.h
+#, fuzzy
msgid "Max In Packets"
-msgstr ""
+msgstr "Maximum par paquet"
#: modules/websocket/websocket_macros.h
#, fuzzy
@@ -18819,7 +18702,7 @@ msgstr "Chemin de la clé privée SSH"
#: modules/websocket/websocket_server.cpp platform/javascript/export/export.cpp
msgid "SSL Certificate"
-msgstr ""
+msgstr "Certificat SSL"
#: modules/websocket/websocket_server.cpp
#, fuzzy
@@ -18869,7 +18752,7 @@ msgstr "Magnétisme intelligent"
#: platform/android/export/export.cpp
msgid "Android SDK Path"
-msgstr ""
+msgstr "Chemin du SDK Android"
#: platform/android/export/export.cpp
#, fuzzy
@@ -18893,20 +18776,21 @@ msgid "Shutdown ADB On Exit"
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid "Launcher Icons"
-msgstr ""
+msgstr "Icônes du lanceur"
#: platform/android/export/export_plugin.cpp
msgid "Main 192 X 192"
-msgstr ""
+msgstr "Principal 192 X 192"
#: platform/android/export/export_plugin.cpp
msgid "Adaptive Foreground 432 X 432"
-msgstr ""
+msgstr "Avant-Plan Adaptatif 432 X 432"
#: platform/android/export/export_plugin.cpp
msgid "Adaptive Background 432 X 432"
-msgstr ""
+msgstr "Arrière-Plan Adaptatif 432 X 432"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -18938,18 +18822,28 @@ msgid "The package must have at least one '.' separator."
msgstr "Le paquet doit comporter au moins un séparateur « . »."
#: platform/android/export/export_plugin.cpp
+msgid "Custom Build"
+msgstr "Construction personnalisé"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
-msgstr ""
+msgstr "Utiliser une construction personnalisé"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Export Format"
-msgstr "Chemin d'exportation"
+msgstr "Format d'exportation"
+
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr "Min SDK"
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr "SDK Cible"
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
-#, fuzzy
msgid "Architectures"
-msgstr "Ajouter une entrée architecture"
+msgstr "Architectures"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -18977,26 +18871,17 @@ msgid "Release Password"
msgstr "Mot de passe"
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid "One Click Deploy"
-msgstr ""
+msgstr "Déploiement en un clic"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Clear Previous Install"
-msgstr "Inspecter l'instance précédente"
+msgstr "Nettoyer l'installation précédente"
#: platform/android/export/export_plugin.cpp
msgid "Code"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr "SDK Minimal"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Cible"
+msgstr "Code"
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
@@ -19018,7 +18903,7 @@ msgstr "Classer En Tant Que Jeu"
#: platform/android/export/export_plugin.cpp
msgid "Retain Data On Uninstall"
-msgstr ""
+msgstr "Conserver les données lors de la désinstallation"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -19026,24 +18911,20 @@ msgid "Exclude From Recents"
msgstr "Supprimer des nœuds"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Graphics"
-msgstr "Décalage de la grille :"
+msgstr "Graphismes"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "OpenGL Debug"
-msgstr "Ouvrir"
+msgstr "Débogage OpenGL"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "XR Features"
-msgstr "Fonctionnalités"
+msgstr "Fonctionnalités XR"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "XR Mode"
-msgstr "Mode navigation"
+msgstr "Mode XR"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -19059,9 +18940,8 @@ msgid "Passthrough"
msgstr ""
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Immersive Mode"
-msgstr "Mode prioritaire"
+msgstr "Mode immersif"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -19090,12 +18970,11 @@ msgstr "Interface utilisateur"
#: platform/android/export/export_plugin.cpp
msgid "Allow"
-msgstr ""
+msgstr "Autoriser"
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
-#, fuzzy
msgid "Command Line"
-msgstr "Communauté"
+msgstr "Ligne de commande"
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Extra Args"
@@ -19108,22 +18987,19 @@ msgstr "Expression"
#: platform/android/export/export_plugin.cpp
msgid "Salt"
-msgstr ""
+msgstr "Sel"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Public Key"
-msgstr "Chemin de la clé publique SSH"
+msgstr "Clé Publique"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Permissions"
-msgstr "Masque d'émission"
+msgstr "Permissions"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Custom Permissions"
-msgstr "Jouer une scène personnalisée"
+msgstr "Permissions Personnalisées"
#: platform/android/export/export_plugin.cpp
msgid "Select device from the list"
@@ -19243,6 +19119,11 @@ msgid ""
"Note that the singleton was also renamed from \"GodotPayments\" to "
"\"GodotGooglePlayBilling\"."
msgstr ""
+"Le module \"GodotPaymentV3\" inclus dans les paramètres du projet à "
+"\"android/modules\" est invalide (Changé dans Godot 3.2.2).\n"
+"Remplacez-le avec le plugin tiers \"GodotGooglePlayBilling\".\n"
+"Notez que ce singleton a aussi été renommé de \"GodotPayments\" en "
+"\"GodotGooglePlayBilling\"."
#: platform/android/export/export_plugin.cpp
msgid "\"Use Custom Build\" must be enabled to use the plugins."
@@ -19250,17 +19131,16 @@ msgstr "« Use Custom Build » doit être activé pour utiliser les plugins."
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
-"« Hand Tracking » est valide uniquement lorsque le « Mode Xr » est « Oculus "
+"« Hand Tracking » est valide uniquement lorsque le « Mode XR » est « Oculus "
"Mobile VrApi »."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
-"« Passthrough » est valide uniquement lorsque le « Xr Mode » est « Oculus "
-"Mobile VrApi »."
+"« Passthrough » est valide uniquement lorsque le « Mode XR » est « OpenXR »."
#: platform/android/export/export_plugin.cpp
msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
@@ -19270,24 +19150,52 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
-"Changer « Min Sdk » est valide uniquement lorsque l'option « Use Custom "
+"Changer « Min SDK » est valide uniquement lorsque l'option « Use Custom "
"Build » est activée."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+"\"Min SDK\" devrait être un nombre entier valide, mais \"%s\" n'est pas "
+"valide."
+
+#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
-"Changer « Target Sdk » est valide uniquement lorsque l'option « Use Custom "
+"« Min SDK » ne peut être inférieur à %d, la version requise par la libraire "
+"de Godot."
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+"Changer « Target SDK » est valide uniquement lorsque l'option « Use Custom "
"Build » est activée."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
-"La version « Target Sdk » doit être supérieure ou égale à la version « Min "
-"Sdk »."
+"« SDK Cible » devrait être un nombre entier valide, mais « %s » n'en est pas "
+"un."
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+"« SDK Cible » %d est plus grande que la version par défaut %d. Cela pourrait "
+"fonctionner, mais ça n'a pas été testé. Le résultat pourrait être instable."
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
+msgstr ""
+"La version « Target SDK » doit être supérieure ou égale à la version « Min "
+"SDK »."
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
#: platform/windows/export/export.cpp
@@ -19485,19 +19393,19 @@ msgstr ""
#: platform/iphone/export/export.cpp
msgid "iPhone 2436 X 1125"
-msgstr ""
+msgstr "iPhone 2436 X 1125"
#: platform/iphone/export/export.cpp
msgid "iPhone 2208 X 1242"
-msgstr ""
+msgstr "iPhone 2208 X 1242"
#: platform/iphone/export/export.cpp
msgid "iPad 1024 X 768"
-msgstr ""
+msgstr "iPad 1024 X 768"
#: platform/iphone/export/export.cpp
msgid "iPad 2048 X 1536"
-msgstr ""
+msgstr "iPad 2048 X 1536"
#: platform/iphone/export/export.cpp
msgid "Portrait Launch Screens"
@@ -19505,31 +19413,31 @@ msgstr ""
#: platform/iphone/export/export.cpp
msgid "iPhone 640 X 960"
-msgstr ""
+msgstr "iPhone 640 X 960"
#: platform/iphone/export/export.cpp
msgid "iPhone 640 X 1136"
-msgstr ""
+msgstr "iPhone 640 X 1136"
#: platform/iphone/export/export.cpp
msgid "iPhone 750 X 1334"
-msgstr ""
+msgstr "iPhone 750 X 1334"
#: platform/iphone/export/export.cpp
msgid "iPhone 1125 X 2436"
-msgstr ""
+msgstr "iPhone 1125 X 2436"
#: platform/iphone/export/export.cpp
msgid "iPad 768 X 1024"
-msgstr ""
+msgstr "iPad 768 X 1024"
#: platform/iphone/export/export.cpp
msgid "iPad 1536 X 2048"
-msgstr ""
+msgstr "iPad 1536 X 2048"
#: platform/iphone/export/export.cpp
msgid "iPhone 1242 X 2208"
-msgstr ""
+msgstr "iPhone 1242 X 2208"
#: platform/iphone/export/export.cpp
msgid "App Store Team ID"
@@ -19562,37 +19470,34 @@ msgid "Export Method Release"
msgstr "Mode d'exportation :"
#: platform/iphone/export/export.cpp
+#, fuzzy
msgid "Targeted Device Family"
-msgstr ""
+msgstr "Famille de système cible"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
msgid "Info"
-msgstr ""
+msgstr "Info"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
msgid "Identifier"
msgstr "Identifiant"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Signature"
-msgstr "Signaux"
+msgstr "Signature"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Short Version"
-msgstr "Version"
+msgstr "Version courte"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Copyright"
-msgstr "En haut à droite"
+msgstr "Copyright"
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Capabilities"
-msgstr "Coller les propriétés"
+msgstr "Capacités"
#: platform/iphone/export/export.cpp
msgid "Access Wi-Fi"
@@ -19604,9 +19509,8 @@ msgid "Push Notifications"
msgstr "Rotation aléatoire :"
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "User Data"
-msgstr "Interface utilisateur"
+msgstr "Données Utilisateur"
#: platform/iphone/export/export.cpp
msgid "Accessible From Files App"
@@ -19617,9 +19521,8 @@ msgid "Accessible From iTunes Sharing"
msgstr ""
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Privacy"
-msgstr "Chemin de la clé privée SSH"
+msgstr "Confidentialité"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
#, fuzzy
@@ -19637,20 +19540,21 @@ msgid "Photolibrary Usage Description"
msgstr "Description des propriétés"
#: platform/iphone/export/export.cpp
+#, fuzzy
msgid "iPhone 120 X 120"
-msgstr ""
+msgstr "iPhone 120 X 120"
#: platform/iphone/export/export.cpp
msgid "iPhone 180 X 180"
-msgstr ""
+msgstr "iPhone 180 X 180"
#: platform/iphone/export/export.cpp
msgid "iPad 76 X 76"
-msgstr ""
+msgstr "iPad 76 X 76"
#: platform/iphone/export/export.cpp
msgid "iPad 152 X 152"
-msgstr ""
+msgstr "iPad 152 X 152"
#: platform/iphone/export/export.cpp
msgid "iPad 167 X 167"
@@ -19692,25 +19596,21 @@ msgid "Custom Image @3x"
msgstr "Nœud Personnalisé"
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Use Custom BG Color"
-msgstr "Nœud Personnalisé"
+msgstr "Utiliser la couleur d'arrière-plan personnalisée"
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Custom BG Color"
-msgstr "Nœud Personnalisé"
+msgstr "Couleur d'arrière-plan personnalisée"
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Prepare Templates"
-msgstr "Gérer les modèles"
+msgstr "Préparer les modèles"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Export template not found."
-msgstr "Modèle de version personnalisée introuvable."
+msgstr "Modèle d'exportation introuvable."
#: platform/iphone/export/export.cpp
msgid "App Store Team ID not specified - cannot configure the project."
@@ -19733,29 +19633,24 @@ msgid "Run exported HTML in the system's default browser."
msgstr "Exécutez le HTML exporté dans le navigateur par défaut du système."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not open template for export: \"%s\"."
-msgstr "Impossible d'ouvrir le modèle pour exportation :"
+msgstr "Impossible d'ouvrir le modèle pour exportation : « %s »."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Invalid export template: \"%s\"."
-msgstr "Modèle d'exportation non valide :"
+msgstr "Modèle d'exportation invalide : « %s »."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not write file: \"%s\"."
-msgstr "Impossible d'écrire le fichier :"
+msgstr "Impossible d'écrire le fichier : « %s »."
#: platform/javascript/export/export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Icon Creation"
-msgstr "Définir la marge"
+msgstr "Création de l'icône"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not read file: \"%s\"."
-msgstr "Impossible de lire le fichier :"
+msgstr "Impossible de lire le fichier : «%s »."
#: platform/javascript/export/export.cpp
msgid "PWA"
@@ -19766,36 +19661,32 @@ msgid "Variant"
msgstr "Variant"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Export Type"
-msgstr "Exporter"
+msgstr "Type d'exportation"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "VRAM Texture Compression"
-msgstr "Expression"
+msgstr "Compression des textures dans la mémoire vidéo"
#: platform/javascript/export/export.cpp
msgid "For Desktop"
-msgstr ""
+msgstr "Pour PC"
#: platform/javascript/export/export.cpp
msgid "For Mobile"
-msgstr ""
+msgstr "Pour Mobile"
#: platform/javascript/export/export.cpp
msgid "HTML"
-msgstr ""
+msgstr "HTML"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Export Icon"
-msgstr "Développer tout"
+msgstr "Icône d'exportation"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Custom HTML Shell"
-msgstr "Nœud Personnalisé"
+msgstr "Shell HTML personnalisé"
#: platform/javascript/export/export.cpp
msgid "Head Include"
@@ -19810,65 +19701,60 @@ msgid "Focus Canvas On Start"
msgstr ""
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Experimental Virtual Keyboard"
-msgstr "Filtrer les signaux"
+msgstr "Clavier virtuel expérimental"
#: platform/javascript/export/export.cpp
msgid "Progressive Web App"
-msgstr ""
+msgstr "Application web progressive"
#: platform/javascript/export/export.cpp
msgid "Offline Page"
-msgstr ""
+msgstr "Page hors ligne"
#: platform/javascript/export/export.cpp
msgid "Icon 144 X 144"
-msgstr ""
+msgstr "Icône 144 X 144"
#: platform/javascript/export/export.cpp
msgid "Icon 180 X 180"
-msgstr ""
+msgstr "Icône 180 X 180"
#: platform/javascript/export/export.cpp
msgid "Icon 512 X 512"
-msgstr ""
+msgstr "Icône 512 X 512"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not read HTML shell: \"%s\"."
-msgstr "Impossible de lire le shell HTML :"
+msgstr "Impossible de lire le shell HTML : « %s »."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not create HTTP server directory: %s."
-msgstr "Impossible de créer le répertoire du serveur HTTP :"
+msgstr "Impossible de créer le répertoire du serveur HTTP : %s."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Error starting HTTP server: %d."
-msgstr "Erreur de démarrage du serveur HTTP :"
+msgstr "Erreur de démarrage du serveur HTTP : %d."
#: platform/javascript/export/export.cpp
msgid "Web"
-msgstr ""
+msgstr "Web"
#: platform/javascript/export/export.cpp
msgid "HTTP Host"
-msgstr ""
+msgstr "Hôte HTTP"
#: platform/javascript/export/export.cpp
msgid "HTTP Port"
-msgstr ""
+msgstr "Port HTTP"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Use SSL"
-msgstr "Utiliser l’aimantation"
+msgstr "Utiliser SSL"
#: platform/javascript/export/export.cpp
msgid "SSL Key"
-msgstr ""
+msgstr "Clé SSL"
#: platform/osx/export/codesign.cpp
msgid "Can't get filesystem access."
@@ -19896,7 +19782,7 @@ msgstr "Échec de création du sous-dossier « %s »."
#: platform/osx/export/codesign.cpp
msgid "Failed to extract thin binary."
-msgstr ""
+msgstr "Échec lors de l'extraction du binaire."
#: platform/osx/export/codesign.cpp
msgid "Invalid binary format."
@@ -19913,7 +19799,7 @@ msgstr "Impossible de charger la ressource."
#: platform/osx/export/codesign.cpp
msgid "Failed to create _CodeSignature subfolder."
-msgstr ""
+msgstr "Échec lors de la création du sous-dossier _CodeSignature."
#: platform/osx/export/codesign.cpp
#, fuzzy
@@ -19930,29 +19816,30 @@ msgid "Invalid executable file."
msgstr "Fichier exécutable invalide."
#: platform/osx/export/codesign.cpp
+#, fuzzy
msgid "Can't resize signature load command."
-msgstr ""
+msgstr "Impossible de redimensionner la commande de chargement des signatures."
#: platform/osx/export/codesign.cpp
msgid "Failed to create fat binary."
-msgstr ""
+msgstr "Échec lors de la création du binaire."
#: platform/osx/export/codesign.cpp
msgid "Unknown bundle type."
-msgstr ""
+msgstr "Type de paquet inconnu."
#: platform/osx/export/codesign.cpp
msgid "Unknown object type."
msgstr "Type d'objet inconnu."
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "App Category"
-msgstr "Catégorie :"
+msgstr "Catégorie de l'application"
#: platform/osx/export/export.cpp
+#, fuzzy
msgid "High Res"
-msgstr ""
+msgstr "Haute Résolution"
#: platform/osx/export/export.cpp
#, fuzzy
@@ -20032,7 +19919,7 @@ msgstr "Nœud Personnalisé"
#: platform/osx/export/export.cpp
msgid "Allow JIT Code Execution"
-msgstr ""
+msgstr "Autoriser l'exécution du code JIT"
#: platform/osx/export/export.cpp
msgid "Allow Unsigned Executable Memory"
@@ -20043,27 +19930,24 @@ msgid "Allow Dyld Environment Variables"
msgstr ""
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Disable Library Validation"
-msgstr "Bouton désactivé"
+msgstr "Désactiver la validation des librairies"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Audio Input"
-msgstr "Ajouter une entrée"
+msgstr "Entrée Audio"
#: platform/osx/export/export.cpp
msgid "Address Book"
-msgstr ""
+msgstr "Carnet d'Adresses"
#: platform/osx/export/export.cpp
msgid "Calendars"
-msgstr ""
+msgstr "Calendrier"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Photos Library"
-msgstr "Bibliothèque d'exportation"
+msgstr "Bibliothèque de photos"
#: platform/osx/export/export.cpp
#, fuzzy
@@ -20076,8 +19960,9 @@ msgid "Debugging"
msgstr "Débogage"
#: platform/osx/export/export.cpp
+#, fuzzy
msgid "App Sandbox"
-msgstr ""
+msgstr "Bac à sable de l'application"
#: platform/osx/export/export.cpp
#, fuzzy
@@ -20165,18 +20050,24 @@ msgid ""
"The notarization process generally takes less than an hour. When the process "
"is completed, you'll receive an email."
msgstr ""
+"Le processus de certification prend généralement moins d'une heure. Quand le "
+"processus sera achevé, vous recevrez un e-mail."
#: platform/osx/export/export.cpp
msgid ""
"You can check progress manually by opening a Terminal and running the "
"following command:"
msgstr ""
+"Vous pouvez contrôler la progression manuellement en ouvrant un Terminal et "
+"en exécutant la commande suivante :"
#: platform/osx/export/export.cpp
msgid ""
"Run the following command to staple the notarization ticket to the exported "
"application (optional):"
msgstr ""
+"Exécutez la commande suivante pour lier le ticket de certification avec "
+"l'application exporté (optionnel) :"
#: platform/osx/export/export.cpp
msgid "Timestamping is not compatible with ad-hoc signature, and was disabled!"
@@ -20200,6 +20091,8 @@ msgid ""
"Could not start codesign executable, make sure Xcode command line tools are "
"installed."
msgstr ""
+"Ne peut lancer l'exécutable codesign, vérifiez que les outils en ligne de "
+"commande de Xcode sont installés."
#: platform/osx/export/export.cpp platform/windows/export/export.cpp
msgid "No identity found."
@@ -20213,6 +20106,8 @@ msgstr "Erreur lors de l'enregistrement du fichier : %s"
#: platform/osx/export/export.cpp
msgid "Relative symlinks are not supported, exported \"%s\" might be broken!"
msgstr ""
+"Les liens symboliques relatifs ne sont pas supportés, « %s » pourrait être "
+"cassé !"
#: platform/osx/export/export.cpp
#, fuzzy
@@ -20225,12 +20120,13 @@ msgid "Could not start hdiutil executable."
msgstr "Impossible de démarrer le sous-processus !"
#: platform/osx/export/export.cpp
+#, fuzzy
msgid "`hdiutil create` failed - file exists."
-msgstr ""
+msgstr "`hdiutil create` a échoué - le fichier existe."
#: platform/osx/export/export.cpp
msgid "`hdiutil create` failed."
-msgstr ""
+msgstr "`hdiutil create` a échoué."
#: platform/osx/export/export.cpp
#, fuzzy
@@ -20252,12 +20148,16 @@ msgid ""
"Relative symlinks are not supported on this OS, the exported project might "
"be broken!"
msgstr ""
+"Les liens symboliques relatifs ne sont pas supportés sur ce système "
+"d'exploitation, le projet exporté pourrait être cassé !"
#: platform/osx/export/export.cpp
msgid ""
"Requested template binary \"%s\" not found. It might be missing from your "
"template archive."
msgstr ""
+"Le binaire modèle requis « %s » n'a pas été trouvé. Il doit être absent de "
+"votre archive de modèles."
#: platform/osx/export/export.cpp
msgid "Making PKG"
@@ -20290,10 +20190,12 @@ msgid ""
"Notarization requires the app to be archived first, select the DMG or ZIP "
"export format instead."
msgstr ""
+"La certification nécessite que l'application soit préalablement archivé. "
+"Sélectionnez le format d'exportation DMG ou ZIP à la place."
#: platform/osx/export/export.cpp
msgid "Sending archive for notarization"
-msgstr ""
+msgstr "Envoi de l'archive pour la certification"
#: platform/osx/export/export.cpp
#, fuzzy
@@ -20314,16 +20216,23 @@ msgid ""
"Warning: Built-in \"codesign\" is selected in the Editor Settings. Code "
"signing is limited to ad-hoc signature only."
msgstr ""
+"Attention : Le « codesign » embarqué est sélectionné dans les paramètres de "
+"l'éditeur. La signature du code se limite à la signature ad-hoc seulement."
#: platform/osx/export/export.cpp
msgid ""
"Warning: Xcode command line tools are not installed, using built-in "
"\"codesign\". Code signing is limited to ad-hoc signature only."
msgstr ""
+"Attention : Les outils en ligne de commande de Xcode ne sont pas installés, "
+"utilisation du « codesign » embarqué. La signature du code se limite à la "
+"signature ad-hoc seulement."
#: platform/osx/export/export.cpp
msgid "Notarization: Notarization with an ad-hoc signature is not supported."
msgstr ""
+"Certification : La certification avec une signature ad-hoc n'est pas "
+"supporté."
#: platform/osx/export/export.cpp
#, fuzzy
@@ -20353,12 +20262,17 @@ msgid ""
"Warning: Notarization is disabled. The exported project will be blocked by "
"Gatekeeper if it's downloaded from an unknown source."
msgstr ""
+"Attention : La certification est désactivé. Le projet exporté sera bloqué "
+"par Gatekeeper si il est téléchargé depuis une source inconnue."
#: platform/osx/export/export.cpp
msgid ""
"Code signing is disabled. The exported project will not run on Macs with "
"enabled Gatekeeper and Apple Silicon powered Macs."
msgstr ""
+"La signature du code est désactivé. Le projet exporté ne fonctionnera pas "
+"sur les Macs avec Gatekeeper activé et sous les Macs fonctionnant sous Apple "
+"Silicon."
#: platform/osx/export/export.cpp
msgid ""
@@ -20376,6 +20290,9 @@ msgid ""
"Warning: Notarization is not supported from this OS. The exported project "
"will be blocked by Gatekeeper if it's downloaded from an unknown source."
msgstr ""
+"Attention : La certification n'est pas compatible avec ce système "
+"d'exploitation. Le projet exporté sera bloqué par Gatekeeper si il est "
+"téléchargé depuis une source inconnue."
#: platform/osx/export/export.cpp
msgid ""
@@ -20425,7 +20342,7 @@ msgstr ""
#: platform/osx/export/export.cpp
msgid "macOS"
-msgstr ""
+msgstr "macOS"
#: platform/osx/export/export.cpp
msgid "Force Builtin Codesign"
@@ -20480,11 +20397,11 @@ msgstr "Débogueur"
#: platform/uwp/export/export.cpp
msgid "Major"
-msgstr ""
+msgstr "Majeur"
#: platform/uwp/export/export.cpp
msgid "Minor"
-msgstr ""
+msgstr "Mineur"
#: platform/uwp/export/export.cpp
#, fuzzy
@@ -20498,7 +20415,7 @@ msgstr "Expression"
#: platform/uwp/export/export.cpp
msgid "Landscape"
-msgstr ""
+msgstr "Paysage"
#: platform/uwp/export/export.cpp
#, fuzzy
@@ -20507,11 +20424,11 @@ msgstr "Retourner les Portals"
#: platform/uwp/export/export.cpp
msgid "Landscape Flipped"
-msgstr ""
+msgstr "Paysage Inversé"
#: platform/uwp/export/export.cpp
msgid "Portrait Flipped"
-msgstr ""
+msgstr "Portrait Inversé"
#: platform/uwp/export/export.cpp
#, fuzzy
@@ -20520,23 +20437,23 @@ msgstr "Mode mise à l'échelle"
#: platform/uwp/export/export.cpp
msgid "Square 44 X 44 Logo"
-msgstr ""
+msgstr "Logo 44 X 44 Carré"
#: platform/uwp/export/export.cpp
msgid "Square 71 X 71 Logo"
-msgstr ""
+msgstr "Logo 71 X 71 Carré"
#: platform/uwp/export/export.cpp
msgid "Square 150 X 150 Logo"
-msgstr ""
+msgstr "Logo 150 X 150 Carré"
#: platform/uwp/export/export.cpp
msgid "Square 310 X 310 Logo"
-msgstr ""
+msgstr "Logo 310 X 310 Carré"
#: platform/uwp/export/export.cpp
msgid "Wide 310 X 150 Logo"
-msgstr ""
+msgstr "Logo 310 X 150 Large"
#: platform/uwp/export/export.cpp
#, fuzzy
@@ -20550,15 +20467,15 @@ msgstr "Fichier"
#: platform/uwp/export/export.cpp
msgid "Show Name On Square 150 X 150"
-msgstr ""
+msgstr "Afficher le nom sur le carré 150 X 150"
#: platform/uwp/export/export.cpp
msgid "Show Name On Wide 310 X 150"
-msgstr ""
+msgstr "Afficher le nom sur le large 310 X 150"
#: platform/uwp/export/export.cpp
msgid "Show Name On Square 310 X 310"
-msgstr ""
+msgstr "Afficher le nom sur le carré 310 X 310"
#: platform/uwp/export/export.cpp
msgid "Invalid package short name."
@@ -20627,7 +20544,7 @@ msgstr ""
#: platform/uwp/export/export.cpp
msgid "UWP"
-msgstr ""
+msgstr "UWP"
#: platform/uwp/export/export.cpp platform/windows/export/export.cpp
#, fuzzy
@@ -20636,7 +20553,7 @@ msgstr "Signaux"
#: platform/uwp/export/export.cpp
msgid "Debug Certificate"
-msgstr ""
+msgstr "Certificat de Débogage"
#: platform/uwp/export/export.cpp
#, fuzzy
@@ -20649,8 +20566,9 @@ msgid "Failed to rename temporary file \"%s\"."
msgstr "Impossible de supprimer le fichier temporaire :"
#: platform/windows/export/export.cpp
+#, fuzzy
msgid "Identity Type"
-msgstr ""
+msgstr "Type d'identité"
#: platform/windows/export/export.cpp
msgid "Timestamp Server URL"
@@ -20690,7 +20608,7 @@ msgstr "Description"
#: platform/windows/export/export.cpp
msgid "Trademarks"
-msgstr ""
+msgstr "Marques Déposées"
#: platform/windows/export/export.cpp
#, fuzzy
@@ -20722,6 +20640,8 @@ msgid ""
"rcedit failed to modify executable:\n"
"%s"
msgstr ""
+"rcedit n'a pas réussi à modifier l'exécutable :\n"
+"%s"
#: platform/windows/export/export.cpp
#, fuzzy
@@ -21000,7 +20920,7 @@ msgstr "Zoomer"
msgid "Custom Viewport"
msgstr "1 vue"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21575,12 +21495,12 @@ msgstr "Bouton désactivé"
#: scene/2d/joints_2d.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp
msgid "Softness"
-msgstr ""
+msgstr "Douceur"
#: scene/2d/joints_2d.cpp scene/resources/animation.cpp
#: scene/resources/ray_shape.cpp scene/resources/segment_shape_2d.cpp
msgid "Length"
-msgstr ""
+msgstr "Longueur"
#: scene/2d/joints_2d.cpp
#, fuzzy
@@ -21593,7 +21513,7 @@ msgstr ""
#: scene/2d/joints_2d.cpp scene/3d/physics_joint.cpp scene/3d/vehicle_body.cpp
msgid "Stiffness"
-msgstr ""
+msgstr "Rigidité"
#: scene/2d/light_2d.cpp
msgid ""
@@ -21617,15 +21537,15 @@ msgstr "RegionDeTexture"
#: scene/3d/light.cpp scene/resources/environment.cpp
#: scene/resources/material.cpp scene/resources/sky.cpp
msgid "Energy"
-msgstr ""
+msgstr "Énergie"
#: scene/2d/light_2d.cpp
msgid "Z Min"
-msgstr ""
+msgstr "Minimum Z"
#: scene/2d/light_2d.cpp
msgid "Z Max"
-msgstr ""
+msgstr "Maximum Z"
#: scene/2d/light_2d.cpp
#, fuzzy
@@ -21696,7 +21616,7 @@ msgstr "Défaut"
#: scene/2d/line_2d.cpp scene/resources/texture.cpp
msgid "Fill"
-msgstr ""
+msgstr "Remplissage"
#: scene/2d/line_2d.cpp scene/resources/texture.cpp
#, fuzzy
@@ -21709,8 +21629,9 @@ msgid "Texture Mode"
msgstr "RegionDeTexture"
#: scene/2d/line_2d.cpp
+#, fuzzy
msgid "Capping"
-msgstr ""
+msgstr "Recouvrement"
#: scene/2d/line_2d.cpp
#, fuzzy
@@ -21738,7 +21659,7 @@ msgstr ""
#: scene/2d/line_2d.cpp
msgid "Round Precision"
-msgstr ""
+msgstr "Précision de l’arrondissement"
#: scene/2d/line_2d.cpp scene/2d/polygon_2d.cpp
#: scene/resources/dynamic_font.cpp
@@ -21755,34 +21676,36 @@ msgstr "Multiplier %s"
#: scene/3d/navigation.cpp scene/animation/root_motion_view.cpp
#: scene/resources/world_2d.cpp servers/physics_2d/physics_2d_server_sw.cpp
msgid "Cell Size"
-msgstr ""
+msgstr "Taille des Cellules"
#: scene/2d/navigation_2d.cpp scene/3d/navigation.cpp
#, fuzzy
msgid "Edge Connection Margin"
msgstr "Modifier la connexion :"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
-msgstr ""
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
+"Le nœud « Navigation2D » et « Navigation2D.get_simple_path() » sont "
+"obsolètes et seront supprimés dans une future version. Utilisez « "
+"Navigation2DServer.map_get_path() » à la place."
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Liaison"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
-msgid "Time Horizon"
-msgstr "Retourner horizontalement"
+msgid "Path Desired Distance"
+msgstr "Choisissez distance :"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Max Speed"
-msgstr "Vitesse :"
+msgid "Target Desired Distance"
+msgstr "Distance Désirée de la Cible"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
@@ -21791,9 +21714,31 @@ msgstr "Choisissez distance :"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
+msgid "Avoidance"
+msgstr "Options avancées"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
msgid "Avoidance Enabled"
msgstr "Activer"
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr "Distance des voisins"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr "Maximum de voisins"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Time Horizon"
+msgstr "Retourner horizontalement"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr "Vitesse Max"
+
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21801,9 +21746,8 @@ msgid ""
msgstr "Le NavigationAgent2D ne peut être utilisé que sous un nœud Node2D."
#: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_obstacle.cpp
-#, fuzzy
msgid "Estimate Radius"
-msgstr "Changer le rayon extérieur de la tour"
+msgstr "Estimer le rayon"
#: scene/2d/navigation_obstacle_2d.cpp
msgid ""
@@ -21841,57 +21785,50 @@ msgstr "Se déplacer"
msgid "Rotation Degrees"
msgstr "Degrés de Rotation"
-#: scene/2d/node_2d.cpp
-#, fuzzy
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
-msgstr "Constante globale"
+msgstr "Rotation Globale"
#: scene/2d/node_2d.cpp
msgid "Global Rotation Degrees"
msgstr "Degrés de Rotation Globale"
#: scene/2d/node_2d.cpp
-#, fuzzy
msgid "Global Scale"
-msgstr "Échelle aléatoire :"
+msgstr "Échelle Globale"
#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
-#, fuzzy
msgid "Global Transform"
-msgstr "Conserver la transformation globale"
+msgstr "Transformation Globale"
#: scene/2d/node_2d.cpp
-#, fuzzy
msgid "Z As Relative"
-msgstr "Alignement relatif"
+msgstr "Z En tant que relatif"
#: scene/2d/parallax_background.cpp scene/gui/scroll_container.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Scroll"
-msgstr ""
+msgstr "Défilement"
#: scene/2d/parallax_background.cpp
-#, fuzzy
msgid "Base Offset"
-msgstr "Décalage :"
+msgstr "Décalage de Base"
#: scene/2d/parallax_background.cpp
-#, fuzzy
msgid "Base Scale"
-msgstr "Utiliser le magnétisme d'échelle"
+msgstr "Échelle de Base"
#: scene/2d/parallax_background.cpp
msgid "Limit Begin"
-msgstr ""
+msgstr "Début de la limite"
#: scene/2d/parallax_background.cpp
-#, fuzzy
msgid "Limit End"
-msgstr "À la fin"
+msgstr "Fin de la limite"
#: scene/2d/parallax_background.cpp
msgid "Ignore Camera Zoom"
-msgstr ""
+msgstr "Ignorer le zoom de la Caméra"
#: scene/2d/parallax_layer.cpp
msgid ""
@@ -21903,9 +21840,8 @@ msgstr ""
#: scene/2d/parallax_layer.cpp scene/2d/physics_body_2d.cpp
#: scene/3d/physics_body.cpp scene/3d/vehicle_body.cpp
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Motion"
-msgstr "Action"
+msgstr "Déplacement"
#: scene/2d/parallax_layer.cpp
#, fuzzy
@@ -21954,19 +21890,17 @@ msgstr ""
"Animation » activé."
#: scene/2d/particles_2d.cpp
-#, fuzzy
msgid "Visibility Rect"
-msgstr "Mode prioritaire"
+msgstr "Zone de Visibilité"
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid "Process Material"
-msgstr ""
+msgstr "Matériau"
#: scene/2d/path_2d.cpp scene/3d/path.cpp scene/resources/sky.cpp
#: scene/resources/texture.cpp
-#, fuzzy
msgid "Curve"
-msgstr "Scinder la courbe"
+msgstr "Courbe"
#: scene/2d/path_2d.cpp
msgid "PathFollow2D only works when set as a child of a Path2D node."
@@ -21980,58 +21914,51 @@ msgid "Unit Offset"
msgstr "Décalage de la grille :"
#: scene/2d/path_2d.cpp scene/3d/camera.cpp scene/3d/path.cpp
-#, fuzzy
msgid "H Offset"
-msgstr "Décalage :"
+msgstr "Décalage Horizontal"
#: scene/2d/path_2d.cpp scene/3d/camera.cpp scene/3d/path.cpp
-#, fuzzy
msgid "V Offset"
-msgstr "Décalage :"
+msgstr "Décalage Vertical"
#: scene/2d/path_2d.cpp scene/3d/path.cpp
msgid "Cubic Interp"
-msgstr ""
+msgstr "Interpolation Cubique"
#: scene/2d/path_2d.cpp
msgid "Lookahead"
msgstr ""
#: scene/2d/physics_body_2d.cpp scene/3d/visual_instance.cpp
-#, fuzzy
msgid "Layers"
-msgstr "Calque"
+msgstr "Calques"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Constant Linear Velocity"
-msgstr "Initialiser"
+msgstr "Vélocité Linéaire Constante"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Constant Angular Velocity"
-msgstr "Initialiser"
+msgstr "Vélocité Angulaire Constante"
#: scene/2d/physics_body_2d.cpp scene/2d/tile_map.cpp scene/3d/physics_body.cpp
#: scene/resources/physics_material.cpp
-#, fuzzy
msgid "Friction"
-msgstr "Fonction"
+msgstr "Friction"
#: scene/2d/physics_body_2d.cpp scene/2d/tile_map.cpp scene/3d/physics_body.cpp
#: scene/resources/physics_material.cpp
msgid "Bounce"
-msgstr ""
+msgstr "Rebond"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
msgid "Physics Material Override"
-msgstr ""
+msgstr "Surcharge du Matériau Des Physiques"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#: scene/resources/world.cpp scene/resources/world_2d.cpp
-#, fuzzy
msgid "Default Gravity"
-msgstr "Aperçu par défaut"
+msgstr "Gravité par Défaut"
#: scene/2d/physics_body_2d.cpp
msgid ""
@@ -22045,21 +21972,19 @@ msgstr ""
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
msgid "Mass"
-msgstr ""
+msgstr "Masse"
#: scene/2d/physics_body_2d.cpp
-#, fuzzy
msgid "Inertia"
-msgstr "Vertical :"
+msgstr "Inertie"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Weight"
-msgstr "Lumière"
+msgstr "Poids"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
msgid "Gravity Scale"
-msgstr ""
+msgstr "Échelle de la Gravité"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#, fuzzy
@@ -22073,44 +21998,40 @@ msgstr "Continu"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
msgid "Contacts Reported"
-msgstr ""
+msgstr "Contact Rapporté"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Contact Monitor"
-msgstr "Prélever une couleur"
+msgstr "Moniteur de Contact"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Sleeping"
-msgstr "Magnétisme intelligent"
+msgstr "Sommeil"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Can Sleep"
-msgstr "Vitesse :"
+msgstr "Peut Dormir"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
msgid "Damp"
-msgstr ""
+msgstr "Atténuation"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
msgid "Angular"
-msgstr ""
+msgstr "Angulaire"
#: scene/2d/physics_body_2d.cpp
msgid "Applied Forces"
-msgstr ""
+msgstr "Forces Appliquées"
#: scene/2d/physics_body_2d.cpp
msgid "Torque"
msgstr ""
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Safe Margin"
-msgstr "Définir la marge"
+msgstr "Marge de sécurité"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
msgid "Sync To Physics"
@@ -22129,9 +22050,8 @@ msgstr ""
#: scene/3d/physics_body.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
#: scene/resources/line_shape_2d.cpp scene/resources/material.cpp
-#, fuzzy
msgid "Normal"
-msgstr "Format"
+msgstr "Normale"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#, fuzzy
@@ -22139,61 +22059,53 @@ msgid "Remainder"
msgstr "Moteur de rendu :"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Local Shape"
-msgstr "Localisation"
+msgstr "Forme Locale"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collider"
-msgstr "Mode collision"
+msgstr "Collisionneur"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#: servers/physics_2d_server.cpp servers/physics_server.cpp
msgid "Collider ID"
-msgstr ""
+msgstr "ID Du Collisionneur"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collider RID"
-msgstr "RID invalide"
+msgstr "RID Du Collisionneur"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collider Shape"
-msgstr "Mode collision"
+msgstr "Forme Du Collisionneur"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Collider Shape Index"
-msgstr "Mode collision"
+msgstr "Index De La Forme Du Collisionneur"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collider Velocity"
-msgstr "Vue de l'orbite vers la droite"
+msgstr "Vélocité Du Collisionneur"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
msgid "Collider Metadata"
-msgstr ""
+msgstr "Méta-Données Du Collisionneur"
#: scene/2d/polygon_2d.cpp
msgid "Invert"
-msgstr ""
+msgstr "Inverser"
#: scene/2d/polygon_2d.cpp
-#, fuzzy
msgid "Vertex Colors"
-msgstr "Vertex"
+msgstr "Couleurs Des Sommets"
#: scene/2d/polygon_2d.cpp
-#, fuzzy
msgid "Internal Vertex Count"
-msgstr "Créer un vertex interne"
+msgstr "Nombre de Sommet Interne"
#: scene/2d/position_2d.cpp
#, fuzzy
@@ -22202,7 +22114,7 @@ msgstr "Gadgets"
#: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp
msgid "Exclude Parent"
-msgstr ""
+msgstr "Exclure Le Parent"
#: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp
#, fuzzy
@@ -22211,7 +22123,7 @@ msgstr "Créer un nœud Shader"
#: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp
msgid "Collide With"
-msgstr ""
+msgstr "Collisionne Avec"
#: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp
msgid "Areas"
@@ -22219,7 +22131,7 @@ msgstr ""
#: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp
msgid "Bodies"
-msgstr ""
+msgstr "Corps"
#: scene/2d/remote_transform_2d.cpp
msgid "Path property must point to a valid Node2D node to work."
@@ -22323,51 +22235,44 @@ msgid "Y Sort"
msgstr "Trier"
#: scene/2d/tile_map.cpp
-#, fuzzy
msgid "Show Collision"
-msgstr "Collision"
+msgstr "Afficher la Collision"
#: scene/2d/tile_map.cpp
-#, fuzzy
msgid "Compatibility Mode"
-msgstr "Mode prioritaire"
+msgstr "Mode de Compatibilité"
#: scene/2d/tile_map.cpp
-#, fuzzy
msgid "Centered Textures"
-msgstr "Fonctionnalités principales :"
+msgstr "Textures Centrées"
#: scene/2d/tile_map.cpp
msgid "Cell Clip UV"
msgstr ""
#: scene/2d/tile_map.cpp
-#, fuzzy
msgid "Use Parent"
-msgstr "Mode collision"
+msgstr "Utiliser le Parent"
#: scene/2d/tile_map.cpp
msgid "Use Kinematic"
-msgstr ""
+msgstr "Utiliser Kinematic"
#: scene/2d/touch_screen_button.cpp
-#, fuzzy
msgid "Shape Centered"
-msgstr "Aimanter au centre du nœud"
+msgstr "Forme Centrée"
#: scene/2d/touch_screen_button.cpp
-#, fuzzy
msgid "Shape Visible"
-msgstr "Rendre visible"
+msgstr "Forme Visible"
#: scene/2d/touch_screen_button.cpp
msgid "Passby Press"
msgstr ""
#: scene/2d/touch_screen_button.cpp
-#, fuzzy
msgid "Visibility Mode"
-msgstr "Mode prioritaire"
+msgstr "Mode de Visibilité"
#: scene/2d/visibility_notifier_2d.cpp
msgid ""
@@ -22384,7 +22289,7 @@ msgstr "Coller l'animation"
#: scene/2d/visibility_notifier_2d.cpp scene/3d/visibility_notifier.cpp
msgid "Freeze Bodies"
-msgstr ""
+msgstr "Geler les corps"
#: scene/2d/visibility_notifier_2d.cpp
#, fuzzy
@@ -22397,22 +22302,20 @@ msgid "Pause Animated Sprites"
msgstr "Coller l'animation"
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid "Process Parent"
-msgstr "Activer la priorité"
+msgstr "Parent du Processus"
#: scene/2d/visibility_notifier_2d.cpp
msgid "Physics Process Parent"
-msgstr ""
+msgstr "Parent du Processus Physique"
#: scene/3d/area.cpp
msgid "Reverb Bus"
msgstr ""
#: scene/3d/area.cpp
-#, fuzzy
msgid "Uniformity"
-msgstr "Définir le nom de l'uniforme"
+msgstr "Uniformité"
#: scene/3d/arvr_nodes.cpp
msgid "ARVRCamera must have an ARVROrigin node as its parent."
@@ -22420,7 +22323,7 @@ msgstr "ARVRCamera doit avoir un nœud ARVROrigin comme parent."
#: scene/3d/arvr_nodes.cpp
msgid "Controller ID"
-msgstr ""
+msgstr "ID Du Contrôleur"
#: scene/3d/arvr_nodes.cpp servers/arvr/arvr_positional_tracker.cpp
msgid "Rumble"
@@ -22460,9 +22363,8 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin requiert un nœud enfant ARVRCamera."
#: scene/3d/arvr_nodes.cpp servers/arvr_server.cpp
-#, fuzzy
msgid "World Scale"
-msgstr "Échelle aléatoire :"
+msgstr "Échelle du Monde"
#: scene/3d/audio_stream_player_3d.cpp
#, fuzzy
@@ -22888,7 +22790,7 @@ msgstr "Aimanter au pixel"
#: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp
msgid "Billboard"
-msgstr ""
+msgstr "Billboard"
#: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp
#, fuzzy
@@ -23056,6 +22958,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformation annulée."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23987,6 +23896,11 @@ msgstr ""
"Modifiez les tailles dans les formes de collision enfants à la place."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Transformation Globale"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25231,6 +25145,11 @@ msgstr "Dossier :"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Sélection uniquement"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Activer"
@@ -25632,18 +25551,6 @@ msgstr "Chemin d'exportation"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Ce Viewport n'est pas sélectionné comme cible de rendu. Si vous avez "
-"l'intention d'afficher son contenu directement à l'écran, rattachez-le à un "
-"nœud de type Control afin qu'il en obtienne une taille. Sinon, faites-en une "
-"RenderTarget et assignez sa texture à un nœud pouvant l'afficher."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25651,6 +25558,15 @@ msgstr ""
"dans les deux sens pour que le rendu soit possible."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27103,14 +27019,12 @@ msgid "Point Size"
msgstr "Vue de devant"
#: scene/resources/material.cpp
-#, fuzzy
msgid "Billboard Mode"
-msgstr "Mode Règle"
+msgstr "Mode billboard"
#: scene/resources/material.cpp
-#, fuzzy
msgid "Billboard Keep Scale"
-msgstr "Mode Règle"
+msgstr "Garder l'échelle du billboard"
#: scene/resources/material.cpp
msgid "Grow"
@@ -27168,7 +27082,7 @@ msgstr ""
#: scene/resources/material.cpp
msgid "Rim"
-msgstr ""
+msgstr "Bordure"
#: scene/resources/material.cpp
#, fuzzy
@@ -27400,6 +27314,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Générer AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Décalage :"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
index 884214d851..db42dda6ed 100644
--- a/editor/translations/ga.po
+++ b/editor/translations/ga.po
@@ -393,6 +393,11 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Scagairí..."
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -445,6 +450,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5291,6 +5300,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7598,11 +7611,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7620,11 +7642,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7767,10 +7784,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17820,6 +17833,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Cruthaigh"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17827,6 +17845,15 @@ msgstr ""
msgid "Export Format"
msgstr ""
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Nód Cumaisc2"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17863,15 +17890,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Nód Cumaisc2"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18093,12 +18111,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18107,17 +18125,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19656,7 +19694,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20331,35 +20369,55 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Ãbhar:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Pathfinding"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Path Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Scagairí..."
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
msgid "Avoidance Enabled"
msgstr "Scagairí..."
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20399,7 +20457,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21452,6 +21510,13 @@ msgstr ""
msgid "Transform Normals"
msgstr ""
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22271,6 +22336,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Athrú: "
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23373,6 +23443,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Scagairí..."
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Scagairí..."
@@ -23734,16 +23809,17 @@ msgstr "Cosán"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25350,6 +25426,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/gl.po b/editor/translations/gl.po
index 398746ea6a..b42b50e5a7 100644
--- a/editor/translations/gl.po
+++ b/editor/translations/gl.po
@@ -425,6 +425,11 @@ msgstr ""
msgid "Command"
msgstr "Comunidade"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fotograma de Física %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -483,6 +488,10 @@ msgid "Pressure"
msgstr "Axustes de Importación"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Axuste Relativo"
@@ -5642,6 +5651,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Encadrar Selección"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8091,11 +8105,20 @@ msgid "New Anim"
msgstr "Nova Animación"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Renomear Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Eliminar Animación?"
@@ -8113,11 +8136,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Renomear Animación"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplicar Animación"
@@ -8261,10 +8279,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nome da Animación:"
@@ -18796,6 +18810,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Cortar Nodos"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18804,6 +18823,16 @@ msgstr ""
msgid "Export Format"
msgstr "Formato"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Tamaño: "
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Obxectivo"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18843,16 +18872,6 @@ msgstr "Anterior Pestana"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Tamaño: "
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Obxectivo"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19102,12 +19121,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19116,17 +19135,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20782,7 +20821,7 @@ msgstr "Aumentar Zoom"
msgid "Custom Viewport"
msgstr "1 Ventá"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21515,11 +21554,42 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Editar Conexión:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Pegar Animación"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Elexir unha Escena Principal"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Avanzado"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Activar"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21537,15 +21607,6 @@ msgstr "Horizontal:"
msgid "Max Speed"
msgstr "Velocidade:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Activar"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21588,7 +21649,7 @@ msgstr "Viaxe"
msgid "Rotation Degrees"
msgstr "Rotando % graos."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Constante"
@@ -22752,6 +22813,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformación"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23648,6 +23716,11 @@ msgstr ""
"lugar."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Transformación"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24868,6 +24941,11 @@ msgstr "Cartafol:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Só a Selección"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Activar"
@@ -25264,18 +25342,6 @@ msgid "Viewport Path"
msgstr "1 Ventá"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Esta Mini-Ventá (Viewport) no está configurada como obxectivo de "
-"renderizado. Se quere que o seu contido se mostre directamente na pantalla, "
-"convértao nun nodo fillo dun nodo Control para que poida recibir dimensións. "
-"Ou ben, fágao un RenderTarget e asigne a súa textura a algún nodo."
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -25285,6 +25351,15 @@ msgstr ""
"renderizar nada."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27026,6 +27101,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Offset:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/he.po b/editor/translations/he.po
index 78c74fd01b..a89d117ead 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -423,6 +423,11 @@ msgstr ""
msgid "Command"
msgstr "פיקוד"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "פיזיקה"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -478,6 +483,10 @@ msgid "Pressure"
msgstr "לחץ"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "GDNative"
@@ -5557,6 +5566,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "GridMap מילוי הבחירה"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8059,11 +8073,20 @@ msgid "New Anim"
msgstr "הנפשה חדשה"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "יצירת הנפשה חדשה"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "שינוי ×©× ×”× ×¤×©×”:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "שינוי ×©× ×”× ×¤×©×”"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "מחיקת ×נימציה?"
@@ -8081,11 +8104,6 @@ msgid "Animation name already exists!"
msgstr "×©× ×”×”× ×¤×©×” כבר ×§×™×™×!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "שינוי ×©× ×”× ×¤×©×”"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "שכפול הנפשה"
@@ -8229,10 +8247,6 @@ msgid "Pin AnimationPlayer"
msgstr "הצמדת AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "יצירת הנפשה חדשה"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "×©× ×”× ×¤×©×”:"
@@ -18932,6 +18946,11 @@ msgid "The package must have at least one '.' separator."
msgstr "החבילה חייבת לכלול לפחות מפריד '.' ×חד."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "גזירת מפרקי×"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18940,6 +18959,16 @@ msgstr ""
msgid "Export Format"
msgstr "×™×™×¦×•× ×ž×™×–×"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "מבט קדמי"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "נתיב המש×ב"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18980,16 +19009,6 @@ msgstr "בדיקת המופע הקוד×"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "מבט קדמי"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "נתיב המש×ב"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19244,13 +19263,13 @@ msgstr "חובה ל×פשר ״שימוש בבניה מות×מת ×ישית״ ×›
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr "\"Hand Tracking\" תקף רק ×›×שר \"מצב Xr\" ×”×•× \"Oculus Mobile VR\"."
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr "\"Hand Tracking\" תקף רק ×›×שר \"מצב Xr\" ×”×•× \"Oculus Mobile VR\"."
#: platform/android/export/export_plugin.cpp
@@ -19259,17 +19278,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20942,7 +20981,7 @@ msgstr "התקרבות"
msgid "Custom Viewport"
msgstr "מבט תחתי"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21676,11 +21715,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "עריכת חיבור:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "קישור"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "בחירת מרחק:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "בחירת מרחק:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "מתקד×"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "הפעלה"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21697,16 +21768,6 @@ msgstr ""
msgid "Max Speed"
msgstr "מהירות (FPS):"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "בחירת מרחק:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "הפעלה"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21751,7 +21812,7 @@ msgstr "טיול"
msgid "Rotation Degrees"
msgstr "הטיה של %s מעלות."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "קבוע"
@@ -22927,6 +22988,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "התמרה"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23826,6 +23894,11 @@ msgstr ""
"×‘×ž×§×•× ×–×ת יש לשנות ×ת גודל צורות ההתנגשות של הצ×צ××™×."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "התמרה"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25055,6 +25128,11 @@ msgstr "יצירת תיקייה"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "בחירה בלבד"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "הפעלה"
@@ -25457,17 +25535,6 @@ msgid "Viewport Path"
msgstr "×™×™×¦×•× ×ž×™×–×"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"חלון תצוגה ×–×” ×ינו מוגדר כיעד עיבוד. להצגת התוכן ישירות למסך, יש להפוך ×ותו "
-"לצ××¦× ×©×œ בקר כדי שיקבל גודל. ×ו להפוך ×ותו ל-RenderTarget ולשייך ×ת ×”×ž×¨×§× "
-"הפנימי שלו למפרק כלשהו לתצוגה."
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -25475,6 +25542,15 @@ msgid ""
msgstr "גודל חלון התצוגה חייב להיות גדול מ-0 על מנת להציג משהו."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27220,6 +27296,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "היסט רשת:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 2486887cac..a598e43071 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -406,6 +406,11 @@ msgstr ""
msgid "Command"
msgstr "समà¥à¤¦à¤¾à¤¯"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "फिजिकà¥à¤¸ फà¥à¤°à¥‡à¤® %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -461,6 +466,10 @@ msgid "Pressure"
msgstr "पà¥à¤°à¥€à¤¸à¥‡à¤Ÿ"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5562,6 +5571,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "सभी खंड"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7982,11 +7996,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -8004,11 +8027,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8151,10 +8169,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18576,6 +18590,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18584,6 +18603,16 @@ msgstr ""
msgid "Export Format"
msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ परिवरà¥à¤¤à¤¨ परिणत"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "आकार: "
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "नोड हटाà¤à¤‚"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18622,16 +18651,6 @@ msgstr "पिछला टैब"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "आकार: "
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "नोड हटाà¤à¤‚"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18872,12 +18891,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18886,17 +18905,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20534,7 +20573,7 @@ msgstr "बड़ा करो"
msgid "Custom Viewport"
msgstr "वà¥à¤¯à¥‚पोरà¥à¤Ÿ चà¥à¤¨à¥‡à¤‚"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21238,34 +21277,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "कनेकà¥à¤¶à¤¨ संपादित करें:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "à¤à¤• मà¥à¤–à¥à¤¯ दृशà¥à¤¯ चà¥à¤¨à¥‡à¤‚"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "अगà¥à¤°à¤µà¤°à¥à¤¤à¥€"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "सकà¥à¤°à¤¿à¤¯ करे"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "सकà¥à¤°à¤¿à¤¯ करे"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21306,7 +21367,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
@@ -22410,6 +22471,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "सदसà¥à¤¯à¤¤à¤¾ बनाà¤à¤‚"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23274,6 +23342,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ परिवरà¥à¤¤à¤¨ परिणत"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24452,6 +24525,11 @@ msgstr "फ़ोलà¥à¤¡à¤°:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "सिरà¥à¤« चयन किये हà¥à¤"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "सकà¥à¤°à¤¿à¤¯ करे"
@@ -24846,16 +24924,17 @@ msgstr "फ़ोकस पाथ"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26567,6 +26646,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "मिटाना"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index c9a87722f5..61aeaeeb10 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -408,6 +408,11 @@ msgstr ""
msgid "Command"
msgstr "Zajednica"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Omogući"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -460,6 +465,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5381,6 +5390,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Izbriši Odabir"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7754,11 +7768,20 @@ msgid "New Anim"
msgstr "Nova Animacija"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Kreiraj Novu Animaciju"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Promijeni Ime Animacije:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Preimenuj animaciju"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Obrisati Animaciju?"
@@ -7776,11 +7799,6 @@ msgid "Animation name already exists!"
msgstr "Animacija sa ovim imenom već postoji!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Preimenuj animaciju"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Dupliciraj Animaciju"
@@ -7923,10 +7941,6 @@ msgid "Pin AnimationPlayer"
msgstr "Pinuj AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Kreiraj Novu Animaciju"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Ime Animacije:"
@@ -18135,6 +18149,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Pomakni Bezier ToÄke"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18143,6 +18162,16 @@ msgstr ""
msgid "Export Format"
msgstr "Izvoz"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Glavna skripta:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Premjesti Ävor(node)"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18179,16 +18208,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Glavna skripta:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Premjesti Ävor(node)"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18419,12 +18438,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18433,17 +18452,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20025,7 +20064,7 @@ msgstr "Zumiraj"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20719,34 +20758,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Uredi vezu:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Zalijepi Animaciju"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Instaliraj"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Napredno"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Omogući"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Omogući"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -20787,7 +20848,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21869,6 +21930,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "NaÄin Ravnala"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22719,6 +22787,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Uredi Tranzicije..."
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23864,6 +23937,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Samo odabir"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Omogući"
@@ -24241,16 +24319,17 @@ msgstr "Put"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25931,6 +26010,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Promijeni vrstu baze:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index 5ee85051da..9f0d894b2a 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -445,6 +445,11 @@ msgstr ""
msgid "Command"
msgstr "Közösség"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fizika Keret %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -502,6 +507,10 @@ msgid "Pressure"
msgstr "Előre beállított"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Relatív Illesztés"
@@ -5670,6 +5679,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Kijelölés Keretezése"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8130,11 +8144,20 @@ msgid "New Anim"
msgstr "Új Animáció"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Új Animáció Létrehozása"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Animáció Nevének Megváltoztatása:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Animáció Ãtnevezése"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Animáció Törlése?"
@@ -8152,11 +8175,6 @@ msgid "Animation name already exists!"
msgstr "Az animáció név már létezik!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Animáció Ãtnevezése"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Animáció Megkettőzése"
@@ -8301,10 +8319,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Új Animáció Létrehozása"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Animáció Neve:"
@@ -18763,6 +18777,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Node-ok kivágása"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18771,6 +18790,16 @@ msgstr ""
msgid "Export Format"
msgstr "Exportálási Útvonal"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Körvonal Mérete:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Cél Felület:"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18810,16 +18839,6 @@ msgstr "Előző lap"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Körvonal Mérete:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Cél Felület:"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19065,12 +19084,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19079,17 +19098,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20740,7 +20779,7 @@ msgstr "Nagyítás"
msgid "Custom Viewport"
msgstr "Nézet Megjelenítése"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21467,34 +21506,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Kapcsolat szerkesztése:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Véletlenszerű Forgatás:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Válasszon egy Fő Jelenetet"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Speciális"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Engedélyezés"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Engedélyezés"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21538,7 +21599,7 @@ msgstr "Utazás"
msgid "Rotation Degrees"
msgstr "Forgatási Léptetés:"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Ãllandó"
@@ -22682,6 +22743,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Ãtalakítás Megszakítva."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23564,6 +23632,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Globális Transzformáció Megtartása"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24778,6 +24851,11 @@ msgstr "Mappa:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Csak kijelölés"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Engedélyezés"
@@ -25180,20 +25258,17 @@ msgstr "Exportálási Útvonal"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
-"Ez a nézetablak nincs beállítva leképezési célnak. Ha azt szeretné, hogy a "
-"tartalma közvetlenül a képernyőn jelenjen meg, tegye azt egy Control "
-"gyermekévé, hogy így kapjon méretet. Ellenkező esetben tegye RenderTarget-"
-"té, és állítsa hozzá a belső textúráját valamilyen node-hoz kirajzolásra."
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26941,6 +27016,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "AABB Generálása"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Rács Eltolás:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 4788d2a7c2..24547a7464 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -26,7 +26,7 @@
# Ade Fikri Malihuddin <ade.fm97@gmail.com>, 2020.
# zephyroths <ridho.hikaru@gmail.com>, 2020, 2021, 2022.
# Richard Urban <redasuio1@gmail.com>, 2020.
-# yusuf afandi <afandi.yusuf.04@gmail.com>, 2020.
+# yusuf afandi <afandi.yusuf.04@gmail.com>, 2020, 2022.
# Habib Rohman <revolusi147id@gmail.com>, 2020.
# Hanz <hanzhaxors@gmail.com>, 2021.
# Reza Almanda <rezaalmanda27@gmail.com>, 2021, 2022.
@@ -44,8 +44,8 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-05-15 09:38+0000\n"
-"Last-Translator: Tsaqib Fadhlurrahman Soka <sokatsaqib@gmail.com>\n"
+"PO-Revision-Date: 2022-07-09 21:12+0000\n"
+"Last-Translator: yusuf afandi <afandi.yusuf.04@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -53,7 +53,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -425,6 +425,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Perintah"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (Secara fisik)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -476,6 +481,11 @@ msgid "Pressure"
msgstr "Tekanan"
#: core/os/input_event.cpp
+#, fuzzy
+msgid "Pen Inverted"
+msgstr "Balik"
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relatif"
@@ -5601,6 +5611,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr "Tombol Ekstra Mouse Navigasi Riwayat"
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Isi Seleksi GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "Penampilan"
@@ -8036,11 +8051,20 @@ msgid "New Anim"
msgstr "Animasi Baru"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Buat Animasi Baru"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Ubah Nama Animasi:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Ubah Nama Animasi"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Hapus Animasi?"
@@ -8058,11 +8082,6 @@ msgid "Animation name already exists!"
msgstr "Nama animasi sudah ada!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Ubah Nama Animasi"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Gandakan Animasi"
@@ -8206,10 +8225,6 @@ msgid "Pin AnimationPlayer"
msgstr "Sematkan AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Buat Animasi Baru"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nama Animasi:"
@@ -18874,6 +18889,11 @@ msgstr "Package setidaknya harus memiliki sebuah pemisah '.'."
#: platform/android/export/export_plugin.cpp
#, fuzzy
+msgid "Custom Build"
+msgstr "Gunakan Direktori Pengguna Kustom"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid "Use Custom Build"
msgstr "Gunakan Direktori Pengguna Kustom"
@@ -18882,6 +18902,16 @@ msgstr "Gunakan Direktori Pengguna Kustom"
msgid "Export Format"
msgstr "Lokasi Ekspor"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Ukuran Garis Tepi:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "FPS Sasaran"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18924,16 +18954,6 @@ msgstr "Inspeksi Instance Sebelumnya"
msgid "Code"
msgstr "Kode"
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Ukuran Garis Tepi:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "FPS Sasaran"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19174,7 +19194,7 @@ msgstr "\"Gunakan Build Custom\" harus diaktifkan untuk menggunakan plugin."
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Pelacakan Tangan\" hanya valid ketika \"Mode Xr\" bernilai \"Oculus Mobile "
@@ -19182,7 +19202,7 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"\"Pelacakan Tangan\" hanya valid ketika \"Mode Xr\" bernilai \"Oculus Mobile "
"VR\"."
@@ -19195,20 +19215,41 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Expor AAB\" hanya bisa valid ketika \"Gunakan Build Custom\" diaktifkan."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Expor AAB\" hanya bisa valid ketika \"Gunakan Build Custom\" diaktifkan."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"Versi \"Target SDK\" harus lebih tinggi atau sama dengan versi \"Min SDK\"."
@@ -20881,7 +20922,7 @@ msgstr "Perbesar Pandangan"
msgid "Custom Viewport"
msgstr "Penampil Kustom"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21618,11 +21659,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Sunting Koneksi:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Mengikat"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Target Jarak yang Diinginkan"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr "Target Jarak yang Diinginkan"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Pilih Jarak:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Lanjut"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Aktifkan"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21639,16 +21712,6 @@ msgstr "Balik secara Horizontal"
msgid "Max Speed"
msgstr "Kecepatan Maks"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Pilih Jarak:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Aktifkan"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21695,7 +21758,7 @@ msgstr "Menjelajah"
msgid "Rotation Degrees"
msgstr "Derajat Putaran"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr "Rotasi Global"
@@ -22849,6 +22912,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformasi Dibatalkan."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr "Vektor Atas"
@@ -23757,6 +23827,11 @@ msgstr ""
"Ubah ukurannya melalui \"collision shape\"-anaknya saja."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Transformasi Global"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr "Matriks"
@@ -24677,7 +24752,7 @@ msgstr ""
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Caret"
-msgstr ""
+msgstr "Tanda sisipan"
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Blink"
@@ -25018,6 +25093,11 @@ msgstr "Direktori:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Hanya yang Dipilih"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Aktifkan"
@@ -25424,19 +25504,6 @@ msgid "Viewport Path"
msgstr "Lokasi Ekspor"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Viewport ini tidak diatur sebagai target render. Jika anda berniat untuk "
-"menampilkan konten-kontennya secara langsung ke layar, jadikan viewport ini "
-"sebagai child dari sebuah Control agar ia bisa memperoleh ukuran. Jika "
-"tidak, jadikan sebagai RenderTarget dan tetapkan tekstur internal nya ke "
-"beberapa node untuk ditampilkan."
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -25444,6 +25511,15 @@ msgid ""
msgstr "Ukuran viewport harus lebih besar dari 0 untuk me-render apa pun."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27214,6 +27290,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Membuat AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Pengimbangan:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/is.po b/editor/translations/is.po
index ea3301ce7f..b7eb0e4b88 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -401,6 +401,10 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr ""
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -453,6 +457,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5368,6 +5376,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Allt úrvalið"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7707,11 +7720,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7729,11 +7751,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7877,10 +7894,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18081,6 +18094,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Tvíteknir lyklar"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18089,6 +18107,15 @@ msgstr ""
msgid "Export Format"
msgstr "Breyta umbreytingu"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Anim DELETE-lyklar"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18125,15 +18152,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Anim DELETE-lyklar"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18361,12 +18379,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18375,17 +18393,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19932,7 +19970,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20617,35 +20655,55 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Breyta Tengingu: "
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Pathfinding"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Path Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Fjarlægja val"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
msgid "Avoidance Enabled"
msgstr "Fjarlægja val"
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20685,7 +20743,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21755,6 +21813,13 @@ msgstr ""
msgid "Transform Normals"
msgstr ""
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22579,6 +22644,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Breyta umbreytingu"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23688,6 +23758,11 @@ msgid "Fold Gutter"
msgstr ""
#: scene/gui/text_edit.cpp
+#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Afrita val"
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr ""
@@ -24059,16 +24134,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25715,6 +25791,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Fjarlægja val"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index c529c06241..36757b891d 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -68,13 +68,14 @@
# Alfonso Scarpino <alfonso.scarpino@gmail.com>, 2022.
# Federico Caprini <caprinifede@gmail.com>, 2022.
# Alessandro Casalino <alessandro.casalino93@gmail.com>, 2022.
+# conecat <ilgrandemax190@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-19 11:52+0000\n"
-"Last-Translator: Mirko <miknsop@gmail.com>\n"
+"PO-Revision-Date: 2022-07-04 05:16+0000\n"
+"Last-Translator: conecat <ilgrandemax190@gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -419,14 +420,12 @@ msgid "Max Size (KB)"
msgstr "Dimensione Massima (KB)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "Modalità spostamento"
+msgstr "Modalità Mouse"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "Elimina Input"
+msgstr "Usa Input Accumulato"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -453,6 +452,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Comando"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (Fisico)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -504,6 +508,10 @@ msgid "Pressure"
msgstr "Pressione"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relativo"
@@ -1237,9 +1245,8 @@ msgid "Animation"
msgstr "Animazione"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Easing"
-msgstr "Easing"
+msgstr "Allentamento"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Time"
@@ -1353,14 +1360,12 @@ msgid "Time (s):"
msgstr "Tempo (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Position:"
-msgstr "Posizione"
+msgstr "Posizione:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rotation:"
-msgstr "Rotazione"
+msgstr "Rotazione:"
#: editor/animation_track_editor.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -1382,9 +1387,8 @@ msgid "(Invalid, expected type: %s)"
msgstr "Template di esportazione non valido:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Easing:"
-msgstr "Easing"
+msgstr "Allentamento:"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -5573,6 +5577,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr "Uso dei tasti aggiuntivi del mouse per navigare la cronologia"
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Selezione GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "Aspetto"
@@ -7930,11 +7939,20 @@ msgid "New Anim"
msgstr "Nuova Animazione"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Crea Nuova Animazione"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Cambia Nome Animazione:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Rinomina Animazione"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Eliminare Animazione?"
@@ -7952,11 +7970,6 @@ msgid "Animation name already exists!"
msgstr "Nome animazione già esistente!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Rinomina Animazione"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplica Animazione"
@@ -8100,10 +8113,6 @@ msgid "Pin AnimationPlayer"
msgstr "Fissa AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Crea Nuova Animazione"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nome Animazione:"
@@ -16241,8 +16250,9 @@ msgid "Flush stdout On Print"
msgstr "Svuota stdout Alla Stampa"
#: main/main.cpp servers/visual_server.cpp
+#, fuzzy
msgid "Logging"
-msgstr ""
+msgstr "Logging"
#: main/main.cpp
msgid "File Logging"
@@ -18562,6 +18572,11 @@ msgid "The package must have at least one '.' separator."
msgstr "Il pacchetto deve avere almeno un \".\" separatore."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Utilizza Build Personalizzata"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr "Utilizza Build Personalizzata"
@@ -18569,6 +18584,14 @@ msgstr "Utilizza Build Personalizzata"
msgid "Export Format"
msgstr "Formato Esportazione"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr "SDK Min"
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr "Target SDK"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18607,14 +18630,6 @@ msgstr "Elimina Installazione Precedente"
msgid "Code"
msgstr "Codice"
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr "SDK Min"
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr "Target SDK"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr "Pacchetto"
@@ -18856,7 +18871,7 @@ msgstr "Per utilizzare i plugin \"Use Custom Build\" deve essere abilitato."
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" è valido solo quando \"Xr Mode\" è impostato su \"Oculus "
@@ -18864,7 +18879,7 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" è valido solo quando \"Xr Mode\" è impostato su \"Oculus "
"Mobile VR\"."
@@ -18877,20 +18892,40 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Export AAB\" è valido soltanto quanto \"Use Custom Build\" è abilitato."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Export AAB\" è valido soltanto quanto \"Use Custom Build\" è abilitato."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -18905,10 +18940,8 @@ msgid ""
"'apksigner' could not be found. Please check that the command is available "
"in the Android SDK build-tools directory. The resulting %s is unsigned."
msgstr ""
-"Non è stato possibile trovare \"apksigner\".\n"
-"Verificare che il comando sia disponibile nella directory degli strumenti di "
-"compilazione Android SDK.\n"
-"Il %s risultato non è firmato."
+"'apksigner' non è stato trovato. Verificare che il comando sia disponibile "
+"nella directory build-tools di Android SDK. Il risultato %s non è firmato."
#: platform/android/export/export_plugin.cpp
msgid "Signing debug %s..."
@@ -19008,9 +19041,8 @@ msgid ""
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
"Compilazione del progetto Android fallita, controlla l'output per vedere gli "
-"errori.\n"
-"In alternativa, visita docs.godotengine.org per la documentazione della "
-"build Android."
+"errori. In alternativa, visita docs.godotengine.org per la documentazione "
+"della build Android."
#: platform/android/export/export_plugin.cpp
msgid "Moving output"
@@ -19045,10 +19077,9 @@ msgid ""
"Please build a template with all required libraries, or uncheck the missing "
"architectures in the export preset."
msgstr ""
-"Mancano librerie nel template di esportazione per le architetture "
-"selezionate: %s.\n"
-"Si prega di costruire un template con tutte le librerie richieste, o "
-"deselezionare le architetture mancanti nel preset di esportazione."
+"Librerie mancanti nel modello di esportazione per le architetture "
+"selezionate: %s. Creare un modello con tutte le librerie richieste o "
+"deselezionare le architetture mancanti nella preimpostazione di esportazione."
#: platform/android/export/export_plugin.cpp
msgid "Adding files..."
@@ -20588,7 +20619,7 @@ msgstr "Ingrandisci"
msgid "Custom Viewport"
msgstr "1 Vista"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -20645,13 +20676,14 @@ msgid "Smoothing"
msgstr "Graduale"
#: scene/2d/camera_2d.cpp
+#, fuzzy
msgid "H"
-msgstr ""
+msgstr "H"
#: scene/2d/camera_2d.cpp
#, fuzzy
msgid "V"
-msgstr "UV"
+msgstr "V"
#: scene/2d/camera_2d.cpp
#, fuzzy
@@ -20962,7 +20994,7 @@ msgstr "Propagazione"
#: scene/resources/particles_material.cpp
#, fuzzy
msgid "Initial Velocity"
-msgstr "Inizializza"
+msgstr "Velocità iniziale"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
@@ -20973,8 +21005,9 @@ msgstr "Velocità"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp servers/physics_2d_server.cpp
#: servers/physics_server.cpp
+#, fuzzy
msgid "Angular Velocity"
-msgstr ""
+msgstr "Velocità angolare"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
@@ -20986,13 +21019,13 @@ msgstr "Velocità"
#: scene/resources/particles_material.cpp
#, fuzzy
msgid "Orbit Velocity"
-msgstr "Orbita la visuale a destra"
+msgstr "Velocità orbitale"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
#, fuzzy
msgid "Linear Accel"
-msgstr "Lineare"
+msgstr "Accelerazione lineare"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
@@ -21013,13 +21046,15 @@ msgstr "Dividi Curva"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
+#, fuzzy
msgid "Radial Accel"
-msgstr ""
+msgstr "Accelerazione radiale"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
+#, fuzzy
msgid "Tangential Accel"
-msgstr ""
+msgstr "Accelerazione tangenziale"
#: scene/2d/cpu_particles_2d.cpp scene/2d/joints_2d.cpp
#: scene/3d/cpu_particles.cpp scene/3d/physics_body.cpp
@@ -21363,11 +21398,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Modifica una connessione:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Associazione"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Scegli la Distanza:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Scegli la Distanza:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Opzioni avanzate"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Abilita"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21385,16 +21452,6 @@ msgstr "Ribalta orizzontalmente"
msgid "Max Speed"
msgstr "Velocità:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Scegli la Distanza:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Abilita"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21440,7 +21497,7 @@ msgstr "Spostamento"
msgid "Rotation Degrees"
msgstr "Rotazione in Gradi"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Costante"
@@ -21858,12 +21915,14 @@ msgstr ""
"Skeleton2D e impostane una."
#: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp
+#, fuzzy
msgid "Hframes"
-msgstr ""
+msgstr "Hframes"
#: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp
+#, fuzzy
msgid "Vframes"
-msgstr ""
+msgstr "Vframes"
#: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp
#, fuzzy
@@ -22121,8 +22180,9 @@ msgstr "Impacchettando"
#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
#: scene/3d/reflection_probe.cpp
+#, fuzzy
msgid "Interior"
-msgstr ""
+msgstr "Interno"
#: scene/3d/baked_lightmap.cpp
msgid "Finding meshes and lights"
@@ -22262,8 +22322,9 @@ msgid "Projection"
msgstr "Proiezione"
#: scene/3d/camera.cpp
+#, fuzzy
msgid "FOV"
-msgstr ""
+msgstr "FOV"
#: scene/3d/camera.cpp
#, fuzzy
@@ -22276,8 +22337,9 @@ msgid "Near"
msgstr "Vicino"
#: scene/3d/camera.cpp
+#, fuzzy
msgid "Far"
-msgstr ""
+msgstr "Lontano"
#: scene/3d/camera.cpp scene/3d/collision_polygon.cpp scene/3d/spring_arm.cpp
#: scene/gui/control.cpp scene/resources/default_theme/default_theme.cpp
@@ -22462,8 +22524,9 @@ msgstr ""
"Per rimuovere questo avviso, disattiva la proprietà Compress di GIProbe."
#: scene/3d/gi_probe.cpp
+#, fuzzy
msgid "Subdiv"
-msgstr ""
+msgstr "Subdiv"
#: scene/3d/gi_probe.cpp
#, fuzzy
@@ -22614,8 +22677,9 @@ msgid "Depth Range"
msgstr "Profondità"
#: scene/3d/light.cpp
+#, fuzzy
msgid "Omni"
-msgstr ""
+msgstr "Omni"
#: scene/3d/light.cpp
#, fuzzy
@@ -22649,6 +22713,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Trasforma Normals"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23348,8 +23419,9 @@ msgid "There should only be one RoomManager in the SceneTree."
msgstr "Ci dovrebbe essere un solo RoomManager nello SceneTree."
#: scene/3d/room_manager.cpp
+#, fuzzy
msgid "Main"
-msgstr ""
+msgstr "Principale"
#: scene/3d/room_manager.cpp scene/animation/animation_blend_tree.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
@@ -23574,6 +23646,11 @@ msgstr ""
"Modifica invece la dimensione nelle forme di collisione figlie."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Mantieni Transform Globale"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23592,8 +23669,9 @@ msgid "Spring Length"
msgstr ""
#: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp
+#, fuzzy
msgid "Opacity"
-msgstr ""
+msgstr "Opacità"
#: scene/3d/sprite_3d.cpp scene/resources/material.cpp
#, fuzzy
@@ -23714,8 +23792,9 @@ msgid "Lightmap Scale"
msgstr ""
#: scene/3d/visual_instance.cpp
+#, fuzzy
msgid "LOD"
-msgstr ""
+msgstr "LOD"
#: scene/3d/visual_instance.cpp scene/animation/skeleton_ik.cpp
#: scene/resources/material.cpp
@@ -24026,8 +24105,9 @@ msgid "Stretch Mode"
msgstr "Modalità di Selezione"
#: scene/gui/aspect_ratio_container.cpp scene/gui/box_container.cpp
+#, fuzzy
msgid "Alignment"
-msgstr ""
+msgstr "Allineamento"
#: scene/gui/base_button.cpp
#, fuzzy
@@ -24812,6 +24892,11 @@ msgstr "Cartella:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Solo nella selezione"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Abilita"
@@ -25219,19 +25304,6 @@ msgstr "Percorso di Esportazione"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Questo viewport non è impostato come target di render. Se si vuole che il "
-"suo contenuto venga direttamente visualizzato sullo schermo, renderlo figlio "
-"di un Control, in modo che possa ottenere una dimensione. Altrimenti, "
-"renderlo un RenderTarget e assegnare la sua texture interna a qualche nodo "
-"per la visualizzazione."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25239,6 +25311,15 @@ msgstr ""
"entrambi i lati per visualizzare qualcosa."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27008,6 +27089,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Generando AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Scostamento:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index 1ae3c9cf8c..5c6358a4c4 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -430,6 +430,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (物ç†çš„)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -482,6 +487,11 @@ msgid "Pressure"
msgstr "圧力"
#: core/os/input_event.cpp
+#, fuzzy
+msgid "Pen Inverted"
+msgstr "å転"
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "相対的"
@@ -5567,6 +5577,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "GridMap ã®é¸æŠž"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "外観"
@@ -7983,11 +7998,20 @@ msgid "New Anim"
msgstr "æ–°è¦ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "アニメーションを新è¦ä½œæˆ"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "アニメーションåを変更:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "アニメーションã®åå‰ã‚’変更"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "アニメーションを削除ã—ã¾ã™ã‹ï¼Ÿ"
@@ -8005,11 +8029,6 @@ msgid "Animation name already exists!"
msgstr "アニメーションåã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ï¼"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "アニメーションã®åå‰ã‚’変更"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "アニメーションを複製"
@@ -8153,10 +8172,6 @@ msgid "Pin AnimationPlayer"
msgstr "アニメーションプレーヤーを固定"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "アニメーションを新è¦ä½œæˆ"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "アニメーションå:"
@@ -18661,6 +18676,11 @@ msgid "The package must have at least one '.' separator."
msgstr "パッケージã«ã¯ä¸€ã¤ä»¥ä¸Šã®åŒºåˆ‡ã‚Šæ–‡å­— '.' ãŒå¿…è¦ã§ã™ã€‚"
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "ノードを切りå–ã‚‹"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18669,6 +18689,15 @@ msgstr ""
msgid "Export Format"
msgstr "エクスãƒãƒ¼ãƒˆå…ˆã®ãƒ‘ス"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "アウトラインã®ã‚µã‚¤ã‚º:"
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr "ターゲットSDK"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18712,15 +18741,6 @@ msgstr "å‰ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’調ã¹ã‚‹"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "アウトラインã®ã‚µã‚¤ã‚º:"
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr "ターゲットSDK"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18968,15 +18988,17 @@ msgstr ""
"ã«ãªã£ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚"
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" 㯠\"Xr Mode\" ㌠\"Oculus Mobile VrApi\" ã¾ãŸã¯ "
"\"OpenXR\" ã®å ´åˆã«ã®ã¿æœ‰åйã§ã™ã€‚"
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr "\"Passthrough\" 㯠\"Xr Mode\" ㌠\"OpenXR\" ã®å ´åˆã«ã®ã¿æœ‰åйã§ã™ã€‚"
#: platform/android/export/export_plugin.cpp
@@ -18985,20 +19007,43 @@ msgstr ""
"\"Export AAB\" 㯠\"Use Custom Build\" ãŒæœ‰åйã§ã‚ã‚‹å ´åˆã«ã®ã¿æœ‰åйã«ãªã‚Šã¾ã™ã€‚"
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Min Sdk\" ã®å¤‰æ›´ã¯ \"Use Custom Build\" ãŒæœ‰åйã§ã‚ã‚‹å ´åˆã«ã®ã¿æœ‰åйã§ã™ã€‚"
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Target Sdk\" ã®å¤‰æ›´ã¯ \"Use Custom Build\" ãŒæœ‰åйã§ã‚ã‚‹å ´åˆã«ã®ã¿æœ‰åйã§ã™ã€‚"
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"\"Target Sdk\" ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ \"Min Sdk\" ãƒãƒ¼ã‚¸ãƒ§ãƒ³ä»¥ä¸Šã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。"
@@ -20681,7 +20726,7 @@ msgstr "ズーム"
msgid "Custom Viewport"
msgstr "1 ビューãƒãƒ¼ãƒˆ"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -21432,11 +21477,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "接続を編集:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "ãƒã‚¤ãƒ³ãƒ‰"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "è·é›¢ã‚’å–å¾—:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "è·é›¢ã‚’å–å¾—:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "高度ãªè¨­å®š"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "有効"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21454,16 +21531,6 @@ msgstr "å·¦å³å転"
msgid "Max Speed"
msgstr "速度:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "è·é›¢ã‚’å–å¾—:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "有効"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21511,7 +21578,7 @@ msgstr "トラベル"
msgid "Rotation Degrees"
msgstr "%s 度回転。"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "コンスタント"
@@ -22718,6 +22785,13 @@ msgstr "ソフトウェアスキニング"
msgid "Transform Normals"
msgstr "トランスフォームã¯ä¸­æ­¢ã•れã¾ã—ãŸã€‚"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23642,6 +23716,11 @@ msgstr ""
"代ã‚りã«ã€å­ã®è¡çªã‚·ã‚§ã‚¤ãƒ—ã®ã‚µã‚¤ã‚ºã‚’変更ã—ã¦ãã ã•ã„。"
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "グローãƒãƒ« ãƒˆãƒ©ãƒ³ã‚¹ãƒ•ã‚©ãƒ¼ãƒ ã‚’ä¿æŒ"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24900,6 +24979,11 @@ msgstr "フォルダー:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "é¸æŠžç¯„å›²ã®ã¿"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "有効"
@@ -25308,22 +25392,19 @@ msgstr "エクスãƒãƒ¼ãƒˆå…ˆã®ãƒ‘ス"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
-"ã“ã®ãƒ“ューãƒãƒ¼ãƒˆã¯ãƒ¬ãƒ³ãƒ€ãƒ¼ ターゲットã¨ã—ã¦è¨­å®šã•れã¦ã„ã¾ã›ã‚“。コンテンツを画"
-"é¢ã«ç›´æŽ¥è¡¨ç¤ºã™ã‚‹å ´åˆã¯ã€ã‚µã‚¤ã‚ºã‚’å–å¾—ã§ãるよã†ã«ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«ã®å­ã«ã—ã¾ã™ã€‚ã"
-"れ以外ã®å ´åˆã¯ã€RenderTarget ã«ã—ã¦ã€ãã®å†…部テクスãƒãƒ£ã‚’表示ã™ã‚‹ãƒŽãƒ¼ãƒ‰ã«å‰²ã‚Š"
-"当ã¦ã¾ã™ã€‚"
+"レンダーã™ã‚‹ã«ã¯Viewportã®ç¸¦æ¨ªãれãžã‚ŒãŒ2ピクセル以上ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚"
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
-"レンダーã™ã‚‹ã«ã¯Viewportã®ç¸¦æ¨ªãれãžã‚ŒãŒ2ピクセル以上ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚"
#: scene/main/viewport.cpp
msgid "ARVR"
@@ -27095,6 +27176,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "AABBを生æˆä¸­"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "オフセット:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index 34914a67b6..f67e7c0bdd 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -407,6 +407,11 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "დáƒáƒ›áƒáƒ™áƒáƒ•შირებელი სიგნáƒáƒšáƒ˜:"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -461,6 +466,10 @@ msgid "Pressure"
msgstr "ზუმის სáƒáƒ¬áƒ§áƒ˜áƒ¡áƒ–ე დáƒáƒ§áƒ”ნებáƒ"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5496,6 +5505,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "ყველრმáƒáƒœáƒ˜áƒ¨áƒœáƒ•áƒ"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7909,11 +7923,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7931,11 +7954,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8079,10 +8097,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18503,6 +18517,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბების áƒáƒ¡áƒšáƒ˜áƒ¡ შექმნáƒ"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18511,6 +18530,16 @@ msgstr ""
msgid "Export Format"
msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ áƒ“áƒáƒ¥áƒ›áƒœáƒ˜áƒ¡ ცვლილებáƒ"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "დáƒáƒ›áƒáƒ™áƒ˜áƒ“ებულებების შემსწáƒáƒ áƒ”ბელი"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "წáƒáƒ¨áƒšáƒ"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18547,16 +18576,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "დáƒáƒ›áƒáƒ™áƒ˜áƒ“ებულებების შემსწáƒáƒ áƒ”ბელი"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "წáƒáƒ¨áƒšáƒ"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18791,12 +18810,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18805,17 +18824,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20411,7 +20450,7 @@ msgstr "ზუმის გáƒáƒ–რდáƒ"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21110,34 +21149,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•ნის მრუდის ცვლილებáƒ"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "მუდმივი"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "დáƒáƒ§áƒ”ნებáƒ"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "დáƒáƒ‘áƒáƒšáƒáƒœáƒ¡áƒ”ბული"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "დáƒáƒ›áƒáƒ™áƒáƒ•შირებელი სიგნáƒáƒšáƒ˜:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "დáƒáƒ›áƒáƒ™áƒáƒ•შირებელი სიგნáƒáƒšáƒ˜:"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21178,7 +21239,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "მუდმივი"
@@ -22273,6 +22334,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "შექმნáƒ"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -23126,6 +23194,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ áƒ“áƒáƒ¥áƒ›áƒœáƒ˜áƒ¡ ცვლილებáƒ"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24286,6 +24359,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "მáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜ მხáƒáƒšáƒáƒ“"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "დáƒáƒ›áƒáƒ™áƒáƒ•შირებელი სიგნáƒáƒšáƒ˜:"
@@ -24668,16 +24746,17 @@ msgstr "გზáƒ"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26366,6 +26445,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•ნის მáƒáƒ¨áƒáƒ áƒ”ბáƒ"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/km.po b/editor/translations/km.po
index 700f4f483c..2da1ccac99 100644
--- a/editor/translations/km.po
+++ b/editor/translations/km.po
@@ -385,6 +385,10 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr ""
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -436,6 +440,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5257,6 +5265,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7545,11 +7557,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7567,11 +7588,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7714,10 +7730,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17719,6 +17731,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Anim ផ្លាស់ប្ážáž¼ážš Transform"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17726,6 +17743,14 @@ msgstr ""
msgid "Export Format"
msgstr ""
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr ""
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17762,14 +17787,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr ""
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -17988,12 +18005,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18002,17 +18019,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19520,7 +19557,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20176,32 +20213,51 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr ""
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Pathfinding"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Desired Distance"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Avoidance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Avoidance Enabled"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Avoidance Enabled"
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp
@@ -20242,7 +20298,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21270,6 +21326,13 @@ msgstr ""
msgid "Transform Normals"
msgstr ""
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22058,6 +22121,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Anim ផ្លាស់ប្ážáž¼ážš Transition"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23134,6 +23202,10 @@ msgid "Fold Gutter"
msgstr ""
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr ""
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr ""
@@ -23486,16 +23558,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25032,6 +25105,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index b4a91e0076..ff2f4ecb80 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -34,13 +34,15 @@
# Taehun Yun <yooontehoon@naver.com>, 2022.
# vrSono <global.sonogong@gmail.com>, 2022.
# Seonghyeon Cho <seonghyeoncho96@gmail.com>, 2022.
+# Haoyu Qiu <timothyqiu32@gmail.com>, 2022.
+# 김태우 <ogosengi3@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-12 13:19+0000\n"
-"Last-Translator: Seonghyeon Cho <seonghyeoncho96@gmail.com>\n"
+"PO-Revision-Date: 2022-06-26 16:16+0000\n"
+"Last-Translator: 김태우 <ogosengi3@gmail.com>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot/ko/>\n"
"Language: ko\n"
@@ -48,7 +50,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -419,6 +421,11 @@ msgstr "메타"
msgid "Command"
msgstr "명령"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (물리)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -470,6 +477,10 @@ msgid "Pressure"
msgstr "ì••ë ¥"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "ìƒëŒ€ì "
@@ -4200,7 +4211,7 @@ msgstr "ë ˆì´ì•„웃 ì‚­ì œ"
#: editor/editor_node.cpp editor/import_dock.cpp
#: editor/script_create_dialog.cpp
msgid "Default"
-msgstr "ë””í´íЏ"
+msgstr "기본값"
#: editor/editor_node.cpp editor/editor_resource_picker.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
@@ -5466,6 +5477,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr "마우스 부가 버튼으로 히스토리 둘러보기"
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "그리드맵 ì„ íƒ"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "모습"
@@ -7887,11 +7903,20 @@ msgid "New Anim"
msgstr "새 애니메ì´ì…˜"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "새 애니메ì´ì…˜ 만들기"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "애니메ì´ì…˜ ì´ë¦„ 바꾸기:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "애니메ì´ì…˜ ì´ë¦„ 바꾸기"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "애니메ì´ì…˜ì„ 삭제할까요?"
@@ -7909,11 +7934,6 @@ msgid "Animation name already exists!"
msgstr "애니메ì´ì…˜ ì´ë¦„ì´ ì´ë¯¸ 있습니다!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "애니메ì´ì…˜ ì´ë¦„ 바꾸기"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "애니메ì´ì…˜ 복제"
@@ -8057,10 +8077,6 @@ msgid "Pin AnimationPlayer"
msgstr "AnimationPlayer ê³ ì •"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "새 애니메ì´ì…˜ 만들기"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "애니메ì´ì…˜ ì´ë¦„:"
@@ -15562,8 +15578,8 @@ msgid ""
"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
-"노드가 그룹 ì•ˆì— ìžˆìŠµë‹ˆë‹¤.\n"
-"í´ë¦­í•˜ë©´ 그룹 ë…ì„ ë³´ì—¬ì¤˜ìš”."
+"노드가 %s 그룹 ì•ˆì— ìžˆìŠµë‹ˆë‹¤.\n"
+"í´ë¦­í•˜ì—¬ 그룹 ë…ì„ ë´…ë‹ˆë‹¤."
#: editor/scene_tree_editor.cpp
msgid "Open Script:"
@@ -18632,6 +18648,11 @@ msgid "The package must have at least one '.' separator."
msgstr "패키지는 ì ì–´ë„ í•˜ë‚˜ì˜ '.' 분리 기호가 있어야 합니다."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "노드 잘ë¼ë‚´ê¸°"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18640,6 +18661,16 @@ msgstr ""
msgid "Export Format"
msgstr "경로 내보내기"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "윤곽선 í¬ê¸°:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Target(대ìƒ)"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18682,16 +18713,6 @@ msgstr "ì´ì „ ì¸ìŠ¤í„´ìŠ¤ 검사"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "윤곽선 í¬ê¸°:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Target(대ìƒ)"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18938,14 +18959,14 @@ msgstr "플러그ì¸ì„ 사용하려면 \"Use Custom Build\"ê°€ 활성화ë˜ì–´ì
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"ì† ì¶”ì \" ì€ \"Xr 모드\" ê°€ \"Oculus Mobile VR\"ì¼ ë•Œë§Œ 사용 가능합니다."
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"\"ì† ì¶”ì \" ì€ \"Xr 모드\" ê°€ \"Oculus Mobile VR\"ì¼ ë•Œë§Œ 사용 가능합니다."
@@ -18956,18 +18977,38 @@ msgstr "\"Export AAB\"는 \"Use Custom Build\"ê°€ í™œì„±í™”ëœ ê²½ìš°ì—ë§Œ 유í
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr "\"Export AAB\"는 \"Use Custom Build\"ê°€ í™œì„±í™”ëœ ê²½ìš°ì—ë§Œ 유효합니다."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr "\"Export AAB\"는 \"Use Custom Build\"ê°€ í™œì„±í™”ëœ ê²½ìš°ì—ë§Œ 유효합니다."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20651,7 +20692,7 @@ msgstr "줌 ì¸"
msgid "Custom Viewport"
msgstr "ë·°í¬íЏ 1ê°œ"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21407,11 +21448,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "연결 변경:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "ë°”ì¸ë”©"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "거리 ì„ íƒ:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "거리 ì„ íƒ:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "고급"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "활성화"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21429,16 +21502,6 @@ msgstr "수í‰ìœ¼ë¡œ 뒤집기"
msgid "Max Speed"
msgstr "ì†ë„:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "거리 ì„ íƒ:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "활성화"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21483,7 +21546,7 @@ msgstr "ì§„í–‰"
msgid "Rotation Degrees"
msgstr "%së„로 회전."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "ìƒìˆ˜"
@@ -22684,6 +22747,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "변형 중단ë¨."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23600,6 +23670,11 @@ msgstr ""
"대신 ìžì‹ 콜리전 ëª¨ì–‘ì˜ í¬ê¸°ë¥¼ 변경하세요."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "전역 변형 유지"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24854,6 +24929,11 @@ msgstr "í´ë”:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "ì„ íƒ ì˜ì—­ë§Œ"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "활성화"
@@ -25264,22 +25344,19 @@ msgstr "경로 내보내기"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
-"ë·°í¬íŠ¸ë¥¼ ë Œë” ëŒ€ìƒìœ¼ë¡œ 설정하지 않았습니다. ë·°í¬íŠ¸ì˜ ë‚´ìš©ì„ í™”ë©´ì— ì§ì ‘ 표시"
-"하려면, Controlì˜ ìžì‹ 노드로 만들어서 í¬ê¸°ë¥¼ 얻어야 합니다. 그렇지 ì•Šì„ ê²½"
-"ìš°, í™”ë©´ì— í‘œì‹œí•˜ê¸° 위해서는 ë·°í¬íŠ¸ë¥¼ RenderTarget으로 만들고 ë‚´ë¶€ì ì¸ í…스처"
-"를 다른 ë…¸ë“œì— ì§€ì •í•´ì•¼ 합니다."
+"무엇ì´ë“  ë Œë”ë§í•˜ë ¤ë©´ ë·°í¬íЏ í¬ê¸°ê°€ 양쪽 ì°¨ì›ì—서 2픽셀 ì´ìƒì´ì–´ì•¼ 합니다."
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
-"무엇ì´ë“  ë Œë”ë§í•˜ë ¤ë©´ ë·°í¬íЏ í¬ê¸°ê°€ 양쪽 ì°¨ì›ì—서 2픽셀 ì´ìƒì´ì–´ì•¼ 합니다."
#: scene/main/viewport.cpp
msgid "ARVR"
@@ -27050,6 +27127,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "AABB 만드는 중"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "오프셋:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index 5f0e9b24ad..8daa544db9 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -417,6 +417,11 @@ msgstr ""
msgid "Command"
msgstr "BendruomenÄ—"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fizikos Kadro %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -471,6 +476,10 @@ msgid "Pressure"
msgstr "Atstatyti PriartinimÄ…"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5473,6 +5482,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Visas Pasirinkimas"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7894,11 +7908,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7916,11 +7939,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8066,10 +8084,6 @@ msgid "Pin AnimationPlayer"
msgstr "Animacija"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18503,6 +18517,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Transition Nodas"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18511,6 +18530,16 @@ msgstr ""
msgid "Export Format"
msgstr "Importuoti iš Nodo:"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Atidaryti Skriptų Editorių"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "TimeScale Nodas"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18547,16 +18576,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Atidaryti Skriptų Editorių"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "TimeScale Nodas"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18793,12 +18812,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18807,17 +18826,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20436,7 +20475,7 @@ msgstr "Priartinti"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21134,34 +21173,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Prijungti"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Konstanta"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Diegti"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Įgalinti"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Įgalinti"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Įgalinti"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21202,7 +21263,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstanta"
@@ -22303,6 +22364,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Keisti Poligono SkalÄ™"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -23159,6 +23227,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Animacija: Pakeisti TransformacijÄ…"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24320,6 +24393,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Pasirinkite Nodus, kuriuos norite importuoti"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Įgalinti"
@@ -24703,16 +24781,17 @@ msgstr "Importuoti iš Nodo:"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26410,6 +26489,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Panaikinti pasirinkimÄ…"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index 7397c083fa..2dabcb40bf 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -419,6 +419,11 @@ msgstr ""
msgid "Command"
msgstr "Komūns"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fizikas kadrs %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -474,6 +479,10 @@ msgid "Pressure"
msgstr "Sagatave"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5544,6 +5553,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Režģkartes izvēle"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7930,11 +7944,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7952,11 +7975,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8099,10 +8117,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18309,6 +18323,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Izgriezt mezglu(s)"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18317,6 +18336,16 @@ msgstr ""
msgid "Export Format"
msgstr "Eksportēt bibliotēku"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Galvenais Skripts:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Izdzēst Mezglu"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18356,16 +18385,6 @@ msgstr "IepriekšējÄ cilne"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Galvenais Skripts:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Izdzēst Mezglu"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18599,12 +18618,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18613,17 +18632,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20249,7 +20288,7 @@ msgstr "PalielinÄt"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -20958,34 +20997,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Izmainīt Savienojumu:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Konstante"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Izvēlēties galveno ainu"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Papildus"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Iespējot"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Iespējot"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21026,7 +21087,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstante"
@@ -22135,6 +22196,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformēt vienmērīgo."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23001,6 +23069,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "PÄreja eksistÄ“!"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24187,6 +24260,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Tikai izvēlētais"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Iespējot"
@@ -24580,16 +24658,17 @@ msgstr "Fokusa ceļš"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26302,6 +26381,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Noņemt tekstūru"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/mk.po b/editor/translations/mk.po
index e37eadfeaf..ef9a504af6 100644
--- a/editor/translations/mk.po
+++ b/editor/translations/mk.po
@@ -3,21 +3,21 @@
# Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
-# Kristijan Fremen Velkovski <me@krisfremen.com>, 2021.
+# Kristijan Fremen Velkovski <me@krisfremen.com>, 2021, 2022.
# Denis <densisman@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2021-11-18 13:37+0000\n"
-"Last-Translator: Denis <densisman@gmail.com>\n"
+"PO-Revision-Date: 2022-06-29 10:04+0000\n"
+"Last-Translator: Kristijan Fremen Velkovski <me@krisfremen.com>\n"
"Language-Team: Macedonian <https://hosted.weblate.org/projects/godot-engine/"
"godot/mk/>\n"
"Language: mk\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n==1 || n%10==1 ? 0 : 1;\n"
-"X-Generator: Weblate 4.9.1-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -25,28 +25,27 @@ msgstr ""
#: core/bind/core_bind.cpp
msgid "Clipboard"
-msgstr ""
+msgstr "Табла Ñо иÑечоци"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Current Screen"
-msgstr "СвојÑтва на анимацијата."
+msgstr "Тековен Екран"
#: core/bind/core_bind.cpp
msgid "Exit Code"
-msgstr ""
+msgstr "Излезен код"
#: core/bind/core_bind.cpp
msgid "V-Sync Enabled"
-msgstr ""
+msgstr "Вертикална Синхронизација е вклучена"
#: core/bind/core_bind.cpp main/main.cpp
msgid "V-Sync Via Compositor"
-msgstr ""
+msgstr "Вертикална Синхронизација преку композитор"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Delta Smoothing"
-msgstr ""
+msgstr "Делта Измазнување"
#: core/bind/core_bind.cpp
msgid "Low Processor Usage Mode"
@@ -58,49 +57,49 @@ msgstr ""
#: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp
msgid "Keep Screen On"
-msgstr ""
+msgstr "Чувај го екранот уклучен"
#: core/bind/core_bind.cpp
msgid "Min Window Size"
-msgstr ""
+msgstr "Минимална Големина на Прозорецот"
#: core/bind/core_bind.cpp
msgid "Max Window Size"
-msgstr ""
+msgstr "МакÑимална Големина на Прозорецот"
#: core/bind/core_bind.cpp
msgid "Screen Orientation"
-msgstr ""
+msgstr "Ориентација на Екран"
#: core/bind/core_bind.cpp core/project_settings.cpp main/main.cpp
#: platform/uwp/os_uwp.cpp
msgid "Window"
-msgstr ""
+msgstr "Прозорец"
#: core/bind/core_bind.cpp core/project_settings.cpp
msgid "Borderless"
-msgstr ""
+msgstr "Без граници"
#: core/bind/core_bind.cpp
msgid "Per Pixel Transparency Enabled"
-msgstr ""
+msgstr "Уклучена е ТранÑпарентоÑта По ПикÑел"
#: core/bind/core_bind.cpp core/project_settings.cpp
msgid "Fullscreen"
-msgstr ""
+msgstr "Цел екран"
#: core/bind/core_bind.cpp
msgid "Maximized"
-msgstr ""
+msgstr "МакÑимизирано"
#: core/bind/core_bind.cpp
msgid "Minimized"
-msgstr ""
+msgstr "Минимизирано"
#: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp
#: scene/gui/graph_node.cpp
msgid "Resizable"
-msgstr ""
+msgstr "Променлива големина"
#: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp
#: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp
@@ -108,7 +107,7 @@ msgstr ""
#: scene/gui/control.cpp scene/gui/line_edit.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Position"
-msgstr ""
+msgstr "Позиција"
#: core/bind/core_bind.cpp core/project_settings.cpp editor/editor_settings.cpp
#: main/main.cpp modules/gridmap/grid_map.cpp
@@ -120,32 +119,31 @@ msgstr ""
#: scene/resources/style_box.cpp scene/resources/texture.cpp
#: scene/resources/visual_shader.cpp servers/visual_server.cpp
msgid "Size"
-msgstr ""
+msgstr "Големина"
#: core/bind/core_bind.cpp
msgid "Endian Swap"
-msgstr ""
+msgstr "ЕндијанÑка размена"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Editor Hint"
-msgstr "Уреди"
+msgstr "Совет за уредник"
#: core/bind/core_bind.cpp
msgid "Print Error Messages"
-msgstr ""
+msgstr "Печати грешни пораки"
#: core/bind/core_bind.cpp
msgid "Iterations Per Second"
-msgstr ""
+msgstr "Итерации во Ñекунда"
#: core/bind/core_bind.cpp
msgid "Target FPS"
-msgstr ""
+msgstr "Цел на FPS"
#: core/bind/core_bind.cpp
msgid "Time Scale"
-msgstr ""
+msgstr "ВременÑка Ñкала"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Physics Jitter Fix"
@@ -153,23 +151,23 @@ msgstr ""
#: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Error"
-msgstr ""
+msgstr "Грешка"
#: core/bind/core_bind.cpp
msgid "Error String"
-msgstr ""
+msgstr "ТекÑÑ‚ на Грешка"
#: core/bind/core_bind.cpp
msgid "Error Line"
-msgstr ""
+msgstr "Линија за грешка"
#: core/bind/core_bind.cpp
msgid "Result"
-msgstr ""
+msgstr "Резултат"
#: core/command_queue_mt.cpp core/message_queue.cpp main/main.cpp
msgid "Memory"
-msgstr ""
+msgstr "Меморија"
#: core/command_queue_mt.cpp core/message_queue.cpp
#: core/register_core_types.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp
@@ -180,11 +178,11 @@ msgstr ""
#: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h
#: servers/visual_server.cpp
msgid "Limits"
-msgstr ""
+msgstr "Граници"
#: core/command_queue_mt.cpp
msgid "Command Queue"
-msgstr ""
+msgstr "Ред за наредби"
#: core/command_queue_mt.cpp
msgid "Multithreading Queue Size (KB)"
@@ -391,6 +389,10 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr ""
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -442,6 +444,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "GDNative(ГДДомороден)"
@@ -5276,6 +5282,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7577,11 +7587,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7599,11 +7618,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7746,10 +7760,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17761,6 +17771,10 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+msgid "Custom Build"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17768,6 +17782,15 @@ msgstr ""
msgid "Export Format"
msgstr ""
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Јазол"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17804,15 +17827,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Јазол"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18033,12 +18047,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18047,17 +18061,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19570,7 +19604,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20230,32 +20264,51 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr ""
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Pathfinding"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Desired Distance"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Avoidance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Avoidance Enabled"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Avoidance Enabled"
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp
@@ -20296,7 +20349,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21328,6 +21381,13 @@ msgstr ""
msgid "Transform Normals"
msgstr ""
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22119,6 +22179,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Ðнимација Промени Прелаз"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23201,6 +23266,10 @@ msgid "Fold Gutter"
msgstr ""
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr ""
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr ""
@@ -23555,16 +23624,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25098,6 +25168,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index 74ea6168e4..1b5bc9e68f 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -394,6 +394,10 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr ""
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -446,6 +450,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5290,6 +5298,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7593,11 +7605,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7615,11 +7636,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7762,10 +7778,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17788,6 +17800,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "à´ªàµà´°à´µàµƒà´¤àµà´¤à´¿à´•ൾ:"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17796,6 +17813,14 @@ msgstr ""
msgid "Export Format"
msgstr "à´¤àµà´°à´¿à´®à´¾à´¨ പരിവർതàµà´¤à´¨à´‚ നോകàµà´•àµà´•"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr ""
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17832,14 +17857,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr ""
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18060,12 +18077,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18074,17 +18091,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19608,7 +19645,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20271,32 +20308,51 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "ചലനം à´šàµà´±àµà´±àµ½"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Pathfinding"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Desired Distance"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Avoidance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Avoidance Enabled"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Avoidance Enabled"
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp
@@ -20337,7 +20393,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21380,6 +21436,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "à´¤àµà´°à´¿à´®à´¾à´¨ പരിവർതàµà´¤à´¨à´‚ നോകàµà´•àµà´•"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22188,6 +22251,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "ചലനം à´šàµà´±àµà´±àµ½"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23277,6 +23345,10 @@ msgid "Fold Gutter"
msgstr ""
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr ""
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr ""
@@ -23632,16 +23704,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25214,6 +25287,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/mr.po b/editor/translations/mr.po
index 005f8a3177..8dffed5d4e 100644
--- a/editor/translations/mr.po
+++ b/editor/translations/mr.po
@@ -394,6 +394,10 @@ msgstr ""
msgid "Command"
msgstr "समà¥à¤¦à¤¾à¤¯"
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr ""
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -446,6 +450,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5280,6 +5288,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7584,11 +7596,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "नवीन अâ€à¥…निमेशन तयार करा"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7606,11 +7627,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7753,10 +7769,6 @@ msgid "Pin AnimationPlayer"
msgstr "अâ€à¥…निमेशनपà¥à¤²à¥‡à¤…र पिन करा"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "नवीन अâ€à¥…निमेशन तयार करा"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "अâ€à¥…निमेशन नाव:"
@@ -17787,6 +17799,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "अâ€à¥…निमेशन टà¥à¤°à¥€"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17794,6 +17811,15 @@ msgstr ""
msgid "Export Format"
msgstr ""
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "नोड हलवा"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17830,15 +17856,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "नोड हलवा"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18061,12 +18078,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18075,17 +18092,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19609,7 +19646,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20284,35 +20321,55 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "अâ€à¥…निमेशन टà¥à¤°à¥€"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Pathfinding"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Path Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "समकà¥à¤°à¤®à¤¿à¤¤ करा"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
msgid "Avoidance Enabled"
msgstr "समकà¥à¤°à¤®à¤¿à¤¤ करा"
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20353,7 +20410,7 @@ msgstr "पà¥à¤°à¤µà¤¾à¤¸"
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21398,6 +21455,13 @@ msgstr ""
msgid "Transform Normals"
msgstr ""
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22208,6 +22272,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "संकà¥à¤°à¤®à¤£: "
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23304,6 +23373,10 @@ msgid "Fold Gutter"
msgstr ""
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr ""
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr ""
@@ -23660,16 +23733,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25239,6 +25313,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index 3ef25ef863..caef354c6c 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -395,6 +395,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Perintah"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fizik"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -446,6 +451,10 @@ msgid "Pressure"
msgstr "Tekanan"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relatif"
@@ -5537,6 +5546,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Semua Pilihan"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7971,11 +7985,20 @@ msgid "New Anim"
msgstr "Anim Baru"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Cipta Animasi Baru"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Tukar Nama Animasi:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Namakan Semula Animasi"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Padam Animasi?"
@@ -7993,11 +8016,6 @@ msgid "Animation name already exists!"
msgstr "Nama animasi sudah wujud!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Namakan Semula Animasi"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Gandakan Animasi"
@@ -8140,10 +8158,6 @@ msgid "Pin AnimationPlayer"
msgstr "Pin AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Cipta Animasi Baru"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nama Animasi:"
@@ -18502,6 +18516,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Potong Nod"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18510,6 +18529,16 @@ msgstr ""
msgid "Export Format"
msgstr "Warna seragam."
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Saiz:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Cipta Nod"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18548,16 +18577,6 @@ msgstr "Tab sebelumnya"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Saiz:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Cipta Nod"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18800,12 +18819,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18814,17 +18833,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20453,7 +20492,7 @@ msgstr "Zum Masuk"
msgid "Custom Viewport"
msgstr "Tunjukkan Viewport"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21167,34 +21206,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Edit Sambungan:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Tampal Animasi"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Pilih Adegan Utama"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Lanjutan"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Aktifkan"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Aktifkan"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21238,7 +21299,7 @@ msgstr "Perjalanan"
msgid "Rotation Degrees"
msgstr "Langkah Putaran:"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Pemalar"
@@ -22362,6 +22423,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Trek Transformasi 3D"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23233,6 +23301,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Kosongkan Transformasi"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24431,6 +24504,11 @@ msgstr "Folder:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Pilihan Sahaja"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Aktifkan"
@@ -24828,16 +24906,17 @@ msgstr "Laluan Fokus"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26577,6 +26656,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Grid Offset:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index e5b0dcc26f..68de0259c2 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -412,6 +412,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Kommando"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fysikk"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -468,6 +473,10 @@ msgid "Pressure"
msgstr "Trykk"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relativ"
@@ -5721,6 +5730,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Slett Valgte"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8259,11 +8273,20 @@ msgid "New Anim"
msgstr "Ny Anim"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Lag Ny Animasjon"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Endre Animasjonsnavn:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Endre navn på Animasjon"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Fjern Animasjon?"
@@ -8281,11 +8304,6 @@ msgid "Animation name already exists!"
msgstr "Animasjonsnavnet finnes allerede!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Endre navn på Animasjon"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Dupliser Animasjon"
@@ -8435,10 +8453,6 @@ msgid "Pin AnimationPlayer"
msgstr "Lim inn Animasjon"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Lag Ny Animasjon"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Animasjonsnavn:"
@@ -19287,6 +19301,11 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
+msgid "Custom Build"
+msgstr "Bruk Tilpasset Brukerkatalog"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid "Use Custom Build"
msgstr "Bruk Tilpasset Brukerkatalog"
@@ -19295,6 +19314,16 @@ msgstr "Bruk Tilpasset Brukerkatalog"
msgid "Export Format"
msgstr "Eksporter Prosjekt"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Størrelse:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "MÃ¥l FPS"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -19336,16 +19365,6 @@ msgstr "Forrige fane"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Størrelse:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "MÃ¥l FPS"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19591,12 +19610,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19605,17 +19624,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -21283,7 +21322,7 @@ msgstr "Forstørr"
msgid "Custom Viewport"
msgstr "Vis hjelpere"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -22015,11 +22054,42 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Tilkoblingsfeil"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Fyll"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Velg en HovedScene"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Avansert"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Aktiver"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -22037,15 +22107,6 @@ msgstr "Vend horisontalt"
msgid "Max Speed"
msgstr "Hastighet (FPS):"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Aktiver"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -22088,7 +22149,7 @@ msgstr "Reise"
msgid "Rotation Degrees"
msgstr "Roterer %s grader."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstant"
@@ -23243,6 +23304,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Lag Poly"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -24126,6 +24194,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Nullstill Transformasjon"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25347,6 +25420,11 @@ msgstr "Mappe:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Kun Valgte"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Aktiver"
@@ -25750,16 +25828,17 @@ msgstr "Eksporter Prosjekt"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -27516,6 +27595,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Avstand:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index 6d43002a17..756bf78add 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -484,6 +484,11 @@ msgstr ""
msgid "Command"
msgstr "Gemeenschap"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Physics Frame %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -542,6 +547,10 @@ msgid "Pressure"
msgstr "Voorinstellingen"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Relatief kleven"
@@ -5714,6 +5723,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "GridMap-selectie vullen"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8207,11 +8221,20 @@ msgid "New Anim"
msgstr "Nieuwe Anim"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Nieuwe Animatie Opstellen"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Verander Animatie Naam:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Animatie Hernoemen"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Animatie wissen?"
@@ -8229,11 +8252,6 @@ msgid "Animation name already exists!"
msgstr "Animatienaam bestaat al!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Animatie Hernoemen"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Dupliceer Animatie"
@@ -8377,10 +8395,6 @@ msgid "Pin AnimationPlayer"
msgstr "Animatiespeler vastzetten"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Nieuwe Animatie Opstellen"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Animatienaam:"
@@ -19143,6 +19157,11 @@ msgid "The package must have at least one '.' separator."
msgstr "De pakketnaam moet ten minste een '.' bevatten."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Knopen knippen"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -19151,6 +19170,16 @@ msgstr ""
msgid "Export Format"
msgstr "Export Pad"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Omlijningsgrootte:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Doel"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -19194,16 +19223,6 @@ msgstr "Inspecteer vorige instantie"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Omlijningsgrootte:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Doel"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19453,7 +19472,7 @@ msgstr "\"Use Custom Build\" moet geactiveerd zijn om plugins te gebruiken."
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" is alleen geldig als \"Xr Mode\" op \"Oculus Mobile VR\" "
@@ -19461,7 +19480,7 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" is alleen geldig als \"Xr Mode\" op \"Oculus Mobile VR\" "
"staat."
@@ -19473,18 +19492,38 @@ msgstr "\"Export AAB\" is alleen geldig als \"Use Custom Build\" aan staat."
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr "\"Export AAB\" is alleen geldig als \"Use Custom Build\" aan staat."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr "\"Export AAB\" is alleen geldig als \"Use Custom Build\" aan staat."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -21172,7 +21211,7 @@ msgstr "Inzoomen"
msgid "Custom Viewport"
msgstr "1 beeldvenster"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21935,11 +21974,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Verbinding bewerken:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Binding"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Selecteerafstand:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Selecteerafstand:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Geavanceerd"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Inschakelen"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21957,16 +22028,6 @@ msgstr "Horizontaal omdraaien"
msgid "Max Speed"
msgstr "Snelheid:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Selecteerafstand:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Inschakelen"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -22012,7 +22073,7 @@ msgstr "Verplaats"
msgid "Rotation Degrees"
msgstr "Roteren %s graden."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Constante"
@@ -23214,6 +23275,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformatie Afgebroken."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -24120,6 +24188,11 @@ msgstr ""
"Verander in plaats daarvan de grootte van de onderliggende botsingsvormen."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Houd Globale Transformatie"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25376,6 +25449,11 @@ msgstr "Map:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Alleen selectie"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Inschakelen"
@@ -25782,18 +25860,6 @@ msgid "Viewport Path"
msgstr "Export Pad"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Dit beeldvenster is niet ingesteld als renderdoelwit. Als de inhoud op het "
-"scherm getoond moet worden, moet je het een kind van een Control knoop "
-"maken, zodat het een grootte kan ontvangen. Anders, maak er een RenderTarget "
-"van en wijs zijn interne textuur toe aan een knoop om te tonen."
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -25802,6 +25868,15 @@ msgstr ""
"De grootte van een Viewport moet groter zijn dan 0 om iets weer te geven."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27571,6 +27646,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "AABB Genereren"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Afstand:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index 5960c6933e..264d623676 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -61,13 +61,14 @@
# Konrad <kobe-interactive@protonmail.com>, 2022.
# Pixel Zone - Godot Engine Tutorials <karoltomaszewskimusic@gmail.com>, 2022.
# DK0492 <doriankaczmarek28@gmail.com>, 2022.
+# Dawid Skubij <davidsd@tlen.pl>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-05-30 16:17+0000\n"
-"Last-Translator: DK0492 <doriankaczmarek28@gmail.com>\n"
+"PO-Revision-Date: 2022-07-10 14:38+0000\n"
+"Last-Translator: Dawid Skubij <davidsd@tlen.pl>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
"Language: pl\n"
@@ -76,7 +77,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -269,7 +270,7 @@ msgstr "Sieć"
#: core/io/file_access_network.cpp
msgid "Remote FS"
-msgstr "Zdalny System Plików"
+msgstr "Zdalny System Plików"
#: core/io/file_access_network.cpp
msgid "Page Size"
@@ -448,6 +449,10 @@ msgstr "Meta"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr "Fizyczny"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -499,6 +504,10 @@ msgid "Pressure"
msgstr "Ciśnienie"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relatywny"
@@ -714,9 +723,8 @@ msgstr "Kontrola wersji"
#: core/project_settings.cpp scene/2d/collision_object_2d.cpp
#: scene/3d/collision_object.cpp scene/gui/control.cpp
-#, fuzzy
msgid "Input"
-msgstr "Input"
+msgstr "Wejście"
#: core/project_settings.cpp
msgid "UI Accept"
@@ -5500,7 +5508,7 @@ msgstr "Miniatura..."
#: editor/editor_settings.cpp
msgid "Docks"
-msgstr ""
+msgstr "Doki"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5616,6 +5624,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Wybór GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "WyglÄ…d"
@@ -7113,7 +7126,7 @@ msgstr ""
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
msgid "sRGB"
-msgstr ""
+msgstr "sRGB"
#: editor/import/resource_importer_layered_texture.cpp
#, fuzzy
@@ -7431,7 +7444,7 @@ msgstr ""
#: scene/2d/mesh_instance_2d.cpp scene/2d/multimesh_instance_2d.cpp
#: scene/2d/particles_2d.cpp scene/2d/sprite.cpp scene/resources/style_box.cpp
msgid "Normal Map"
-msgstr ""
+msgstr "Mapa normalnych"
#: editor/import/resource_importer_texture.cpp
#, fuzzy
@@ -8095,11 +8108,20 @@ msgid "New Anim"
msgstr "Nowa animacja"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Utwórz nową animację"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Zmień nazwę animacji:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Zmień nazwę animacji"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Usunąć animację?"
@@ -8117,11 +8139,6 @@ msgid "Animation name already exists!"
msgstr "Nazwa animacji już istnieje!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Zmień nazwę animacji"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplikuj animacjÄ™"
@@ -8265,10 +8282,6 @@ msgid "Pin AnimationPlayer"
msgstr "Przypnij AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Utwórz nową animację"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nazwa animacji:"
@@ -9841,7 +9854,7 @@ msgstr "Utwórz obrys"
#: scene/resources/multimesh.cpp scene/resources/primitive_meshes.cpp
#: scene/resources/texture.cpp
msgid "Mesh"
-msgstr "Siatka"
+msgstr "Mesh"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -17085,9 +17098,8 @@ msgstr "GDNative"
#: modules/gdscript/editor/gdscript_highlighter.cpp
#: modules/gdscript/gdscript.cpp
-#, fuzzy
msgid "GDScript"
-msgstr "Skrypt"
+msgstr "GDScript"
#: modules/gdscript/editor/gdscript_highlighter.cpp
msgid "Function Definition Color"
@@ -18857,6 +18869,11 @@ msgstr "Paczka musi mieć co najmniej jedną kropkę jako separator."
#: platform/android/export/export_plugin.cpp
#, fuzzy
+msgid "Custom Build"
+msgstr "Użyj niestandardowego katalogu użytkownika"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid "Use Custom Build"
msgstr "Użyj niestandardowego katalogu użytkownika"
@@ -18865,6 +18882,16 @@ msgstr "Użyj niestandardowego katalogu użytkownika"
msgid "Export Format"
msgstr "Ścieżka eksportu"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Rozmiar zarysu:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Docelowa liczba klatek na sekundÄ™ (FPS)"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18908,16 +18935,6 @@ msgstr "Sprawdź poprzednią instancję"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Rozmiar zarysu:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Docelowa liczba klatek na sekundÄ™ (FPS)"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19166,15 +19183,17 @@ msgid "\"Use Custom Build\" must be enabled to use the plugins."
msgstr "\"Use Custom Build\" musi być włączone, by używać wtyczek."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" jest poprawne tylko, gdy \"Xr Mode\" jest \"Oculus Mobile "
"VrApi\" lub \"OpenXR\"."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr "\"Passthrough\" jest poprawne tylko, gdy \"Xr Mode\" jest \"OpenXR\"."
#: platform/android/export/export_plugin.cpp
@@ -19183,22 +19202,45 @@ msgstr ""
"\"Eksportuj AAB\" jest ważne tylko gdy \"Use Custom Build\" jest włączone."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Zmiana \"Min Sdk\" jest poprawna tylko, gdy \"Use Custom Build\" jest "
"włączone."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Zmiana \"Target Sdk\" jest poprawna tylko, gdy \"Use Custom Build\" jest "
"włączone."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr "Wersja \"Target Sdk\" musi być większa lub równa wersji \"Min Sdk\"."
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19264,9 +19306,8 @@ msgid "Invalid filename! Android APK requires the *.apk extension."
msgstr "Nieprawidłowa nazwa pliku! APK Androida wymaga rozszerzenia *.apk."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Unsupported export format!"
-msgstr "Nieobsługiwany format eksportu!\n"
+msgstr "Nieobsługiwany format eksportu!"
#: platform/android/export/export_plugin.cpp
msgid ""
@@ -19296,9 +19337,8 @@ msgstr ""
"projektu"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not export project files to gradle project."
-msgstr "Nie udało się eksportować plików projektu do projektu gradle\n"
+msgstr "Nie udało się eksportować plików projektu do projektu gradle."
#: platform/android/export/export_plugin.cpp
msgid "Could not write expansion package file!"
@@ -20227,9 +20267,8 @@ msgid "ZIP Creation"
msgstr "Projekt"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not open file to read from path \"%s\"."
-msgstr "Nie udało się eksportować plików projektu do projektu gradle\n"
+msgstr "Nie udało się otworzyć pliku do odczytu ze ścieżki \"%s\"."
#: platform/osx/export/export.cpp
msgid "Invalid bundle identifier:"
@@ -20938,7 +20977,7 @@ msgstr "Przybliż"
msgid "Custom Viewport"
msgstr "1 widok"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21215,26 +21254,23 @@ msgstr ""
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
#: scene/3d/cpu_particles.cpp scene/3d/particles.cpp scene/main/timer.cpp
-#, fuzzy
msgid "One Shot"
-msgstr "Jednorazowy Węzeł"
+msgstr "Wyemituj raz"
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
#: scene/3d/cpu_particles.cpp scene/3d/particles.cpp
-#, fuzzy
msgid "Preprocess"
-msgstr "Przetwarzanie końcowe"
+msgstr "Przetwarzanie wstępne"
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
#: scene/3d/cpu_particles.cpp scene/3d/particles.cpp
msgid "Explosiveness"
-msgstr ""
+msgstr "Wybuchowość"
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
#: scene/3d/cpu_particles.cpp scene/3d/particles.cpp
-#, fuzzy
msgid "Randomness"
-msgstr "Losowy restart (s):"
+msgstr "Losowość"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
@@ -21708,11 +21744,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Edytuj połączenie:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "WiÄ…zanie"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Wybierz odległość:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Wybierz odległość:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Zaawansowane"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Włącz"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21730,16 +21798,6 @@ msgstr "Odbij poziomo"
msgid "Max Speed"
msgstr "Szybkość:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Wybierz odległość:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Włącz"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21787,7 +21845,7 @@ msgstr "Przejdź"
msgid "Rotation Degrees"
msgstr "Obracanie o %s stopni."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Stała globalna"
@@ -21901,9 +21959,8 @@ msgstr ""
"\"Particles Animation\"."
#: scene/2d/particles_2d.cpp
-#, fuzzy
msgid "Visibility Rect"
-msgstr "Tryb priorytetów"
+msgstr "Prostokąt widoczności"
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid "Process Material"
@@ -23002,6 +23059,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformacja Zaniechana."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23563,9 +23627,8 @@ msgid "A RoomGroup should not be a child or grandchild of a Portal."
msgstr "RoomGroup nie powinien być potomkiem Portalu."
#: scene/3d/portal.cpp
-#, fuzzy
msgid "Portal Active"
-msgstr " [portale aktywne]"
+msgstr "Portal Aktywny"
#: scene/3d/portal.cpp scene/resources/occluder_shape_polygon.cpp
msgid "Two Way"
@@ -23932,6 +23995,11 @@ msgstr ""
"Zamiast tego, zmień rozmiary kształtów kolizji w węzłach podrzędnych."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Zachowaj globalnÄ… transformacjÄ™"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24848,7 +24916,7 @@ msgstr ""
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Caret"
-msgstr ""
+msgstr "Karetka"
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Blink"
@@ -25190,6 +25258,11 @@ msgstr "Folder:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Tylko zaznaczenie"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Włącz"
@@ -25526,9 +25599,8 @@ msgid "Draw 2D Outlines"
msgstr "Utwórz obrys"
#: scene/main/scene_tree.cpp servers/visual_server.cpp
-#, fuzzy
msgid "Reflections"
-msgstr "Kierunki"
+msgstr "Odbicia"
#: scene/main/scene_tree.cpp
#, fuzzy
@@ -25601,18 +25673,6 @@ msgstr "Ścieżka eksportu"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Ten Viewport nie jest ustawiony jako Render Target. Jeśli chcesz wyświetlić "
-"jego zawartość na ekranie dodaj go jako dziecko węzła typu Control, aby "
-"otrzymał jakiś rozmiar. W przeciwnym wypadku ustawi opcję RenderTarget i "
-"przyporządkuj jego teksturę dla któregoś węzła."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25620,6 +25680,15 @@ msgstr ""
"cokolwiek renderować."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -26711,7 +26780,7 @@ msgstr "Warunek"
#: scene/resources/environment.cpp
msgid "Fog"
-msgstr ""
+msgstr "Mgła"
#: scene/resources/environment.cpp
#, fuzzy
@@ -26893,9 +26962,8 @@ msgstr ""
#: scene/resources/environment.cpp
#: servers/audio/effects/audio_effect_chorus.cpp
-#, fuzzy
msgid "2"
-msgstr "2D"
+msgstr "2"
#: scene/resources/environment.cpp
#: servers/audio/effects/audio_effect_chorus.cpp
@@ -27392,6 +27460,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Generowanie AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Przesunięcie:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 139d252495..5c33524652 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -413,6 +413,11 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Paste yer Node"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -465,6 +470,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5460,6 +5469,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Yar, Blow th' Selected Down!"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7885,11 +7899,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7908,11 +7931,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8056,10 +8074,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18559,6 +18573,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Slit th' Node"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18567,6 +18586,16 @@ msgstr ""
msgid "Export Format"
msgstr "Change yer Anim Transform"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Edit"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Slit th' Node"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18606,16 +18635,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Edit"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Slit th' Node"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18849,12 +18868,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18863,17 +18882,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20478,7 +20517,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21175,34 +21214,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Slit th' Node"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Slit th' Node"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Edit"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Paste yer Node"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Paste yer Node"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Paste yer Node"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21243,7 +21304,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Rename Variable"
@@ -22334,6 +22395,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Slit th' Node"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -23185,6 +23253,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Change yer Anim Transform"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24330,6 +24403,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Slit th' Node"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Paste yer Node"
@@ -24712,16 +24790,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26410,6 +26489,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Discharge ye' Variable"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/pt.po b/editor/translations/pt.po
index c0af7140fc..0b2fa35ae5 100644
--- a/editor/translations/pt.po
+++ b/editor/translations/pt.po
@@ -16,20 +16,22 @@
# ssantos <ssantos@web.de>, 2018, 2019, 2020, 2021.
# Gonçalo Dinis Guerreiro João <goncalojoao205@gmail.com>, 2019.
# Manuela Silva <mmsrs@sky.com>, 2020.
-# Murilo Gama <murilovsky2030@gmail.com>, 2020.
+# Murilo Gama <murilovsky2030@gmail.com>, 2020, 2022.
# Ricardo Subtil <ricasubtil@gmail.com>, 2020.
# André Silva <andre.olivais@gmail.com>, 2021.
# Danilo Conceição Rosa <danilorosa@protonmail.com>, 2022.
# Kaycke <kaycke@ymail.com>, 2022.
# Renu <ifpilucas@gmail.com>, 2022.
# El_ExpertPlayer <xpertnathan37@gmail.com>, 2022.
+# Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>, 2022.
+# Ednaldo Pereira Confia <filat51823@storypo.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-13 03:39+0000\n"
-"Last-Translator: El_ExpertPlayer <xpertnathan37@gmail.com>\n"
+"PO-Revision-Date: 2022-07-11 21:32+0000\n"
+"Last-Translator: Ednaldo Pereira Confia <filat51823@storypo.com>\n"
"Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/"
"godot/pt/>\n"
"Language: pt\n"
@@ -37,7 +39,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.14-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -61,7 +63,7 @@ msgstr "V-Sync ativado"
#: core/bind/core_bind.cpp main/main.cpp
msgid "V-Sync Via Compositor"
-msgstr "V-Sync Via Compositor"
+msgstr "V-Sync via Compositor"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Delta Smoothing"
@@ -143,7 +145,7 @@ msgstr "Tamanho"
#: core/bind/core_bind.cpp
msgid "Endian Swap"
-msgstr "Troca Endiana"
+msgstr "Troca Endian"
#: core/bind/core_bind.cpp
msgid "Editor Hint"
@@ -230,7 +232,7 @@ msgstr "Rede"
#: core/io/file_access_network.cpp
msgid "Remote FS"
-msgstr "SF Remoto"
+msgstr "FS Remoto"
#: core/io/file_access_network.cpp
msgid "Page Size"
@@ -238,11 +240,11 @@ msgstr "Tamanho da Página"
#: core/io/file_access_network.cpp
msgid "Page Read Ahead"
-msgstr "Leitura de página em frente"
+msgstr "Página Lida Adiante"
#: core/io/http_client.cpp
msgid "Blocking Mode Enabled"
-msgstr "Modo de blocagem ativado"
+msgstr "Modo de Bloqueio Ativado"
#: core/io/http_client.cpp
msgid "Connection"
@@ -294,11 +296,11 @@ msgstr "Tamanho Máximo do Amortecedor de OutPut"
#: core/io/packet_peer.cpp
msgid "Stream Peer"
-msgstr ""
+msgstr "Fluxo de pares"
#: core/io/stream_peer.cpp
msgid "Big Endian"
-msgstr ""
+msgstr "Grande Endian"
#: core/io/stream_peer.cpp
msgid "Data Array"
@@ -306,7 +308,7 @@ msgstr "Lista de dados"
#: core/io/stream_peer_ssl.cpp
msgid "Blocking Handshake"
-msgstr ""
+msgstr "Bloquear Handshake"
#: core/io/udp_server.cpp
msgid "Max Pending Connections"
@@ -329,9 +331,8 @@ msgstr ""
"Número de \"bytes\" insuficientes para descodificar, ou o formato é inválido."
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid input %d (not passed) in expression"
-msgstr "Entrada inválida %i (não passada) na expressão"
+msgstr "Entrada inválida %d (não passada) na expressão"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
@@ -368,21 +369,19 @@ msgstr "Estado"
#: core/message_queue.cpp
msgid "Message Queue"
-msgstr ""
+msgstr "Fila de Mensagens"
#: core/message_queue.cpp
msgid "Max Size (KB)"
msgstr "Tamanho Máximo (KB)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "Modo Mover"
+msgstr "Modo Mouse"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "Apagar entrada"
+msgstr "Usar Entrada Acumulada"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -395,60 +394,58 @@ msgstr "Alt"
#: core/os/input_event.cpp
msgid "Shift"
-msgstr ""
+msgstr "Shift"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Control"
-msgstr "Controle de Versões"
+msgstr "Controle"
#: core/os/input_event.cpp
msgid "Meta"
-msgstr ""
+msgstr "Meta"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Command"
-msgstr "Comunidade"
+msgstr "Comando"
+
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (Físico)"
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Pressed"
-msgstr "Predefinições"
+msgstr "Pressionado"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Scancode"
-msgstr "Pequisar"
+msgstr "Código de Digitalização"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Physical Scancode"
-msgstr "Chave Física"
+msgstr "Código de Digitalização Físico"
#: core/os/input_event.cpp
msgid "Unicode"
-msgstr ""
+msgstr "Unicode"
#: core/os/input_event.cpp
msgid "Echo"
-msgstr ""
+msgstr "Eco"
#: core/os/input_event.cpp scene/gui/base_button.cpp
-#, fuzzy
msgid "Button Mask"
-msgstr "Botão"
+msgstr "Mascara de Botão"
#: core/os/input_event.cpp scene/2d/node_2d.cpp scene/gui/control.cpp
msgid "Global Position"
msgstr "Posição Global"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Factor"
-msgstr "Vetor"
+msgstr "Fator"
#: core/os/input_event.cpp
msgid "Button Index"
@@ -460,12 +457,15 @@ msgstr "Clique duplo"
#: core/os/input_event.cpp
msgid "Tilt"
-msgstr ""
+msgstr "Inclinar"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Pressure"
-msgstr "Predefinições"
+msgstr "Pressione"
+
+#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
#: core/os/input_event.cpp
msgid "Relative"
@@ -500,7 +500,7 @@ msgstr "Ação"
#: core/os/input_event.cpp scene/resources/environment.cpp
#: scene/resources/material.cpp
msgid "Strength"
-msgstr ""
+msgstr "Força"
#: core/os/input_event.cpp
msgid "Delta"
@@ -539,14 +539,12 @@ msgstr "Valor do Controlador"
#: core/project_settings.cpp editor/editor_node.cpp main/main.cpp
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Application"
-msgstr "Ação"
+msgstr "Aplicação"
#: core/project_settings.cpp main/main.cpp
-#, fuzzy
msgid "Config"
-msgstr "Configurar Ajuste"
+msgstr "Configurações"
#: core/project_settings.cpp
msgid "Project Settings Override"
@@ -584,39 +582,36 @@ msgid "Main Scene"
msgstr "Cena Principal"
#: core/project_settings.cpp
-#, fuzzy
msgid "Disable stdout"
-msgstr "Desativar Autotile"
+msgstr "Desativar stdout"
#: core/project_settings.cpp
-#, fuzzy
msgid "Disable stderr"
-msgstr "Item Desativado"
+msgstr "Desativar stderr"
#: core/project_settings.cpp
msgid "Use Hidden Project Data Directory"
-msgstr ""
+msgstr "Use o diretório de dados ocultos do projeto"
#: core/project_settings.cpp
msgid "Use Custom User Dir"
-msgstr ""
+msgstr "Usar Diretório de Usuário Personalizado"
#: core/project_settings.cpp
msgid "Custom User Dir Name"
-msgstr ""
+msgstr "Nome de Diretório de Usuário Personalizado"
#: core/project_settings.cpp main/main.cpp
#: platform/javascript/export/export.cpp platform/osx/export/export.cpp
#: platform/uwp/os_uwp.cpp
-#, fuzzy
msgid "Display"
-msgstr "Mostrar Tudo"
+msgstr "Exibição"
#: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp
#: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp
#: scene/3d/label_3d.cpp scene/gui/text_edit.cpp scene/resources/texture.cpp
msgid "Width"
-msgstr ""
+msgstr "Largura"
#: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp
#: modules/gltf/gltf_node.cpp modules/opensimplex/noise_texture.cpp
@@ -624,23 +619,20 @@ msgstr ""
#: scene/resources/capsule_shape_2d.cpp scene/resources/cylinder_shape.cpp
#: scene/resources/font.cpp scene/resources/navigation_mesh.cpp
#: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp
-#, fuzzy
msgid "Height"
-msgstr "Luz"
+msgstr "Altura"
#: core/project_settings.cpp
msgid "Always On Top"
-msgstr ""
+msgstr "Sempre no topo"
#: core/project_settings.cpp
-#, fuzzy
msgid "Test Width"
-msgstr "Esquerda Wide"
+msgstr "Largura de Teste"
#: core/project_settings.cpp
-#, fuzzy
msgid "Test Height"
-msgstr "Em teste"
+msgstr "Altura de Teste"
#: core/project_settings.cpp editor/animation_track_editor.cpp
#: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp
@@ -668,70 +660,60 @@ msgstr "Nomear a Cena"
#: core/project_settings.cpp
msgid "Search In File Extensions"
-msgstr ""
+msgstr "Pesquisar em Extensões de Arquivo"
#: core/project_settings.cpp
msgid "Script Templates Search Path"
-msgstr ""
+msgstr "Caminho de Pesquisa para Modelos de Script"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Autoload On Startup"
-msgstr "Sistema de Controlo de Versões"
+msgstr "Carregamento Automático de Controle de Versão na inicialização"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Plugin Name"
-msgstr "Controle de Versões"
+msgstr "Nome do Plug-in de Controle de Versão"
#: core/project_settings.cpp scene/2d/collision_object_2d.cpp
#: scene/3d/collision_object.cpp scene/gui/control.cpp
-#, fuzzy
msgid "Input"
-msgstr "Adicionar entrada"
+msgstr "Entrada"
#: core/project_settings.cpp
msgid "UI Accept"
-msgstr ""
+msgstr "Aceitar UI"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Select"
-msgstr "Selecionar"
+msgstr "Selecionar IU"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Cancel"
-msgstr "Cancelar"
+msgstr "Cancelar IU"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Focus Next"
-msgstr "Caminho de Foco"
+msgstr "Foco da IU em Seguida"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Focus Prev"
-msgstr "Caminho de Foco"
+msgstr "Foco da IU Anterior"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Left"
-msgstr "Topo Esquerda"
+msgstr "IU Esquerda"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Right"
-msgstr "Topo Direita"
+msgstr "IU Direita"
#: core/project_settings.cpp
msgid "UI Up"
-msgstr ""
+msgstr "UI Acima"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Down"
-msgstr "Para baixo"
+msgstr "IU Baixo"
#: core/project_settings.cpp
msgid "UI Page Up"
@@ -739,16 +721,15 @@ msgstr "UI Página Acima"
#: core/project_settings.cpp
msgid "UI Page Down"
-msgstr ""
+msgstr "UI Página Inferior"
#: core/project_settings.cpp
msgid "UI Home"
-msgstr ""
+msgstr "UI Inicio"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI End"
-msgstr "No Fim"
+msgstr "IU Final"
#: core/project_settings.cpp main/main.cpp modules/bullet/register_types.cpp
#: modules/bullet/space_bullet.cpp scene/2d/physics_body_2d.cpp
@@ -769,12 +750,11 @@ msgstr "Física"
#: scene/3d/physics_body.cpp scene/resources/world.cpp
#: servers/physics/space_sw.cpp servers/physics_server.cpp
msgid "3D"
-msgstr ""
+msgstr "3D"
#: core/project_settings.cpp
-#, fuzzy
msgid "Smooth Trimesh Collision"
-msgstr "Criar Irmão de Colisão Trimesh"
+msgstr "Colisão Trimesh Suave"
#: core/project_settings.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles2/rasterizer_scene_gles2.cpp
@@ -796,7 +776,7 @@ msgstr "Renderizar"
#: scene/resources/multimesh.cpp servers/visual/visual_server_scene.cpp
#: servers/visual_server.cpp
msgid "Quality"
-msgstr ""
+msgstr "Qualidade"
#: core/project_settings.cpp scene/gui/file_dialog.cpp
#: scene/main/scene_tree.cpp scene/resources/navigation_mesh.cpp
@@ -806,7 +786,7 @@ msgstr "Filtros"
#: core/project_settings.cpp scene/main/viewport.cpp
msgid "Sharpen Intensity"
-msgstr ""
+msgstr "Intensidade da Nitidez"
#: core/project_settings.cpp editor/editor_export.cpp editor/editor_node.cpp
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
@@ -831,55 +811,52 @@ msgid "Profiler"
msgstr "Analisador"
#: core/project_settings.cpp
-#, fuzzy
msgid "Max Functions"
-msgstr "Criar Função"
+msgstr "Funções Máximas"
#: core/project_settings.cpp scene/3d/vehicle_body.cpp
-#, fuzzy
msgid "Compression"
-msgstr "Expressão"
+msgstr "Compressão"
#: core/project_settings.cpp
-#, fuzzy
msgid "Formats"
-msgstr "Formato"
+msgstr "Formatos"
#: core/project_settings.cpp
msgid "Zstd"
-msgstr ""
+msgstr "Zstd"
#: core/project_settings.cpp
msgid "Long Distance Matching"
-msgstr ""
+msgstr "Correspondência de Longa Distância"
#: core/project_settings.cpp
msgid "Compression Level"
-msgstr ""
+msgstr "Nível de Compressão"
#: core/project_settings.cpp
msgid "Window Log Size"
-msgstr ""
+msgstr "Tamanho da Janela de Registro"
#: core/project_settings.cpp
msgid "Zlib"
-msgstr ""
+msgstr "Zlib"
#: core/project_settings.cpp
msgid "Gzip"
-msgstr ""
+msgstr "Gzip"
#: core/project_settings.cpp platform/android/export/export.cpp
msgid "Android"
-msgstr ""
+msgstr "Android"
#: core/project_settings.cpp
msgid "Modules"
-msgstr ""
+msgstr "Módulos"
#: core/register_core_types.cpp
msgid "TCP"
-msgstr ""
+msgstr "TCP"
#: core/register_core_types.cpp
msgid "Connect Timeout Seconds"
@@ -887,15 +864,15 @@ msgstr "Segundos de Timeout da Conexão"
#: core/register_core_types.cpp
msgid "Packet Peer Stream"
-msgstr ""
+msgstr "Fluxo de Pacotes de Pares"
#: core/register_core_types.cpp
msgid "Max Buffer (Power of 2)"
-msgstr ""
+msgstr "Buffer máximo (Potência de 2)"
#: core/register_core_types.cpp editor/editor_settings.cpp main/main.cpp
msgid "SSL"
-msgstr ""
+msgstr "SSL"
#: core/register_core_types.cpp main/main.cpp
msgid "Certificates"
@@ -908,9 +885,8 @@ msgid "Resource"
msgstr "Recurso"
#: core/resource.cpp
-#, fuzzy
msgid "Local To Scene"
-msgstr "Fechar Cena"
+msgstr "Local para Cena"
#: core/resource.cpp editor/dependency_editor.cpp
#: editor/editor_autoload_settings.cpp editor/plugins/path_editor_plugin.cpp
@@ -920,22 +896,20 @@ msgid "Path"
msgstr "Caminho"
#: core/script_language.cpp
-#, fuzzy
msgid "Source Code"
-msgstr "Fonte"
+msgstr "Código Fonte"
#: core/translation.cpp editor/project_settings_editor.cpp
msgid "Locale"
msgstr "Localização"
#: core/translation.cpp
-#, fuzzy
msgid "Test"
-msgstr "Em teste"
+msgstr "Testar"
#: core/translation.cpp scene/resources/font.cpp
msgid "Fallback"
-msgstr ""
+msgstr "Alternativa"
#: core/ustring.cpp scene/resources/segment_shape_2d.cpp
msgid "B"
@@ -971,17 +945,17 @@ msgstr "EiB"
#: drivers/gles3/rasterizer_scene_gles3.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp modules/gltf/gltf_state.cpp
msgid "Buffers"
-msgstr ""
+msgstr "Buffers"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
msgid "Canvas Polygon Buffer Size (KB)"
-msgstr ""
+msgstr "Tamanho do Buffer do Polígono da Tela (KB)"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
msgid "Canvas Polygon Index Buffer Size (KB)"
-msgstr ""
+msgstr "Tamanho do buffer do índice do polígono da tela (KB)"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp
@@ -993,56 +967,52 @@ msgstr ""
#: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp
#: servers/visual_server.cpp
msgid "2D"
-msgstr ""
+msgstr "2D"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
-#, fuzzy
msgid "Snapping"
-msgstr "Ajuste Inteligente"
+msgstr "Encaixe"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
-#, fuzzy
msgid "Use GPU Pixel Snap"
-msgstr "Usar Ajuste de Pixel"
+msgstr "Usar o Encaixe Pixel da GPU"
#: drivers/gles2/rasterizer_scene_gles2.cpp
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Immediate Buffer Size (KB)"
-msgstr ""
+msgstr "Tamanho de Buffer Imediato (KB)"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
-#, fuzzy
msgid "Lightmapping"
-msgstr "Consolidar Lightmaps"
+msgstr "Mapeamento de Luz"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
msgid "Use Bicubic Sampling"
-msgstr ""
+msgstr "Usar amostragem Bicúbica"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Renderable Elements"
-msgstr ""
+msgstr "Máximo de Elementos Renderizáveis"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Renderable Lights"
-msgstr ""
+msgstr "Máximo de Luzes Renderizáveis"
#: drivers/gles3/rasterizer_scene_gles3.cpp
-#, fuzzy
msgid "Max Renderable Reflections"
-msgstr "Centrar Seleção"
+msgstr "Máximo de Reflexões Renderizáveis"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Lights Per Object"
-msgstr ""
+msgstr "Máximo de Luzes por Objeto"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Subsurface Scattering"
-msgstr ""
+msgstr "Dispersão de Subsuperfície"
#: drivers/gles3/rasterizer_scene_gles3.cpp editor/animation_track_editor.cpp
#: editor/import/resource_importer_texture.cpp
@@ -1058,25 +1028,24 @@ msgid "Scale"
msgstr "Escala"
#: drivers/gles3/rasterizer_scene_gles3.cpp
-#, fuzzy
msgid "Follow Surface"
-msgstr "Povoar superfície"
+msgstr "Seguir a Superfície"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Weight Samples"
-msgstr ""
+msgstr "Amostras de Peso"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Voxel Cone Tracing"
-msgstr ""
+msgstr "Rastreamento de Cone de Voxel"
#: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp
msgid "High Quality"
-msgstr ""
+msgstr "Alta Qualidade"
#: drivers/gles3/rasterizer_storage_gles3.cpp
msgid "Blend Shape Max Buffer Size (KB)"
-msgstr ""
+msgstr "Tamanho Máximo do Buffer da Blend Shape (KB)"
#. TRANSLATORS: Adjective, refers to the mode for Bezier handles (Free, Balanced, Mirror).
#: editor/animation_bezier_editor.cpp
@@ -1150,9 +1119,8 @@ msgstr "Anim Mudar Chamada"
#: editor/animation_track_editor.cpp scene/2d/animated_sprite.cpp
#: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Frame"
-msgstr "Frame %"
+msgstr "Quadro"
#: editor/animation_track_editor.cpp editor/editor_profiler.cpp
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
@@ -1163,16 +1131,14 @@ msgstr "Tempo"
#: editor/animation_track_editor.cpp editor/import/resource_importer_scene.cpp
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Location"
msgstr "Localização"
#: editor/animation_track_editor.cpp modules/gltf/gltf_node.cpp
#: scene/2d/polygon_2d.cpp scene/2d/remote_transform_2d.cpp
#: scene/3d/remote_transform.cpp scene/3d/spatial.cpp scene/gui/control.cpp
-#, fuzzy
msgid "Rotation"
-msgstr "Passo da rotação:"
+msgstr "Rotação"
#: editor/animation_track_editor.cpp editor/script_editor_debugger.cpp
#: modules/visual_script/visual_script_nodes.cpp scene/gui/range.cpp
@@ -1180,14 +1146,13 @@ msgid "Value"
msgstr "Valor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Arg Count"
-msgstr "Valor:"
+msgstr "Contagem de Argumentos"
#: editor/animation_track_editor.cpp main/main.cpp
#: modules/mono/mono_gd/gd_mono.cpp
msgid "Args"
-msgstr ""
+msgstr "Argumentos"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp
@@ -1197,31 +1162,27 @@ msgid "Type"
msgstr "Tipo"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "In Handle"
-msgstr "Definir Manipulador"
+msgstr "Dentro do Controle"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Out Handle"
-msgstr "Definir Manipulador"
+msgstr "Fora do Controle"
#: editor/animation_track_editor.cpp
#: editor/import/resource_importer_texture.cpp
#: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp
#: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp
msgid "Stream"
-msgstr ""
+msgstr "Fluxo"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Start Offset"
-msgstr "Compensação da grelha:"
+msgstr "Deslocamento Inicial"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "End Offset"
-msgstr "Compensação:"
+msgstr "Deslocamento Final"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/import/resource_importer_scene.cpp
@@ -1234,9 +1195,8 @@ msgid "Animation"
msgstr "Animação"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Easing"
-msgstr "Easing In-Out"
+msgstr "Flexibilização"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Time"
@@ -1345,19 +1305,16 @@ msgid "Remove this track."
msgstr "Remover esta Pista."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Time (s):"
-msgstr "Tempo (s): "
+msgstr "Tempo (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Position:"
-msgstr "Posição"
+msgstr "Posição:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rotation:"
-msgstr "Passo da rotação:"
+msgstr "Rotação:"
#: editor/animation_track_editor.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -1374,44 +1331,36 @@ msgid "Type:"
msgstr "Tipo:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "(Invalid, expected type: %s)"
-msgstr "Modelo de exportação inválido:"
+msgstr "(Inválido, tipo esperado: %s)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Easing:"
-msgstr "Easing In-Out"
+msgstr "Flexibilização:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "In-Handle:"
-msgstr "Definir Manipulador"
+msgstr "Em manuseio:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Out-Handle:"
-msgstr "Definir Manipulador"
+msgstr "Fora de controle:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Stream:"
-msgstr "Item Rádio"
+msgstr "Fluxo:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Start (s):"
-msgstr "Reinício (s):"
+msgstr "Início (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "End (s):"
-msgstr "Aparecer (s):"
+msgstr "Fim (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Clip:"
-msgstr "Animações:"
+msgstr "Clipe de Animação:"
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
@@ -1495,14 +1444,12 @@ msgstr "Remover Pista de Animação"
#: editor/plugins/tile_map_editor_plugin.cpp editor/scene_tree_dock.cpp
#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Editors"
-msgstr "Editor"
+msgstr "Editores"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Confirm Insert Track"
-msgstr "Anim Inserir Pista & Chave"
+msgstr "Confirmar Inserir Faixa"
#. TRANSLATORS: %s will be replaced by a phrase describing the target of track.
#: editor/animation_track_editor.cpp
@@ -1628,9 +1575,8 @@ msgid "Add Method Track Key"
msgstr "Adicionar Chave da Pista Método"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Method not found in object:"
-msgstr "Método não encontrado no objeto: "
+msgstr "Método não encontrado no objeto:"
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
@@ -1650,7 +1596,7 @@ msgstr "Métodos"
#: editor/animation_track_editor.cpp
msgid "Bezier"
-msgstr ""
+msgstr "Bezier"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2240,7 +2186,7 @@ msgstr "Abrir"
#: editor/dependency_editor.cpp
msgid "Owners of: %s (Total: %d)"
-msgstr ""
+msgstr "Proprietários de: %s (Total: %d)"
#: editor/dependency_editor.cpp
msgid ""
@@ -2352,7 +2298,6 @@ msgstr "Desenvolvedor-chefe"
#. TRANSLATORS: This refers to a job title.
#: editor/editor_about.cpp
-#, fuzzy
msgctxt "Job Title"
msgid "Project Manager"
msgstr "Gestor de Projetos"
@@ -2599,9 +2544,8 @@ msgid "There is no '%s' file."
msgstr "Não existe ficheiro '%s'."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Layout:"
-msgstr "Esquema"
+msgstr "Esquema:"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
@@ -2650,9 +2594,8 @@ msgid "Create a new Bus Layout."
msgstr "Criar um novo Modelo de Barramento."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Audio Bus Layout"
-msgstr "Abrir Modelo de barramento de áudio"
+msgstr "Modelo de barramento de áudio"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -2806,22 +2749,19 @@ msgstr "Escolha"
#: editor/editor_export.cpp
msgid "Project export for platform:"
-msgstr ""
+msgstr "Exportação do projeto para plataforma:"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed with errors."
-msgstr "Copiar Caminho do Nó"
+msgstr "Concluído com erros."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed successfully."
-msgstr "Pacote Instalado com sucesso!"
+msgstr "Concluído com sucesso."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed."
-msgstr "Falhou:"
+msgstr "Falhou."
#: editor/editor_export.cpp
msgid "Storing File:"
@@ -2936,11 +2876,11 @@ msgstr "Formato Binário"
#: editor/editor_export.cpp
msgid "64 Bits"
-msgstr ""
+msgstr "64 Bits"
#: editor/editor_export.cpp
msgid "Embed PCK"
-msgstr ""
+msgstr "Incorporar PCK"
#: editor/editor_export.cpp platform/osx/export/export.cpp
#, fuzzy
@@ -2949,19 +2889,19 @@ msgstr "TextureRegion"
#: editor/editor_export.cpp
msgid "BPTC"
-msgstr ""
+msgstr "BPTC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "S3TC"
-msgstr ""
+msgstr "S3TC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "ETC"
-msgstr ""
+msgstr "ETC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "ETC2"
-msgstr ""
+msgstr "ETC2"
#: editor/editor_export.cpp
#, fuzzy
@@ -3013,7 +2953,7 @@ msgstr ""
#: editor/editor_export.cpp
msgid "Convert Text Resources To Binary On Export"
-msgstr ""
+msgstr "Converter Recursos de Texto em Binário na Exportação"
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -3334,7 +3274,7 @@ msgstr "Alternar Ficheiros Escondidos"
#: editor/editor_file_dialog.cpp
msgid "Disable Overwrite Warning"
-msgstr ""
+msgstr "Desativar Aviso de Sobrescrita"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
@@ -3437,7 +3377,7 @@ msgstr "A (Re)Importar Recursos"
#: editor/editor_file_system.cpp
msgid "Reimport Missing Imported Files"
-msgstr ""
+msgstr "Reimportar Arquivos Importados Ausentes"
#: editor/editor_help.cpp scene/2d/camera_2d.cpp scene/gui/control.cpp
#: scene/gui/nine_patch_rect.cpp scene/resources/dynamic_font.cpp
@@ -3548,7 +3488,7 @@ msgstr "Ajuda"
#: editor/editor_help.cpp
msgid "Sort Functions Alphabetically"
-msgstr ""
+msgstr "Classificar Funções em Ordem Alfabética"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -4336,6 +4276,8 @@ msgstr "%d mais Ficheiros"
msgid ""
"Unable to write to file '%s', file in use, locked or lacking permissions."
msgstr ""
+"Não foi possível gravar no arquivo '%s', arquivo em uso, bloqueado ou sem "
+"permissões."
#: editor/editor_node.cpp editor/editor_settings.cpp editor/scene_tree_dock.cpp
#: servers/arvr/arvr_interface.cpp
@@ -4355,11 +4297,11 @@ msgstr "Mostrar Grelha Sempre"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Resize If Many Tabs"
-msgstr ""
+msgstr "Redimensionar se Houver Muitas Guias"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Minimum Width"
-msgstr ""
+msgstr "Largura Mínima"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Output"
@@ -4372,15 +4314,15 @@ msgstr "Limpar Saída"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Always Open Output On Play"
-msgstr ""
+msgstr "Sempre Abra a Saída na Reprodução"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Always Close Output On Stop"
-msgstr ""
+msgstr "Sempre Feche a Saída na Parada"
#: editor/editor_node.cpp
msgid "Save On Focus Loss"
-msgstr ""
+msgstr "Salvar ao Perder o Foco"
#: editor/editor_node.cpp editor/editor_settings.cpp
#, fuzzy
@@ -4417,7 +4359,7 @@ msgstr "Obter Nó da Cena"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Show Thumbnail On Hover"
-msgstr ""
+msgstr "Mostrar Miniatura ao Passar o Mouse Por Cima"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Inspector"
@@ -4429,7 +4371,7 @@ msgstr "Estilo de Nome da Propriedade Predefinida"
#: editor/editor_node.cpp
msgid "Default Float Step"
-msgstr ""
+msgstr "FloatStep Padrão"
#: editor/editor_node.cpp scene/gui/tree.cpp
#, fuzzy
@@ -4438,15 +4380,15 @@ msgstr "Desativar Botão"
#: editor/editor_node.cpp
msgid "Auto Unfold Foreign Scenes"
-msgstr ""
+msgstr "Desdobramento Automático de Cenas Estrangeiras"
#: editor/editor_node.cpp
msgid "Horizontal Vector2 Editing"
-msgstr ""
+msgstr "Edição Horizontal do Vector2"
#: editor/editor_node.cpp
msgid "Horizontal Vector Types Editing"
-msgstr ""
+msgstr "Edição de Tipo de Vetor Horizontal"
#: editor/editor_node.cpp
#, fuzzy
@@ -4460,7 +4402,7 @@ msgstr "Abrir no Inspetor"
#: editor/editor_node.cpp
msgid "Default Color Picker Mode"
-msgstr ""
+msgstr "Modo Seletor de Cores Padrão"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
@@ -4627,12 +4569,12 @@ msgid ""
"mobile device).\n"
"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Quando esta opção é ativada, ao usar distribuição por um clique o executável "
-"irá tentar ligar-se ao endereço IP deste computador, para que o projeto "
-"possa ser depurado.\n"
-"Esta opção foi criada para ser usada pela depuração remota (tipicamente com "
-"um aparelho móvel).\n"
-"Não é necessário ativá-la para usar o depurador de GDScript localmente."
+"Quando esta opção está habilitada, Distribuição por um clique que fará o "
+"executável tentar se conectar ao IP deste computador e então o projeto atual "
+"pode ser depurado.\n"
+"Essa opção foi pensada para ser usada em depuração remota (normalmente com "
+"dispositivos móveis).\n"
+"Você não precisa habilitá-la para usar o depurador do GDScript localmente."
#: editor/editor_node.cpp
msgid "Small Deploy with Network Filesystem"
@@ -4649,9 +4591,9 @@ msgid ""
msgstr ""
"Quando esta opção é ativada, a distribuição por um clique para Android vai "
"exportar um executável sem os dados do projeto.\n"
-"O Sistema de Ficheiros será fornecido ao Projeto pelo Editor sobre a rede.\n"
-"Em Android, a distribuição irá usar a ligação USB para melhor performance. "
-"Esta opção acelera o teste de jogos pesados."
+"O sistema de arquivos será fornecido ao projeto pelo editor sobre a rede.\n"
+"Em Android, a distribuição irá usar o cabo USB para melhor performance. Esta "
+"opção acelera o teste para projetos com assets grandes ."
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
@@ -4662,8 +4604,8 @@ msgid ""
"When this option is enabled, collision shapes and raycast nodes (for 2D and "
"3D) will be visible in the running project."
msgstr ""
-"Quando esta opção está ativada, as formas de colisões e nós raycast (para 2D "
-"e 3D) serão visíveis no projeto em execução."
+"Quando esta opção está ativada, as formas de colisões e nós de raycast (para "
+"2D e 3D) serão visíveis no projeto em execução."
#: editor/editor_node.cpp
msgid "Visible Navigation"
@@ -5115,7 +5057,7 @@ msgstr "Depurador"
#: editor/editor_profiler.cpp
msgid "Profiler Frame History Size"
-msgstr ""
+msgstr "Tamanho do Histórico do Perfilador de Quadro"
#: editor/editor_profiler.cpp
#, fuzzy
@@ -5332,23 +5274,23 @@ msgstr "Mostrar Tudo"
#: editor/editor_settings.cpp
msgid "Custom Display Scale"
-msgstr ""
+msgstr "Escala de Exibição Personalizada"
#: editor/editor_settings.cpp
msgid "Main Font Size"
-msgstr ""
+msgstr "Tamanho da Fonte Principal"
#: editor/editor_settings.cpp
msgid "Code Font Size"
-msgstr ""
+msgstr "Tamanho da Fonte do Código"
#: editor/editor_settings.cpp
msgid "Font Antialiased"
-msgstr ""
+msgstr "Fonte Suave"
#: editor/editor_settings.cpp
msgid "Font Hinting"
-msgstr ""
+msgstr "Alinhar Fonte"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5357,7 +5299,7 @@ msgstr "Cena Principal"
#: editor/editor_settings.cpp
msgid "Main Font Bold"
-msgstr ""
+msgstr "Fonte Principal em Negrito"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5366,15 +5308,15 @@ msgstr "Adicionar Ponto Nó"
#: editor/editor_settings.cpp
msgid "Dim Editor On Dialog Popup"
-msgstr ""
+msgstr "Atenuar Editor na Caixa de Diálogo de Popup"
#: editor/editor_settings.cpp main/main.cpp
msgid "Low Processor Mode Sleep (µsec)"
-msgstr ""
+msgstr "Duração do Modo de Baixo Consumo do Processador (µsec)"
#: editor/editor_settings.cpp
msgid "Unfocused Low Processor Mode Sleep (µsec)"
-msgstr ""
+msgstr "Duração do Modo de Baixo Consumo do Processador Fora de Foco (µsec)"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5383,11 +5325,11 @@ msgstr "Modo Livre de Distrações"
#: editor/editor_settings.cpp
msgid "Automatically Open Screenshots"
-msgstr ""
+msgstr "Abrir Capturas de Tela Automaticamente"
#: editor/editor_settings.cpp
msgid "Max Array Dictionary Items Per Page"
-msgstr ""
+msgstr "Máximo de Itens de Dicionário de Array por Página"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp
@@ -5401,81 +5343,71 @@ msgstr "Predefinições"
#: editor/editor_settings.cpp
msgid "Icon And Font Color"
-msgstr ""
+msgstr "Ãcone e Cor da Fonte"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Base Color"
-msgstr "Cores"
+msgstr "Cor Base"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Accent Color"
-msgstr "Escolher cor"
+msgstr "Cor de Destaque"
#: editor/editor_settings.cpp scene/resources/environment.cpp
msgid "Contrast"
-msgstr ""
+msgstr "Contraste"
#: editor/editor_settings.cpp
msgid "Relationship Line Opacity"
-msgstr ""
+msgstr "Opacidade da Linha de Relacionamento"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Highlight Tabs"
-msgstr "A guardar lightmaps"
+msgstr "Destacar Guias"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Border Size"
-msgstr "Pixeis da Margem"
+msgstr "Tamanho da Borda"
#: editor/editor_settings.cpp
msgid "Use Graph Node Headers"
-msgstr ""
+msgstr "Usar Cabeçalhos de Nós de Gráficos"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Additional Spacing"
-msgstr "Loop da Animação"
+msgstr "Espaçamento Adicional"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Custom Theme"
-msgstr "Editor de Tema"
+msgstr "Tema Personalizado"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Show Script Button"
-msgstr "Roda Botão Direito"
+msgstr "Mostrar Botão de Script"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Directories"
-msgstr "Direções"
+msgstr "Diretórios"
#: editor/editor_settings.cpp
msgid "Autoscan Project Path"
-msgstr "Autoscan Caminho do Projeto"
+msgstr "Verificação Automática do Caminho do Projeto"
#: editor/editor_settings.cpp
msgid "Default Project Path"
-msgstr "Caminho do Projeto Predefinido"
+msgstr "Caminho Padrão do Projeto"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "On Save"
-msgstr "Guardar"
+msgstr "Ao Salvar"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Compress Binary Resources"
-msgstr "Copiar Recurso"
+msgstr "Comprimir Recursos Binários"
#: editor/editor_settings.cpp
msgid "Safe Save On Backup Then Rename"
-msgstr ""
+msgstr "Salvar com Segurança no Backup e Renomear"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5488,7 +5420,7 @@ msgstr "Tamanho da Miniatura"
#: editor/editor_settings.cpp
msgid "Docks"
-msgstr ""
+msgstr "Painéis"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5497,7 +5429,7 @@ msgstr "Obter Ãrvore da Cena"
#: editor/editor_settings.cpp
msgid "Start Create Dialog Fully Expanded"
-msgstr ""
+msgstr "Iniciar Diálogo de Criação Totalmente Expandido"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5511,7 +5443,7 @@ msgstr "Editor de Grupo"
#: editor/editor_settings.cpp
msgid "Auto Refresh Interval"
-msgstr ""
+msgstr "Intervalo de Atualização Automática"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5526,13 +5458,12 @@ msgstr "Editor de Tema"
#: editor/editor_settings.cpp scene/3d/label_3d.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Line Spacing"
-msgstr ""
+msgstr "Espaçamento de Linha"
#: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp
#: modules/gdscript/editor/gdscript_highlighter.cpp
-#, fuzzy
msgid "Highlighting"
-msgstr "Iluminação direta"
+msgstr "Destaque"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
#, fuzzy
@@ -5541,15 +5472,15 @@ msgstr "Destaque de Sintaxe"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Highlight All Occurrences"
-msgstr ""
+msgstr "Destacar Todas as Ocorrências"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Highlight Current Line"
-msgstr ""
+msgstr "Destacar Linha Atual"
#: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp
msgid "Highlight Type Safe Lines"
-msgstr ""
+msgstr "Destacar Linhas com Tipo Seguro"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5582,11 +5513,11 @@ msgstr "Navegação"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Smooth Scrolling"
-msgstr ""
+msgstr "Rolagem Suave"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "V Scroll Speed"
-msgstr ""
+msgstr "Velocidade de Rolagem V"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5595,15 +5526,20 @@ msgstr "Mostrar Origem"
#: editor/editor_settings.cpp
msgid "Minimap Width"
-msgstr ""
+msgstr "Largura do Minimapa"
#: editor/editor_settings.cpp
msgid "Mouse Extra Buttons Navigate History"
-msgstr ""
+msgstr "Botões extra do Mouse para Navegar no Histórico"
+
+#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Seleção de GridMap"
#: editor/editor_settings.cpp
msgid "Appearance"
-msgstr ""
+msgstr "Aparência"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Show Line Numbers"
@@ -5615,7 +5551,7 @@ msgstr "Números da Linha Preenchidos com Zeros"
#: editor/editor_settings.cpp
msgid "Show Bookmark Gutter"
-msgstr ""
+msgstr "Mostrar Barra de Favoritos"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5624,27 +5560,27 @@ msgstr "Saltar Pontos de Paragem"
#: editor/editor_settings.cpp
msgid "Show Info Gutter"
-msgstr ""
+msgstr "Mostrar Barra de Informações"
#: editor/editor_settings.cpp
msgid "Code Folding"
-msgstr ""
+msgstr "Agrupamento de Código"
#: editor/editor_settings.cpp
msgid "Word Wrap"
-msgstr ""
+msgstr "Quebra de Palavras"
#: editor/editor_settings.cpp
msgid "Show Line Length Guidelines"
-msgstr ""
+msgstr "Exibir Guias de Comprimento de Linha"
#: editor/editor_settings.cpp
msgid "Line Length Guideline Soft Column"
-msgstr ""
+msgstr "Diretriz de Comprimento de Linha de Coluna Flexível"
#: editor/editor_settings.cpp
msgid "Line Length Guideline Hard Column"
-msgstr ""
+msgstr "Diretriz de Comprimento de Linha de Coluna Rígida"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -5653,7 +5589,7 @@ msgstr "Editor de Script"
#: editor/editor_settings.cpp
msgid "Show Members Overview"
-msgstr ""
+msgstr "Mostrar Visão Geral dos Membros"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -5667,19 +5603,19 @@ msgstr "Apagar Espaços nos Limites"
#: editor/editor_settings.cpp
msgid "Autosave Interval Secs"
-msgstr ""
+msgstr "Segundos de Intervalo de Salvamento Automático"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
msgid "Restore Scripts On Load"
-msgstr ""
+msgstr "Restaurar Scripts ao Carregar"
#: editor/editor_settings.cpp
msgid "Auto Reload And Parse Scripts On Save"
-msgstr ""
+msgstr "Auto Recarrega e Analisa de Scripts ao Salvar"
#: editor/editor_settings.cpp
msgid "Auto Reload Scripts On External Change"
-msgstr ""
+msgstr "Recarregamento Automático de Scripts em Caso de Mudança Externa"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5688,27 +5624,27 @@ msgstr "Forçar Shader de Reserva"
#: editor/editor_settings.cpp
msgid "Sort Members Outline Alphabetically"
-msgstr ""
+msgstr "Ordenar Esquema de Membros em Ordem Alfabética"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Cursor"
-msgstr ""
+msgstr "Cursor"
#: editor/editor_settings.cpp
msgid "Scroll Past End Of File"
-msgstr ""
+msgstr "Rolar Além do Final do Arquivo"
#: editor/editor_settings.cpp
msgid "Block Caret"
-msgstr ""
+msgstr "Cursor em Bloco"
#: editor/editor_settings.cpp
msgid "Caret Blink"
-msgstr ""
+msgstr "Cursor Piscando"
#: editor/editor_settings.cpp
msgid "Caret Blink Speed"
-msgstr ""
+msgstr "Velocidade do Piscamento do Cursor"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5723,23 +5659,23 @@ msgstr "Conclusão"
#: editor/editor_settings.cpp
msgid "Idle Parse Delay"
-msgstr ""
+msgstr "Atraso de Análise de Inatividade"
#: editor/editor_settings.cpp
msgid "Auto Brace Complete"
-msgstr ""
+msgstr "Autocompletar Parênteses"
#: editor/editor_settings.cpp
msgid "Code Complete Delay"
-msgstr ""
+msgstr "Atraso no Auto Completar do Código"
#: editor/editor_settings.cpp
msgid "Put Callhint Tooltip Below Current Line"
-msgstr ""
+msgstr "Mostrar Sugestão de Chamada Abaixo da Linha Atual"
#: editor/editor_settings.cpp
msgid "Callhint Tooltip Offset"
-msgstr ""
+msgstr "Deslocamento da Sugestão de Chamada"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5762,15 +5698,15 @@ msgstr "Mostrar Ajudantes"
#: editor/editor_settings.cpp
msgid "Help Font Size"
-msgstr ""
+msgstr "Tamanho da Fonte de Ajuda"
#: editor/editor_settings.cpp
msgid "Help Source Font Size"
-msgstr ""
+msgstr "Tamanho da Fonte de Código de Ajuda"
#: editor/editor_settings.cpp
msgid "Help Title Font Size"
-msgstr ""
+msgstr "Tamanho da Fonte do Título da Ajuda"
#: editor/editor_settings.cpp modules/gridmap/grid_map_editor_plugin.cpp
msgid "Grid Map"
@@ -5787,11 +5723,11 @@ msgstr "Pré-visualização"
#: editor/editor_settings.cpp
msgid "Primary Grid Color"
-msgstr ""
+msgstr "Cor da Grade Primária"
#: editor/editor_settings.cpp
msgid "Secondary Grid Color"
-msgstr ""
+msgstr "Cor da Grade Secundária"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5828,7 +5764,7 @@ msgstr "Ponto"
#: scene/resources/particles_material.cpp servers/physics_2d_server.cpp
#: servers/physics_server.cpp
msgid "Shape"
-msgstr ""
+msgstr "Forma"
#: editor/editor_settings.cpp
msgid "Primary Grid Steps"
@@ -5840,15 +5776,15 @@ msgstr "Tamanho da Grelha"
#: editor/editor_settings.cpp
msgid "Grid Division Level Max"
-msgstr ""
+msgstr "Nível Máximo de Divisão de Grade"
#: editor/editor_settings.cpp
msgid "Grid Division Level Min"
-msgstr ""
+msgstr "Nível Mínimo de Divisão de Grade"
#: editor/editor_settings.cpp
msgid "Grid Division Level Bias"
-msgstr ""
+msgstr "Viés de Nível de Divisão de Grade"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5882,7 +5818,7 @@ msgstr "Predefinição"
#: editor/editor_settings.cpp
msgid "Lightmap Baking Number Of CPU Threads"
-msgstr ""
+msgstr "Número de threads da CPU para Baking do Mapa de luz"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5906,11 +5842,11 @@ msgstr "Diminuir Zoom"
#: editor/editor_settings.cpp
msgid "Emulate Numpad"
-msgstr ""
+msgstr "Emular Teclado Numérico"
#: editor/editor_settings.cpp
msgid "Emulate 3 Button Mouse"
-msgstr ""
+msgstr "Emular Mouse de 3 Botões"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5929,7 +5865,7 @@ msgstr "Modificado"
#: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Warped Mouse Panning"
-msgstr ""
+msgstr "Panorama do Mouse Distorcido"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5938,11 +5874,11 @@ msgstr "Modo Navegação"
#: editor/editor_settings.cpp
msgid "Orbit Sensitivity"
-msgstr ""
+msgstr "Sensibilidade da Órbita"
#: editor/editor_settings.cpp
msgid "Orbit Inertia"
-msgstr ""
+msgstr "Inércia da Órbita"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6006,7 +5942,7 @@ msgstr "Ajuste Inteligente"
#: editor/editor_settings.cpp
msgid "Bone Width"
-msgstr ""
+msgstr "Largura do Osso"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6024,11 +5960,11 @@ msgstr "Cor dos Ossos Selecionados"
#: editor/editor_settings.cpp
msgid "Bone IK Color"
-msgstr ""
+msgstr "Cor do Osso IK"
#: editor/editor_settings.cpp
msgid "Bone Outline Color"
-msgstr ""
+msgstr "Color do Contorno do Osso"
#: editor/editor_settings.cpp
msgid "Bone Outline Size"
@@ -6036,19 +5972,19 @@ msgstr "Tamanho do Contorno dos Ossos"
#: editor/editor_settings.cpp
msgid "Viewport Border Color"
-msgstr ""
+msgstr "Cor da borda do Viewport"
#: editor/editor_settings.cpp
msgid "Constrain Editor View"
-msgstr ""
+msgstr "Restringir a Visualização do Editor"
#: editor/editor_settings.cpp
msgid "Simple Panning"
-msgstr ""
+msgstr "Panorâmica Simples"
#: editor/editor_settings.cpp
msgid "Scroll To Pan"
-msgstr ""
+msgstr "Rolar para Arrastar"
#: editor/editor_settings.cpp
msgid "Pan Speed"
@@ -6061,7 +5997,7 @@ msgstr "Editor UV de Polígono 2D"
#: editor/editor_settings.cpp
msgid "Point Grab Radius"
-msgstr ""
+msgstr "Raio do Ponto de Captura"
#: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -6075,7 +6011,7 @@ msgstr "Renomear Animação"
#: editor/editor_settings.cpp
msgid "Default Create Bezier Tracks"
-msgstr ""
+msgstr "Criar Faixas de Bézier Padrão"
#: editor/editor_settings.cpp
#, fuzzy
@@ -6084,84 +6020,77 @@ msgstr "Criar Pista(s) RESET"
#: editor/editor_settings.cpp
msgid "Onion Layers Past Color"
-msgstr ""
+msgstr "Camadas de Cebola Cor Passada"
#: editor/editor_settings.cpp
msgid "Onion Layers Future Color"
-msgstr ""
+msgstr "Camadas de Cebola Cor Futura"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Visual Editors"
-msgstr "Editor de Grupo"
+msgstr "Editor Visual"
#: editor/editor_settings.cpp
msgid "Minimap Opacity"
-msgstr ""
+msgstr "Opacidade do Minimapa"
#: editor/editor_settings.cpp
msgid "Window Placement"
-msgstr ""
+msgstr "Posicionamento da Janela"
#: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp
#: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp
#: scene/gui/control.cpp
-#, fuzzy
msgid "Rect"
-msgstr "Rect Completo"
+msgstr "Retângulo"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Rect Custom Position"
-msgstr "Definir posição Curve Out"
+msgstr "Posição Personalizada do Retângulo"
#: editor/editor_settings.cpp platform/android/export/export_plugin.cpp
msgid "Screen"
-msgstr ""
+msgstr "Tela"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Auto Save"
-msgstr "Corte automático"
+msgstr "Salvamento Automático"
#: editor/editor_settings.cpp
msgid "Save Before Running"
-msgstr "Guardar Antes de Executar"
+msgstr "Salvar Antes de Executar"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Font Size"
-msgstr "Vista de Frente"
+msgstr "Tamanho da Fonte"
#: editor/editor_settings.cpp
#: modules/gdscript/language_server/gdscript_language_server.cpp
msgid "Remote Host"
-msgstr "Hospedeiro Remoto"
+msgstr "Host Remoto"
#: editor/editor_settings.cpp
#: modules/gdscript/language_server/gdscript_language_server.cpp
-#, fuzzy
msgid "Remote Port"
-msgstr "Remover Ponto"
+msgstr "Porta Remota"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Editor SSL Certificates"
-msgstr "Configurações do Editor"
+msgstr "Editor de Certificados SSL"
#: editor/editor_settings.cpp
msgid "HTTP Proxy"
-msgstr ""
+msgstr "Proxy HTTP"
#: editor/editor_settings.cpp
msgid "Host"
-msgstr ""
+msgstr "Host"
#: editor/editor_settings.cpp editor/fileserver/editor_file_server.cpp
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Port"
-msgstr ""
+msgstr "Porta"
#. TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects.
#: editor/editor_settings.cpp
@@ -6175,36 +6104,35 @@ msgstr "Ordem de Classificação"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Symbol Color"
-msgstr ""
+msgstr "Cor do Símbolo"
#: editor/editor_settings.cpp
msgid "Keyword Color"
-msgstr ""
+msgstr "Cor da Palavra-Chave"
#: editor/editor_settings.cpp
msgid "Control Flow Keyword Color"
-msgstr ""
+msgstr "Cor da Palavra-Chave do Fluxo de Controle"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Base Type Color"
-msgstr "Mudar tipo base"
+msgstr "Cor do Tipo Base"
#: editor/editor_settings.cpp
msgid "Engine Type Color"
-msgstr ""
+msgstr "Cor do Tipo de Motor"
#: editor/editor_settings.cpp
msgid "User Type Color"
-msgstr ""
+msgstr "Cor do Tipo de Usuário"
#: editor/editor_settings.cpp
msgid "Comment Color"
-msgstr ""
+msgstr "Cor do Comentário"
#: editor/editor_settings.cpp
msgid "String Color"
-msgstr "Cor da Cadeia"
+msgstr "Cor da String"
#: editor/editor_settings.cpp platform/javascript/export/export.cpp
#: platform/uwp/export/export.cpp
@@ -6214,29 +6142,27 @@ msgstr "Cor de Fundo"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Background Color"
-msgstr "Conclusão da Cor de Fundo"
+msgstr "Cor de Preenchimento de Fundo"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Completion Selected Color"
-msgstr "Importar Selecionado"
+msgstr "Cor de Preenchimento Selecionada"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Existing Color"
-msgstr ""
+msgstr "Cor de Preenchimento Existente"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Scroll Color"
-msgstr ""
+msgstr "Cor de Preenchimento de Rolagem"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Font Color"
-msgstr ""
+msgstr "Cor de Preenchimento de Fonte"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Text Color"
-msgstr "Próximo Piso"
+msgstr "Cor do Texto"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Line Number Color"
@@ -6248,86 +6174,75 @@ msgstr "Cor do Número da Linha Segura"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Caret Color"
-msgstr ""
+msgstr "Cor do Cursor"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Caret Background Color"
msgstr "Cor de Fundo do Cursor"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Text Selected Color"
-msgstr "Apagar Selecionado"
+msgstr "Cor do Texto Selecionado"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Selection Color"
-msgstr "Apenas seleção"
+msgstr "Cor da Seleção"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Brace Mismatch Color"
-msgstr ""
+msgstr "Cor da Incompatibilidade de Fechamento de Chaves"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Current Line Color"
-msgstr "Cena Atual"
+msgstr "Cor da Linha Atual"
#: editor/editor_settings.cpp
msgid "Line Length Guideline Color"
-msgstr ""
+msgstr "Cor da Diretriz do Comprimento da Linha"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Word Highlighted Color"
-msgstr "Destaque de Sintaxe"
+msgstr "Cor da Palavra Destacada"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Number Color"
-msgstr ""
+msgstr "Cor do Número"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Function Color"
-msgstr "Função"
+msgstr "Cor da Função"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Member Variable Color"
-msgstr "Mudar nome da Variável"
+msgstr "Cor da Variável de Membro"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Mark Color"
-msgstr "Escolher cor"
+msgstr "Cor da Marca"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Bookmark Color"
-msgstr "Marcadores"
+msgstr "Cor dos Favoritos"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Breakpoint Color"
-msgstr "Pontos de paragem"
+msgstr "Color do Breakpoint"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Executing Line Color"
-msgstr ""
+msgstr "Cor da Linha em Execução"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Code Folding Color"
-msgstr ""
+msgstr "Cor do Agrupamento de Código"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Search Result Color"
-msgstr "Resultados da Pesquisa"
+msgstr "Color dos Resultados da Pesquisa"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Search Result Border Color"
-msgstr "Resultados da Pesquisa"
+msgstr "Cor da Borda dos Resultados da Pesquisa"
#: editor/editor_spin_slider.cpp
msgid "Hold %s to round to integers. Hold Shift for more precise changes."
@@ -6336,14 +6251,12 @@ msgstr ""
"mais precisas."
#: editor/editor_spin_slider.cpp scene/gui/button.cpp
-#, fuzzy
msgid "Flat"
-msgstr "Plano 0"
+msgstr "Flat"
#: editor/editor_spin_slider.cpp
-#, fuzzy
msgid "Hide Slider"
-msgstr "Modo Colisão"
+msgstr "Ocultar Slider"
#: editor/editor_sub_scene.cpp
msgid "Select Node(s) to Import"
@@ -6639,7 +6552,7 @@ msgstr ""
#: editor/fileserver/editor_file_server.cpp
msgid "File Server"
-msgstr ""
+msgstr "Servidor de Arquivos"
#: editor/fileserver/editor_file_server.cpp
#: editor/plugins/version_control_editor_plugin.cpp
@@ -6707,6 +6620,11 @@ msgid ""
"After renaming to an unknown extension, the file won't be shown in the "
"editor anymore."
msgstr ""
+"Esta extensão de arquivo não é reconhecida pelo editor.\n"
+"Se você de qualquer maneira quiser renomeá-lo, use o gerenciador de arquivos "
+"do seu sistema operacional.\n"
+"Após renomear para uma extensão desconhecida, o arquivo não será mais "
+"exibido no editor."
#: editor/filesystem_dock.cpp
msgid ""
@@ -7007,11 +6925,11 @@ msgstr "Gerir Grupos"
#: editor/import/editor_import_collada.cpp
msgid "Collada"
-msgstr ""
+msgstr "Collada"
#: editor/import/editor_import_collada.cpp
msgid "Use Ambient"
-msgstr ""
+msgstr "Usar Ambiente"
#: editor/import/resource_importer_bitmask.cpp
#, fuzzy
@@ -7021,7 +6939,7 @@ msgstr "Criar Pasta"
#: editor/import/resource_importer_bitmask.cpp
#: servers/audio/effects/audio_effect_compressor.cpp
msgid "Threshold"
-msgstr ""
+msgstr "Limite"
#: editor/import/resource_importer_csv_translation.cpp
#: editor/import/resource_importer_layered_texture.cpp
@@ -7034,7 +6952,7 @@ msgstr "Componentes"
#: editor/import/resource_importer_csv_translation.cpp
msgid "Delimiter"
-msgstr ""
+msgstr "Delimitador"
#: editor/import/resource_importer_layered_texture.cpp
#, fuzzy
@@ -7043,7 +6961,7 @@ msgstr "Função Cor."
#: editor/import/resource_importer_layered_texture.cpp
msgid "No BPTC If RGB"
-msgstr ""
+msgstr "Sem BPTC Se RGB"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/2d/cpu_particles_2d.cpp
@@ -7051,13 +6969,13 @@ msgstr ""
#: scene/resources/material.cpp scene/resources/particles_material.cpp
#: scene/resources/texture.cpp scene/resources/visual_shader.cpp
msgid "Flags"
-msgstr ""
+msgstr "Flags"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/animation/tween.cpp
#: scene/resources/texture.cpp
msgid "Repeat"
-msgstr ""
+msgstr "Repetir"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/2d/light_2d.cpp
@@ -7074,12 +6992,12 @@ msgstr "Sinais"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
msgid "Anisotropic"
-msgstr ""
+msgstr "Anisotrópico"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
msgid "sRGB"
-msgstr ""
+msgstr "sRGB"
#: editor/import/resource_importer_layered_texture.cpp
#, fuzzy
@@ -7106,23 +7024,21 @@ msgid "Generate Tangents"
msgstr "Gerar Pontos"
#: editor/import/resource_importer_obj.cpp
-#, fuzzy
msgid "Scale Mesh"
-msgstr "Modo Escalar"
+msgstr "Escalar Forma"
#: editor/import/resource_importer_obj.cpp
msgid "Offset Mesh"
-msgstr "Malha de Compensação"
+msgstr "Forma de Compensação"
#: editor/import/resource_importer_obj.cpp
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Octahedral Compression"
-msgstr "Expressão"
+msgstr "Compressão Octaédrica"
#: editor/import/resource_importer_obj.cpp
msgid "Optimize Mesh Flags"
-msgstr "Otimizar Flags da Malha"
+msgstr "Otimizar Flags da Forma"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Single Scene"
@@ -7166,29 +7082,24 @@ msgstr "Importar como Cenas Múltiplas + Materiais"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
#: scene/3d/physics_joint.cpp
-#, fuzzy
msgid "Nodes"
-msgstr "Nó"
+msgstr "Nós"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Root Type"
-msgstr "Voltar"
+msgstr "Tipo da Raiz"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Root Name"
-msgstr "Nome do Remoto"
+msgstr "Nome da Raiz"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Root Scale"
-msgstr "Escala"
+msgstr "Escala da Raiz"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Custom Script"
-msgstr "CustomNode"
+msgstr "Script Personalizado"
#: editor/import/resource_importer_scene.cpp scene/resources/texture.cpp
msgid "Storage"
@@ -7196,54 +7107,47 @@ msgstr "Armazenamento"
#: editor/import/resource_importer_scene.cpp
msgid "Use Legacy Names"
-msgstr ""
+msgstr "Usar Nomes Legados"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
msgid "Materials"
msgstr "Materiais"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Keep On Reimport"
-msgstr "Reimportar"
+msgstr "Manter ao Reimportar"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
-#, fuzzy
msgid "Meshes"
-msgstr "Malha"
+msgstr "Malhas"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Ensure Tangents"
-msgstr "Modificar tangente da curva"
+msgstr "Assegurar Tangentes"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Light Baking"
-msgstr "Consolidar Lightmaps"
+msgstr "Baking de Luz"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Lightmap Texel Size"
-msgstr "Consolidar Lightmaps"
+msgstr "Tamanho do Texel do Mapa de Luz"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
msgid "Skins"
-msgstr ""
+msgstr "Skins"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Use Named Skins"
-msgstr "Usar Ajuste de Escala"
+msgstr "Usar Skins com Nome"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "External Files"
-msgstr "Abrir um Ficheiro"
+msgstr "Arquivos Externos"
#: editor/import/resource_importer_scene.cpp
msgid "Store In Subdir"
-msgstr ""
+msgstr "Armazenar no Subdiretório"
#: editor/import/resource_importer_scene.cpp
#, fuzzy
@@ -7319,13 +7223,12 @@ msgid "Generating Lightmaps"
msgstr "A gerar Lightmaps"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Generating for Mesh:"
-msgstr "A gerar para Malha: "
+msgstr "Gerar para Forma:"
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
-msgstr "A executar Script Customizado..."
+msgstr "A executar Script Personalizado..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
@@ -7352,155 +7255,148 @@ msgid ""
"%s: Texture detected as used as a normal map in 3D. Enabling red-green "
"texture compression to reduce memory usage (blue channel is discarded)."
msgstr ""
+"%s: Textura detectada como usada como mapa normal em 3D. Ativando a "
+"compactação de textura vermelho-verde para reduzir o uso de memória (o canal "
+"azul é descartado)."
#: editor/import/resource_importer_texture.cpp
msgid ""
"%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap "
"generation and VRAM texture compression."
msgstr ""
+"%s: Textura detectada como usada em 3D. Ativando filtro, repetição, geração "
+"de mapa MIP e compressão de textura VRAM."
#: editor/import/resource_importer_texture.cpp
msgid "2D, Detect 3D"
-msgstr ""
+msgstr "2D, Detectar 3D"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "2D Pixel"
-msgstr "Pixeis Sólidos"
+msgstr "Pixel 2D"
#: editor/import/resource_importer_texture.cpp scene/resources/texture.cpp
msgid "Lossy Quality"
-msgstr ""
+msgstr "Qualidade com Perdas"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "HDR Mode"
-msgstr "Modo Seleção"
+msgstr "Modo HDR"
#: editor/import/resource_importer_texture.cpp
msgid "BPTC LDR"
-msgstr ""
+msgstr "BPTC LDR"
#: editor/import/resource_importer_texture.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp
#: scene/2d/mesh_instance_2d.cpp scene/2d/multimesh_instance_2d.cpp
#: scene/2d/particles_2d.cpp scene/2d/sprite.cpp scene/resources/style_box.cpp
msgid "Normal Map"
-msgstr ""
+msgstr "Mapa Normal"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Process"
-msgstr "Pós-processamento"
+msgstr "Processo"
#: editor/import/resource_importer_texture.cpp
msgid "Fix Alpha Border"
-msgstr ""
+msgstr "Corrigir Borda Alfa"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Premult Alpha"
-msgstr "Editar Polígono"
+msgstr "Pré-multiplicar Alfa"
#: editor/import/resource_importer_texture.cpp
msgid "Hdr As Srgb"
-msgstr ""
+msgstr "Hdr como Srgb"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Invert Color"
-msgstr "Vértice"
+msgstr "Inverter Cor"
#: editor/import/resource_importer_texture.cpp
msgid "Normal Map Invert Y"
-msgstr "Mapa Normal Inverter Y"
+msgstr "Inverter Y no Mapa Normal"
#: editor/import/resource_importer_texture.cpp
msgid "Size Limit"
-msgstr "Limite do Tamanho"
+msgstr "Tamanho Limite"
#: editor/import/resource_importer_texture.cpp
msgid "Detect 3D"
-msgstr ""
+msgstr "Detectar 3D"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "SVG"
-msgstr "HSV"
+msgstr "SVG"
#: editor/import/resource_importer_texture.cpp
msgid ""
"Warning, no suitable PC VRAM compression enabled in Project Settings. This "
"texture will not display correctly on PC."
msgstr ""
+"Aviso, nenhuma compactação de VRAM de PC adequada ativada nas configurações "
+"do projeto. Esta textura não será exibida corretamente no PC."
#: editor/import/resource_importer_texture_atlas.cpp
msgid "Atlas File"
-msgstr "Ficheiro Atlas"
+msgstr "Arquivo de Atlas"
#: editor/import/resource_importer_texture_atlas.cpp
msgid "Import Mode"
msgstr "Modo de Importação"
#: editor/import/resource_importer_texture_atlas.cpp
-#, fuzzy
msgid "Crop To Region"
-msgstr "Definir Região Tile"
+msgstr "Cortar Para Região"
#: editor/import/resource_importer_texture_atlas.cpp
msgid "Trim Alpha Border From Region"
-msgstr ""
+msgstr "Aparar Borda Alfa da Região"
#: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp
-#, fuzzy
msgid "Force"
-msgstr "Forçar Impulso"
+msgstr "Força"
#: editor/import/resource_importer_wav.cpp
msgid "8 Bit"
-msgstr ""
+msgstr "8 Bits"
#: editor/import/resource_importer_wav.cpp main/main.cpp
#: modules/mono/editor/csharp_project.cpp modules/mono/mono_gd/gd_mono.cpp
msgid "Mono"
-msgstr ""
+msgstr "Mono"
#: editor/import/resource_importer_wav.cpp
-#, fuzzy
msgid "Max Rate"
-msgstr "Nó Mix"
+msgstr "Taxa Máxima"
#: editor/import/resource_importer_wav.cpp
-#, fuzzy
msgid "Max Rate Hz"
-msgstr "Nó Mix"
+msgstr "Taxa Máxima Hz"
#: editor/import/resource_importer_wav.cpp
msgid "Trim"
-msgstr ""
+msgstr "Aparar"
#: editor/import/resource_importer_wav.cpp
-#, fuzzy
msgid "Normalize"
-msgstr "Formato"
+msgstr "Normalizar"
#: editor/import/resource_importer_wav.cpp
#: scene/resources/audio_stream_sample.cpp
-#, fuzzy
msgid "Loop Mode"
-msgstr "Modo Mover"
+msgstr "Modo de Loop"
#: editor/import/resource_importer_wav.cpp
#: scene/resources/audio_stream_sample.cpp
-#, fuzzy
msgid "Loop Begin"
-msgstr "Modo Mover"
+msgstr "Inicio do Loop"
#: editor/import/resource_importer_wav.cpp
#: scene/resources/audio_stream_sample.cpp
-#, fuzzy
msgid "Loop End"
-msgstr "Modo Mover"
+msgstr "Fim do Loop"
#: editor/import_defaults_editor.cpp
msgid "Select Importer"
@@ -7597,7 +7493,7 @@ msgstr "Localização"
#: editor/inspector_dock.cpp
msgid "Localization not available for current language."
-msgstr ""
+msgstr "Localização não disponível para o idioma atual."
#: editor/inspector_dock.cpp
msgid "Copy Properties"
@@ -8045,11 +7941,20 @@ msgid "New Anim"
msgstr "Nova Animação"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Criar Nova Animação"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Mudar o Nome da Animação:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Renomear Animação"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Apagar Animação?"
@@ -8067,11 +7972,6 @@ msgid "Animation name already exists!"
msgstr "Já existe o nome da Animação!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Renomear Animação"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplicar Animação"
@@ -8216,10 +8116,6 @@ msgid "Pin AnimationPlayer"
msgstr "Pregar AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Criar Nova Animação"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nome da Animação:"
@@ -8473,7 +8369,7 @@ msgstr "Filtros..."
#: editor/plugins/asset_library_editor_plugin.cpp scene/main/http_request.cpp
msgid "Use Threads"
-msgstr ""
+msgstr "Usar Threads"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Contents:"
@@ -8705,7 +8601,7 @@ msgstr "Em teste"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Failed to get repository configuration."
-msgstr ""
+msgstr "Falha ao obter a configuração do repositório."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -8762,7 +8658,7 @@ msgstr "Consolidar Lightmaps"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "LightMap Bake"
-msgstr ""
+msgstr "Bake de Mapa de Luz"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Select lightmap bake file:"
@@ -9279,7 +9175,7 @@ msgstr "Ajuste Inteligente"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Hide"
-msgstr ""
+msgstr "Esconder"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -9636,11 +9532,11 @@ msgstr "Gradiente Editado"
#: editor/plugins/gradient_texture_2d_editor_plugin.cpp
msgid "Swap GradientTexture2D Fill Points"
-msgstr ""
+msgstr "Trocar pontos de preenchimento do Gradiente de Textura 2D"
#: editor/plugins/gradient_texture_2d_editor_plugin.cpp
msgid "Swap Gradient Fill Points"
-msgstr ""
+msgstr "Trocar Pontos de Preenchimento de Gradiente"
#: editor/plugins/gradient_texture_2d_editor_plugin.cpp
#, fuzzy
@@ -9664,7 +9560,7 @@ msgstr "Ãcone"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "ID"
-msgstr ""
+msgstr "ID"
#: editor/plugins/item_list_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -10461,7 +10357,7 @@ msgstr "Sincronizar Ossos com Polígono"
#: editor/plugins/ray_cast_2d_editor_plugin.cpp
msgid "Set cast_to"
-msgstr ""
+msgstr "Definir cast_to"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ERROR: Couldn't load resource!"
@@ -10792,11 +10688,11 @@ msgstr "Resultados da Pesquisa"
#: editor/plugins/script_editor_plugin.cpp
msgid "Open Dominant Script On Scene Change"
-msgstr ""
+msgstr "Abrir Script Dominante na Mudança de Cena"
#: editor/plugins/script_editor_plugin.cpp
msgid "External"
-msgstr ""
+msgstr "Externo"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -10815,11 +10711,11 @@ msgstr "Selecionar Ficheiro de Modelo"
#: editor/plugins/script_editor_plugin.cpp
msgid "Highlight Current Script"
-msgstr ""
+msgstr "Destacar Script Atual"
#: editor/plugins/script_editor_plugin.cpp
msgid "Script Temperature History Size"
-msgstr ""
+msgstr "Tamanho do Histórico de Temperatura do Script"
#: editor/plugins/script_editor_plugin.cpp
msgid "Current Script Background Color"
@@ -10842,7 +10738,7 @@ msgstr "Nome do Script:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Exec Flags"
-msgstr ""
+msgstr "Flags de Execução"
#: editor/plugins/script_editor_plugin.cpp
msgid "Clear Recent Scripts"
@@ -11356,7 +11252,7 @@ msgstr "Pré-visualização Cinemática"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "(Not in GLES2)"
-msgstr ""
+msgstr "(Não em GLES2)"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -11657,11 +11553,11 @@ msgstr "Pós"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Manipulator Gizmo Size"
-msgstr ""
+msgstr "Tamanho do Gizmo do Manipulador"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Manipulator Gizmo Opacity"
-msgstr ""
+msgstr "Opacidade do Gizmo do Manipulador"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -12347,41 +12243,41 @@ msgid "Add Item Type"
msgstr "Adicionar Tipo de Item"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Set Variation Base Type"
-msgstr "Definir tipo de variável"
+msgstr "Definir Tipo Base da Variação"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Set Base Type"
-msgstr "Mudar tipo base"
+msgstr "Definir Tipo Base"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Show Default"
-msgstr "Mostrar Predefinição"
+msgstr "Mostrar Padrão"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Show default type items alongside items that have been overridden."
-msgstr ""
-"Mostrar itens do tipo predefinido ao lado de itens que foram sobrepostos."
+msgstr "Mostrar itens do tipo padrão ao lado de itens que foram sobrepostos."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Override All"
-msgstr "Sobrepor Tudo"
+msgstr "Substituir Tudo"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Override all default type items."
-msgstr "Sobrepõe todos os itens de tipo predefinido."
+msgstr "Substituir todos os itens de tipo padrão."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Select the variation base type from a list of available types."
msgstr ""
+"Selecione o tipo de base de variação em uma lista de tipos disponíveis."
#: editor/plugins/theme_editor_plugin.cpp
msgid ""
"A type associated with a built-in class cannot be marked as a variation of "
"another type."
msgstr ""
+"Um tipo associado a uma classe integrada não pode ser marcado como uma "
+"variação de outro tipo."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme:"
@@ -12626,7 +12522,7 @@ msgstr "Pintar TileMap"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Palette Min Width"
-msgstr ""
+msgstr "Largura Mínima da Paleta"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -14219,11 +14115,13 @@ msgstr "Executável"
#: editor/project_export.cpp
msgid "Export the project for all the presets defined."
-msgstr ""
+msgstr "Exporte o projeto para todas as predefinições definidas."
#: editor/project_export.cpp
msgid "All presets must have an export path defined for Export All to work."
msgstr ""
+"Todas as predefinições devem ter um caminho de exportação definido para que "
+"Exportar Tudo funcione."
#: editor/project_export.cpp
msgid "Delete preset '%s'?"
@@ -14335,6 +14233,8 @@ msgid ""
"Note: Encryption key needs to be stored in the binary,\n"
"you need to build the export templates from source."
msgstr ""
+"Nota: A chave de criptografia precisa ser armazenada no binário,\n"
+"você precisa construir os modelos de exportação da fonte."
#: editor/project_export.cpp
#, fuzzy
@@ -15493,7 +15393,7 @@ msgstr "Tornar Local"
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
msgid "Another node already uses this unique name in the scene."
-msgstr ""
+msgstr "Outro nó já usa esse nome exclusivo na cena."
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -15579,7 +15479,7 @@ msgstr "Sub-recursos"
#: editor/scene_tree_dock.cpp
msgid "Access as Scene Unique Name"
-msgstr ""
+msgstr "Acesso como Nome Exclusivo da Cena"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance"
@@ -15684,7 +15584,7 @@ msgstr "Centrar Seleção"
#: editor/scene_tree_dock.cpp
msgid "Derive Script Globals By Name"
-msgstr ""
+msgstr "Derivar Globais de Script Por Nome"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -15717,6 +15617,9 @@ msgid ""
"with the '%s' prefix in a node path.\n"
"Click to disable this."
msgstr ""
+"Este nó pode ser acessado de qualquer lugar na cena, precedendo-o com o "
+"prefixo '%s' em um caminho de nó.\n"
+"Clique para desabilitar isso."
#: editor/scene_tree_editor.cpp
msgid ""
@@ -16010,15 +15913,15 @@ msgstr "Filtrar Tiles"
#: editor/script_editor_debugger.cpp
msgid "Auto Switch To Remote Scene Tree"
-msgstr ""
+msgstr "Mudar Automático para Ãrvore de Cena Remota"
#: editor/script_editor_debugger.cpp
msgid "Remote Scene Tree Refresh Interval"
-msgstr ""
+msgstr "Intervalo de Atualização da Ãrvore de Cena Remota"
#: editor/script_editor_debugger.cpp
msgid "Remote Inspect Refresh Interval"
-msgstr ""
+msgstr "Intervalo de Atualização de Inspeção Remota"
#: editor/script_editor_debugger.cpp
msgid "Network Profiler"
@@ -16116,7 +16019,7 @@ msgstr "Mudar raio da luz"
#: editor/spatial_editor_gizmos.cpp
msgid "Stream Player 3D"
-msgstr ""
+msgstr "Reprodutor de Fluxo 3D"
#: editor/spatial_editor_gizmos.cpp
msgid "Change AudioStreamPlayer3D Emission Angle"
@@ -16126,7 +16029,7 @@ msgstr "Mudar ângulo de emissão de AudioStreamPlayer3D"
#: platform/osx/export/export.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Camera"
-msgstr ""
+msgstr "Câmera"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Camera FOV"
@@ -16138,7 +16041,7 @@ msgstr "Mudar tamanho da Câmara"
#: editor/spatial_editor_gizmos.cpp
msgid "Visibility Notifier"
-msgstr ""
+msgstr "Notificador de Visibilidade"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Notifier AABB"
@@ -16149,23 +16052,20 @@ msgid "Change Particles AABB"
msgstr "Mudar partículas AABB"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Reflection Probe"
-msgstr "Selecionar Propriedade"
+msgstr "Sonda de Reflexão"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Probe Extents"
msgstr "Mudar Extensões de Sonda"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "GI Probe"
-msgstr "Consolidar Sonda GI"
+msgstr "Sonda GI"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Baked Indirect Light"
-msgstr "Iluminação indireta"
+msgstr "Iluminação Indireta Pré-feita"
#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
msgid "Change Sphere Shape Radius"
@@ -16196,57 +16096,52 @@ msgid "Change Ray Shape Length"
msgstr "Mudar comprimento da forma raio"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Navigation Edge"
-msgstr "Modo Navegação"
+msgstr "Borda de Navegação"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Navigation Edge Disabled"
-msgstr "Modo Navegação"
+msgstr "Borda de Navegação Desabilitada"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Navigation Solid"
-msgstr "Modo Navegação"
+msgstr "Sólido de Navegação"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Navigation Solid Disabled"
-msgstr "Modo Navegação"
+msgstr "Sólido de Navegação Desativado"
#: editor/spatial_editor_gizmos.cpp
msgid "Joint Body A"
-msgstr ""
+msgstr "Corpo de Articulação A"
#: editor/spatial_editor_gizmos.cpp
msgid "Joint Body B"
-msgstr ""
+msgstr "Corpo de Articulação B"
#: editor/spatial_editor_gizmos.cpp
msgid "Room Edge"
-msgstr ""
+msgstr "Borda da Sala"
#: editor/spatial_editor_gizmos.cpp
msgid "Room Overlap"
-msgstr ""
+msgstr "Sobreposição de Sala"
#: editor/spatial_editor_gizmos.cpp
msgid "Set Room Point Position"
msgstr "Definir Posição do Ponto do Room"
#: editor/spatial_editor_gizmos.cpp scene/3d/portal.cpp
-#, fuzzy
msgid "Portal Margin"
-msgstr "Definir Margem"
+msgstr "Margem do Portal"
#: editor/spatial_editor_gizmos.cpp
msgid "Portal Edge"
-msgstr ""
+msgstr "Borda do Portal"
#: editor/spatial_editor_gizmos.cpp
msgid "Portal Arrow"
-msgstr ""
+msgstr "Seta do Portal"
#: editor/spatial_editor_gizmos.cpp
msgid "Set Portal Point Position"
@@ -16254,18 +16149,16 @@ msgstr "Definir Posição do Ponto do Portal"
#: editor/spatial_editor_gizmos.cpp
msgid "Portal Front"
-msgstr ""
+msgstr "Portal Frente"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Portal Back"
-msgstr "Voltar"
+msgstr "Portal Atras"
#: editor/spatial_editor_gizmos.cpp scene/2d/light_occluder_2d.cpp
#: scene/2d/tile_map.cpp
-#, fuzzy
msgid "Occluder"
-msgstr "Modo Oclusão"
+msgstr "Oclusor"
#: editor/spatial_editor_gizmos.cpp
msgid "Set Occluder Sphere Radius"
@@ -16276,440 +16169,397 @@ msgid "Set Occluder Sphere Position"
msgstr "Definir Posição da Esfera do Oclusor"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Set Occluder Polygon Point Position"
-msgstr "Definir Posição do Ponto do Portal"
+msgstr "Definir a Posição do Ponto do Polígono Oclusor"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Set Occluder Hole Point Position"
-msgstr "Definir posição do Ponto da curva"
+msgstr "Definir a Posição do Ponto do Orifício do Oclusor"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Occluder Polygon Front"
-msgstr "Criar Polígono Oclusor"
+msgstr "Frente do Polígono Oclusor"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Occluder Polygon Back"
-msgstr "Criar Polígono Oclusor"
+msgstr "Parte de Trás do Polígono Oclusor"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Occluder Hole"
-msgstr "Criar Polígono Oclusor"
+msgstr "Buraco Oclusor"
#: main/main.cpp
msgid "Godot Physics"
-msgstr ""
+msgstr "Física do Godot"
#: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp
#: servers/visual/visual_server_scene.cpp
msgid "Use BVH"
-msgstr ""
+msgstr "Usar BVH"
#: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp
#: servers/visual/visual_server_scene.cpp
-#, fuzzy
msgid "BVH Collision Margin"
-msgstr "Modo Colisão"
+msgstr "Margem de Colisão BVH"
#: main/main.cpp
-#, fuzzy
msgid "Crash Handler"
-msgstr "Definir Manipulador"
+msgstr "Gerenciador de Falhas"
#: main/main.cpp
-#, fuzzy
msgid "Multithreaded Server"
-msgstr "Conjunto MultiNó"
+msgstr "Servidor com Multi-Thread"
#: main/main.cpp
msgid "RID Pool Prealloc"
-msgstr ""
+msgstr "Pré-alocação de pool RID"
#: main/main.cpp
-#, fuzzy
msgid "Debugger stdout"
-msgstr "Depurador"
+msgstr "Depurador stdout"
#: main/main.cpp
msgid "Max Chars Per Second"
-msgstr ""
+msgstr "Máximo de Caracteres Por Segundo"
#: main/main.cpp
msgid "Max Messages Per Frame"
-msgstr ""
+msgstr "Máximo de Mensagens Por Quadro"
#: main/main.cpp
msgid "Max Errors Per Second"
-msgstr ""
+msgstr "Máximo de Erros Por Segundo"
#: main/main.cpp
msgid "Max Warnings Per Second"
-msgstr ""
+msgstr "Máximo de Avisos Por Segundo"
#: main/main.cpp
msgid "Flush stdout On Print"
-msgstr ""
+msgstr "Esvaziar stdout Na Impressão"
#: main/main.cpp servers/visual_server.cpp
msgid "Logging"
-msgstr ""
+msgstr "Registro de Log"
#: main/main.cpp
msgid "File Logging"
-msgstr ""
+msgstr "Log de Arquivo"
#: main/main.cpp
-#, fuzzy
msgid "Enable File Logging"
-msgstr "Ativar Filtragem"
+msgstr "Ativar Log de Arquivos"
#: main/main.cpp
-#, fuzzy
msgid "Log Path"
-msgstr "Copiar Caminho"
+msgstr "Caminho de Log"
#: main/main.cpp
msgid "Max Log Files"
-msgstr ""
+msgstr "Máximo de Arquivos de Log"
#: main/main.cpp
msgid "Driver"
-msgstr ""
+msgstr "Driver"
#: main/main.cpp
-#, fuzzy
msgid "Driver Name"
-msgstr "Nome do Script:"
+msgstr "Nome do Driver"
#: main/main.cpp
msgid "Fallback To GLES2"
-msgstr ""
+msgstr "Alternar para GLES2"
#: main/main.cpp
msgid "Use Nvidia Rect Flicker Workaround"
-msgstr ""
+msgstr "Use a Solução Alternativa do Nvidia Rect Flicker"
#: main/main.cpp
msgid "DPI"
-msgstr ""
+msgstr "DPI"
#: main/main.cpp
msgid "Allow hiDPI"
-msgstr ""
+msgstr "Permitir hiDPI"
#: main/main.cpp
-#, fuzzy
msgid "V-Sync"
-msgstr "Sinc"
+msgstr "Sincronização Vertical"
#: main/main.cpp
-#, fuzzy
msgid "Use V-Sync"
-msgstr "Usar Ajuste"
+msgstr "Usar Sincronização Vertical"
#: main/main.cpp
msgid "Per Pixel Transparency"
-msgstr ""
+msgstr "Transparência Por Pixel"
#: main/main.cpp
msgid "Allowed"
-msgstr ""
+msgstr "Permitido"
#: main/main.cpp
msgid "Intended Usage"
-msgstr ""
+msgstr "Uso Pretendido"
#: main/main.cpp
-#, fuzzy
msgid "Framebuffer Allocation"
-msgstr "Seleção de Frame"
+msgstr "Alocação de Framebuffer"
#: main/main.cpp platform/uwp/os_uwp.cpp
-#, fuzzy
msgid "Energy Saving"
-msgstr "Erro Ao Gravar"
+msgstr "Economia de Energia"
#: main/main.cpp
msgid "Threads"
-msgstr ""
+msgstr "Threads"
#: main/main.cpp servers/physics_2d/physics_2d_server_wrap_mt.h
-#, fuzzy
msgid "Thread Model"
-msgstr "Alternar Modo"
+msgstr "Modelo de Thread"
#: main/main.cpp
msgid "Thread Safe BVH"
-msgstr ""
+msgstr "Thread Segura BVH"
#: main/main.cpp
msgid "Handheld"
-msgstr ""
+msgstr "Portátil"
#: main/main.cpp platform/javascript/export/export.cpp
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Orientation"
-msgstr "Documentação Online"
+msgstr "Orientação"
#: main/main.cpp scene/gui/scroll_container.cpp scene/gui/text_edit.cpp
#: scene/main/scene_tree.cpp scene/register_scene_types.cpp
-#, fuzzy
msgid "Common"
-msgstr "Comunidade"
+msgstr "Comum"
#: main/main.cpp
-#, fuzzy
msgid "Physics FPS"
-msgstr "Frame de Física %"
+msgstr "Física FPS"
#: main/main.cpp
-#, fuzzy
msgid "Force FPS"
-msgstr "Forçar Impulso"
+msgstr "Forçar FPS"
#: main/main.cpp
msgid "Enable Pause Aware Picking"
-msgstr ""
+msgstr "Ativar a Seleção Consciente de Pausa"
#: main/main.cpp scene/gui/item_list.cpp scene/gui/popup_menu.cpp
#: scene/gui/scroll_container.cpp scene/gui/text_edit.cpp scene/gui/tree.cpp
#: scene/main/viewport.cpp scene/register_scene_types.cpp
msgid "GUI"
-msgstr ""
+msgstr "Interface Gráfica"
#: main/main.cpp
msgid "Drop Mouse On GUI Input Disabled"
-msgstr ""
+msgstr "Desabilitar Soltar o Mouse na Entrada da Interface Gráfica"
#: main/main.cpp
msgid "stdout"
-msgstr ""
+msgstr "stdout"
#: main/main.cpp
msgid "Print FPS"
-msgstr ""
+msgstr "Imprimir FPS"
#: main/main.cpp
msgid "Verbose stdout"
-msgstr ""
+msgstr "stdout Verboso"
#: main/main.cpp scene/main/scene_tree.cpp scene/resources/multimesh.cpp
-#, fuzzy
msgid "Physics Interpolation"
-msgstr "Modo de Interpolação"
+msgstr "Interpolação Física"
#: main/main.cpp
-#, fuzzy
msgid "Enable Warnings"
-msgstr "Ativar Filtragem"
+msgstr "Ativar Avisos"
#: main/main.cpp
-#, fuzzy
msgid "Frame Delay Msec"
-msgstr "Seleção de Frame"
+msgstr "Atraso de Quadro Msec"
#: main/main.cpp
msgid "Low Processor Mode"
-msgstr ""
+msgstr "Modo de Baixo Uso do Processador"
#: main/main.cpp
msgid "Delta Sync After Draw"
-msgstr ""
+msgstr "Sincronização Delta Após Desenhar"
#: main/main.cpp
msgid "iOS"
-msgstr ""
+msgstr "iOS"
#: main/main.cpp
msgid "Hide Home Indicator"
-msgstr ""
+msgstr "Esconder Indicador de Home"
#: main/main.cpp
-#, fuzzy
msgid "Input Devices"
-msgstr "Todos os Aparelhos"
+msgstr "Dispositivos de Entrada"
#: main/main.cpp
-#, fuzzy
msgid "Pointing"
-msgstr "Ponto"
+msgstr "Pontuação"
#: main/main.cpp
msgid "Touch Delay"
-msgstr ""
+msgstr "Atraso de Toque"
#: main/main.cpp servers/visual_server.cpp
msgid "GLES3"
-msgstr ""
+msgstr "GLES3"
#: main/main.cpp servers/visual_server.cpp
-#, fuzzy
msgid "Shaders"
-msgstr "Shader"
+msgstr "Shaders"
#: main/main.cpp
-#, fuzzy
msgid "Debug Shader Fallbacks"
-msgstr "Forçar Shader de Reserva"
+msgstr "Depurar Fallbacks do Shader"
#: main/main.cpp scene/3d/baked_lightmap.cpp scene/3d/camera.cpp
#: scene/3d/world_environment.cpp scene/main/scene_tree.cpp
#: scene/resources/world.cpp
-#, fuzzy
msgid "Environment"
-msgstr "Ver ambiente"
+msgstr "Ambiente"
#: main/main.cpp
msgid "Default Clear Color"
-msgstr ""
+msgstr "Cor Clara Padrão"
#: main/main.cpp
msgid "Boot Splash"
-msgstr ""
+msgstr "Plano de Fundo de Inicialização"
#: main/main.cpp
-#, fuzzy
msgid "Show Image"
-msgstr "Mostrar ossos"
+msgstr "Mostrar Imagem"
#: main/main.cpp
msgid "Image"
-msgstr ""
+msgstr "Imagem"
#: main/main.cpp
msgid "Fullsize"
-msgstr ""
+msgstr "Tamanho Máximo"
#: main/main.cpp scene/resources/dynamic_font.cpp
-#, fuzzy
msgid "Use Filter"
-msgstr "Filtro:"
+msgstr "Usar Filtro"
#: main/main.cpp scene/resources/style_box.cpp
-#, fuzzy
msgid "BG Color"
-msgstr "Cores"
+msgstr "Cor de Fundo"
#: main/main.cpp
-#, fuzzy
msgid "macOS Native Icon"
-msgstr "Definir Ãcone de Tile"
+msgstr "Ãcone Nativo do macOS"
#: main/main.cpp
msgid "Windows Native Icon"
-msgstr ""
+msgstr "Ãcone nativo do Windows"
#: main/main.cpp
msgid "Buffering"
-msgstr ""
+msgstr "Buffering"
#: main/main.cpp
msgid "Agile Event Flushing"
-msgstr ""
+msgstr "Liberação Ãgil de Eventos"
#: main/main.cpp
msgid "Emulate Touch From Mouse"
-msgstr ""
+msgstr "Emular Toque do Mouse"
#: main/main.cpp
msgid "Emulate Mouse From Touch"
-msgstr ""
+msgstr "Emular o Mouse do Toque"
#: main/main.cpp
-#, fuzzy
msgid "Mouse Cursor"
-msgstr "Botão do rato"
+msgstr "Cursor do Mouse"
#: main/main.cpp
-#, fuzzy
msgid "Custom Image"
-msgstr "CustomNode"
+msgstr "Imagem Personalizada"
#: main/main.cpp
msgid "Custom Image Hotspot"
-msgstr ""
+msgstr "Imagem de Ponto de Acesso Personalizada"
#: main/main.cpp
-#, fuzzy
msgid "Tooltip Position Offset"
-msgstr "Compensação da rotação:"
+msgstr "Deslocamento de Posição da Dica"
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
-#, fuzzy
msgid "Debugger Agent"
-msgstr "Depurador"
+msgstr "Agente Depurador"
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
-#, fuzzy
msgid "Wait For Debugger"
-msgstr "Depurador"
+msgstr "Esperar o Depurador"
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
msgid "Wait Timeout"
-msgstr "Timeout de Espera"
+msgstr "Tempo Limite de Espera"
#: main/main.cpp
msgid "Runtime"
-msgstr ""
+msgstr "Execução"
#: main/main.cpp
msgid "Unhandled Exception Policy"
-msgstr ""
+msgstr "Política de Exceção não Tratada"
#: main/main.cpp
-#, fuzzy
msgid "Main Loop Type"
-msgstr "Localizar Tipo de Nó"
+msgstr "Tipo de Loop Principal"
#: main/main.cpp scene/gui/texture_progress.cpp
#: scene/gui/viewport_container.cpp
-#, fuzzy
msgid "Stretch"
-msgstr "Trazer"
+msgstr "Esticar"
#: main/main.cpp
-#, fuzzy
msgid "Aspect"
-msgstr "Inspetor"
+msgstr "Aspecto"
#: main/main.cpp
msgid "Shrink"
-msgstr ""
+msgstr "Encolher"
#: main/main.cpp scene/main/scene_tree.cpp
msgid "Auto Accept Quit"
-msgstr ""
+msgstr "Auto Aceitar Sair"
#: main/main.cpp scene/main/scene_tree.cpp
-#, fuzzy
msgid "Quit On Go Back"
-msgstr "Voltar"
+msgstr "Sair em Voltar"
#: main/main.cpp scene/main/viewport.cpp
-#, fuzzy
msgid "Snap Controls To Pixels"
-msgstr "Ajustar aos Lados do Nó"
+msgstr "Ajustar Controles aos Pixels"
#: main/main.cpp
msgid "Dynamic Fonts"
-msgstr ""
+msgstr "Fontes Dinâmicas"
#: main/main.cpp
msgid "Use Oversampling"
-msgstr ""
+msgstr "Usar Sobreamostragem"
#: modules/bullet/register_types.cpp modules/bullet/space_bullet.cpp
msgid "Active Soft World"
-msgstr ""
+msgstr "Mundo Suave Ativo"
#: modules/csg/csg_gizmos.cpp
msgid "CSG"
-msgstr ""
+msgstr "CSG"
#: modules/csg/csg_gizmos.cpp
msgid "Change Cylinder Radius"
@@ -16728,13 +16578,12 @@ msgid "Change Torus Outer Radius"
msgstr "Mudar Raio Externo do Toro"
#: modules/csg/csg_shape.cpp
-#, fuzzy
msgid "Operation"
-msgstr "Opções"
+msgstr "Operação"
#: modules/csg/csg_shape.cpp
msgid "Calculate Tangents"
-msgstr ""
+msgstr "Calcular Tangentes"
#: modules/csg/csg_shape.cpp
#, fuzzy
@@ -16792,7 +16641,7 @@ msgstr "Mostrar Guias"
#: modules/csg/csg_shape.cpp
msgid "Cone"
-msgstr ""
+msgstr "Cone"
#: modules/csg/csg_shape.cpp
#, fuzzy
@@ -16806,7 +16655,7 @@ msgstr "Mudar Raio Externo do Toro"
#: modules/csg/csg_shape.cpp
msgid "Ring Sides"
-msgstr ""
+msgstr "Lados do Anel"
#: modules/csg/csg_shape.cpp scene/2d/collision_polygon_2d.cpp
#: scene/2d/light_occluder_2d.cpp scene/2d/polygon_2d.cpp
@@ -16817,11 +16666,11 @@ msgstr "Polígonos"
#: modules/csg/csg_shape.cpp
msgid "Spin Degrees"
-msgstr ""
+msgstr "Graus de Rotação"
#: modules/csg/csg_shape.cpp
msgid "Spin Sides"
-msgstr ""
+msgstr "Girar Lados"
#: modules/csg/csg_shape.cpp
#, fuzzy
@@ -16835,11 +16684,11 @@ msgstr "Criar vértice interno"
#: modules/csg/csg_shape.cpp
msgid "Path Interval"
-msgstr ""
+msgstr "Intervalo de Caminho"
#: modules/csg/csg_shape.cpp
msgid "Path Simplify Angle"
-msgstr ""
+msgstr "Simplifique o Ângulo do Caminho"
#: modules/csg/csg_shape.cpp
#, fuzzy
@@ -16888,15 +16737,15 @@ msgstr "Mostrar Grelha Sempre"
#: modules/enet/networked_multiplayer_enet.cpp
msgid "Server Relay"
-msgstr ""
+msgstr "Retransmissão do Servidor"
#: modules/enet/networked_multiplayer_enet.cpp
msgid "DTLS Verify"
-msgstr ""
+msgstr "Verificar DTLS"
#: modules/enet/networked_multiplayer_enet.cpp
msgid "DTLS Hostname"
-msgstr ""
+msgstr "Nome do Host DTLS"
#: modules/enet/networked_multiplayer_enet.cpp
#, fuzzy
@@ -16905,11 +16754,11 @@ msgstr "Usar Ajuste"
#: modules/fbx/editor_scene_importer_fbx.cpp
msgid "FBX"
-msgstr ""
+msgstr "FBX"
#: modules/fbx/editor_scene_importer_fbx.cpp
msgid "Use FBX"
-msgstr ""
+msgstr "Usar FBX"
#: modules/gdnative/gdnative.cpp
#, fuzzy
@@ -17019,7 +16868,7 @@ msgstr "Script"
#: modules/gdscript/editor/gdscript_highlighter.cpp
msgid "Function Definition Color"
-msgstr ""
+msgstr "Função de Definição de Cor"
#: modules/gdscript/editor/gdscript_highlighter.cpp
#, fuzzy
@@ -17028,19 +16877,19 @@ msgstr "Copiar Caminho do Nó"
#: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp
msgid "Max Call Stack"
-msgstr ""
+msgstr "Pilha Máxima de Chamadas"
#: modules/gdscript/gdscript.cpp
msgid "Treat Warnings As Errors"
-msgstr ""
+msgstr "Tratar Avisos como Erros"
#: modules/gdscript/gdscript.cpp
msgid "Exclude Addons"
-msgstr ""
+msgstr "Excluir Complementos"
#: modules/gdscript/gdscript.cpp
msgid "Autocomplete Setters And Getters"
-msgstr ""
+msgstr "Autocompletar Setters e Getters"
#: modules/gdscript/gdscript_functions.cpp
msgid "Step argument is zero!"
@@ -17095,7 +16944,7 @@ msgstr "Mostrar Símbolos Nativos No Editor"
#: modules/gdscript/language_server/gdscript_language_server.cpp
msgid "Use Thread"
-msgstr ""
+msgstr "Usar Thread"
#: modules/gltf/editor_scene_exporter_gltf_plugin.cpp
msgid "Export Mesh GLTF2"
@@ -17147,11 +16996,11 @@ msgstr "Instância"
#: modules/gltf/gltf_accessor.cpp
msgid "Sparse Indices Buffer View"
-msgstr ""
+msgstr "Visualização de Buffer de Ãndices Esparsos"
#: modules/gltf/gltf_accessor.cpp
msgid "Sparse Indices Byte Offset"
-msgstr ""
+msgstr "Deslocamento de Bytes de Ãndices Esparsos"
#: modules/gltf/gltf_accessor.cpp
#, fuzzy
@@ -17160,11 +17009,11 @@ msgstr "A analisar geometria..."
#: modules/gltf/gltf_accessor.cpp
msgid "Sparse Values Buffer View"
-msgstr ""
+msgstr "Visualização de Buffer de Valores Esparsos"
#: modules/gltf/gltf_accessor.cpp
msgid "Sparse Values Byte Offset"
-msgstr ""
+msgstr "Deslocamento de Bytes de Valores Esparsos"
#: modules/gltf/gltf_buffer_view.cpp
#, fuzzy
@@ -17178,7 +17027,7 @@ msgstr "Tema Predefinido"
#: modules/gltf/gltf_buffer_view.cpp
msgid "Byte Stride"
-msgstr ""
+msgstr "Passo de Byte"
#: modules/gltf/gltf_buffer_view.cpp
#, fuzzy
@@ -17192,7 +17041,7 @@ msgstr "Tamanho:"
#: modules/gltf/gltf_camera.cpp
msgid "Zfar"
-msgstr ""
+msgstr "Zfar"
#: modules/gltf/gltf_camera.cpp
#, fuzzy
@@ -17214,7 +17063,7 @@ msgstr "Cores"
#: modules/gltf/gltf_light.cpp scene/3d/reflection_probe.cpp
#: scene/resources/environment.cpp
msgid "Intensity"
-msgstr ""
+msgstr "Intensidade"
#: modules/gltf/gltf_light.cpp scene/2d/light_2d.cpp scene/3d/light.cpp
#, fuzzy
@@ -17223,11 +17072,11 @@ msgstr "Mudar"
#: modules/gltf/gltf_light.cpp
msgid "Inner Cone Angle"
-msgstr ""
+msgstr "Ângulo do Cone Interno"
#: modules/gltf/gltf_light.cpp
msgid "Outer Cone Angle"
-msgstr ""
+msgstr "Ângulo do Cone Externo"
#: modules/gltf/gltf_mesh.cpp
#, fuzzy
@@ -17251,7 +17100,7 @@ msgstr "Plataforma"
#: modules/gltf/gltf_node.cpp scene/3d/mesh_instance.cpp
msgid "Skin"
-msgstr ""
+msgstr "Skin"
#: modules/gltf/gltf_node.cpp scene/3d/spatial.cpp
#, fuzzy
@@ -17270,11 +17119,11 @@ msgstr "Ponto"
#: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp
msgid "Roots"
-msgstr ""
+msgstr "Raizes"
#: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_state.cpp
msgid "Unique Names"
-msgstr ""
+msgstr "Nomes Únicos"
#: modules/gltf/gltf_skeleton.cpp
#, fuzzy
@@ -17293,7 +17142,7 @@ msgstr "Focar na Origem"
#: modules/gltf/gltf_skin.cpp
msgid "Inverse Binds"
-msgstr ""
+msgstr "Inverter Ligações"
#: modules/gltf/gltf_skin.cpp
#, fuzzy
@@ -17302,27 +17151,27 @@ msgstr "Mover Junta"
#: modules/gltf/gltf_skin.cpp
msgid "Joint I To Bone I"
-msgstr ""
+msgstr "Articulação I ao Osso I"
#: modules/gltf/gltf_skin.cpp
msgid "Joint I To Name"
-msgstr ""
+msgstr "Junta I A Nomear"
#: modules/gltf/gltf_skin.cpp
msgid "Godot Skin"
-msgstr ""
+msgstr "Skin Godot"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Diffuse Img"
-msgstr ""
+msgstr "Imagem Difusa"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Diffuse Factor"
-msgstr ""
+msgstr "Fator Difuso"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Gloss Factor"
-msgstr ""
+msgstr "Fator de Brilho"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Specular Factor"
@@ -17330,11 +17179,11 @@ msgstr "Fator Especular"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Spec Gloss Img"
-msgstr ""
+msgstr "Imagem Brilhante Especular"
#: modules/gltf/gltf_state.cpp
msgid "Json"
-msgstr ""
+msgstr "Json"
#: modules/gltf/gltf_state.cpp
#, fuzzy
@@ -17353,7 +17202,7 @@ msgstr "Com Dados"
#: modules/gltf/gltf_state.cpp
msgid "Use Named Skin Binds"
-msgstr ""
+msgstr "Usar Ligações de Skin Nomeadas"
#: modules/gltf/gltf_state.cpp
#, fuzzy
@@ -17362,7 +17211,7 @@ msgstr "Vista de Trás"
#: modules/gltf/gltf_state.cpp
msgid "Accessors"
-msgstr ""
+msgstr "Assessores"
#: modules/gltf/gltf_state.cpp
#, fuzzy
@@ -17382,11 +17231,11 @@ msgstr "Funcionalidades"
#: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp
msgid "Images"
-msgstr ""
+msgstr "Imagens"
#: modules/gltf/gltf_state.cpp
msgid "Cameras"
-msgstr ""
+msgstr "Câmeras"
#: modules/gltf/gltf_state.cpp servers/visual_server.cpp
#, fuzzy
@@ -17434,7 +17283,7 @@ msgstr "Consolidar Lightmaps"
#: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp
msgid "Cell"
-msgstr ""
+msgstr "Célula"
#: modules/gridmap/grid_map.cpp
#, fuzzy
@@ -17460,7 +17309,7 @@ msgstr "Centro"
#: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp
#: scene/resources/material.cpp
msgid "Mask"
-msgstr ""
+msgstr "Máscara"
#: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp
#, fuzzy
@@ -17638,19 +17487,19 @@ msgstr "Consolidar Lightmaps"
#: modules/lightmapper_cpu/register_types.cpp
msgid "Low Quality Ray Count"
-msgstr ""
+msgstr "Contagem de Raios de Baixa Qualidade"
#: modules/lightmapper_cpu/register_types.cpp
msgid "Medium Quality Ray Count"
-msgstr ""
+msgstr "Contagem de Raios de Média Qualidade"
#: modules/lightmapper_cpu/register_types.cpp
msgid "High Quality Ray Count"
-msgstr ""
+msgstr "Contagem de Raios de Alta Qualidade"
#: modules/lightmapper_cpu/register_types.cpp
msgid "Ultra Quality Ray Count"
-msgstr ""
+msgstr "Contagem de Raios de Ultra Qualidade"
#: modules/minimp3/audio_stream_mp3.cpp
#: modules/minimp3/resource_importer_mp3.cpp
@@ -17662,11 +17511,11 @@ msgstr "Compensação:"
#: modules/mobile_vr/mobile_vr_interface.cpp
msgid "Eye Height"
-msgstr ""
+msgstr "Altura do Olho"
#: modules/mobile_vr/mobile_vr_interface.cpp
msgid "IOD"
-msgstr ""
+msgstr "IOD"
#: modules/mobile_vr/mobile_vr_interface.cpp
#, fuzzy
@@ -17680,15 +17529,15 @@ msgstr "Vista sem sombras"
#: modules/mobile_vr/mobile_vr_interface.cpp
msgid "Oversample"
-msgstr ""
+msgstr "Excesso de Amostra"
#: modules/mobile_vr/mobile_vr_interface.cpp
msgid "K1"
-msgstr ""
+msgstr "K1"
#: modules/mobile_vr/mobile_vr_interface.cpp
msgid "K2"
-msgstr ""
+msgstr "K2"
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
@@ -17776,7 +17625,7 @@ msgstr "Feito!"
#: modules/opensimplex/noise_texture.cpp
msgid "Seamless"
-msgstr ""
+msgstr "Sem Emenda"
#: modules/opensimplex/noise_texture.cpp
#, fuzzy
@@ -17785,11 +17634,11 @@ msgstr "Escala aleatória:"
#: modules/opensimplex/noise_texture.cpp
msgid "Bump Strength"
-msgstr ""
+msgstr "Força da Colisão"
#: modules/opensimplex/noise_texture.cpp
msgid "Noise"
-msgstr ""
+msgstr "Ruido"
#: modules/opensimplex/noise_texture.cpp
#, fuzzy
@@ -17798,11 +17647,11 @@ msgstr "Compensação da grelha:"
#: modules/opensimplex/open_simplex_noise.cpp
msgid "Octaves"
-msgstr ""
+msgstr "Oitavas"
#: modules/opensimplex/open_simplex_noise.cpp
msgid "Period"
-msgstr ""
+msgstr "Periodo"
#: modules/opensimplex/open_simplex_noise.cpp
#, fuzzy
@@ -17811,11 +17660,11 @@ msgstr "Perspetiva"
#: modules/opensimplex/open_simplex_noise.cpp
msgid "Lacunarity"
-msgstr ""
+msgstr "Lacunaridade"
#: modules/regex/regex.cpp
msgid "Subject"
-msgstr ""
+msgstr "Sujeito"
#: modules/regex/regex.cpp
#, fuzzy
@@ -17829,15 +17678,15 @@ msgstr "Configuração:"
#: modules/upnp/upnp.cpp
msgid "Discover Multicast If"
-msgstr ""
+msgstr "Descobrir se Multicast"
#: modules/upnp/upnp.cpp
msgid "Discover Local Port"
-msgstr ""
+msgstr "Descobrir Porta Local"
#: modules/upnp/upnp.cpp
msgid "Discover IPv6"
-msgstr ""
+msgstr "Descobrir IPv6"
#: modules/upnp/upnp_device.cpp
#, fuzzy
@@ -17851,7 +17700,7 @@ msgstr "Definir tipo de variável"
#: modules/upnp/upnp_device.cpp
msgid "IGD Control URL"
-msgstr ""
+msgstr "URL de controle IGD"
#: modules/upnp/upnp_device.cpp
#, fuzzy
@@ -17860,7 +17709,7 @@ msgstr "Definir tipo de variável"
#: modules/upnp/upnp_device.cpp
msgid "IGD Our Addr"
-msgstr ""
+msgstr "IGD Nosso Endereço"
#: modules/upnp/upnp_device.cpp
#, fuzzy
@@ -18541,7 +18390,7 @@ msgstr "SubCall"
#: modules/visual_script/visual_script_nodes.cpp scene/gui/graph_node.cpp
msgid "Title"
-msgstr ""
+msgstr "Titulo"
#: modules/visual_script/visual_script_nodes.cpp
msgid "Construct %s"
@@ -18611,19 +18460,19 @@ msgstr "Modo Prioridade"
#: modules/webrtc/webrtc_data_channel.h
msgid "WebRTC"
-msgstr ""
+msgstr "WebRTC"
#: modules/webrtc/webrtc_data_channel.h
msgid "Max Channel In Buffer (KB)"
-msgstr ""
+msgstr "Buffer máximo de canal (KB)"
#: modules/websocket/websocket_client.cpp
msgid "Verify SSL"
-msgstr ""
+msgstr "Verificar SSL"
#: modules/websocket/websocket_client.cpp
msgid "Trusted SSL Certificate"
-msgstr ""
+msgstr "Certificado SSL Confiável"
#: modules/websocket/websocket_macros.h
#, fuzzy
@@ -18637,7 +18486,7 @@ msgstr "Tamanho Máximo (KB)"
#: modules/websocket/websocket_macros.h
msgid "Max In Packets"
-msgstr ""
+msgstr "Máximo de Pacotes de Entrada"
#: modules/websocket/websocket_macros.h
#, fuzzy
@@ -18646,7 +18495,7 @@ msgstr "Tamanho Máximo (KB)"
#: modules/websocket/websocket_macros.h
msgid "Max Out Packets"
-msgstr ""
+msgstr "Máximo de Pacotes de Saida"
#: modules/websocket/websocket_macros.h
#, fuzzy
@@ -18655,7 +18504,7 @@ msgstr "Analisador de Rede"
#: modules/websocket/websocket_server.cpp
msgid "Bind IP"
-msgstr ""
+msgstr "Associar IP"
#: modules/websocket/websocket_server.cpp
#, fuzzy
@@ -18664,7 +18513,7 @@ msgstr "Caminho da Chave Privada SSH"
#: modules/websocket/websocket_server.cpp platform/javascript/export/export.cpp
msgid "SSL Certificate"
-msgstr ""
+msgstr "Certificado SSL"
#: modules/websocket/websocket_server.cpp
#, fuzzy
@@ -18692,11 +18541,11 @@ msgstr "Funcionalidades Principais:"
#: modules/webxr/webxr_interface.cpp
msgid "Requested Reference Space Types"
-msgstr ""
+msgstr "Tipos de Espaço de Referência Solicitados"
#: modules/webxr/webxr_interface.cpp
msgid "Reference Space Type"
-msgstr ""
+msgstr "Tipo de Espaço de Referência"
#: modules/webxr/webxr_interface.cpp
#, fuzzy
@@ -18715,7 +18564,7 @@ msgstr "Ajuste Inteligente"
#: platform/android/export/export.cpp
msgid "Android SDK Path"
-msgstr ""
+msgstr "Caminho do SDK Android"
#: platform/android/export/export.cpp
#, fuzzy
@@ -18724,35 +18573,35 @@ msgstr "Depurador"
#: platform/android/export/export.cpp
msgid "Debug Keystore User"
-msgstr ""
+msgstr "Depuração do Usuário do Armazenamento de Chaves"
#: platform/android/export/export.cpp
msgid "Debug Keystore Pass"
-msgstr ""
+msgstr "Depurar Senha de Armazenamento de Chaves"
#: platform/android/export/export.cpp
msgid "Force System User"
-msgstr ""
+msgstr "Forçar Usuário do Sistema"
#: platform/android/export/export.cpp
msgid "Shutdown ADB On Exit"
-msgstr ""
+msgstr "Desligar o ADB na Saída"
#: platform/android/export/export_plugin.cpp
msgid "Launcher Icons"
-msgstr ""
+msgstr "Ãcones do Inicializador"
#: platform/android/export/export_plugin.cpp
msgid "Main 192 X 192"
-msgstr ""
+msgstr "Principal 192 X 192"
#: platform/android/export/export_plugin.cpp
msgid "Adaptive Foreground 432 X 432"
-msgstr ""
+msgstr "Primeiro Plano Adaptável 432 X 432"
#: platform/android/export/export_plugin.cpp
msgid "Adaptive Background 432 X 432"
-msgstr ""
+msgstr "Plano de Fundo Adaptável 432 X 432"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -18781,14 +18630,29 @@ msgid "The package must have at least one '.' separator."
msgstr "O pacote deve ter pelo menos um separador '.'."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Usar Compilação Personalizada"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
-msgstr ""
+msgstr "Usar Compilação Personalizada"
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid "Export Format"
msgstr "Exportar Caminho"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Tamanho do contorno:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Alvo"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18821,7 +18685,7 @@ msgstr "Senha"
#: platform/android/export/export_plugin.cpp
msgid "One Click Deploy"
-msgstr ""
+msgstr "Implantação com Um Clique"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -18830,17 +18694,7 @@ msgstr "Inspecionar instância anterior"
#: platform/android/export/export_plugin.cpp
msgid "Code"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Tamanho do contorno:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Alvo"
+msgstr "Código"
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
@@ -18864,7 +18718,7 @@ msgstr "Nome de Classe:"
#: platform/android/export/export_plugin.cpp
msgid "Retain Data On Uninstall"
-msgstr ""
+msgstr "Reter Dados na Desinstalação"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -18898,11 +18752,11 @@ msgstr "Empacotamento"
#: platform/android/export/export_plugin.cpp
msgid "Hand Tracking Frequency"
-msgstr ""
+msgstr "Frequência de Rastreamento Manual"
#: platform/android/export/export_plugin.cpp
msgid "Passthrough"
-msgstr ""
+msgstr "Atravessar"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -18936,7 +18790,7 @@ msgstr "Interface do Utilizador"
#: platform/android/export/export_plugin.cpp
msgid "Allow"
-msgstr ""
+msgstr "Permitir"
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
@@ -18955,7 +18809,7 @@ msgstr "Expressão"
#: platform/android/export/export_plugin.cpp
msgid "Salt"
-msgstr ""
+msgstr "Sal"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -19086,21 +18940,28 @@ msgid ""
"Note that the singleton was also renamed from \"GodotPayments\" to "
"\"GodotGooglePlayBilling\"."
msgstr ""
+"Módulo \"GodotPaymentV3\" inválido incluído na configuração do projeto "
+"\"android/modules\" (alterado no Godot 3.2.2).\n"
+"Substitua-o pelo plug-in primário \"GodotGooglePlayBilling\".\n"
+"Observe que o singleton também foi renomeado de \"GodotPayments\" para "
+"\"GodotGooglePlayBilling\"."
#: platform/android/export/export_plugin.cpp
msgid "\"Use Custom Build\" must be enabled to use the plugins."
msgstr "\"Use Custom Build\" têm de estar ativa para usar os plugins."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Rastreamento de Mão\" só é válido quando \"Modo Xr\" é \"Oculus Mobile "
"VrApi\" ou \"OpenXR\"."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr "\"Passthrough\" só é válido quando \"Modo Xr\" é \"OpenXR\"."
#: platform/android/export/export_plugin.cpp
@@ -19108,20 +18969,43 @@ msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
msgstr "\"Exportar AAB\" só é válido quando \"Use Custom Build\" está ativa."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Mudança de \"Min Sdk\" só é válida quando \"Use Custom Build\" está ativa."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Mudança de \"Target Sdk\" só é válida quando \"Use Custom Build\" está ativa."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"Versão de \"Target Sdk\" tem de ser maior ou igual à versão de \"Min Sdk\"."
@@ -19132,15 +19016,12 @@ msgid "Code Signing"
msgstr "Sinal"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"'apksigner' could not be found. Please check that the command is available "
"in the Android SDK build-tools directory. The resulting %s is unsigned."
msgstr ""
-"'apksigner' não foi encontrado.\n"
-"Verifique se o comando está disponível na diretoria Android SDK build-"
-"tools.\n"
-"O % resultante não está assinado."
+"'apksigner' não foi encontrado. Verifique se o comando está disponível no "
+"diretório do Android SDK build-tools. O %s resultante não está assinado."
#: platform/android/export/export_plugin.cpp
msgid "Signing debug %s..."
@@ -19155,9 +19036,8 @@ msgid "Could not find keystore, unable to export."
msgstr "Incapaz de encontrar keystore e exportar."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not start apksigner executable."
-msgstr "Não consegui iniciar o subprocesso!"
+msgstr "Não foi possível iniciar o executável apksigner."
#: platform/android/export/export_plugin.cpp
msgid "'apksigner' returned with error #%d"
@@ -19189,9 +19069,8 @@ msgid "Invalid filename! Android APK requires the *.apk extension."
msgstr "Nome de ficheiro inválido! APK Android exige a extensão *.apk."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Unsupported export format!"
-msgstr "Formato de exportação não suportado!\n"
+msgstr "Formato de exportação não suportado!"
#: platform/android/export/export_plugin.cpp
msgid ""
@@ -19202,15 +19081,13 @@ msgstr ""
"versão. Reinstale no menu 'Projeto'."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Android build version mismatch: Template installed: %s, Godot version: %s. "
"Please reinstall Android build template from 'Project' menu."
msgstr ""
-"Incompatibilidade da versão Android:\n"
-" Modelo instalado: %s\n"
-" Versão Godot: %s\n"
-"Reinstale o modelo de compilação Android no menu 'Projeto'."
+"Incompatibilidade de versão de compilação do Android: Modelo instalado: %s, "
+"versão Godot: %s. Por favor, reinstale o modelo de compilação do Android no "
+"menu 'Projeto'."
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -19221,9 +19098,8 @@ msgstr ""
"do projeto"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not export project files to gradle project."
-msgstr "Incapaz de exportar ficheiros do projeto para projeto gradle\n"
+msgstr "Incapaz de exportar ficheiros do projeto para projeto gradle."
#: platform/android/export/export_plugin.cpp
msgid "Could not write expansion package file!"
@@ -19234,14 +19110,13 @@ msgid "Building Android Project (gradle)"
msgstr "A compilar Projeto Android (gradle)"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Building of Android project failed, check output for the error. "
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
-"Falhou a compilação do projeto Android, verifique o erro na saída.\n"
-"Em alternativa visite docs.godotengine.org para a documentação sobre "
-"compilação Android."
+"Falhou a compilação do projeto Android, verifique o erro na saída. Em "
+"alternativa visite docs.godotengine.org para a documentação sobre compilação "
+"Android."
#: platform/android/export/export_plugin.cpp
msgid "Moving output"
@@ -19265,23 +19140,18 @@ msgid "Creating APK..."
msgstr "A criar APK..."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not find template APK to export: \"%s\"."
-msgstr ""
-"Incapaz de encontrar modelo APK para exportar:\n"
-"%s"
+msgstr "Incapaz de encontrar modelo APK para exportar: \"%s\"."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Missing libraries in the export template for the selected architectures: %s. "
"Please build a template with all required libraries, or uncheck the missing "
"architectures in the export preset."
msgstr ""
"Bibliotecas em falta no modelo de exportação para as arquiteturas "
-"selecionadas: %s.\n"
-"Construa um modelo com todas as bibliotecas necessárias, ou desmarque as "
-"arquiteturas em falta na predefinição de exportação."
+"selecionadas: %s. Construa um modelo com todas as bibliotecas necessárias, "
+"ou desmarque as arquiteturas em falta no preset de exportação."
#: platform/android/export/export_plugin.cpp
msgid "Adding files..."
@@ -19310,67 +19180,67 @@ msgstr "O carácter \"%s\" não é permitido no Identificador."
#: platform/iphone/export/export.cpp
msgid "Landscape Launch Screens"
-msgstr ""
+msgstr "Telas de Inicialização de Paisagem"
#: platform/iphone/export/export.cpp
msgid "iPhone 2436 X 1125"
-msgstr ""
+msgstr "iPhone 2436 X 1125"
#: platform/iphone/export/export.cpp
msgid "iPhone 2208 X 1242"
-msgstr ""
+msgstr "iPhone 2208 X 1242"
#: platform/iphone/export/export.cpp
msgid "iPad 1024 X 768"
-msgstr ""
+msgstr "iPad 1024 X 768"
#: platform/iphone/export/export.cpp
msgid "iPad 2048 X 1536"
-msgstr ""
+msgstr "iPad 2048 X 1536"
#: platform/iphone/export/export.cpp
msgid "Portrait Launch Screens"
-msgstr ""
+msgstr "Telas de Lançamento de Retrato"
#: platform/iphone/export/export.cpp
msgid "iPhone 640 X 960"
-msgstr ""
+msgstr "iPhone 640 X 960"
#: platform/iphone/export/export.cpp
msgid "iPhone 640 X 1136"
-msgstr ""
+msgstr "iPhone 640 X 1136"
#: platform/iphone/export/export.cpp
msgid "iPhone 750 X 1334"
-msgstr ""
+msgstr "iPhone 750 X 1334"
#: platform/iphone/export/export.cpp
msgid "iPhone 1125 X 2436"
-msgstr ""
+msgstr "iPhone 1125 X 2436"
#: platform/iphone/export/export.cpp
msgid "iPad 768 X 1024"
-msgstr ""
+msgstr "iPad 768 X 1024"
#: platform/iphone/export/export.cpp
msgid "iPad 1536 X 2048"
-msgstr ""
+msgstr "iPad 1536 X 2048"
#: platform/iphone/export/export.cpp
msgid "iPhone 1242 X 2208"
-msgstr ""
+msgstr "iPhone 1242 X 2208"
#: platform/iphone/export/export.cpp
msgid "App Store Team ID"
-msgstr ""
+msgstr "ID da Equipe na App Store"
#: platform/iphone/export/export.cpp
msgid "Provisioning Profile UUID Debug"
-msgstr ""
+msgstr "Depuração de UUID do Perfil de Provisionamento"
#: platform/iphone/export/export.cpp
msgid "Code Sign Identity Debug"
-msgstr ""
+msgstr "Depuração de Identidade de Sinal de Código"
#: platform/iphone/export/export.cpp
#, fuzzy
@@ -19379,11 +19249,11 @@ msgstr "Exportar com Depuração"
#: platform/iphone/export/export.cpp
msgid "Provisioning Profile UUID Release"
-msgstr ""
+msgstr "Liberação de UUID do Perfil de Provisionamento"
#: platform/iphone/export/export.cpp
msgid "Code Sign Identity Release"
-msgstr ""
+msgstr "Liberação de Identidade de Sinal de Código"
#: platform/iphone/export/export.cpp
#, fuzzy
@@ -19392,11 +19262,11 @@ msgstr "Modo exportação:"
#: platform/iphone/export/export.cpp
msgid "Targeted Device Family"
-msgstr ""
+msgstr "Família de Dispositivos Visados"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
msgid "Info"
-msgstr ""
+msgstr "Informações"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
#, fuzzy
@@ -19440,11 +19310,11 @@ msgstr "Interface do Utilizador"
#: platform/iphone/export/export.cpp
msgid "Accessible From Files App"
-msgstr ""
+msgstr "Acessível a partir do Aplicativo de Arquivos"
#: platform/iphone/export/export.cpp
msgid "Accessible From iTunes Sharing"
-msgstr ""
+msgstr "Acessível a partir do Compartilhamento do iTunes"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
#, fuzzy
@@ -19468,43 +19338,43 @@ msgstr "Descrições da Propriedade"
#: platform/iphone/export/export.cpp
msgid "iPhone 120 X 120"
-msgstr ""
+msgstr "iPhone 120 X 120"
#: platform/iphone/export/export.cpp
msgid "iPhone 180 X 180"
-msgstr ""
+msgstr "iPhone 180 X 180"
#: platform/iphone/export/export.cpp
msgid "iPad 76 X 76"
-msgstr ""
+msgstr "iPad 76 X 76"
#: platform/iphone/export/export.cpp
msgid "iPad 152 X 152"
-msgstr ""
+msgstr "iPad 152 X 152"
#: platform/iphone/export/export.cpp
msgid "iPad 167 X 167"
-msgstr ""
+msgstr "iPad 167 X 167"
#: platform/iphone/export/export.cpp
msgid "App Store 1024 X 1024"
-msgstr ""
+msgstr "App Store 1024 X 1024"
#: platform/iphone/export/export.cpp
msgid "Spotlight 40 X 40"
-msgstr ""
+msgstr "Destaque 40 X 40"
#: platform/iphone/export/export.cpp
msgid "Spotlight 80 X 80"
-msgstr ""
+msgstr "Destaque 80 X 80"
#: platform/iphone/export/export.cpp
msgid "Storyboard"
-msgstr ""
+msgstr "Storyboard"
#: platform/iphone/export/export.cpp
msgid "Use Launch Screen Storyboard"
-msgstr ""
+msgstr "Use o Storyboard da Tela de Inicialização"
#: platform/iphone/export/export.cpp
#, fuzzy
@@ -19590,7 +19460,7 @@ msgstr "Incapaz de ler ficheiro:"
#: platform/javascript/export/export.cpp
msgid "PWA"
-msgstr ""
+msgstr "PWA"
#: platform/javascript/export/export.cpp
#, fuzzy
@@ -19609,15 +19479,15 @@ msgstr "Expressão"
#: platform/javascript/export/export.cpp
msgid "For Desktop"
-msgstr ""
+msgstr "Para Desktop"
#: platform/javascript/export/export.cpp
msgid "For Mobile"
-msgstr ""
+msgstr "Para Mobile"
#: platform/javascript/export/export.cpp
msgid "HTML"
-msgstr ""
+msgstr "HTML"
#: platform/javascript/export/export.cpp
#, fuzzy
@@ -19631,15 +19501,15 @@ msgstr "CustomNode"
#: platform/javascript/export/export.cpp
msgid "Head Include"
-msgstr ""
+msgstr "Incluir Cabeçalho"
#: platform/javascript/export/export.cpp
msgid "Canvas Resize Policy"
-msgstr ""
+msgstr "Política de Redimensionamento da Tela"
#: platform/javascript/export/export.cpp
msgid "Focus Canvas On Start"
-msgstr ""
+msgstr "Focar Tela ao Iniciar"
#: platform/javascript/export/export.cpp
#, fuzzy
@@ -19648,23 +19518,23 @@ msgstr "Filtrar sinais"
#: platform/javascript/export/export.cpp
msgid "Progressive Web App"
-msgstr ""
+msgstr "Aplicativo da Web Progressivo"
#: platform/javascript/export/export.cpp
msgid "Offline Page"
-msgstr ""
+msgstr "Pagina Offline"
#: platform/javascript/export/export.cpp
msgid "Icon 144 X 144"
-msgstr ""
+msgstr "Ãcone 144 X 144"
#: platform/javascript/export/export.cpp
msgid "Icon 180 X 180"
-msgstr ""
+msgstr "Ãcone 180 X 180"
#: platform/javascript/export/export.cpp
msgid "Icon 512 X 512"
-msgstr ""
+msgstr "Ãcone 512 X 512"
#: platform/javascript/export/export.cpp
#, fuzzy
@@ -19683,15 +19553,15 @@ msgstr "Erro ao iniciar servidor HTTP:"
#: platform/javascript/export/export.cpp
msgid "Web"
-msgstr ""
+msgstr "Web"
#: platform/javascript/export/export.cpp
msgid "HTTP Host"
-msgstr ""
+msgstr "Host HTTP"
#: platform/javascript/export/export.cpp
msgid "HTTP Port"
-msgstr ""
+msgstr "Porta HTTP"
#: platform/javascript/export/export.cpp
#, fuzzy
@@ -19700,15 +19570,15 @@ msgstr "Usar Ajuste"
#: platform/javascript/export/export.cpp
msgid "SSL Key"
-msgstr ""
+msgstr "Chave SSL"
#: platform/osx/export/codesign.cpp
msgid "Can't get filesystem access."
-msgstr ""
+msgstr "Não é possível obter acesso ao sistema de arquivos."
#: platform/osx/export/codesign.cpp
msgid "Failed to get Info.plist hash."
-msgstr ""
+msgstr "Falha ao obter o hash de Info.plist."
#: platform/osx/export/codesign.cpp
#, fuzzy
@@ -19717,7 +19587,7 @@ msgstr "Nome do projeto inválido."
#: platform/osx/export/codesign.cpp
msgid "Invalid Info.plist, no bundle id."
-msgstr ""
+msgstr "Info.plist inválido, sem ID de pacote."
#: platform/osx/export/codesign.cpp
#, fuzzy
@@ -19731,7 +19601,7 @@ msgstr "Não consegui criar pasta."
#: platform/osx/export/codesign.cpp
msgid "Failed to extract thin binary."
-msgstr ""
+msgstr "Falha ao extrair o binário fino."
#: platform/osx/export/codesign.cpp
#, fuzzy
@@ -19740,7 +19610,7 @@ msgstr "Caminho base inválido."
#: platform/osx/export/codesign.cpp
msgid "Already signed!"
-msgstr ""
+msgstr "Já assinado!"
#: platform/osx/export/codesign.cpp
#, fuzzy
@@ -19749,7 +19619,7 @@ msgstr "Falha ao carregar recurso."
#: platform/osx/export/codesign.cpp
msgid "Failed to create _CodeSignature subfolder."
-msgstr ""
+msgstr "Falha ao criar a subpasta _CodeSignature."
#: platform/osx/export/codesign.cpp
#, fuzzy
@@ -19768,19 +19638,19 @@ msgstr "Extensão inválida."
#: platform/osx/export/codesign.cpp
msgid "Can't resize signature load command."
-msgstr ""
+msgstr "Não é possível redimensionar o comando de carregamento de assinatura."
#: platform/osx/export/codesign.cpp
msgid "Failed to create fat binary."
-msgstr ""
+msgstr "Falha ao criar binário gordo."
#: platform/osx/export/codesign.cpp
msgid "Unknown bundle type."
-msgstr ""
+msgstr "Tipo de pacote desconhecido."
#: platform/osx/export/codesign.cpp
msgid "Unknown object type."
-msgstr ""
+msgstr "Tipo de objeto desconhecido."
#: platform/osx/export/export.cpp
#, fuzzy
@@ -19789,7 +19659,7 @@ msgstr "Categoria:"
#: platform/osx/export/export.cpp
msgid "High Res"
-msgstr ""
+msgstr "Alta resolução"
#: platform/osx/export/export.cpp
#, fuzzy
@@ -19798,7 +19668,7 @@ msgstr "Descrição"
#: platform/osx/export/export.cpp
msgid "Address Book Usage Description"
-msgstr ""
+msgstr "Descrição de Uso do Catálogo de Endereços"
#: platform/osx/export/export.cpp
#, fuzzy
@@ -19822,15 +19692,15 @@ msgstr "Descrições do Método"
#: platform/osx/export/export.cpp
msgid "Downloads Folder Usage Description"
-msgstr ""
+msgstr "Descrição do Uso da Pasta de Downloads"
#: platform/osx/export/export.cpp
msgid "Network Volumes Usage Description"
-msgstr ""
+msgstr "Descrição do Uso de Volumes de Rede"
#: platform/osx/export/export.cpp
msgid "Removable Volumes Usage Description"
-msgstr ""
+msgstr "Descrição de Uso de Volumes Removíveis"
#: platform/osx/export/export.cpp platform/windows/export/export.cpp
#, fuzzy
@@ -19850,7 +19720,7 @@ msgstr "Tempo"
#: platform/osx/export/export.cpp
msgid "Hardened Runtime"
-msgstr ""
+msgstr "Tempo de Execução Reforçado"
#: platform/osx/export/export.cpp
#, fuzzy
@@ -19984,9 +19854,8 @@ msgid "Could not open icon file \"%s\"."
msgstr "Incapaz de exportar ficheiros do projeto"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not start xcrun executable."
-msgstr "Não consegui iniciar o subprocesso!"
+msgstr "Não foi possível iniciar o executável xcrun."
#: platform/osx/export/export.cpp
#, fuzzy
@@ -20058,9 +19927,8 @@ msgid "DMG Creation"
msgstr "Direções"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not start hdiutil executable."
-msgstr "Não consegui iniciar o subprocesso!"
+msgstr "Não foi possível iniciar o executável hdiutil."
#: platform/osx/export/export.cpp
msgid "`hdiutil create` failed - file exists."
@@ -20139,9 +20007,8 @@ msgid "ZIP Creation"
msgstr "Projeto"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not open file to read from path \"%s\"."
-msgstr "Incapaz de exportar ficheiros do projeto para projeto gradle\n"
+msgstr "Não foi possível abrir o arquivo para ler do caminho \"%s\"."
#: platform/osx/export/export.cpp
msgid "Invalid bundle identifier:"
@@ -20813,7 +20680,7 @@ msgstr "Aumentar Zoom"
msgid "Custom Viewport"
msgstr "1 Viewport"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21576,11 +21443,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Editar Conexão:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Ligação"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Distância de escolha:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Distância de escolha:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Avançado"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Ativar"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21598,16 +21497,6 @@ msgstr "Inverter na Horizontal"
msgid "Max Speed"
msgstr "Velocidade:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Distância de escolha:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Ativar"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21654,7 +21543,7 @@ msgstr "Viagem"
msgid "Rotation Degrees"
msgstr "Graus de Rotação"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Constante Global"
@@ -22858,6 +22747,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Normais da Transformação"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23785,6 +23681,11 @@ msgstr ""
"Em vez disso, mude o tamanho das formas de colisão filhas."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Manter Transformação Global"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25040,6 +24941,11 @@ msgstr "Pasta:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Apenas seleção"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Ativar"
@@ -25452,18 +25358,6 @@ msgstr "Exportar Caminho"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Este viewport não está definida como alvo de Renderização. Se pretende "
-"apresentar o seu conteúdo diretamente no ecrã, torne-a um filho de um "
-"Control de modo a que obtenha um tamanho. Caso contrário, torne-a um "
-"RenderTarget e atribua a sua textura interna a outro nó para visualizar."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25471,6 +25365,15 @@ msgstr ""
"dimensões para renderizar."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27238,6 +27141,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "A gerar AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Compensação:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index df7e56059b..a812335e4b 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -127,7 +127,7 @@
# Mário Victor Ribeiro Silva <mariovictorrs@gmail.com>, 2021.
# jak3z <jose_renato06@outlook.com>, 2021.
# Henrique Darko <henridark00@gmail.com>, 2021.
-# Cearaj <pmoraisleal@gmail.com>, 2021.
+# Cearaj <pmoraisleal@gmail.com>, 2021, 2022.
# Alefy San <alefyferreiradeoliveira@outlook.com>, 2021.
# Joel Gomes da Silva <joelgomes1994@hotmail.com>, 2021, 2022.
# Orangotango De tanga <luizinho0045@gmail.com>, 2021.
@@ -140,13 +140,15 @@
# blue wemes <bluewemes@gmail.com>, 2022.
# José Miranda Neto <dodimi95@gmail.com>, 2022.
# lucas rossy brasil coelho <lucasrossy270@gmail.com>, 2022.
+# Kaycke <kaycke@ymail.com>, 2022.
+# Ednaldo Pereira Confia <filat51823@storypo.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2022-06-19 11:52+0000\n"
-"Last-Translator: lucas rossy brasil coelho <lucasrossy270@gmail.com>\n"
+"PO-Revision-Date: 2022-07-16 06:20+0000\n"
+"Last-Translator: Cearaj <pmoraisleal@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -154,7 +156,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.13.1-dev\n"
+"X-Generator: Weblate 4.14-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -490,14 +492,12 @@ msgid "Max Size (KB)"
msgstr "Tamanho Máximo (KB)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "Modo de Movimentação"
+msgstr "Modo do cursor"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "Deletar Entrada"
+msgstr "Usar entrada acumulada"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -524,6 +524,10 @@ msgstr "Meta"
msgid "Command"
msgstr "Comando"
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr "Físico"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -575,6 +579,11 @@ msgid "Pressure"
msgstr "Pressão"
#: core/os/input_event.cpp
+#, fuzzy
+msgid "Pen Inverted"
+msgstr "Inverter"
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relativo"
@@ -711,9 +720,8 @@ msgstr "Nome do Diretório de Usuário Personalizado"
#: core/project_settings.cpp main/main.cpp
#: platform/javascript/export/export.cpp platform/osx/export/export.cpp
#: platform/uwp/os_uwp.cpp
-#, fuzzy
msgid "Display"
-msgstr "Exibir Tudo"
+msgstr "Exibição"
#: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp
#: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp
@@ -727,23 +735,20 @@ msgstr "Largura"
#: scene/resources/capsule_shape_2d.cpp scene/resources/cylinder_shape.cpp
#: scene/resources/font.cpp scene/resources/navigation_mesh.cpp
#: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp
-#, fuzzy
msgid "Height"
-msgstr "Luz"
+msgstr "Altura"
#: core/project_settings.cpp
msgid "Always On Top"
msgstr "Sempre no topo"
#: core/project_settings.cpp
-#, fuzzy
msgid "Test Width"
-msgstr "Largura Esquerda"
+msgstr "Largura de teste"
#: core/project_settings.cpp
-#, fuzzy
msgid "Test Height"
-msgstr "Testando"
+msgstr "Altura de teste"
#: core/project_settings.cpp editor/animation_track_editor.cpp
#: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp
@@ -778,14 +783,12 @@ msgid "Script Templates Search Path"
msgstr "Caminho de Pesquisa de Modelos de Script"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Autoload On Startup"
-msgstr "Carregamento Automático na Inicialização"
+msgstr "Carregamento Automático do Controle de Versão na Inicialização"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Plugin Name"
-msgstr "Controle de Versão"
+msgstr "Nome do plugin de controle de Versão"
#: core/project_settings.cpp scene/2d/collision_object_2d.cpp
#: scene/3d/collision_object.cpp scene/gui/control.cpp
@@ -1084,15 +1087,13 @@ msgstr "2D"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
-#, fuzzy
msgid "Snapping"
msgstr "Encaixe inteligente"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
-#, fuzzy
msgid "Use GPU Pixel Snap"
-msgstr "Usar Encaixe de Pixel"
+msgstr "Usar Encaixe de Pixels da GPU"
#: drivers/gles2/rasterizer_scene_gles2.cpp
#: drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1118,9 +1119,8 @@ msgid "Max Renderable Lights"
msgstr "Máximo de luzes renderizáveis"
#: drivers/gles3/rasterizer_scene_gles3.cpp
-#, fuzzy
msgid "Max Renderable Reflections"
-msgstr "Seleção Central"
+msgstr "Reflexões máximas renderizáveis"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Max Lights Per Object"
@@ -1128,7 +1128,7 @@ msgstr "Máximo de luzes por objeto"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Subsurface Scattering"
-msgstr ""
+msgstr "Dispersão Subsuperficial"
#: drivers/gles3/rasterizer_scene_gles3.cpp editor/animation_track_editor.cpp
#: editor/import/resource_importer_texture.cpp
@@ -1149,11 +1149,11 @@ msgstr "Seguir Superfície"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Weight Samples"
-msgstr ""
+msgstr "Amostras de Peso"
#: drivers/gles3/rasterizer_scene_gles3.cpp
msgid "Voxel Cone Tracing"
-msgstr ""
+msgstr "Rastreamento de Cone Voxel"
#: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp
msgid "High Quality"
@@ -1235,9 +1235,8 @@ msgstr "Alterar Chamada da Animação"
#: editor/animation_track_editor.cpp scene/2d/animated_sprite.cpp
#: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Frame"
-msgstr "Frame %"
+msgstr "Quadro"
#: editor/animation_track_editor.cpp editor/editor_profiler.cpp
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
@@ -1248,7 +1247,6 @@ msgstr "Tempo"
#: editor/animation_track_editor.cpp editor/import/resource_importer_scene.cpp
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Location"
msgstr "Localização"
@@ -1264,14 +1262,13 @@ msgid "Value"
msgstr "Valor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Arg Count"
-msgstr "Quantidade"
+msgstr "Quantia de argumentos"
#: editor/animation_track_editor.cpp main/main.cpp
#: modules/mono/mono_gd/gd_mono.cpp
msgid "Args"
-msgstr ""
+msgstr "Argumentos"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp
@@ -1295,17 +1292,15 @@ msgstr "Definir Manipulador"
#: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp
#: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp
msgid "Stream"
-msgstr ""
+msgstr "Fluxo"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Start Offset"
-msgstr "Deslocamento da Grade:"
+msgstr "Iniciar deslocamento"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "End Offset"
-msgstr "Deslocamento H"
+msgstr "Terminar deslocamento"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/import/resource_importer_scene.cpp
@@ -1318,7 +1313,6 @@ msgid "Animation"
msgstr "Animação"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Easing"
msgstr "Facilitar Entrada-Saída"
@@ -1433,14 +1427,12 @@ msgid "Time (s):"
msgstr "Tempo (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Position:"
-msgstr "Posição"
+msgstr "Posição:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rotation:"
-msgstr "Rotação"
+msgstr "Rotação:"
#: editor/animation_track_editor.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -1457,42 +1449,36 @@ msgid "Type:"
msgstr "Tipo:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "(Invalid, expected type: %s)"
-msgstr "Template de exportação inválido:"
+msgstr "(Inválido, tipo esperado: %s)"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Easing:"
-msgstr "Facilitar Entrada-Saída"
+msgstr "Facilitar Entrada-Saída:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "In-Handle:"
-msgstr "Definir Manipulador"
+msgstr "Definir Manipulador:"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Out-Handle:"
-msgstr "Definir Manipulador"
+msgstr "Definir Manipulador:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Stream:"
-msgstr "Par de stream"
+msgstr "Transmissão:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Start (s):"
-msgstr "Reinício(s):"
+msgstr "Início (s):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "End (s):"
-msgstr "[i]Fade In[/i](s):"
+msgstr "Final (is):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Clip:"
msgstr "Animações:"
@@ -1582,9 +1568,8 @@ msgid "Editors"
msgstr "Editores"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Confirm Insert Track"
-msgstr "Inserir Trilha e Chave na Anim"
+msgstr "Confirmar Inserção de Trilha"
#. TRANSLATORS: %s will be replaced by a phrase describing the target of track.
#: editor/animation_track_editor.cpp
@@ -1731,7 +1716,7 @@ msgstr "Métodos"
#: editor/animation_track_editor.cpp
msgid "Bezier"
-msgstr ""
+msgstr "Bézier"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2321,7 +2306,7 @@ msgstr "Abrir"
#: editor/dependency_editor.cpp
msgid "Owners of: %s (Total: %d)"
-msgstr ""
+msgstr "Proprietários de: %s (Total: %d)"
#: editor/dependency_editor.cpp
msgid ""
@@ -2678,9 +2663,8 @@ msgid "There is no '%s' file."
msgstr "Não existe o arquivo '%s'."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Layout:"
-msgstr "Layout"
+msgstr "Layout:"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
@@ -2729,9 +2713,8 @@ msgid "Create a new Bus Layout."
msgstr "Criar um novo Layout de Canais."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Audio Bus Layout"
-msgstr "Abrir Layout de Canais de Ãudio"
+msgstr "Layout de Canais de Ãudio"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -2884,22 +2867,19 @@ msgstr "Escolher"
#: editor/editor_export.cpp
msgid "Project export for platform:"
-msgstr ""
+msgstr "Exportação do projeto para plataforma:"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed with errors."
-msgstr "Copiar Caminho do Nó"
+msgstr "Concluído com erros."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed successfully."
-msgstr "Pacote instalado com sucesso!"
+msgstr "Concluído com sucesso."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed."
-msgstr "Falhou:"
+msgstr "Falhou."
#: editor/editor_export.cpp
msgid "Storing File:"
@@ -2914,29 +2894,24 @@ msgid "Packing"
msgstr "Empacotando"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save PCK"
-msgstr "Salvar Como"
+msgstr "Salvar PCK"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Cannot create file \"%s\"."
-msgstr "Não foi possível criar a pasta."
+msgstr "Não foi possível criar arquivo \"%s\"."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to export project files."
-msgstr "Não foi possível exportar os arquivos do projeto"
+msgstr "Falha ao exportar arquivos do projeto."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Can't open file to read from path \"%s\"."
-msgstr "Não é possível abrir arquivo para escrita:"
+msgstr "Não é possível abrir arquivo para leitura a partir do caminho \"%s\"."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save ZIP"
-msgstr "Salvar Como"
+msgstr "Salvar ZIP"
#: editor/editor_export.cpp
msgid ""
@@ -3014,37 +2989,36 @@ msgstr "Formato Binário"
#: editor/editor_export.cpp
msgid "64 Bits"
-msgstr ""
+msgstr "64 Bits"
#: editor/editor_export.cpp
msgid "Embed PCK"
-msgstr ""
+msgstr "Incorporar PCK"
#: editor/editor_export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Texture Format"
-msgstr "Região da Textura"
+msgstr "Formato da Textura"
#: editor/editor_export.cpp
msgid "BPTC"
-msgstr ""
+msgstr "BPTC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "S3TC"
-msgstr ""
+msgstr "S3TC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "ETC"
-msgstr ""
+msgstr "ETC"
#: editor/editor_export.cpp platform/osx/export/export.cpp
msgid "ETC2"
-msgstr ""
+msgstr "ETC2"
#: editor/editor_export.cpp
#, fuzzy
msgid "No BPTC Fallbacks"
-msgstr "Forçar Fallbacks do Shader"
+msgstr "Sem Fallbacks do BPTC"
#: editor/editor_export.cpp platform/android/export/export_plugin.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -3056,33 +3030,28 @@ msgstr "Modelo customizado de depuração não encontrado."
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
msgid "Custom release template not found."
-msgstr "Template customizado de release não encontrado."
+msgstr "Modelo customizado de lançamento não encontrado."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Prepare Template"
-msgstr "Gerenciar Templates"
+msgstr "Preparar Modelo"
#: editor/editor_export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "The given export path doesn't exist."
-msgstr "O caminho de exportação informado não existe:"
+msgstr "O caminho de exportação informado não existe."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
-#, fuzzy
msgid "Template file not found: \"%s\"."
-msgstr "Arquivo de modelo não encontrado:"
+msgstr "Arquivo de modelo não encontrado: \"%s\"."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to copy export template."
-msgstr "Template de exportação inválido:"
+msgstr "Falha ao copiar o modelo de exportação."
#: editor/editor_export.cpp platform/windows/export/export.cpp
#: platform/x11/export/export.cpp
-#, fuzzy
msgid "PCK Embedding"
-msgstr "Preenchimento"
+msgstr "Incorporação de PCK"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
@@ -3090,7 +3059,7 @@ msgstr "Em exportações de 32 bits, o PCK embutido não pode ser maior que 4GB.
#: editor/editor_export.cpp
msgid "Convert Text Resources To Binary On Export"
-msgstr ""
+msgstr "Converter Recursos de Texto para Binário na Exportação"
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -3297,9 +3266,8 @@ msgid "Manage Editor Feature Profiles"
msgstr "Gerenciar perfis de recurso do editor"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Default Feature Profile"
-msgstr "Perfil de funcionalidade do Godot"
+msgstr "Perfil de funcionalidade Padrão"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -3411,7 +3379,7 @@ msgstr "Mostrar Arquivos Ocultos"
#: editor/editor_file_dialog.cpp
msgid "Disable Overwrite Warning"
-msgstr ""
+msgstr "Desativar Aviso de Substituição"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
@@ -3514,7 +3482,7 @@ msgstr "(Re)Importando Assets"
#: editor/editor_file_system.cpp
msgid "Reimport Missing Imported Files"
-msgstr ""
+msgstr "Reimportar Arquivos Importados Ausentes"
#: editor/editor_help.cpp scene/2d/camera_2d.cpp scene/gui/control.cpp
#: scene/gui/nine_patch_rect.cpp scene/resources/dynamic_font.cpp
@@ -3625,7 +3593,7 @@ msgstr "Ajuda"
#: editor/editor_help.cpp
msgid "Sort Functions Alphabetically"
-msgstr ""
+msgstr "Classificar Funções em Ordem Alfabética"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -3707,7 +3675,7 @@ msgstr "Propriedade:"
#: editor/editor_inspector.cpp editor/editor_spin_slider.cpp
#, fuzzy
msgid "Label"
-msgstr "Valor"
+msgstr "Etiqueta"
#: editor/editor_inspector.cpp editor/editor_spin_slider.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -4091,18 +4059,16 @@ msgid "Quick Open Script..."
msgstr "Abrir Script Rapidamente..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save & Reload"
-msgstr "Salvar e Reiniciar"
+msgstr "Salvar & Recarregar"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save changes to '%s' before reloading?"
-msgstr "Salvar alterações em '%s' antes de fechar?"
+msgstr "Salvar alterações em '%s' antes de recarregar?"
#: editor/editor_node.cpp
msgid "Save & Close"
-msgstr "Salvar e Fechar"
+msgstr "Salvar & Fechar"
#: editor/editor_node.cpp
msgid "Save changes to '%s' before closing?"
@@ -4217,9 +4183,8 @@ msgid "Open Project Manager?"
msgstr "Abrir Gerenciador de Projetos?"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save changes to the following scene(s) before reloading?"
-msgstr "Salvar alterações na(s) seguinte(s) cena(s) antes de sair?"
+msgstr "Salvar alterações na(s) seguinte(s) cena(s) antes de recarregar?"
#: editor/editor_node.cpp
msgid "Save & Quit"
@@ -4412,6 +4377,8 @@ msgstr "%d mais arquivo(s)"
msgid ""
"Unable to write to file '%s', file in use, locked or lacking permissions."
msgstr ""
+"Não foi possível gravar no arquivo '%s', arquivo em uso, bloqueado ou sem "
+"permissões."
#: editor/editor_node.cpp editor/editor_settings.cpp editor/scene_tree_dock.cpp
#: servers/arvr/arvr_interface.cpp
@@ -4423,53 +4390,48 @@ msgid "Scene Tabs"
msgstr "Abas de Cena"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Always Show Close Button"
-msgstr "Sempre Mostrar Grade"
+msgstr "Sempre mostrar o botão de fechar."
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Resize If Many Tabs"
-msgstr ""
+msgstr "Redimensionar se houver muitas guias"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Minimum Width"
-msgstr ""
+msgstr "Largura Mínima"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Output"
msgstr "Saída"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Always Clear Output On Play"
-msgstr "Limpar Saída"
+msgstr "Sempre limpar saída ao jogar"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Always Open Output On Play"
-msgstr ""
+msgstr "Sempre abrir a saída ao jogar"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Always Close Output On Stop"
-msgstr ""
+msgstr "Sempre fechar a saída ao parar"
#: editor/editor_node.cpp
msgid "Save On Focus Loss"
-msgstr ""
+msgstr "Salvar em caso de perda de foco"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Save Each Scene On Quit"
-msgstr "Salvar Ramo como Cena"
+msgstr "Salvar cada cena ao sair"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Quit Confirmation"
-msgstr "Visualizar Informações"
+msgstr "Confirmação de saída"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Show Update Spinner"
-msgstr "Ocultar Spinner de Atualização"
+msgstr "Mostrar Spinner de Atualização"
#: editor/editor_node.cpp
msgid "Update Continuously"
@@ -4489,51 +4451,47 @@ msgstr "Restaurar Cenas ao Carregar"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Show Thumbnail On Hover"
-msgstr ""
+msgstr "Mostrar miniatura ao passar o mouse"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Inspector"
msgstr "Inspetor"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Default Property Name Style"
-msgstr "Caminho Padrão do Projeto"
+msgstr "Estilo de Nome de Propriedade Padrão"
#: editor/editor_node.cpp
msgid "Default Float Step"
-msgstr ""
+msgstr "Passo de ponto flutuante padrão"
#: editor/editor_node.cpp scene/gui/tree.cpp
-#, fuzzy
msgid "Disable Folding"
-msgstr "Botão Desativado"
+msgstr "Desativar Dobragem"
#: editor/editor_node.cpp
msgid "Auto Unfold Foreign Scenes"
-msgstr ""
+msgstr "Desdobrar cenas estrangeiras automaticamente"
#: editor/editor_node.cpp
msgid "Horizontal Vector2 Editing"
-msgstr ""
+msgstr "Edição Horizontal do Vector2"
#: editor/editor_node.cpp
msgid "Horizontal Vector Types Editing"
-msgstr ""
+msgstr "Edição Horizontal de Tipos de Vetor"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Resources In Current Inspector"
-msgstr "Abrir no inspetor"
+msgstr "Abrir Recursos no Inspetor Atual"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Resources To Open In New Inspector"
-msgstr "Abrir no inspetor"
+msgstr "Recursos para abrir em Novo Inspetor"
#: editor/editor_node.cpp
msgid "Default Color Picker Mode"
-msgstr ""
+msgstr "Modo de Seletor de Cores Padrão"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
@@ -4689,7 +4647,7 @@ msgstr "Sair para a Lista de Projetos"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
-msgstr "Distribuir com Depuragem Remota"
+msgstr "Implantar com Depuração Remota"
#: editor/editor_node.cpp
msgid ""
@@ -5676,6 +5634,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Seleção Do GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8130,11 +8093,20 @@ msgid "New Anim"
msgstr "Nova Animação"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Criar Nova Animação"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Alterar Nome da Animação:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Renomear Animação"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Excluir Animação?"
@@ -8152,11 +8124,6 @@ msgid "Animation name already exists!"
msgstr "O nome da animação já existe!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Renomear Animação"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplicar Animação"
@@ -8303,10 +8270,6 @@ msgid "Pin AnimationPlayer"
msgstr "Fixar AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Criar Nova Animação"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nome da Animação:"
@@ -10882,7 +10845,7 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Results"
-msgstr "Pesquisar resultados"
+msgstr "Resultados de Pesquisa"
#: editor/plugins/script_editor_plugin.cpp
msgid "Open Dominant Script On Scene Change"
@@ -13246,15 +13209,15 @@ msgstr "Nenhuma mensagem de commit foi fornecida."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
-msgstr "Confirmação"
+msgstr "Commit"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Staged Changes"
-msgstr "Mudanças em fases"
+msgstr "Alterações Preparadas"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Unstaged Changes"
-msgstr "Mudanças Não Fásicas"
+msgstr "Alterações não Preparadas"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit:"
@@ -13318,7 +13281,7 @@ msgstr "Preparar todas as alterações"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Unstage all changes"
-msgstr "Desfaça todas as alterações"
+msgstr "Desfazer todas as alterações"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Message"
@@ -13326,15 +13289,15 @@ msgstr "Mensagem de Commit"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
-msgstr "Confirmar Mudanças"
+msgstr "Criar Commit"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit List"
-msgstr "Lista de compromissos"
+msgstr "Lista de Commit"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit list size"
-msgstr "Confirmar tamanho da lista"
+msgstr "Tamanho da lista de commit"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Branches"
@@ -14439,7 +14402,6 @@ msgid "Export PCK/Zip..."
msgstr "Exportar PCK/Zip..."
#: editor/project_export.cpp
-#, fuzzy
msgid "Export Project..."
msgstr "Exportar Projeto…"
@@ -14452,7 +14414,6 @@ msgid "Choose an export mode:"
msgstr "Escolha um modo de exportação:"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export All..."
msgstr "Exportar tudo…"
@@ -15192,7 +15153,7 @@ msgstr "Plugins"
#: editor/project_settings_editor.cpp
msgid "Import Defaults"
-msgstr "Importar padrões"
+msgstr "Padrões de Importação"
#: editor/property_editor.cpp
msgid "Preset..."
@@ -16019,9 +15980,8 @@ msgid "Attach Node Script"
msgstr "Adicionar Script ao Nó"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Remote %s:"
-msgstr "Remoto %s:"
+msgstr "%s remoto:"
#: editor/script_editor_debugger.cpp
msgid "Bytes:"
@@ -18510,9 +18470,8 @@ msgstr "Redimensionar Vetor"
#: modules/visual_script/visual_script_nodes.cpp scene/resources/material.cpp
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Operator"
-msgstr "Iterador"
+msgstr "Operador"
#: modules/visual_script/visual_script_nodes.cpp
msgid "Invalid argument of type:"
@@ -18870,6 +18829,11 @@ msgstr "O pacote deve ter pelo menos um separador '.'."
#: platform/android/export/export_plugin.cpp
#, fuzzy
+msgid "Custom Build"
+msgstr "Usar Diretório de Usuário Personalizado"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid "Use Custom Build"
msgstr "Usar Diretório de Usuário Personalizado"
@@ -18878,6 +18842,15 @@ msgstr "Usar Diretório de Usuário Personalizado"
msgid "Export Format"
msgstr "Caminho de Exportação"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr "SDK Mínimo"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "FPS alvo"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18921,15 +18894,6 @@ msgstr "Inspecionar a Instância Anterior"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr "SDK Mínimo"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "FPS alvo"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19181,14 +19145,16 @@ msgstr ""
"utilizar plugins."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Hand Tracking\" só é válido quando o \"Xr Mode\" é \"Oculus Mobile VR\"."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"\"Passthrough\" só é válido quando o \"Xr Mode\" é \"Oculus Mobile VR\"."
@@ -19199,22 +19165,45 @@ msgstr ""
"habilitado."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Exportar AAB\" só é válido quando \"Usar Compilação Customizada\" está "
"habilitado."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Exportar AAB\" só é válido quando \"Usar Compilação Customizada\" está "
"habilitado."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"Versão do \"Target Sdk\" precisa ser igual ou maior que a versão do \"Min "
"Sdk\"."
@@ -19247,9 +19236,8 @@ msgid "Could not find keystore, unable to export."
msgstr "O keystore não foi encontrado, não foi possível exportar."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not start apksigner executable."
-msgstr "Não se pôde iniciar sub-processo!"
+msgstr "Não foi possível iniciar o executável apksigner."
#: platform/android/export/export_plugin.cpp
msgid "'apksigner' returned with error #%d"
@@ -19293,15 +19281,13 @@ msgstr ""
"'Projeto'."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Android build version mismatch: Template installed: %s, Godot version: %s. "
"Please reinstall Android build template from 'Project' menu."
msgstr ""
-"Diferença na versão da build do Android:\n"
-" Modelo instalado: %s\n"
-" Versão do Godot: %s\n"
-"Por favor reinstale o modelo de compilação do Android pelo menu 'Projeto'."
+"Diferença na versão da build do Android: Modelo instalado: %s, Versão do "
+"Godot: %s. Por favor reinstale o modelo de compilação do Android pelo menu "
+"'Projeto'."
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -19326,14 +19312,13 @@ msgid "Building Android Project (gradle)"
msgstr "Construindo Projeto Android (gradle)"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Building of Android project failed, check output for the error. "
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
-"A construção do projeto Android falhou, verifique a saída para detalhes.\n"
-"Alternativamente, visite docs.godotengine.org para ver a documentação de "
-"compilação do Android."
+"A compilação do projeto Android falhou, verifique a saída para detalhes. Ou "
+"então visite docs.godotengine.org para ver a documentação de compilação do "
+"Android."
#: platform/android/export/export_plugin.cpp
msgid "Moving output"
@@ -19348,41 +19333,35 @@ msgstr ""
"diretório do projeto gradle por saídas."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Package not found: \"%s\"."
-msgstr "Pacote não encontrado: '%s'"
+msgstr "Pacote não encontrado: \"%s\"."
#: platform/android/export/export_plugin.cpp
msgid "Creating APK..."
msgstr "Criando APK..."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not find template APK to export: \"%s\"."
-msgstr ""
-"Não foi possível encontrar o modelo de APK para exportar:\n"
-"%s"
+msgstr "Não foi possível encontrar o modelo de APK para exportação: %s."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Missing libraries in the export template for the selected architectures: %s. "
"Please build a template with all required libraries, or uncheck the missing "
"architectures in the export preset."
msgstr ""
"Faltam bibliotecas no modelo de exportação para as arquiteturas "
-"selecionadas: %s.\n"
-"Crie um modelo com todas as bibliotecas necessárias ou desmarque as "
-"arquiteturas ausentes na predefinição de exportação."
+"selecionadas: %s. Por favor, crie um modelo com todas as bibliotecas "
+"necessárias ou desmarque as arquiteturas ausentes na predefinição de "
+"exportação."
#: platform/android/export/export_plugin.cpp
msgid "Adding files..."
msgstr "Adicionando arquivos..."
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not export project files."
-msgstr "Não foi possível exportar os arquivos do projeto"
+msgstr "Não foi possível exportar os arquivos do projeto."
#: platform/android/export/export_plugin.cpp
msgid "Aligning APK..."
@@ -19653,9 +19632,8 @@ msgid "Run exported HTML in the system's default browser."
msgstr "Rodar HTML exportado no navegador padrão do sistema."
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not open template for export: \"%s\"."
-msgstr "Não foi possível abrir o modelo para exportar:"
+msgstr "Não foi possível abrir o modelo para exportação: \"%s\"."
#: platform/javascript/export/export.cpp
#, fuzzy
@@ -19673,9 +19651,8 @@ msgid "Icon Creation"
msgstr "Definir Margem"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not read file: \"%s\"."
-msgstr "Não foi possível ler o arquivo:"
+msgstr "Não foi possível ler o arquivo: \"%s\"."
#: platform/javascript/export/export.cpp
msgid "PWA"
@@ -19755,9 +19732,8 @@ msgid "Icon 512 X 512"
msgstr ""
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not read HTML shell: \"%s\"."
-msgstr "Não foi possível ler o shell HTML:"
+msgstr "Não foi possível ler o shell HTML: \"%s\"."
#: platform/javascript/export/export.cpp
#, fuzzy
@@ -19765,9 +19741,8 @@ msgid "Could not create HTTP server directory: %s."
msgstr "Não foi possível criar o diretório do servidor HTTP:"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Error starting HTTP server: %d."
-msgstr "Erro ao iniciar servidor HTTP:"
+msgstr "Erro ao iniciar o servidor HTTP: %d."
#: platform/javascript/export/export.cpp
msgid "Web"
@@ -20066,19 +20041,16 @@ msgid "Apple Team ID"
msgstr ""
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not open icon file \"%s\"."
-msgstr "Não foi possível exportar os arquivos do projeto"
+msgstr "Não foi possível abrir o arquivo de ícone \"%s\"."
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not start xcrun executable."
-msgstr "Não se pôde iniciar sub-processo!"
+msgstr "Não foi possível iniciar o executável xcrun."
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Notarization failed."
-msgstr "Localização"
+msgstr "Falha na notarização."
#: platform/osx/export/export.cpp
msgid "Notarization request UUID: \"%s\""
@@ -20145,9 +20117,8 @@ msgid "DMG Creation"
msgstr "Direções"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not start hdiutil executable."
-msgstr "Não se pôde iniciar sub-processo!"
+msgstr "Não foi possível iniciar o executável hdiutil."
#: platform/osx/export/export.cpp
msgid "`hdiutil create` failed - file exists."
@@ -20163,14 +20134,13 @@ msgid "Creating app bundle"
msgstr "Criando Miniatura"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not find template app to export: \"%s\"."
-msgstr "Não foi possível encontrar o aplicativo de modelo para exportar:"
+msgstr ""
+"Não foi possível encontrar o aplicativo de modelo para exportar: \"%s\"."
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Invalid export format."
-msgstr "Template de exportação inválido:"
+msgstr "Formato de exportação inválido."
#: platform/osx/export/export.cpp
msgid ""
@@ -20226,10 +20196,9 @@ msgid "ZIP Creation"
msgstr "Projeção"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not open file to read from path \"%s\"."
msgstr ""
-"Não foi possível exportar os arquivos do projeto ao projeto do gradle\n"
+"Não foi possível abrir o arquivo para leitura a partir do caminho \"%s\"."
#: platform/osx/export/export.cpp
msgid "Invalid bundle identifier:"
@@ -20638,9 +20607,8 @@ msgid "Could not find osslsigncode executable at \"%s\"."
msgstr "O keystore não foi encontrado, não foi possível exportar."
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Invalid identity type."
-msgstr "O nome não é um identificador válido:"
+msgstr "Tipo de identidade inválido."
#: platform/windows/export/export.cpp
#, fuzzy
@@ -20660,9 +20628,8 @@ msgid ""
msgstr ""
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Failed to remove temporary file \"%s\"."
-msgstr "Não é possível remover o arquivo temporário:"
+msgstr "Falha ao remover o arquivo temporário \"%s\"."
#: platform/windows/export/export.cpp
msgid ""
@@ -20896,7 +20863,7 @@ msgstr "Ampliar"
msgid "Custom Viewport"
msgstr "1 Viewport"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21644,11 +21611,42 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Margem de Ligação da Borda"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "VInculamento"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Distância do Caminho U"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr "Distância Máxima do Caminho"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Avançado"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Habilitar"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21665,15 +21663,6 @@ msgstr "Inverter Horizontalmente"
msgid "Max Speed"
msgstr "Velocidade Máxima"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr "Distância Máxima do Caminho"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Habilitar"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21716,7 +21705,7 @@ msgstr "Viagem"
msgid "Rotation Degrees"
msgstr "Graus de Rotação"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr "Rotação Global"
@@ -22882,6 +22871,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Normais de Transformação"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23787,6 +23783,11 @@ msgstr ""
"Altere o tamanho em formas de colisão de crianças."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Manter Transformação Global"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25040,6 +25041,11 @@ msgstr "Pasta:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Selecionar Apenas"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Habilitar"
@@ -25449,19 +25455,6 @@ msgstr "Caminho de Exportação"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Este viewport não está definido como destino de renderização. Se você "
-"pretende que ele mostre seu conteúdo diretamente na tela, faça-o filho de um "
-"nó de Controle para que ele possa ter um tamanho. Caso contrário, defina-o "
-"como destino de renderização e atribua sua textura interna a algum nó para "
-"exibir."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25469,6 +25462,15 @@ msgstr ""
"dimensões para renderizar algo."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27155,9 +27157,8 @@ msgid "Source Geometry Mode"
msgstr ""
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Source Group Name"
-msgstr "Origem"
+msgstr "Origem do Nome do Grupo"
#: scene/resources/navigation_mesh.cpp
msgid "Cells"
@@ -27226,6 +27227,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Gerando AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Deslocamento Base"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index b6b92325e4..395185bd3e 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -418,6 +418,11 @@ msgstr ""
msgid "Command"
msgstr "Comunitate"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Cadru Fizic %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -472,6 +477,10 @@ msgid "Pressure"
msgstr "Presiune"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Relativ"
@@ -5619,6 +5628,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Toată selecția"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8086,11 +8100,20 @@ msgid "New Anim"
msgstr "Anim Nouă"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Creează Animație Nouă"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Schimbă Numele Animației:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Redenumește Animația"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Ștergi Animația?"
@@ -8110,11 +8133,6 @@ msgid "Animation name already exists!"
msgstr "EROARE: Numele animației există deja!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Redenumește Animația"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplicare Animație"
@@ -8262,10 +8280,6 @@ msgid "Pin AnimationPlayer"
msgstr "Lipește Animație"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Creează Animație Nouă"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Nume Animație:"
@@ -18991,6 +19005,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Creează Nod"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18999,6 +19018,16 @@ msgstr ""
msgid "Export Format"
msgstr "Exportă Proiectul"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Dimensiunea Conturului:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Suprafață Țintă:"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -19037,16 +19066,6 @@ msgstr "Fila anterioară"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Dimensiunea Conturului:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Suprafață Țintă:"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19292,12 +19311,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19306,17 +19325,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20968,7 +21007,7 @@ msgstr "Apropiere"
msgid "Custom Viewport"
msgstr "Arată Fereastra de Lucru"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21688,34 +21727,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Modifică Conexiunea:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Rotație aleatorie:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Alege o Scenă Principală"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Avansate"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Activați"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Activați"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21758,7 +21819,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr "Pas Rotație:"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Permanent"
@@ -22899,6 +22960,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformare uniformă."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23776,6 +23844,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Anim Schimbare transformare"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24985,6 +25058,11 @@ msgstr "Folderul:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Numai Selecția"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Activați"
@@ -25387,16 +25465,17 @@ msgstr "Exportă Proiectul"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -27139,6 +27218,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Generare AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Compensare Grilă:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index b920136351..befaceac4c 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -115,13 +115,16 @@
# Deleted User <noreply+44465@weblate.org>, 2022.
# Bozhko Artyom Dmitrievich <jek_sun@mail.ru>, 2022.
# FuzzMix <fmwolfiechad@gmail.com>, 2022.
+# Jasuse <jasusemaele@gmail.com>, 2022.
+# Vadim Mitroshkin <Vadim7540@yandex.ru>, 2022.
+# Maksim Marchukov <mar.maksim63@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-12 13:19+0000\n"
-"Last-Translator: FuzzMix <fmwolfiechad@gmail.com>\n"
+"PO-Revision-Date: 2022-07-17 07:14+0000\n"
+"Last-Translator: Maksim Marchukov <mar.maksim63@gmail.com>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
"Language: ru\n"
@@ -130,7 +133,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.14-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -469,14 +472,12 @@ msgid "Max Size (KB)"
msgstr "МакÑимальный размер (КБ)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "Режим перемещениÑ"
+msgstr "Режим мыши"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "Удалить вход"
+msgstr "ИÑпользовать накопленный ввод"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -503,6 +504,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "(ФизичеÑкаÑ)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -554,6 +560,10 @@ msgid "Pressure"
msgstr "Давление"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "ОтноÑительный"
@@ -2332,8 +2342,9 @@ msgid "Fix Dependencies"
msgstr "ИÑправить завиÑимоÑти"
#: editor/dependency_editor.cpp
+#, fuzzy
msgid "Errors loading!"
-msgstr "Ошибки загрузки!"
+msgstr "Ошибки загружаютÑÑ!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
@@ -5588,6 +5599,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr "ÐÐ°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ñ Ð¿Ð¾ иÑтории дополнительными кнопками мыши"
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Выделение Ñетки"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "Внешний вид"
@@ -7919,11 +7935,20 @@ msgid "New Anim"
msgstr "ÐÐ¾Ð²Ð°Ñ Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Создать новую анимацию"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Изменить Ð¸Ð¼Ñ Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ð¸:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Переименовать анимацию"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Удалить анимацию?"
@@ -7941,11 +7966,6 @@ msgid "Animation name already exists!"
msgstr "Такое название анимации уже ÑущеÑтвует!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Переименовать анимацию"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Дублировать анимацию"
@@ -8091,10 +8111,6 @@ msgid "Pin AnimationPlayer"
msgstr "Закрепить анимацию игрока"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Создать новую анимацию"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Ðазвание анимации:"
@@ -9530,7 +9546,7 @@ msgstr "Иконка"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "ID"
-msgstr ""
+msgstr "Идентификатор"
#: editor/plugins/item_list_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -17055,7 +17071,7 @@ msgstr "Скин Godot"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Diffuse Img"
-msgstr ""
+msgstr "РаÑÑеÑнное изображение"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Diffuse Factor"
@@ -18486,6 +18502,11 @@ msgstr "Пакет должен иметь Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один раздели
#: platform/android/export/export_plugin.cpp
#, fuzzy
+msgid "Custom Build"
+msgstr "ИÑпользовать ÑобÑтвенную директорию данных пользователÑ"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid "Use Custom Build"
msgstr "ИÑпользовать ÑобÑтвенную директорию данных пользователÑ"
@@ -18494,6 +18515,16 @@ msgstr "ИÑпользовать ÑобÑтвенную директорию дÐ
msgid "Export Format"
msgstr "Путь ÑкÑпорта"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Минимальный размер"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Целевой FPS"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18537,16 +18568,6 @@ msgstr "ОÑмотреть предыдущий ÑкземплÑÑ€"
msgid "Code"
msgstr "Код"
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Минимальный размер"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Целевой FPS"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18800,15 +18821,17 @@ msgid "\"Use Custom Build\" must be enabled to use the plugins."
msgstr "«Use Custom Build» должен быть включен Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð»Ð°Ð³Ð¸Ð½Ð¾Ð²."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"«Hand Tracking» дейÑтвителен только тогда, когда «Xr Mode» уÑтановлен в "
"«Oculus Mobile VrApi» или «OpenXR»."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"«Passthrough» дейÑтвителен только тогда, когда «Xr Mode» уÑтановлен в "
"«OpenXR»."
@@ -18820,22 +18843,45 @@ msgstr ""
"пользовательÑкую Ñборку»."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Изменение «Min Sdk» дейÑтвительно только еÑли включён параметр «ИÑпользовать "
"пользовательÑкую Ñборку»."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Изменение «Target Sdk» дейÑтвительно только еÑли включён параметр "
"«ИÑпользовать пользовательÑкую Ñборку»."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr "ВерÑÐ¸Ñ Â«Target Sdk» должна быть больше или равна верÑии «Min Sdk»."
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20543,7 +20589,7 @@ msgstr "Приблизить"
msgid "Custom Viewport"
msgstr "1 Окно"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21284,11 +21330,43 @@ msgstr "Размер Ñчейки"
msgid "Edge Connection Margin"
msgstr "Пограничное Ñоединение"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "ПривÑзка"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "РаÑÑтоÑние пути U"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "МакÑимальное раÑÑтоÑние пути"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Дополнительно"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Включить"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21305,16 +21383,6 @@ msgstr "Перевернуть по горизонтали"
msgid "Max Speed"
msgstr "ÐœÐ°ÐºÑ ÑкороÑть"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "МакÑимальное раÑÑтоÑние пути"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Включить"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21362,7 +21430,7 @@ msgstr "ПеремеÑтитÑÑ"
msgid "Rotation Degrees"
msgstr "ГрадуÑÑ‹ вращениÑ"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr "Глобальный поворот"
@@ -22527,6 +22595,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Преобразование нормалей"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23461,6 +23536,11 @@ msgstr ""
"shapes)."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Глобальное преобразование"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24685,6 +24765,11 @@ msgstr "ПолоÑа ÑворачиваниÑ"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Только выделенное"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Включить"
@@ -25086,19 +25171,6 @@ msgstr "Путь ÑкÑпорта"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Этот viewport не уÑтановлен в качеÑтве цели рендеринга. ЕÑли вы ÑобираетеÑÑŒ "
-"иÑпользовать его Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñодержимого прÑмо на Ñкран, то Ñделайте её "
-"потомком Control'а, чтобы он мог получить размер. Ð’ противном Ñлучае, "
-"Ñделайте его целью рендеринга и назначьте его внутреннюю текÑтуру какому-"
-"либо узлу Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25106,6 +25178,15 @@ msgstr ""
"измерениÑÑ…, чтобы отобразить что-либо."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -26845,6 +26926,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Базовое Ñмещение"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr "Сферы"
@@ -26865,7 +26956,7 @@ msgstr "Передвинуть точки"
#: scene/resources/packed_scene.cpp
msgid "Bundled"
-msgstr ""
+msgstr "Вложенный"
#: scene/resources/particles_material.cpp
msgid "Trail"
@@ -27918,12 +28009,12 @@ msgstr "СовмеÑтимоÑть"
#: servers/visual_server.cpp
msgid "Disable Half Float"
-msgstr ""
+msgstr "Выключить вещеÑтвенные чиÑла половинной точноÑти"
#: servers/visual_server.cpp
#, fuzzy
msgid "Enable High Float"
-msgstr "Включить приоритет"
+msgstr "Включить вещеÑтвенные чиÑла повышенной точноÑти"
#: servers/visual_server.cpp
msgid "Precision"
@@ -27938,13 +28029,12 @@ msgid "UV Contract Amount"
msgstr ""
#: servers/visual_server.cpp
-#, fuzzy
msgid "Use Simple PVS"
-msgstr "ИÑпользовать привÑзку маÑштабированиÑ"
+msgstr "ИÑпользовать проÑтой PVS"
#: servers/visual_server.cpp
msgid "PVS Logging"
-msgstr ""
+msgstr "ВеÑти запиÑÑŒ PVS"
#: servers/visual_server.cpp
msgid "Use Signals"
@@ -27974,17 +28064,17 @@ msgid "Max Active Polygons"
msgstr "МакÑимальное количеÑтво активных полигонов"
#: servers/visual_server.cpp
-#, fuzzy
msgid "Shader Compilation Mode"
-msgstr "Режим интерполÑции"
+msgstr "Режим компилÑции шейдеров"
#: servers/visual_server.cpp
msgid "Max Simultaneous Compiles"
-msgstr ""
+msgstr "МакÑимальное количеÑтво одновременных компилÑций"
#: servers/visual_server.cpp
+#, fuzzy
msgid "Log Active Async Compiles Count"
-msgstr ""
+msgstr "РегиÑтрировать количеÑтво активных аÑинхронных компилÑций"
#: servers/visual_server.cpp
msgid "Shader Cache Size (MB)"
diff --git a/editor/translations/si.po b/editor/translations/si.po
index d28d0a4f81..bfba193a6a 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -398,6 +398,10 @@ msgstr ""
msgid "Command"
msgstr ""
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr ""
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -450,6 +454,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5333,6 +5341,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7672,11 +7684,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7694,11 +7715,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7841,10 +7857,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17988,6 +18000,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "යතුරු පිටපත් කරන්න"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17996,6 +18013,15 @@ msgstr ""
msgid "Export Format"
msgstr "Anim පරිවර්තනය වෙනස් කරන්න"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "යතුරු මක෠දමන්න"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18032,15 +18058,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "යතුරු මක෠දමන්න"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18266,12 +18283,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18280,17 +18297,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19828,7 +19865,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20507,35 +20544,55 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "à·à·Šâ€à¶»à·’à¶­:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Pathfinding"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Path Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "සමතුලිතයි"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
msgid "Avoidance Enabled"
msgstr "මෙම ලුහුබදින්න෠ඉවත් කරන්න."
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20575,7 +20632,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr ""
@@ -21638,6 +21695,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "3D රූපà·à¶±à·Šà¶­à¶»à¶«à¶º ලුහුබදින්න"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22479,6 +22543,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Anim පරිවර්තනය වෙනස් කරන්න"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23593,6 +23662,10 @@ msgid "Fold Gutter"
msgstr ""
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr ""
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr ""
@@ -23963,16 +24036,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25606,6 +25680,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 6615ae93a0..f711be3039 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -431,6 +431,11 @@ msgstr ""
msgid "Command"
msgstr "Komunita"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fyzická Snímka %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -488,6 +493,10 @@ msgid "Pressure"
msgstr "Preset"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Prichytiť Relatívne"
@@ -5644,6 +5653,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Všetky vybrané"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8107,11 +8121,20 @@ msgid "New Anim"
msgstr "Nová Animácia"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Vytvoriť Novú Animáciu"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Zmeniť Meno Animácie:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Premenovať Animáciu"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Naozaj chcete vymazať Animáciu?"
@@ -8129,11 +8152,6 @@ msgid "Animation name already exists!"
msgstr "Toto meno Animácie už existuje!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Premenovať Animáciu"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplikovať Animáciu"
@@ -8276,10 +8294,6 @@ msgid "Pin AnimationPlayer"
msgstr "Pripnúť PrehrávaÄ Animácie"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Vytvoriť Novú Animáciu"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Meno Animácie:"
@@ -18915,6 +18929,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Vložiť"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18923,6 +18942,16 @@ msgstr ""
msgid "Export Format"
msgstr "Konštanty:"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Veľkosť: "
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Vytvoriť Node"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18961,16 +18990,6 @@ msgstr "Minulá karta"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Veľkosť: "
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Vytvoriť Node"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19216,12 +19235,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19230,17 +19249,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20891,7 +20930,7 @@ msgstr "Priblížiť"
msgid "Custom Viewport"
msgstr "Zobraziť Výrez"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21618,34 +21657,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Upraviť Pripojenie:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Prilepiť Animáciu"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Vyberte hlavnú scénu"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "PokroÄilé"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Povoliť"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Povoliť"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21689,7 +21750,7 @@ msgstr "Cestovať"
msgid "Rotation Degrees"
msgstr "Krok Rotácie:"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konštant"
@@ -22830,6 +22891,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Vytvoriť adresár"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23707,6 +23775,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Preložiť Preloženie:"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24912,6 +24985,11 @@ msgstr "PrieÄinok:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Iba Výber"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Povoliť"
@@ -25312,16 +25390,17 @@ msgstr "Zamerať Cestu"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -27063,6 +27142,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Odchýlka Mriežky:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index acb24489bd..aae6c8ba68 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -13,13 +13,14 @@
# Alex <alexrixhardson@gmail.com>, 2019.
# Andrew Poženel <andrej.pozenel@outlook.com>, 2020, 2022.
# Jakob Tadej VrtaÄnik <minecraftalka2@gmail.com>, 2021.
+# Andrew Poženel <andrew.pozenel@protonmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-04 10:56+0000\n"
-"Last-Translator: Andrew Poženel <andrej.pozenel@outlook.com>\n"
+"PO-Revision-Date: 2022-06-23 16:41+0000\n"
+"Last-Translator: Andrew Poženel <andrew.pozenel@protonmail.com>\n"
"Language-Team: Slovenian <https://hosted.weblate.org/projects/godot-engine/"
"godot/sl/>\n"
"Language: sl\n"
@@ -28,7 +29,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || "
"n%100==4 ? 2 : 3;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -403,6 +404,11 @@ msgstr ""
msgid "Command"
msgstr "Skupnost"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fizikalni Okvir %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -411,9 +417,8 @@ msgid "Pressed"
msgstr "Prednastavitev..."
#: core/os/input_event.cpp
-#, fuzzy
msgid "Scancode"
-msgstr "Preglej"
+msgstr "Skenirna koda"
#: core/os/input_event.cpp
msgid "Physical Scancode"
@@ -421,7 +426,7 @@ msgstr ""
#: core/os/input_event.cpp
msgid "Unicode"
-msgstr ""
+msgstr "Unicode"
#: core/os/input_event.cpp
msgid "Echo"
@@ -461,6 +466,10 @@ msgid "Pressure"
msgstr "Prednastavitev..."
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Pripni Relativno"
@@ -884,7 +893,7 @@ msgstr ""
#: core/register_core_types.cpp
msgid "TCP"
-msgstr ""
+msgstr "TCP"
#: core/register_core_types.cpp
#, fuzzy
@@ -3868,7 +3877,7 @@ msgstr ""
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: scene/main/node.cpp scene/resources/default_theme/default_theme.cpp
msgid "Node"
-msgstr "Gradnik"
+msgstr "VozliÅ¡Äe"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
@@ -5715,6 +5724,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "GridMap Izbriši Izbor"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7220,7 +7234,7 @@ msgstr ""
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
msgid "sRGB"
-msgstr ""
+msgstr "sRGB"
#: editor/import/resource_importer_layered_texture.cpp
msgid "Slices"
@@ -8232,11 +8246,20 @@ msgid "New Anim"
msgstr "Nova Animacija"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Ustvari Novo Animacijo"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Spremeni Ime Animacije:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Preimenuj Animacijo"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Izbrišem animacijo?"
@@ -8256,11 +8279,6 @@ msgid "Animation name already exists!"
msgstr "NAPAKA: Animacija s tem imenom že obstaja!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Preimenuj Animacijo"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Podvoji Animacijo"
@@ -8409,10 +8427,6 @@ msgid "Pin AnimationPlayer"
msgstr "Prilepi animacijo"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Ustvari Novo Animacijo"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Ime Animacije:"
@@ -9834,7 +9848,7 @@ msgstr ""
#: editor/plugins/curve_editor_plugin.cpp
msgid "Flat 1"
-msgstr ""
+msgstr "Raven 1"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease In"
@@ -10062,7 +10076,7 @@ msgstr ""
#: scene/resources/multimesh.cpp scene/resources/primitive_meshes.cpp
#: scene/resources/texture.cpp
msgid "Mesh"
-msgstr ""
+msgstr "Geometrijski objekt"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -10965,7 +10979,7 @@ msgstr "Prejšnji zavihek"
#: editor/plugins/script_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "File"
-msgstr ""
+msgstr "Datoteka"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -11421,7 +11435,7 @@ msgstr "Zaženi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Orthogonal"
-msgstr ""
+msgstr "Ortogonalno"
#: editor/plugins/spatial_editor_plugin.cpp modules/gltf/gltf_camera.cpp
msgid "Perspective"
@@ -11587,7 +11601,7 @@ msgstr "Lastnosti"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "FPS: %d (%s ms)"
-msgstr ""
+msgstr "FPS: %d (%s ms)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View."
@@ -13649,7 +13663,7 @@ msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "SSH Passphrase"
-msgstr ""
+msgstr "geslo SSH"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -18664,7 +18678,7 @@ msgstr ""
#: modules/visual_script/visual_script_flow_control.cpp
msgid "While"
-msgstr ""
+msgstr "Medtem ko"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "while (cond):"
@@ -18995,7 +19009,7 @@ msgstr "Odstrani Gradnik VizualnaSkripta"
#: modules/visual_script/visual_script_yield_nodes.cpp
msgid "Yield"
-msgstr ""
+msgstr "Donos"
#: modules/visual_script/visual_script_yield_nodes.cpp
msgid "Wait"
@@ -19206,6 +19220,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Gradnik Prehod"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -19214,6 +19233,16 @@ msgstr ""
msgid "Export Format"
msgstr "Izvozi Projekt"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Zaženi Skripto"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Gradnik ÄŒasovnoMerilo"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -19253,16 +19282,6 @@ msgstr "Prejšnji zavihek"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Zaženi Skripto"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Gradnik ÄŒasovnoMerilo"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19509,12 +19528,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19523,17 +19542,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -21190,7 +21229,7 @@ msgstr "Približaj"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21913,34 +21952,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Napaka Pri Povezavi"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Prilepi animacijo"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Izberi Glavno Sceno"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Možnosti pripenjanja"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "OmogoÄi"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "OmogoÄi"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21983,7 +22044,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr "Rotacijski Korak:"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstanta"
@@ -23122,6 +23183,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Preoblikovanje Dialoga..."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23996,6 +24064,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Preoblikovanje"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25209,6 +25282,11 @@ msgstr "Ustvarite Mapo"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Samo Izbira"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "OmogoÄi"
@@ -25605,16 +25683,17 @@ msgstr "Izvozi Projekt"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26893,7 +26972,7 @@ msgstr ""
#: scene/resources/environment.cpp
msgid "Bloom"
-msgstr ""
+msgstr "UÄinek žarenja"
#: scene/resources/environment.cpp
msgid "HDR Threshold"
@@ -27353,6 +27432,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Mrežni Zamik:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index c97aac239a..f405b8b8a9 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -415,6 +415,11 @@ msgstr ""
msgid "Command"
msgstr "Komuniteti"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Hapi i Fizikës %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -473,6 +478,10 @@ msgid "Pressure"
msgstr "Ngarko Gabimet"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5651,6 +5660,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Fshi të Selektuarat"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8093,11 +8107,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -8115,11 +8138,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8262,10 +8280,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18698,6 +18712,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Dyfisho Nyjet"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18706,6 +18725,16 @@ msgstr ""
msgid "Export Format"
msgstr "Konstantet"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Madhësia: "
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Fshi Nyjen"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18744,16 +18773,6 @@ msgstr "Tabi i mëparshëm"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Madhësia: "
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Fshi Nyjen"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18998,12 +19017,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19012,17 +19031,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20654,7 +20693,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr "Zgjidh një 'Viewport'"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21350,34 +21389,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Modifiko Lidhjen: "
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Konstantet"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Zgjidh një Skenë Kryesore"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "I Balancuar"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Lejo"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Lejo"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21418,7 +21479,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstantet"
@@ -22513,6 +22574,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Binari i Transformimeve 3D"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23361,6 +23429,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Binari i Transformimeve 3D"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24531,6 +24604,11 @@ msgstr "Folderi:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Zgjidh Këtë Folder"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Lejo"
@@ -24922,16 +25000,17 @@ msgstr "Fokuso Rrugën"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26636,6 +26715,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Ndrysho Tipin e %s"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index 55387743e7..9d7c4c5db8 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -431,6 +431,11 @@ msgstr ""
msgid "Command"
msgstr "Заједница"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Слика физике %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -489,6 +494,10 @@ msgid "Pressure"
msgstr "ПоÑтавке"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "Залепи релативно"
@@ -5964,6 +5973,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "МапаМреже ИÑпуни Одабрано"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8584,11 +8598,20 @@ msgid "New Anim"
msgstr "Ðова анимација"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Ðаправи нову анимацију"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Измени име анимације:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Преименуј анимацију"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Обриши анимацију?"
@@ -8608,11 +8631,6 @@ msgid "Animation name already exists!"
msgstr "Грешка: име анимације већ поÑтоји!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Преименуј анимацију"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Дуплирај анимацију"
@@ -8762,10 +8780,6 @@ msgid "Pin AnimationPlayer"
msgstr "Ðалепи анимацију"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Ðаправи нову анимацију"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Име анимације:"
@@ -20554,6 +20568,11 @@ msgid "The package must have at least one '.' separator."
msgstr "Паковање мора имати бар један '.' раздвојник."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Ðаправи чвор"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -20562,6 +20581,16 @@ msgstr ""
msgid "Export Format"
msgstr "Извези пројекат"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Величина ивице:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Мета"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -20604,16 +20633,6 @@ msgstr "ИÑтражи Претходну ИнÑтанцу"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Величина ивице:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Мета"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -20876,12 +20895,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -20890,17 +20909,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -22599,7 +22638,7 @@ msgstr "Увеличај"
msgid "Custom Viewport"
msgstr "1 прозор"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -23365,11 +23404,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Повезивање не уÑпешно"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Спојеви"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Одабери ОдÑтојање:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Одабери ОдÑтојање:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "ПоÑтавке залепљавања"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Укључи"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -23387,16 +23458,6 @@ msgstr "Обрни Хоризонтално"
msgid "Max Speed"
msgstr "Брзина (FPS):"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Одабери ОдÑтојање:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Укључи"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -23442,7 +23503,7 @@ msgstr "Путуј"
msgid "Rotation Degrees"
msgstr "Ротација за %s Ñтепени."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "КонÑтантан"
@@ -24678,6 +24739,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "ТранÑформација прекинута."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -25584,6 +25652,11 @@ msgstr ""
"рада."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Сачувај Глобалну ТранÑформу"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -26865,6 +26938,11 @@ msgstr "ПреÑавији линију"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Само одабрано"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Укључи"
@@ -27275,24 +27353,20 @@ msgstr "Извези пројекат"
#: scene/main/viewport.cpp
#, fuzzy
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Овај viewport није поÑтављен као мета за иÑцртавање. Ðко намераваш да "
-"прикаже Ñадржај директно на екран, учини га дететом Контроле да може да "
-"добави величину. У Ñупротном, учини га МетомИÑцртавања и додели његову "
-"унутрашњу текÑтуру неком чвору за приказ."
-
-#: scene/main/viewport.cpp
-#, fuzzy
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr "Величина Viewport-а мора бити већа од 0 да би Ñе нешто иÑцртало."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -29061,6 +29135,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "ГенериÑање оÑног поравнаног граничниог оквира (AABB)"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "ОфÑет:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index 21d94999a2..d3f588aca6 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -406,6 +406,11 @@ msgstr ""
msgid "Command"
msgstr "Zajednica"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Filtriraj signale"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -458,6 +463,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5350,6 +5359,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Sve sekcije"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7695,11 +7709,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7717,11 +7740,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7864,10 +7882,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18053,6 +18067,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Animacija Uduplaj KljuÄeve"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18061,6 +18080,15 @@ msgstr ""
msgid "Export Format"
msgstr "Homogenost Boje."
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Ukloni ÄŒvor"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18097,15 +18125,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Ukloni ÄŒvor"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -18336,12 +18355,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18350,17 +18369,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19919,7 +19958,7 @@ msgstr "UveliÄaj"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20611,35 +20650,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Izmeni Konekciju:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Target Desired Distance"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
-msgstr ""
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Kontanta"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Path Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Napredno"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
#, fuzzy
msgid "Avoidance Enabled"
msgstr "Filtriraj signale"
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Neighbors"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20679,7 +20739,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Kontanta"
@@ -21765,6 +21825,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformacija homogenosti."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22612,6 +22679,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Animacija Promjeni Transformaciju"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23753,6 +23825,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Samo Obeleženo"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Filtriraj signale"
@@ -24129,16 +24206,17 @@ msgstr "Putanja"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25807,6 +25885,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Obriši Selekciju"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index 54655bcecf..08b57d1a25 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -442,6 +442,11 @@ msgstr ""
msgid "Command"
msgstr "Gemenskap"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Fysik Bildruta %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -500,6 +505,10 @@ msgid "Pressure"
msgstr "Återställ Zoom"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "GDNative"
@@ -5660,6 +5669,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Alla urval"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8159,11 +8173,20 @@ msgid "New Anim"
msgstr "Ny Anim"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Skapa Ny Animation"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Ändra Animationsnamn:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Byt namn på Animation"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Ta bort Animation?"
@@ -8183,11 +8206,6 @@ msgid "Animation name already exists!"
msgstr "ERROR: Animationsnamn finns redan!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Byt namn på Animation"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Duplicera Animation"
@@ -8335,10 +8353,6 @@ msgid "Pin AnimationPlayer"
msgstr "Klistra in Animation"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Skapa Ny Animation"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18984,6 +18998,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Klipp ut Noder"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18992,6 +19011,16 @@ msgstr ""
msgid "Export Format"
msgstr "Exportera Projekt"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Storlek:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Byt Förälder-Node"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -19030,16 +19059,6 @@ msgstr "Föregående flik"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Storlek:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Byt Förälder-Node"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19284,12 +19303,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19298,17 +19317,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20964,7 +21003,7 @@ msgstr "Zooma In"
msgid "Custom Viewport"
msgstr "Vy underifrån"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21687,34 +21726,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Redigera Koppling:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Slumpmässig Rotation:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Välj en Huvudscen"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "Avancerad"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Aktivera"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Aktivera"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21757,7 +21818,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr "Roterar %s grader."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Konstant"
@@ -22906,6 +22967,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Transformera uniform."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23784,6 +23852,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Transformera"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24989,6 +25062,11 @@ msgstr "Mapp:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Endast Urval"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Aktivera"
@@ -25386,16 +25464,17 @@ msgstr "Exportera Projekt"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -27128,6 +27207,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Ta Bort Mall"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/te.po b/editor/translations/te.po
index 7e39aed20c..98eb54ce5c 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -388,6 +388,10 @@ msgstr ""
msgid "Command"
msgstr "సంఘం"
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr ""
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -440,6 +444,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5259,6 +5267,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr ""
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7546,11 +7558,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7568,11 +7589,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7715,10 +7731,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -17717,6 +17729,10 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+msgid "Custom Build"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -17724,6 +17740,15 @@ msgstr ""
msgid "Export Format"
msgstr ""
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "నోడà±"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -17760,15 +17785,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr ""
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "నోడà±"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr ""
@@ -17988,12 +18004,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18002,17 +18018,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19527,7 +19563,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20188,32 +20224,52 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr ""
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Desired Distance"
+msgstr ""
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
+msgid "Avoidance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+msgid "Avoidance Enabled"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Avoidance Enabled"
+msgid "Time Horizon"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Max Speed"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp
@@ -20254,7 +20310,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±"
@@ -21284,6 +21340,13 @@ msgstr ""
msgid "Transform Normals"
msgstr ""
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22087,6 +22150,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "గణనలà±"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -23166,6 +23234,10 @@ msgid "Fold Gutter"
msgstr ""
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr ""
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr ""
@@ -23522,16 +23594,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -25064,6 +25137,14 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr ""
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index cf482896d4..9460318ef8 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -438,6 +438,11 @@ msgstr ""
msgid "Command"
msgstr "ชุมชน"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "% ของเฟรมฟิสิà¸à¸ªà¹Œ"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -496,6 +501,10 @@ msgid "Pressure"
msgstr "พรีเซ็ต"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "จำà¸à¸±à¸”โดยใช้ตำà¹à¸«à¸™à¹ˆà¸‡à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™"
@@ -5639,6 +5648,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "เติมที่เลือà¸à¹ƒà¸™ GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8119,11 +8133,20 @@ msgid "New Anim"
msgstr "à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¸¡à¹ˆ"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "สร้างà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¸¡à¹ˆ"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "เปลี่ยนชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "เปลี่ยนชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "ลบà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™?"
@@ -8141,11 +8164,6 @@ msgid "Animation name already exists!"
msgstr "ชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸™à¸µà¹‰ มีอยู่à¹à¸¥à¹‰à¸§!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "เปลี่ยนชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "ทำซ้ำà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
@@ -8289,10 +8307,6 @@ msgid "Pin AnimationPlayer"
msgstr "ปัà¸à¸«à¸¡à¸¸à¸” AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "สร้างà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¸¡à¹ˆ"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "ชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™:"
@@ -18936,6 +18950,11 @@ msgid "The package must have at least one '.' separator."
msgstr "à¹à¸žà¹‡à¸„เà¸à¸ˆà¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้องมี '.' อย่างน้อยหนึ่งตัว"
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "ตัดโหนด"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18944,6 +18963,16 @@ msgstr ""
msgid "Export Format"
msgstr "ไดเรà¸à¸—อรีส่งออà¸"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "ขนาดเส้นรอบรูป:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "เป้าหมาย"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18986,16 +19015,6 @@ msgstr "ตรวจสอบอินสà¹à¸•นซ์à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "ขนาดเส้นรอบรูป:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "เป้าหมาย"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19242,13 +19261,13 @@ msgstr "\"Use Custom Build\" จำเป็นต้องเปิดà¸à¸²à¸£
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr "\"Hand Tracking\" จะสามารถใช้ได้เมื่อ \"Xr Mode\" เป็น \"Oculus Mobile VR\""
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr "\"Hand Tracking\" จะสามารถใช้ได้เมื่อ \"Xr Mode\" เป็น \"Oculus Mobile VR\""
#: platform/android/export/export_plugin.cpp
@@ -19258,18 +19277,38 @@ msgstr "\"Export AAB\" จะใช้ได้เฉพาะเมื่อเ
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr "\"Export AAB\" จะใช้ได้เฉพาะเมื่อเปิดใช้งาน \"Use Custom Build\""
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr "\"Export AAB\" จะใช้ได้เฉพาะเมื่อเปิดใช้งาน \"Use Custom Build\""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20946,7 +20985,7 @@ msgstr "ขยาย"
msgid "Custom Viewport"
msgstr "1 วิวพอร์ต"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21698,11 +21737,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•่อ:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "ปุ่มลัด"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "ระยะà¸à¸²à¸£à¹€à¸¥à¸·à¸­à¸:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "ระยะà¸à¸²à¸£à¹€à¸¥à¸·à¸­à¸:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "ขั้นสูง"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "เปิด"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21720,16 +21791,6 @@ msgstr "พลิà¸à¹à¸™à¸§à¸™à¸­à¸™"
msgid "Max Speed"
msgstr "ความเร็ว:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "ระยะà¸à¸²à¸£à¹€à¸¥à¸·à¸­à¸:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "เปิด"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21773,7 +21834,7 @@ msgstr "à¸à¸²à¸£à¹€à¸„ลื่อนที่"
msgid "Rotation Degrees"
msgstr "หมุน %s องศา"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "คงที่"
@@ -22953,6 +23014,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¹€à¸„ลื่อนย้าย"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23854,6 +23922,11 @@ msgstr ""
"เปลี่ยนขนาดของขอบเขตà¸à¸²à¸£à¸Šà¸™à¸¥à¸¹à¸à¹à¸—น"
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "เà¸à¹‡à¸š Global Transform"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25098,6 +25171,11 @@ msgstr "โฟลเดอร์:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "เฉพาะที่à¸à¸³à¸¥à¸±à¸‡à¹€à¸¥à¸·à¸­à¸"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "เปิด"
@@ -25504,17 +25582,6 @@ msgid "Viewport Path"
msgstr "ไดเรà¸à¸—อรีส่งออà¸"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Viewport นี้ไม่ได้เป็น render target ถ้าท่านต้องà¸à¸²à¸£à¹à¸ªà¸”งผลบนหน้าจอโดยตรง "
-"ให้à¹à¸à¹‰à¹„ขโหนดนี้ให้เป็นโหนดลูà¸à¸‚อง Control à¹à¸•่ถ้าไม่ ให้ปรับเป็น render target à¹à¸¥à¸°à¸™à¸³à¹„ปใช้เป็น "
-"texture ของโหนดอื่น"
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -25522,6 +25589,15 @@ msgid ""
msgstr "ขนาดวิวพอร์ตจะต้องมาà¸à¸à¸§à¹ˆà¸² 0 เพื่อที่จะเรนเดอร์ได้"
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27291,6 +27367,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "เลื่อน:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/tl.po b/editor/translations/tl.po
index 963d542e6d..a7a9bacaeb 100644
--- a/editor/translations/tl.po
+++ b/editor/translations/tl.po
@@ -415,6 +415,11 @@ msgstr ""
msgid "Command"
msgstr "Pamayanan"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Paganahin"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -471,6 +476,10 @@ msgid "Pressure"
msgstr "Preset"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
#, fuzzy
msgid "Relative"
msgstr "GDNative"
@@ -5453,6 +5462,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Kopyahin Ang Pinagpipilian"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7848,11 +7862,20 @@ msgid "New Anim"
msgstr "Bagong Anim"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Gumawa ng Bagong Animasyon"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Baguhin ang Pangalan ng Animasyon:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Palitan ang Pangalan ng Animation"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Alisin ang Animation?"
@@ -7870,11 +7893,6 @@ msgid "Animation name already exists!"
msgstr "May nakapangalan na parehas sa Animation na ito!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Palitan ang Pangalan ng Animation"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8017,10 +8035,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Gumawa ng Bagong Animasyon"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Pangalan ng Animasyon:"
@@ -18258,6 +18272,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Kopyahin ang mga Node"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18266,6 +18285,16 @@ msgstr ""
msgid "Export Format"
msgstr "Iluwas ang Library"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Pangunahing Skrip:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Pinagtututukan"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18304,16 +18333,6 @@ msgstr "Nakaraang tab"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Pangunahing Skrip:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Pinagtututukan"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18552,12 +18571,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18566,17 +18585,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20201,7 +20240,7 @@ msgstr "Palakihin Ang Tanaw"
msgid "Custom Viewport"
msgstr "1 Tinginan"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -20909,11 +20948,42 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Ayusin Ang Pagkakabit:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Constant"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Pumili ng Pangunahing Eksena"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Paganahin"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Paganahin"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -20930,15 +21000,6 @@ msgstr ""
msgid "Max Speed"
msgstr "Bilis:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Paganahin"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20978,7 +21039,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Constant"
@@ -22099,6 +22160,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Track na Pang-3D Transform"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -22968,6 +23036,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Transisyon: "
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24160,6 +24233,11 @@ msgstr "Folder:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Napili lang"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Paganahin"
@@ -24551,14 +24629,6 @@ msgstr "1 Tinginan"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -24566,6 +24636,15 @@ msgstr ""
"alinman."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -26291,6 +26370,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Usog:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index ea437aaf30..3cbd52b7e4 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -72,13 +72,15 @@
# Emir Tunahan Alim <emrtnhalim@gmail.com>, 2022.
# inci <incialien@gmail.com>, 2022.
# Ramazan Aslan <legendraslan@gmail.com>, 2022.
+# paledega <paledega@yandex.ru>, 2022.
+# Yekez <yasintonge@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-12 13:19+0000\n"
-"Last-Translator: Ramazan Aslan <legendraslan@gmail.com>\n"
+"PO-Revision-Date: 2022-07-03 00:44+0000\n"
+"Last-Translator: Yekez <yasintonge@gmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
"Language: tr\n"
@@ -86,11 +88,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
-msgstr "Tablet Sürücüsü"
+msgstr "Tablet Sürücü"
#: core/bind/core_bind.cpp
msgid "Clipboard"
@@ -98,7 +100,7 @@ msgstr "Pano"
#: core/bind/core_bind.cpp
msgid "Current Screen"
-msgstr "Åžu anki ekran"
+msgstr "Åžu anki Ekran"
#: core/bind/core_bind.cpp
msgid "Exit Code"
@@ -106,11 +108,11 @@ msgstr "Çıkış Kodu"
#: core/bind/core_bind.cpp
msgid "V-Sync Enabled"
-msgstr "V-Sync EtkinleÅŸtirildi"
+msgstr "V-Sync Etkin"
#: core/bind/core_bind.cpp main/main.cpp
msgid "V-Sync Via Compositor"
-msgstr ""
+msgstr "Compositor Üzerinden V-Sync"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Delta Smoothing"
@@ -460,6 +462,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Komut"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (Fiziksel)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -467,8 +474,9 @@ msgid "Pressed"
msgstr "Basılmış"
#: core/os/input_event.cpp
+#, fuzzy
msgid "Scancode"
-msgstr "TuÅŸ Kodu"
+msgstr "Tarama kodu"
#: core/os/input_event.cpp
msgid "Physical Scancode"
@@ -514,6 +522,10 @@ msgid "Pressure"
msgstr "Baskı"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Göreceli"
@@ -909,6 +921,7 @@ msgid "Modules"
msgstr "Modüller"
#: core/register_core_types.cpp
+#, fuzzy
msgid "TCP"
msgstr "TCP"
@@ -1109,7 +1122,7 @@ msgstr ""
#. TRANSLATORS: Adjective, refers to the mode for Bezier handles (Free, Balanced, Mirror).
#: editor/animation_bezier_editor.cpp
msgid "Free"
-msgstr "Ücretsiz"
+msgstr "Özgür"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
@@ -5640,6 +5653,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "GridMap Seçimi"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8115,11 +8133,20 @@ msgid "New Anim"
msgstr "Yeni Animasyon"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Yeni Animasyon OluÅŸtur"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Animasyon İsmini Değiştir:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Animasyonu Yeniden Adlandır"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Animasyon Silinsin mi?"
@@ -8137,11 +8164,6 @@ msgid "Animation name already exists!"
msgstr "Animasyon ismi zaten var!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Animasyonu Yeniden Adlandır"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Animasyonu Çoğalt"
@@ -8285,10 +8307,6 @@ msgid "Pin AnimationPlayer"
msgstr "Animasyon Oynatıcıyı Sabitle"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Yeni Animasyon OluÅŸtur"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Animasyon Adı:"
@@ -13290,6 +13308,7 @@ msgid "Select SSH private key path"
msgstr "SSH özel anahtar yolu seç"
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "SSH Passphrase"
msgstr "SSH Parolası"
@@ -18856,6 +18875,11 @@ msgid "The package must have at least one '.' separator."
msgstr "Paket en azından bir tane '.' ayıracına sahip olmalıdır."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "ÖzelSınıf"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18864,6 +18888,16 @@ msgstr ""
msgid "Export Format"
msgstr "Dışa aktarım Yolu"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Kontur Boyutu:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "Hedef"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18907,16 +18941,6 @@ msgstr "Önceki Örneği İncele"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Kontur Boyutu:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "Hedef"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19166,15 +19190,17 @@ msgstr ""
"Eklentileri kullanabilmek için \"Özel Derleme Kullan\" seçeneği aktif olmalı."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"El Takibi (Hand Tracking)\" sadece \"Xr Modu\" \"Oculus Mobile VR\" ya da "
"\"OpenXR\" olduğunda geçerlidir."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr "\"İçinden Geçme\" sadece \"Xr Mod\" \"OpenXR\" ise geçerlidir."
#: platform/android/export/export_plugin.cpp
@@ -19184,22 +19210,45 @@ msgstr ""
"geçerlidir."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Min Sdk\" değiştirilmesi sadece \"Özel Yapı\" etkinleştirildiğinde "
"geçerlidir."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Target Sdk\" değiştirilmesi sadece \"Özel Yapı\" etkinleştirildiğinde "
"geçerlidir."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
"\"Target Sdk\" sürümü \"Min Sdk\" sürümünden daha büyük veya eşit olmalıdır."
@@ -20890,7 +20939,7 @@ msgstr "Yaklaştır"
msgid "Custom Viewport"
msgstr "1 Görüntü Kapısı"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21654,11 +21703,43 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Bağlantıyı Düzenle:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Bağlayıcı"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Uzaklık Seç:"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Max Distance"
+msgstr "Uzaklık Seç:"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "GeliÅŸmiÅŸ"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Etkin"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21676,16 +21757,6 @@ msgstr "Yatay Yansıt"
msgid "Max Speed"
msgstr "Hız:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "Uzaklık Seç:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Etkin"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21732,7 +21803,7 @@ msgstr "Seyahat"
msgid "Rotation Degrees"
msgstr "%s Düzey Dönüyor."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Genel Sabit"
@@ -22941,6 +23012,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Dönüşüm Durduruldu."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23864,6 +23942,11 @@ msgstr ""
"Bunun yerine alt düğümlerde çarpışma şekillerindeki boyutu değiştirin."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Bütünsel Dönüşümü Tut"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25125,6 +25208,11 @@ msgstr "Dosya:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Yalnızca Seçim"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Etkin"
@@ -25536,18 +25624,6 @@ msgstr "Dışa aktarım Yolu"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Bu görüntükapısı bir işleyici hedefi olarak ayarlanmamış. Eğer bunu doğrudan "
-"ekran içeriğini görüntülemek için düşünüyorsanız, bir Control'ün çocuğu "
-"yapın böylece bir boyut elde edebilir. Aksi takdirde, Görüntüleme için bunu "
-"bir RenderTarget yap ve dahili dokusunu herhangi bir düğüme ata."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -25555,6 +25631,15 @@ msgstr ""
"pikselden büyük ya da buna eşit olmalıdır."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27324,6 +27409,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "AABB Üretimi"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Kaydırma:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index 6d96ccc30b..fd20ea0a29 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -23,13 +23,14 @@
# Wald Sin <naaveranos@gmail.com>, 2022.
# Гліб Соколов <ramithes@i.ua>, 2022.
# Max Donchenko <maxx.donchenko@gmail.com>, 2022.
+# Artem <artem@molotov.work>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Ukrainian (Godot Engine)\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-06-12 13:19+0000\n"
-"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
+"PO-Revision-Date: 2022-07-03 00:44+0000\n"
+"Last-Translator: Artem <artem@molotov.work>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/"
"godot/uk/>\n"
"Language: uk\n"
@@ -38,7 +39,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.13.1-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -378,14 +379,12 @@ msgid "Max Size (KB)"
msgstr "МакÑ. розмір (кБ)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "Режим переміщеннÑ"
+msgstr "Режим миші"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "Видалити введеннÑ"
+msgstr "ВикориÑтати накопичувальне введеннÑ"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -412,6 +411,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Команда"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr " (фізичний)"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -463,6 +467,11 @@ msgid "Pressure"
msgstr "ТиÑк"
#: core/os/input_event.cpp
+#, fuzzy
+msgid "Pen Inverted"
+msgstr "Інвертувати"
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "ВідноÑний"
@@ -662,14 +671,12 @@ msgid "Script Templates Search Path"
msgstr "ШлÑÑ… пошуку Ð´Ð»Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ñ–Ð² Ñкриптів"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Autoload On Startup"
-msgstr "Ðвтоматично завантажувати під Ñ‡Ð°Ñ Ð·Ð°Ð¿ÑƒÑку"
+msgstr "Ðвтоматичне Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñми під Ñ‡Ð°Ñ Ð·Ð°Ð¿ÑƒÑку"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Plugin Name"
-msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñми"
+msgstr "Ðазва додатка ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñми"
#: core/project_settings.cpp scene/2d/collision_object_2d.cpp
#: scene/3d/collision_object.cpp scene/gui/control.cpp
@@ -2186,7 +2193,7 @@ msgstr "Відкрити"
#: editor/dependency_editor.cpp
msgid "Owners of: %s (Total: %d)"
-msgstr ""
+msgstr "ВлаÑник: %s (Загалом: %d)"
#: editor/dependency_editor.cpp
msgid ""
@@ -2746,22 +2753,19 @@ msgstr "Оберіть"
#: editor/editor_export.cpp
msgid "Project export for platform:"
-msgstr ""
+msgstr "ЕкÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð¸:"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed with errors."
-msgstr "Повні шлÑхи до файлів"
+msgstr "Завершено з помилками."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed successfully."
-msgstr "Пакунок уÑпішно вÑтановлено!"
+msgstr "Завершено уÑпішно."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed."
-msgstr "Ðе вдалоÑÑ:"
+msgstr "Помилка."
#: editor/editor_export.cpp
msgid "Storing File:"
@@ -2776,29 +2780,24 @@ msgid "Packing"
msgstr "ПакуваннÑ"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save PCK"
-msgstr "Зберегти Ñк"
+msgstr "Зберегти PCK"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Cannot create file \"%s\"."
-msgstr "Ðеможливо Ñтворити теку."
+msgstr "Ðе вдалоÑÑ Ñтворити файл «%s»."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to export project files."
-msgstr "Ðе вдалоÑÑ ÐµÐºÑпортувати файли проєкту"
+msgstr "Ðе вдалоÑÑ ÐµÐºÑпортувати файли проєкту."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Can't open file to read from path \"%s\"."
-msgstr "Ðеможливо відкрити файл Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу:"
+msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ñ– шлÑху «%s»."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save ZIP"
-msgstr "Зберегти Ñк"
+msgstr "Зберегти ZIP"
#: editor/editor_export.cpp
msgid ""
@@ -2918,30 +2917,25 @@ msgid "Custom release template not found."
msgstr "Ðетипового шаблону випуÑку не знайдено."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Prepare Template"
-msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°Ð¼Ð¸"
+msgstr "Приготувати шаблон"
#: editor/editor_export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "The given export path doesn't exist."
-msgstr "Вказаного шлÑху Ð´Ð»Ñ ÐµÐºÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ Ñ–Ñнує:"
+msgstr "Вказаного шлÑху Ð´Ð»Ñ ÐµÐºÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ Ñ–Ñнує."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
-#, fuzzy
msgid "Template file not found: \"%s\"."
-msgstr "Файл шаблону не знайдено:"
+msgstr "Ðе знайдено файла шаблона: «%s»."
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to copy export template."
-msgstr "Ðеправильний шаблон екÑпорту:"
+msgstr "Ðе вдалоÑÑ Ñкопіювати шаблон екÑпортуваннÑ."
#: editor/editor_export.cpp platform/windows/export/export.cpp
#: platform/x11/export/export.cpp
-#, fuzzy
msgid "PCK Embedding"
-msgstr "ФаÑка"
+msgstr "Ð’Ð±ÑƒÐ´Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ PCK"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
@@ -5216,9 +5210,8 @@ msgstr ""
"меню «ЕкÑпорт» або визначне наÑвний набір Ñк придатний до викориÑтаннÑ."
#: editor/editor_run_native.cpp
-#, fuzzy
msgid "Project Run"
-msgstr "Проєкт"
+msgstr "ЗапуÑк проєкту"
#: editor/editor_run_script.cpp
msgid "Write your logic in the _run() method."
@@ -5502,6 +5495,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr "Додаткові кнопки миші Ð´Ð»Ñ Ð½Ð°Ð²Ñ–Ð³Ð°Ñ†Ñ–Ñ— журналом"
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Вибір GridMap"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "ВиглÑд"
@@ -7156,12 +7154,18 @@ msgid ""
"%s: Texture detected as used as a normal map in 3D. Enabling red-green "
"texture compression to reduce memory usage (blue channel is discarded)."
msgstr ""
+"%s: виÑвлено текÑтуру, Ñк викориÑтано Ñк нормальну карту у проÑторовій "
+"формі. Вмикаємо ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‡ÐµÑ€Ð²Ð¾Ð½Ð¾-зеленої текÑтури Ð´Ð»Ñ Ð·Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ ÑÐ¿Ð¾Ð¶Ð¸Ð²Ð°Ð½Ð½Ñ "
+"пам'Ñті (канал Ñинього відкинуто)."
#: editor/import/resource_importer_texture.cpp
msgid ""
"%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap "
"generation and VRAM texture compression."
msgstr ""
+"%s: виÑвлено, що текÑтуру викориÑтано у проÑторовій формі. Вмикаємо "
+"фільтруваннÑ, повтореннÑ, ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼Ð½Ð¾Ð¶Ð¸Ð½Ð½Ð¾Ð³Ð¾ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‚Ð° ÑтиÑÐºÐ°Ð½Ð½Ñ "
+"текÑтур у відеопам'Ñті."
#: editor/import/resource_importer_texture.cpp
msgid "2D, Detect 3D"
@@ -7841,11 +7845,20 @@ msgid "New Anim"
msgstr "Ðова анімаціÑ"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Створити нову анімацію"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Змінити ім'Ñ Ð°Ð½Ñ–Ð¼Ð°Ñ†Ñ–Ñ—:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Перейменувати анімацію"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Видалити анімацію?"
@@ -7863,11 +7876,6 @@ msgid "Animation name already exists!"
msgstr "ÐÐ½Ñ–Ð¼Ð°Ñ†Ñ–Ñ Ñ–Ð· такою назвою вже Ñ–Ñнує!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Перейменувати анімацію"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Дублювати анімацію"
@@ -8011,10 +8019,6 @@ msgid "Pin AnimationPlayer"
msgstr "Пришпилити AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Створити нову анімацію"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Ðазва анімації:"
@@ -11504,9 +11508,8 @@ msgid "Invalid geometry, can't replace by mesh."
msgstr "Ðекоректна геометріÑ, неможливо замінити Ñіткою."
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to MeshInstance2D"
-msgstr "Перетворити на Mesh2D"
+msgstr "Перетворити на MeshInstance2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
@@ -12875,14 +12878,12 @@ msgid "Selected Collision"
msgstr "Позначене зіткненнÑ"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Selected Collision One Way"
-msgstr "Тільки виділити"
+msgstr "Позначене одноÑпрÑмоване зіткненнÑ"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Selected Collision One Way Margin"
-msgstr "Поле Ð·Ñ–Ñ‚ÐºÐ½ÐµÐ½Ð½Ñ BVH"
+msgstr "Поле позначеного одноÑпрÑмованого зіткненнÑ"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Selected Navigation"
@@ -14142,9 +14143,8 @@ msgid "Export templates for this platform are missing:"
msgstr "Ðемає шаблонів екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— платформи:"
#: editor/project_export.cpp
-#, fuzzy
msgid "Project Export"
-msgstr "ЗаÑновники проєкту"
+msgstr "ЕкÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ"
#: editor/project_export.cpp
msgid "Manage Export Templates"
@@ -16705,7 +16705,7 @@ msgstr "Копіювати вузол шлÑху"
#: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp
msgid "Max Call Stack"
-msgstr ""
+msgstr "МакÑимум Ñтеку викликів"
#: modules/gdscript/gdscript.cpp
msgid "Treat Warnings As Errors"
@@ -16815,11 +16815,11 @@ msgstr "КількіÑть розÑіюваннÑ"
#: modules/gltf/gltf_accessor.cpp
msgid "Sparse Indices Buffer View"
-msgstr ""
+msgstr "ПереглÑд буфера розріджених індекÑів"
#: modules/gltf/gltf_accessor.cpp
msgid "Sparse Indices Byte Offset"
-msgstr ""
+msgstr "Байтовий зÑув розріджених індекÑів"
#: modules/gltf/gltf_accessor.cpp
msgid "Sparse Indices Component Type"
@@ -18362,6 +18362,11 @@ msgid "The package must have at least one '.' separator."
msgstr "У назві пакунка має бути принаймні один роздільник «.»."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Ðетипова збірка"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr "Ðетипова збірка"
@@ -18369,6 +18374,14 @@ msgstr "Ðетипова збірка"
msgid "Export Format"
msgstr "Формат екÑпортуваннÑ"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr "Мін. SDK"
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr "SDK призначеннÑ"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18406,14 +18419,6 @@ msgstr "Вилучити попередньо вÑтановлене"
msgid "Code"
msgstr "Код"
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr "Мін. SDK"
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr "SDK призначеннÑ"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr "Пакунок"
@@ -18651,15 +18656,17 @@ msgstr ""
"«ВикориÑтовувати нетипову збірку»."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"«СтеженнÑм за руками» можна ÑкориÑтатиÑÑ, лише Ñкщо «Режим Xr» дорівнює "
"«Oculus Mobile VR» або «OpenXR»."
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"«СтеженнÑм за руками» можна ÑкориÑтатиÑÑ, лише Ñкщо «Режим Xr» дорівнює "
"«OpenXR»."
@@ -18671,22 +18678,45 @@ msgstr ""
"нетипове збираннÑ»."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Пункт «Мін. SDK» Ñ” чинним, лише Ñкщо увімкнено «ВикориÑтовувати нетипове "
"збираннÑ»."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"Пункт «SDK цілі» Ñ” чинним, лише Ñкщо увімкнено «ВикориÑтовувати нетипове "
"збираннÑ»."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr "ВерÑÑ–Ñ Â«SDK цілі» має бути більшою або рівною за верÑÑ–ÑŽ «Мін. SDK»."
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19029,7 +19059,7 @@ msgstr "ÐžÐ¿Ð¸Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð¼Ñ–ÐºÑ€Ð¾Ñ„Ð¾Ð½Ð°"
#: platform/iphone/export/export.cpp
msgid "Photolibrary Usage Description"
-msgstr "ÐžÐ¿Ð¸Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ¸ фотографій"
+msgstr "ÐžÐ¿Ð¸Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ¸ Ñвітлин"
#: platform/iphone/export/export.cpp
msgid "iPhone 120 X 120"
@@ -19349,7 +19379,7 @@ msgstr "ÐžÐ¿Ð¸Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ"
#: platform/osx/export/export.cpp
msgid "Photos Library Usage Description"
-msgstr "ÐžÐ¿Ð¸Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ¸ фотографій"
+msgstr "ÐžÐ¿Ð¸Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ¸ Ñвітлин"
#: platform/osx/export/export.cpp
msgid "Desktop Folder Usage Description"
@@ -19430,7 +19460,7 @@ msgstr "Календарі"
#: platform/osx/export/export.cpp
msgid "Photos Library"
-msgstr "Бібліотека фотографій"
+msgstr "Бібліотека Ñвітлин"
#: platform/osx/export/export.cpp
msgid "Apple Events"
@@ -19815,7 +19845,7 @@ msgid ""
"Privacy: Photo library access is enabled, but usage description is not "
"specified."
msgstr ""
-"КонфіденційніÑть: увімкнено доÑтуп до бібліотеки фотографій, але Ð¾Ð¿Ð¸Ñ "
+"КонфіденційніÑть: увімкнено доÑтуп до бібліотеки Ñвітлин, але Ð¾Ð¿Ð¸Ñ "
"викориÑÑ‚Ð°Ð½Ð½Ñ Ð½Ðµ вказано."
#: platform/osx/export/export.cpp
@@ -20348,7 +20378,7 @@ msgstr "МаÑштаб"
msgid "Custom Viewport"
msgstr "1 панель переглÑду"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -21027,11 +21057,42 @@ msgstr "Розмір комірки"
msgid "Edge Connection Margin"
msgstr "Поле з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ€ÐµÐ±ÐµÑ€"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Палітурка"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "U-відÑтань контуру"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr "МакÑ. відÑтань контуру"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Додатково"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "ÐŸÑ€Ð¸Ñ…Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¾"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21047,15 +21108,6 @@ msgstr "Віддзеркалити горизонтально"
msgid "Max Speed"
msgstr "МакÑ. швидкіÑть"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr "МакÑ. відÑтань контуру"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "ÐŸÑ€Ð¸Ñ…Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¾"
-
#: scene/2d/navigation_agent_2d.cpp
#, fuzzy
msgid ""
@@ -21102,7 +21154,7 @@ msgstr "Подорож"
msgid "Rotation Degrees"
msgstr "ГрудуÑи обертаннÑ"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr "Загальна Ñтала"
@@ -22187,6 +22239,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Перетворити нормалі"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr "Вектор"
@@ -23055,6 +23114,11 @@ msgstr ""
"ЗаміÑть цієї зміни, вам варто змінити розміри дочірніх форм зіткненнÑ."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Зберегти загальне перетвореннÑ"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr "МатрицÑ"
@@ -24161,6 +24225,11 @@ msgid "Fold Gutter"
msgstr "МіжÑтовпцевий проміжок згортаннÑ"
#: scene/gui/text_edit.cpp
+#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Увімкнено позначеннÑ"
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr "ÐŸÑ€Ð¸Ñ…Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¾"
@@ -24519,18 +24588,6 @@ msgstr "ШлÑÑ… до панелі переглÑду"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"Ð¦Ñ Ð¿Ð°Ð½ÐµÐ»ÑŒ показу не Ñ” ціллю обробки зображеннÑ. Якщо ви хочете, щоб Ñ—Ñ— вміÑÑ‚ "
-"було безпоÑередньо показано на екрані, зробіть Ñ—Ñ— дочірньою Ð´Ð»Ñ Ð²ÑƒÐ·Ð»Ð° "
-"Control, щоб у неї був розмір. Крім того, можна зробити її RenderTarget і "
-"пов'Ñзати Ñ—Ñ— внутрішню текÑтуру з одним із вузлів Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ."
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr ""
@@ -24538,6 +24595,15 @@ msgstr ""
"або рівним 2 пікÑелÑм в обох вимірах."
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr "ARVR"
@@ -26093,6 +26159,16 @@ msgstr "Розміри планки"
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Базове зміщеннÑ"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 79cb7b84e2..46cd56a57b 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -408,6 +408,11 @@ msgstr ""
msgid "Command"
msgstr "کمیونٹی"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "سب سکریپشن بنائیں"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -460,6 +465,10 @@ msgid "Pressure"
msgstr ""
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5407,6 +5416,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr ".تمام کا انتخاب"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -7799,11 +7813,20 @@ msgid "New Anim"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr ""
@@ -7821,11 +7844,6 @@ msgid "Animation name already exists!"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -7969,10 +7987,6 @@ msgid "Pin AnimationPlayer"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -18373,6 +18387,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "ایکشن منتقل کریں"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18381,6 +18400,16 @@ msgstr ""
msgid "Export Format"
msgstr "سب سکریپشن بنائیں"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "سب سکریپشن بنائیں"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr ".اینیمیشن کی کیز کو ڈیلیٹ کرو"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -18417,16 +18446,6 @@ msgstr ""
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "سب سکریپشن بنائیں"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr ".اینیمیشن کی کیز کو ڈیلیٹ کرو"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -18663,12 +18682,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -18677,17 +18696,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20272,7 +20311,7 @@ msgstr ""
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -20963,34 +21002,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr ".تمام کا انتخاب"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "مستقل"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "ایک مینو منظر چنیں"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "سب سکریپشن بنائیں"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "سب سکریپشن بنائیں"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "سب سکریپشن بنائیں"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21031,7 +21092,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "مستقل"
@@ -22114,6 +22175,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "سب سکریپشن بنائیں"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr ""
@@ -22948,6 +23016,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "سب سکریپشن بنائیں"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24083,6 +24156,11 @@ msgstr ""
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr ".تمام کا انتخاب"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "سب سکریپشن بنائیں"
@@ -24462,16 +24540,17 @@ msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -26143,6 +26222,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr ".تمام کا انتخاب"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index a16d75a4bc..32fe3c1087 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -412,6 +412,11 @@ msgstr "Meta"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "Vật lí"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -465,6 +470,10 @@ msgid "Pressure"
msgstr "Ãp lá»±c"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "Tương đối"
@@ -5492,6 +5501,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "Chá»n tất cả"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "Ngoại hình"
@@ -7953,11 +7967,20 @@ msgid "New Anim"
msgstr "Hoạt ảnh mới"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "Tạo Hoạt ảnh mới"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "Äổi tên Hoạt ảnh:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Äổi tên hoạt hình"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "Xoá hoạt hình?"
@@ -7975,11 +7998,6 @@ msgid "Animation name already exists!"
msgstr "Tên Hoạt ảnh đã tồn tại!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "Äổi tên hoạt hình"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "Nhân đôi hoạt hình"
@@ -8124,10 +8142,6 @@ msgid "Pin AnimationPlayer"
msgstr "Ghim AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "Tạo Hoạt ảnh mới"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "Tên hoạt hình:"
@@ -18786,6 +18800,11 @@ msgid "The package must have at least one '.' separator."
msgstr "Kí tự phân cách '.' phải xuất hiện ít nhất một lần trong tên gói."
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "Cắt các nút"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18794,6 +18813,16 @@ msgstr ""
msgid "Export Format"
msgstr "ÄÆ°á»ng dẫn xuất"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "Kích cỡ viá»n:"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "BỠmặt mục tiêu:"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18836,16 +18865,6 @@ msgstr "Cửa sổ trước"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "Kích cỡ viá»n:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "BỠmặt mục tiêu:"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19092,7 +19111,7 @@ msgstr "\"Sá»­ dụng Bản dá»±ng tùy chỉnh\" phải được bật để sá
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"\"Theo dõi chuyển động tay\" chỉ dùng được khi \"Xr Mode\" là \"Oculus "
@@ -19100,7 +19119,7 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
"\"Theo dõi chuyển động tay\" chỉ dùng được khi \"Xr Mode\" là \"Oculus "
"Mobile VR\"."
@@ -19113,20 +19132,40 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Xuất AAB\" chỉ dùng được khi \"Sử dụng Bản dựng tùy chỉnh\" được bật."
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
#, fuzzy
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr ""
"\"Xuất AAB\" chỉ dùng được khi \"Sử dụng Bản dựng tùy chỉnh\" được bật."
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -20810,7 +20849,7 @@ msgstr "Phóng to"
msgid "Custom Viewport"
msgstr "1 Cổng xem"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21559,11 +21598,42 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "Chỉnh sửa kết nối:"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "Äệm"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "Chá»n ô"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "Nâng cao"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "Mở"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21581,15 +21651,6 @@ msgstr "Lật Ngang"
msgid "Max Speed"
msgstr "Tốc độ:"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr ""
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "Mở"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -21634,7 +21695,7 @@ msgstr "Di chuyển"
msgid "Rotation Degrees"
msgstr "Xoay %s độ."
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "Hằng số"
@@ -22819,6 +22880,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "Hủy Biến đổi."
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23714,6 +23782,11 @@ msgstr ""
"Hãy sửa kích cỡ khối va chạm của nút con ý."
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "Xóa biến đổi"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -24935,6 +25008,11 @@ msgstr "Thư mục:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "Chỉ chá»n"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "Mở"
@@ -25339,16 +25417,17 @@ msgstr "ÄÆ°á»ng dẫn xuất"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
+"The Viewport size must be greater than or equal to 2 pixels on both "
+"dimensions to render anything."
msgstr ""
#: scene/main/viewport.cpp
msgid ""
-"The Viewport size must be greater than or equal to 2 pixels on both "
-"dimensions to render anything."
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
msgstr ""
#: scene/main/viewport.cpp
@@ -27106,6 +27185,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "Äang sinh AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "Äá»™ dá»i:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index ea23349421..a2183dd550 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -89,7 +89,7 @@ msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2022-06-19 11:52+0000\n"
+"PO-Revision-Date: 2022-07-09 21:12+0000\n"
"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hans/>\n"
@@ -466,6 +466,10 @@ msgstr "Meta"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr "物ç†"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -517,6 +521,11 @@ msgid "Pressure"
msgstr "压力"
#: core/os/input_event.cpp
+#, fuzzy
+msgid "Pen Inverted"
+msgstr "翻转"
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr "相对"
@@ -716,14 +725,12 @@ msgid "Script Templates Search Path"
msgstr "è„šæœ¬æ¨¡æ¿æœç´¢è·¯å¾„"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Autoload On Startup"
-msgstr "å¯åŠ¨æ—¶è‡ªåŠ¨åŠ è½½"
+msgstr "å¯åŠ¨æ—¶è‡ªåŠ¨åŠ è½½ç‰ˆæœ¬æŽ§åˆ¶"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Plugin Name"
-msgstr "版本控制"
+msgstr "版本控制æ’ä»¶å"
#: core/project_settings.cpp scene/2d/collision_object_2d.cpp
#: scene/3d/collision_object.cpp scene/gui/control.cpp
@@ -2788,7 +2795,6 @@ msgid "Completed with errors."
msgstr "已完æˆï¼Œå­˜åœ¨é”™è¯¯ã€‚"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed successfully."
msgstr "æˆåŠŸå®Œæˆã€‚"
@@ -5434,6 +5440,10 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr "使用专门鼠标按键查看历å²"
#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr "拖放选中内容"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "外观"
@@ -5665,7 +5675,7 @@ msgstr "网格细分级别下é™"
#: editor/editor_settings.cpp
msgid "Grid Division Level Bias"
-msgstr "网格细分级别å倚"
+msgstr "网格细分级别åç½®"
#: editor/editor_settings.cpp
msgid "Grid XZ Plane"
@@ -7738,11 +7748,20 @@ msgid "New Anim"
msgstr "新建动画"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "创建新动画"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "修改动画å称:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "é‡å‘½å动画"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "是å¦åˆ é™¤åŠ¨ç”»ï¼Ÿ"
@@ -7760,11 +7779,6 @@ msgid "Animation name already exists!"
msgstr "动画å称已存在ï¼"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "é‡å‘½å动画"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "å¤åˆ¶åŠ¨ç”»"
@@ -7907,10 +7921,6 @@ msgid "Pin AnimationPlayer"
msgstr "固定 AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "创建新动画"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "动画å称:"
@@ -14173,7 +14183,7 @@ msgid ""
"Please edit the project and set the main scene in the Project Settings under "
"the \"Application\" category."
msgstr ""
-"无法è¿è¡Œé¡¹ç›®ï¼šæœªå®šä¹‰ä¸»åœºæ™¯ã€‚ \n"
+"无法è¿è¡Œé¡¹ç›®ï¼šæœªå®šä¹‰ä¸»åœºæ™¯ã€‚\n"
"请编辑项目并在 “项目设置†的 “Application†类别下设置主场景。"
#: editor/project_manager.cpp
@@ -18068,6 +18078,10 @@ msgid "The package must have at least one '.' separator."
msgstr "包必须至少有一个 “.†分隔符。"
#: platform/android/export/export_plugin.cpp
+msgid "Custom Build"
+msgstr "自定义构建"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr "使用自定义构建"
@@ -18075,6 +18089,14 @@ msgstr "使用自定义构建"
msgid "Export Format"
msgstr "导出格å¼"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr "æœ€å° SDK"
+
+#: platform/android/export/export_plugin.cpp
+msgid "Target SDK"
+msgstr "目标 SDK"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr "æž¶æž„"
@@ -18111,14 +18133,6 @@ msgstr "清除上次安装"
msgid "Code"
msgstr "代ç "
-#: platform/android/export/export_plugin.cpp
-msgid "Min SDK"
-msgstr "æœ€å° SDK"
-
-#: platform/android/export/export_plugin.cpp
-msgid "Target SDK"
-msgstr "目标 SDK"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
msgid "Package"
msgstr "包"
@@ -18340,33 +18354,54 @@ msgstr "å¿…é¡»å¯ç”¨ “使用自定义构建†æ‰èƒ½ä½¿ç”¨æ’件。"
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
-msgstr ""
-"“Hand Trackingâ€åªæœ‰åœ¨å½““Xr Modeâ€æ˜¯â€œOculus Mobile VrApiâ€æˆ–“OpenXRâ€æ—¶æ‰æœ‰æ•ˆã€‚"
+msgstr "“手势跟踪â€åªæœ‰åœ¨å½““XR 模å¼â€æ˜¯â€œOculus Mobile VrApiâ€æˆ–“OpenXRâ€æ—¶æ‰æœ‰æ•ˆã€‚"
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
-msgstr "“Passthroughâ€åªæœ‰åœ¨å½““Xr Modeâ€æ˜¯â€œOpenXRâ€æ—¶æ‰æœ‰æ•ˆã€‚"
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
+msgstr "“穿é€â€åªæœ‰åœ¨å½““XR Modeâ€æ˜¯â€œOpenXRâ€æ—¶æ‰æœ‰æ•ˆã€‚"
#: platform/android/export/export_plugin.cpp
msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
-msgstr "“Export AABâ€åªæœ‰åœ¨å½“å¯ç”¨â€œUse Custom Buildâ€æ—¶æ‰æœ‰æ•ˆã€‚"
+msgstr "“Export AABâ€åªæœ‰åœ¨å½“å¯ç”¨â€œä½¿ç”¨è‡ªå®šä¹‰æž„å»ºâ€æ—¶æ‰æœ‰æ•ˆã€‚"
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
-msgstr "修改“Min Sdkâ€åªæœ‰åœ¨å½“å¯ç”¨â€œUse Custom Buildâ€æ—¶æ‰æœ‰æ•ˆã€‚"
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr "ä¿®æ”¹â€œæœ€å° SDKâ€åªæœ‰åœ¨å½“å¯ç”¨â€œä½¿ç”¨è‡ªå®šä¹‰æž„å»ºâ€æ—¶æ‰æœ‰æ•ˆã€‚"
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr "â€œæœ€å° SDKâ€åº”当为有效的整数,但获得了无效的“%sâ€ã€‚"
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
-msgstr "修改“Target Sdkâ€åªæœ‰åœ¨å½“å¯ç”¨â€œUse Custom Buildâ€æ—¶æ‰æœ‰æ•ˆã€‚"
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr "â€œæœ€å° SDKâ€ä¸èƒ½ä½ŽäºŽ %d,这是 Godot 库所需è¦çš„版本。"
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
-msgstr "“Target Sdkâ€ç‰ˆæœ¬å¿…须大于等于“Min Sdkâ€ç‰ˆæœ¬ã€‚"
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr "修改“目标 SDKâ€åªæœ‰åœ¨å½“å¯ç”¨â€œä½¿ç”¨è‡ªå®šä¹‰æž„å»ºâ€æ—¶æ‰æœ‰æ•ˆã€‚"
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr "“目标 SDKâ€åº”当为有效的整数,但获得了无效的“%sâ€ã€‚"
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+"“目标 SDKâ€%d 比默认版本 %d è¦é«˜ã€‚这样åšä¹Ÿè®¸å¯è¡Œï¼Œä½†å¹¶æ²¡æœ‰ç»è¿‡æµ‹è¯•,å¯èƒ½ä¸ç¨³"
+"定。"
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
+msgstr "“目标 SDKâ€ç‰ˆæœ¬å¿…é¡»å¤§äºŽç­‰äºŽâ€œæœ€å° SDKâ€ç‰ˆæœ¬ã€‚"
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
#: platform/windows/export/export.cpp
@@ -19693,8 +19728,8 @@ msgid ""
"The rcedit tool must be configured in the Editor Settings (Export > Windows "
"> Rcedit) to change the icon or app information data."
msgstr ""
-"必须在编辑器设置中é…ç½® rcedit 工具(Export > Windows > Rcedit)æ‰èƒ½ä¿®æ”¹å›¾æ ‡æˆ–"
-"åº”ç”¨ä¿¡æ¯æ•°æ®ã€‚"
+"必须在编辑器设置中é…ç½® rcedit 工具(导出 > Windows > Rcedit)æ‰èƒ½ä¿®æ”¹å›¾æ ‡æˆ–应"
+"ç”¨ä¿¡æ¯æ•°æ®ã€‚"
#: platform/windows/export/export.cpp
msgid "Invalid icon path:"
@@ -19897,7 +19932,7 @@ msgstr "缩放"
msgid "Custom Viewport"
msgstr "自定义视区"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
msgid "Process Mode"
@@ -20397,7 +20432,7 @@ msgstr "节点 B"
#: scene/3d/light.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp
#: scene/resources/environment.cpp
msgid "Bias"
-msgstr "å倚"
+msgstr "åç½®"
#: scene/2d/joints_2d.cpp
msgid "Disable Collision"
@@ -20564,11 +20599,40 @@ msgstr "å•元格大å°"
msgid "Edge Connection Margin"
msgstr "边界连接边è·"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+"“Navigation2Dâ€èŠ‚ç‚¹å’Œâ€œNavigation2D.get_simple_path()â€å·²åºŸå¼ƒï¼Œä¼šåœ¨å°†æ¥çš„版本中"
+"移除。请用“Navigation2DServer.map_get_path()â€æ›¿ä»£ã€‚"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Pathfinding"
+msgstr "寻路"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Desired Distance"
+msgstr "路径期望è·ç¦»"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr "目标期望è·ç¦»"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr "路径最大è·ç¦»"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Avoidance"
+msgstr "é¿éšœ"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Avoidance Enabled"
+msgstr "å¯ç”¨é¿éšœ"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr "邻接è·ç¦»"
@@ -20584,14 +20648,6 @@ msgstr "时间下é™"
msgid "Max Speed"
msgstr "最大速度"
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
-msgstr "路径最大è·ç¦»"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Avoidance Enabled"
-msgstr "å¯ç”¨é¿éšœ"
-
#: scene/2d/navigation_agent_2d.cpp
msgid ""
"The NavigationAgent2D can be used only under a Node2D inheriting parent node."
@@ -20631,7 +20687,7 @@ msgstr "移动消耗"
msgid "Rotation Degrees"
msgstr "旋转角度"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
msgid "Global Rotation"
msgstr "全局旋转"
@@ -21535,7 +21591,7 @@ msgstr "动æ€èŒƒå›´"
#: scene/3d/gi_probe.cpp scene/3d/light.cpp
msgid "Normal Bias"
-msgstr "法线å倚"
+msgstr "法线åç½®"
#: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp
#: scene/resources/primitive_meshes.cpp
@@ -21646,7 +21702,7 @@ msgstr "æ··åˆæ‹†åˆ†"
#: scene/3d/light.cpp
msgid "Bias Split Scale"
-msgstr "å倚拆分缩放"
+msgstr "å置拆分缩放"
#: scene/3d/light.cpp
msgid "Depth Range"
@@ -21684,6 +21740,15 @@ msgstr "软件蒙皮"
msgid "Transform Normals"
msgstr "å˜æ¢æ³•线"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+"“Navigationâ€èŠ‚ç‚¹å’Œâ€œNavigation.get_simple_path()â€å·²åºŸå¼ƒï¼Œä¼šåœ¨å°†æ¥çš„版本中移"
+"除。请用“NavigationServer.map_get_path()â€æ›¿ä»£ã€‚"
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
msgid "Up Vector"
msgstr "上å‘é‡"
@@ -21871,7 +21936,7 @@ msgstr "角度下é™"
#: scene/3d/physics_body.cpp
msgid "Angular Limit Bias"
-msgstr "角度é™åˆ¶å倚"
+msgstr "角度é™åˆ¶åç½®"
#: scene/3d/physics_body.cpp
msgid "Angular Limit Softness"
@@ -22497,6 +22562,11 @@ msgstr ""
"建议修改å­èŠ‚ç‚¹çš„ç¢°æ’žä½“å½¢çŠ¶å°ºå¯¸ã€‚"
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "å…¨å±€å˜æ¢"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr "矩阵"
@@ -23587,6 +23657,10 @@ msgid "Fold Gutter"
msgstr "æŠ˜å æ "
#: scene/gui/text_edit.cpp
+msgid "Drag And Drop Selection Enabled"
+msgstr "å¯ç”¨æ‹–放选中内容"
+
+#: scene/gui/text_edit.cpp
msgid "Hiding Enabled"
msgstr "å¯ç”¨éšè—"
@@ -23943,22 +24017,23 @@ msgstr "Viewport 路径"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"这个视窗未被设置为渲染目标。如果你想让其直接在å±å¹•上显示内容,请使其æˆä¸º "
-"Control çš„å­èŠ‚ç‚¹ï¼Œè¿™æ ·ä¸€æ¥è¯¥ Viewport æ‰ä¼šæœ‰å¤§å°ã€‚å¦åˆ™è¯·ä¸ºå…¶è®¾ç½® "
-"RenderTarget 并分é…å…¶å†…éƒ¨çº¹ç†æ¥æ˜¾ç¤ºã€‚"
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr "Viewport 的宽高都大于等于 2 åƒç´ æ—¶æ‰èƒ½è¿›è¡Œæ¸²æŸ“。"
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+"这个 Viewport å¯ç”¨äº† HDR,但其 Usage 为 2D 或 2D No-Sampling。\n"
+"HDR 仅在 Usage 为 3D 或 3D No-Effects çš„ Viewport 中支æŒã€‚\n"
+"这个 Viewport å°†ç¦ç”¨ HDR。"
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr "ARVR"
@@ -25465,6 +25540,14 @@ msgstr "凸å°èŒƒå›´"
msgid "Walkable Low Height Spans"
msgstr "å¯è¡Œèµ°ä½Žé«˜åº¦èŒƒå›´"
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr "烘焙 AABB"
+
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB Offset"
+msgstr "烘焙 AABB åç§»"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr "çƒä½“"
@@ -25587,7 +25670,7 @@ msgstr "A"
#: scene/resources/shape_2d.cpp
msgid "Custom Solver Bias"
-msgstr "自定义求解器å倚"
+msgstr "自定义求解器åç½®"
#: scene/resources/skin.cpp
msgid "Bind Count"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index 01c72c6ee1..dcd0403c6a 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -417,6 +417,11 @@ msgstr ""
msgid "Command"
msgstr "社群"
+#: core/os/input_event.cpp
+#, fuzzy
+msgid "Physical"
+msgstr "物ç†å¹€ %"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -474,6 +479,10 @@ msgid "Pressure"
msgstr "é‡è¨­ç¸®æ”¾æ¯”例"
#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
+
+#: core/os/input_event.cpp
msgid "Relative"
msgstr ""
@@ -5663,6 +5672,11 @@ msgid "Mouse Extra Buttons Navigate History"
msgstr ""
#: editor/editor_settings.cpp
+#, fuzzy
+msgid "Drag And Drop Selection"
+msgstr "刪除é¸ä¸­æª”案"
+
+#: editor/editor_settings.cpp
msgid "Appearance"
msgstr ""
@@ -8183,11 +8197,20 @@ msgid "New Anim"
msgstr "新增動畫"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "更改動畫å稱:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "釿–°å‘½åå‹•ç•«"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "刪除動畫?"
@@ -8207,11 +8230,6 @@ msgid "Animation name already exists!"
msgstr "錯誤:動畫å稱已存在ï¼"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "釿–°å‘½åå‹•ç•«"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr ""
@@ -8363,10 +8381,6 @@ msgid "Pin AnimationPlayer"
msgstr "貼上動畫"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr ""
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr ""
@@ -19119,6 +19133,11 @@ msgid "The package must have at least one '.' separator."
msgstr ""
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "貼上"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -19127,6 +19146,16 @@ msgstr ""
msgid "Export Format"
msgstr "匯出"
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Min SDK"
+msgstr "下一個腳本"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "目標"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
msgid "Architectures"
msgstr ""
@@ -19165,16 +19194,6 @@ msgstr "上一個tab"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "下一個腳本"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "目標"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
@@ -19419,12 +19438,12 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -19433,17 +19452,37 @@ msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
msgstr ""
#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
msgstr ""
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr ""
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -21095,7 +21134,7 @@ msgstr "放大"
msgid "Custom Viewport"
msgstr ""
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -21801,34 +21840,56 @@ msgstr ""
msgid "Edge Connection Margin"
msgstr "編輯連接"
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "貼上動畫"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Path Desired Distance"
+msgstr "鏿“‡ä¸»å ´æ™¯"
+
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Neighbor Dist"
+msgid "Path Max Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Neighbors"
-msgstr ""
+#, fuzzy
+msgid "Avoidance"
+msgstr "進階"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Time Horizon"
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "啟用"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Neighbor Dist"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Max Speed"
+msgid "Max Neighbors"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-msgid "Path Max Distance"
+msgid "Time Horizon"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "啟用"
+msgid "Max Speed"
+msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21869,7 +21930,7 @@ msgstr ""
msgid "Rotation Degrees"
msgstr ""
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "常數"
@@ -22988,6 +23049,13 @@ msgstr ""
msgid "Transform Normals"
msgstr "縮放selection"
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
+
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
msgid "Up Vector"
@@ -23855,6 +23923,11 @@ msgid ""
msgstr ""
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "翻譯"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
@@ -25042,6 +25115,11 @@ msgstr "資料夾:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "åªé™é¸ä¸­"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "啟用"
@@ -25435,14 +25513,6 @@ msgid "Viewport Path"
msgstr "匯出"
#: scene/main/viewport.cpp
-msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-
-#: scene/main/viewport.cpp
#, fuzzy
msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
@@ -25450,6 +25520,15 @@ msgid ""
msgstr "viewport大å°å¿…須大於ï¼ä»¥æ¸²æŸ“任何æ±è¥¿ã€‚"
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -27170,6 +27249,15 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+msgid "Baking AABB"
+msgstr ""
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "移除é¸é …"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index be888529cc..d56bc9ec23 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -33,13 +33,16 @@
# Haoyu Qiu <timothyqiu32@gmail.com>, 2022.
# Otis Kao <momoslim@gmail.com>, 2022.
# YuChiang Chang <chiang.c.tw@gmail.com>, 2022.
+# è˜è˜ <rrt467778@gmail.com>, 2022.
+# marktwtn <marktwtn@gmail.com>, 2022.
+# Shi-Xun Hong <jimmy3421@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-05-30 16:17+0000\n"
-"Last-Translator: YuChiang Chang <chiang.c.tw@gmail.com>\n"
+"PO-Revision-Date: 2022-07-18 08:11+0000\n"
+"Last-Translator: è˜è˜ <rrt467778@gmail.com>\n"
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hant/>\n"
"Language: zh_TW\n"
@@ -47,7 +50,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.13-dev\n"
+"X-Generator: Weblate 4.14-dev\n"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Tablet Driver"
@@ -70,27 +73,22 @@ msgid "V-Sync Enabled"
msgstr "å•Ÿç”¨åž‚ç›´åŒæ­¥"
#: core/bind/core_bind.cpp main/main.cpp
-#, fuzzy
msgid "V-Sync Via Compositor"
msgstr "é€éŽåˆæˆå™¨åž‚ç›´åŒæ­¥"
#: core/bind/core_bind.cpp main/main.cpp
-#, fuzzy
msgid "Delta Smoothing"
-msgstr "變é‡å¹³æ»‘"
+msgstr "å·®é‡å¹³æ»‘"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Low Processor Usage Mode"
msgstr "低處ç†å™¨ä½¿ç”¨çŽ‡æ¨¡å¼"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Low Processor Usage Mode Sleep (µsec)"
msgstr "低處ç†å™¨ä½¿ç”¨çŽ‡æ¨¡å¼ç¡çœ ï¼ˆå¾®ç§’)"
#: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp
-#, fuzzy
msgid "Keep Screen On"
msgstr "ä¿æŒèž¢å¹•開啟"
@@ -157,9 +155,8 @@ msgid "Size"
msgstr "大å°"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Endian Swap"
-msgstr "切æ›ç«¯åº"
+msgstr "切æ›å­—節åº"
#: core/bind/core_bind.cpp
msgid "Editor Hint"
@@ -178,9 +175,8 @@ msgid "Target FPS"
msgstr "標準FPS"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Time Scale"
-msgstr "TimeScale 節點"
+msgstr "時間縮放"
#: core/bind/core_bind.cpp main/main.cpp
msgid "Physics Jitter Fix"
@@ -199,9 +195,8 @@ msgid "Error Line"
msgstr "發生錯誤之行數"
#: core/bind/core_bind.cpp
-#, fuzzy
msgid "Result"
-msgstr "æœå°‹çµæžœ"
+msgstr "çµæžœ"
#: core/command_queue_mt.cpp core/message_queue.cpp main/main.cpp
msgid "Memory"
@@ -230,7 +225,6 @@ msgstr "多執行緒佇列大å°(KB)"
#: modules/visual_script/visual_script_func_nodes.cpp
#: modules/visual_script/visual_script_nodes.cpp
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Function"
msgstr "函å¼"
@@ -260,17 +254,14 @@ msgid "Page Read Ahead"
msgstr "é å…ˆè®€å–é æ•¸"
#: core/io/http_client.cpp
-#, fuzzy
msgid "Blocking Mode Enabled"
-msgstr "啟用阻礙模å¼"
+msgstr "啟用阻塞模å¼"
#: core/io/http_client.cpp
-#, fuzzy
msgid "Connection"
msgstr "連接"
#: core/io/http_client.cpp
-#, fuzzy
msgid "Read Chunk Size"
msgstr "讀å–å€å¡Šå¤§å°"
@@ -287,12 +278,10 @@ msgid "Refuse New Network Connections"
msgstr "拒絕新網路連接"
#: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp
-#, fuzzy
msgid "Network Peer"
-msgstr "å°ç­‰ç¶²è·¯ä½¿ç”¨è€…"
+msgstr "å°ç­‰ç¶²è·¯"
#: core/io/multiplayer_api.cpp scene/animation/animation_player.cpp
-#, fuzzy
msgid "Root Node"
msgstr "根節點"
@@ -301,9 +290,8 @@ msgid "Refuse New Connections"
msgstr "拒絕新網路連接"
#: core/io/networked_multiplayer_peer.cpp
-#, fuzzy
msgid "Transfer Mode"
-msgstr "轉æ›é¡žåž‹"
+msgstr "傳輸模å¼"
#: core/io/packet_peer.cpp
msgid "Encode Buffer Max Size"
@@ -353,9 +341,8 @@ msgid "Not enough bytes for decoding bytes, or invalid format."
msgstr "ä½å…ƒçµ„長度ä¸è¶³ä»¥é€²è¡Œè§£ç¢¼æˆ–或格å¼ç„¡æ•ˆã€‚"
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid input %d (not passed) in expression"
-msgstr "é‹ç®—å¼ä¸­çš„輸入 %i 無效 (未傳éžï¼‰"
+msgstr "é‹ç®—å¼çš„輸入%d 無效(未傳éžï¼‰"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
@@ -387,7 +374,6 @@ msgid "Seed"
msgstr "種å­"
#: core/math/random_number_generator.cpp
-#, fuzzy
msgid "State"
msgstr "狀態"
@@ -400,14 +386,12 @@ msgid "Max Size (KB)"
msgstr "最大大å°ï¼ˆKB)"
#: core/os/input.cpp
-#, fuzzy
msgid "Mouse Mode"
-msgstr "移動模å¼"
+msgstr "滑鼠模å¼"
#: core/os/input.cpp
-#, fuzzy
msgid "Use Accumulated Input"
-msgstr "刪除輸入"
+msgstr "使用累ç©è¼¸å…¥"
#: core/os/input_event.cpp editor/project_settings_editor.cpp
#: servers/audio_server.cpp
@@ -434,10 +418,13 @@ msgstr "Meta"
msgid "Command"
msgstr "Command"
+#: core/os/input_event.cpp
+msgid "Physical"
+msgstr "物ç†"
+
#: core/os/input_event.cpp scene/2d/touch_screen_button.cpp
#: scene/gui/base_button.cpp scene/gui/texture_button.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Pressed"
msgstr "按下"
@@ -446,21 +433,18 @@ msgid "Scancode"
msgstr "éµç›¤æŽƒæç¢¼"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Physical Scancode"
-msgstr "實體éµç›¤æŽƒæç¢¼"
+msgstr "ç‰©ç†æŽƒæç¢¼"
#: core/os/input_event.cpp
msgid "Unicode"
msgstr "Unicode"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Echo"
-msgstr "Echo"
+msgstr "回è²"
#: core/os/input_event.cpp scene/gui/base_button.cpp
-#, fuzzy
msgid "Button Mask"
msgstr "按éµé®ç½©"
@@ -469,7 +453,6 @@ msgid "Global Position"
msgstr "全域ä½ç½®"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Factor"
msgstr "å› ç´ "
@@ -486,12 +469,14 @@ msgid "Tilt"
msgstr "傾斜"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Pressure"
-msgstr "按壓"
+msgstr "壓力"
+
+#: core/os/input_event.cpp
+msgid "Pen Inverted"
+msgstr ""
#: core/os/input_event.cpp
-#, fuzzy
msgid "Relative"
msgstr "相å°"
@@ -527,12 +512,10 @@ msgid "Strength"
msgstr "強度"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Delta"
-msgstr "變é‡"
+msgstr "å·®é‡"
#: core/os/input_event.cpp
-#, fuzzy
msgid "Channel"
msgstr "é »é“"
@@ -608,14 +591,12 @@ msgid "Main Scene"
msgstr "主場景"
#: core/project_settings.cpp
-#, fuzzy
msgid "Disable stdout"
-msgstr "ç¦ç”¨è‡ªå‹•圖塊"
+msgstr "åœç”¨æ¨™æº–輸出"
#: core/project_settings.cpp
-#, fuzzy
msgid "Disable stderr"
-msgstr "å·²åœç”¨çš„é …ç›®"
+msgstr "åœç”¨æ¨™æº–錯誤輸出"
#: core/project_settings.cpp
msgid "Use Hidden Project Data Directory"
@@ -632,15 +613,14 @@ msgstr "自訂使用者目錄å稱"
#: core/project_settings.cpp main/main.cpp
#: platform/javascript/export/export.cpp platform/osx/export/export.cpp
#: platform/uwp/os_uwp.cpp
-#, fuzzy
msgid "Display"
-msgstr "全部顯示"
+msgstr "顯示"
#: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp
#: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp
#: scene/3d/label_3d.cpp scene/gui/text_edit.cpp scene/resources/texture.cpp
msgid "Width"
-msgstr ""
+msgstr "寬"
#: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp
#: modules/gltf/gltf_node.cpp modules/opensimplex/noise_texture.cpp
@@ -648,23 +628,20 @@ msgstr ""
#: scene/resources/capsule_shape_2d.cpp scene/resources/cylinder_shape.cpp
#: scene/resources/font.cpp scene/resources/navigation_mesh.cpp
#: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp
-#, fuzzy
msgid "Height"
-msgstr "燈光"
+msgstr "高度"
#: core/project_settings.cpp
msgid "Always On Top"
-msgstr ""
+msgstr "置頂"
#: core/project_settings.cpp
-#, fuzzy
msgid "Test Width"
-msgstr "左延展"
+msgstr "測試寬度"
#: core/project_settings.cpp
-#, fuzzy
msgid "Test Height"
-msgstr "測試"
+msgstr "測試高度"
#: core/project_settings.cpp editor/animation_track_editor.cpp
#: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp
@@ -683,33 +660,28 @@ msgid "Editor"
msgstr "編輯器"
#: core/project_settings.cpp
-#, fuzzy
msgid "Main Run Args"
msgstr "主執行引數"
#: core/project_settings.cpp
-#, fuzzy
msgid "Scene Naming"
-msgstr "場景路徑:"
+msgstr "場景命å"
#: core/project_settings.cpp
-#, fuzzy
msgid "Search In File Extensions"
-msgstr "ä»¥å‰¯æª”åæœå°‹"
+msgstr "ä»¥æª”æ¡ˆå‰¯æª”åæœå°‹"
#: core/project_settings.cpp
msgid "Script Templates Search Path"
msgstr "è…³æœ¬æ¨£æ¿æœå°‹è·¯å¾‘"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Autoload On Startup"
-msgstr "啟動時自動載入"
+msgstr "啟動時自動載入版本控制"
#: core/project_settings.cpp
-#, fuzzy
msgid "Version Control Plugin Name"
-msgstr "版本控制"
+msgstr "版本控制外掛å稱"
#: core/project_settings.cpp scene/2d/collision_object_2d.cpp
#: scene/3d/collision_object.cpp scene/gui/control.cpp
@@ -717,9 +689,8 @@ msgid "Input"
msgstr "輸入"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Accept"
-msgstr "UI確定"
+msgstr "確定 (UI)"
#: core/project_settings.cpp
msgid "UI Select"
@@ -730,43 +701,36 @@ msgid "UI Cancel"
msgstr "UIå–æ¶ˆ"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Focus Next"
-msgstr "èšç„¦è·¯å¾‘"
+msgstr "èšç„¦ä¸‹ä¸€å€‹ (UI)"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Focus Prev"
-msgstr "èšç„¦è·¯å¾‘"
+msgstr "èšç„¦ä¸Šä¸€å€‹ (UI)"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Left"
-msgstr "左上"
+msgstr "å·¦ (UI)"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Right"
-msgstr "å³ä¸Š"
+msgstr "å³ (UI)"
#: core/project_settings.cpp
msgid "UI Up"
msgstr "UI上"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Down"
-msgstr "UI下"
+msgstr "下 (UI)"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Page Up"
-msgstr "UIé é¢å‘上滾動"
+msgstr "é é¢ä¸Šæ»¾ (UI)"
#: core/project_settings.cpp
-#, fuzzy
msgid "UI Page Down"
-msgstr "UIé é¢å‘下滾動"
+msgstr "é é¢ä¸‹æ»¾ (UI)"
#: core/project_settings.cpp
msgid "UI Home"
@@ -798,7 +762,6 @@ msgid "3D"
msgstr "3D"
#: core/project_settings.cpp
-#, fuzzy
msgid "Smooth Trimesh Collision"
msgstr "平滑三角網格碰撞"
@@ -827,12 +790,10 @@ msgstr "å“質"
#: core/project_settings.cpp scene/gui/file_dialog.cpp
#: scene/main/scene_tree.cpp scene/resources/navigation_mesh.cpp
#: servers/visual_server.cpp
-#, fuzzy
msgid "Filters"
msgstr "篩é¸å™¨"
#: core/project_settings.cpp scene/main/viewport.cpp
-#, fuzzy
msgid "Sharpen Intensity"
msgstr "銳化強度"
@@ -859,9 +820,8 @@ msgid "Profiler"
msgstr "分æžå·¥å…·"
#: core/project_settings.cpp
-#, fuzzy
msgid "Max Functions"
-msgstr "最大值函å¼"
+msgstr "æœ€å¤§å‡½å¼æ•¸"
#: core/project_settings.cpp scene/3d/vehicle_body.cpp
msgid "Compression"
@@ -876,18 +836,16 @@ msgid "Zstd"
msgstr "Zstd"
#: core/project_settings.cpp
-#, fuzzy
msgid "Long Distance Matching"
-msgstr "é•·è·é…å°"
+msgstr "é•·è·é›¢åŒ¹é…"
#: core/project_settings.cpp
msgid "Compression Level"
msgstr "壓縮等級"
#: core/project_settings.cpp
-#, fuzzy
msgid "Window Log Size"
-msgstr "視窗日誌大å°"
+msgstr "è¦–çª—å°æ•¸å¤§å°"
#: core/project_settings.cpp
msgid "Zlib"
@@ -910,14 +868,12 @@ msgid "TCP"
msgstr "TCP"
#: core/register_core_types.cpp
-#, fuzzy
msgid "Connect Timeout Seconds"
-msgstr "連接逾時秒數"
+msgstr "連線逾時秒數"
#: core/register_core_types.cpp
-#, fuzzy
msgid "Packet Peer Stream"
-msgstr "å°åŒ…å°ç­‰ä¸²æµ"
+msgstr "å°åŒ…å°ç­‰æµ"
#: core/register_core_types.cpp
msgid "Max Buffer (Power of 2)"
@@ -928,7 +884,6 @@ msgid "SSL"
msgstr "SSL"
#: core/register_core_types.cpp main/main.cpp
-#, fuzzy
msgid "Certificates"
msgstr "憑證"
@@ -939,9 +894,8 @@ msgid "Resource"
msgstr "資æº"
#: core/resource.cpp
-#, fuzzy
msgid "Local To Scene"
-msgstr "關閉場景"
+msgstr "åƒ…é™æœ¬å ´æ™¯"
#: core/resource.cpp editor/dependency_editor.cpp
#: editor/editor_autoload_settings.cpp editor/plugins/path_editor_plugin.cpp
@@ -959,14 +913,12 @@ msgid "Locale"
msgstr "地å€"
#: core/translation.cpp
-#, fuzzy
msgid "Test"
msgstr "測試"
#: core/translation.cpp scene/resources/font.cpp
-#, fuzzy
msgid "Fallback"
-msgstr "éžè£œ"
+msgstr "後備語言"
#: core/ustring.cpp scene/resources/segment_shape_2d.cpp
msgid "B"
@@ -1028,27 +980,23 @@ msgstr "2D"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
-#, fuzzy
msgid "Snapping"
msgstr "å¸é™„"
#: drivers/gles2/rasterizer_canvas_base_gles2.cpp
#: drivers/gles3/rasterizer_canvas_base_gles3.cpp
-#, fuzzy
msgid "Use GPU Pixel Snap"
-msgstr "使用GPUåƒç´ å¸é™„"
+msgstr "使用 GPU åƒç´ å¸é™„"
#: drivers/gles2/rasterizer_scene_gles2.cpp
#: drivers/gles3/rasterizer_scene_gles3.cpp
-#, fuzzy
msgid "Immediate Buffer Size (KB)"
msgstr "峿™‚ç·©è¡å€å¤§å°ï¼ˆKB)"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
-#, fuzzy
msgid "Lightmapping"
-msgstr "烘焙光照圖"
+msgstr "光照貼圖"
#: drivers/gles2/rasterizer_storage_gles2.cpp
#: drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1097,9 +1045,8 @@ msgid "Weight Samples"
msgstr "æ¬Šé‡æŽ¡æ¨£"
#: drivers/gles3/rasterizer_scene_gles3.cpp
-#, fuzzy
msgid "Voxel Cone Tracing"
-msgstr "é«”ç´ æ¤Žé«”ææ‘¹"
+msgstr "體素éŒè¿½è¸ª"
#: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp
msgid "High Quality"
@@ -1181,9 +1128,8 @@ msgstr "更改動畫呼å«"
#: editor/animation_track_editor.cpp scene/2d/animated_sprite.cpp
#: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Frame"
-msgstr "影格 %"
+msgstr "影格"
#: editor/animation_track_editor.cpp editor/editor_profiler.cpp
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
@@ -1194,16 +1140,14 @@ msgstr "時間"
#: editor/animation_track_editor.cpp editor/import/resource_importer_scene.cpp
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Location"
-msgstr "本地化"
+msgstr "ä½ç½®"
#: editor/animation_track_editor.cpp modules/gltf/gltf_node.cpp
#: scene/2d/polygon_2d.cpp scene/2d/remote_transform_2d.cpp
#: scene/3d/remote_transform.cpp scene/3d/spatial.cpp scene/gui/control.cpp
-#, fuzzy
msgid "Rotation"
-msgstr "旋轉步長:"
+msgstr "旋轉"
#: editor/animation_track_editor.cpp editor/script_editor_debugger.cpp
#: modules/visual_script/visual_script_nodes.cpp scene/gui/range.cpp
@@ -1211,14 +1155,13 @@ msgid "Value"
msgstr "數值"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Arg Count"
-msgstr "數é‡ï¼š"
+msgstr "引數數é‡"
#: editor/animation_track_editor.cpp main/main.cpp
#: modules/mono/mono_gd/gd_mono.cpp
msgid "Args"
-msgstr ""
+msgstr "åƒæ•¸"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp
@@ -1230,29 +1173,27 @@ msgstr "型別"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "In Handle"
-msgstr "設定處ç†ç¨‹å¼"
+msgstr "輸入把手"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Out Handle"
-msgstr "設定處ç†ç¨‹å¼"
+msgstr "輸出把手"
#: editor/animation_track_editor.cpp
#: editor/import/resource_importer_texture.cpp
#: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp
#: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp
msgid "Stream"
-msgstr ""
+msgstr "æµ"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Start Offset"
-msgstr "網格åç§»é‡ï¼š"
+msgstr "起點åç§»"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "End Offset"
-msgstr "å移:"
+msgstr "終點åç§»"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
#: editor/import/resource_importer_scene.cpp
@@ -1265,7 +1206,6 @@ msgid "Animation"
msgstr "å‹•ç•«"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Easing"
msgstr "緩入緩出"
@@ -1376,19 +1316,16 @@ msgid "Remove this track."
msgstr "移除該動畫軌。"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Time (s):"
-msgstr "時間(秒) : "
+msgstr "時間(秒):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Position:"
-msgstr "ä½ç½®"
+msgstr "ä½ç½®ï¼š"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rotation:"
-msgstr "旋轉步長:"
+msgstr "旋轉:"
#: editor/animation_track_editor.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -1405,14 +1342,12 @@ msgid "Type:"
msgstr "型別:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "(Invalid, expected type: %s)"
-msgstr "無效的輸出樣æ¿ï¼š"
+msgstr "ï¼ˆç„¡æ•ˆï¼Œé æœŸåž‹åˆ¥ï¼š%s)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Easing:"
-msgstr "緩入緩出"
+msgstr "緩入緩出:"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -1425,24 +1360,20 @@ msgid "Out-Handle:"
msgstr "設定處ç†ç¨‹å¼"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Stream:"
-msgstr "串æµä½¿ç”¨è€…"
+msgstr "æµï¼š"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Start (s):"
-msgstr "釿–°é–‹å§‹ï¼ˆç§’):"
+msgstr "開始(秒):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "End (s):"
-msgstr "淡入(秒):"
+msgstr "çµæŸï¼ˆç§’):"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Clip:"
-msgstr "動畫:"
+msgstr "動畫片段:"
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
@@ -1496,9 +1427,8 @@ msgid "Duplicate Key(s)"
msgstr "é‡è¤‡é—œéµç•«æ ¼"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add RESET Value(s)"
-msgstr "新增 %d 個影格"
+msgstr "新增 RESET 值"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
@@ -1527,14 +1457,12 @@ msgstr "刪除動畫軌"
#: editor/plugins/tile_map_editor_plugin.cpp editor/scene_tree_dock.cpp
#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Editors"
msgstr "編輯器"
#: editor/animation_track_editor.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Confirm Insert Track"
-msgstr "新增動畫軌é“與關éµç•«æ ¼"
+msgstr "ç¢ºèªæ’入軌é“"
#. TRANSLATORS: %s will be replaced by a phrase describing the target of track.
#: editor/animation_track_editor.cpp
@@ -1658,9 +1586,8 @@ msgid "Add Method Track Key"
msgstr "新增方法軌é“é—œéµç•«æ ¼"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Method not found in object:"
-msgstr "在物件中找ä¸åˆ°æ–¹æ³•: "
+msgstr "在物件中找ä¸åˆ°è©²æ–¹æ³•:"
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
@@ -1701,9 +1628,8 @@ msgid ""
msgstr "該é¸é …ä¸é©ç”¨è²èŒ²æ›²ç·šç·¨è¼¯ï¼Œå› æ›²ç·šåƒ…有單一軌é“。"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Add RESET Keys"
-msgstr "動畫縮放關éµå½±æ ¼"
+msgstr "新增動畫 RESET éµ"
#: editor/animation_track_editor.cpp
msgid ""
@@ -1717,7 +1643,7 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
-"該動畫屬於外部匯入之場景,套用於匯入軌é“çš„ä¿®æ”¹å°‡ä¸æœƒè¢«ä¿å­˜ã€‚\n"
+"該動畫屬於外部匯入之場景,套用於匯入軌é“çš„ä¿®æ”¹å°‡ä¸æœƒè¢«å„²å­˜ã€‚\n"
"\n"
"è‹¥è¦é–‹å•Ÿã€ŒåŠ å…¥å®¢åˆ¶è»Œã€çš„功能,請在場景在匯入設定中將 [Animation] -> "
"[Storage] 設定為\n"
@@ -2263,7 +2189,7 @@ msgstr "開啟"
#: editor/dependency_editor.cpp
msgid "Owners of: %s (Total: %d)"
-msgstr ""
+msgstr "%s 的所有者(總計:%d)"
#: editor/dependency_editor.cpp
msgid ""
@@ -2372,7 +2298,6 @@ msgstr "主è¦é–‹ç™¼è€…"
#. TRANSLATORS: This refers to a job title.
#: editor/editor_about.cpp
-#, fuzzy
msgctxt "Job Title"
msgid "Project Manager"
msgstr "專案管ç†å“¡"
@@ -2614,9 +2539,8 @@ msgid "There is no '%s' file."
msgstr "檔案「%sã€ä¸å­˜åœ¨ã€‚"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Layout:"
-msgstr "ç•«é¢é…ç½®"
+msgstr "佈局:"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
@@ -2650,7 +2574,7 @@ msgstr "å¦å­˜æ–°æª”"
#: editor/editor_audio_buses.cpp
msgid "Save this Bus Layout to a file."
-msgstr "å°‡è©²åŒ¯æµæŽ’é…ç½®ä¿å­˜è‡³æª”案。"
+msgstr "å°‡è©²åŒ¯æµæŽ’é…置儲存至檔案。"
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
@@ -2665,9 +2589,8 @@ msgid "Create a new Bus Layout."
msgstr "å»ºç«‹æ–°åŒ¯æµæŽ’é…置。"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Audio Bus Layout"
-msgstr "é–‹å•ŸéŸ³è¨ŠåŒ¯æµæŽ’é…ç½®"
+msgstr "éŸ³è¨ŠåŒ¯æµæŽ’ä½ˆå±€"
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -2785,7 +2708,7 @@ msgstr "[空]"
#: editor/plugins/text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "[unsaved]"
-msgstr "[未ä¿å­˜]"
+msgstr "[未儲存]"
#: editor/editor_dir_dialog.cpp
msgid "Please select a base directory first."
@@ -2820,22 +2743,19 @@ msgstr "鏿“‡"
#: editor/editor_export.cpp
msgid "Project export for platform:"
-msgstr ""
+msgstr "專案匯出平å°ï¼š"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed with errors."
-msgstr "複製節點路徑"
+msgstr "已完æˆï¼Œå­˜åœ¨éŒ¯èª¤ã€‚"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Completed successfully."
-msgstr "å¥—ä»¶å®‰è£æˆåŠŸï¼"
+msgstr "å¥—ä»¶å®‰è£æˆåŠŸã€‚"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed."
-msgstr "失敗:"
+msgstr "失敗。"
#: editor/editor_export.cpp
msgid "Storing File:"
@@ -2850,29 +2770,24 @@ msgid "Packing"
msgstr "正在打包"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save PCK"
-msgstr "å¦å­˜æ–°æª”"
+msgstr "儲存 PCK"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Cannot create file \"%s\"."
-msgstr "無法新增資料夾。"
+msgstr "無法建立「%sã€æª”案。"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to export project files."
-msgstr "無法匯出專案檔案"
+msgstr "無法匯出專案檔。"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Can't open file to read from path \"%s\"."
-msgstr "無法開啟欲寫入的檔案:"
+msgstr "ç„¡æ³•æ‰“é–‹ä½æ–¼ã€Œ%sã€çš„æª”案用於讀å–。"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Save ZIP"
-msgstr "å¦å­˜æ–°æª”"
+msgstr "儲存 ZIP"
#: editor/editor_export.cpp
msgid ""
@@ -2897,7 +2812,7 @@ msgid ""
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
-"目標平å°ä¸Šçš„ GLES2 回退驅動器功能必須使用「ETCã€ç´‹ç†å£“縮。\n"
+"目標平å°ä¸Šçš„ GLES2 後備驅動器功能必須使用「ETCã€ç´‹ç†å£“縮。\n"
"請在專案設定中啟用「Import Etcã€æˆ–是ç¦ç”¨ã€ŒDriver Fallback Enabledã€ã€‚"
#: editor/editor_export.cpp
@@ -2923,15 +2838,14 @@ msgid ""
"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
-"目標平å°ä¸Šçš„ GLES2 回退驅動器功能必須使用「PVRTCã€ç´‹ç†å£“縮。\n"
+"目標平å°ä¸Šçš„ GLES2 後備驅動器功能必須使用「PVRTCã€ç´‹ç†å£“縮。\n"
"請在專案設定中啟用「Import Pvrtcã€æˆ–是ç¦ç”¨ã€ŒDriver Fallback Enabledã€ã€‚"
#: editor/editor_export.cpp platform/android/export/export_plugin.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
-#, fuzzy
msgid "Custom Template"
-msgstr "編輯器主題"
+msgstr "自訂模æ¿"
#: editor/editor_export.cpp editor/project_export.cpp
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
@@ -2941,9 +2855,8 @@ msgid "Release"
msgstr "發行"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Binary Format"
-msgstr "色彩é‹ç®—å­ã€‚"
+msgstr "äºŒé€²ä½æ ¼å¼"
#: editor/editor_export.cpp
msgid "64 Bits"
@@ -2954,9 +2867,8 @@ msgid "Embed PCK"
msgstr "內嵌PCK"
#: editor/editor_export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Texture Format"
-msgstr "ç´‹ç†è²¼åœ–å€åŸŸ"
+msgstr "ç´‹ç†è²¼åœ–æ ¼å¼"
#: editor/editor_export.cpp
msgid "BPTC"
@@ -2975,9 +2887,8 @@ msgid "ETC2"
msgstr "ETC2"
#: editor/editor_export.cpp
-#, fuzzy
msgid "No BPTC Fallbacks"
-msgstr "ç„¡BPTC回è½"
+msgstr "無 BPTC 後備"
#: editor/editor_export.cpp platform/android/export/export_plugin.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -2992,30 +2903,25 @@ msgid "Custom release template not found."
msgstr "找ä¸åˆ°è‡ªå®šç¾©ç™¼è¡Œæ¨£æ¿ã€‚"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Prepare Template"
-msgstr "ç®¡ç†æ¨£æ¿"
+msgstr "ç®¡ç†æ¨¡æ¿"
#: editor/editor_export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "The given export path doesn't exist."
-msgstr "給定的匯出路徑ä¸å­˜åœ¨ï¼š"
+msgstr "給定的匯出路徑ä¸å­˜åœ¨ã€‚"
#: editor/editor_export.cpp platform/javascript/export/export.cpp
-#, fuzzy
msgid "Template file not found: \"%s\"."
-msgstr "找ä¸åˆ°æ¨£æ¿æª”案:"
+msgstr "找ä¸åˆ°æ¨¡æ¿æª”案:「%sã€ã€‚"
#: editor/editor_export.cpp
-#, fuzzy
msgid "Failed to copy export template."
-msgstr "無效的輸出樣æ¿ï¼š"
+msgstr "複製匯出模æ¿å¤±æ•—。"
#: editor/editor_export.cpp platform/windows/export/export.cpp
#: platform/x11/export/export.cpp
-#, fuzzy
msgid "PCK Embedding"
-msgstr "å¡«å……"
+msgstr "PCK 內嵌"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
@@ -3223,9 +3129,8 @@ msgid "Manage Editor Feature Profiles"
msgstr "管ç†ç·¨è¼¯å™¨åŠŸèƒ½è¨­å®šæª”"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Default Feature Profile"
-msgstr "Godot 功能設定檔"
+msgstr "é è¨­åŠŸèƒ½è¨­å®šæª”"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -3290,21 +3195,19 @@ msgstr "開啟檔案或資料夾"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
-msgstr "ä¿å­˜"
+msgstr "儲存"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Save a File"
-msgstr "ä¿å­˜æª”案"
+msgstr "儲存檔案"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Access"
-msgstr "æˆåŠŸï¼"
+msgstr "å­˜å–"
#: editor/editor_file_dialog.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Display Mode"
-msgstr "播放模å¼ï¼š"
+msgstr "顯示模å¼"
#: editor/editor_file_dialog.cpp
#: editor/import/resource_importer_layered_texture.cpp
@@ -3317,30 +3220,25 @@ msgstr "播放模å¼ï¼š"
#: scene/resources/environment.cpp scene/resources/material.cpp
#: scene/resources/visual_shader.cpp
#: servers/audio/effects/audio_effect_distortion.cpp
-#, fuzzy
msgid "Mode"
-msgstr "平移模å¼"
+msgstr "模å¼"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Current Dir"
-msgstr "ç›®å‰ï¼š"
+msgstr "ç›®å‰ç›®éŒ„"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Current File"
-msgstr "ç›®å‰è¨­å®šæª”:"
+msgstr "所在檔案"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Current Path"
-msgstr "ç›®å‰ï¼š"
+msgstr "所在目錄"
#: editor/editor_file_dialog.cpp editor/editor_settings.cpp
#: scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Show Hidden Files"
-msgstr "顯示ï¼å–æ¶ˆé¡¯ç¤ºéš±è—æª”案"
+msgstr "顯示隱è—的檔案"
#: editor/editor_file_dialog.cpp
msgid "Disable Overwrite Warning"
@@ -3475,9 +3373,8 @@ msgid "Properties"
msgstr "屬性"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "複寫:"
+msgstr "覆蓋 %s:"
#: editor/editor_help.cpp
msgid "default:"
@@ -3635,46 +3532,39 @@ msgid "Property:"
msgstr "屬性:"
#: editor/editor_inspector.cpp editor/editor_spin_slider.cpp
-#, fuzzy
msgid "Label"
-msgstr "數值"
+msgstr "標籤"
#: editor/editor_inspector.cpp editor/editor_spin_slider.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Read Only"
-msgstr "僅顯示方法"
+msgstr "åªè®€"
#: editor/editor_inspector.cpp editor/plugins/item_list_editor_plugin.cpp
-#, fuzzy
msgid "Checkable"
-msgstr "檢查項目"
+msgstr "å¯å‹¾é¸"
#: editor/editor_inspector.cpp editor/plugins/item_list_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Checked"
-msgstr "已檢查的項目"
+msgstr "已勾é¸"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Draw Red"
-msgstr "繪製呼å«ï¼š"
+msgstr "繪製紅色"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Keying"
-msgstr "執行"
+msgstr "輸入"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Pin value"
-msgstr "(數值)"
+msgstr "固定值"
#: editor/editor_inspector.cpp
msgid ""
"Pinning a value forces it to be saved even if it's equal to the default."
-msgstr "釘é¸çš„æ•¸å€¼å°‡è¢«è¿«ä¿å­˜ï¼Œå³ä½¿å…¶å€¼èˆ‡é è¨­å€¼ç›¸åŒã€‚"
+msgstr "釘é¸çš„æ•¸å€¼å°‡è¢«è¿«å„²å­˜ï¼Œå³ä½¿å…¶å€¼èˆ‡é è¨­å€¼ç›¸åŒã€‚"
#: editor/editor_inspector.cpp
msgid "Pin value [Disabled because '%s' is editor-only]"
@@ -3702,19 +3592,16 @@ msgid "Unpinned %s"
msgstr "已解除釘é¸%s"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property"
msgstr "複製屬性"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Paste Property"
msgstr "貼上屬性"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property Path"
-msgstr "複製腳本路徑"
+msgstr "複製屬性路徑"
#: editor/editor_log.cpp
msgid "Output:"
@@ -3804,7 +3691,7 @@ msgstr "ç·¨è¼¯å™¨è¦–çª—é‡æ–°ç¹ªè£½æ™‚旋轉。"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr "匯入的資æºç„¡æ³•ä¿å­˜ã€‚"
+msgstr "匯入的資æºç„¡æ³•儲存。"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
@@ -3820,7 +3707,7 @@ msgstr "ä¿å­˜è³‡æºæ™‚發生錯誤ï¼"
msgid ""
"This resource can't be saved because it does not belong to the edited scene. "
"Make it unique first."
-msgstr "由於該資æºä¸å±¬æ–¼å·²ç·¨è¼¯çš„場景,無法ä¿å­˜è©²è³‡æºã€‚請先使其ç¨ç«‹åŒ–。"
+msgstr "由於該資æºä¸å±¬æ–¼å·²ç·¨è¼¯çš„場景,無法儲存該資æºã€‚請先使其ç¨ç«‹åŒ–。"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
@@ -3879,22 +3766,22 @@ msgid ""
"This scene can't be saved because there is a cyclic instancing inclusion.\n"
"Please resolve it and then attempt to save again."
msgstr ""
-"該場景有循環性實體化å•題,無法ä¿å­˜ã€‚\n"
+"該場景有循環性實體化å•題,無法儲存。\n"
"請先解決此å•題後å†è©¦ä¸€æ¬¡ã€‚"
#: editor/editor_node.cpp
msgid ""
"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
"be satisfied."
-msgstr "無法ä¿å­˜å ´æ™¯ã€‚å¯èƒ½æ˜¯ç”±æ–¼ç›¸ä¾æ€§ï¼ˆå¯¦é«”或繼承)無法滿足。"
+msgstr "無法儲存場景。å¯èƒ½æ˜¯ç”±æ–¼ç›¸ä¾æ€§ï¼ˆå¯¦é«”或繼承)無法滿足。"
#: editor/editor_node.cpp
msgid "Could not save one or more scenes!"
-msgstr "無法ä¿å­˜ä¸€æˆ–多個場景ï¼"
+msgstr "無法儲存一或多個場景ï¼"
#: editor/editor_node.cpp
msgid "Save All Scenes"
-msgstr "ä¿å­˜æ‰€æœ‰å ´æ™¯"
+msgstr "儲存所有場景"
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "Can't overwrite scene that is still open!"
@@ -3921,7 +3808,7 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
-"ä¿å­˜ç·¨è¼¯å™¨ç•«é¢é…置時發生錯誤。\n"
+"儲存編輯器畫é¢é…置時發生錯誤。\n"
"請確èªç·¨è¼¯å™¨çš„使用者資料路徑是å¦å¯å¯«å…¥ã€‚"
#: editor/editor_node.cpp
@@ -3990,7 +3877,7 @@ msgstr "未定義欲執行之場景。"
#: editor/editor_node.cpp
msgid "Save scene before running..."
-msgstr "執行å‰å…ˆä¿å­˜å ´æ™¯..."
+msgstr "執行å‰å…ˆå„²å­˜å ´æ™¯..."
#: editor/editor_node.cpp
msgid "Could not start subprocess!"
@@ -4017,38 +3904,36 @@ msgid "Quick Open Script..."
msgstr "快速開啟腳本…"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save & Reload"
-msgstr "ä¿å­˜ä¸¦é‡æ–°å•Ÿå‹•"
+msgstr "å„²å­˜ä¸¦é‡æ–°è¼‰å…¥"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save changes to '%s' before reloading?"
-msgstr "é—œé–‰å‰æ˜¯å¦ä¿å­˜å°ã€Œ%sã€çš„æ›´æ”¹ï¼Ÿ"
+msgstr "是å¦åœ¨é‡æ–°è¼‰å…¥å‰å„²å­˜å°ã€Œ%sã€çš„變更?"
#: editor/editor_node.cpp
msgid "Save & Close"
-msgstr "ä¿å­˜ä¸¦é—œé–‰"
+msgstr "儲存並關閉"
#: editor/editor_node.cpp
msgid "Save changes to '%s' before closing?"
-msgstr "é—œé–‰å‰æ˜¯å¦ä¿å­˜å°ã€Œ%sã€çš„æ›´æ”¹ï¼Ÿ"
+msgstr "é—œé–‰å‰æ˜¯å¦å„²å­˜å°ã€Œ%sã€çš„æ›´æ”¹ï¼Ÿ"
#: editor/editor_node.cpp
msgid "%s no longer exists! Please specify a new save location."
-msgstr "%sä¸å­˜åœ¨ï¼è«‹æŒ‡å®šæ–°çš„ä¿å­˜ä½ç½®ã€‚"
+msgstr "%sä¸å­˜åœ¨ï¼è«‹æŒ‡å®šæ–°çš„儲存ä½ç½®ã€‚"
#: editor/editor_node.cpp
msgid ""
"The current scene has no root node, but %d modified external resource(s) "
"were saved anyway."
-msgstr "ç›®å‰çš„場景無根節點,但%d個被更改的外部資æºå·²è¢«ä¿å­˜ã€‚"
+msgstr "ç›®å‰çš„場景無根節點,但%d個被更改的外部資æºå·²è¢«å„²å­˜ã€‚"
#: editor/editor_node.cpp
msgid ""
"A root node is required to save the scene. You can add a root node using the "
"Scene tree dock."
-msgstr "必須有根節點æ‰å¯ä¿å­˜å ´æ™¯ã€‚您å¯ä½¿ç”¨å ´æ™¯åœä½‡åˆ—以加入一個根節點。"
+msgstr "必須有根節點æ‰å¯å„²å­˜å ´æ™¯ã€‚您å¯ä½¿ç”¨å ´æ™¯åœä½‡åˆ—以加入一個根節點。"
#: editor/editor_node.cpp
msgid "Save Scene As..."
@@ -4076,7 +3961,7 @@ msgstr "è«‹å…ˆé¸æ“‡ç¯€é»žä»¥åŸ·è¡Œè©²æ“作。"
#: editor/editor_node.cpp
msgid "Current scene not saved. Open anyway?"
-msgstr "尚未ä¿å­˜ç›®å‰å ´æ™¯ã€‚ä»ç„¶è¦é–‹å•Ÿå—Žï¼Ÿ"
+msgstr "尚未儲存目å‰å ´æ™¯ã€‚ä»ç„¶è¦é–‹å•Ÿå—Žï¼Ÿ"
#: editor/editor_node.cpp
msgid "Can't undo while mouse buttons are pressed."
@@ -4104,18 +3989,18 @@ msgstr "å–æ¶ˆå¾©åŽŸï¼š%s"
#: editor/editor_node.cpp
msgid "Can't reload a scene that was never saved."
-msgstr "ç„¡æ³•é‡æ–°è¼‰å…¥å¾žæœªä¿å­˜éŽçš„場景。"
+msgstr "ç„¡æ³•é‡æ–°è¼‰å…¥å¾žæœªå„²å­˜éŽçš„場景。"
#: editor/editor_node.cpp
msgid "Reload Saved Scene"
-msgstr "釿–°è¼‰å…¥å·²ä¿å­˜çš„場景"
+msgstr "釿–°è¼‰å…¥å·²å„²å­˜çš„場景"
#: editor/editor_node.cpp
msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
msgstr ""
-"ç›®å‰å ´æ™¯æœ‰æœªä¿å­˜çš„æ”¹å‹•。\n"
+"ç›®å‰å ´æ™¯æœ‰æœªå„²å­˜çš„æ”¹å‹•。\n"
"ä»è¦é‡æ–°è¼‰å…¥å ´æ™¯å—Žï¼Ÿæ­¤æ“作將無法復原。"
#: editor/editor_node.cpp
@@ -4139,21 +4024,20 @@ msgid "Open Project Manager?"
msgstr "è¦é–‹å•Ÿå°ˆæ¡ˆç®¡ç†å“¡å—Žï¼Ÿ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save changes to the following scene(s) before reloading?"
-msgstr "退出å‰è¦å…ˆä¿å­˜ä¸‹åˆ—場景嗎?"
+msgstr "釿–°è¼‰å…¥å‰è¦å„²å­˜ä¸‹åˆ—場景的變更嗎?"
#: editor/editor_node.cpp
msgid "Save & Quit"
-msgstr "ä¿å­˜ä¸¦é€€å‡º"
+msgstr "儲存並退出"
#: editor/editor_node.cpp
msgid "Save changes to the following scene(s) before quitting?"
-msgstr "退出å‰è¦å…ˆä¿å­˜ä¸‹åˆ—場景嗎?"
+msgstr "退出å‰è¦å…ˆå„²å­˜ä¸‹åˆ—場景嗎?"
#: editor/editor_node.cpp
msgid "Save changes to the following scene(s) before opening Project Manager?"
-msgstr "開啟專案管ç†å“¡å‰è¦å…ˆä¿å­˜ä»¥ä¸‹å ´æ™¯å—Žï¼Ÿ"
+msgstr "開啟專案管ç†å“¡å‰è¦å…ˆå„²å­˜ä»¥ä¸‹å ´æ™¯å—Žï¼Ÿ"
#: editor/editor_node.cpp
msgid ""
@@ -4217,7 +4101,7 @@ msgid ""
"open the scene, then save it inside the project path."
msgstr ""
"載入場景時發生錯誤,場景必須置於專案路徑內。請使用 [匯入] 來開啟該場景,並將"
-"å…¶ä¿å­˜æ–¼å°ˆæ¡ˆè·¯å¾‘內。"
+"其儲存於專案路徑內。"
#: editor/editor_node.cpp
msgid "Scene '%s' has broken dependencies:"
@@ -4319,19 +4203,16 @@ msgstr "無法寫入檔案'%s',該檔案正被使用ã€éŽ–å®šæˆ–å› æ¬Šé™ä¸è¶
#: editor/editor_node.cpp editor/editor_settings.cpp editor/scene_tree_dock.cpp
#: servers/arvr/arvr_interface.cpp
-#, fuzzy
msgid "Interface"
-msgstr "使用者界é¢"
+msgstr "界é¢"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Scene Tabs"
-msgstr "切æ›å ´æ™¯åˆ†é "
+msgstr "場景分é "
#: editor/editor_node.cpp
-#, fuzzy
msgid "Always Show Close Button"
-msgstr "æ°¸é é¡¯ç¤ºç¶²æ ¼"
+msgstr "æ°¸é é¡¯ç¤ºé—œé–‰æŒ‰éˆ•"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Resize If Many Tabs"
@@ -4346,14 +4227,12 @@ msgid "Output"
msgstr "輸出"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Always Clear Output On Play"
-msgstr "清除輸出"
+msgstr "åŸ·è¡Œæ™‚æ°¸é æ¸…除輸出"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Always Open Output On Play"
-msgstr "播放時永é é–‹å•Ÿè¼¸å‡º"
+msgstr "執行時永é é–‹å•Ÿè¼¸å‡º"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Always Close Output On Stop"
@@ -4361,41 +4240,35 @@ msgstr "åœæ­¢æ™‚æ°¸é é—œé–‰è¼¸å‡º"
#: editor/editor_node.cpp
msgid "Save On Focus Loss"
-msgstr "失去焦點時ä¿å­˜"
+msgstr "失去焦點時儲存"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Save Each Scene On Quit"
-msgstr "ä¿å­˜åˆ†æ”¯ç‚ºå ´æ™¯"
+msgstr "退出時儲存å„場景"
#: editor/editor_node.cpp editor/editor_settings.cpp
-#, fuzzy
msgid "Quit Confirmation"
-msgstr "檢視資訊"
+msgstr "退出確èª"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Show Update Spinner"
-msgstr "éš±è—æ›´æ–°æ—‹è½‰åœ–"
+msgstr "顯示更新旋轉圖"
#: editor/editor_node.cpp
msgid "Update Continuously"
msgstr "æŒçºŒæ›´æ–°"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Vital Only"
-msgstr "æè³ªè®Šæ›´ï¼š"
+msgstr "僅更新 Vital"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Localize Settings"
-msgstr "本地化"
+msgstr "在地化設定"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Restore Scenes On Load"
-msgstr "TimeSeek 節點"
+msgstr "載入時æ¢å¾©å ´æ™¯"
#: editor/editor_node.cpp editor/editor_settings.cpp
msgid "Show Thumbnail On Hover"
@@ -4406,23 +4279,20 @@ msgid "Inspector"
msgstr "å±¬æ€§é¢æ¿"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Default Property Name Style"
-msgstr "專案路徑:"
+msgstr "é è¨­å±¬æ€§å稱樣å¼"
#: editor/editor_node.cpp
msgid "Default Float Step"
msgstr "é è¨­æµ®é»žæ•¸é–“éš”"
#: editor/editor_node.cpp scene/gui/tree.cpp
-#, fuzzy
msgid "Disable Folding"
-msgstr "å·²åœç”¨çš„æŒ‰éˆ•"
+msgstr "åœç”¨æŠ˜ç–Š"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Auto Unfold Foreign Scenes"
-msgstr "自動展開å°å¤–場景"
+msgstr "自動展開場景"
#: editor/editor_node.cpp
msgid "Horizontal Vector2 Editing"
@@ -4433,14 +4303,12 @@ msgid "Horizontal Vector Types Editing"
msgstr "水平Vector類別編輯"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Resources In Current Inspector"
-msgstr "åœ¨å±¬æ€§é¢æ¿ä¸­é–‹å•Ÿ"
+msgstr "在目å‰çš„å±¬æ€§é¢æ¿æ‰“開資æº"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Resources To Open In New Inspector"
-msgstr "åœ¨å±¬æ€§é¢æ¿ä¸­é–‹å•Ÿ"
+msgstr "åœ¨æ–°çš„å±¬æ€§é¢æ¿é–‹å•Ÿè³‡æº"
#: editor/editor_node.cpp
msgid "Default Color Picker Mode"
@@ -4451,9 +4319,8 @@ msgid "Version Control"
msgstr "版本控制"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Username"
-msgstr "釿–°å‘½å"
+msgstr "使用者å稱"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "SSH Public Key Path"
@@ -4525,7 +4392,7 @@ msgstr "最近開啟的場景"
#: editor/editor_node.cpp
msgid "Save Scene"
-msgstr "ä¿å­˜å ´æ™¯"
+msgstr "儲存場景"
#: editor/editor_node.cpp
msgid "Convert To..."
@@ -4579,9 +4446,8 @@ msgid "Install Android Build Template..."
msgstr "å®‰è£ Android 建置樣æ¿..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open User Data Folder"
-msgstr "開啟編輯器資料目錄"
+msgstr "打開使用者資料資料夾"
#: editor/editor_node.cpp editor/editor_settings.cpp
#: editor/plugins/tile_set_editor_plugin.cpp
@@ -4657,12 +4523,10 @@ msgid ""
msgstr "開啟該é¸é …後,導航網格與多邊形將在專案執行時å¯è¦‹ã€‚"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Force Shader Fallbacks"
-msgstr "強制著色器回è½"
+msgstr "強制著色器後備"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, shaders will be used in their fallback form "
"(either visible via an ubershader or hidden) during all the run time.\n"
@@ -4671,10 +4535,10 @@ msgid ""
"Asynchronous shader compilation must be enabled in the project settings for "
"this option to make a difference."
msgstr ""
-"當該é¸é …啟用時,著色器將以回è½çš„形弿–¼åŸ·è¡Œæ™‚作用(é€éŽUbershader顯示或隱"
+"啟用該é¸é …時,著色器在é‹è¡Œæ™‚會使用其後備形å¼ï¼ˆé€éŽ ubershader 顯示或隱"
"è—)。\n"
-"å¯ç”¨æ–¼é©—證回è½çš„å¤–è§€å’Œæ•ˆèƒ½ï¼Œå…¶åœ¨æ­£å¸¸çš„æƒ…å½¢ä¸‹åªæœƒçŸ­æš«åœ°é¡¯ç¤ºã€‚\n"
-"需啟用專案設定中的éžåŒæ­¥è‘—色器編譯以使該é¸é …ç™¼æ®æ•ˆæžœã€‚"
+"å¯ç”¨æ–¼é©—證後備外觀和效能,正常情æ³ä¸‹åªæœƒçŸ­æš«é¡¯ç¤ºã€‚\n"
+"必須在專案設定中啟用éžåŒæ­¥è‘—色器編譯,該é¸é …æ‰æœƒæœ‰æ•ˆæžœã€‚"
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
@@ -4701,7 +4565,7 @@ msgid ""
"When used remotely on a device, this is more efficient when the network "
"filesystem option is enabled."
msgstr ""
-"開啟該é¸é …後,ä¿å­˜è…³æœ¬æ™‚æœƒæ–¼åŸ·è¡Œä¸­çš„éŠæˆ²å…§é‡æ–°è¼‰å…¥è…³æœ¬ã€‚\n"
+"開啟該é¸é …å¾Œï¼Œå„²å­˜è…³æœ¬æ™‚æœƒæ–¼åŸ·è¡Œä¸­çš„éŠæˆ²å…§é‡æ–°è¼‰å…¥è…³æœ¬ã€‚\n"
"若在é ç«¯è£ç½®ä¸Šä½¿ç”¨ï¼Œå¯ä½¿ç”¨ç¶²è·¯æª”案系統 NFS 以ç²å¾—最佳效能。"
#: editor/editor_node.cpp
@@ -4819,17 +4683,15 @@ msgstr "更改視訊驅動程å¼éœ€è¦é‡æ–°å•Ÿå‹•編輯器。"
#: editor/editor_node.cpp editor/project_settings_editor.cpp
#: editor/settings_config_dialog.cpp
msgid "Save & Restart"
-msgstr "ä¿å­˜ä¸¦é‡æ–°å•Ÿå‹•"
+msgstr "å„²å­˜ä¸¦é‡æ–°å•Ÿå‹•"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update All Changes"
-msgstr "更改時更新"
+msgstr "更新所有變更"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Vital Changes"
-msgstr "æè³ªè®Šæ›´ï¼š"
+msgstr "æ›´æ–° Vital æ›´å‹•"
#: editor/editor_node.cpp
msgid "Hide Update Spinner"
@@ -4847,7 +4709,7 @@ msgstr "å±•é–‹åº•éƒ¨é¢æ¿"
#: editor/editor_node.cpp
msgid "Don't Save"
-msgstr "ä¸ä¿å­˜"
+msgstr "ä¸å„²å­˜"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
@@ -4933,7 +4795,7 @@ msgstr "釿–°è¼‰å…¥"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Resave"
-msgstr "釿–°ä¿å­˜"
+msgstr "釿–°å„²å­˜"
#: editor/editor_node.cpp
msgid "New Inherited"
@@ -5085,14 +4947,12 @@ msgid "Debugger"
msgstr "除錯工具"
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Profiler Frame History Size"
-msgstr "效能分æžå·¥å…·å¹€æ•¸æ­·å²æ—¥èªŒå¤§å°"
+msgstr "分æžå·¥å…·å½±æ ¼æ­·å²å¤§å°"
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Profiler Frame Max Functions"
-msgstr "釿–°å‘½å函å¼"
+msgstr "分æžå·¥å…·å½±æ ¼æœ€å¤§å‡½å¼æ•¸"
#: editor/editor_properties.cpp
msgid "Edit Text:"
@@ -5131,7 +4991,7 @@ msgid ""
"Can't create a ViewportTexture on resources saved as a file.\n"
"Resource needs to belong to a scene."
msgstr ""
-"無法為欲ä¿å­˜æˆæª”案之資æºå»ºç«‹ ViewportTexture。\n"
+"ç„¡æ³•ç‚ºæ¬²å„²å­˜æˆæª”案之資æºå»ºç«‹ ViewportTexture。\n"
"資æºå¿…須屬於一個場景。"
#: editor/editor_properties.cpp
@@ -5159,9 +5019,8 @@ msgid "Size:"
msgstr "大å°ï¼š"
#: editor/editor_properties_array_dict.cpp
-#, fuzzy
msgid "Page:"
-msgstr "é ï¼š "
+msgstr "é ï¼š"
#: editor/editor_properties_array_dict.cpp
#: editor/plugins/theme_editor_plugin.cpp
@@ -5221,20 +5080,17 @@ msgstr "新增 %s"
#: modules/visual_script/visual_script_func_nodes.cpp
#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_yield_nodes.cpp
-#, fuzzy
msgid "Base Type"
-msgstr "更改基礎型別"
+msgstr "基礎型別"
#: editor/editor_resource_picker.cpp
-#, fuzzy
msgid "Edited Resource"
-msgstr "新增資æº"
+msgstr "已經編輯資"
#: editor/editor_resource_picker.cpp scene/gui/line_edit.cpp
#: scene/gui/slider.cpp scene/gui/spin_box.cpp
-#, fuzzy
msgid "Editable"
-msgstr "å¯ç·¨è¼¯çš„é …ç›®"
+msgstr "å¯ç·¨è¼¯"
#: editor/editor_resource_picker.cpp editor/property_editor.cpp
msgid "New Script"
@@ -5245,9 +5101,8 @@ msgid "Extend Script"
msgstr "擴充腳本"
#: editor/editor_resource_picker.cpp
-#, fuzzy
msgid "Script Owner"
-msgstr "腳本å稱:"
+msgstr "腳本所有者"
#: editor/editor_run_native.cpp
msgid ""
@@ -5259,9 +5114,8 @@ msgstr ""
"請在 [匯出] é¸å–®ä¸­æ–°å¢žä¸€å€‹å¯åŸ·è¡Œçš„é è¨­è¨­å®šï¼Œæˆ–å°‡ç¾æœ‰çš„é è¨­è¨­å®šè¨­ç‚ºå¯åŸ·è¡Œã€‚"
#: editor/editor_run_native.cpp
-#, fuzzy
msgid "Project Run"
-msgstr "專案"
+msgstr "執行專案"
#: editor/editor_run_script.cpp
msgid "Write your logic in the _run() method."
@@ -5288,21 +5142,18 @@ msgid "Did you forget the '_run' method?"
msgstr "æ˜¯å¦æœªæ–°å¢žã€Œ_runã€æ–¹æ³•?"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Editor Language"
-msgstr "編輯器é…ç½®"
+msgstr "編輯器語言"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Display Scale"
-msgstr "全部顯示"
+msgstr "顯示縮放"
#: editor/editor_settings.cpp
msgid "Custom Display Scale"
msgstr "自訂顯示縮放"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Main Font Size"
msgstr "主è¦å­—體大å°"
@@ -5319,32 +5170,28 @@ msgid "Font Hinting"
msgstr "字體微調"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Main Font"
-msgstr "主場景"
+msgstr "主è¦å­—é«”"
#: editor/editor_settings.cpp
msgid "Main Font Bold"
msgstr "主è¦å­—體粗體"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Code Font"
-msgstr "新增節點頂點"
+msgstr "程å¼ç¢¼å­—é«”"
#: editor/editor_settings.cpp
msgid "Dim Editor On Dialog Popup"
msgstr "å°è©±æ¡†å½ˆå‡ºæ™‚使編輯器變暗"
#: editor/editor_settings.cpp main/main.cpp
-#, fuzzy
msgid "Low Processor Mode Sleep (µsec)"
-msgstr "低處ç†å™¨ä½¿ç”¨æ¨¡å¼ç¡çœ ï¼ˆå¾®ç§’)"
+msgstr "低處ç†å™¨ç¡çœ æ¨¡å¼ï¼ˆå¾®ç§’)"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Unfocused Low Processor Mode Sleep (µsec)"
-msgstr "éžèšç„¦ä½Žè™•ç†å™¨ä½¿ç”¨æ¨¡å¼ç¡çœ ï¼ˆå¾®ç§’)"
+msgstr "未èšç„¦ä½Žè™•ç†å™¨ç¡çœ æ¨¡å¼ï¼ˆå¾®ç§’)"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5356,9 +5203,8 @@ msgid "Automatically Open Screenshots"
msgstr "自動開啟截圖"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Max Array Dictionary Items Per Page"
-msgstr "æ¯é æœ€å¤§é™£åˆ—字典項目數"
+msgstr "æ¯é æœ€å¤§é™£åˆ—å­—å…¸ç‰©å“æ•¸"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp
@@ -5375,131 +5221,108 @@ msgid "Icon And Font Color"
msgstr "圖標åŠå­—é«”é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Base Color"
-msgstr "é¡è‰²"
+msgstr "基礎é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Accent Color"
-msgstr "鏿“‡é¡è‰²"
+msgstr "強調é¡è‰²"
#: editor/editor_settings.cpp scene/resources/environment.cpp
msgid "Contrast"
msgstr "å°æ¯”"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Relationship Line Opacity"
msgstr "關係線ä¸é€æ˜Žåº¦"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Highlight Tabs"
-msgstr "正在ä¿å­˜å…‰ç…§åœ–"
+msgstr "çªé¡¯é¸é …å¡"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Border Size"
-msgstr "邊界åƒç´ "
+msgstr "邊框大å°"
#: editor/editor_settings.cpp
msgid "Use Graph Node Headers"
msgstr "使用圖形節點標題"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Additional Spacing"
-msgstr "é‡è¤‡å‹•ç•«"
+msgstr "é¡å¤–é–“è·"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Custom Theme"
-msgstr "編輯器主題"
+msgstr "自訂主題"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Show Script Button"
-msgstr "滾輪å‘峿Œ‰éµ"
+msgstr "顯示腳本按鈕"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Directories"
msgstr "æ–¹å‘"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Autoscan Project Path"
-msgstr "專案路徑:"
+msgstr "自動掃æå°ˆæ¡ˆè·¯å¾‘"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Default Project Path"
-msgstr "專案路徑:"
+msgstr "é è¨­å°ˆæ¡ˆè·¯å¾‘"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "On Save"
-msgstr "ä¿å­˜"
+msgstr "儲存時"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Compress Binary Resources"
-msgstr "複製資æº"
+msgstr "壓縮二進ä½è³‡æº"
#: editor/editor_settings.cpp
msgid "Safe Save On Backup Then Rename"
-msgstr "備份時安全ä¿å­˜å¾Œé‡æ–°å‘½å"
+msgstr "å‚™ä»½æ™‚å®‰å…¨å„²å­˜å¾Œé‡æ–°å‘½å"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "File Dialog"
-msgstr "XForm å°è©±æ¡†"
+msgstr "檔案å°è©±æ¡†"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Thumbnail Size"
-msgstr "縮圖…"
+msgstr "縮圖大å°"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Docks"
-msgstr "功能介é¢"
+msgstr "颿¿"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Scene Tree"
-msgstr "正在編輯場景樹"
+msgstr "場景樹"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Start Create Dialog Fully Expanded"
-msgstr "開始新建完全展開å°è©±"
+msgstr "é è¨­å®Œå…¨å±•開建立å°è©±æ¡†"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Always Show Folders"
-msgstr "æ°¸é é¡¯ç¤ºç¶²æ ¼"
+msgstr "æ°¸é é¡¯ç¤ºè³‡æ–™å¤¾"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Property Editor"
-msgstr "群組編輯器"
+msgstr "屬性編輯器"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Auto Refresh Interval"
-msgstr "自動刷新間隔"
+msgstr "自動更新頻率"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Subresource Hue Tint"
-msgstr "å­è³‡æº"
+msgstr "å­è³‡æºå½©è‰²é¡¯ç¤º"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Color Theme"
-msgstr "編輯器主題"
+msgstr "é¡è‰²ä¸»é¡Œ"
#: editor/editor_settings.cpp scene/3d/label_3d.cpp
#: scene/resources/default_theme/default_theme.cpp
@@ -5508,52 +5331,44 @@ msgstr "行間è·"
#: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp
#: modules/gdscript/editor/gdscript_highlighter.cpp
-#, fuzzy
msgid "Highlighting"
-msgstr "呿€§å…‰ç…§"
+msgstr "çªå‡ºé¡¯ç¤º"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
-#, fuzzy
msgid "Syntax Highlighting"
-msgstr "高亮顯示語法"
+msgstr "語法çªå‡ºé¡¯ç¤º"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
msgid "Highlight All Occurrences"
msgstr "凸顯所有符åˆé …ç›®"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
-#, fuzzy
msgid "Highlight Current Line"
-msgstr "凸顯目å‰è¡Œ"
+msgstr "çªé¡¯ç›®å‰è¡Œ"
#: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Highlight Type Safe Lines"
msgstr "凸顯型別安全的行"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Indent"
-msgstr "å‘左縮排"
+msgstr "縮排"
#: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp
msgid "Auto Indent"
msgstr "自動縮排"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Convert Indent On Save"
-msgstr "轉æ›ç¸®æŽ’為空白"
+msgstr "儲存時轉æ›ç¸®æŽ’"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
-#, fuzzy
msgid "Draw Tabs"
-msgstr "繪製呼å«ï¼š"
+msgstr "繪製分é "
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
-#, fuzzy
msgid "Draw Spaces"
-msgstr "繪製呼å«ï¼š"
+msgstr "繪製空格"
#: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/2d/tile_map.cpp
@@ -5571,37 +5386,36 @@ msgid "V Scroll Speed"
msgstr "垂直滾動速度"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Show Minimap"
-msgstr "顯示原點"
+msgstr "顯示迷你地圖"
#: editor/editor_settings.cpp
msgid "Minimap Width"
msgstr "迷你地圖寬度"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Mouse Extra Buttons Navigate History"
-msgstr "滑鼠é¡å¤–æŒ‰éµæ“作歷å²ç´€éŒ„"
+msgstr "使用é¡å¤–æ»‘é¼ æŒ‰éµæŸ¥çœ‹æ­·å²"
+
+#: editor/editor_settings.cpp
+msgid "Drag And Drop Selection"
+msgstr "æ‹–ç§»é¸æ“‡çš„æª”案"
#: editor/editor_settings.cpp
msgid "Appearance"
msgstr "外觀"
#: editor/editor_settings.cpp scene/gui/text_edit.cpp
-#, fuzzy
msgid "Show Line Numbers"
-msgstr "行號:"
+msgstr "顯示行號"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Line Numbers Zero Padded"
-msgstr "行號:"
+msgstr "行號歸零"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Show Bookmark Gutter"
-msgstr "顯示書籤欄ä½"
+msgstr "顯示書籤欄"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5609,44 +5423,38 @@ msgid "Show Breakpoint Gutter"
msgstr "è·³éŽä¸­æ–·é»ž"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Show Info Gutter"
-msgstr "顯示資訊欄ä½"
+msgstr "顯示資訊欄"
#: editor/editor_settings.cpp
msgid "Code Folding"
msgstr "程å¼ç¢¼æŠ˜ç–Š"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Word Wrap"
-msgstr "æ›è¡Œ"
+msgstr "自動æ›è¡Œ"
#: editor/editor_settings.cpp
msgid "Show Line Length Guidelines"
msgstr "顯示行長度åƒè€ƒç·š"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Line Length Guideline Soft Column"
-msgstr "行長度åƒè€ƒç·šè»Ÿåˆ—"
+msgstr "行長度åƒè€ƒç·šè»Ÿåˆ—數"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Line Length Guideline Hard Column"
-msgstr "行長度åƒè€ƒç·šç¡¬åˆ—"
+msgstr "行長度åƒè€ƒç·šç¡¬åˆ—數"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Script List"
-msgstr "腳本編輯器"
+msgstr "腳本列表"
#: editor/editor_settings.cpp
msgid "Show Members Overview"
msgstr "顯示æˆå“¡æ¦‚è¦"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Files"
msgstr "檔案"
@@ -5657,7 +5465,7 @@ msgstr "移除後方空白字元"
#: editor/editor_settings.cpp
msgid "Autosave Interval Secs"
-msgstr "自動ä¿å­˜é–“隔秒數"
+msgstr "自動儲存間隔秒數"
#: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp
msgid "Restore Scripts On Load"
@@ -5665,11 +5473,11 @@ msgstr "載入時æ¢å¾©è…³æœ¬"
#: editor/editor_settings.cpp
msgid "Auto Reload And Parse Scripts On Save"
-msgstr ""
+msgstr "å„²å­˜æ™‚è‡ªå‹•é‡æ–°è¼‰å…¥èˆ‡è§£æžè…³æœ¬"
#: editor/editor_settings.cpp
msgid "Auto Reload Scripts On External Change"
-msgstr ""
+msgstr "å¾žå¤–éƒ¨æ›´æ”¹æ™‚è‡ªå‹•é‡æ–°è¼‰å…¥è…³æœ¬"
#: editor/editor_settings.cpp
msgid "Create Signal Callbacks"
@@ -5684,14 +5492,12 @@ msgid "Cursor"
msgstr "游標"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Scroll Past End Of File"
-msgstr "æ»¾å‹•è¶…éŽæª”案çµå°¾"
+msgstr "æ»¾å‹•è¶…éŽæª”案末尾"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Block Caret"
-msgstr "方形æ’入符"
+msgstr "方形 Caret"
#: editor/editor_settings.cpp
msgid "Caret Blink"
@@ -5709,7 +5515,6 @@ msgstr "å³éµé»žæ“Šä»¥æ–°å¢žæŽ§åˆ¶é»ž"
#: editor/editor_settings.cpp modules/gdscript/gdscript.cpp
#: modules/gdscript/gdscript_editor.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Completion"
msgstr "自動完æˆ"
@@ -5718,22 +5523,20 @@ msgid "Idle Parse Delay"
msgstr "閒置解æžå»¶é²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Auto Brace Complete"
msgstr "自動補齊括號"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Code Complete Delay"
-msgstr "程å¼ç¢¼å®Œæˆå»¶é²"
+msgstr "程å¼ç¢¼è‡ªå‹•完æˆå»¶é²"
#: editor/editor_settings.cpp
msgid "Put Callhint Tooltip Below Current Line"
-msgstr ""
+msgstr "å°‡å‘¼å«æç¤ºå·¥å…·æç¤ºæ¡†ç½®æ–¼ç•¶å‰è¡Œä¹‹ä¸‹"
#: editor/editor_settings.cpp
msgid "Callhint Tooltip Offset"
-msgstr ""
+msgstr "å‘¼å«æç¤ºå·¥å…·æç¤ºæ¡†åç§»é‡"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5741,80 +5544,71 @@ msgid "Complete File Paths"
msgstr "複製節點路徑"
#: editor/editor_settings.cpp modules/gdscript/gdscript_editor.cpp
-#, fuzzy
msgid "Add Type Hints"
-msgstr "新增類別"
+msgstr "新增類別æç¤º"
#: editor/editor_settings.cpp
msgid "Use Single Quotes"
msgstr "使用單引號"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Show Help Index"
-msgstr "顯示輔助資訊"
+msgstr "顯示輔助索引"
#: editor/editor_settings.cpp
msgid "Help Font Size"
-msgstr ""
+msgstr "幫助字體大å°"
#: editor/editor_settings.cpp
msgid "Help Source Font Size"
-msgstr ""
+msgstr "幫助æºå­—體大å°"
#: editor/editor_settings.cpp
msgid "Help Title Font Size"
-msgstr ""
+msgstr "幫助標題字體大å°"
#: editor/editor_settings.cpp modules/gridmap/grid_map_editor_plugin.cpp
msgid "Grid Map"
msgstr "網格地圖"
#: editor/editor_settings.cpp modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Pick Distance"
-msgstr "鏿“‡è·é›¢ï¼š"
+msgstr "拾å–è·é›¢"
#: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Preview Size"
-msgstr "é è¦½"
+msgstr "é è¦½å¤§å°"
#: editor/editor_settings.cpp
msgid "Primary Grid Color"
-msgstr ""
+msgstr "主è¦ç¶²æ ¼é¡è‰²"
#: editor/editor_settings.cpp
msgid "Secondary Grid Color"
-msgstr ""
+msgstr "次è¦ç¶²æ ¼é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Selection Box Color"
-msgstr "僅æœå°‹æ‰€é¸å€åŸŸ"
+msgstr "所é¸å€åŸŸé¡è‰²"
#: editor/editor_settings.cpp editor/plugins/path_editor_plugin.cpp
#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "3D Gizmos"
-msgstr "Gizmo"
+msgstr "3D 控制項"
#: editor/editor_settings.cpp editor/plugins/path_editor_plugin.cpp
#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Gizmo Colors"
-msgstr "發射色彩"
+msgstr "控制項é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Instanced"
-msgstr "實體"
+msgstr "已實體化"
#: editor/editor_settings.cpp modules/gltf/gltf_node.cpp
#: scene/3d/physics_body.cpp
-#, fuzzy
msgid "Joint"
-msgstr "點"
+msgstr "交點"
#: editor/editor_settings.cpp scene/2d/collision_shape_2d.cpp
#: scene/2d/cpu_particles_2d.cpp scene/2d/touch_screen_button.cpp
@@ -5823,110 +5617,95 @@ msgstr "點"
#: scene/resources/particles_material.cpp servers/physics_2d_server.cpp
#: servers/physics_server.cpp
msgid "Shape"
-msgstr ""
+msgstr "形狀"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Primary Grid Steps"
-msgstr "網格大å°ï¼š"
+msgstr "主網格步長"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Grid Size"
-msgstr "網格大å°ï¼š"
+msgstr "網格大å°"
#: editor/editor_settings.cpp
msgid "Grid Division Level Max"
-msgstr ""
+msgstr "網格劃分級別最大值"
#: editor/editor_settings.cpp
msgid "Grid Division Level Min"
-msgstr ""
+msgstr "網格劃分級別最å°å€¼"
#: editor/editor_settings.cpp
msgid "Grid Division Level Bias"
-msgstr ""
+msgstr "網格劃分級別å差值"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Grid XZ Plane"
-msgstr "網格地圖繪圖"
+msgstr "網格XZå¹³é¢"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Grid XY Plane"
-msgstr "網格地圖繪圖"
+msgstr "網格XYå¹³é¢"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Grid YZ Plane"
-msgstr "網格地圖繪圖"
+msgstr "網格YZå¹³é¢"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Default FOV"
-msgstr "é è¨­"
+msgstr "é è¨­FOV"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Default Z Near"
-msgstr "é è¨­ä¸»é¡Œ"
+msgstr "é è¨­Z近處"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Default Z Far"
-msgstr "é è¨­"
+msgstr "é è¨­Zé è™•"
#: editor/editor_settings.cpp
msgid "Lightmap Baking Number Of CPU Threads"
-msgstr ""
+msgstr "光照圖烘焙中央處ç†å™¨ç·šç¨‹æ•¸"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Navigation Scheme"
-msgstr "導航模å¼"
+msgstr "導引模å¼"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Invert Y Axis"
-msgstr "編輯 Y 軸"
+msgstr "翻轉 Y 軸"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Invert X Axis"
-msgstr "編輯 X 軸"
+msgstr "翻轉 X 軸"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Zoom Style"
-msgstr "縮å°"
+msgstr "縮放樣å¼"
#: editor/editor_settings.cpp
msgid "Emulate Numpad"
-msgstr ""
+msgstr "模擬數字éµç›¤"
#: editor/editor_settings.cpp
msgid "Emulate 3 Button Mouse"
-msgstr ""
+msgstr "æ¨¡æ“¬ä¸‰éµæ»‘é¼ "
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Orbit Modifier"
-msgstr "按最早修改時間排åº"
+msgstr "軌é“修改器"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Pan Modifier"
-msgstr "平移模å¼"
+msgstr "平移修改器"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Zoom Modifier"
-msgstr "已修改"
+msgstr "縮放修改器"
#: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Warped Mouse Panning"
-msgstr ""
+msgstr "彎曲滑鼠平移"
#: editor/editor_settings.cpp
#, fuzzy
@@ -5935,235 +5714,205 @@ msgstr "導航模å¼"
#: editor/editor_settings.cpp
msgid "Orbit Sensitivity"
-msgstr ""
+msgstr "軌é“éˆæ•度"
#: editor/editor_settings.cpp
msgid "Orbit Inertia"
-msgstr ""
+msgstr "è»Œé“æ…£æ€§"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Translation Inertia"
-msgstr "翻譯"
+msgstr "平移慣性"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Zoom Inertia"
-msgstr "放大"
+msgstr "變焦慣性"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Freelook"
-msgstr "自由視圖 上"
+msgstr "自由觀看"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Freelook Navigation Scheme"
-msgstr "建立導航網格"
+msgstr "自由觀看ç€è¦½æ¨¡å¼"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Freelook Sensitivity"
-msgstr "自由視圖 左"
+msgstr "è‡ªç”±è§€çœ‹éˆæ•度"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Freelook Inertia"
-msgstr "自由視圖 左"
+msgstr "自由觀看慣性"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Freelook Base Speed"
-msgstr "加速自由視圖速度"
+msgstr "自由觀看基本速度"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Freelook Activation Modifier"
-msgstr "放慢自由視圖速度"
+msgstr "自由觀看啟動修飾符"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Freelook Speed Zoom Link"
-msgstr "加速自由視圖速度"
+msgstr "自由觀看速度縮放連çµ"
#: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Grid Color"
-msgstr "鏿“‡é¡è‰²"
+msgstr "網格é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Guides Color"
-msgstr "鏿“‡é¡è‰²"
+msgstr "åƒè€ƒç·šé¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Smart Snapping Line Color"
-msgstr "智慧型å¸é™„"
+msgstr "æ™ºæ…§æ•æ‰ç·šé¡è‰²"
#: editor/editor_settings.cpp
msgid "Bone Width"
-msgstr ""
+msgstr "骨骼寬度"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Bone Color 1"
-msgstr "釿–°å‘½åé¡è‰²é …ç›®"
+msgstr "骨骼é¡è‰²1"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Bone Color 2"
-msgstr "釿–°å‘½åé¡è‰²é …ç›®"
+msgstr "骨骼é¡è‰²2"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Bone Selected Color"
-msgstr "設定所é¸ä¹‹è¨­å®šæª”:"
+msgstr "所é¸ä¹‹éª¨éª¼é¡è‰²"
#: editor/editor_settings.cpp
msgid "Bone IK Color"
-msgstr ""
+msgstr "骨骼IKé¡è‰²"
#: editor/editor_settings.cpp
msgid "Bone Outline Color"
-msgstr ""
+msgstr "骨骼輪廓é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Bone Outline Size"
-msgstr "輪廓尺寸:"
+msgstr "骨骼輪廓大å°"
#: editor/editor_settings.cpp
msgid "Viewport Border Color"
-msgstr ""
+msgstr "檢視å€é‚Šæ¡†é¡è‰²"
#: editor/editor_settings.cpp
msgid "Constrain Editor View"
-msgstr ""
+msgstr "é™åˆ¶ç·¨è¼¯å™¨è¦–圖"
#: editor/editor_settings.cpp
msgid "Simple Panning"
-msgstr ""
+msgstr "簡易平移"
#: editor/editor_settings.cpp
msgid "Scroll To Pan"
-msgstr ""
+msgstr "滾動以平移"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Pan Speed"
-msgstr "速度:"
+msgstr "平移速度"
#: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Poly Editor"
-msgstr "Polygon2D UV 編輯器"
+msgstr "多邊形編輯器"
#: editor/editor_settings.cpp
msgid "Point Grab Radius"
-msgstr ""
+msgstr "點抓å–åŠå¾‘"
#: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Show Previous Outline"
-msgstr "上一個平é¢"
+msgstr "顯示上一個大綱"
#: editor/editor_settings.cpp editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Autorename Animation Tracks"
-msgstr "釿–°å‘½åå‹•ç•«"
+msgstr "è‡ªå‹•é‡æ–°å‘½å動畫軌é“"
#: editor/editor_settings.cpp
msgid "Default Create Bezier Tracks"
-msgstr ""
+msgstr "é è¨­å»ºç«‹è²èŒ²è»Œé“"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Default Create Reset Tracks"
-msgstr "貼上關éµç•«æ ¼"
+msgstr "é è¨­å»ºç«‹é‡ç½®è»Œé“"
#: editor/editor_settings.cpp
msgid "Onion Layers Past Color"
-msgstr ""
+msgstr "洋蔥層先å‰é¡è‰²"
#: editor/editor_settings.cpp
msgid "Onion Layers Future Color"
-msgstr ""
+msgstr "洋蔥層未來é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Visual Editors"
-msgstr "群組編輯器"
+msgstr "視覺化編輯器"
#: editor/editor_settings.cpp
msgid "Minimap Opacity"
-msgstr ""
+msgstr "迷你地圖ä¸é€æ˜Žåº¦"
#: editor/editor_settings.cpp
msgid "Window Placement"
-msgstr ""
+msgstr "視窗擺放"
#: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp
#: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp
#: scene/gui/control.cpp
-#, fuzzy
msgid "Rect"
-msgstr "全矩形"
+msgstr "矩形"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Rect Custom Position"
-msgstr "設定曲線外控制點ä½ç½®"
+msgstr "矩形自定義ä½ç½®"
#: editor/editor_settings.cpp platform/android/export/export_plugin.cpp
msgid "Screen"
-msgstr ""
+msgstr "螢幕"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Auto Save"
-msgstr "自動剪è£"
+msgstr "自動ä¿å­˜"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Save Before Running"
-msgstr "執行å‰å…ˆä¿å­˜å ´æ™¯..."
+msgstr "執行å‰å„²å­˜"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Font Size"
-msgstr "å‰è¦–圖"
+msgstr "字體大å°"
#: editor/editor_settings.cpp
#: modules/gdscript/language_server/gdscript_language_server.cpp
-#, fuzzy
msgid "Remote Host"
-msgstr "é ç«¯ "
+msgstr "é ç«¯ä¸»æ©Ÿ"
#: editor/editor_settings.cpp
#: modules/gdscript/language_server/gdscript_language_server.cpp
-#, fuzzy
msgid "Remote Port"
-msgstr "移除控制點"
+msgstr "é ç«¯é˜œ"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Editor SSL Certificates"
-msgstr "編輯器設定"
+msgstr "編輯SSLèªè­‰"
#: editor/editor_settings.cpp
msgid "HTTP Proxy"
-msgstr ""
+msgstr "HTTP 代ç†ç¨‹å¼"
#: editor/editor_settings.cpp
msgid "Host"
-msgstr ""
+msgstr "主機"
#: editor/editor_settings.cpp editor/fileserver/editor_file_server.cpp
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
#: scene/resources/default_theme/default_theme.cpp
msgid "Port"
-msgstr ""
+msgstr "連接埠"
#. TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects.
#: editor/editor_settings.cpp
@@ -6172,55 +5921,50 @@ msgstr "專案管ç†å“¡"
#. TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects.
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Sorting Order"
-msgstr "釿–°å‘½å資料夾:"
+msgstr "æŽ’åºæ–¹å¼"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Symbol Color"
-msgstr ""
+msgstr "符號é¡è‰²"
#: editor/editor_settings.cpp
msgid "Keyword Color"
-msgstr ""
+msgstr "é—œéµå­—é¡è‰²"
#: editor/editor_settings.cpp
msgid "Control Flow Keyword Color"
-msgstr ""
+msgstr "控制æµé—œéµå­—é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Base Type Color"
-msgstr "更改基礎型別"
+msgstr "基礎型別é¡è‰²"
#: editor/editor_settings.cpp
msgid "Engine Type Color"
-msgstr ""
+msgstr "引擎類別é¡è‰²"
#: editor/editor_settings.cpp
msgid "User Type Color"
-msgstr ""
+msgstr "使用者類別é¡è‰²"
#: editor/editor_settings.cpp
msgid "Comment Color"
-msgstr ""
+msgstr "註解é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "String Color"
-msgstr "儲存檔案:"
+msgstr "字串é¡è‰²"
#: editor/editor_settings.cpp platform/javascript/export/export.cpp
#: platform/uwp/export/export.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Background Color"
-msgstr "無效的背景é¡è‰²ã€‚"
+msgstr "背景é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Completion Background Color"
-msgstr "無效的背景é¡è‰²ã€‚"
+msgstr "自動補全背景é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -6229,128 +5973,111 @@ msgstr "匯入所é¸"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Existing Color"
-msgstr ""
+msgstr "完æˆå­˜åœ¨ä¸­é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Scroll Color"
-msgstr ""
+msgstr "å®Œæˆæ»¾å‹•é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Completion Font Color"
-msgstr ""
+msgstr "完æˆå­—åž‹é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Text Color"
-msgstr "下一個地æ¿"
+msgstr "文字é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Line Number Color"
-msgstr "行號:"
+msgstr "行號é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Safe Line Number Color"
-msgstr "行號:"
+msgstr "安全行號é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Caret Color"
-msgstr ""
+msgstr "跳脫字元é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Caret Background Color"
-msgstr "無效的背景é¡è‰²ã€‚"
+msgstr "跳脫字元背景é¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Text Selected Color"
-msgstr "刪除所é¸"
+msgstr "æ‰€é¸æ–‡å­—é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Selection Color"
-msgstr "僅æœå°‹æ‰€é¸å€åŸŸ"
+msgstr "所é¸é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Brace Mismatch Color"
-msgstr ""
+msgstr "大括號ä¸å°ç¨±é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Current Line Color"
-msgstr "ç›®å‰å ´æ™¯"
+msgstr "ç›®å‰è¡Œé¡è‰²"
#: editor/editor_settings.cpp
msgid "Line Length Guideline Color"
-msgstr ""
+msgstr "線長導引é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Word Highlighted Color"
-msgstr "高亮顯示語法"
+msgstr "單字醒目顯示é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Number Color"
-msgstr ""
+msgstr "數字é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Function Color"
-msgstr "函å¼"
+msgstr "函å¼é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Member Variable Color"
-msgstr "釿–°å‘½å變數"
+msgstr "æˆå“¡è®Šæ•¸é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Mark Color"
-msgstr "鏿“‡é¡è‰²"
+msgstr "標記é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Bookmark Color"
-msgstr "書籤"
+msgstr "書籤é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Breakpoint Color"
-msgstr "中斷點"
+msgstr "中斷點é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Executing Line Color"
-msgstr ""
+msgstr "執行列é¡è‰²"
#: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp
msgid "Code Folding Color"
-msgstr ""
+msgstr "程å¼ç¢¼æ‘ºç–Šé¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Search Result Color"
-msgstr "æœå°‹çµæžœ"
+msgstr "æœå°‹çµæžœé¡è‰²"
#: editor/editor_settings.cpp
-#, fuzzy
msgid "Search Result Border Color"
-msgstr "æœå°‹çµæžœ"
+msgstr "æœå°‹çµæžœé‚Šç•Œé¡è‰²"
#: editor/editor_spin_slider.cpp
msgid "Hold %s to round to integers. Hold Shift for more precise changes."
msgstr "æŒ‰ä½ %s 以喿•´æ•¸ã€‚æŒ‰ä½ Shift 以進行更精確的更動。"
#: editor/editor_spin_slider.cpp scene/gui/button.cpp
-#, fuzzy
msgid "Flat"
-msgstr "å¹³é¢0"
+msgstr "å¹³é¢"
#: editor/editor_spin_slider.cpp
-#, fuzzy
msgid "Hide Slider"
-msgstr "碰撞模å¼"
+msgstr "éš±è—æ‹–曳æ¢"
#: editor/editor_sub_scene.cpp
msgid "Select Node(s) to Import"
@@ -6370,9 +6097,8 @@ msgstr "自節點中匯入:"
#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
#: editor/editor_vcs_interface.cpp
-#, fuzzy
msgid "%s Error"
-msgstr "錯誤"
+msgstr "%s 錯誤"
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
@@ -6636,13 +6362,13 @@ msgstr ""
#: editor/fileserver/editor_file_server.cpp
msgid "File Server"
-msgstr ""
+msgstr "檔案伺æœå™¨"
#: editor/fileserver/editor_file_server.cpp
#: editor/plugins/version_control_editor_plugin.cpp
#: platform/uwp/export/export.cpp platform/windows/export/export.cpp
msgid "Password"
-msgstr ""
+msgstr "密碼"
#: editor/filesystem_dock.cpp
msgid "Favorites"
@@ -6700,6 +6426,9 @@ msgid ""
"After renaming to an unknown extension, the file won't be shown in the "
"editor anymore."
msgstr ""
+"編輯器無法辨識該檔案副檔å。\n"
+"如果你ä»è¦é‡æ–°å‘½å,請使用系統的檔案管ç†å“¡ã€‚\n"
+"釿–°å‘½å為未知副檔åå¾Œï¼Œè©²æª”æ¡ˆä¸æœƒåœ¨ç·¨è¼¯å™¨ä¸­é¡¯ç¤ºã€‚"
#: editor/filesystem_dock.cpp
msgid ""
@@ -6919,14 +6648,12 @@ msgid "Replace..."
msgstr "å–代..."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Replace in Files"
-msgstr "å–代全部"
+msgstr "在檔案中å–代"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace All (NO UNDO)"
-msgstr "å–代全部"
+msgstr "å–代全部(ä¸å¯å¾©åŽŸï¼‰"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -6999,21 +6726,20 @@ msgstr "管ç†ç¾¤çµ„"
#: editor/import/editor_import_collada.cpp
msgid "Collada"
-msgstr ""
+msgstr "Collada"
#: editor/import/editor_import_collada.cpp
msgid "Use Ambient"
-msgstr ""
+msgstr "使用環境通é“"
#: editor/import/resource_importer_bitmask.cpp
-#, fuzzy
msgid "Create From"
-msgstr "建立資料夾"
+msgstr "從æŸè™•建立"
#: editor/import/resource_importer_bitmask.cpp
#: servers/audio/effects/audio_effect_compressor.cpp
msgid "Threshold"
-msgstr ""
+msgstr "臨界值"
#: editor/import/resource_importer_csv_translation.cpp
#: editor/import/resource_importer_layered_texture.cpp
@@ -7026,16 +6752,15 @@ msgstr "元件"
#: editor/import/resource_importer_csv_translation.cpp
msgid "Delimiter"
-msgstr ""
+msgstr "分隔符號"
#: editor/import/resource_importer_layered_texture.cpp
-#, fuzzy
msgid "ColorCorrect"
-msgstr "é¡è‰²å‡½å¼ã€‚"
+msgstr "é¡è‰²æ ¡æ­£"
#: editor/import/resource_importer_layered_texture.cpp
msgid "No BPTC If RGB"
-msgstr ""
+msgstr "å‡è¨­æ˜¯RGBä¸ä½¿ç”¨BPTC"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/2d/cpu_particles_2d.cpp
@@ -7043,36 +6768,34 @@ msgstr ""
#: scene/resources/material.cpp scene/resources/particles_material.cpp
#: scene/resources/texture.cpp scene/resources/visual_shader.cpp
msgid "Flags"
-msgstr ""
+msgstr "旗標"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/animation/tween.cpp
#: scene/resources/texture.cpp
msgid "Repeat"
-msgstr ""
+msgstr "é‡è¦†"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp scene/2d/light_2d.cpp
#: scene/gui/control.cpp
-#, fuzzy
msgid "Filter"
-msgstr "篩é¸ï¼š"
+msgstr "篩é¸"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Mipmaps"
-msgstr "訊號"
+msgstr "Mipmap"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
msgid "Anisotropic"
-msgstr ""
+msgstr "ç•°å‘æ€§"
#: editor/import/resource_importer_layered_texture.cpp
#: editor/import/resource_importer_texture.cpp
msgid "sRGB"
-msgstr ""
+msgstr "sRGB"
#: editor/import/resource_importer_layered_texture.cpp
#, fuzzy
@@ -7083,17 +6806,15 @@ msgstr "自動剪è£"
#: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp
#: scene/gui/nine_patch_rect.cpp scene/gui/scroll_container.cpp
#: scene/resources/style_box.cpp
-#, fuzzy
msgid "Horizontal"
-msgstr "水平:"
+msgstr "æ°´å¹³"
#: editor/import/resource_importer_layered_texture.cpp
#: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp
#: scene/gui/nine_patch_rect.cpp scene/gui/scroll_container.cpp
#: scene/resources/style_box.cpp
-#, fuzzy
msgid "Vertical"
-msgstr "垂直:"
+msgstr "垂直"
#: editor/import/resource_importer_obj.cpp
#, fuzzy
@@ -7101,14 +6822,12 @@ msgid "Generate Tangents"
msgstr "產生點"
#: editor/import/resource_importer_obj.cpp
-#, fuzzy
msgid "Scale Mesh"
-msgstr "縮放模å¼"
+msgstr "縮放網格"
#: editor/import/resource_importer_obj.cpp
-#, fuzzy
msgid "Offset Mesh"
-msgstr "å移:"
+msgstr "Mesh åç§»"
#: editor/import/resource_importer_obj.cpp
#: editor/import/resource_importer_scene.cpp
@@ -7117,9 +6836,8 @@ msgid "Octahedral Compression"
msgstr "設定表示å¼"
#: editor/import/resource_importer_obj.cpp
-#, fuzzy
msgid "Optimize Mesh Flags"
-msgstr "大å°ï¼š "
+msgstr "優化 Mesh 標誌"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Single Scene"
@@ -7163,51 +6881,42 @@ msgstr "匯入為多個場景 + ç´ æ"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
#: scene/3d/physics_joint.cpp
-#, fuzzy
msgid "Nodes"
msgstr "節點"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Root Type"
-msgstr "æˆå“¡åž‹åˆ¥"
+msgstr "根型別"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Root Name"
-msgstr "é ç«¯ "
+msgstr "æ ¹å稱"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Root Scale"
-msgstr "縮放"
+msgstr "根縮放"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Custom Script"
-msgstr "剪下節點"
+msgstr "自訂腳本"
#: editor/import/resource_importer_scene.cpp scene/resources/texture.cpp
-#, fuzzy
msgid "Storage"
-msgstr "儲存檔案:"
+msgstr "儲存"
#: editor/import/resource_importer_scene.cpp
msgid "Use Legacy Names"
-msgstr ""
+msgstr "使用既有å稱"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
-#, fuzzy
msgid "Materials"
-msgstr "æè³ªè®Šæ›´ï¼š"
+msgstr "æè³ª"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Keep On Reimport"
-msgstr "釿–°åŒ¯å…¥"
+msgstr "ä¿æŒæˆ–釿–°åŒ¯å…¥"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
-#, fuzzy
msgid "Meshes"
msgstr "網格"
@@ -7217,9 +6926,8 @@ msgid "Ensure Tangents"
msgstr "修改曲線切線"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Light Baking"
-msgstr "烘焙光照圖"
+msgstr "光照烘焙"
#: editor/import/resource_importer_scene.cpp
#, fuzzy
@@ -7228,7 +6936,7 @@ msgstr "烘焙光照圖"
#: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp
msgid "Skins"
-msgstr ""
+msgstr "Skin"
#: editor/import/resource_importer_scene.cpp
#, fuzzy
@@ -7236,16 +6944,14 @@ msgid "Use Named Skins"
msgstr "使用縮放å¸é™„"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "External Files"
-msgstr "開啟檔案"
+msgstr "é¡å¤–檔案"
#: editor/import/resource_importer_scene.cpp
msgid "Store In Subdir"
-msgstr ""
+msgstr "儲存於å­ç›®éŒ„"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Filter Script"
msgstr "篩é¸è…³æœ¬"
@@ -7255,9 +6961,8 @@ msgid "Keep Custom Tracks"
msgstr "變æ›"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Optimizer"
-msgstr "最佳化"
+msgstr "最佳化器"
#: editor/import/resource_importer_scene.cpp
#: editor/plugins/item_list_editor_plugin.cpp main/main.cpp
@@ -7271,41 +6976,34 @@ msgstr "最佳化"
#: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp
#: scene/gui/rich_text_label.cpp scene/resources/curve.cpp
#: scene/resources/environment.cpp scene/resources/material.cpp
-#, fuzzy
msgid "Enabled"
-msgstr "啟用"
+msgstr "已啟用"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Max Linear Error"
-msgstr "最大線性誤差:"
+msgstr "最大線性誤差"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Max Angular Error"
-msgstr "最大角度誤差:"
+msgstr "最大角度誤差"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Max Angle"
-msgstr "數值"
+msgstr "最大角度"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Remove Unused Tracks"
-msgstr "刪除動畫軌"
+msgstr "移除未使用的動畫軌"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Clips"
msgstr "動畫片段"
#: editor/import/resource_importer_scene.cpp scene/2d/cpu_particles_2d.cpp
#: scene/2d/particles_2d.cpp scene/3d/area.cpp scene/3d/cpu_particles.cpp
#: scene/3d/particles.cpp scene/resources/environment.cpp
-#, fuzzy
msgid "Amount"
-msgstr "數é‡ï¼š"
+msgstr "數é‡"
#: editor/import/resource_importer_scene.cpp
#: editor/plugins/mesh_library_editor_plugin.cpp
@@ -7321,9 +7019,8 @@ msgid "Generating Lightmaps"
msgstr "正在產生光照圖"
#: editor/import/resource_importer_scene.cpp
-#, fuzzy
msgid "Generating for Mesh:"
-msgstr "正在產生網格: "
+msgstr "ç”Ÿæˆ Mesh 中:"
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
@@ -7354,159 +7051,144 @@ msgid ""
"%s: Texture detected as used as a normal map in 3D. Enabling red-green "
"texture compression to reduce memory usage (blue channel is discarded)."
msgstr ""
+"%s: 嵿¸¬åˆ°ä½¿ç”¨åœ¨3D上的法線貼圖。啟用紅-ç¶ æè³ªå£“縮來減少記憶體用é‡(è—色通é“å·²"
+"è¢«æ¨æ£„)。"
#: editor/import/resource_importer_texture.cpp
msgid ""
"%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap "
"generation and VRAM texture compression."
-msgstr ""
+msgstr "%s: 嵿¸¬åˆ°ä½¿ç”¨åœ¨3D上的æè³ªã€‚啟用濾é¡ã€é‡è¦†ã€Mipmap產生和VRAMæè³ªå£“縮。"
#: editor/import/resource_importer_texture.cpp
msgid "2D, Detect 3D"
-msgstr ""
+msgstr "2Dï¼Œåµæ¸¬3D"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "2D Pixel"
-msgstr "實體åƒç´ "
+msgstr "2Dåƒç´ "
#: editor/import/resource_importer_texture.cpp scene/resources/texture.cpp
msgid "Lossy Quality"
-msgstr ""
+msgstr "低å“質"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "HDR Mode"
-msgstr "鏿“‡æ¨¡å¼"
+msgstr "HDR模å¼"
#: editor/import/resource_importer_texture.cpp
msgid "BPTC LDR"
-msgstr ""
+msgstr "BPTC LDR"
#: editor/import/resource_importer_texture.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp
#: scene/2d/mesh_instance_2d.cpp scene/2d/multimesh_instance_2d.cpp
#: scene/2d/particles_2d.cpp scene/2d/sprite.cpp scene/resources/style_box.cpp
msgid "Normal Map"
-msgstr ""
+msgstr "法線貼圖"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Process"
-msgstr "後處ç†"
+msgstr "處ç†"
#: editor/import/resource_importer_texture.cpp
msgid "Fix Alpha Border"
-msgstr ""
+msgstr "修正Alpha邊界"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Premult Alpha"
-msgstr "編輯多邊形"
+msgstr "é ä¹˜ Alpha"
#: editor/import/resource_importer_texture.cpp
msgid "Hdr As Srgb"
-msgstr ""
+msgstr "Hdr作為SRGB"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Invert Color"
-msgstr "頂點"
+msgstr "翻轉é¡è‰²"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Normal Map Invert Y"
-msgstr "隨機縮放:"
+msgstr "法線貼圖å轉 Y"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "Size Limit"
-msgstr "大å°ï¼š "
+msgstr "大å°é™åˆ¶"
#: editor/import/resource_importer_texture.cpp
msgid "Detect 3D"
-msgstr ""
+msgstr "嵿¸¬3D"
#: editor/import/resource_importer_texture.cpp
-#, fuzzy
msgid "SVG"
-msgstr "HSV"
+msgstr "SVG"
#: editor/import/resource_importer_texture.cpp
msgid ""
"Warning, no suitable PC VRAM compression enabled in Project Settings. This "
"texture will not display correctly on PC."
msgstr ""
+"注æ„,專案設定內啟用了éžé©åˆçš„PC VRAM壓縮。此æè³ªå°‡ç„¡æ³•在PC上正確顯示。"
#: editor/import/resource_importer_texture_atlas.cpp
-#, fuzzy
msgid "Atlas File"
-msgstr "輪廓尺寸:"
+msgstr "åˆé›†æª”案"
#: editor/import/resource_importer_texture_atlas.cpp
-#, fuzzy
msgid "Import Mode"
-msgstr "匯出模å¼ï¼š"
+msgstr "匯入模å¼"
#: editor/import/resource_importer_texture_atlas.cpp
-#, fuzzy
msgid "Crop To Region"
-msgstr "鏿“‡åœ–塊å€åŸŸ"
+msgstr "è£å‰ªè‡³å€åŸŸ"
#: editor/import/resource_importer_texture_atlas.cpp
msgid "Trim Alpha Border From Region"
-msgstr ""
+msgstr "從å€åŸŸç°¡åŒ–Alpha邊界"
#: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp
-#, fuzzy
msgid "Force"
-msgstr "來æºç¶²æ ¼ï¼š"
+msgstr "強制"
#: editor/import/resource_importer_wav.cpp
msgid "8 Bit"
-msgstr ""
+msgstr "8ä½å…ƒçµ„"
#: editor/import/resource_importer_wav.cpp main/main.cpp
#: modules/mono/editor/csharp_project.cpp modules/mono/mono_gd/gd_mono.cpp
msgid "Mono"
-msgstr ""
+msgstr "Mono"
#: editor/import/resource_importer_wav.cpp
-#, fuzzy
msgid "Max Rate"
-msgstr "Mix 節點"
+msgstr "最大頻率"
#: editor/import/resource_importer_wav.cpp
-#, fuzzy
msgid "Max Rate Hz"
-msgstr "Mix 節點"
+msgstr "最大頻率Hz"
#: editor/import/resource_importer_wav.cpp
msgid "Trim"
-msgstr ""
+msgstr "簡化"
#: editor/import/resource_importer_wav.cpp
-#, fuzzy
msgid "Normalize"
-msgstr "æ ¼å¼"
+msgstr "æ­£è¦åŒ–"
#: editor/import/resource_importer_wav.cpp
#: scene/resources/audio_stream_sample.cpp
-#, fuzzy
msgid "Loop Mode"
-msgstr "移動模å¼"
+msgstr "é‡è¦†æ¨¡å¼"
#: editor/import/resource_importer_wav.cpp
#: scene/resources/audio_stream_sample.cpp
-#, fuzzy
msgid "Loop Begin"
-msgstr "移動模å¼"
+msgstr "é–‹å§‹é‡è¦†"
#: editor/import/resource_importer_wav.cpp
#: scene/resources/audio_stream_sample.cpp
-#, fuzzy
msgid "Loop End"
-msgstr "移動模å¼"
+msgstr "çµæŸé‡è¦†"
#: editor/import_defaults_editor.cpp
msgid "Select Importer"
@@ -7557,7 +7239,7 @@ msgstr "匯入為:"
#: editor/import_dock.cpp
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "ä¿å­˜å ´æ™¯ã€é‡æ–°åŒ¯å…¥ã€ä¸¦é‡æ–°å•Ÿå‹•"
+msgstr "儲存場景ã€é‡æ–°åŒ¯å…¥ã€ä¸¦é‡æ–°å•Ÿå‹•"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -7572,34 +7254,31 @@ msgstr "警告:有素æä½¿ç”¨è©²è³‡æºï¼Œå°‡ç„¡æ³•正確加載。"
msgid ""
"Select a resource file in the filesystem or in the inspector to adjust "
"import settings."
-msgstr ""
+msgstr "å¾žæª”æ¡ˆç³»çµ±ä¸­é¸æ“‡è³‡æºæª”ï¼Œæˆ–æ˜¯åœ¨é¢æ¿ä¸Šèª¿æ•´åŒ¯å…¥è¨­å®šã€‚"
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
msgstr "加載資æºå¤±æ•—。"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Property Name Style"
-msgstr "專案å稱:"
+msgstr "屬性å稱樣å¼"
#: editor/inspector_dock.cpp scene/gui/color_picker.cpp
msgid "Raw"
msgstr "原始"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Capitalized"
msgstr "首字æ¯å¤§å¯«"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Localized"
-msgstr "地å€"
+msgstr "已本地化"
#: editor/inspector_dock.cpp
msgid "Localization not available for current language."
-msgstr ""
+msgstr "ç›®å‰çš„èªžè¨€ä¸æ”¯æ´æœ¬åœ°åŒ–。"
#: editor/inspector_dock.cpp
msgid "Copy Properties"
@@ -7623,7 +7302,7 @@ msgstr "從ç£ç¢Ÿä¸­è¼‰å…¥ç¾æœ‰çš„資æºä¸¦ç·¨è¼¯ã€‚"
#: editor/inspector_dock.cpp
msgid "Save the currently edited resource."
-msgstr "ä¿å­˜ç›®å‰ç·¨è¼¯çš„資æºã€‚"
+msgstr "儲存目å‰ç·¨è¼¯çš„資æºã€‚"
#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -8040,11 +7719,20 @@ msgid "New Anim"
msgstr "新增動畫"
#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr "建立新動畫"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
msgstr "更改動畫å稱:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "釿–°å‘½åå‹•ç•«"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
msgstr "是å¦åˆªé™¤å‹•畫?"
@@ -8062,11 +7750,6 @@ msgid "Animation name already exists!"
msgstr "å‹•ç•«å稱已存在ï¼"
#: editor/plugins/animation_player_editor_plugin.cpp
-#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Rename Animation"
-msgstr "釿–°å‘½åå‹•ç•«"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
msgstr "é‡è¤‡å‹•ç•«"
@@ -8132,9 +7815,8 @@ msgid "New"
msgstr "新增"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Paste As Reference"
-msgstr "%s 類別åƒç…§"
+msgstr "複製為åƒç…§"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Edit Transitions..."
@@ -8210,10 +7892,6 @@ msgid "Pin AnimationPlayer"
msgstr "固定 AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
-msgid "Create New Animation"
-msgstr "建立新動畫"
-
-#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
msgstr "å‹•ç•«å稱:"
@@ -8327,9 +8005,8 @@ msgid "Set the end animation. This is useful for sub-transitions."
msgstr "設定çµå°¾å‹•畫。é©ç”¨æ–¼å­è½‰å ´ã€‚"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition:"
-msgstr "轉場: "
+msgstr "轉場效果:"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Play Mode:"
@@ -8466,7 +8143,7 @@ msgstr "篩é¸..."
#: editor/plugins/asset_library_editor_plugin.cpp scene/main/http_request.cpp
msgid "Use Threads"
-msgstr ""
+msgstr "使用執行緒"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Contents:"
@@ -8514,7 +8191,7 @@ msgstr "è¦æ±‚失敗,回傳代碼:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Cannot save response to:"
-msgstr "無法ä¿å­˜å›žè¦†è‡³ï¼š"
+msgstr "無法儲存回覆至:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Write error."
@@ -8593,9 +8270,8 @@ msgid "Download Error"
msgstr "下載錯誤"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Available URLs"
-msgstr "å¯ç”¨è¨­å®šæª”:"
+msgstr "å¯ç”¨ URL"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download for this asset is already in progress!"
@@ -8630,28 +8306,24 @@ msgid "Loading..."
msgstr "正在載入..."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgctxt "Pagination"
msgid "First"
-msgstr "首é "
+msgstr "第一個"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgctxt "Pagination"
msgid "Previous"
-msgstr "上一é "
+msgstr "上一個"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgctxt "Pagination"
msgid "Next"
-msgstr "下一é "
+msgstr "下一個"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgctxt "Pagination"
msgid "Last"
-msgstr "最後"
+msgstr "最後一個"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "All"
@@ -8699,7 +8371,7 @@ msgstr "測試"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Failed to get repository configuration."
-msgstr ""
+msgstr "無法å–得倉儲設定。"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -8714,8 +8386,8 @@ msgid ""
"Can't determine a save path for lightmap images.\n"
"Save your scene and try again."
msgstr ""
-"無法判斷光照圖的ä¿å­˜è·¯å¾‘。\n"
-"è«‹ä¿å­˜å ´æ™¯ä¸¦é‡è©¦ã€‚"
+"無法判斷光照圖的儲存路徑。\n"
+"請儲存場景並é‡è©¦ã€‚"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -8750,7 +8422,7 @@ msgstr "烘焙光照圖"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "LightMap Bake"
-msgstr ""
+msgstr "光照貼圖烘培"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Select lightmap bake file:"
@@ -9059,9 +8731,8 @@ msgid "Alt+Drag: Move selected node."
msgstr "Alt+拖移:移動所é¸çš„節點。"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Alt+Drag: Scale selected node."
-msgstr "Alt+拖移:移動所é¸çš„節點。"
+msgstr "Alt+拖曳:縮放所é¸çš„節點。"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "V: Set selected node's pivot position."
@@ -9192,9 +8863,8 @@ msgstr "在其ä½ç½®ä¸ŠéŽ–å®šæ‰€é¸ç‰©ä»¶ï¼ˆç„¡æ³•移動)。"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected Node(s)"
-msgstr "鎖定所é¸"
+msgstr "鎖定所é¸çš„節點"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -9203,9 +8873,8 @@ msgstr "解鎖所é¸ç‰©ä»¶ï¼ˆå¯ç§»å‹•)。"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected Node(s)"
-msgstr "å–æ¶ˆéŽ–å®šæ‰€é¸"
+msgstr "å–æ¶ˆéŽ–å®šæ‰€é¸çš„節點"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -9214,9 +8883,8 @@ msgstr "確ä¿ç‰©ä»¶çš„å­ç´šé …ç›®ç„¡æ³•è¢«é¸æ“‡ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected Node(s)"
-msgstr "為所é¸çš„項目建立群組"
+msgstr "為所é¸çš„節點建立群組"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -9225,9 +8893,8 @@ msgstr "æ¢å¾©è®“物件的å­ç´šé …ç›®å¯é¸æ“‡ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected Node(s)"
-msgstr "移除所é¸é …目的群組"
+msgstr "å–æ¶ˆæ‰€é¸ç¯€é»žçš„群組"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -9252,23 +8919,20 @@ msgid "View"
msgstr "檢視"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Show"
-msgstr "顯示網格"
+msgstr "顯示"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Show When Snapping"
-msgstr "智慧型å¸é™„"
+msgstr "ç•¶å¸é™„時顯示"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Hide"
-msgstr ""
+msgstr "éš±è—"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Grid"
-msgstr "åˆ‡æ›æ¨¡å¼"
+msgstr "切æ›ç¶²æ ¼"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -9546,7 +9210,7 @@ msgstr "å¹³é¢0"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Flat 1"
-msgstr ""
+msgstr "å¹³é¢ 1"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease In"
@@ -9625,9 +9289,8 @@ msgid "Swap Gradient Fill Points"
msgstr ""
#: editor/plugins/gradient_texture_2d_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Grid Snap"
-msgstr "åˆ‡æ›æ¨¡å¼"
+msgstr "切æ›ç¶²æ ¼å¸é™„"
#: editor/plugins/item_list_editor_plugin.cpp editor/project_export.cpp
#: scene/3d/label_3d.cpp scene/gui/button.cpp scene/gui/dialogs.cpp
@@ -9646,13 +9309,12 @@ msgstr "圖示"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "ID"
-msgstr ""
+msgstr "ID"
#: editor/plugins/item_list_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Separator"
-msgstr "分隔:"
+msgstr "分隔線"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item %d"
@@ -9881,9 +9543,8 @@ msgstr ""
"%s"
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid "MeshLibrary"
-msgstr "網格庫"
+msgstr "網格資æºåº«"
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Add Item"
@@ -9906,14 +9567,12 @@ msgid "Update from Scene"
msgstr "自場景更新"
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid "Apply without Transforms"
-msgstr "套用MeshInstance變æ›"
+msgstr "ä¸åŒ…å«è®Šæ›çš„套用"
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid "Apply with Transforms"
-msgstr "套用MeshInstance變æ›"
+msgstr "包å«è®Šæ›çš„套用"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and no MultiMesh set in node)."
@@ -10079,9 +9738,8 @@ msgid "Volume"
msgstr "é«”ç©"
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Emission Source:"
-msgstr "發射æºï¼š "
+msgstr "發射æºï¼š"
#: editor/plugins/particles_editor_plugin.cpp
msgid "A processor material of type 'ParticlesMaterial' is required."
@@ -10512,7 +10170,7 @@ msgstr "清除最近的檔案"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close and save changes?"
-msgstr "關閉並ä¿å­˜ä¿®æ”¹å—Žï¼Ÿ"
+msgstr "關閉並儲存修改嗎?"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error writing TextFile:"
@@ -10585,7 +10243,7 @@ msgstr "ä¿å­˜éŒ¯èª¤"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme As..."
-msgstr "ä¿å­˜ä¸»é¡Œç‚º..."
+msgstr "儲存主題為..."
#: editor/plugins/script_editor_plugin.cpp
msgid "%s Class Reference"
@@ -10652,7 +10310,7 @@ msgstr "釿–°æ‰“開關閉的腳本"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
-msgstr "全部ä¿å­˜"
+msgstr "全部儲存"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
@@ -10680,7 +10338,7 @@ msgstr "釿–°è¼‰å…¥ä¸»é¡Œ"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme"
-msgstr "ä¿å­˜ä¸»é¡Œ"
+msgstr "儲存主題"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
@@ -10766,50 +10424,43 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "External"
-msgstr ""
+msgstr "é¡å¤–çš„"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Use External Editor"
-msgstr "使用外部編輯器進行除錯"
+msgstr "使用外部編輯器"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Exec Path"
-msgstr "匯出路徑"
+msgstr "執行路徑"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Script Temperature Enabled"
-msgstr "鏿“‡æ¨£æ¿æª”案"
+msgstr "啟用腳本樣å¼"
#: editor/plugins/script_editor_plugin.cpp
msgid "Highlight Current Script"
-msgstr ""
+msgstr "強調顯示目å‰çš„腳本"
#: editor/plugins/script_editor_plugin.cpp
msgid "Script Temperature History Size"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Current Script Background Color"
-msgstr "無效的背景é¡è‰²ã€‚"
+msgstr "ç›®å‰è…³æœ¬èƒŒæ™¯é¡è‰²"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Group Help Pages"
-msgstr "為所é¸çš„項目建立群組"
+msgstr "幫助é åˆ†çµ„"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Sort Scripts By"
-msgstr "建立腳本"
+msgstr "排åºè…³æœ¬æ ¹æ“š"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "List Script Names As"
-msgstr "腳本å稱:"
+msgstr "將腳本å稱列為"
#: editor/plugins/script_editor_plugin.cpp
msgid "Exec Flags"
@@ -10966,9 +10617,8 @@ msgid "Find in Files..."
msgstr "在檔案中æœå°‹..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Replace in Files..."
-msgstr "å–代..."
+msgstr "在檔案中å–代..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
@@ -11172,15 +10822,13 @@ msgstr "移動"
#. TRANSLATORS: Refers to changing the scale of a node in the 3D editor.
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Scaling:"
-msgstr "縮放: "
+msgstr "縮放:"
#. TRANSLATORS: Refers to changing the position of a node in the 3D editor.
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Translating:"
-msgstr "移動: "
+msgstr "移動:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotating %s degrees."
@@ -11228,7 +10876,7 @@ msgstr "頂點:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "FPS: %d (%s ms)"
-msgstr ""
+msgstr "FPS: %d (%s 毫秒)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View."
@@ -11328,13 +10976,12 @@ msgstr "效果é è¦½"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "(Not in GLES2)"
-msgstr ""
+msgstr "(ä¸åœ¨GLES2中)"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid ""
"Debug draw modes are only available when using the GLES3 renderer, not GLES2."
-msgstr "使用 GLES2 算繪引擎時無法使用。"
+msgstr "除錯繪製模å¼åƒ…在使用 GLES3 算繪引擎時å¯ç”¨ï¼ŒGLES2 ä¸å¯ç”¨ã€‚"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Left"
@@ -11497,16 +11144,15 @@ msgstr "開啟ï¼é—œé–‰è‡ªç”±è¦–圖"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Decrease Field of View"
-msgstr ""
+msgstr "減少å¯è¦–範åœ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Increase Field of View"
-msgstr ""
+msgstr "增加å¯è¦–範åœ"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Reset Field of View to Default"
-msgstr "é‡è¨­ç‚ºé è¨­å€¼"
+msgstr "é‡è¨­ç‚ºé è¨­è¦–野"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Object to Floor"
@@ -11720,19 +11366,16 @@ msgid "Sprite"
msgstr "拼åˆåœ–"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Simplification:"
-msgstr "簡化: "
+msgstr "簡化:"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Shrink (Pixels):"
-msgstr "收縮(åƒç´ ï¼‰ï¼š "
+msgstr "收縮(åƒç´ ï¼‰ï¼š"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Grow (Pixels):"
-msgstr "擴展(åƒç´ ï¼‰ï¼š "
+msgstr "擴展(åƒç´ ï¼‰ï¼š"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Update Preview"
@@ -12278,9 +11921,8 @@ msgid "Available Node-based types:"
msgstr "å¯ç”¨è¨­å®šæª”:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Type name is empty!"
-msgstr "檔案å稱為空。"
+msgstr "型別å稱為空ï¼"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -12977,9 +12619,8 @@ msgstr "å¸é™„é¸é …"
#: scene/gui/graph_node.cpp scene/gui/rich_text_effect.cpp
#: scene/main/canvas_layer.cpp scene/resources/material.cpp
#: scene/resources/particles_material.cpp scene/resources/style_box.cpp
-#, fuzzy
msgid "Offset"
-msgstr "å移:"
+msgstr "åç§»"
#: editor/plugins/tile_set_editor_plugin.cpp editor/rename_dialog.cpp
#: scene/gui/range.cpp scene/resources/animation.cpp
@@ -12990,9 +12631,8 @@ msgstr "步長"
#: editor/plugins/tile_set_editor_plugin.cpp
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Separation"
-msgstr "分隔:"
+msgstr "é–“è·"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -13011,16 +12651,14 @@ msgid "Texture"
msgstr "純文字"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Tex Offset"
-msgstr "網格åç§»é‡ï¼š"
+msgstr "ç´‹ç†åç§»"
#: editor/plugins/tile_set_editor_plugin.cpp modules/csg/csg_shape.cpp
#: scene/2d/canvas_item.cpp scene/2d/particles_2d.cpp
#: scene/3d/mesh_instance.cpp scene/resources/primitive_meshes.cpp
-#, fuzzy
msgid "Material"
-msgstr "æè³ªè®Šæ›´ï¼š"
+msgstr "æè³ª"
#: editor/plugins/tile_set_editor_plugin.cpp scene/2d/canvas_item.cpp
#: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/style_box.cpp
@@ -13039,9 +12677,8 @@ msgid "Autotile Bitmask Mode"
msgstr "優先模å¼"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Subtile Size"
-msgstr "輪廓尺寸:"
+msgstr "å­åœ–塊大å°"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -13059,9 +12696,8 @@ msgid "Navigation Offset"
msgstr "導航模å¼"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Shape Offset"
-msgstr "å移:"
+msgstr "形狀åç§»"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -13110,7 +12746,7 @@ msgstr "ç„¡å¯ç”¨çš„版本控制 (VCS) 擴充功能。"
#: editor/plugins/version_control_editor_plugin.cpp
msgid ""
"Remote settings are empty. VCS features that use the network may not work."
-msgstr ""
+msgstr "é ç«¯è¨­å®šæ˜¯ç©ºçš„。使用網路的VCS功能æç„¡æ³•é‹ä½œã€‚"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -13122,32 +12758,28 @@ msgid "Commit"
msgstr "æäº¤"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Staged Changes"
-msgstr "著色器變更:"
+msgstr "暫存變更"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Unstaged Changes"
-msgstr "著色器變更:"
+msgstr "未暫存變更"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Commit:"
-msgstr "æäº¤"
+msgstr "æäº¤ï¼š"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Date:"
-msgstr ""
+msgstr "日期:"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Subtitle:"
-msgstr "å­æ¨¹"
+msgstr "副標題:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Do you want to remove the %s branch?"
-msgstr ""
+msgstr "你確定è¦ç§»é™¤ %s 分支?"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -13174,34 +12806,31 @@ msgstr "移除控制點"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Select SSH public key path"
-msgstr ""
+msgstr "鏿“‡SSH公鑰的路徑"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Select SSH private key path"
-msgstr ""
+msgstr "鏿“‡SSHç§é‘°çš„路徑"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "SSH Passphrase"
-msgstr ""
+msgstr "SSH 通關片段"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "嵿¸¬æ–°æ”¹å‹•"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Discard all changes"
-msgstr "關閉並ä¿å­˜ä¿®æ”¹å—Žï¼Ÿ"
+msgstr "æ¨æ£„所有變更"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Stage all changes"
-msgstr "正在儲存變更..."
+msgstr "é å­˜æ‰€æœ‰è®Šæ›´"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Unstage all changes"
-msgstr "æè³ªè®Šæ›´ï¼š"
+msgstr "撤銷暫存所有變更"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -13219,12 +12848,11 @@ msgstr "æäº¤"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit list size"
-msgstr ""
+msgstr "簽入列表大å°"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Branches"
-msgstr "ç¬¦åˆæ¢ä»¶ï¼š"
+msgstr "分支"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -13238,7 +12866,7 @@ msgstr "刪除動畫軌"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Branch Name"
-msgstr ""
+msgstr "分支å稱"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -13256,31 +12884,28 @@ msgid "Remove Remote"
msgstr "移除項目"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Remote Name"
-msgstr "é ç«¯ "
+msgstr "é ç«¯å稱"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Remote URL"
-msgstr "é ç«¯ "
+msgstr "é ç«¯ç¶²å€"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Fetch"
-msgstr ""
+msgstr "æå–"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Pull"
-msgstr ""
+msgstr "拉é€"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Push"
-msgstr ""
+msgstr "推é€"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Force Push"
-msgstr "來æºç¶²æ ¼ï¼š"
+msgstr "強制推é€"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -13300,12 +12925,11 @@ msgstr "æ ¼å¼æ›´æ”¹"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Unmerged"
-msgstr ""
+msgstr "未åˆä½µ"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "View:"
-msgstr "檢視"
+msgstr "檢視:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -14294,28 +13918,24 @@ msgid "More Info..."
msgstr "移動至..."
#: editor/project_export.cpp
-#, fuzzy
msgid "Export PCK/Zip..."
-msgstr "匯出 PCK/ZIP"
+msgstr "匯出 PCK/ZIP..."
#: editor/project_export.cpp
-#, fuzzy
msgid "Export Project..."
-msgstr "匯出專案"
+msgstr "匯出專案..."
#: editor/project_export.cpp
msgid "Export All"
msgstr "全部匯出"
#: editor/project_export.cpp
-#, fuzzy
msgid "Choose an export mode:"
-msgstr "è«‹é¸æ“‡ä¸€å€‹ç©ºè³‡æ–™å¤¾ã€‚"
+msgstr "鏿“‡åŒ¯å‡ºæ¨¡å¼ï¼š"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export All..."
-msgstr "全部匯出"
+msgstr "全部匯出..."
#: editor/project_export.cpp editor/project_manager.cpp
msgid "ZIP File"
@@ -14620,8 +14240,8 @@ msgid ""
"Language changed.\n"
"The interface will update after restarting the editor or project manager."
msgstr ""
-"語言已更改。\n"
-"界é¢å°‡æœƒåœ¨é‡æ–°å•Ÿå‹•編輯器或專案管ç†å“¡å¾Œæ›´æ–°ã€‚"
+"語言已變更。\n"
+"釿–°å•Ÿå‹•編輯器或專案管ç†å“¡å¾Œå°‡æœƒå¥—ç”¨ç•Œé¢æ›´æ–°ã€‚"
#: editor/project_manager.cpp
msgid ""
@@ -14898,7 +14518,7 @@ msgstr "ä¿å­˜è¨­å®šæ™‚發生錯誤。"
#: editor/project_settings_editor.cpp
msgid "Settings saved OK."
-msgstr "設定ä¿å­˜æˆåŠŸã€‚"
+msgstr "設定儲存æˆåŠŸã€‚"
#: editor/project_settings_editor.cpp
msgid "Moved Input Action Event"
@@ -14982,7 +14602,7 @@ msgstr "索引:"
#: editor/project_settings_editor.cpp
msgid "Localization"
-msgstr "本地化"
+msgstr "在地化"
#: editor/project_settings_editor.cpp
msgid "Translations"
@@ -15357,7 +14977,7 @@ msgid ""
"FileSystem dock context menu\n"
"or create an inherited scene using Scene > New Inherited Scene... instead."
msgstr ""
-"無法ä¿å­˜ä½œç‚ºå¯¦é«”化場景的根節點分支。\n"
+"無法儲存作為實體化場景的根節點分支。\n"
"請使用檔案系統åœä½‡åˆ—çš„å³éµé¸å–®ä¾†è¤‡è£½å®ƒï¼Œä»¥æ‹·è²ç›®å‰å ´æ™¯åŠ ä»¥ç·¨è¼¯ã€‚\n"
"或是使用場景 > 新增繼承場景...以建立一個繼承場景。"
@@ -15367,7 +14987,7 @@ msgid ""
"To create a variation of a scene, you can make an inherited scene based on "
"the instanced scene using Scene > New Inherited Scene... instead."
msgstr ""
-"無法ä¿å­˜å·²å¯¦é«”化場景的分支。\n"
+"無法儲存已實體化場景的分支。\n"
"è‹¥è¦å»ºç«‹å ´æ™¯è®Šé«”,您å¯ä½¿ç”¨å ´æ™¯ > 新增繼承場景...根據實體化的場景建立一個繼承"
"場景。"
@@ -15412,14 +15032,12 @@ msgid "Another node already uses this unique name in the scene."
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Enable Scene Unique Name"
-msgstr "節點å稱:"
+msgstr "啟用場景ç¨ç«‹å稱"
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Disable Scene Unique Name"
-msgstr "節點å稱:"
+msgstr "åœç”¨å ´æ™¯ç¨ç«‹å稱"
#: editor/scene_tree_dock.cpp
msgid "New Scene Root"
@@ -15477,7 +15095,7 @@ msgstr "更改節點的型別"
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
-msgstr "無法ä¿å­˜æ–°å ´æ™¯ã€‚å¯èƒ½æ˜¯ç”±æ–¼ç„¡æ³•滿足其ä¾è³´æ€§ï¼ˆå¯¦é«”)。"
+msgstr "無法儲存新場景。å¯èƒ½æ˜¯ç”±æ–¼ç„¡æ³•滿足其ä¾è³´æ€§ï¼ˆå¯¦é«”)。"
#: editor/scene_tree_dock.cpp
msgid "Error saving scene."
@@ -15485,7 +15103,7 @@ msgstr "ä¿å­˜å ´æ™¯æ™‚發生錯誤。"
#: editor/scene_tree_dock.cpp
msgid "Error duplicating scene to save it."
-msgstr "複製場景以進行ä¿å­˜æ™‚發生錯誤。"
+msgstr "複製場景以進行儲存時發生錯誤。"
#: editor/scene_tree_dock.cpp
msgid "Sub-Resources"
@@ -15542,7 +15160,7 @@ msgstr "åˆä½µè‡ªå ´æ™¯"
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
msgid "Save Branch as Scene"
-msgstr "ä¿å­˜åˆ†æ”¯ç‚ºå ´æ™¯"
+msgstr "儲存分支為場景"
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
msgid "Copy Node Path"
@@ -15833,9 +15451,8 @@ msgid "Attach Node Script"
msgstr "附加節點腳本"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Remote %s:"
-msgstr "é ç«¯ "
+msgstr "é ç«¯ %s:"
#: editor/script_editor_debugger.cpp
msgid "Bytes:"
@@ -16287,9 +15904,8 @@ msgid "Driver"
msgstr ""
#: main/main.cpp
-#, fuzzy
msgid "Driver Name"
-msgstr "腳本å稱:"
+msgstr "é©…å‹•å稱"
#: main/main.cpp
msgid "Fallback To GLES2"
@@ -16374,9 +15990,8 @@ msgid "Physics FPS"
msgstr "物ç†å½±æ ¼ %"
#: main/main.cpp
-#, fuzzy
msgid "Force FPS"
-msgstr "來æºç¶²æ ¼ï¼š"
+msgstr "強制 FPS"
#: main/main.cpp
msgid "Enable Pause Aware Picking"
@@ -16490,9 +16105,8 @@ msgid "Fullsize"
msgstr ""
#: main/main.cpp scene/resources/dynamic_font.cpp
-#, fuzzy
msgid "Use Filter"
-msgstr "篩é¸ï¼š"
+msgstr "使用篩é¸å™¨"
#: main/main.cpp scene/resources/style_box.cpp
#, fuzzy
@@ -16539,9 +16153,8 @@ msgid "Custom Image Hotspot"
msgstr ""
#: main/main.cpp
-#, fuzzy
msgid "Tooltip Position Offset"
-msgstr "旋轉åç§»é‡ï¼š"
+msgstr "工具æç¤ºä½ç½®åç§»"
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
#, fuzzy
@@ -16554,9 +16167,8 @@ msgid "Wait For Debugger"
msgstr "除錯工具"
#: main/main.cpp modules/mono/mono_gd/gd_mono.cpp
-#, fuzzy
msgid "Wait Timeout"
-msgstr "逾時。"
+msgstr "等待逾時"
#: main/main.cpp
msgid "Runtime"
@@ -16670,14 +16282,12 @@ msgstr "轉æ›å¤§å°å¯«"
#: scene/resources/cylinder_shape.cpp scene/resources/environment.cpp
#: scene/resources/navigation_mesh.cpp scene/resources/primitive_meshes.cpp
#: scene/resources/sphere_shape.cpp
-#, fuzzy
msgid "Radius"
-msgstr "åŠå¾‘:"
+msgstr "åŠå¾‘"
#: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp
-#, fuzzy
msgid "Radial Segments"
-msgstr "主場景引數:"
+msgstr "徑呿®µæ•¸"
#: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp
#, fuzzy
@@ -16746,9 +16356,8 @@ msgid "Path Simplify Angle"
msgstr ""
#: modules/csg/csg_shape.cpp
-#, fuzzy
msgid "Path Rotation"
-msgstr "隨機旋轉:"
+msgstr "路徑旋轉"
#: modules/csg/csg_shape.cpp
#, fuzzy
@@ -16761,14 +16370,12 @@ msgid "Path Continuous U"
msgstr "連續"
#: modules/csg/csg_shape.cpp
-#, fuzzy
msgid "Path U Distance"
-msgstr "鏿“‡è·é›¢ï¼š"
+msgstr "路徑 U è·é›¢"
#: modules/csg/csg_shape.cpp
-#, fuzzy
msgid "Path Joined"
-msgstr "隨機旋轉:"
+msgstr "路徑接åˆ"
#: modules/enet/networked_multiplayer_enet.cpp
#, fuzzy
@@ -16816,9 +16423,8 @@ msgid "Use FBX"
msgstr ""
#: modules/gdnative/gdnative.cpp
-#, fuzzy
msgid "Config File"
-msgstr "儲存檔案:"
+msgstr "組態檔案"
#: modules/gdnative/gdnative.cpp
#, fuzzy
@@ -16832,9 +16438,8 @@ msgid "Singleton"
msgstr "骨架"
#: modules/gdnative/gdnative.cpp
-#, fuzzy
msgid "Symbol Prefix"
-msgstr "å‰ç½®ï¼š"
+msgstr "符號å‰ç¶´"
#: modules/gdnative/gdnative.cpp
#, fuzzy
@@ -16892,19 +16497,16 @@ msgid "Disabled GDNative Singleton"
msgstr "ç¦ç”¨ GDNative 單例"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Libraries:"
-msgstr "函å¼åº«ï¼š "
+msgstr "函å¼åº«ï¼š"
#: modules/gdnative/nativescript/nativescript.cpp
-#, fuzzy
msgid "Class Name"
-msgstr "類別å稱:"
+msgstr "類別å稱"
#: modules/gdnative/nativescript/nativescript.cpp
-#, fuzzy
msgid "Script Class"
-msgstr "腳本å稱:"
+msgstr "腳本類別"
#: modules/gdnative/nativescript/nativescript.cpp
#, fuzzy
@@ -16983,9 +16585,8 @@ msgid "Object can't provide a length."
msgstr "物件無法æä¾›é•·åº¦ã€‚"
#: modules/gdscript/language_server/gdscript_language_server.cpp
-#, fuzzy
msgid "Language Server"
-msgstr "語言:"
+msgstr "語言伺æœå™¨"
#: modules/gdscript/language_server/gdscript_language_server.cpp
#, fuzzy
@@ -17014,9 +16615,8 @@ msgid "Buffer View"
msgstr "後視圖"
#: modules/gltf/gltf_accessor.cpp modules/gltf/gltf_buffer_view.cpp
-#, fuzzy
msgid "Byte Offset"
-msgstr "網格åç§»é‡ï¼š"
+msgstr "字節åç§»"
#: modules/gltf/gltf_accessor.cpp
#, fuzzy
@@ -17029,9 +16629,8 @@ msgid "Normalized"
msgstr "æ ¼å¼"
#: modules/gltf/gltf_accessor.cpp
-#, fuzzy
msgid "Count"
-msgstr "數é‡ï¼š"
+msgstr "數é‡"
#: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp
#, fuzzy
@@ -17057,9 +16656,8 @@ msgid "Sparse Indices Byte Offset"
msgstr ""
#: modules/gltf/gltf_accessor.cpp
-#, fuzzy
msgid "Sparse Indices Component Type"
-msgstr "正在解æžå¤šé‚Šå½¢..."
+msgstr "稀ç–頂點元件型別"
#: modules/gltf/gltf_accessor.cpp
msgid "Sparse Values Buffer View"
@@ -17089,9 +16687,8 @@ msgid "Indices"
msgstr "所有è£ç½®"
#: modules/gltf/gltf_camera.cpp
-#, fuzzy
msgid "FOV Size"
-msgstr "大å°ï¼š"
+msgstr "FOV 大å°"
#: modules/gltf/gltf_camera.cpp
msgid "Zfar"
@@ -17138,9 +16735,8 @@ msgid "Blend Weights"
msgstr "烘焙光照圖"
#: modules/gltf/gltf_mesh.cpp
-#, fuzzy
msgid "Instance Materials"
-msgstr "æè³ªè®Šæ›´ï¼š"
+msgstr "實體æè³ª"
#: modules/gltf/gltf_node.cpp scene/3d/skeleton.cpp
#, fuzzy
@@ -17228,9 +16824,8 @@ msgid "Gloss Factor"
msgstr ""
#: modules/gltf/gltf_spec_gloss.cpp
-#, fuzzy
msgid "Specular Factor"
-msgstr "ç´”é‡é‹ç®—å­ã€‚"
+msgstr "é¡é¢å射係數"
#: modules/gltf/gltf_spec_gloss.cpp
msgid "Spec Gloss Img"
@@ -17269,9 +16864,8 @@ msgid "Accessors"
msgstr ""
#: modules/gltf/gltf_state.cpp
-#, fuzzy
msgid "Scene Name"
-msgstr "場景路徑:"
+msgstr "場景å稱"
#: modules/gltf/gltf_state.cpp
#, fuzzy
@@ -17298,9 +16892,8 @@ msgid "Lights"
msgstr "燈光"
#: modules/gltf/gltf_state.cpp
-#, fuzzy
msgid "Unique Animation Names"
-msgstr "新增動畫å稱:"
+msgstr "ç¨ç«‹å‹•ç•«å稱"
#: modules/gltf/gltf_state.cpp
#, fuzzy
@@ -17313,9 +16906,8 @@ msgid "Skeleton To Node"
msgstr "鏿“‡ä¸€å€‹ç¯€é»ž"
#: modules/gltf/gltf_state.cpp
-#, fuzzy
msgid "Animations"
-msgstr "動畫:"
+msgstr "å‹•ç•«"
#: modules/gltf/gltf_texture.cpp
#, fuzzy
@@ -17560,9 +17152,8 @@ msgstr ""
#: modules/minimp3/resource_importer_mp3.cpp
#: modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
#: modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
-#, fuzzy
msgid "Loop Offset"
-msgstr "å移:"
+msgstr "循環åç§»"
#: modules/mobile_vr/mobile_vr_interface.cpp
msgid "Eye Height"
@@ -17681,9 +17272,8 @@ msgid "Seamless"
msgstr ""
#: modules/opensimplex/noise_texture.cpp
-#, fuzzy
msgid "As Normal Map"
-msgstr "隨機縮放:"
+msgstr "作為法線貼圖"
#: modules/opensimplex/noise_texture.cpp
msgid "Bump Strength"
@@ -17694,9 +17284,8 @@ msgid "Noise"
msgstr ""
#: modules/opensimplex/noise_texture.cpp
-#, fuzzy
msgid "Noise Offset"
-msgstr "網格åç§»é‡ï¼š"
+msgstr "噪è²åç§»"
#: modules/opensimplex/open_simplex_noise.cpp
msgid "Octaves"
@@ -17725,9 +17314,8 @@ msgid "Names"
msgstr "å稱"
#: modules/regex/regex.cpp
-#, fuzzy
msgid "Strings"
-msgstr "設定:"
+msgstr "字串"
#: modules/upnp/upnp.cpp
msgid "Discover Multicast If"
@@ -17788,18 +17376,16 @@ msgid ""
msgstr "回傳值需被指定為é‹ç®—記憶體節點的第一個元素ï¼è«‹ä¿®æ­£è©²ç¯€é»žã€‚"
#: modules/visual_script/visual_script.cpp
-#, fuzzy
msgid "Node returned an invalid sequence output:"
-msgstr "節點回傳了一個無效的連續輸出: "
+msgstr "節點回傳了一個無效的åºåˆ—輸出:"
#: modules/visual_script/visual_script.cpp
msgid "Found sequence bit but not the node in the stack, report bug!"
msgstr "發ç¾äº†é€£çºŒä½å…ƒ (Sequance Bit) 但並éžåœ¨å †ç–Šä¸­çš„節點,請回報該錯誤ï¼"
#: modules/visual_script/visual_script.cpp
-#, fuzzy
msgid "Stack overflow with stack depth:"
-msgstr "堆疊深度的堆疊溢出: "
+msgstr "堆疊深度的堆疊溢出:"
#: modules/visual_script/visual_script.cpp
#, fuzzy
@@ -18166,18 +17752,16 @@ msgid "for (elem) in (input):"
msgstr ""
#: modules/visual_script/visual_script_flow_control.cpp
-#, fuzzy
msgid "Input type not iterable:"
-msgstr "輸入型別éžå¯è¿­ä»£åž‹åˆ¥ï¼š "
+msgstr "輸入型別éžå¯è¿­ä»£åž‹åˆ¥ï¼š"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Iterator became invalid"
msgstr "迭代器已ä¸å¯ç”¨"
#: modules/visual_script/visual_script_flow_control.cpp
-#, fuzzy
msgid "Iterator became invalid:"
-msgstr "迭代器已ä¸å¯ç”¨ï¼š "
+msgstr "迭代器無效:"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Sequence"
@@ -18194,18 +17778,16 @@ msgid "Steps"
msgstr "步長"
#: modules/visual_script/visual_script_flow_control.cpp
-#, fuzzy
msgid "Switch"
-msgstr "仰角:"
+msgstr "切æ›"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "'input' is:"
msgstr ""
#: modules/visual_script/visual_script_flow_control.cpp
-#, fuzzy
msgid "Type Cast"
-msgstr "類別:"
+msgstr "型別轉æ›"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Is %s?"
@@ -18251,9 +17833,8 @@ msgid "Use Default Args"
msgstr "é‡è¨­ç‚ºé è¨­"
#: modules/visual_script/visual_script_func_nodes.cpp
-#, fuzzy
msgid "Validate"
-msgstr "å¯ä½¿ç”¨çš„字元:"
+msgstr "é©—è­‰"
#: modules/visual_script/visual_script_func_nodes.cpp
#, fuzzy
@@ -18345,19 +17926,16 @@ msgstr "調整陣列大å°"
#: modules/visual_script/visual_script_nodes.cpp scene/resources/material.cpp
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Operator"
-msgstr "疊加é‹ç®—å­ã€‚"
+msgstr "é‹ç®—å­"
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "Invalid argument of type:"
-msgstr ": 無效的引數型別: "
+msgstr "無效的引數型別:"
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "Invalid arguments:"
-msgstr ": 無效的引數: "
+msgstr "無效的引數:"
#: modules/visual_script/visual_script_nodes.cpp
msgid "a if cond, else b"
@@ -18369,14 +17947,12 @@ msgid "Var Name"
msgstr "å稱"
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "VariableGet not found in script:"
-msgstr "腳本中未找到 VariableGet(å–得變數): "
+msgstr "腳本中未找到 VariableGet(å–得變數):"
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "VariableSet not found in script:"
-msgstr "腳本中未找到 VariableSet(設定變數): "
+msgstr "腳本中未找到 VariableSet(設定變數):"
#: modules/visual_script/visual_script_nodes.cpp
#, fuzzy
@@ -18491,7 +18067,7 @@ msgstr "產生"
#: modules/visual_script/visual_script_yield_nodes.cpp
msgid "Wait"
-msgstr ""
+msgstr "等待"
#: modules/visual_script/visual_script_yield_nodes.cpp
#, fuzzy
@@ -18596,9 +18172,8 @@ msgid "CA Chain"
msgstr "清除 IK éˆ"
#: modules/websocket/websocket_server.cpp
-#, fuzzy
msgid "Handshake Timeout"
-msgstr "逾時。"
+msgstr "Handshake 逾時"
#: modules/webxr/webxr_interface.cpp
#, fuzzy
@@ -18606,14 +18181,12 @@ msgid "Session Mode"
msgstr "å€åŸŸæ¨¡å¼"
#: modules/webxr/webxr_interface.cpp
-#, fuzzy
msgid "Required Features"
-msgstr "主è¦åŠŸèƒ½ï¼š"
+msgstr "å¿…è¦ç‰¹æ€§"
#: modules/webxr/webxr_interface.cpp
-#, fuzzy
msgid "Optional Features"
-msgstr "主è¦åŠŸèƒ½ï¼š"
+msgstr "å¯é¸ç‰¹æ€§"
#: modules/webxr/webxr_interface.cpp
msgid "Requested Reference Space Types"
@@ -18704,6 +18277,11 @@ msgid "The package must have at least one '.' separator."
msgstr "套件必須至少有一個「.ã€åˆ†éš”字元。"
#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Custom Build"
+msgstr "剪下節點"
+
+#: platform/android/export/export_plugin.cpp
msgid "Use Custom Build"
msgstr ""
@@ -18712,6 +18290,15 @@ msgstr ""
msgid "Export Format"
msgstr "匯出路徑"
+#: platform/android/export/export_plugin.cpp
+msgid "Min SDK"
+msgstr "æœ€å° SDK"
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "Target SDK"
+msgstr "目標"
+
#: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp
#, fuzzy
msgid "Architectures"
@@ -18754,25 +18341,14 @@ msgstr "嵿Ÿ¥å‰ä¸€å€‹å¯¦é«”"
msgid "Code"
msgstr ""
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Min SDK"
-msgstr "輪廓尺寸:"
-
-#: platform/android/export/export_plugin.cpp
-#, fuzzy
-msgid "Target SDK"
-msgstr "目標"
-
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
#, fuzzy
msgid "Package"
msgstr "正在打包"
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
-#, fuzzy
msgid "Unique Name"
-msgstr "節點å稱:"
+msgstr "ç¨ç«‹å稱"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -18780,9 +18356,8 @@ msgid "Signed"
msgstr "訊號"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Classify As Game"
-msgstr "類別å稱:"
+msgstr "åˆ†é¡žç‚ºéŠæˆ²"
#: platform/android/export/export_plugin.cpp
msgid "Retain Data On Uninstall"
@@ -18794,9 +18369,8 @@ msgid "Exclude From Recents"
msgstr "刪除節點"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Graphics"
-msgstr "網格åç§»é‡ï¼š"
+msgstr "圖形"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -18866,9 +18440,8 @@ msgid "Command Line"
msgstr "社群"
#: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp
-#, fuzzy
msgid "Extra Args"
-msgstr "é¡å¤–呼å«å¼•數:"
+msgstr "é¡å¤–引數"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -19003,15 +18576,17 @@ msgid "\"Use Custom Build\" must be enabled to use the plugins."
msgstr "「使用自定建置ã€å¿…須啟用以使用本外掛。"
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VrApi\" "
+"\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" "
"or \"OpenXR\"."
msgstr ""
"「Hand Trackingã€ï¼ˆæ‰‹éƒ¨è¿½è¹¤ï¼‰åƒ…å¯åœ¨ã€ŒXr Modeã€ï¼ˆXR 模å¼ï¼‰è¨­ç‚ºã€ŒOculus Mobile "
"VRã€æˆ–「OpenXRã€æ™‚å¯ç”¨ã€‚"
#: platform/android/export/export_plugin.cpp
-msgid "\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."
+#, fuzzy
+msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"."
msgstr "「Passthroughã€åƒ…å¯åœ¨ã€ŒXr Modeã€ï¼ˆXR 模å¼ï¼‰è¨­ç‚ºã€ŒOpenXRã€æ™‚å¯ç”¨ã€‚"
#: platform/android/export/export_plugin.cpp
@@ -19019,18 +18594,41 @@ msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
msgstr "「Export AABã€åƒ…於「Use Custom Buildã€å•Ÿç”¨æ™‚å¯ç”¨ã€‚"
#: platform/android/export/export_plugin.cpp
+#, fuzzy
msgid ""
-"Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."
+"\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr "å°ã€ŒMin Sdkã€çš„修改僅在「Use Custom Buildã€å•Ÿç”¨æ™‚有效。"
#: platform/android/export/export_plugin.cpp
+msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
msgid ""
-"Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is "
-"enabled."
+"\"Min SDK\" cannot be lower than %d, which is the version needed by the "
+"Godot library."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid ""
+"\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled."
msgstr "å°ã€ŒTarget Sdkã€çš„修改僅於「Use Custom Buildã€å•Ÿç”¨æ™‚有效。"
#: platform/android/export/export_plugin.cpp
-msgid "\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."
+msgid ""
+"\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+msgid ""
+"\"Target SDK\" %d is higher than the default version %d. This may work, but "
+"wasn't tested and may be unstable."
+msgstr ""
+
+#: platform/android/export/export_plugin.cpp
+#, fuzzy
+msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version."
msgstr "「Target Sdkã€ç‰ˆæœ¬å¿…須高於或于「Min Sdkã€ç‰ˆæœ¬ä¸€è‡´ã€‚"
#: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp
@@ -19040,14 +18638,12 @@ msgid "Code Signing"
msgstr "訊號"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"'apksigner' could not be found. Please check that the command is available "
"in the Android SDK build-tools directory. The resulting %s is unsigned."
msgstr ""
-"找ä¸åˆ°ã€Œapksigner'ã€ã€‚\n"
-"è«‹ç¢ºèªæ­¤å‘½ä»¤å¯ç”¨æ–¼Android SDK build-tools的目錄。\n"
-"%s 未簽署。"
+"找ä¸åˆ°ã€Œapksignerã€ã€‚請檢查 Android SDK çš„ build-tools è³‡æ–™å¤¾ä¸­æ˜¯å¦æœ‰æ­¤æŒ‡ä»¤ã€‚"
+"「%sã€æœªç°½ç½²ã€‚"
#: platform/android/export/export_plugin.cpp
msgid "Signing debug %s..."
@@ -19062,9 +18658,8 @@ msgid "Could not find keystore, unable to export."
msgstr "找ä¸åˆ°é‡‘鑰儲存å€ï¼Œç„¡æ³•匯出。"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not start apksigner executable."
-msgstr "無法啟動å­è™•ç†ç¨‹åºï¼"
+msgstr "無法啟動 apksigner å¯åŸ·è¡Œæª”案。"
#: platform/android/export/export_plugin.cpp
msgid "'apksigner' returned with error #%d"
@@ -19095,9 +18690,8 @@ msgid "Invalid filename! Android APK requires the *.apk extension."
msgstr "無效的檔案å稱ï¼Android APK å¿…é ˆè¦æœ‰ *.apk 副檔å。"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Unsupported export format!"
-msgstr "䏿”¯æ´çš„匯出格å¼ï¼\n"
+msgstr "䏿”¯æ´çš„匯出格å¼ï¼"
#: platform/android/export/export_plugin.cpp
msgid ""
@@ -19107,26 +18701,21 @@ msgstr ""
"嘗試自自定建置樣æ¿é€²è¡Œå»ºç½®ï¼Œä½†ç„¡ç‰ˆæœ¬è³‡è¨Šå¯ç”¨ã€‚請自「專案ã€é¸å–®ä¸­é‡æ–°å®‰è£ã€‚"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Android build version mismatch: Template installed: %s, Godot version: %s. "
"Please reinstall Android build template from 'Project' menu."
msgstr ""
-"Android 建置版本ä¸ç¬¦åˆï¼š\n"
-" 已安è£çš„æ¨£æ¿ï¼š%s\n"
-" Godot 版本:%s\n"
-"請自「專案ã€ç›®éŒ„䏭釿–°å®‰è£ Android 建置樣æ¿ã€‚"
+"Android 建構版本ä¸åŒ¹é…ï¼šå·²å®‰è£æ¨¡æ¿ï¼š %s,Godot 版本:%s。請從專案é¸å–®é‡æ–°å®‰"
+"è£ Android 構建模æ¿ã€‚"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Unable to overwrite res://android/build/res/*.xml files with project name."
-msgstr "無法以專案å稱覆蓋檔案res://android/build/res/*.xml"
+msgstr "無法以專案å稱覆蓋 res://android/build/res/*.xml 檔案。"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not export project files to gradle project."
-msgstr "無法匯出專案檔至Gradle專案。\n"
+msgstr "無法匯出專案檔至 Gradle 專案。"
#: platform/android/export/export_plugin.cpp
msgid "Could not write expansion package file!"
@@ -19137,13 +18726,12 @@ msgid "Building Android Project (gradle)"
msgstr "建置 Android 專案(Gradle)"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Building of Android project failed, check output for the error. "
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
-"建置 Android 專案失敗,請檢查輸出以確èªéŒ¯èª¤ã€‚\n"
-"也å¯ä»¥ç€è¦½ docs.godotengine.org 以ç€è¦½ Android 建置說明文件。"
+"建置 Android 專案失敗,請檢查輸出以確èªéŒ¯èª¤ã€‚也å¯ä»¥ç€è¦½ docs.godotengine.org "
+"檢視 Android 建置說明文件。"
#: platform/android/export/export_plugin.cpp
msgid "Moving output"
@@ -19156,39 +18744,33 @@ msgid ""
msgstr "無法複製並更å匯出的檔案,請於 Gradle 專案資料夾內確èªè¼¸å‡ºã€‚"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Package not found: \"%s\"."
-msgstr "未找到套件:「%sã€"
+msgstr "未找到套件:「%sã€ã€‚"
#: platform/android/export/export_plugin.cpp
msgid "Creating APK..."
msgstr "正在建立APK……"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not find template APK to export: \"%s\"."
-msgstr ""
-"找ä¸åˆ°æ¨£æ¿APK以匯出:\n"
-"%s"
+msgstr "找ä¸åˆ° APK 模æ¿ä»¥åŒ¯å‡ºï¼šã€Œ%sã€ã€‚"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid ""
"Missing libraries in the export template for the selected architectures: %s. "
"Please build a template with all required libraries, or uncheck the missing "
"architectures in the export preset."
msgstr ""
-"éºå¤±æ‰€é¸å–架構(%s)的匯出樣æ¿å‡½å¼åº«ã€‚\n"
-"請使用所有必è¦çš„函å¼åº«å»ºæ§‹æ¨£æ¿ï¼Œæˆ–在匯出é è¨­è¨­å®šä¸­å–消勾é¸éºå¤±çš„æž¶æ§‹ã€‚"
+"éºå¤±æ‰€é¸æž¶æ§‹ï¼ˆ%s)的匯出模æ¿å‡½å¼åº«ã€‚請使用所有必è¦çš„函å¼åº«å»ºæ§‹æ¨¡æ¿ï¼Œæˆ–在匯出"
+"é è¨­è¨­å®šä¸­å–消勾é¸éºå¤±çš„æž¶æ§‹ã€‚"
#: platform/android/export/export_plugin.cpp
msgid "Adding files..."
msgstr "正在加入檔案 %s……"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Could not export project files."
-msgstr "無法匯出專案檔案"
+msgstr "無法匯出專案檔。"
#: platform/android/export/export_plugin.cpp
msgid "Aligning APK..."
@@ -19284,9 +18866,8 @@ msgid "Code Sign Identity Release"
msgstr ""
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Export Method Release"
-msgstr "匯出模å¼ï¼š"
+msgstr "發行匯出模å¼"
#: platform/iphone/export/export.cpp
msgid "Targeted Device Family"
@@ -19297,9 +18878,8 @@ msgid "Info"
msgstr ""
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
-#, fuzzy
msgid "Identifier"
-msgstr "無效的識別符:"
+msgstr "標識符"
#: platform/iphone/export/export.cpp platform/osx/export/export.cpp
#, fuzzy
@@ -19323,14 +18903,12 @@ msgid "Capabilities"
msgstr "貼上屬性"
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Access Wi-Fi"
-msgstr "æˆåŠŸï¼"
+msgstr "å­˜å– Wi-Fi"
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Push Notifications"
-msgstr "隨機旋轉:"
+msgstr "推é€é€šçŸ¥"
#: platform/iphone/export/export.cpp
#, fuzzy
@@ -19462,19 +19040,16 @@ msgid "Run exported HTML in the system's default browser."
msgstr "在系統的é è¨­ç€è¦½å™¨ä¸­åŸ·è¡Œå·²åŒ¯å‡ºçš„ HTML。"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not open template for export: \"%s\"."
-msgstr "無法開啟樣æ¿ä»¥è¼¸å‡ºï¼š"
+msgstr "無法開啟模æ¿ä»¥åŒ¯å‡ºï¼šã€Œ%sã€ã€‚"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Invalid export template: \"%s\"."
-msgstr "無效的輸出樣æ¿ï¼š"
+msgstr "無效的匯出模æ¿ï¼šã€Œ%sã€ã€‚"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not write file: \"%s\"."
-msgstr "無法寫入檔案:"
+msgstr "無法寫入檔案:「%sã€ã€‚"
#: platform/javascript/export/export.cpp platform/osx/export/export.cpp
#, fuzzy
@@ -19482,18 +19057,16 @@ msgid "Icon Creation"
msgstr "設定外邊è·"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not read file: \"%s\"."
-msgstr "ç„¡æ³•è®€å–æª”案:"
+msgstr "ç„¡æ³•è®€å–æª”案:「%sã€ã€‚"
#: platform/javascript/export/export.cpp
msgid "PWA"
msgstr ""
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Variant"
-msgstr "分隔:"
+msgstr "變體"
#: platform/javascript/export/export.cpp
#, fuzzy
@@ -19565,19 +19138,16 @@ msgid "Icon 512 X 512"
msgstr ""
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not read HTML shell: \"%s\"."
-msgstr "無法讀å–HTML殼層:"
+msgstr "ç„¡æ³•è®€å– HTML 殼層:「%sã€ã€‚"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not create HTTP server directory: %s."
-msgstr "無法建立HTTP伺æœå™¨ç›®éŒ„:"
+msgstr "無法建立 HTTP 伺æœå™¨ç›®éŒ„:%s。"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Error starting HTTP server: %d."
-msgstr "啟動HTTP伺æœå™¨æ™‚發生錯誤:"
+msgstr "啟動 HTTP 伺æœå™¨æ™‚發生錯誤:%d。"
#: platform/javascript/export/export.cpp
msgid "Web"
@@ -19681,9 +19251,8 @@ msgid "Unknown object type."
msgstr ""
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "App Category"
-msgstr "分類:"
+msgstr "App 分類"
#: platform/osx/export/export.cpp
msgid "High Res"
@@ -19859,9 +19428,8 @@ msgid "Custom Options"
msgstr "åŒ¯æµæŽ’é¸é …"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Notarization"
-msgstr "本地化"
+msgstr "公證"
#: platform/osx/export/export.cpp
msgid "Apple ID Name"
@@ -19876,19 +19444,16 @@ msgid "Apple Team ID"
msgstr ""
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not open icon file \"%s\"."
-msgstr "無法匯出專案檔案"
+msgstr "無法開啟符號檔 「%sã€ã€‚"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not start xcrun executable."
-msgstr "無法啟動å­è™•ç†ç¨‹åºï¼"
+msgstr "無法啟動 xcrun å¯åŸ·è¡Œæª”案。"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Notarization failed."
-msgstr "本地化"
+msgstr "公證失敗。"
#: platform/osx/export/export.cpp
msgid "Notarization request UUID: \"%s\""
@@ -19941,9 +19506,8 @@ msgid "No identity found."
msgstr "未發ç¾ä»»ä½•圖示。"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Cannot sign file %s."
-msgstr "無法ä¿å­˜æª”案:%s"
+msgstr "無法簽署檔案 %s。"
#: platform/osx/export/export.cpp
msgid "Relative symlinks are not supported, exported \"%s\" might be broken!"
@@ -19955,9 +19519,8 @@ msgid "DMG Creation"
msgstr "æ–¹å‘"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not start hdiutil executable."
-msgstr "無法啟動å­è™•ç†ç¨‹åºï¼"
+msgstr "無法啟動 hdiutil å¯åŸ·è¡Œæª”案。"
#: platform/osx/export/export.cpp
msgid "`hdiutil create` failed - file exists."
@@ -19973,16 +19536,12 @@ msgid "Creating app bundle"
msgstr "正在建立縮圖"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not find template app to export: \"%s\"."
-msgstr ""
-"找ä¸åˆ°æ¨£æ¿APK以匯出:\n"
-"%s"
+msgstr "找ä¸åˆ° app 模æ¿ä»¥åŒ¯å‡ºï¼šã€Œ%sã€ã€‚"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Invalid export format."
-msgstr "無效的輸出樣æ¿ï¼š"
+msgstr "無效的匯出格å¼ã€‚"
#: platform/osx/export/export.cpp
msgid ""
@@ -20038,9 +19597,8 @@ msgid "ZIP Creation"
msgstr "專案"
#: platform/osx/export/export.cpp
-#, fuzzy
msgid "Could not open file to read from path \"%s\"."
-msgstr "無法匯出專案檔至Gradle專案。\n"
+msgstr "ç„¡æ³•æ‰“é–‹ä½æ–¼ã€Œ%sã€çš„æª”案進行讀å–。"
#: platform/osx/export/export.cpp
msgid "Invalid bundle identifier:"
@@ -20167,23 +19725,20 @@ msgid "Display Name"
msgstr "全部顯示"
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Short Name"
-msgstr "腳本å稱:"
+msgstr "短å稱"
#: platform/uwp/export/export.cpp
msgid "Publisher"
msgstr ""
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Publisher Display Name"
-msgstr "無效的套件發佈者顯示å稱。"
+msgstr "發布者顯示å稱"
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Product GUID"
-msgstr "ç„¡æ•ˆçš„ç”¢å“ GUID。"
+msgstr "ç”¢å“ GUID"
#: platform/uwp/export/export.cpp
#, fuzzy
@@ -20196,9 +19751,8 @@ msgid "Signing"
msgstr "訊號"
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Certificate"
-msgstr "頂點:"
+msgstr "憑證"
#: platform/uwp/export/export.cpp
#, fuzzy
@@ -20266,9 +19820,8 @@ msgid "Wide 310 X 150 Logo"
msgstr ""
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Splash Screen"
-msgstr "繪製呼å«ï¼š"
+msgstr "啟動畫é¢"
#: platform/uwp/export/export.cpp
#, fuzzy
@@ -20358,9 +19911,8 @@ msgid "Debug Algorithm"
msgstr "除錯工具"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Failed to rename temporary file \"%s\"."
-msgstr "無法移除臨時檔案:"
+msgstr "ç„¡æ³•é‡æ–°å‘½åæ¨¡æ¿æª”案 「%sã€ã€‚"
#: platform/windows/export/export.cpp
msgid "Identity Type"
@@ -20386,19 +19938,16 @@ msgid "File Version"
msgstr "版本"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Product Version"
-msgstr "ç„¡æ•ˆçš„ç”¢å“ GUID。"
+msgstr "產å“版本"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Company Name"
-msgstr "節點å稱:"
+msgstr "å…¬å¸å稱"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Product Name"
-msgstr "專案å稱:"
+msgstr "產å“å稱"
#: platform/windows/export/export.cpp
#, fuzzy
@@ -20410,9 +19959,8 @@ msgid "Trademarks"
msgstr ""
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Resources Modification"
-msgstr "隨機旋轉:"
+msgstr "資æºä¿®æ”¹"
#: platform/windows/export/export.cpp
#, fuzzy
@@ -20447,9 +19995,8 @@ msgid "Could not find osslsigncode executable at \"%s\"."
msgstr "找ä¸åˆ°é‡‘鑰儲存å€ï¼Œç„¡æ³•匯出。"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Invalid identity type."
-msgstr "無效的識別符:"
+msgstr "身份類型無效。"
#: platform/windows/export/export.cpp
#, fuzzy
@@ -20469,9 +20016,8 @@ msgid ""
msgstr ""
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Failed to remove temporary file \"%s\"."
-msgstr "無法移除臨時檔案:"
+msgstr "ç„¡æ³•ç§»é™¤æ¨¡æ¿æª”案 「%sã€ã€‚"
#: platform/windows/export/export.cpp
msgid ""
@@ -20480,19 +20026,16 @@ msgid ""
msgstr ""
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Invalid icon path:"
-msgstr "無效的路徑。"
+msgstr "無效符號路徑:"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Invalid file version:"
-msgstr "無效的副檔å。"
+msgstr "無效的檔案版本:"
#: platform/windows/export/export.cpp
-#, fuzzy
msgid "Invalid product version:"
-msgstr "ç„¡æ•ˆçš„ç”¢å“ GUID。"
+msgstr "無效的產å“版本:"
#: platform/windows/export/export.cpp
msgid "Windows executables cannot be >= 4 GiB."
@@ -20661,9 +20204,8 @@ msgstr ""
#: scene/3d/light.cpp scene/3d/reflection_probe.cpp
#: scene/3d/visibility_notifier.cpp scene/3d/visual_instance.cpp
#: scene/resources/material.cpp
-#, fuzzy
msgid "Max Distance"
-msgstr "鏿“‡è·é›¢ï¼š"
+msgstr "最大è·é›¢"
#: scene/2d/audio_stream_player_2d.cpp scene/3d/light.cpp
#, fuzzy
@@ -20691,15 +20233,13 @@ msgid "Anchor Mode"
msgstr "圖示模å¼"
#: scene/2d/camera_2d.cpp
-#, fuzzy
msgid "Rotating"
-msgstr "旋轉步長:"
+msgstr "旋轉"
#: scene/2d/camera_2d.cpp scene/2d/listener_2d.cpp scene/3d/camera.cpp
#: scene/3d/listener.cpp scene/animation/animation_blend_tree.cpp
-#, fuzzy
msgid "Current"
-msgstr "ç›®å‰ï¼š"
+msgstr "ç›®å‰"
#: scene/2d/camera_2d.cpp scene/gui/graph_edit.cpp
#, fuzzy
@@ -20711,7 +20251,7 @@ msgstr "放大"
msgid "Custom Viewport"
msgstr "1 個檢視å€"
-#: scene/2d/camera_2d.cpp scene/3d/camera.cpp
+#: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp
#: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp
#: scene/animation/animation_tree_player.cpp scene/main/timer.cpp
#, fuzzy
@@ -20781,14 +20321,12 @@ msgid "Drag Margin"
msgstr "設定外邊è·"
#: scene/2d/camera_2d.cpp
-#, fuzzy
msgid "Draw Screen"
-msgstr "繪製呼å«ï¼š"
+msgstr "繪製螢幕"
#: scene/2d/camera_2d.cpp
-#, fuzzy
msgid "Draw Limits"
-msgstr "繪製呼å«ï¼š"
+msgstr "繪製é™åˆ¶"
#: scene/2d/camera_2d.cpp
#, fuzzy
@@ -20965,9 +20503,8 @@ msgstr ""
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
#: scene/3d/cpu_particles.cpp scene/3d/particles.cpp
-#, fuzzy
msgid "Emitting"
-msgstr "設定:"
+msgstr "發射"
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
#: scene/3d/cpu_particles.cpp scene/3d/particles.cpp
@@ -20993,9 +20530,8 @@ msgstr ""
#: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp
#: scene/3d/cpu_particles.cpp scene/3d/particles.cpp
-#, fuzzy
msgid "Randomness"
-msgstr "éš¨æ©Ÿé‡æ–°é–‹å§‹ï¼ˆç§’):"
+msgstr "隨機性"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
@@ -21037,9 +20573,8 @@ msgstr "發射é®ç½©"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
-#, fuzzy
msgid "Sphere Radius"
-msgstr "發射æºï¼š "
+msgstr "çƒé«”åŠå¾‘"
#: scene/2d/cpu_particles_2d.cpp
#, fuzzy
@@ -21107,9 +20642,8 @@ msgstr "線性"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
-#, fuzzy
msgid "Accel"
-msgstr "æˆåŠŸï¼"
+msgstr "加速度"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
@@ -21168,9 +20702,8 @@ msgid "Angle Curve"
msgstr "關閉曲線"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
-#, fuzzy
msgid "Scale Amount"
-msgstr "數é‡ï¼š"
+msgstr "縮放é‡"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
msgid "Scale Amount Random"
@@ -21194,27 +20727,23 @@ msgstr ""
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
-#, fuzzy
msgid "Hue Variation"
-msgstr "分隔:"
+msgstr "色相變化"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
-#, fuzzy
msgid "Variation"
-msgstr "分隔:"
+msgstr "變化"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
-#, fuzzy
msgid "Variation Random"
-msgstr "分隔:"
+msgstr "隨機變化"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
-#, fuzzy
msgid "Variation Curve"
-msgstr "分隔:"
+msgstr "變化曲線"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
@@ -21230,9 +20759,8 @@ msgstr "拆分控制點"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
-#, fuzzy
msgid "Offset Random"
-msgstr "å移:"
+msgstr "隨機åç§»"
#: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp
#: scene/resources/particles_material.cpp
@@ -21425,14 +20953,12 @@ msgid "Begin Cap Mode"
msgstr "å€åŸŸæ¨¡å¼"
#: scene/2d/line_2d.cpp
-#, fuzzy
msgid "End Cap Mode"
-msgstr "å¸é™„模å¼ï¼š"
+msgstr "尾端模å¼"
#: scene/2d/line_2d.cpp scene/2d/polygon_2d.cpp scene/resources/style_box.cpp
-#, fuzzy
msgid "Border"
-msgstr "釿–°å‘½å資料夾:"
+msgstr "邊框"
#: scene/2d/line_2d.cpp
msgid "Sharp Limit"
@@ -21459,15 +20985,44 @@ msgid "Cell Size"
msgstr ""
#: scene/2d/navigation_2d.cpp scene/3d/navigation.cpp
-#, fuzzy
msgid "Edge Connection Margin"
-msgstr "編輯連接內容:"
+msgstr "邊界連接邊è·"
+
+#: scene/2d/navigation_2d.cpp
+msgid ""
+"'Navigation2D' node and 'Navigation2D.get_simple_path()' are deprecated and "
+"will be removed in a future version. Use 'Navigation2DServer.map_get_path()' "
+"instead."
+msgstr ""
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Pathfinding"
+msgstr "ç¶å®š"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Desired Distance"
+msgstr "路徑所需è·é›¢"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Target Desired Distance"
msgstr ""
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+msgid "Path Max Distance"
+msgstr "路徑最大è·é›¢"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance"
+msgstr "進階"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
+#, fuzzy
+msgid "Avoidance Enabled"
+msgstr "啟用"
+
+#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
msgid "Neighbor Dist"
msgstr ""
@@ -21481,19 +21036,8 @@ msgid "Time Horizon"
msgstr "水平翻轉"
#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
msgid "Max Speed"
-msgstr "速度:"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Path Max Distance"
-msgstr "鏿“‡è·é›¢ï¼š"
-
-#: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp
-#, fuzzy
-msgid "Avoidance Enabled"
-msgstr "啟用"
+msgstr "最大速度"
#: scene/2d/navigation_agent_2d.cpp
msgid ""
@@ -21535,24 +21079,21 @@ msgstr "行程"
#: scene/2d/node_2d.cpp scene/2d/polygon_2d.cpp scene/3d/spatial.cpp
#: scene/main/canvas_layer.cpp
-#, fuzzy
msgid "Rotation Degrees"
-msgstr "旋轉 %s 度。"
+msgstr "旋轉角度"
-#: scene/2d/node_2d.cpp
+#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
msgid "Global Rotation"
msgstr "常數"
#: scene/2d/node_2d.cpp
-#, fuzzy
msgid "Global Rotation Degrees"
-msgstr "旋轉 %s 度。"
+msgstr "全域旋轉角度"
#: scene/2d/node_2d.cpp
-#, fuzzy
msgid "Global Scale"
-msgstr "隨機縮放:"
+msgstr "全域縮放"
#: scene/2d/node_2d.cpp scene/3d/spatial.cpp
#, fuzzy
@@ -21570,9 +21111,8 @@ msgid "Scroll"
msgstr ""
#: scene/2d/parallax_background.cpp
-#, fuzzy
msgid "Base Offset"
-msgstr "å移:"
+msgstr "基礎åç§»"
#: scene/2d/parallax_background.cpp
#, fuzzy
@@ -21662,19 +21202,16 @@ msgid "PathFollow2D only works when set as a child of a Path2D node."
msgstr "PathFollow2D 僅在其為 Path2D çš„å­ç¯€é»žæ™‚有效。"
#: scene/2d/path_2d.cpp scene/3d/path.cpp
-#, fuzzy
msgid "Unit Offset"
-msgstr "網格åç§»é‡ï¼š"
+msgstr "å–®ä½åç§»"
#: scene/2d/path_2d.cpp scene/3d/camera.cpp scene/3d/path.cpp
-#, fuzzy
msgid "H Offset"
-msgstr "å移:"
+msgstr "H åç§»"
#: scene/2d/path_2d.cpp scene/3d/camera.cpp scene/3d/path.cpp
-#, fuzzy
msgid "V Offset"
-msgstr "å移:"
+msgstr "V åç§»"
#: scene/2d/path_2d.cpp scene/3d/path.cpp
msgid "Cubic Interp"
@@ -21735,9 +21272,8 @@ msgid "Mass"
msgstr ""
#: scene/2d/physics_body_2d.cpp
-#, fuzzy
msgid "Inertia"
-msgstr "垂直:"
+msgstr "慣性"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#, fuzzy
@@ -21774,9 +21310,8 @@ msgid "Sleeping"
msgstr "智慧型å¸é™„"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Can Sleep"
-msgstr "速度:"
+msgstr "å¯ä»¥ç¡çœ "
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
msgid "Damp"
@@ -21800,9 +21335,8 @@ msgid "Safe Margin"
msgstr "設定外邊è·"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Sync To Physics"
-msgstr " (物ç†ï¼‰"
+msgstr "與物ç†åŒæ­¥"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#, fuzzy
@@ -21822,9 +21356,8 @@ msgid "Normal"
msgstr "æ ¼å¼"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Remainder"
-msgstr "算繪引擎:"
+msgstr "餘é‡"
#: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp
#, fuzzy
@@ -22014,9 +21547,8 @@ msgid "Compatibility Mode"
msgstr "優先模å¼"
#: scene/2d/tile_map.cpp
-#, fuzzy
msgid "Centered Textures"
-msgstr "主è¦åŠŸèƒ½ï¼š"
+msgstr "ç´‹ç†å±…中"
#: scene/2d/tile_map.cpp
msgid "Cell Clip UV"
@@ -22135,9 +21667,8 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin 必須有一個 ARVRCamera å­ç¯€é»žã€‚"
#: scene/3d/arvr_nodes.cpp servers/arvr_server.cpp
-#, fuzzy
msgid "World Scale"
-msgstr "隨機縮放:"
+msgstr "世界縮放"
#: scene/3d/audio_stream_player_3d.cpp
#, fuzzy
@@ -22166,9 +21697,8 @@ msgid "Emission Angle"
msgstr "發射色彩"
#: scene/3d/audio_stream_player_3d.cpp
-#, fuzzy
msgid "Degrees"
-msgstr "旋轉 %s 度。"
+msgstr "角度"
#: scene/3d/audio_stream_player_3d.cpp
#, fuzzy
@@ -22250,9 +21780,8 @@ msgid "Bounce Indirect Energy"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Use Denoiser"
-msgstr "篩é¸ï¼š"
+msgstr "使用é™å™ªå™¨"
#: scene/3d/baked_lightmap.cpp scene/resources/texture.cpp
msgid "Use HDR"
@@ -22279,9 +21808,8 @@ msgid "Generate"
msgstr "一般"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Max Size"
-msgstr "大å°ï¼š"
+msgstr "最大大å°"
#: scene/3d/baked_lightmap.cpp
#, fuzzy
@@ -22289,9 +21817,8 @@ msgid "Custom Sky"
msgstr "剪下節點"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Custom Sky Rotation Degrees"
-msgstr "旋轉 %s 度。"
+msgstr "自定義天空旋轉角度"
#: scene/3d/baked_lightmap.cpp scene/3d/ray_cast.cpp
#, fuzzy
@@ -22323,9 +21850,8 @@ msgid "Light Data"
msgstr "åŒ…å«æ•¸æ“š"
#: scene/3d/bone_attachment.cpp scene/3d/physics_body.cpp
-#, fuzzy
msgid "Bone Name"
-msgstr "節點å稱:"
+msgstr "骨骼å稱"
#: scene/3d/camera.cpp
msgid "Keep Aspect"
@@ -22350,9 +21876,8 @@ msgid "FOV"
msgstr ""
#: scene/3d/camera.cpp
-#, fuzzy
msgid "Frustum Offset"
-msgstr "網格åç§»é‡ï¼š"
+msgstr "視éŒåç§»"
#: scene/3d/camera.cpp
#, fuzzy
@@ -22604,9 +22129,8 @@ msgid "Font"
msgstr "å­—é«”"
#: scene/3d/label_3d.cpp scene/resources/primitive_meshes.cpp
-#, fuzzy
msgid "Horizontal Alignment"
-msgstr "水平:"
+msgstr "æ°´å¹³å°é½Š"
#: scene/3d/label_3d.cpp
#, fuzzy
@@ -22670,9 +22194,8 @@ msgid "Split 3"
msgstr "拆分路徑"
#: scene/3d/light.cpp
-#, fuzzy
msgid "Blend Splits"
-msgstr "æ··åˆæ™‚間:"
+msgstr "æ··åˆæ‹†åˆ†"
#: scene/3d/light.cpp
#, fuzzy
@@ -22716,9 +22239,15 @@ msgid "Software Skinning"
msgstr ""
#: scene/3d/mesh_instance.cpp
-#, fuzzy
msgid "Transform Normals"
-msgstr "已中止變æ›ã€‚"
+msgstr "è®Šæ›æ³•ç·š"
+
+#: scene/3d/navigation.cpp
+msgid ""
+"'Navigation' node and 'Navigation.get_simple_path()' are deprecated and will "
+"be removed in a future version. Use 'NavigationServer.map_get_path()' "
+"instead."
+msgstr ""
#: scene/3d/navigation.cpp scene/resources/curve.cpp
#, fuzzy
@@ -22800,14 +22329,12 @@ msgid "Visibility AABB"
msgstr "切æ›å¯è¦‹ï¼éš±è—"
#: scene/3d/particles.cpp
-#, fuzzy
msgid "Draw Passes"
-msgstr "繪製呼å«ï¼š"
+msgstr "繪製階段"
#: scene/3d/particles.cpp
-#, fuzzy
msgid "Passes"
-msgstr "繪製呼å«ï¼š"
+msgstr "階段"
#: scene/3d/path.cpp
msgid "PathFollow only works when set as a child of a Path node."
@@ -22903,9 +22430,8 @@ msgstr ""
#: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp
#: scene/3d/vehicle_body.cpp
-#, fuzzy
msgid "Relaxation"
-msgstr "分隔:"
+msgstr "鬆弛"
#: scene/3d/physics_body.cpp
#, fuzzy
@@ -22918,9 +22444,8 @@ msgid "Angular Limit Upper"
msgstr "線性"
#: scene/3d/physics_body.cpp
-#, fuzzy
msgid "Angular Limit Lower"
-msgstr "最大角度誤差:"
+msgstr "角度下é™"
#: scene/3d/physics_body.cpp
#, fuzzy
@@ -23051,9 +22576,8 @@ msgid "Angular Equilibrium Point"
msgstr ""
#: scene/3d/physics_body.cpp
-#, fuzzy
msgid "Body Offset"
-msgstr "å移:"
+msgstr "形體åç§»"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
@@ -23085,9 +22609,8 @@ msgid "Exclude Nodes"
msgstr "刪除節點"
#: scene/3d/physics_joint.cpp
-#, fuzzy
msgid "Params"
-msgstr "å·²æ›´æ”¹åƒæ•¸ï¼š"
+msgstr "引數"
#: scene/3d/physics_joint.cpp
msgid "Angular Limit"
@@ -23113,9 +22636,8 @@ msgid "Target Velocity"
msgstr "å‘å³ç’°è¦–"
#: scene/3d/physics_joint.cpp
-#, fuzzy
msgid "Max Impulse"
-msgstr "速度:"
+msgstr "最大è¡é‡"
#: scene/3d/physics_joint.cpp
#, fuzzy
@@ -23123,14 +22645,12 @@ msgid "Linear Limit"
msgstr "線性"
#: scene/3d/physics_joint.cpp
-#, fuzzy
msgid "Upper Distance"
-msgstr "鏿“‡è·é›¢ï¼š"
+msgstr "è·é›¢ä¸Šé™"
#: scene/3d/physics_joint.cpp
-#, fuzzy
msgid "Lower Distance"
-msgstr "鏿“‡è·é›¢ï¼š"
+msgstr "è·é›¢ä¸‹é™"
#: scene/3d/physics_joint.cpp
#, fuzzy
@@ -23163,9 +22683,8 @@ msgid "Angular Motion"
msgstr "å‹•ç•«"
#: scene/3d/physics_joint.cpp
-#, fuzzy
msgid "Angular Ortho"
-msgstr "最大角度誤差:"
+msgstr "角度正交"
#: scene/3d/physics_joint.cpp
#, fuzzy
@@ -23178,9 +22697,8 @@ msgid "Linear Motor X"
msgstr "åˆå§‹åŒ–"
#: scene/3d/physics_joint.cpp
-#, fuzzy
msgid "Force Limit"
-msgstr "繪製呼å«ï¼š"
+msgstr "力度é™åˆ¶"
#: scene/3d/physics_joint.cpp
#, fuzzy
@@ -23278,9 +22796,8 @@ msgid "Two Way"
msgstr ""
#: scene/3d/portal.cpp
-#, fuzzy
msgid "Linked Room"
-msgstr "峿™‚編輯根節點:"
+msgstr "連接房間"
#: scene/3d/portal.cpp
#, fuzzy
@@ -23297,9 +22814,8 @@ msgid "Dispatch Mode"
msgstr ""
#: scene/3d/proximity_group.cpp
-#, fuzzy
msgid "Grid Radius"
-msgstr "åŠå¾‘:"
+msgstr "網格åŠå¾‘"
#: scene/3d/ray_cast.cpp
#, fuzzy
@@ -23316,9 +22832,8 @@ msgid "Update Mode"
msgstr "旋轉模å¼"
#: scene/3d/reflection_probe.cpp
-#, fuzzy
msgid "Origin Offset"
-msgstr "網格åç§»é‡ï¼š"
+msgstr "原點åç§»"
#: scene/3d/reflection_probe.cpp
#, fuzzy
@@ -23580,14 +23095,12 @@ msgid "Parent Collision Ignore"
msgstr "建立碰撞多邊形"
#: scene/3d/soft_body.cpp
-#, fuzzy
msgid "Simulation Precision"
-msgstr "無效的動畫樹。"
+msgstr "模擬精度"
#: scene/3d/soft_body.cpp
-#, fuzzy
msgid "Total Mass"
-msgstr "總計:"
+msgstr "總質é‡"
#: scene/3d/soft_body.cpp
msgid "Linear Stiffness"
@@ -23631,13 +23144,17 @@ msgstr ""
"請改為修改其å­ç¯€é»žçš„碰撞形狀之大å°ã€‚"
#: scene/3d/spatial.cpp
+#, fuzzy
+msgid "Global Translation"
+msgstr "ä¿æŒå…¨åŸŸè®Šæ›"
+
+#: scene/3d/spatial.cpp
msgid "Matrix"
msgstr ""
#: scene/3d/spatial.cpp
-#, fuzzy
msgid "Gizmo"
-msgstr "Gizmo"
+msgstr "控制器"
#: scene/3d/spatial_velocity_tracker.cpp
#, fuzzy
@@ -23696,18 +23213,16 @@ msgid "VehicleBody Motion"
msgstr ""
#: scene/3d/vehicle_body.cpp
-#, fuzzy
msgid "Use As Traction"
-msgstr "分隔:"
+msgstr "用作牽引"
#: scene/3d/vehicle_body.cpp
msgid "Use As Steering"
msgstr ""
#: scene/3d/vehicle_body.cpp
-#, fuzzy
msgid "Wheel"
-msgstr "滾輪å‘上。"
+msgstr "車輪"
#: scene/3d/vehicle_body.cpp
msgid "Roll Influence"
@@ -23743,9 +23258,8 @@ msgid "Material Override"
msgstr "複寫"
#: scene/3d/visual_instance.cpp
-#, fuzzy
msgid "Material Overlay"
-msgstr "æè³ªè®Šæ›´ï¼š"
+msgstr "æè³ªè¦†è“‹å±¤"
#: scene/3d/visual_instance.cpp
#, fuzzy
@@ -23753,9 +23267,8 @@ msgid "Cast Shadow"
msgstr "建立著色器節點"
#: scene/3d/visual_instance.cpp
-#, fuzzy
msgid "Extra Cull Margin"
-msgstr "é¡å¤–呼å«å¼•數:"
+msgstr "é¡å¤–剔除邊è·"
#: scene/3d/visual_instance.cpp
#, fuzzy
@@ -23777,9 +23290,8 @@ msgstr ""
#: scene/3d/visual_instance.cpp scene/animation/skeleton_ik.cpp
#: scene/resources/material.cpp
-#, fuzzy
msgid "Min Distance"
-msgstr "鏿“‡è·é›¢ï¼š"
+msgstr "最å°è·é›¢"
#: scene/3d/visual_instance.cpp
msgid "Min Hysteresis"
@@ -24280,18 +23792,16 @@ msgid "Mouse"
msgstr ""
#: scene/gui/control.cpp
-#, fuzzy
msgid "Default Cursor Shape"
-msgstr "載入é è¨­åŒ¯æµæŽ’é…置。"
+msgstr "é è¨­æ¸¸æ¨™å½¢ç‹€"
#: scene/gui/control.cpp
msgid "Pass On Modal Close Click"
msgstr ""
#: scene/gui/control.cpp
-#, fuzzy
msgid "Size Flags"
-msgstr "大å°ï¼š "
+msgstr "å¤§å° Flag:"
#: scene/gui/control.cpp
#, fuzzy
@@ -24657,9 +24167,8 @@ msgid "Max Value"
msgstr "數值"
#: scene/gui/range.cpp
-#, fuzzy
msgid "Page"
-msgstr "é ï¼š "
+msgstr "é "
#: scene/gui/range.cpp
#, fuzzy
@@ -24847,9 +24356,8 @@ msgid "All Tabs In Front"
msgstr ""
#: scene/gui/tab_container.cpp scene/gui/tabs.cpp
-#, fuzzy
msgid "Drag To Rearrange Enabled"
-msgstr "æ‹–æ”¾ä»¥é‡æ–°æŽ’列。"
+msgstr "å•Ÿç”¨æ‹–ç§»é‡æ–°æŽ’列"
#: scene/gui/tab_container.cpp
msgid "Use Hidden Tabs For Min Size"
@@ -24884,6 +24392,11 @@ msgstr "資料夾:"
#: scene/gui/text_edit.cpp
#, fuzzy
+msgid "Drag And Drop Selection Enabled"
+msgstr "僅æœå°‹æ‰€é¸å€åŸŸ"
+
+#: scene/gui/text_edit.cpp
+#, fuzzy
msgid "Hiding Enabled"
msgstr "啟用"
@@ -24981,9 +24494,8 @@ msgid "Initial Angle"
msgstr "åˆå§‹åŒ–"
#: scene/gui/texture_progress.cpp
-#, fuzzy
msgid "Fill Degrees"
-msgstr "旋轉 %s 度。"
+msgstr "填充角度"
#: scene/gui/texture_progress.cpp scene/resources/primitive_meshes.cpp
#, fuzzy
@@ -25090,9 +24602,8 @@ msgid "Max Redirects"
msgstr ""
#: scene/main/http_request.cpp
-#, fuzzy
msgid "Timeout"
-msgstr "逾時。"
+msgstr "逾時"
#: scene/main/node.cpp
msgid ""
@@ -25220,9 +24731,8 @@ msgid "Draw 2D Outlines"
msgstr "建立輪廓"
#: scene/main/scene_tree.cpp servers/visual_server.cpp
-#, fuzzy
msgid "Reflections"
-msgstr "æ–¹å‘"
+msgstr "åå°„"
#: scene/main/scene_tree.cpp
#, fuzzy
@@ -25294,22 +24804,20 @@ msgstr "匯出路徑"
#: scene/main/viewport.cpp
msgid ""
-"This viewport is not set as render target. If you intend for it to display "
-"its contents directly to the screen, make it a child of a Control so it can "
-"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
-"texture to some node for display."
-msgstr ""
-"該 Viewport 尚未被設定為算繪目標。若你想直接將其內容顯示於畫é¢ä¸Šï¼Œè«‹å°‡å…¶è¨­ç‚º "
-"Control çš„å­ç¯€é»žä»¥è®“å…¶å–得大å°ã€‚å¦å‰‡è«‹å°‡å…¶è¨­ç‚º RenderTarget 並指派其內部紋ç†"
-"為其他節點以顯示。"
-
-#: scene/main/viewport.cpp
-msgid ""
"The Viewport size must be greater than or equal to 2 pixels on both "
"dimensions to render anything."
msgstr "Viewport長與寬必須皆大於或等於2åƒç´ æ‰å¯é€²è¡Œç®—繪。"
#: scene/main/viewport.cpp
+msgid ""
+"This Viewport has HDR enabled, but its Usage is set to 2D or 2D No-"
+"Sampling.\n"
+"HDR is only supported in Viewports that have their Usage set to 3D or 3D No-"
+"Effects.\n"
+"HDR will be disabled for this Viewport."
+msgstr ""
+
+#: scene/main/viewport.cpp
msgid "ARVR"
msgstr ""
@@ -25861,9 +25369,8 @@ msgid "Labeled Separator Right"
msgstr "帶å稱的分隔線"
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Font Separator"
-msgstr "色彩é‹ç®—å­ã€‚"
+msgstr "分隔線字體"
#: scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -25871,9 +25378,8 @@ msgid "Font Color Accel"
msgstr "釿–°å‘½åé¡è‰²é …ç›®"
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Font Color Separator"
-msgstr "色彩é‹ç®—å­ã€‚"
+msgstr "分隔線字體é¡è‰²"
#: scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -26161,9 +25667,8 @@ msgid "Label Width"
msgstr "左延展"
#: scene/resources/default_theme/default_theme.cpp
-#, fuzzy
msgid "Screen Picker"
-msgstr "濾色é‹ç®—å­ã€‚"
+msgstr "å±å¹•å–色器"
#: scene/resources/default_theme/default_theme.cpp
#, fuzzy
@@ -26378,9 +25883,8 @@ msgid "Sky Rotation"
msgstr "旋轉步長:"
#: scene/resources/environment.cpp
-#, fuzzy
msgid "Sky Rotation Degrees"
-msgstr "旋轉 %s 度。"
+msgstr "天空旋轉角度"
#: scene/resources/environment.cpp
msgid "Canvas Max Layer"
@@ -26560,9 +26064,8 @@ msgid "Distance"
msgstr "鏿“‡è·é›¢ï¼š"
#: scene/resources/environment.cpp
-#, fuzzy
msgid "Transition"
-msgstr "轉場: "
+msgstr "轉場效果"
#: scene/resources/environment.cpp
msgid "DOF Near Blur"
@@ -26645,9 +26148,8 @@ msgid "Saturation"
msgstr "分隔:"
#: scene/resources/environment.cpp
-#, fuzzy
msgid "Color Correction"
-msgstr "é¡è‰²å‡½å¼ã€‚"
+msgstr "é¡è‰²æ ¡æ­£"
#: scene/resources/font.cpp
#, fuzzy
@@ -26729,9 +26231,8 @@ msgid "Disable Ambient Light"
msgstr "å‘å³ç¸®æŽ’"
#: scene/resources/material.cpp
-#, fuzzy
msgid "Ensure Correct Normals"
-msgstr "已中止變æ›ã€‚"
+msgstr "ç¢ºä¿æ­£ç¢ºæ³•ç·š"
#: scene/resources/material.cpp
msgid "Albedo Tex MSDF"
@@ -26898,9 +26399,8 @@ msgid "Subsurf Scatter"
msgstr ""
#: scene/resources/material.cpp
-#, fuzzy
msgid "Transmission"
-msgstr "轉場: "
+msgstr "轉場"
#: scene/resources/material.cpp
#, fuzzy
@@ -26968,14 +26468,12 @@ msgid "NavMesh Transform"
msgstr "清除變æ›"
#: scene/resources/multimesh.cpp
-#, fuzzy
msgid "Color Format"
-msgstr "色彩é‹ç®—å­ã€‚"
+msgstr "é¡è‰²æ ¼å¼"
#: scene/resources/multimesh.cpp
-#, fuzzy
msgid "Transform Format"
-msgstr "已中止變æ›ã€‚"
+msgstr "è®Šæ›æ ¼å¼"
#: scene/resources/multimesh.cpp
msgid "Custom Data Format"
@@ -26991,9 +26489,8 @@ msgid "Visible Instance Count"
msgstr ""
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Sampling"
-msgstr "縮放: "
+msgstr "縮放:"
#: scene/resources/navigation_mesh.cpp
#, fuzzy
@@ -27001,9 +26498,8 @@ msgid "Partition Type"
msgstr "設定變數型別"
#: scene/resources/navigation_mesh.cpp
-#, fuzzy
msgid "Parsed Geometry Type"
-msgstr "正在解æžå¤šé‚Šå½¢..."
+msgstr "è§£æžå¹¾ä½•體類型"
#: scene/resources/navigation_mesh.cpp
msgid "Source Geometry Mode"
@@ -27081,6 +26577,16 @@ msgstr ""
msgid "Walkable Low Height Spans"
msgstr ""
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB"
+msgstr "正在產生 AABB"
+
+#: scene/resources/navigation_mesh.cpp
+#, fuzzy
+msgid "Baking AABB Offset"
+msgstr "å移:"
+
#: scene/resources/occluder_shape.cpp
msgid "Spheres"
msgstr ""
@@ -27127,9 +26633,8 @@ msgid "Point Texture"
msgstr "發射點:"
#: scene/resources/particles_material.cpp
-#, fuzzy
msgid "Normal Texture"
-msgstr "發射æºï¼š "
+msgstr "法線紋ç†è²¼åœ–"
#: scene/resources/particles_material.cpp
#, fuzzy
@@ -27333,9 +26838,8 @@ msgid "Base Texture"
msgstr "移除紋ç†"
#: scene/resources/texture.cpp
-#, fuzzy
msgid "Image Size"
-msgstr "é ï¼š "
+msgstr "圖片大å°"
#: scene/resources/texture.cpp
#, fuzzy
@@ -27747,9 +27251,8 @@ msgid "Pan Pullout"
msgstr ""
#: servers/audio/effects/audio_effect_stereo_enhance.cpp
-#, fuzzy
msgid "Time Pullout (ms)"
-msgstr "逾時。"
+msgstr "撤離時間(毫秒)"
#: servers/audio/effects/audio_effect_stereo_enhance.cpp
msgid "Surround"
@@ -27804,119 +27307,105 @@ msgstr "é€è¦–"
#: servers/physics/space_sw.cpp servers/physics_2d/space_2d_sw.cpp
msgid "Sleep Threshold Linear"
-msgstr ""
+msgstr "線性ç¡çœ é€Ÿåº¦é–¾å€¼"
#: servers/physics/space_sw.cpp servers/physics_2d/space_2d_sw.cpp
msgid "Sleep Threshold Angular"
-msgstr ""
+msgstr "ç¡çœ è§’速度閾值"
#: servers/physics/space_sw.cpp servers/physics_2d/space_2d_sw.cpp
msgid "Time Before Sleep"
-msgstr ""
+msgstr "ç¡çœ å‰æ™‚é–“"
#: servers/physics_2d/physics_2d_server_sw.cpp
-#, fuzzy
msgid "BP Hash Table Size"
-msgstr "大å°ï¼š"
+msgstr "BP 雜湊表大å°"
#: servers/physics_2d/physics_2d_server_sw.cpp
msgid "Large Object Surface Threshold In Cells"
-msgstr ""
+msgstr "大物件表é¢å–®ä½æ ¼é–¾å€¼"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
msgid "Inverse Mass"
-msgstr ""
+msgstr "逆質é‡"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Inverse Inertia"
-msgstr "自由視圖 左"
+msgstr "逆慣性"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
msgid "Total Angular Damp"
-msgstr ""
+msgstr "總角速度減幅"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Total Linear Damp"
-msgstr "線性"
+msgstr "總線性速度減幅"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Total Gravity"
-msgstr "é è¨­é è¦½"
+msgstr "總é‡åŠ›"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Linear Velocity"
-msgstr "åˆå§‹åŒ–"
+msgstr "線性速度"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
msgid "Exclude"
-msgstr ""
+msgstr "排除"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
msgid "Shape RID"
-msgstr ""
+msgstr "形狀RID"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collide With Bodies"
-msgstr "碰撞模å¼"
+msgstr "形體間碰撞"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
msgid "Collide With Areas"
-msgstr ""
+msgstr "å€åŸŸé–“碰撞"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
msgid "Motion Remainder"
-msgstr ""
+msgstr "é‹å‹•剩餘é‡"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collision Point"
-msgstr "碰撞模å¼"
+msgstr "碰撞點"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collision Normal"
-msgstr "碰撞模å¼"
+msgstr "碰撞法線"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collision Depth"
-msgstr "碰撞模å¼"
+msgstr "碰撞深度"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collision Safe Fraction"
-msgstr "碰撞模å¼"
+msgstr "碰撞安全比值"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Collision Unsafe Fraction"
-msgstr "碰撞模å¼"
+msgstr "碰撞éžå®‰å…¨æ¯”值"
#: servers/physics_2d_server.cpp servers/physics_server.cpp
-#, fuzzy
msgid "Physics Engine"
-msgstr "物ç†å½±æ ¼ %"
+msgstr "物ç†å¼•擎"
#: servers/physics_server.cpp
-#, fuzzy
msgid "Center Of Mass"
-msgstr "中左"
+msgstr "質é‡ä¸­å¿ƒ"
#: servers/physics_server.cpp
msgid "Principal Inertia Axes"
-msgstr ""
+msgstr "主慣性軸"
#: servers/visual/shader_language.cpp
msgid "Varying may not be assigned in the '%s' function."
-msgstr "Varying 變數ä¸å¯åœ¨å‡½å¼ã€Œ%sã€ä¸­è¢«æŒ‡æ´¾ã€‚"
+msgstr "Varying變數ä¸å¯åœ¨ã€Œ%sã€å‡½å¼ä¸­è¢«æŒ‡æ´¾ã€‚"
#: servers/visual/shader_language.cpp
-#, fuzzy
msgid ""
"Varyings which were assigned in 'vertex' function may not be reassigned in "
"'fragment' or 'light'."
@@ -27925,7 +27414,6 @@ msgstr ""
"指派。"
#: servers/visual/shader_language.cpp
-#, fuzzy
msgid ""
"Varyings which were assigned in 'fragment' function may not be reassigned in "
"'vertex' or 'light'."
@@ -27946,39 +27434,32 @@ msgid "Constants cannot be modified."
msgstr "ä¸å¯ä¿®æ”¹å¸¸æ•¸ã€‚"
#: servers/visual/visual_server_scene.cpp
-#, fuzzy
msgid "Spatial Partitioning"
-msgstr "正在分割..."
+msgstr "空間分割"
#: servers/visual_server.cpp
-#, fuzzy
msgid "Render Loop Enabled"
-msgstr "篩é¸è¨Šè™Ÿ"
+msgstr "啟用算繪迴圈"
#: servers/visual_server.cpp
-#, fuzzy
msgid "VRAM Compression"
-msgstr "設定表示å¼"
+msgstr "VRAM壓縮"
#: servers/visual_server.cpp
-#, fuzzy
msgid "Import BPTC"
-msgstr "匯入"
+msgstr "匯入BPTC"
#: servers/visual_server.cpp
-#, fuzzy
msgid "Import S3TC"
-msgstr "匯入"
+msgstr "匯入S3TC"
#: servers/visual_server.cpp
-#, fuzzy
msgid "Import ETC"
-msgstr "匯入"
+msgstr "匯入ETC"
#: servers/visual_server.cpp
-#, fuzzy
msgid "Import ETC2"
-msgstr "匯入"
+msgstr "匯入ETC2"
#: servers/visual_server.cpp
#, fuzzy
@@ -27990,9 +27471,8 @@ msgid "Lossless Compression"
msgstr ""
#: servers/visual_server.cpp
-#, fuzzy
msgid "Force PNG"
-msgstr "來æºç¶²æ ¼ï¼š"
+msgstr "強制 PNG"
#: servers/visual_server.cpp
msgid "WebP Compression Level"
@@ -28036,7 +27516,7 @@ msgstr "篩é¸ç¯€é»ž"
#: servers/visual_server.cpp
#, fuzzy
msgid "Texture Array Reflections"
-msgstr "置中所é¸"
+msgstr "ç´‹ç†è²¼åœ–陣列åå°„"
#: servers/visual_server.cpp
msgid "High Quality GGX"
@@ -28093,20 +27573,24 @@ msgid "Use Nearest Mipmap Filter"
msgstr ""
#: servers/visual_server.cpp
+#, fuzzy
msgid "Skinning"
-msgstr ""
+msgstr "外觀變更"
#: servers/visual_server.cpp
+#, fuzzy
msgid "Software Skinning Fallback"
-msgstr ""
+msgstr "軟體外觀變更後備"
#: servers/visual_server.cpp
+#, fuzzy
msgid "Force Software Skinning"
-msgstr ""
+msgstr "強制軟體外觀變更"
#: servers/visual_server.cpp
+#, fuzzy
msgid "Use Software Skinning"
-msgstr ""
+msgstr "使用軟體外觀變更"
#: servers/visual_server.cpp
#, fuzzy
@@ -28136,9 +27620,8 @@ msgid "Legacy Stream"
msgstr ""
#: servers/visual_server.cpp
-#, fuzzy
msgid "Batching"
-msgstr "正在æœå°‹..."
+msgstr "分批"
#: servers/visual_server.cpp
msgid "Use Batching"
@@ -28168,7 +27651,7 @@ msgstr ""
#: servers/visual_server.cpp
#, fuzzy
msgid "Max Join Items"
-msgstr "管ç†é …目……"
+msgstr "最大加入項目數"
#: servers/visual_server.cpp
msgid "Batch Buffer Size"
@@ -28224,7 +27707,7 @@ msgstr "使用縮放å¸é™„"
#: servers/visual_server.cpp
msgid "PVS Logging"
-msgstr ""
+msgstr "PVS 日誌"
#: servers/visual_server.cpp
#, fuzzy
@@ -28256,9 +27739,8 @@ msgid "Max Active Polygons"
msgstr "移動多邊形"
#: servers/visual_server.cpp
-#, fuzzy
msgid "Shader Compilation Mode"
-msgstr "æ’值模å¼"
+msgstr "著色器編譯模å¼"
#: servers/visual_server.cpp
msgid "Max Simultaneous Compiles"
@@ -28269,6 +27751,5 @@ msgid "Log Active Async Compiles Count"
msgstr ""
#: servers/visual_server.cpp
-#, fuzzy
msgid "Shader Cache Size (MB)"
-msgstr "更改相機尺寸"
+msgstr "著色器快å–å¤§å° ï¼ˆMB)"
diff --git a/main/main.cpp b/main/main.cpp
index bfb0eacdfc..7d803d901d 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -148,7 +148,7 @@ static bool cmdline_tool = false;
static String locale;
static bool show_help = false;
static bool auto_quit = false;
-static OS::ProcessID allow_focus_steal_pid = 0;
+static OS::ProcessID editor_pid = 0;
#ifdef TOOLS_ENABLED
static bool auto_build_solutions = false;
static String debug_server_uri;
@@ -175,6 +175,7 @@ static Vector2 init_custom_pos;
static bool use_debug_profiler = false;
#ifdef DEBUG_ENABLED
static bool debug_collisions = false;
+static bool debug_paths = false;
static bool debug_navigation = false;
#endif
static int frame_delay = 0;
@@ -357,6 +358,7 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n");
#if defined(DEBUG_ENABLED)
OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n");
+ OS::get_singleton()->print(" --debug-paths Show path lines when running the scene.\n");
OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n");
OS::get_singleton()->print(" --debug-stringnames Print all StringName allocations to stdout when the engine quits.\n");
#endif
@@ -408,6 +410,8 @@ Error Main::test_setup() {
String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues"));
GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2);
+ register_core_settings(); //here globals are present
+
translation_server = memnew(TranslationServer);
tsman = memnew(TextServerManager);
@@ -619,11 +623,18 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
/* argument parsing and main creation */
List<String> args;
List<String> main_args;
+ List<String> platform_args = OS::get_singleton()->get_cmdline_platform_args();
+ // Add command line arguments.
for (int i = 0; i < argc; i++) {
args.push_back(String::utf8(argv[i]));
}
+ // Add arguments received from macOS LaunchService (URL schemas, file associations).
+ for (const String &arg : platform_args) {
+ args.push_back(arg);
+ }
+
List<String>::Element *I = args.front();
while (I) {
@@ -671,9 +682,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
packed_data->add_pack_source(zip_packed_data);
#endif
+ // Default exit code, can be modified for certain errors.
+ Error exit_code = ERR_INVALID_PARAMETER;
+
I = args.front();
while (I) {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
// Ignore the process serial number argument passed by macOS Gatekeeper.
// Otherwise, Godot would try to open a non-existent project on the first start and abort.
if (I->get().begins_with("-psn_")) {
@@ -686,10 +700,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (I->get() == "-h" || I->get() == "--help" || I->get() == "/?") { // display help
show_help = true;
+ exit_code = ERR_HELP; // Hack to force an early exit in `main()` with a success code.
goto error;
} else if (I->get() == "--version") {
print_line(get_full_version_string());
+ exit_code = ERR_HELP; // Hack to force an early exit in `main()` with a success code.
goto error;
} else if (I->get() == "-v" || I->get() == "--verbose") { // verbose output
@@ -1030,10 +1046,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (I->next()) {
String p = I->next()->get();
- if (OS::get_singleton()->set_cwd(p) == OK) {
- //nothing
- } else {
- project_path = I->next()->get(); //use project_path instead
+ if (OS::get_singleton()->set_cwd(p) != OK) {
+ OS::get_singleton()->print("Invalid project path specified: \"%s\", aborting.\n", p.utf8().get_data());
+ goto error;
}
N = I->next()->next();
} else {
@@ -1107,6 +1122,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#if defined(DEBUG_ENABLED)
} else if (I->get() == "--debug-collisions") {
debug_collisions = true;
+ } else if (I->get() == "--debug-paths") {
+ debug_paths = true;
} else if (I->get() == "--debug-navigation") {
debug_navigation = true;
} else if (I->get() == "--debug-stringnames") {
@@ -1125,9 +1142,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->print("Missing remote debug host address, aborting.\n");
goto error;
}
- } else if (I->get() == "--allow_focus_steal_pid") { // not exposed to user
+ } else if (I->get() == "--editor-pid") { // not exposed to user
if (I->next()) {
- allow_focus_steal_pid = I->next()->get().to_int();
+ editor_pid = I->next()->get().to_int();
N = I->next()->next();
} else {
OS::get_singleton()->print("Missing editor PID argument, aborting.\n");
@@ -1257,7 +1274,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
PROPERTY_HINT_RANGE,
"0, 200, 1, or_greater"));
- EngineDebugger::initialize(debug_uri, skip_breakpoints, breakpoints);
+ EngineDebugger::initialize(debug_uri, skip_breakpoints, breakpoints, []() {
+ if (editor_pid) {
+ DisplayServer::get_singleton()->enable_for_stealing_focus(editor_pid);
+ }
+ });
#ifdef TOOLS_ENABLED
if (editor) {
@@ -1451,11 +1472,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
/* Determine audio and video drivers */
// Display driver, e.g. X11, Wayland.
- // print_line("requested display driver : " + display_driver);
+ // Make sure that headless is the last one, which it is assumed to be by design.
+ DEV_ASSERT(String("headless") == DisplayServer::get_create_function_name(DisplayServer::get_create_function_count() - 1));
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
String name = DisplayServer::get_create_function_name(i);
- // print_line("\t" + itos(i) + " : " + name);
-
if (display_driver == name) {
display_driver_idx = i;
break;
@@ -1463,6 +1483,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
if (display_driver_idx < 0) {
+ // If the requested driver wasn't found, pick the first entry.
+ // If all else failed it would be the headless server.
display_driver_idx = 0;
}
@@ -1475,6 +1497,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
audio_driver = GLOBAL_GET("audio/driver/driver");
}
+ // Make sure that dummy is the last one, which it is assumed to be by design.
+ DEV_ASSERT(String("Dummy") == AudioDriverManager::get_driver(AudioDriverManager::get_driver_count() - 1)->get_name());
for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
if (audio_driver == AudioDriverManager::get_driver(i)->get_name()) {
audio_driver_idx = i;
@@ -1483,7 +1507,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
if (audio_driver_idx < 0) {
- audio_driver_idx = 0; // 0 Is always available as the dummy driver (no sound)
+ // If the requested driver wasn't found, pick the first entry.
+ // If all else failed it would be the dummy driver (no sound).
+ audio_driver_idx = 0;
}
if (write_movie_path != String()) {
@@ -1632,7 +1658,7 @@ error:
OS::get_singleton()->finalize_core();
locale = String();
- return ERR_INVALID_PARAMETER;
+ return exit_code;
}
Error Main::setup2(Thread::ID p_main_tid_override) {
@@ -1676,10 +1702,12 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
Error err;
display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
if (err != OK || display_server == nullptr) {
- //ok i guess we can't use this display server, try other ones
- for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
+ // We can't use this display server, try other ones as fallback.
+ // Skip headless (always last registered) because that's not what users
+ // would expect if they didn't request it explicitly.
+ for (int i = 0; i < DisplayServer::get_create_function_count() - 1; i++) {
if (i == display_driver_idx) {
- continue; //don't try the same twice
+ continue; // Don't try the same twice.
}
display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
if (err == OK && display_server != nullptr) {
@@ -1815,10 +1843,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP, true);
}
- if (allow_focus_steal_pid) {
- DisplayServer::get_singleton()->enable_for_stealing_focus(allow_focus_steal_pid);
- }
-
MAIN_PRINT("Main: Load Boot Image");
Color clear = GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3));
@@ -2175,6 +2199,13 @@ bool Main::start() {
#endif
}
+ uint64_t minimum_time_msec = GLOBAL_DEF("application/boot_splash/minimum_display_time", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("application/boot_splash/minimum_display_time",
+ PropertyInfo(Variant::INT,
+ "application/boot_splash/minimum_display_time",
+ PROPERTY_HINT_RANGE,
+ "0,100,1,or_greater,suffix:ms")); // No negative numbers.
+
#ifdef TOOLS_ENABLED
if (!doc_tool_path.is_empty()) {
// Needed to instance editor-only classes for their default values
@@ -2375,6 +2406,9 @@ bool Main::start() {
if (debug_collisions) {
sml->set_debug_collisions_hint(true);
}
+ if (debug_paths) {
+ sml->set_debug_paths_hint(true);
+ }
if (debug_navigation) {
sml->set_debug_navigation_hint(true);
}
@@ -2636,7 +2670,7 @@ bool Main::start() {
ERR_FAIL_COND_V_MSG(!scene, false, "Failed loading scene: " + local_game_path);
sml->add_current_scene(scene);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
String mac_iconpath = GLOBAL_DEF("application/config/macos_native_icon", "Variant()");
if (!mac_iconpath.is_empty()) {
DisplayServer::get_singleton()->set_native_icon(mac_iconpath);
@@ -2692,6 +2726,15 @@ bool Main::start() {
if (movie_writer) {
movie_writer->begin(DisplayServer::get_singleton()->window_get_size(), fixed_fps, write_movie_path);
}
+
+ if (minimum_time_msec) {
+ uint64_t minimum_time = 1000 * minimum_time_msec;
+ uint64_t elapsed_time = OS::get_singleton()->get_ticks_usec();
+ if (elapsed_time < minimum_time) {
+ OS::get_singleton()->delay_usec(minimum_time - elapsed_time);
+ }
+ }
+
return true;
}
diff --git a/methods.py b/methods.py
index b4a55cab79..1db3a8aa01 100644
--- a/methods.py
+++ b/methods.py
@@ -833,15 +833,15 @@ def Run(env, function, short_message, subprocess=True):
def detect_darwin_sdk_path(platform, env):
sdk_name = ""
- if platform == "osx":
+ if platform == "macos":
sdk_name = "macosx"
var_name = "MACOS_SDK_PATH"
- elif platform == "iphone":
+ elif platform == "ios":
sdk_name = "iphoneos"
- var_name = "IPHONESDK"
- elif platform == "iphonesimulator":
+ var_name = "IOS_SDK_PATH"
+ elif platform == "iossimulator":
sdk_name = "iphonesimulator"
- var_name = "IPHONESDK"
+ var_name = "IOS_SDK_PATH"
else:
raise Exception("Invalid platform argument passed to detect_darwin_sdk_path")
diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/Info.plist
index 846533594f..846533594f 100644
--- a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist
+++ b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/Info.plist
diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64/empty
index bd3e894333..bd3e894333 100644
--- a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty
+++ b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64/empty
diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/empty
index bd3e894333..bd3e894333 100644
--- a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty
+++ b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/empty
diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/Info.plist
index 846533594f..846533594f 100644
--- a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist
+++ b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/Info.plist
diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64/empty
index bd3e894333..bd3e894333 100644
--- a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty
+++ b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64/empty
diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/empty
index bd3e894333..bd3e894333 100644
--- a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty
+++ b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/empty
diff --git a/misc/dist/osx/editor.entitlements b/misc/dist/macos/editor.entitlements
index d0137910a3..d0137910a3 100644
--- a/misc/dist/osx/editor.entitlements
+++ b/misc/dist/macos/editor.entitlements
diff --git a/misc/dist/osx_template.app/Contents/Info.plist b/misc/dist/macos_template.app/Contents/Info.plist
index 542146cdb8..542146cdb8 100644
--- a/misc/dist/osx_template.app/Contents/Info.plist
+++ b/misc/dist/macos_template.app/Contents/Info.plist
diff --git a/misc/dist/osx_template.app/Contents/PkgInfo b/misc/dist/macos_template.app/Contents/PkgInfo
index 6f749b0f37..6f749b0f37 100644
--- a/misc/dist/osx_template.app/Contents/PkgInfo
+++ b/misc/dist/macos_template.app/Contents/PkgInfo
diff --git a/misc/dist/osx_template.app/Contents/Resources/icon.icns b/misc/dist/macos_template.app/Contents/Resources/icon.icns
index be9254630c..be9254630c 100644
--- a/misc/dist/osx_template.app/Contents/Resources/icon.icns
+++ b/misc/dist/macos_template.app/Contents/Resources/icon.icns
Binary files differ
diff --git a/misc/dist/osx_tools.app/Contents/Info.plist b/misc/dist/macos_tools.app/Contents/Info.plist
index 886df87cc6..886df87cc6 100644
--- a/misc/dist/osx_tools.app/Contents/Info.plist
+++ b/misc/dist/macos_tools.app/Contents/Info.plist
diff --git a/misc/dist/osx_tools.app/Contents/PkgInfo b/misc/dist/macos_tools.app/Contents/PkgInfo
index 6f749b0f37..6f749b0f37 100644
--- a/misc/dist/osx_tools.app/Contents/PkgInfo
+++ b/misc/dist/macos_tools.app/Contents/PkgInfo
diff --git a/misc/dist/osx_tools.app/Contents/Resources/GDScript.icns b/misc/dist/macos_tools.app/Contents/Resources/GDScript.icns
index b08e8df339..b08e8df339 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/GDScript.icns
+++ b/misc/dist/macos_tools.app/Contents/Resources/GDScript.icns
Binary files differ
diff --git a/misc/dist/osx_tools.app/Contents/Resources/Godot.icns b/misc/dist/macos_tools.app/Contents/Resources/Godot.icns
index 61697976c6..61697976c6 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/Godot.icns
+++ b/misc/dist/macos_tools.app/Contents/Resources/Godot.icns
Binary files differ
diff --git a/misc/dist/osx_tools.app/Contents/Resources/Project.icns b/misc/dist/macos_tools.app/Contents/Resources/Project.icns
index 10e31528e4..10e31528e4 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/Project.icns
+++ b/misc/dist/macos_tools.app/Contents/Resources/Project.icns
Binary files differ
diff --git a/misc/dist/osx_tools.app/Contents/Resources/Resource.icns b/misc/dist/macos_tools.app/Contents/Resources/Resource.icns
index 9648cb616e..9648cb616e 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/Resource.icns
+++ b/misc/dist/macos_tools.app/Contents/Resources/Resource.icns
Binary files differ
diff --git a/misc/dist/osx_tools.app/Contents/Resources/Scene.icns b/misc/dist/macos_tools.app/Contents/Resources/Scene.icns
index c8c3dee07e..c8c3dee07e 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/Scene.icns
+++ b/misc/dist/macos_tools.app/Contents/Resources/Scene.icns
Binary files differ
diff --git a/misc/dist/osx_tools.app/Contents/Resources/Shader.icns b/misc/dist/macos_tools.app/Contents/Resources/Shader.icns
index a76e648a1a..a76e648a1a 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/Shader.icns
+++ b/misc/dist/macos_tools.app/Contents/Resources/Shader.icns
Binary files differ
diff --git a/misc/dist/osx_tools.app/Contents/Resources/af.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/af.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/af.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/af.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/az.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/az.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/az.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/az.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/br.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/br.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/br.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/br.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/da.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/da.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/da.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/da.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/de.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/de.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/de.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/de.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/el.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/el.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/el.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/el.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/en.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/en.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/en.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/en.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/es.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/es.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/es.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/es.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/et.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/et.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/et.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/et.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/he.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/he.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/he.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/he.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/id.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/id.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/id.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/id.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/is.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/is.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/is.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/is.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/it.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/it.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/it.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/it.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/km.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/km.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/km.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/km.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/or.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/or.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/or.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/or.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/si.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/si.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/si.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/si.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/te.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/te.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/te.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/te.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/th.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/th.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/th.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/th.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings
index e69de29bb2..e69de29bb2 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings
+++ b/misc/dist/macos_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings
diff --git a/misc/dist/osx_template.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json b/misc/dist/osx_template.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json
deleted file mode 100644
index c4f8f71d0e..0000000000
--- a/misc/dist/osx_template.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "file_format_version" : "1.0.0",
- "ICD": {
- "library_path": "../../../Frameworks/libMoltenVK.dylib",
- "api_version" : "1.1.0"
- }
-}
diff --git a/misc/dist/osx_tools.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json b/misc/dist/osx_tools.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json
deleted file mode 100644
index c4f8f71d0e..0000000000
--- a/misc/dist/osx_tools.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "file_format_version" : "1.0.0",
- "ICD": {
- "library_path": "../../../Frameworks/libMoltenVK.dylib",
- "api_version" : "1.1.0"
- }
-}
diff --git a/misc/scripts/install_vulkan_sdk_macos.sh b/misc/scripts/install_vulkan_sdk_macos.sh
new file mode 100755
index 0000000000..817302d77f
--- /dev/null
+++ b/misc/scripts/install_vulkan_sdk_macos.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+IFS=$'\n\t'
+
+# Download and install the Vulkan SDK.
+curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan-sdk.dmg" -o /tmp/vulkan-sdk.dmg
+hdiutil attach /tmp/vulkan-sdk.dmg -mountpoint /Volumes/vulkan-sdk
+/Volumes/vulkan-sdk/InstallVulkan.app/Contents/MacOS/InstallVulkan \
+ --accept-licenses --default-answer --confirm-command install
+hdiutil detach /Volumes/vulkan-sdk
+rm -f /tmp/vulkan-sdk.dmg
+
+echo 'Vulkan SDK installed successfully! You can now build Godot by running "scons".'
diff --git a/modules/camera/SCsub b/modules/camera/SCsub
index de97724d09..9a6147d433 100644
--- a/modules/camera/SCsub
+++ b/modules/camera/SCsub
@@ -9,6 +9,6 @@ if env["platform"] == "windows":
env_camera.add_source_files(env.modules_sources, "register_types.cpp")
env_camera.add_source_files(env.modules_sources, "camera_win.cpp")
-elif env["platform"] == "osx":
+elif env["platform"] == "macos":
env_camera.add_source_files(env.modules_sources, "register_types.cpp")
- env_camera.add_source_files(env.modules_sources, "camera_osx.mm")
+ env_camera.add_source_files(env.modules_sources, "camera_macos.mm")
diff --git a/modules/camera/camera_osx.h b/modules/camera/camera_macos.h
index b0db844599..badf78f0e8 100644
--- a/modules/camera/camera_osx.h
+++ b/modules/camera/camera_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* camera_osx.h */
+/* camera_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,19 +28,19 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CAMERAOSX_H
-#define CAMERAOSX_H
+#ifndef CAMERA_MACOS_H
+#define CAMERA_MACOS_H
///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimize code duplication!!!!
// If you fix something here, make sure you fix it there as well!
#include "servers/camera_server.h"
-class CameraOSX : public CameraServer {
+class CameraMacOS : public CameraServer {
public:
- CameraOSX();
+ CameraMacOS();
void update_feeds();
};
-#endif /* CAMERAOSX_H */
+#endif /* CAMERA_MACOS_H */
diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_macos.mm
index d199c31b2f..0b9696a3e9 100644
--- a/modules/camera/camera_osx.mm
+++ b/modules/camera/camera_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* camera_osx.mm */
+/* camera_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -31,7 +31,7 @@
///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimize code duplication!!!!
// If you fix something here, make sure you fix it there as well!
-#include "camera_osx.h"
+#include "camera_macos.h"
#include "servers/camera/camera_feed.h"
#import <AVFoundation/AVFoundation.h>
@@ -191,9 +191,9 @@
@end
//////////////////////////////////////////////////////////////////////////
-// CameraFeedOSX - Subclass for camera feeds in OSX
+// CameraFeedMacOS - Subclass for camera feeds in macOS
-class CameraFeedOSX : public CameraFeed {
+class CameraFeedMacOS : public CameraFeed {
private:
AVCaptureDevice *device;
MyCaptureSession *capture_session;
@@ -201,7 +201,7 @@ private:
public:
AVCaptureDevice *get_device() const;
- CameraFeedOSX();
+ CameraFeedMacOS();
void set_device(AVCaptureDevice *p_device);
@@ -209,16 +209,16 @@ public:
void deactivate_feed();
};
-AVCaptureDevice *CameraFeedOSX::get_device() const {
+AVCaptureDevice *CameraFeedMacOS::get_device() const {
return device;
};
-CameraFeedOSX::CameraFeedOSX() {
+CameraFeedMacOS::CameraFeedMacOS() {
device = nullptr;
capture_session = nullptr;
};
-void CameraFeedOSX::set_device(AVCaptureDevice *p_device) {
+void CameraFeedMacOS::set_device(AVCaptureDevice *p_device) {
device = p_device;
// get some info
@@ -232,7 +232,7 @@ void CameraFeedOSX::set_device(AVCaptureDevice *p_device) {
};
};
-bool CameraFeedOSX::activate_feed() {
+bool CameraFeedMacOS::activate_feed() {
if (capture_session) {
// Already recording!
} else {
@@ -258,7 +258,7 @@ bool CameraFeedOSX::activate_feed() {
return true;
};
-void CameraFeedOSX::deactivate_feed() {
+void CameraFeedMacOS::deactivate_feed() {
// end camera capture if we have one
if (capture_session) {
[capture_session cleanup];
@@ -271,7 +271,7 @@ void CameraFeedOSX::deactivate_feed() {
// when devices are connected/disconnected
@interface MyDeviceNotifications : NSObject {
- CameraOSX *camera_server;
+ CameraMacOS *camera_server;
}
@end
@@ -282,7 +282,7 @@ void CameraFeedOSX::deactivate_feed() {
camera_server->update_feeds();
}
-- (id)initForServer:(CameraOSX *)p_server {
+- (id)initForServer:(CameraMacOS *)p_server {
if (self = [super init]) {
camera_server = p_server;
@@ -303,9 +303,9 @@ void CameraFeedOSX::deactivate_feed() {
MyDeviceNotifications *device_notifications = nil;
//////////////////////////////////////////////////////////////////////////
-// CameraOSX - Subclass for our camera server on OSX
+// CameraMacOS - Subclass for our camera server on macOS
-void CameraOSX::update_feeds() {
+void CameraMacOS::update_feeds() {
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101500
AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:[NSArray arrayWithObjects:AVCaptureDeviceTypeExternalUnknown, AVCaptureDeviceTypeBuiltInWideAngleCamera, nil] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified];
NSArray *devices = session.devices;
@@ -315,7 +315,7 @@ void CameraOSX::update_feeds() {
// remove devices that are gone..
for (int i = feeds.size() - 1; i >= 0; i--) {
- Ref<CameraFeedOSX> feed = (Ref<CameraFeedOSX>)feeds[i];
+ Ref<CameraFeedMacOS> feed = (Ref<CameraFeedMacOS>)feeds[i];
if (![devices containsObject:feed->get_device()]) {
// remove it from our array, this will also destroy it ;)
@@ -326,14 +326,14 @@ void CameraOSX::update_feeds() {
for (AVCaptureDevice *device in devices) {
bool found = false;
for (int i = 0; i < feeds.size() && !found; i++) {
- Ref<CameraFeedOSX> feed = (Ref<CameraFeedOSX>)feeds[i];
+ Ref<CameraFeedMacOS> feed = (Ref<CameraFeedMacOS>)feeds[i];
if (feed->get_device() == device) {
found = true;
};
};
if (!found) {
- Ref<CameraFeedOSX> newfeed;
+ Ref<CameraFeedMacOS> newfeed;
newfeed.instantiate();
newfeed->set_device(device);
@@ -346,7 +346,7 @@ void CameraOSX::update_feeds() {
};
};
-CameraOSX::CameraOSX() {
+CameraMacOS::CameraMacOS() {
// Find available cameras we have at this time
update_feeds();
diff --git a/modules/camera/config.py b/modules/camera/config.py
index 8a22751aa7..d2b2542dd9 100644
--- a/modules/camera/config.py
+++ b/modules/camera/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return platform == "osx" or platform == "windows"
+ return platform == "macos" or platform == "windows"
def configure(env):
diff --git a/modules/camera/register_types.cpp b/modules/camera/register_types.cpp
index 98a4b5ca1a..40e2224d6b 100644
--- a/modules/camera/register_types.cpp
+++ b/modules/camera/register_types.cpp
@@ -33,8 +33,8 @@
#if defined(WINDOWS_ENABLED)
#include "camera_win.h"
#endif
-#if defined(OSX_ENABLED)
-#include "camera_osx.h"
+#if defined(MACOS_ENABLED)
+#include "camera_macos.h"
#endif
void initialize_camera_module(ModuleInitializationLevel p_level) {
@@ -45,8 +45,8 @@ void initialize_camera_module(ModuleInitializationLevel p_level) {
#if defined(WINDOWS_ENABLED)
CameraServer::make_default<CameraWindows>();
#endif
-#if defined(OSX_ENABLED)
- CameraServer::make_default<CameraOSX>();
+#if defined(MACOS_ENABLED)
+ CameraServer::make_default<CameraMacOS>();
#endif
}
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index 2c0e604e66..eb5614338b 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -409,9 +409,7 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig
}
Ref<Image> img = memnew(Image(width, height, mipmaps - 1, info.format, src_data));
-
- Ref<ImageTexture> texture = memnew(ImageTexture);
- texture->create_from_image(img);
+ Ref<ImageTexture> texture = ImageTexture::create_from_image(img);
if (r_error) {
*r_error = OK;
diff --git a/modules/denoise/config.py b/modules/denoise/config.py
index 3aa840acb0..521115dae5 100644
--- a/modules/denoise/config.py
+++ b/modules/denoise/config.py
@@ -4,7 +4,7 @@ def can_build(env, platform):
# It's also only relevant for tools build and desktop platforms,
# as doing lightmap generation and denoising on Android or HTML5
# would be a bit far-fetched.
- desktop_platforms = ["linuxbsd", "osx", "windows"]
+ desktop_platforms = ["linuxbsd", "macos", "windows"]
supported_arch = env["bits"] == "64"
if env["arch"] == "arm64":
supported_arch = False
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 70151c4d21..10cf783e73 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -144,6 +144,7 @@
[/codeblock]
[b]Important:[/b] The path must be absolute, a local path will just return [code]null[/code].
This method is a simplified version of [method ResourceLoader.load], which can be used for more advanced scenarios.
+ [b]Note:[/b] You have to import the files into the engine first to load them using [method load]. If you want to load [Image]s at run-time, you may use [method Image.load]. If you want to import audio files, you can use the snippet described in [member AudioStreamMP3.data].
</description>
</method>
<method name="preload">
@@ -257,4 +258,162 @@
[b]Note:[/b] "Not a Number" is only a concept with floating-point numbers, and has no equivalent for integers. Dividing an integer [code]0[/code] by [code]0[/code] will not result in [constant NAN] and will result in a run-time error instead.
</constant>
</constants>
+ <annotations>
+ <annotation name="@export">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_category">
+ <return type="void" />
+ <argument index="0" name="name" type="String" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_color_no_alpha">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_dir">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_enum" qualifiers="vararg">
+ <return type="void" />
+ <argument index="0" name="names" type="String" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_exp_easing" qualifiers="vararg">
+ <return type="void" />
+ <argument index="0" name="hints" type="String" default="&quot;&quot;" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_file" qualifiers="vararg">
+ <return type="void" />
+ <argument index="0" name="filter" type="String" default="&quot;&quot;" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_flags" qualifiers="vararg">
+ <return type="void" />
+ <argument index="0" name="names" type="String" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_flags_2d_navigation">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_flags_2d_physics">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_flags_2d_render">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_flags_3d_navigation">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_flags_3d_physics">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_flags_3d_render">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_global_dir">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_global_file" qualifiers="vararg">
+ <return type="void" />
+ <argument index="0" name="filter" type="String" default="&quot;&quot;" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_group">
+ <return type="void" />
+ <argument index="0" name="name" type="String" />
+ <argument index="1" name="prefix" type="String" default="&quot;&quot;" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_multiline">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_node_path" qualifiers="vararg">
+ <return type="void" />
+ <argument index="0" name="type" type="String" default="&quot;&quot;" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_placeholder">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_range" qualifiers="vararg">
+ <return type="void" />
+ <argument index="0" name="min" type="float" />
+ <argument index="1" name="max" type="float" />
+ <argument index="2" name="step" type="float" default="1.0" />
+ <argument index="3" name="extra_hints" type="String" default="&quot;&quot;" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@export_subgroup">
+ <return type="void" />
+ <argument index="0" name="name" type="String" />
+ <argument index="1" name="prefix" type="String" default="&quot;&quot;" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@icon">
+ <return type="void" />
+ <argument index="0" name="icon_path" type="String" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@onready">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@rpc" qualifiers="vararg">
+ <return type="void" />
+ <argument index="0" name="mode" type="String" default="&quot;&quot;" />
+ <argument index="1" name="sync" type="String" default="&quot;&quot;" />
+ <argument index="2" name="transfer_mode" type="String" default="&quot;&quot;" />
+ <argument index="3" name="transfer_channel" type="int" default="0" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@tool">
+ <return type="void" />
+ <description>
+ </description>
+ </annotation>
+ <annotation name="@warning_ignore" qualifiers="vararg">
+ <return type="void" />
+ <argument index="0" name="warning" type="String" />
+ <description>
+ </description>
+ </annotation>
+ </annotations>
</class>
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index b86e9b386d..4372bb33ba 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -55,7 +55,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
bool in_function_args = false;
bool in_member_variable = false;
bool in_node_path = false;
+ bool in_node_ref = false;
bool in_annotation = false;
+ bool in_string_name = false;
bool is_hex_notation = false;
bool is_bin_notation = false;
bool expect_type = false;
@@ -165,6 +167,12 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
if (in_node_path && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
region_color = node_path_color;
}
+ if (in_node_ref && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
+ region_color = node_ref_color;
+ }
+ if (in_string_name && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
+ region_color = string_name_color;
+ }
prev_color = region_color;
highlighter_info["color"] = region_color;
@@ -387,24 +395,42 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
in_member_variable = false;
}
- if (!in_node_path && in_region == -1 && (str[j] == '$' || str[j] == '%')) {
+ if (!in_node_path && in_region == -1 && (str[j] == '^')) {
in_node_path = true;
} else if (in_region != -1 || (is_a_symbol && str[j] != '/' && str[j] != '%')) {
in_node_path = false;
}
+ if (!in_node_ref && in_region == -1 && (str[j] == '$' || str[j] == '%')) {
+ in_node_ref = true;
+ } else if (in_region != -1 || (is_a_symbol && str[j] != '/' && str[j] != '%')) {
+ in_node_ref = false;
+ }
+
if (!in_annotation && in_region == -1 && str[j] == '@') {
in_annotation = true;
} else if (in_region != -1 || is_a_symbol) {
in_annotation = false;
}
+ if (!in_string_name && in_region == -1 && str[j] == '&') {
+ in_string_name = true;
+ } else if (in_region != -1 || is_a_symbol) {
+ in_string_name = false;
+ }
+
if (in_node_path) {
next_type = NODE_PATH;
color = node_path_color;
+ } else if (in_node_ref) {
+ next_type = NODE_REF;
+ color = node_ref_color;
} else if (in_annotation) {
next_type = ANNOTATION;
color = annotation_color;
+ } else if (in_string_name) {
+ next_type = STRING_NAME;
+ color = string_name_color;
} else if (in_keyword) {
next_type = KEYWORD;
color = keyword_color;
@@ -592,17 +618,23 @@ void GDScriptSyntaxHighlighter::_update_cache() {
if (godot_2_theme || EditorSettings::get_singleton()->is_dark_theme()) {
function_definition_color = Color(0.4, 0.9, 1.0);
- node_path_color = Color(0.39, 0.76, 0.35);
+ node_path_color = Color(0.72, 0.77, 0.49);
+ node_ref_color = Color(0.39, 0.76, 0.35);
annotation_color = Color(1.0, 0.7, 0.45);
+ string_name_color = Color(1.0, 0.66, 0.72);
} else {
function_definition_color = Color(0.0, 0.65, 0.73);
- node_path_color = Color(0.32, 0.55, 0.29);
+ node_path_color = Color(0.62, 0.67, 0.39);
+ node_ref_color = Color(0.32, 0.55, 0.29);
annotation_color = Color(0.8, 0.5, 0.25);
+ string_name_color = Color(0.9, 0.56, 0.62);
}
EDITOR_DEF("text_editor/theme/highlighting/gdscript/function_definition_color", function_definition_color);
EDITOR_DEF("text_editor/theme/highlighting/gdscript/node_path_color", node_path_color);
+ EDITOR_DEF("text_editor/theme/highlighting/gdscript/node_reference_color", node_ref_color);
EDITOR_DEF("text_editor/theme/highlighting/gdscript/annotation_color", annotation_color);
+ EDITOR_DEF("text_editor/theme/highlighting/gdscript/string_name_color", string_name_color);
if (text_edit_color_theme == "Default" || godot_2_theme) {
EditorSettings::get_singleton()->set_initial_value(
"text_editor/theme/highlighting/gdscript/function_definition_color",
@@ -613,14 +645,24 @@ void GDScriptSyntaxHighlighter::_update_cache() {
node_path_color,
true);
EditorSettings::get_singleton()->set_initial_value(
+ "text_editor/theme/highlighting/gdscript/node_reference_color",
+ node_ref_color,
+ true);
+ EditorSettings::get_singleton()->set_initial_value(
"text_editor/theme/highlighting/gdscript/annotation_color",
annotation_color,
true);
+ EditorSettings::get_singleton()->set_initial_value(
+ "text_editor/theme/highlighting/gdscript/string_name_color",
+ string_name_color,
+ true);
}
function_definition_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/function_definition_color");
node_path_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/node_path_color");
+ node_ref_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/node_reference_color");
annotation_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/annotation_color");
+ string_name_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/string_name_color");
type_color = EDITOR_GET("text_editor/theme/highlighting/base_type_color");
}
diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h
index 92764e3891..7987582f07 100644
--- a/modules/gdscript/editor/gdscript_highlighter.h
+++ b/modules/gdscript/editor/gdscript_highlighter.h
@@ -54,7 +54,9 @@ private:
NONE,
REGION,
NODE_PATH,
+ NODE_REF,
ANNOTATION,
+ STRING_NAME,
SYMBOL,
NUMBER,
FUNCTION,
@@ -74,7 +76,9 @@ private:
Color number_color;
Color member_color;
Color node_path_color;
+ Color node_ref_color;
Color annotation_color;
+ Color string_name_color;
Color type_color;
void add_color_region(const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only = false);
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index e6aeef2fd1..964c1133ff 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -536,6 +536,9 @@ void GDScript::_update_doc() {
List<PropertyInfo> props;
_get_script_property_list(&props, false);
for (int i = 0; i < props.size(); i++) {
+ if (props[i].usage & PROPERTY_USAGE_CATEGORY || props[i].usage & PROPERTY_USAGE_GROUP || props[i].usage & PROPERTY_USAGE_SUBGROUP) {
+ continue;
+ }
ScriptMemberInfo scr_member_info;
scr_member_info.propinfo = props[i];
scr_member_info.propinfo.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
@@ -867,7 +870,7 @@ Error GDScript::reload(bool p_keep_state) {
}
// TODO: Show all error messages.
_err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT);
- ERR_FAIL_V(ERR_PARSE_ERROR);
+ return ERR_PARSE_ERROR;
}
GDScriptAnalyzer analyzer(&parser);
@@ -883,7 +886,7 @@ Error GDScript::reload(bool p_keep_state) {
_err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT);
e = e->next();
}
- ERR_FAIL_V(ERR_PARSE_ERROR);
+ return ERR_PARSE_ERROR;
}
bool can_run = ScriptServer::is_scripting_enabled() || parser.is_tool();
@@ -901,7 +904,7 @@ Error GDScript::reload(bool p_keep_state) {
GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error());
}
_err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), false, ERR_HANDLER_SCRIPT);
- ERR_FAIL_V(ERR_COMPILATION_FAILED);
+ return ERR_COMPILATION_FAILED;
} else {
return err;
}
@@ -1050,7 +1053,7 @@ Error GDScript::load_source_code(const String &p_path) {
w[len] = 0;
String s;
- if (s.parse_utf8((const char *)w)) {
+ if (s.parse_utf8((const char *)w) != OK) {
ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
}
@@ -1524,7 +1527,6 @@ void GDScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
for (const KeyValue<StringName, GDScriptFunction *> &E : sptr->member_functions) {
MethodInfo mi;
mi.name = E.key;
- mi.flags |= METHOD_FLAG_FROM_SCRIPT;
for (int i = 0; i < E.value->get_argument_count(); i++) {
mi.arguments.push_back(PropertyInfo(Variant::NIL, "arg" + itos(i)));
}
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index feb0a237df..e9a206f48b 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -489,6 +489,7 @@ public:
virtual void get_public_functions(List<MethodInfo> *p_functions) const override;
virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const override;
+ virtual void get_public_annotations(List<MethodInfo> *p_annotations) const override;
virtual void profiling_start() override;
virtual void profiling_stop() override;
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index ea994654bf..8b4c245bf6 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -655,43 +655,43 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
} else {
ERR_PRINT("Parser bug (please report): tried to assign unset node without an identifier.");
}
- } else {
- if (member.variable->datatype_specifier != nullptr) {
- datatype = specified_type;
+ }
- if (member.variable->initializer != nullptr) {
- if (!is_type_compatible(datatype, member.variable->initializer->get_datatype(), true, member.variable->initializer)) {
- // Try reverse test since it can be a masked subtype.
- if (!is_type_compatible(member.variable->initializer->get_datatype(), datatype, true, member.variable->initializer)) {
- push_error(vformat(R"(Value of type "%s" cannot be assigned to a variable of type "%s".)", member.variable->initializer->get_datatype().to_string(), datatype.to_string()), member.variable->initializer);
- } else {
- // TODO: Add warning.
- mark_node_unsafe(member.variable->initializer);
- member.variable->use_conversion_assign = true;
- }
- } else if (datatype.builtin_type == Variant::INT && member.variable->initializer->get_datatype().builtin_type == Variant::FLOAT) {
-#ifdef DEBUG_ENABLED
- parser->push_warning(member.variable->initializer, GDScriptWarning::NARROWING_CONVERSION);
-#endif
- }
- if (member.variable->initializer->get_datatype().is_variant()) {
- // TODO: Warn unsafe assign.
+ if (member.variable->datatype_specifier != nullptr) {
+ datatype = specified_type;
+
+ if (member.variable->initializer != nullptr) {
+ if (!is_type_compatible(datatype, member.variable->initializer->get_datatype(), true, member.variable->initializer)) {
+ // Try reverse test since it can be a masked subtype.
+ if (!is_type_compatible(member.variable->initializer->get_datatype(), datatype, true, member.variable->initializer)) {
+ push_error(vformat(R"(Value of type "%s" cannot be assigned to a variable of type "%s".)", member.variable->initializer->get_datatype().to_string(), datatype.to_string()), member.variable->initializer);
+ } else {
+ // TODO: Add warning.
mark_node_unsafe(member.variable->initializer);
member.variable->use_conversion_assign = true;
}
+ } else if (datatype.builtin_type == Variant::INT && member.variable->initializer->get_datatype().builtin_type == Variant::FLOAT) {
+#ifdef DEBUG_ENABLED
+ parser->push_warning(member.variable->initializer, GDScriptWarning::NARROWING_CONVERSION);
+#endif
}
- } else if (member.variable->infer_datatype) {
- if (member.variable->initializer == nullptr) {
- push_error(vformat(R"(Cannot infer the type of "%s" variable because there's no default value.)", member.variable->identifier->name), member.variable->identifier);
- } else if (!datatype.is_set() || datatype.has_no_type()) {
- push_error(vformat(R"(Cannot infer the type of "%s" variable because the initial value doesn't have a set type.)", member.variable->identifier->name), member.variable->initializer);
- } else if (datatype.is_variant()) {
- push_error(vformat(R"(Cannot infer the type of "%s" variable because the initial value is Variant. Use explicit "Variant" type if this is intended.)", member.variable->identifier->name), member.variable->initializer);
- } else if (datatype.builtin_type == Variant::NIL) {
- push_error(vformat(R"(Cannot infer the type of "%s" variable because the initial value is "null".)", member.variable->identifier->name), member.variable->initializer);
+ if (member.variable->initializer->get_datatype().is_variant()) {
+ // TODO: Warn unsafe assign.
+ mark_node_unsafe(member.variable->initializer);
+ member.variable->use_conversion_assign = true;
}
- datatype.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
}
+ } else if (member.variable->infer_datatype) {
+ if (member.variable->initializer == nullptr) {
+ push_error(vformat(R"(Cannot infer the type of "%s" variable because there's no default value.)", member.variable->identifier->name), member.variable->identifier);
+ } else if (!datatype.is_set() || datatype.has_no_type()) {
+ push_error(vformat(R"(Cannot infer the type of "%s" variable because the initial value doesn't have a set type.)", member.variable->identifier->name), member.variable->initializer);
+ } else if (datatype.is_variant()) {
+ push_error(vformat(R"(Cannot infer the type of "%s" variable because the initial value is Variant. Use explicit "Variant" type if this is intended.)", member.variable->identifier->name), member.variable->initializer);
+ } else if (datatype.builtin_type == Variant::NIL) {
+ push_error(vformat(R"(Cannot infer the type of "%s" variable because the initial value is "null".)", member.variable->identifier->name), member.variable->initializer);
+ }
+ datatype.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
}
datatype.is_constant = false;
@@ -860,6 +860,9 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
case GDScriptParser::ClassNode::Member::CLASS:
check_class_member_name_conflict(p_class, member.m_class->identifier->name, member.m_class);
break;
+ case GDScriptParser::ClassNode::Member::GROUP:
+ // No-op, but needed to silence warnings.
+ break;
case GDScriptParser::ClassNode::Member::UNDEFINED:
ERR_PRINT("Trying to resolve undefined member.");
break;
diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp
index 4c15fca91e..48d5fbc569 100644
--- a/modules/gdscript/gdscript_cache.cpp
+++ b/modules/gdscript/gdscript_cache.cpp
@@ -157,7 +157,7 @@ String GDScriptCache::get_source_code(const String &p_path) {
source_file.write[len] = 0;
String source;
- if (source.parse_utf8((const char *)source_file.ptr())) {
+ if (source.parse_utf8((const char *)source_file.ptr()) != OK) {
ERR_FAIL_V_MSG("", "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
}
return source;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 1daf8ff7a9..e36252ada5 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -43,7 +43,7 @@ bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringN
return false;
}
- if (codegen.locals.has(p_name)) {
+ if (codegen.parameters.has(p_name) || codegen.locals.has(p_name)) {
return false; //shadowed
}
@@ -1059,22 +1059,22 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
bool known_type = assigned.type.has_type;
bool is_shared = Variant::is_type_shared(assigned.type.builtin_type);
- if (!known_type) {
- // Jump shared values since they are already updated in-place.
- gen->write_jump_if_shared(assigned);
- }
- if (known_type && !is_shared) {
+ if (!known_type || !is_shared) {
+ if (!known_type) {
+ // Jump shared values since they are already updated in-place.
+ gen->write_jump_if_shared(assigned);
+ }
if (!info.is_named) {
gen->write_set(info.base, info.key, assigned);
- if (info.key.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
- gen->pop_temporary();
- }
} else {
gen->write_set_named(info.base, info.name, assigned);
}
+ if (!known_type) {
+ gen->write_end_jump_if_shared();
+ }
}
- if (!known_type) {
- gen->write_end_jump_if_shared();
+ if (!info.is_named && info.key.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
gen->pop_temporary();
@@ -2452,6 +2452,25 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
}
#endif
} break;
+
+ case GDScriptParser::ClassNode::Member::GROUP: {
+ const GDScriptParser::AnnotationNode *annotation = member.annotation;
+ StringName name = annotation->export_info.name;
+
+ // This is not a normal member, but we need this to keep indices in order.
+ GDScript::MemberInfo minfo;
+ minfo.index = p_script->member_indices.size();
+
+ PropertyInfo prop_info;
+ prop_info.name = name;
+ prop_info.usage = annotation->export_info.usage;
+ prop_info.hint_string = annotation->export_info.hint_string;
+
+ p_script->member_info[name] = prop_info;
+ p_script->member_indices[name] = minfo;
+ p_script->members.insert(name);
+ } break;
+
default:
break; // Nothing to do here.
}
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 474c8094f2..90dcfa307e 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -445,6 +445,16 @@ void GDScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_const
p_constants->push_back(nan);
}
+void GDScriptLanguage::get_public_annotations(List<MethodInfo> *p_annotations) const {
+ GDScriptParser parser;
+ List<MethodInfo> annotations;
+ parser.get_annotation_list(&annotations);
+
+ for (const MethodInfo &E : annotations) {
+ p_annotations->push_back(E);
+ }
+}
+
String GDScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const {
#ifdef TOOLS_ENABLED
bool th = EditorSettings::get_singleton()->get_setting("text_editor/completion/add_type_hints");
@@ -569,7 +579,7 @@ static int _get_enum_constant_location(StringName p_class, StringName p_enum_con
// END LOCATION METHODS
static String _get_visual_datatype(const PropertyInfo &p_info, bool p_is_arg = true) {
- if (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (p_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
String enum_name = p_info.class_name;
if (!enum_name.contains(".")) {
return enum_name;
@@ -950,6 +960,8 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class,
}
option = ScriptLanguage::CodeCompletionOption(member.signal->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_SIGNAL, location);
break;
+ case GDScriptParser::ClassNode::Member::GROUP:
+ break; // No-op, but silences warnings.
case GDScriptParser::ClassNode::Member::UNDEFINED:
break;
}
@@ -1292,7 +1304,7 @@ static GDScriptCompletionIdentifier _type_from_property(const PropertyInfo &p_pr
return ci;
}
- if (p_property.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (p_property.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
ci.enumeration = p_property.class_name;
}
@@ -1843,7 +1855,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
while (suite) {
for (int i = 0; i < suite->statements.size(); i++) {
- if (suite->statements[i]->start_line > p_context.current_line) {
+ if (suite->statements[i]->end_line >= p_context.current_line) {
break;
}
@@ -1891,7 +1903,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
suite = suite->parent_block;
}
- if (last_assigned_expression && last_assign_line != p_context.current_line) {
+ if (last_assigned_expression && last_assign_line < p_context.current_line) {
GDScriptParser::CompletionContext c = p_context;
c.current_line = last_assign_line;
r_type.assigned_expression = last_assigned_expression;
@@ -1992,8 +2004,8 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
return false;
}
- // Check autoloads.
- if (ProjectSettings::get_singleton()->has_autoload(p_identifier)) {
+ // Check global variables (including autoloads).
+ if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(p_identifier)) {
r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[p_identifier]);
return true;
}
@@ -2028,7 +2040,10 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
return true;
case GDScriptParser::ClassNode::Member::VARIABLE:
if (!is_static) {
- if (member.variable->initializer) {
+ if (member.variable->get_datatype().is_set() && !member.variable->get_datatype().is_variant()) {
+ r_type.type = member.variable->get_datatype();
+ return true;
+ } else if (member.variable->initializer) {
const GDScriptParser::ExpressionNode *init = member.variable->initializer;
if (init->is_constant) {
r_type.value = init->reduced_value;
@@ -2050,9 +2065,6 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
r_type.type = init->get_datatype();
return true;
}
- } else if (member.variable->get_datatype().is_set() && !member.variable->get_datatype().is_variant()) {
- r_type.type = member.variable->get_datatype();
- return true;
}
}
// TODO: Check assignments in constructor.
@@ -2082,6 +2094,8 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
r_type.type.kind = GDScriptParser::DataType::CLASS;
r_type.type.class_type = member.m_class;
return true;
+ case GDScriptParser::ClassNode::Member::GROUP:
+ return false; // No-op, but silences warnings.
case GDScriptParser::ClassNode::Member::UNDEFINED:
return false; // Unreachable.
}
@@ -2407,7 +2421,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
if (p_argidx < method_args) {
PropertyInfo arg_info = info.arguments[p_argidx];
- if (arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
_find_enumeration_candidates(p_context, arg_info.class_name, r_result);
}
}
@@ -3376,6 +3390,15 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
return OK;
}
} break;
+ case GDScriptParser::COMPLETION_ANNOTATION: {
+ const String annotation_symbol = "@" + p_symbol;
+ if (parser.annotation_exists(annotation_symbol)) {
+ r_result.type = ScriptLanguage::LOOKUP_RESULT_CLASS_ANNOTATION;
+ r_result.class_name = "@GDScript";
+ r_result.class_member = annotation_symbol;
+ return OK;
+ }
+ } break;
default: {
}
}
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 9e347eed5a..01a672c330 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -105,6 +105,10 @@ void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const
}
}
+bool GDScriptParser::annotation_exists(const String &p_annotation_name) const {
+ return valid_annotations.has(p_annotation_name);
+}
+
GDScriptParser::GDScriptParser() {
// Register valid annotations.
// TODO: Should this be static?
@@ -113,27 +117,32 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@onready"), AnnotationInfo::VARIABLE, &GDScriptParser::onready_annotation);
// Export annotations.
register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NONE, Variant::NIL>);
- register_annotation(MethodInfo("@export_enum", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_ENUM, Variant::INT>, 0, true);
- register_annotation(MethodInfo("@export_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FILE, Variant::STRING>, 1, true);
+ register_annotation(MethodInfo("@export_enum", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_ENUM, Variant::INT>, varray(), true);
+ register_annotation(MethodInfo("@export_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FILE, Variant::STRING>, varray(""), true);
register_annotation(MethodInfo("@export_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_DIR, Variant::STRING>);
- register_annotation(MethodInfo("@export_global_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_GLOBAL_FILE, Variant::STRING>, 1, true);
+ register_annotation(MethodInfo("@export_global_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_GLOBAL_FILE, Variant::STRING>, varray(""), true);
register_annotation(MethodInfo("@export_global_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_GLOBAL_DIR, Variant::STRING>);
register_annotation(MethodInfo("@export_multiline"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_MULTILINE_TEXT, Variant::STRING>);
register_annotation(MethodInfo("@export_placeholder"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_PLACEHOLDER_TEXT, Variant::STRING>);
- register_annotation(MethodInfo("@export_range", PropertyInfo(Variant::FLOAT, "min"), PropertyInfo(Variant::FLOAT, "max"), PropertyInfo(Variant::FLOAT, "step"), PropertyInfo(Variant::STRING, "slider1"), PropertyInfo(Variant::STRING, "slider2"), PropertyInfo(Variant::STRING, "slider3")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_RANGE, Variant::FLOAT>, 4);
- register_annotation(MethodInfo("@export_exp_easing", PropertyInfo(Variant::STRING, "hint1"), PropertyInfo(Variant::STRING, "hint2")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_EXP_EASING, Variant::FLOAT>, 2);
+ register_annotation(MethodInfo("@export_range", PropertyInfo(Variant::FLOAT, "min"), PropertyInfo(Variant::FLOAT, "max"), PropertyInfo(Variant::FLOAT, "step"), PropertyInfo(Variant::STRING, "extra_hints")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_RANGE, Variant::FLOAT>, varray(1.0, ""), true);
+ register_annotation(MethodInfo("@export_exp_easing", PropertyInfo(Variant::STRING, "hints")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_EXP_EASING, Variant::FLOAT>, varray(""), true);
register_annotation(MethodInfo("@export_color_no_alpha"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_COLOR_NO_ALPHA, Variant::COLOR>);
- register_annotation(MethodInfo("@export_node_path", PropertyInfo(Variant::STRING, "type")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NODE_PATH_VALID_TYPES, Variant::NODE_PATH>, 1, true);
- register_annotation(MethodInfo("@export_flags", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FLAGS, Variant::INT>, 0, true);
+ register_annotation(MethodInfo("@export_node_path", PropertyInfo(Variant::STRING, "type")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NODE_PATH_VALID_TYPES, Variant::NODE_PATH>, varray(""), true);
+ register_annotation(MethodInfo("@export_flags", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FLAGS, Variant::INT>, varray(), true);
register_annotation(MethodInfo("@export_flags_2d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_RENDER, Variant::INT>);
register_annotation(MethodInfo("@export_flags_2d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_PHYSICS, Variant::INT>);
register_annotation(MethodInfo("@export_flags_2d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_NAVIGATION, Variant::INT>);
register_annotation(MethodInfo("@export_flags_3d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_RENDER, Variant::INT>);
register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>);
register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>);
- register_annotation(MethodInfo("@warning_ignore", PropertyInfo(Variant::STRING, "warning")), AnnotationInfo::CLASS | AnnotationInfo::VARIABLE | AnnotationInfo::SIGNAL | AnnotationInfo::CONSTANT | AnnotationInfo::FUNCTION | AnnotationInfo::STATEMENT, &GDScriptParser::warning_annotations, 0, true);
+ // Export grouping annotations.
+ register_annotation(MethodInfo("@export_category", PropertyInfo(Variant::STRING, "name")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_CATEGORY>);
+ register_annotation(MethodInfo("@export_group", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "prefix")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_GROUP>, varray(""));
+ register_annotation(MethodInfo("@export_subgroup", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "prefix")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_SUBGROUP>, varray(""));
+ // Warning annotations.
+ register_annotation(MethodInfo("@warning_ignore", PropertyInfo(Variant::STRING, "warning")), AnnotationInfo::CLASS | AnnotationInfo::VARIABLE | AnnotationInfo::SIGNAL | AnnotationInfo::CONSTANT | AnnotationInfo::FUNCTION | AnnotationInfo::STATEMENT, &GDScriptParser::warning_annotations, varray(), true);
// Networking.
- register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<Multiplayer::RPC_MODE_AUTHORITY>, 4, true);
+ register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<Multiplayer::RPC_MODE_AUTHORITY>, varray("", "", "", 0), true);
}
GDScriptParser::~GDScriptParser() {
@@ -153,6 +162,7 @@ void GDScriptParser::clear() {
for_completion = false;
errors.clear();
multiline_stack.clear();
+ nodes_in_progress.clear();
}
void GDScriptParser::push_error(const String &p_message, const Node *p_origin) {
@@ -404,6 +414,9 @@ GDScriptTokenizer::Token GDScriptParser::advance() {
push_error(current.literal);
current = tokenizer.scan();
}
+ for (Node *n : nodes_in_progress) {
+ update_extents(n);
+ }
return previous;
}
@@ -519,9 +532,13 @@ void GDScriptParser::parse_program() {
head = alloc_node<ClassNode>();
current_class = head;
+ // If we happen to parse an annotation before extends or class_name keywords, track it.
+ // @tool is allowed, but others should fail.
+ AnnotationNode *premature_annotation = nullptr;
+
if (match(GDScriptTokenizer::Token::ANNOTATION)) {
- // Check for @tool annotation.
- AnnotationNode *annotation = parse_annotation(AnnotationInfo::SCRIPT | AnnotationInfo::CLASS_LEVEL);
+ // Check for @tool, script-level, or standalone annotation.
+ AnnotationNode *annotation = parse_annotation(AnnotationInfo::SCRIPT | AnnotationInfo::STANDALONE | AnnotationInfo::CLASS_LEVEL);
if (annotation != nullptr) {
if (annotation->name == SNAME("@tool")) {
// TODO: don't allow @tool anywhere else. (Should all script annotations be the first thing?).
@@ -531,7 +548,14 @@ void GDScriptParser::parse_program() {
}
// @tool annotation has no specific target.
annotation->apply(this, nullptr);
+ } else if (annotation->applies_to(AnnotationInfo::SCRIPT | AnnotationInfo::STANDALONE)) {
+ premature_annotation = annotation;
+ if (previous.type != GDScriptTokenizer::Token::NEWLINE) {
+ push_error(R"(Expected newline after a standalone annotation.)");
+ }
+ annotation->apply(this, head);
} else {
+ premature_annotation = annotation;
annotation_stack.push_back(annotation);
}
}
@@ -541,8 +565,8 @@ void GDScriptParser::parse_program() {
// Order here doesn't matter, but there should be only one of each at most.
switch (current.type) {
case GDScriptTokenizer::Token::CLASS_NAME:
- if (!annotation_stack.is_empty()) {
- push_error(R"("class_name" should be used before annotations.)");
+ if (premature_annotation != nullptr) {
+ push_error(R"("class_name" should be used before annotations (except @tool).)");
}
advance();
if (head->identifier != nullptr) {
@@ -552,8 +576,8 @@ void GDScriptParser::parse_program() {
}
break;
case GDScriptTokenizer::Token::EXTENDS:
- if (!annotation_stack.is_empty()) {
- push_error(R"("extends" should be used before annotations.)");
+ if (premature_annotation != nullptr) {
+ push_error(R"("extends" should be used before annotations (except @tool).)");
}
advance();
if (head->extends_used) {
@@ -574,12 +598,12 @@ void GDScriptParser::parse_program() {
}
if (match(GDScriptTokenizer::Token::ANNOTATION)) {
- // Check for @icon annotation.
- AnnotationNode *annotation = parse_annotation(AnnotationInfo::SCRIPT | AnnotationInfo::CLASS_LEVEL);
+ // Check for a script-level, or standalone annotation.
+ AnnotationNode *annotation = parse_annotation(AnnotationInfo::SCRIPT | AnnotationInfo::STANDALONE | AnnotationInfo::CLASS_LEVEL);
if (annotation != nullptr) {
- if (annotation->name == SNAME("@icon")) {
+ if (annotation->applies_to(AnnotationInfo::SCRIPT | AnnotationInfo::STANDALONE)) {
if (previous.type != GDScriptTokenizer::Token::NEWLINE) {
- push_error(R"(Expected newline after "@icon" annotation.)");
+ push_error(R"(Expected newline after a standalone annotation.)");
}
annotation->apply(this, head);
} else {
@@ -589,6 +613,7 @@ void GDScriptParser::parse_program() {
}
parse_class_body(true);
+ complete_extents(head);
#ifdef TOOLS_ENABLED
for (const KeyValue<int, GDScriptTokenizer::CommentData> &E : tokenizer.get_comments()) {
@@ -629,6 +654,7 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class() {
if (multiline && !consume(GDScriptTokenizer::Token::INDENT, R"(Expected indented block after class declaration.)")) {
current_class = previous_class;
+ complete_extents(n_class);
return n_class;
}
@@ -641,6 +667,7 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class() {
}
parse_class_body(multiline);
+ complete_extents(n_class);
if (multiline) {
consume(GDScriptTokenizer::Token::DEDENT, R"(Missing unindent at the end of the class body.)");
@@ -807,9 +834,18 @@ void GDScriptParser::parse_class_body(bool p_is_multiline) {
break;
case GDScriptTokenizer::Token::ANNOTATION: {
advance();
- AnnotationNode *annotation = parse_annotation(AnnotationInfo::CLASS_LEVEL);
+
+ // Check for class-level annotations.
+ AnnotationNode *annotation = parse_annotation(AnnotationInfo::STANDALONE | AnnotationInfo::CLASS_LEVEL);
if (annotation != nullptr) {
- annotation_stack.push_back(annotation);
+ if (annotation->applies_to(AnnotationInfo::STANDALONE)) {
+ if (previous.type != GDScriptTokenizer::Token::NEWLINE) {
+ push_error(R"(Expected newline after a standalone annotation.)");
+ }
+ annotation->apply(this, head);
+ } else {
+ annotation_stack.push_back(annotation);
+ }
}
break;
}
@@ -841,11 +877,13 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable() {
}
GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_allow_property) {
+ VariableNode *variable = alloc_node<VariableNode>();
+
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected variable name after "var".)")) {
+ complete_extents(variable);
return nullptr;
}
- VariableNode *variable = alloc_node<VariableNode>();
variable->identifier = parse_identifier();
variable->export_info.name = variable->identifier->name;
@@ -853,10 +891,10 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_allow_proper
if (check(GDScriptTokenizer::Token::NEWLINE)) {
if (p_allow_property) {
advance();
-
return parse_property(variable, true);
} else {
push_error(R"(Expected type after ":")");
+ complete_extents(variable);
return nullptr;
}
} else if (check((GDScriptTokenizer::Token::EQUAL))) {
@@ -895,6 +933,7 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_allow_proper
}
}
+ complete_extents(variable);
end_statement("variable declaration");
return variable;
@@ -903,6 +942,7 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_allow_proper
GDScriptParser::VariableNode *GDScriptParser::parse_property(VariableNode *p_variable, bool p_need_indent) {
if (p_need_indent) {
if (!consume(GDScriptTokenizer::Token::INDENT, R"(Expected indented block for property after ":".)")) {
+ complete_extents(p_variable);
return nullptr;
}
}
@@ -912,6 +952,7 @@ GDScriptParser::VariableNode *GDScriptParser::parse_property(VariableNode *p_var
make_completion_context(COMPLETION_PROPERTY_DECLARATION, property);
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected "get" or "set" for property declaration.)")) {
+ complete_extents(p_variable);
return nullptr;
}
@@ -968,6 +1009,7 @@ GDScriptParser::VariableNode *GDScriptParser::parse_property(VariableNode *p_var
}
function = parse_identifier();
}
+ complete_extents(p_variable);
if (p_variable->property == VariableNode::PROP_SETGET) {
end_statement("property declaration");
@@ -982,37 +1024,37 @@ GDScriptParser::VariableNode *GDScriptParser::parse_property(VariableNode *p_var
void GDScriptParser::parse_property_setter(VariableNode *p_variable) {
switch (p_variable->property) {
case VariableNode::PROP_INLINE: {
- consume(GDScriptTokenizer::Token::PARENTHESIS_OPEN, R"(Expected "(" after "set".)");
- if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected parameter name after "(".)")) {
- p_variable->setter_parameter = parse_identifier();
- }
- consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after parameter name.)*");
- consume(GDScriptTokenizer::Token::COLON, R"*(Expected ":" after ")".)*");
-
+ FunctionNode *function = alloc_node<FunctionNode>();
IdentifierNode *identifier = alloc_node<IdentifierNode>();
+ complete_extents(identifier);
identifier->name = "@" + p_variable->identifier->name + "_setter";
-
- FunctionNode *function = alloc_node<FunctionNode>();
function->identifier = identifier;
- FunctionNode *previous_function = current_function;
- current_function = function;
+ consume(GDScriptTokenizer::Token::PARENTHESIS_OPEN, R"(Expected "(" after "set".)");
ParameterNode *parameter = alloc_node<ParameterNode>();
- parameter->identifier = p_variable->setter_parameter;
-
- if (parameter->identifier != nullptr) {
+ if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected parameter name after "(".)")) {
+ reset_extents(parameter, previous);
+ p_variable->setter_parameter = parse_identifier();
+ parameter->identifier = p_variable->setter_parameter;
function->parameters_indices[parameter->identifier->name] = 0;
function->parameters.push_back(parameter);
+ }
+ complete_extents(parameter);
+ consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after parameter name.)*");
+ consume(GDScriptTokenizer::Token::COLON, R"*(Expected ":" after ")".)*");
+
+ FunctionNode *previous_function = current_function;
+ current_function = function;
+ if (p_variable->setter_parameter != nullptr) {
SuiteNode *body = alloc_node<SuiteNode>();
body->add_local(parameter, function);
-
function->body = parse_suite("setter declaration", body);
p_variable->setter = function;
}
-
current_function = previous_function;
+ complete_extents(function);
break;
}
case VariableNode::PROP_SETGET:
@@ -1030,12 +1072,13 @@ void GDScriptParser::parse_property_setter(VariableNode *p_variable) {
void GDScriptParser::parse_property_getter(VariableNode *p_variable) {
switch (p_variable->property) {
case VariableNode::PROP_INLINE: {
+ FunctionNode *function = alloc_node<FunctionNode>();
+
consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after "get".)");
IdentifierNode *identifier = alloc_node<IdentifierNode>();
+ complete_extents(identifier);
identifier->name = "@" + p_variable->identifier->name + "_getter";
-
- FunctionNode *function = alloc_node<FunctionNode>();
function->identifier = identifier;
FunctionNode *previous_function = current_function;
@@ -1043,9 +1086,10 @@ void GDScriptParser::parse_property_getter(VariableNode *p_variable) {
SuiteNode *body = alloc_node<SuiteNode>();
function->body = parse_suite("getter declaration", body);
-
p_variable->getter = function;
+
current_function = previous_function;
+ complete_extents(function);
break;
}
case VariableNode::PROP_SETGET:
@@ -1061,11 +1105,12 @@ void GDScriptParser::parse_property_getter(VariableNode *p_variable) {
}
GDScriptParser::ConstantNode *GDScriptParser::parse_constant() {
+ ConstantNode *constant = alloc_node<ConstantNode>();
+
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected constant name after "const".)")) {
return nullptr;
}
- ConstantNode *constant = alloc_node<ConstantNode>();
constant->identifier = parse_identifier();
if (match(GDScriptTokenizer::Token::COLON)) {
@@ -1084,12 +1129,15 @@ GDScriptParser::ConstantNode *GDScriptParser::parse_constant() {
if (constant->initializer == nullptr) {
push_error(R"(Expected initializer expression for constant.)");
+ complete_extents(constant);
return nullptr;
}
} else {
+ complete_extents(constant);
return nullptr;
}
+ complete_extents(constant);
end_statement("constant declaration");
return constant;
@@ -1119,15 +1167,18 @@ GDScriptParser::ParameterNode *GDScriptParser::parse_parameter() {
parameter->default_value = parse_expression(false);
}
+ complete_extents(parameter);
return parameter;
}
GDScriptParser::SignalNode *GDScriptParser::parse_signal() {
+ SignalNode *signal = alloc_node<SignalNode>();
+
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected signal name after "signal".)")) {
+ complete_extents(signal);
return nullptr;
}
- SignalNode *signal = alloc_node<SignalNode>();
signal->identifier = parse_identifier();
if (check(GDScriptTokenizer::Token::PARENTHESIS_OPEN)) {
@@ -1159,6 +1210,7 @@ GDScriptParser::SignalNode *GDScriptParser::parse_signal() {
consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected closing ")" after signal parameters.)*");
}
+ complete_extents(signal);
end_statement("signal declaration");
return signal;
@@ -1270,6 +1322,7 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum() {
}
#endif // TOOLS_ENABLED
+ complete_extents(enum_node);
end_statement("enum");
return enum_node;
@@ -1321,19 +1374,22 @@ void GDScriptParser::parse_function_signature(FunctionNode *p_function, SuiteNod
}
GDScriptParser::FunctionNode *GDScriptParser::parse_function() {
+ FunctionNode *function = alloc_node<FunctionNode>();
+
bool _static = false;
if (previous.type == GDScriptTokenizer::Token::STATIC) {
// TODO: Improve message if user uses "static" with "var" or "const"
if (!consume(GDScriptTokenizer::Token::FUNC, R"(Expected "func" after "static".)")) {
+ complete_extents(function);
return nullptr;
}
_static = true;
}
- FunctionNode *function = alloc_node<FunctionNode>();
make_completion_context(COMPLETION_OVERRIDE_METHOD, function);
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected function name after "func".)")) {
+ complete_extents(function);
return nullptr;
}
@@ -1355,6 +1411,7 @@ GDScriptParser::FunctionNode *GDScriptParser::parse_function() {
function->body = parse_suite("function declaration", body);
current_function = previous_function;
+ complete_extents(function);
return function;
}
@@ -1402,6 +1459,7 @@ GDScriptParser::AnnotationNode *GDScriptParser::parse_annotation(uint32_t p_vali
}
pop_completion_call();
}
+ complete_extents(annotation);
match(GDScriptTokenizer::Token::NEWLINE); // Newline after annotation is optional.
@@ -1420,12 +1478,12 @@ void GDScriptParser::clear_unused_annotations() {
annotation_stack.clear();
}
-bool GDScriptParser::register_annotation(const MethodInfo &p_info, uint32_t p_target_kinds, AnnotationAction p_apply, int p_optional_arguments, bool p_is_vararg) {
+bool GDScriptParser::register_annotation(const MethodInfo &p_info, uint32_t p_target_kinds, AnnotationAction p_apply, const Vector<Variant> &p_default_arguments, bool p_is_vararg) {
ERR_FAIL_COND_V_MSG(valid_annotations.has(p_info.name), false, vformat(R"(Annotation "%s" already registered.)", p_info.name));
AnnotationInfo new_annotation;
new_annotation.info = p_info;
- new_annotation.info.default_arguments.resize(p_optional_arguments);
+ new_annotation.info.default_arguments = p_default_arguments;
if (p_is_vararg) {
new_annotation.info.flags |= METHOD_FLAG_VARARG;
}
@@ -1451,9 +1509,11 @@ GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context,
if (multiline) {
if (!consume(GDScriptTokenizer::Token::INDENT, vformat(R"(Expected indented block after %s.)", p_context))) {
current_suite = suite->parent_block;
+ complete_extents(suite);
return suite;
}
}
+ reset_extents(suite, current);
int error_count = 0;
@@ -1503,6 +1563,8 @@ GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context,
} while ((multiline || previous.type == GDScriptTokenizer::Token::SEMICOLON) && !check(GDScriptTokenizer::Token::DEDENT) && !lambda_ended && !is_at_end());
+ complete_extents(suite);
+
if (multiline) {
if (!lambda_ended) {
consume(GDScriptTokenizer::Token::DEDENT, vformat(R"(Missing unindent at the end of %s.)", p_context));
@@ -1533,6 +1595,7 @@ GDScriptParser::Node *GDScriptParser::parse_statement() {
case GDScriptTokenizer::Token::PASS:
advance();
result = alloc_node<PassNode>();
+ complete_extents(result);
end_statement(R"("pass")");
break;
case GDScriptTokenizer::Token::VAR:
@@ -1580,6 +1643,7 @@ GDScriptParser::Node *GDScriptParser::parse_statement() {
// If this fails the expression will be nullptr, but that's the same as no return, so it's fine.
n_return->return_value = parse_expression(false);
}
+ complete_extents(n_return);
result = n_return;
current_suite->has_return = true;
@@ -1590,6 +1654,7 @@ GDScriptParser::Node *GDScriptParser::parse_statement() {
case GDScriptTokenizer::Token::BREAKPOINT:
advance();
result = alloc_node<BreakpointNode>();
+ complete_extents(result);
end_statement(R"("breakpoint")");
break;
case GDScriptTokenizer::Token::ASSERT:
@@ -1615,10 +1680,12 @@ GDScriptParser::Node *GDScriptParser::parse_statement() {
lambda_ended = true;
has_ended_lambda = true;
} else {
+ advance();
push_error(vformat(R"(Expected statement, found "%s" instead.)", previous.get_name()));
}
+ } else {
+ end_statement("expression");
}
- end_statement("expression");
lambda_ended = lambda_ended || has_ended_lambda;
result = expression;
@@ -1681,6 +1748,7 @@ GDScriptParser::AssertNode *GDScriptParser::parse_assert() {
assert->condition = parse_expression(false);
if (assert->condition == nullptr) {
push_error("Expected expression to assert.");
+ complete_extents(assert);
return nullptr;
}
@@ -1689,12 +1757,14 @@ GDScriptParser::AssertNode *GDScriptParser::parse_assert() {
assert->message = parse_expression(false);
if (assert->message == nullptr) {
push_error(R"(Expected error message for assert after ",".)");
+ complete_extents(assert);
return nullptr;
}
}
consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after assert expression.)*");
+ complete_extents(assert);
end_statement(R"("assert")");
return assert;
@@ -1704,8 +1774,10 @@ GDScriptParser::BreakNode *GDScriptParser::parse_break() {
if (!can_break) {
push_error(R"(Cannot use "break" outside of a loop.)");
}
+ BreakNode *break_node = alloc_node<BreakNode>();
+ complete_extents(break_node);
end_statement(R"("break")");
- return alloc_node<BreakNode>();
+ return break_node;
}
GDScriptParser::ContinueNode *GDScriptParser::parse_continue() {
@@ -1713,9 +1785,10 @@ GDScriptParser::ContinueNode *GDScriptParser::parse_continue() {
push_error(R"(Cannot use "continue" outside of a loop or pattern matching block.)");
}
current_suite->has_continue = true;
- end_statement(R"("continue")");
ContinueNode *cont = alloc_node<ContinueNode>();
cont->is_for_match = is_continue_match;
+ complete_extents(cont);
+ end_statement(R"("continue")");
return cont;
}
@@ -1748,11 +1821,16 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
SuiteNode *suite = alloc_node<SuiteNode>();
if (n_for->variable) {
+ const SuiteNode::Local &local = current_suite->get_local(n_for->variable->name);
+ if (local.type != SuiteNode::Local::UNDEFINED) {
+ push_error(vformat(R"(There is already a %s named "%s" declared in this scope.)", local.get_name(), n_for->variable->name), n_for->variable);
+ }
suite->add_local(SuiteNode::Local(n_for->variable, current_function));
}
suite->parent_for = n_for;
n_for->loop = parse_suite(R"("for" block)", suite);
+ complete_extents(n_for);
// Reset break/continue state.
can_break = could_break;
@@ -1780,15 +1858,16 @@ GDScriptParser::IfNode *GDScriptParser::parse_if(const String &p_token) {
}
if (match(GDScriptTokenizer::Token::ELIF)) {
- IfNode *elif = parse_if("elif");
-
SuiteNode *else_block = alloc_node<SuiteNode>();
+ IfNode *elif = parse_if("elif");
else_block->statements.push_back(elif);
+ complete_extents(else_block);
n_if->false_block = else_block;
} else if (match(GDScriptTokenizer::Token::ELSE)) {
consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after "else".)");
n_if->false_block = parse_suite(R"("else" block)");
}
+ complete_extents(n_if);
if (n_if->false_block != nullptr && n_if->false_block->has_return && n_if->true_block->has_return) {
current_suite->has_return = true;
@@ -1812,6 +1891,7 @@ GDScriptParser::MatchNode *GDScriptParser::parse_match() {
consume(GDScriptTokenizer::Token::NEWLINE, R"(Expected a newline after "match" statement.)");
if (!consume(GDScriptTokenizer::Token::INDENT, R"(Expected an indented block after "match" statement.)")) {
+ complete_extents(match);
return match;
}
@@ -1829,7 +1909,7 @@ GDScriptParser::MatchNode *GDScriptParser::parse_match() {
}
#ifdef DEBUG_ENABLED
- if (have_wildcard_without_continue) {
+ if (have_wildcard_without_continue && !branch->patterns.is_empty()) {
push_warning(branch->patterns[0], GDScriptWarning::UNREACHABLE_PATTERN);
}
@@ -1845,6 +1925,7 @@ GDScriptParser::MatchNode *GDScriptParser::parse_match() {
#endif
match->branches.push_back(branch);
}
+ complete_extents(match);
consume(GDScriptTokenizer::Token::DEDENT, R"(Expected an indented block after "match" statement.)");
@@ -1859,6 +1940,7 @@ GDScriptParser::MatchNode *GDScriptParser::parse_match() {
GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
MatchBranchNode *branch = alloc_node<MatchBranchNode>();
+ reset_extents(branch, current);
bool has_bind = false;
@@ -1886,6 +1968,7 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
}
if (!consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after "match" patterns.)")) {
+ complete_extents(branch);
return nullptr;
}
@@ -1906,6 +1989,7 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
}
branch->block = parse_suite("match pattern block", suite);
+ complete_extents(branch);
// Restore continue state.
can_continue = could_continue;
@@ -1916,12 +2000,14 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_root_pattern) {
PatternNode *pattern = alloc_node<PatternNode>();
+ reset_extents(pattern, current);
switch (current.type) {
case GDScriptTokenizer::Token::VAR: {
// Bind.
advance();
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected bind name after "var".)")) {
+ complete_extents(pattern);
return nullptr;
}
pattern->pattern_type = PatternNode::PT_BIND;
@@ -1932,12 +2018,14 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
if (p_root_pattern != nullptr) {
if (p_root_pattern->has_bind(pattern->bind->name)) {
push_error(vformat(R"(Bind variable name "%s" was already used in this pattern.)", pattern->bind->name));
+ complete_extents(pattern);
return nullptr;
}
}
if (current_suite->has_local(pattern->bind->name)) {
push_error(vformat(R"(There's already a %s named "%s" in this scope.)", current_suite->get_local(pattern->bind->name).get_name(), pattern->bind->name));
+ complete_extents(pattern);
return nullptr;
}
@@ -1990,6 +2078,7 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
push_error(R"(The ".." pattern must be the last element in the pattern dictionary.)");
} else {
PatternNode *sub_pattern = alloc_node<PatternNode>();
+ complete_extents(sub_pattern);
sub_pattern->pattern_type = PatternNode::PT_REST;
pattern->dictionary.push_back({ nullptr, sub_pattern });
pattern->rest_used = true;
@@ -2038,6 +2127,7 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
break;
}
}
+ complete_extents(pattern);
return pattern;
}
@@ -2071,6 +2161,7 @@ GDScriptParser::WhileNode *GDScriptParser::parse_while() {
is_continue_match = false;
n_while->loop = parse_suite(R"("while" block)");
+ complete_extents(n_while);
// Reset break/continue state.
can_break = could_break;
@@ -2143,6 +2234,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_identifier(ExpressionNode
ERR_FAIL_V_MSG(nullptr, "Parser bug: parsing literal node without literal token.");
}
IdentifierNode *identifier = alloc_node<IdentifierNode>();
+ complete_extents(identifier);
identifier->name = previous.get_identifier();
if (current_suite != nullptr && current_suite->has_local(identifier->name)) {
@@ -2194,6 +2286,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_literal(ExpressionNode *p_
}
LiteralNode *literal = alloc_node<LiteralNode>();
+ complete_extents(literal);
literal->value = previous.literal;
return literal;
}
@@ -2203,6 +2296,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_self(ExpressionNode *p_pre
push_error(R"(Cannot use "self" inside a static function.)");
}
SelfNode *self = alloc_node<SelfNode>();
+ complete_extents(self);
self->current_class = current_class;
return self;
}
@@ -2210,6 +2304,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_self(ExpressionNode *p_pre
GDScriptParser::ExpressionNode *GDScriptParser::parse_builtin_constant(ExpressionNode *p_previous_operand, bool p_can_assign) {
GDScriptTokenizer::Token::Type op_type = previous.type;
LiteralNode *constant = alloc_node<LiteralNode>();
+ complete_extents(constant);
switch (op_type) {
case GDScriptTokenizer::Token::CONST_PI:
@@ -2270,30 +2365,38 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_unary_operator(ExpressionN
}
break;
default:
+ complete_extents(operation);
return nullptr; // Unreachable.
}
+ complete_extents(operation);
return operation;
}
GDScriptParser::ExpressionNode *GDScriptParser::parse_binary_not_in_operator(ExpressionNode *p_previous_operand, bool p_can_assign) {
// check that NOT is followed by IN by consuming it before calling parse_binary_operator which will only receive a plain IN
+ UnaryOpNode *operation = alloc_node<UnaryOpNode>();
+ reset_extents(operation, p_previous_operand);
+ update_extents(operation);
consume(GDScriptTokenizer::Token::IN, R"(Expected "in" after "not" in content-test operator.)");
ExpressionNode *in_operation = parse_binary_operator(p_previous_operand, p_can_assign);
- UnaryOpNode *operation = alloc_node<UnaryOpNode>();
operation->operation = UnaryOpNode::OP_LOGIC_NOT;
operation->variant_op = Variant::OP_NOT;
operation->operand = in_operation;
+ complete_extents(operation);
return operation;
}
GDScriptParser::ExpressionNode *GDScriptParser::parse_binary_operator(ExpressionNode *p_previous_operand, bool p_can_assign) {
GDScriptTokenizer::Token op = previous;
BinaryOpNode *operation = alloc_node<BinaryOpNode>();
+ reset_extents(operation, p_previous_operand);
+ update_extents(operation);
Precedence precedence = (Precedence)(get_rule(op.type)->precedence + 1);
operation->left_operand = p_previous_operand;
operation->right_operand = parse_precedence(precedence, false);
+ complete_extents(operation);
if (operation->right_operand == nullptr) {
push_error(vformat(R"(Expected expression after "%s" operator.")", op.get_name()));
@@ -2396,8 +2499,10 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_binary_operator(Expression
GDScriptParser::ExpressionNode *GDScriptParser::parse_ternary_operator(ExpressionNode *p_previous_operand, bool p_can_assign) {
// Only one ternary operation exists, so no abstraction here.
TernaryOpNode *operation = alloc_node<TernaryOpNode>();
- operation->true_expr = p_previous_operand;
+ reset_extents(operation, p_previous_operand);
+ update_extents(operation);
+ operation->true_expr = p_previous_operand;
operation->condition = parse_precedence(PREC_TERNARY, false);
if (operation->condition == nullptr) {
@@ -2412,6 +2517,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_ternary_operator(Expressio
push_error(R"(Expected expression after "else".)");
}
+ complete_extents(operation);
return operation;
}
@@ -2464,6 +2570,9 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_assignment(ExpressionNode
}
AssignmentNode *assignment = alloc_node<AssignmentNode>();
+ reset_extents(assignment, p_previous_operand);
+ update_extents(assignment);
+
make_completion_context(COMPLETION_ASSIGN, assignment);
#ifdef DEBUG_ENABLED
bool has_operator = true;
@@ -2528,6 +2637,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_assignment(ExpressionNode
if (assignment->assigned_value == nullptr) {
push_error(R"(Expected an expression after "=".)");
}
+ complete_extents(assignment);
#ifdef DEBUG_ENABLED
if (source_variable != nullptr) {
@@ -2549,6 +2659,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_await(ExpressionNode *p_pr
push_error(R"(Expected signal or coroutine after "await".)");
}
await->to_await = element;
+ complete_extents(await);
if (current_function) { // Might be null in a getter or setter.
current_function->is_coroutine = true;
@@ -2577,6 +2688,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_array(ExpressionNode *p_pr
}
pop_multiline();
consume(GDScriptTokenizer::Token::BRACKET_CLOSE, R"(Expected closing "]" after array elements.)");
+ complete_extents(array);
return array;
}
@@ -2668,6 +2780,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_dictionary(ExpressionNode
}
pop_multiline();
consume(GDScriptTokenizer::Token::BRACE_CLOSE, R"(Expected closing "}" after dictionary elements.)");
+ complete_extents(dictionary);
return dictionary;
}
@@ -2685,6 +2798,8 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_grouping(ExpressionNode *p
GDScriptParser::ExpressionNode *GDScriptParser::parse_attribute(ExpressionNode *p_previous_operand, bool p_can_assign) {
SubscriptNode *attribute = alloc_node<SubscriptNode>();
+ reset_extents(attribute, p_previous_operand);
+ update_extents(attribute);
if (for_completion) {
bool is_builtin = false;
@@ -2704,17 +2819,21 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_attribute(ExpressionNode *
attribute->base = p_previous_operand;
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifier after "." for attribute access.)")) {
+ complete_extents(attribute);
return attribute;
}
attribute->is_attribute = true;
attribute->attribute = parse_identifier();
+ complete_extents(attribute);
return attribute;
}
GDScriptParser::ExpressionNode *GDScriptParser::parse_subscript(ExpressionNode *p_previous_operand, bool p_can_assign) {
SubscriptNode *subscript = alloc_node<SubscriptNode>();
+ reset_extents(subscript, p_previous_operand);
+ update_extents(subscript);
make_completion_context(COMPLETION_SUBSCRIPT, subscript);
@@ -2727,15 +2846,19 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_subscript(ExpressionNode *
pop_multiline();
consume(GDScriptTokenizer::Token::BRACKET_CLOSE, R"(Expected "]" after subscription index.)");
+ complete_extents(subscript);
return subscript;
}
GDScriptParser::ExpressionNode *GDScriptParser::parse_cast(ExpressionNode *p_previous_operand, bool p_can_assign) {
CastNode *cast = alloc_node<CastNode>();
+ reset_extents(cast, p_previous_operand);
+ update_extents(cast);
cast->operand = p_previous_operand;
cast->cast_type = parse_type();
+ complete_extents(cast);
if (cast->cast_type == nullptr) {
push_error(R"(Expected type specifier after "as".)");
@@ -2747,6 +2870,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_cast(ExpressionNode *p_pre
GDScriptParser::ExpressionNode *GDScriptParser::parse_call(ExpressionNode *p_previous_operand, bool p_can_assign) {
CallNode *call = alloc_node<CallNode>();
+ reset_extents(call, p_previous_operand);
if (previous.type == GDScriptTokenizer::Token::SUPER) {
// Super call.
@@ -2757,6 +2881,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_call(ExpressionNode *p_pre
if (current_function == nullptr) {
push_error(R"(Cannot use implicit "super" call outside of a function.)");
pop_multiline();
+ complete_extents(call);
return nullptr;
}
if (current_function->identifier) {
@@ -2769,6 +2894,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_call(ExpressionNode *p_pre
make_completion_context(COMPLETION_SUPER_METHOD, call, true);
if (!consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected function name after ".".)")) {
pop_multiline();
+ complete_extents(call);
return nullptr;
}
IdentifierNode *identifier = parse_identifier();
@@ -2825,6 +2951,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_call(ExpressionNode *p_pre
pop_multiline();
consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected closing ")" after call arguments.)*");
+ complete_extents(call);
return call;
}
@@ -2868,6 +2995,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_get_node(ExpressionNode *p
if (previous.type == GDScriptTokenizer::Token::PERCENT) {
if (path_state != PATH_STATE_START && path_state != PATH_STATE_SLASH) {
push_error(R"("%" is only valid in the beginning of a node name (either after "$" or after "/"))");
+ complete_extents(get_node);
return nullptr;
}
get_node->full_path += "%";
@@ -2876,6 +3004,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_get_node(ExpressionNode *p
} else if (previous.type == GDScriptTokenizer::Token::SLASH) {
if (path_state != PATH_STATE_START && path_state != PATH_STATE_NODE_NAME) {
push_error(R"("/" is only valid at the beginning of the path or after a node name.)");
+ complete_extents(get_node);
return nullptr;
}
@@ -2903,6 +3032,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_get_node(ExpressionNode *p
break;
}
push_error(vformat(R"(Expected node path as string or identifier after "%s".)", previous_token));
+ complete_extents(get_node);
return nullptr;
}
@@ -2916,10 +3046,12 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_get_node(ExpressionNode *p
path_state = PATH_STATE_NODE_NAME;
} else if (!check(GDScriptTokenizer::Token::SLASH) && !check(GDScriptTokenizer::Token::PERCENT)) {
push_error(vformat(R"(Unexpected "%s" in node path.)", current.get_name()));
+ complete_extents(get_node);
return nullptr;
}
} while (match(GDScriptTokenizer::Token::SLASH) || match(GDScriptTokenizer::Token::PERCENT));
+ complete_extents(get_node);
return get_node;
}
@@ -2943,6 +3075,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_preload(ExpressionNode *p_
pop_multiline();
consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after preload path.)*");
+ complete_extents(preload);
return preload;
}
@@ -2992,6 +3125,8 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_lambda(ExpressionNode *p_p
in_lambda = true;
function->body = parse_suite("lambda declaration", body, true);
+ complete_extents(function);
+ complete_extents(lambda);
pop_multiline();
@@ -3036,13 +3171,15 @@ GDScriptParser::TypeNode *GDScriptParser::parse_type(bool p_allow_void) {
if (!match(GDScriptTokenizer::Token::IDENTIFIER)) {
if (match(GDScriptTokenizer::Token::VOID)) {
if (p_allow_void) {
- TypeNode *void_type = alloc_node<TypeNode>();
+ complete_extents(type);
+ TypeNode *void_type = type;
return void_type;
} else {
push_error(R"("void" is only allowed for a function return type.)");
}
}
// Leave error message to the caller who knows the context.
+ complete_extents(type);
return nullptr;
}
@@ -3055,11 +3192,15 @@ GDScriptParser::TypeNode *GDScriptParser::parse_type(bool p_allow_void) {
type->container_type = parse_type(false); // Don't allow void for array element type.
if (type->container_type == nullptr) {
push_error(R"(Expected type for collection after "[".)");
+ complete_extents(type);
type = nullptr;
} else if (type->container_type->container_type != nullptr) {
push_error("Nested typed collections are not supported.");
}
consume(GDScriptTokenizer::Token::BRACKET_CLOSE, R"(Expected closing "]" after collection type.)");
+ if (type != nullptr) {
+ complete_extents(type);
+ }
return type;
}
@@ -3072,6 +3213,7 @@ GDScriptParser::TypeNode *GDScriptParser::parse_type(bool p_allow_void) {
}
}
+ complete_extents(type);
return type;
}
@@ -3280,7 +3422,16 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String &
p_tutorials.append(Pair<String, String>(title, link));
break;
case DONE:
- return;
+ break;
+ }
+ }
+ if (current_class->members.size() > 0) {
+ const ClassNode::Member &m = current_class->members[0];
+ int first_member_line = m.get_line();
+ if (first_member_line == line) {
+ p_brief = "";
+ p_desc = "";
+ p_tutorials.clear();
}
}
}
@@ -3605,8 +3756,12 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
variable->export_info.type = Variant::OBJECT;
variable->export_info.hint = PROPERTY_HINT_RESOURCE_TYPE;
variable->export_info.hint_string = export_type.native_type;
+ } else if (ClassDB::is_parent_class(export_type.native_type, SNAME("Node"))) {
+ variable->export_info.type = Variant::OBJECT;
+ variable->export_info.hint = PROPERTY_HINT_NODE_TYPE;
+ variable->export_info.hint_string = export_type.native_type;
} else {
- push_error(R"(Export type can only be built-in, a resource, or an enum.)", variable);
+ push_error(R"(Export type can only be built-in, a resource, a node, or an enum.)", variable);
return false;
}
break;
@@ -3658,6 +3813,36 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
return true;
}
+template <PropertyUsageFlags t_usage>
+bool GDScriptParser::export_group_annotations(const AnnotationNode *p_annotation, Node *p_node) {
+ AnnotationNode *annotation = const_cast<AnnotationNode *>(p_annotation);
+
+ annotation->export_info.name = annotation->resolved_arguments[0];
+
+ switch (t_usage) {
+ case PROPERTY_USAGE_CATEGORY: {
+ annotation->export_info.usage = t_usage;
+ } break;
+
+ case PROPERTY_USAGE_GROUP: {
+ annotation->export_info.usage = t_usage;
+ if (annotation->resolved_arguments.size() == 2) {
+ annotation->export_info.hint_string = annotation->resolved_arguments[1];
+ }
+ } break;
+
+ case PROPERTY_USAGE_SUBGROUP: {
+ annotation->export_info.usage = t_usage;
+ if (annotation->resolved_arguments.size() == 2) {
+ annotation->export_info.hint_string = annotation->resolved_arguments[1];
+ }
+ } break;
+ }
+
+ current_class->add_member_group(annotation);
+ return true;
+}
+
bool GDScriptParser::warning_annotations(const AnnotationNode *p_annotation, Node *p_node) {
#ifdef DEBUG_ENABLED
bool has_error = false;
@@ -3855,6 +4040,46 @@ GDScriptParser::DataType GDScriptParser::DataType::get_typed_container_type() co
return type;
}
+void GDScriptParser::complete_extents(Node *p_node) {
+ while (!nodes_in_progress.is_empty() && nodes_in_progress.back()->get() != p_node) {
+ ERR_PRINT("Parser bug: Mismatch in extents tracking stack.");
+ nodes_in_progress.pop_back();
+ }
+ if (nodes_in_progress.is_empty()) {
+ ERR_PRINT("Parser bug: Extents tracking stack is empty.");
+ } else {
+ nodes_in_progress.pop_back();
+ }
+}
+
+void GDScriptParser::update_extents(Node *p_node) {
+ p_node->end_line = previous.end_line;
+ p_node->end_column = previous.end_column;
+ p_node->leftmost_column = MIN(p_node->leftmost_column, previous.leftmost_column);
+ p_node->rightmost_column = MAX(p_node->rightmost_column, previous.rightmost_column);
+}
+
+void GDScriptParser::reset_extents(Node *p_node, GDScriptTokenizer::Token p_token) {
+ p_node->start_line = p_token.start_line;
+ p_node->end_line = p_token.end_line;
+ p_node->start_column = p_token.start_column;
+ p_node->end_column = p_token.end_column;
+ p_node->leftmost_column = p_token.leftmost_column;
+ p_node->rightmost_column = p_token.rightmost_column;
+}
+
+void GDScriptParser::reset_extents(Node *p_node, Node *p_from) {
+ if (p_from == nullptr) {
+ return;
+ }
+ p_node->start_line = p_from->start_line;
+ p_node->end_line = p_from->end_line;
+ p_node->start_column = p_from->start_column;
+ p_node->end_column = p_from->end_column;
+ p_node->leftmost_column = p_from->leftmost_column;
+ p_node->rightmost_column = p_from->rightmost_column;
+}
+
/*---------- PRETTY PRINT FOR DEBUG ----------*/
#ifdef DEBUG_ENABLED
@@ -4141,6 +4366,8 @@ void GDScriptParser::TreePrinter::print_class(ClassNode *p_class) {
break;
case ClassNode::Member::ENUM_VALUE:
break; // Nothing. Will be printed by enum.
+ case ClassNode::Member::GROUP:
+ break; // Nothing. Groups are only used by inspector.
case ClassNode::Member::UNDEFINED:
push_line("<unknown member>");
break;
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index e3f8d4b8ba..9c97f98fbc 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -325,6 +325,7 @@ public:
Vector<Variant> resolved_arguments;
AnnotationInfo *info = nullptr;
+ PropertyInfo export_info;
bool apply(GDScriptParser *p_this, Node *p_target) const;
bool applies_to(uint32_t p_target_kinds) const;
@@ -500,6 +501,7 @@ public:
VARIABLE,
ENUM,
ENUM_VALUE, // For unnamed enums.
+ GROUP, // For member grouping.
};
Type type = UNDEFINED;
@@ -511,6 +513,7 @@ public:
SignalNode *signal;
VariableNode *variable;
EnumNode *m_enum;
+ AnnotationNode *annotation;
};
EnumNode::Value enum_value;
@@ -532,6 +535,8 @@ public:
return "enum";
case ENUM_VALUE:
return "enum value";
+ case GROUP:
+ return "group";
}
return "";
}
@@ -552,6 +557,8 @@ public:
return m_enum->start_line;
case SIGNAL:
return signal->start_line;
+ case GROUP:
+ return annotation->start_line;
case UNDEFINED:
ERR_FAIL_V_MSG(-1, "Reaching undefined member type.");
}
@@ -586,6 +593,9 @@ public:
// TODO: Add parameter info.
return type;
}
+ case GROUP: {
+ return DataType();
+ }
case UNDEFINED:
return DataType();
}
@@ -622,6 +632,10 @@ public:
type = ENUM_VALUE;
enum_value = p_enum_value;
}
+ Member(AnnotationNode *p_annotation) {
+ type = GROUP;
+ annotation = p_annotation;
+ }
};
IdentifierNode *identifier = nullptr;
@@ -668,6 +682,10 @@ public:
members_indices[p_enum_value.identifier->name] = members.size();
members.push_back(Member(p_enum_value));
}
+ void add_member_group(AnnotationNode *p_annotation_node) {
+ members_indices[p_annotation_node->export_info.name] = members.size();
+ members.push_back(Member(p_annotation_node));
+ }
ClassNode() {
type = CLASS;
@@ -1238,6 +1256,7 @@ private:
SIGNAL = 1 << 4,
FUNCTION = 1 << 5,
STATEMENT = 1 << 6,
+ STANDALONE = 1 << 7,
CLASS_LEVEL = CLASS | VARIABLE | FUNCTION,
};
uint32_t target_kind = 0; // Flags.
@@ -1282,6 +1301,12 @@ private:
};
static ParseRule *get_rule(GDScriptTokenizer::Token::Type p_token_type);
+ List<Node *> nodes_in_progress;
+ void complete_extents(Node *p_node);
+ void update_extents(Node *p_node);
+ void reset_extents(Node *p_node, GDScriptTokenizer::Token p_token);
+ void reset_extents(Node *p_node, Node *p_from);
+
template <class T>
T *alloc_node() {
T *node = memnew(T);
@@ -1289,13 +1314,8 @@ private:
node->next = list;
list = node;
- // TODO: Properly set positions for all nodes.
- node->start_line = previous.start_line;
- node->end_line = previous.end_line;
- node->start_column = previous.start_column;
- node->end_column = previous.end_column;
- node->leftmost_column = previous.leftmost_column;
- node->rightmost_column = previous.rightmost_column;
+ reset_extents(node, previous);
+ nodes_in_progress.push_back(node);
return node;
}
@@ -1340,7 +1360,7 @@ private:
SuiteNode *parse_suite(const String &p_context, SuiteNode *p_suite = nullptr, bool p_for_lambda = false);
// Annotations
AnnotationNode *parse_annotation(uint32_t p_valid_targets);
- bool register_annotation(const MethodInfo &p_info, uint32_t p_target_kinds, AnnotationAction p_apply, int p_optional_arguments = 0, bool p_is_vararg = false);
+ bool register_annotation(const MethodInfo &p_info, uint32_t p_target_kinds, AnnotationAction p_apply, const Vector<Variant> &p_default_arguments = Vector<Variant>(), bool p_is_vararg = false);
bool validate_annotation_arguments(AnnotationNode *p_annotation);
void clear_unused_annotations();
bool tool_annotation(const AnnotationNode *p_annotation, Node *p_target);
@@ -1348,6 +1368,8 @@ private:
bool onready_annotation(const AnnotationNode *p_annotation, Node *p_target);
template <PropertyHint t_hint, Variant::Type t_type>
bool export_annotations(const AnnotationNode *p_annotation, Node *p_target);
+ template <PropertyUsageFlags t_usage>
+ bool export_group_annotations(const AnnotationNode *p_annotation, Node *p_target);
bool warning_annotations(const AnnotationNode *p_annotation, Node *p_target);
template <Multiplayer::RPCMode t_mode>
bool network_annotations(const AnnotationNode *p_annotation, Node *p_target);
@@ -1413,6 +1435,7 @@ public:
CompletionContext get_completion_context() const { return completion_context; }
CompletionCall get_completion_call() const { return completion_call; }
void get_annotation_list(List<MethodInfo> *r_annotations) const;
+ bool annotation_exists(const String &p_annotation_name) const;
const List<ParserError> &get_errors() const { return errors; }
const List<String> get_dependencies() const {
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 16a8e728e4..e0beed367a 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -1032,11 +1032,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#endif
#ifdef DEBUG_ENABLED
if (!valid) {
- if (src->has_method(*index)) {
- err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "'). Did you mean '." + index->operator String() + "()' or funcref(obj, \"" + index->operator String() + "\") ?";
- } else {
- err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "').";
- }
+ err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "').";
OPCODE_BREAK;
}
*dst = ret;
@@ -1897,7 +1893,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
VariantInternal::initialize(ret, Variant::OBJECT);
Object **ret_opaque = VariantInternal::get_object(ret);
method->ptrcall(base_obj, argptrs, ret_opaque);
- VariantInternal::object_assign(ret, *ret_opaque); // Set so ID is correct too.
+ VariantInternal::update_object_id(ret);
#ifdef DEBUG_ENABLED
if (GDScriptLanguage::get_singleton()->profiling) {
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index d3c5fed95a..03e93821c7 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -307,6 +307,8 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
parse_class_symbol(m.m_class, symbol);
r_symbol.children.push_back(symbol);
} break;
+ case ClassNode::Member::GROUP:
+ break; // No-op, but silences warnings.
case ClassNode::Member::UNDEFINED:
break; // Unreachable.
}
@@ -815,6 +817,8 @@ Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode
methods.append(dump_function_api(m.function));
}
} break;
+ case ClassNode::Member::GROUP:
+ break; // No-op, but silences warnings.
case ClassNode::Member::UNDEFINED:
break; // Unreachable.
}
diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp
index de5cd10e7c..ff4832bde0 100644
--- a/modules/gdscript/tests/gdscript_test_runner.cpp
+++ b/modules/gdscript/tests/gdscript_test_runner.cpp
@@ -363,7 +363,7 @@ void GDScriptTest::disable_stdout() {
OS::get_singleton()->set_stderr_enabled(false);
}
-void GDScriptTest::print_handler(void *p_this, const String &p_message, bool p_error) {
+void GDScriptTest::print_handler(void *p_this, const String &p_message, bool p_error, bool p_rich) {
TestResult *result = (TestResult *)p_this;
result->output += p_message + "\n";
}
diff --git a/modules/gdscript/tests/gdscript_test_runner.h b/modules/gdscript/tests/gdscript_test_runner.h
index d6c6419e21..ee21afd9c9 100644
--- a/modules/gdscript/tests/gdscript_test_runner.h
+++ b/modules/gdscript/tests/gdscript_test_runner.h
@@ -86,7 +86,7 @@ private:
TestResult execute_test_code(bool p_is_generating);
public:
- static void print_handler(void *p_this, const String &p_message, bool p_error);
+ static void print_handler(void *p_this, const String &p_message, bool p_error, bool p_rich);
static void error_handler(void *p_this, const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_explanation, bool p_editor_notify, ErrorHandlerType p_type);
TestResult run_test();
bool generate_output();
diff --git a/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.gd b/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.gd
index d13d713454..ada6030132 100644
--- a/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.gd
+++ b/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.gd
@@ -1,6 +1,6 @@
-# Error here. `class_name` should be used *before* annotations, not after.
+# Error here. `class_name` should be used *before* annotations, not after (except @tool).
@icon("res://path/to/optional/icon.svg")
class_name HelloWorld
func test():
- pass
+ pass
diff --git a/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out b/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out
index 0bcc8acc55..02b33c8692 100644
--- a/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out
+++ b/modules/gdscript/tests/scripts/parser/errors/class_name_after_annotation.out
@@ -1,2 +1,2 @@
GDTEST_PARSER_ERROR
-"class_name" should be used before annotations.
+"class_name" should be used before annotations (except @tool).
diff --git a/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_for_variable.gd b/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_for_variable.gd
new file mode 100644
index 0000000000..409da11051
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_for_variable.gd
@@ -0,0 +1,4 @@
+func test():
+ var TEST = 1
+ for TEST in 2:
+ pass
diff --git a/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_for_variable.out b/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_for_variable.out
new file mode 100644
index 0000000000..407f094ca0
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_for_variable.out
@@ -0,0 +1,2 @@
+GDTEST_PARSER_ERROR
+There is already a variable named "TEST" declared in this scope.
diff --git a/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_variable.gd b/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_variable.gd
new file mode 100644
index 0000000000..b353fd1288
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_variable.gd
@@ -0,0 +1,3 @@
+func test():
+ var TEST = 1
+ var TEST = 2
diff --git a/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_variable.out b/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_variable.out
new file mode 100644
index 0000000000..407f094ca0
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/variable_conflicts_variable.out
@@ -0,0 +1,2 @@
+GDTEST_PARSER_ERROR
+There is already a variable named "TEST" declared in this scope.
diff --git a/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.gd b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.gd
new file mode 100644
index 0000000000..d2f3a3e18f
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.gd
@@ -0,0 +1,19 @@
+func test():
+ var dictionary1: Variant = {1:Vector2()}
+ dictionary1[1].x = 2
+ var dictionary2: Dictionary = {3:Vector2()}
+ dictionary2[3].x = 4
+ var array1: Variant = [[Vector2()]]
+ array1[0][0].x = 5
+ var array2: Array = [[Vector2()]]
+ array2[0][0].x = 6
+ var array3: Array[Array] = [[Vector2()]]
+ array3[0][0].x = 7
+ var transform = Transform3D()
+ transform.basis.x = Vector3(8.0, 9.0, 7.0)
+ print(dictionary1)
+ print(dictionary2)
+ print(array1)
+ print(array2)
+ print(array3)
+ print(transform)
diff --git a/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out
new file mode 100644
index 0000000000..5e7ccf534a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out
@@ -0,0 +1,7 @@
+GDTEST_OK
+{1:(2, 0)}
+{3:(4, 0)}
+[[(5, 0)]]
+[[(6, 0)]]
+[[(7, 0)]]
+[X: (8, 9, 7), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 0, 0)]
diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp
index 64891d9ee8..b1c2140039 100644
--- a/modules/glslang/register_types.cpp
+++ b/modules/glslang/register_types.cpp
@@ -38,7 +38,8 @@
#include <glslang/Public/ShaderLang.h>
#include <glslang/SPIRV/GlslangToSpv.h>
-static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error, const RenderingDevice::Capabilities *p_capabilities) {
+static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error, const RenderingDevice *p_render_device) {
+ const RD::Capabilities *capabilities = p_render_device->get_device_capabilities();
Vector<uint8_t> ret;
ERR_FAIL_COND_V(p_language == RenderingDevice::SHADER_LANGUAGE_HLSL, ret);
@@ -58,12 +59,12 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage
glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_5;
glslang::TShader::ForbidIncluder includer;
- if (p_capabilities->device_family == RenderingDevice::DeviceFamily::DEVICE_VULKAN) {
- if (p_capabilities->version_major == 1 && p_capabilities->version_minor == 0) {
+ if (capabilities->device_family == RenderingDevice::DeviceFamily::DEVICE_VULKAN) {
+ if (capabilities->version_major == 1 && capabilities->version_minor == 0) {
ClientVersion = glslang::EShTargetVulkan_1_0;
TargetVersion = glslang::EShTargetSpv_1_0;
check_subgroup_support = false; // subgroups are not supported in Vulkan 1.0
- } else if (p_capabilities->version_major == 1 && p_capabilities->version_minor == 1) {
+ } else if (capabilities->version_major == 1 && capabilities->version_minor == 1) {
ClientVersion = glslang::EShTargetVulkan_1_1;
TargetVersion = glslang::EShTargetSpv_1_3;
} else {
@@ -90,34 +91,36 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage
if (check_subgroup_support) {
uint32_t stage_bit = 1 << p_stage;
- if ((p_capabilities->subgroup_in_shaders & stage_bit) == stage_bit) {
+ uint32_t subgroup_in_shaders = uint32_t(p_render_device->limit_get(RD::LIMIT_SUBGROUP_IN_SHADERS));
+ uint32_t subgroup_operations = uint32_t(p_render_device->limit_get(RD::LIMIT_SUBGROUP_OPERATIONS));
+ if ((subgroup_in_shaders & stage_bit) == stage_bit) {
// stage supports subgroups
preamble += "#define has_GL_KHR_shader_subgroup_basic 1\n";
- if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_VOTE_BIT) {
+ if (subgroup_operations & RenderingDevice::SUBGROUP_VOTE_BIT) {
preamble += "#define has_GL_KHR_shader_subgroup_vote 1\n";
}
- if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_ARITHMETIC_BIT) {
+ if (subgroup_operations & RenderingDevice::SUBGROUP_ARITHMETIC_BIT) {
preamble += "#define has_GL_KHR_shader_subgroup_arithmetic 1\n";
}
- if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_BALLOT_BIT) {
+ if (subgroup_operations & RenderingDevice::SUBGROUP_BALLOT_BIT) {
preamble += "#define has_GL_KHR_shader_subgroup_ballot 1\n";
}
- if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_SHUFFLE_BIT) {
+ if (subgroup_operations & RenderingDevice::SUBGROUP_SHUFFLE_BIT) {
preamble += "#define has_GL_KHR_shader_subgroup_shuffle 1\n";
}
- if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_SHUFFLE_RELATIVE_BIT) {
+ if (subgroup_operations & RenderingDevice::SUBGROUP_SHUFFLE_RELATIVE_BIT) {
preamble += "#define has_GL_KHR_shader_subgroup_shuffle_relative 1\n";
}
- if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_CLUSTERED_BIT) {
+ if (subgroup_operations & RenderingDevice::SUBGROUP_CLUSTERED_BIT) {
preamble += "#define has_GL_KHR_shader_subgroup_clustered 1\n";
}
- if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_QUAD_BIT) {
+ if (subgroup_operations & RenderingDevice::SUBGROUP_QUAD_BIT) {
preamble += "#define has_GL_KHR_shader_subgroup_quad 1\n";
}
}
}
- if (p_capabilities->supports_multiview) {
+ if (p_render_device->has_feature(RD::SUPPORTS_MULTIVIEW)) {
preamble += "#define has_VK_KHR_multiview 1\n";
}
@@ -184,9 +187,10 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage
return ret;
}
-static String _get_cache_key_function_glsl(const RenderingDevice::Capabilities *p_capabilities) {
+static String _get_cache_key_function_glsl(const RenderingDevice *p_render_device) {
+ const RD::Capabilities *capabilities = p_render_device->get_device_capabilities();
String version;
- version = "SpirVGen=" + itos(glslang::GetSpirvGeneratorVersion()) + ", major=" + itos(p_capabilities->version_major) + ", minor=" + itos(p_capabilities->version_minor) + " , subgroup_size=" + itos(p_capabilities->subgroup_operations) + " , subgroup_ops=" + itos(p_capabilities->subgroup_operations) + " , subgroup_in_shaders=" + itos(p_capabilities->subgroup_in_shaders);
+ version = "SpirVGen=" + itos(glslang::GetSpirvGeneratorVersion()) + ", major=" + itos(capabilities->version_major) + ", minor=" + itos(capabilities->version_minor) + " , subgroup_size=" + itos(p_render_device->limit_get(RD::LIMIT_SUBGROUP_SIZE)) + " , subgroup_ops=" + itos(p_render_device->limit_get(RD::LIMIT_SUBGROUP_OPERATIONS)) + " , subgroup_in_shaders=" + itos(p_render_device->limit_get(RD::LIMIT_SUBGROUP_IN_SHADERS));
return version;
}
diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp
index 676862ea5a..8002c185c7 100644
--- a/modules/gltf/editor/editor_scene_importer_blend.cpp
+++ b/modules/gltf/editor/editor_scene_importer_blend.cpp
@@ -292,7 +292,7 @@ static bool _test_blender_path(const String &p_path, String *r_err = nullptr) {
path = path.plus_file("blender");
#endif
-#if defined(OSX_ENABLED)
+#if defined(MACOS_ENABLED)
if (!FileAccess::exists(path)) {
path = path.plus_file("Blender");
}
@@ -449,8 +449,8 @@ bool EditorFileSystemImportFormatSupportQueryBlend::query() {
EditorNode::get_singleton()->get_gui_base()->add_child(configure_blender_dialog);
- configure_blender_dialog->get_ok_button()->set_text(TTR("Confirm Path"));
- configure_blender_dialog->get_cancel_button()->set_text(TTR("Disable '.blend' Import"));
+ configure_blender_dialog->set_ok_button_text(TTR("Confirm Path"));
+ configure_blender_dialog->set_cancel_button_text(TTR("Disable '.blend' Import"));
configure_blender_dialog->get_cancel_button()->set_tooltip(TTR("Disables Blender '.blend' files import for this project. Can be re-enabled in Project Settings."));
configure_blender_dialog->connect("confirmed", callable_mp(this, &EditorFileSystemImportFormatSupportQueryBlend::_path_confirmed));
@@ -468,7 +468,7 @@ bool EditorFileSystemImportFormatSupportQueryBlend::query() {
// Autodetect
auto_detected_path = "";
-#if defined(OSX_ENABLED)
+#if defined(MACOS_ENABLED)
{
Vector<String> mdfind_paths;
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 2017355717..babdc9f33b 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -3080,9 +3080,9 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat
// We'll assume that we use either URI or bufferView, so let's warn the user
// if their image somehow uses both. And fail if it has neither.
- ERR_CONTINUE_MSG(!d.has("uri") && !d.has("bufferView"), "Invalid image definition in glTF file, it should specific an 'uri' or 'bufferView'.");
+ ERR_CONTINUE_MSG(!d.has("uri") && !d.has("bufferView"), "Invalid image definition in glTF file, it should specify an 'uri' or 'bufferView'.");
if (d.has("uri") && d.has("bufferView")) {
- WARN_PRINT("Invalid image definition in glTF file using both 'uri' and 'bufferView'. 'bufferView' will take precedence.");
+ WARN_PRINT("Invalid image definition in glTF file using both 'uri' and 'bufferView'. 'uri' will take precedence.");
}
String mimetype;
@@ -3202,12 +3202,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat
state->images.push_back(Ref<Texture2D>());
continue;
}
-
- Ref<ImageTexture> t;
- t.instantiate();
- t->create_from_image(img);
-
- state->images.push_back(t);
+ state->images.push_back(ImageTexture::create_from_image(img));
}
print_verbose("glTF: Total images: " + itos(state->images.size()));
@@ -3428,7 +3423,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
}
}
orm_image->generate_mipmaps();
- orm_texture->create_from_image(orm_image);
+ orm_texture->set_image(orm_image);
GLTFTextureIndex orm_texture_index = -1;
if (has_ao || has_roughness || has_metalness) {
orm_texture->set_name(material->get_name() + "_orm");
@@ -3476,7 +3471,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
img->set_pixel(x, y, c);
}
}
- tex->create_from_image(img);
+ tex->set_image(img);
}
}
}
@@ -3784,13 +3779,8 @@ void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Re
}
rm_img->generate_mipmaps();
r_spec_gloss->diffuse_img->generate_mipmaps();
- Ref<ImageTexture> diffuse_image_texture;
- diffuse_image_texture.instantiate();
- diffuse_image_texture->create_from_image(r_spec_gloss->diffuse_img);
- p_material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, diffuse_image_texture);
- Ref<ImageTexture> rm_image_texture;
- rm_image_texture.instantiate();
- rm_image_texture->create_from_image(rm_img);
+ p_material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, ImageTexture::create_from_image(r_spec_gloss->diffuse_img));
+ Ref<ImageTexture> rm_image_texture = ImageTexture::create_from_image(rm_img);
if (has_roughness) {
p_material->set_texture(BaseMaterial3D::TEXTURE_ROUGHNESS, rm_image_texture);
p_material->set_roughness_texture_channel(BaseMaterial3D::TEXTURE_CHANNEL_GREEN);
@@ -5176,19 +5166,16 @@ Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, const GLTFNodeIndex
}
const float range = CLAMP(l->range, 0, 4096);
- // Doubling the range will double the effective brightness, so we need double attenuation (half brightness).
- // We want to have double intensity give double brightness, so we need half the attenuation.
- const float attenuation = range / (intensity * 2048);
if (l->light_type == "point") {
OmniLight3D *light = memnew(OmniLight3D);
- light->set_param(OmniLight3D::PARAM_ATTENUATION, attenuation);
+ light->set_param(OmniLight3D::PARAM_ENERGY, intensity);
light->set_param(OmniLight3D::PARAM_RANGE, range);
light->set_color(l->color);
return light;
}
if (l->light_type == "spot") {
SpotLight3D *light = memnew(SpotLight3D);
- light->set_param(SpotLight3D::PARAM_ATTENUATION, attenuation);
+ light->set_param(SpotLight3D::PARAM_ENERGY, intensity);
light->set_param(SpotLight3D::PARAM_RANGE, range);
light->set_param(SpotLight3D::PARAM_SPOT_ANGLE, Math::rad2deg(l->outer_cone_angle));
light->set_color(l->color);
@@ -5253,14 +5240,12 @@ GLTFLightIndex GLTFDocument::_convert_light(Ref<GLTFState> state, Light3D *p_lig
l->light_type = "point";
OmniLight3D *light = cast_to<OmniLight3D>(p_light);
l->range = light->get_param(OmniLight3D::PARAM_RANGE);
- float attenuation = p_light->get_param(OmniLight3D::PARAM_ATTENUATION);
- l->intensity = l->range / (attenuation * 2048);
+ l->intensity = light->get_param(OmniLight3D::PARAM_ENERGY);
} else if (cast_to<SpotLight3D>(p_light)) {
l->light_type = "spot";
SpotLight3D *light = cast_to<SpotLight3D>(p_light);
l->range = light->get_param(SpotLight3D::PARAM_RANGE);
- float attenuation = light->get_param(SpotLight3D::PARAM_ATTENUATION);
- l->intensity = l->range / (attenuation * 2048);
+ l->intensity = light->get_param(SpotLight3D::PARAM_ENERGY);
l->outer_cone_angle = Math::deg2rad(light->get_param(SpotLight3D::PARAM_SPOT_ANGLE));
// This equation is the inverse of the import equation (which has a desmos link).
diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp
index b694c109e1..f975d95079 100644
--- a/modules/gridmap/editor/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp
@@ -1262,7 +1262,7 @@ GridMapEditor::GridMapEditor() {
info_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
info_message->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART);
info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
- info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ info_message->set_anchors_and_offsets_preset(PRESET_FULL_RECT, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
mesh_library_palette->add_child(info_message);
edit_axis = Vector3::AXIS_Y;
diff --git a/modules/lightmapper_rd/SCsub b/modules/lightmapper_rd/SCsub
index 5cc9d8ee8b..fe9737b36f 100644
--- a/modules/lightmapper_rd/SCsub
+++ b/modules/lightmapper_rd/SCsub
@@ -7,9 +7,7 @@ env_lightmapper_rd = env_modules.Clone()
env_lightmapper_rd.GLSL_HEADER("lm_raster.glsl")
env_lightmapper_rd.GLSL_HEADER("lm_compute.glsl")
env_lightmapper_rd.GLSL_HEADER("lm_blendseams.glsl")
-env_lightmapper_rd.Depends("lm_raster.glsl.gen.h", "lm_common_inc.glsl")
-env_lightmapper_rd.Depends("lm_compute.glsl.gen.h", "lm_common_inc.glsl")
-env_lightmapper_rd.Depends("lm_blendseams.glsl.gen.h", "lm_common_inc.glsl")
+env_lightmapper_rd.Depends(Glob("*.glsl.gen.h"), ["lm_common_inc.glsl", "#glsl_builders.py"])
# Godot source files
env_lightmapper_rd.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp
index 2ce3715bea..83ac478a97 100644
--- a/modules/lightmapper_rd/lightmapper_rd.cpp
+++ b/modules/lightmapper_rd/lightmapper_rd.cpp
@@ -271,8 +271,8 @@ Lightmapper::BakeError LightmapperRD::_blit_meshes_into_atlas(int p_max_texture_
mi.offset.x = best_atlas_offsets[m_i].x;
mi.offset.y = best_atlas_offsets[m_i].y;
mi.slice = best_atlas_offsets[m_i].z;
- albedo_images.write[mi.slice]->blit_rect(mi.data.albedo_on_uv2, Rect2(Vector2(), Size2i(mi.data.albedo_on_uv2->get_width(), mi.data.albedo_on_uv2->get_height())), mi.offset);
- emission_images.write[mi.slice]->blit_rect(mi.data.emission_on_uv2, Rect2(Vector2(), Size2i(mi.data.emission_on_uv2->get_width(), mi.data.emission_on_uv2->get_height())), mi.offset);
+ albedo_images.write[mi.slice]->blit_rect(mi.data.albedo_on_uv2, Rect2i(Vector2i(), mi.data.albedo_on_uv2->get_size()), mi.offset);
+ emission_images.write[mi.slice]->blit_rect(mi.data.emission_on_uv2, Rect2(Vector2i(), mi.data.emission_on_uv2->get_size()), mi.offset);
}
return BAKE_OK;
@@ -1420,7 +1420,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
img2.instantiate();
img2->create(2, 2, false, Image::FORMAT_RGBAF, s);
img2->convert(Image::FORMAT_RGB8);
- img->blit_rect(img2, Rect2(0, 0, 2, 2), Point2((j % 3) * 2, (j / 3) * 2));
+ img->blit_rect(img2, Rect2i(0, 0, 2, 2), Point2i((j % 3) * 2, (j / 3) * 2));
}
img->save_png("res://3_light_probe_" + itos(i) + ".png");
}
diff --git a/modules/minimp3/doc_classes/AudioStreamMP3.xml b/modules/minimp3/doc_classes/AudioStreamMP3.xml
index f5f7d3ef17..404f6c31e5 100644
--- a/modules/minimp3/doc_classes/AudioStreamMP3.xml
+++ b/modules/minimp3/doc_classes/AudioStreamMP3.xml
@@ -4,13 +4,36 @@
MP3 audio stream driver.
</brief_description>
<description>
- MP3 audio stream driver.
+ MP3 audio stream driver. See [member data] if you want to load an MP3 file at run-time.
</description>
<tutorials>
</tutorials>
<members>
<member name="data" type="PackedByteArray" setter="set_data" getter="get_data" default="PackedByteArray()">
Contains the audio data in bytes.
+ You can load a file without having to import it beforehand using the code snippet below. Keep in mind that this snippet loads the whole file into memory and may not be ideal for huge files (hundreds of megabytes or more).
+ [codeblocks]
+ [gdscript]
+ func load_mp3(path):
+ var file = File.new()
+ file.open(path, File.READ)
+ var sound = AudioStreamMP3.new()
+ sound.data = file.get_buffer(file.get_length())
+ file.close()
+ return sound
+ [/gdscript]
+ [csharp]
+ public AudioStreamMP3 LoadMP3(string path)
+ {
+ var file = new File();
+ file.Open(path, File.READ);
+ var sound = new AudioStreamMP3();
+ sound.Data = file.GetBuffer(file.GetLength());
+ file.Close();
+ return sound;
+ }
+ [/csharp]
+ [/codeblocks]
</member>
<member name="loop" type="bool" setter="set_loop" getter="has_loop" default="false">
If [code]true[/code], the stream will automatically loop when it reaches the end.
diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp
index 5876b6cbf3..95f1a657a4 100644
--- a/modules/mobile_vr/mobile_vr_interface.cpp
+++ b/modules/mobile_vr/mobile_vr_interface.cpp
@@ -45,7 +45,7 @@ uint32_t MobileVRInterface::get_capabilities() const {
Vector3 MobileVRInterface::scale_magneto(const Vector3 &p_magnetometer) {
// Our magnetometer doesn't give us nice clean data.
- // Well it may on Mac OS X because we're getting a calibrated value in the current implementation but Android we're getting raw data.
+ // Well it may on macOS because we're getting a calibrated value in the current implementation but Android we're getting raw data.
// This is a fairly simple adjustment we can do to correct for the magnetometer data being elliptical
Vector3 mag_raw = p_magnetometer;
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index 3bafa351a9..d10ebc7b47 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -55,7 +55,7 @@ env_mono.add_source_files(env.modules_sources, "utils/*.cpp")
env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.cpp")
-if env["platform"] in ["osx", "iphone"]:
+if env["platform"] in ["macos", "ios"]:
env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.mm")
env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.m")
elif env["platform"] == "android":
diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py
index 1920ef1c1a..3459244bc2 100644
--- a/modules/mono/build_scripts/make_android_mono_config.py
+++ b/modules/mono/build_scripts/make_android_mono_config.py
@@ -43,7 +43,7 @@ String get_godot_android_mono_config() {
Compression::decompress(w, config_uncompressed_size, config_compressed_data,
config_compressed_size, Compression::MODE_DEFLATE);
String s;
- if (s.parse_utf8((const char *)w, data.size())) {
+ if (s.parse_utf8((const char *)w, data.size()) != OK) {
ERR_FAIL_V(String());
}
return s;
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 8e441e7e07..e69904c54b 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -63,15 +63,15 @@ def copy_file(src_dir, dst_dir, src_name, dst_name=""):
def is_desktop(platform):
- return platform in ["windows", "osx", "linuxbsd", "server", "uwp", "haiku"]
+ return platform in ["windows", "macos", "linuxbsd", "server", "uwp", "haiku"]
def is_unix_like(platform):
- return platform in ["osx", "linuxbsd", "server", "android", "haiku", "iphone"]
+ return platform in ["macos", "linuxbsd", "server", "android", "haiku", "ios"]
def module_supports_tools_on(platform):
- return platform not in ["android", "javascript", "iphone"]
+ return platform not in ["android", "javascript", "ios"]
def find_wasm_src_dir(mono_root):
@@ -89,7 +89,7 @@ def configure(env, env_mono):
bits = env["bits"]
is_android = env["platform"] == "android"
is_javascript = env["platform"] == "javascript"
- is_ios = env["platform"] == "iphone"
+ is_ios = env["platform"] == "ios"
is_ios_sim = is_ios and env["arch"] in ["x86", "x86_64"]
tools_enabled = env["tools"]
@@ -206,7 +206,7 @@ def configure(env, env_mono):
copy_file(mono_bin_path, "#bin", mono_dll_file)
else:
- is_apple = env["platform"] in ["osx", "iphone"]
+ is_apple = env["platform"] in ["macos", "ios"]
is_macos = is_apple and not is_ios
sharedlib_ext = ".dylib" if is_apple else ".so"
@@ -221,7 +221,7 @@ def configure(env, env_mono):
)
if not mono_root and is_macos:
- # Try with some known directories under OSX
+ # Try with some known directories under macOS
hint_dirs = ["/Library/Frameworks/Mono.framework/Versions/Current", "/usr/local/var/homebrew/linked/mono"]
for hint_dir in hint_dirs:
if os.path.isdir(hint_dir):
@@ -270,7 +270,7 @@ def configure(env, env_mono):
def copy_mono_lib(libname_wo_ext):
copy_file(
- mono_lib_path, "#bin", libname_wo_ext + ".a", "%s.iphone.%s.a" % (libname_wo_ext, arch)
+ mono_lib_path, "#bin", libname_wo_ext + ".a", "%s.ios.%s.a" % (libname_wo_ext, arch)
)
# Copy Mono libraries to the output folder. These are meant to be bundled with
@@ -539,7 +539,7 @@ def copy_mono_shared_libs(env, mono_root, target_mono_root_dir):
os.makedirs(target_mono_lib_dir)
lib_file_names = []
- if platform == "osx":
+ if platform == "macos":
lib_file_names = [
lib_name + ".dylib"
for lib_name in ["libmono-btls-shared", "libmono-native-compat", "libMonoPosixHelper"]
diff --git a/modules/mono/config.py b/modules/mono/config.py
index df02d9a309..3e6584590c 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -1,4 +1,4 @@
-supported_platforms = ["windows", "osx", "linuxbsd", "server", "android", "haiku", "javascript", "iphone"]
+supported_platforms = ["windows", "macos", "linuxbsd", "server", "android", "haiku", "javascript", "ios"]
def can_build(env, platform):
@@ -15,7 +15,7 @@ def configure(env):
from SCons.Script import BoolVariable, PathVariable, Variables, Help
- default_mono_static = platform in ["iphone", "javascript"]
+ default_mono_static = platform in ["ios", "javascript"]
default_mono_bundles_zlib = platform in ["javascript"]
envvars = Variables()
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 622838b308..3dc26cfbe4 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -2866,6 +2866,12 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
r_hint = PROPERTY_HINT_RESOURCE_TYPE;
r_hint_string = String(NATIVE_GDMONOCLASS_NAME(field_native_class));
+ } else if (p_variant_type == Variant::OBJECT && CACHED_CLASS(Node)->is_assignable_from(p_type.type_class)) {
+ GDMonoClass *field_native_class = GDMonoUtils::get_class_native_base(p_type.type_class);
+ CRASH_COND(field_native_class == nullptr);
+
+ r_hint = PROPERTY_HINT_NODE_TYPE;
+ r_hint_string = String(NATIVE_GDMONOCLASS_NAME(field_native_class));
} else if (p_allow_generics && p_variant_type == Variant::ARRAY) {
// Nested arrays are not supported in the inspector
@@ -3063,16 +3069,11 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) {
Vector<GDMonoMethod *> methods = top->get_all_methods();
for (int i = 0; i < methods.size(); i++) {
if (!methods[i]->is_static()) {
- Multiplayer::RPCMode mode = p_script->_member_get_rpc_mode(methods[i]);
- if (Multiplayer::RPC_MODE_DISABLED != mode) {
- Multiplayer::RPCConfig nd;
- nd.name = methods[i]->get_name();
- nd.rpc_mode = mode;
- // TODO Transfer mode, channel
- nd.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE;
- nd.channel = 0;
- if (-1 == p_script->rpc_functions.find(nd)) {
- p_script->rpc_functions.push_back(nd);
+ Multiplayer::RPCConfig rpc_config = p_script->_member_get_rpc_config(methods[i]);
+ if (rpc_config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) {
+ // RPC annotations can only be used once per method
+ if (p_script->rpc_functions.find(rpc_config) == -1) {
+ p_script->rpc_functions.push_back(rpc_config);
}
}
}
@@ -3507,15 +3508,19 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
return -1;
}
-Multiplayer::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const {
- if (p_member->has_attribute(CACHED_CLASS(AnyPeerAttribute))) {
- return Multiplayer::RPC_MODE_ANY_PEER;
- }
- if (p_member->has_attribute(CACHED_CLASS(AuthorityAttribute))) {
- return Multiplayer::RPC_MODE_AUTHORITY;
+Multiplayer::RPCConfig CSharpScript::_member_get_rpc_config(IMonoClassMember *p_member) const {
+ Multiplayer::RPCConfig rpc_config;
+
+ MonoObject *rpc_attribute = p_member->get_attribute(CACHED_CLASS(RPCAttribute));
+ if (rpc_attribute != nullptr) {
+ rpc_config.name = p_member->get_name();
+ rpc_config.rpc_mode = (Multiplayer::RPCMode)CACHED_PROPERTY(RPCAttribute, Mode)->get_int_value(rpc_attribute);
+ rpc_config.call_local = CACHED_PROPERTY(RPCAttribute, CallLocal)->get_bool_value(rpc_attribute);
+ rpc_config.transfer_mode = (Multiplayer::TransferMode)CACHED_PROPERTY(RPCAttribute, TransferMode)->get_int_value(rpc_attribute);
+ rpc_config.channel = CACHED_PROPERTY(RPCAttribute, TransferChannel)->get_int_value(rpc_attribute);
}
- return Multiplayer::RPC_MODE_DISABLED;
+ return rpc_config;
}
const Vector<Multiplayer::RPCConfig> CSharpScript::get_rpc_methods() const {
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 69bd8703aa..b17473470f 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -179,7 +179,7 @@ private:
static void update_script_class_info(Ref<CSharpScript> p_script);
static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native);
- Multiplayer::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const;
+ Multiplayer::RPCConfig _member_get_rpc_config(IMonoClassMember *p_member) const;
protected:
static void _bind_methods();
@@ -502,6 +502,7 @@ public:
/* TODO? */ void get_public_functions(List<MethodInfo> *p_functions) const override {}
/* TODO? */ void get_public_constants(List<Pair<String, Variant>> *p_constants) const override {}
+ /* TODO? */ void get_public_annotations(List<MethodInfo> *p_annotations) const override {}
void reload_all_scripts() override;
void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) override;
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
index 0128f5c706..5a499742e9 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
@@ -57,7 +57,7 @@
<PropertyGroup Condition=" '$(GodotTargetPlatform)' == '' ">
<GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(Linux))' ">linuxbsd</GodotTargetPlatform>
<GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(FreeBSD))' ">linuxbsd</GodotTargetPlatform>
- <GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(OSX))' ">osx</GodotTargetPlatform>
+ <GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(OSX))' ">macos</GodotTargetPlatform>
<GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(Windows))' ">windows</GodotTargetPlatform>
</PropertyGroup>
@@ -76,12 +76,12 @@
-->
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'windows' ">GODOT_WINDOWS;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'linuxbsd' ">GODOT_LINUXBSD;GODOT_PC</GodotPlatformConstants>
- <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'osx' ">GODOT_OSX;GODOT_MACOS;GODOT_PC</GodotPlatformConstants>
+ <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'macos' ">GODOT_OSX;GODOT_MACOS;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'server' ">GODOT_SERVER;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'uwp' ">GODOT_UWP;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'haiku' ">GODOT_HAIKU;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'android' ">GODOT_ANDROID;GODOT_MOBILE</GodotPlatformConstants>
- <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'iphone' ">GODOT_IPHONE;GODOT_IOS;GODOT_MOBILE</GodotPlatformConstants>
+ <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'ios' ">GODOT_IPHONE;GODOT_IOS;GODOT_MOBILE</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'javascript' ">GODOT_JAVASCRIPT;GODOT_HTML5;GODOT_WASM;GODOT_WEB</GodotPlatformConstants>
<GodotDefineConstants>$(GodotDefineConstants);$(GodotPlatformConstants)</GodotDefineConstants>
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs b/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs
index 16dd1c8c6b..63b97e981e 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs
@@ -99,7 +99,7 @@ namespace GodotTools.Build
if (Utils.OS.IsWindows)
{
// %APPDATA% for both
- return new[] {Path.Combine(applicationData, "NuGet", "NuGet.Config")};
+ return new[] { Path.Combine(applicationData, "NuGet", "NuGet.Config") };
}
var paths = new string[2];
@@ -156,6 +156,7 @@ namespace GodotTools.Build
</packageSources>
</configuration>
";
+ System.IO.Directory.CreateDirectory(Path.GetDirectoryName(nuGetConfigPath));
System.IO.File.WriteAllText(nuGetConfigPath, defaultConfig, Encoding.UTF8); // UTF-8 with BOM
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index e2f4d2f5fd..e9718cc82c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -336,10 +336,10 @@ MONO_AOT_MODE_LAST = 1000,
// Add the required Mono libraries to the Xcode project
- string MonoLibFile(string libFileName) => libFileName + ".iphone.fat.a";
+ string MonoLibFile(string libFileName) => libFileName + ".ios.fat.a";
string MonoLibFromTemplate(string libFileName) =>
- Path.Combine(Internal.FullTemplatesDir, "iphone-mono-libs", MonoLibFile(libFileName));
+ Path.Combine(Internal.FullExportTemplatesDir, "ios-mono-libs", MonoLibFile(libFileName));
exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmonosgen-2.0"));
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index 3e46a89b7c..cca18a2a1f 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -337,7 +337,7 @@ namespace GodotTools.Export
string TemplateDirName() => $"data.mono.{platform}.{bits}.{target}";
- string templateDirPath = Path.Combine(Internal.FullTemplatesDir, TemplateDirName());
+ string templateDirPath = Path.Combine(Internal.FullExportTemplatesDir, TemplateDirName());
bool validTemplatePathFound = true;
if (!Directory.Exists(templateDirPath))
@@ -347,7 +347,7 @@ namespace GodotTools.Export
if (isDebug)
{
target = "debug"; // Support both 'release_debug' and 'debug' for the template data directory name
- templateDirPath = Path.Combine(Internal.FullTemplatesDir, TemplateDirName());
+ templateDirPath = Path.Combine(Internal.FullExportTemplatesDir, TemplateDirName());
validTemplatePathFound = true;
if (!Directory.Exists(templateDirPath))
@@ -380,7 +380,7 @@ namespace GodotTools.Export
private static bool PlatformHasTemplateDir(string platform)
{
- // OSX export templates are contained in a zip, so we place our custom template inside it and let Godot do the rest.
+ // macOS export templates are contained in a zip, so we place our custom template inside it and let Godot do the rest.
return !new[] { OS.Platforms.MacOS, OS.Platforms.Android, OS.Platforms.iOS, OS.Platforms.HTML5 }.Contains(platform);
}
@@ -398,13 +398,13 @@ namespace GodotTools.Export
private static string GetBclProfileDir(string profile)
{
- string templatesDir = Internal.FullTemplatesDir;
+ string templatesDir = Internal.FullExportTemplatesDir;
return Path.Combine(templatesDir, "bcl", profile);
}
private static string DeterminePlatformBclDir(string platform)
{
- string templatesDir = Internal.FullTemplatesDir;
+ string templatesDir = Internal.FullExportTemplatesDir;
string platformBclDir = Path.Combine(templatesDir, "bcl", platform);
if (!File.Exists(Path.Combine(platformBclDir, "mscorlib.dll")))
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 69960bdbeb..b39c3d1c0d 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -263,16 +263,16 @@ namespace GodotTools
var args = new List<string>();
- bool osxAppBundleInstalled = false;
+ bool macOSAppBundleInstalled = false;
if (OS.IsMacOS)
{
// The package path is '/Applications/Visual Studio Code.app'
const string vscodeBundleId = "com.microsoft.VSCode";
- osxAppBundleInstalled = Internal.IsOsxAppBundleInstalled(vscodeBundleId);
+ macOSAppBundleInstalled = Internal.IsMacOSAppBundleInstalled(vscodeBundleId);
- if (osxAppBundleInstalled)
+ if (macOSAppBundleInstalled)
{
args.Add("-b");
args.Add(vscodeBundleId);
@@ -307,13 +307,13 @@ namespace GodotTools
if (OS.IsMacOS)
{
- if (!osxAppBundleInstalled && string.IsNullOrEmpty(_vsCodePath))
+ if (!macOSAppBundleInstalled && string.IsNullOrEmpty(_vsCodePath))
{
GD.PushError("Cannot find code editor: VSCode");
return Error.FileNotFound;
}
- command = osxAppBundleInstalled ? "/usr/bin/open" : _vsCodePath;
+ command = macOSAppBundleInstalled ? "/usr/bin/open" : _vsCodePath;
}
else
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
index 3f1d5ac3ca..7a0983a8cb 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
@@ -30,7 +30,7 @@ namespace GodotTools.Ides.MonoDevelop
{
string bundleId = BundleIds[_editorId];
- if (Internal.IsOsxAppBundleInstalled(bundleId))
+ if (Internal.IsMacOSAppBundleInstalled(bundleId))
{
command = "open";
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
index 77370090ec..12c90178c9 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
@@ -12,12 +12,12 @@ namespace GodotTools.Internals
public static string UpdateApiAssembliesFromPrebuilt(string config) =>
internal_UpdateApiAssembliesFromPrebuilt(config);
- public static string FullTemplatesDir =>
- internal_FullTemplatesDir();
+ public static string FullExportTemplatesDir =>
+ internal_FullExportTemplatesDir();
public static string SimplifyGodotPath(this string path) => internal_SimplifyGodotPath(path);
- public static bool IsOsxAppBundleInstalled(string bundleId) => internal_IsOsxAppBundleInstalled(bundleId);
+ public static bool IsMacOSAppBundleInstalled(string bundleId) => internal_IsMacOSAppBundleInstalled(bundleId);
public static bool GodotIs32Bits() => internal_GodotIs32Bits();
@@ -57,13 +57,13 @@ namespace GodotTools.Internals
private static extern string internal_UpdateApiAssembliesFromPrebuilt(string config);
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern string internal_FullTemplatesDir();
+ private static extern string internal_FullExportTemplatesDir();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_SimplifyGodotPath(this string path);
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern bool internal_IsOsxAppBundleInstalled(string bundleId);
+ private static extern bool internal_IsMacOSAppBundleInstalled(string bundleId);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool internal_GodotIs32Bits();
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index 2db549c623..5cef6e5c3c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -37,13 +37,13 @@ namespace GodotTools.Utils
public static class Platforms
{
public const string Windows = "windows";
- public const string MacOS = "osx";
+ public const string MacOS = "macos";
public const string LinuxBSD = "linuxbsd";
public const string Server = "server";
public const string UWP = "uwp";
public const string Haiku = "haiku";
public const string Android = "android";
- public const string iOS = "iphone";
+ public const string iOS = "ios";
public const string HTML5 = "javascript";
}
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 9d3d481068..7cc195201b 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -990,6 +990,10 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
p_output.append("\n" INDENT1 OPEN_BLOCK);
}
+ if (ienum.is_flags) {
+ p_output.append("\n" INDENT1 "[System.Flags]");
+ }
+
p_output.append("\n" INDENT1 "public enum ");
p_output.append(enum_proxy_name);
p_output.append(" : long");
@@ -1434,6 +1438,10 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
for (const EnumInterface &ienum : itype.enums) {
ERR_FAIL_COND_V(ienum.constants.is_empty(), ERR_BUG);
+ if (ienum.is_flags) {
+ output.append(MEMBER_BEGIN "[System.Flags]");
+ }
+
output.append(MEMBER_BEGIN "public enum ");
output.append(ienum.cname.operator String());
output.append(" : long");
@@ -2865,7 +2873,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
" We only expected Object.free, but found '" +
itype.name + "." + imethod.name + "'.");
}
- } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ } else if (return_info.type == Variant::INT && return_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
imethod.return_type.cname = return_info.class_name;
imethod.return_type.is_enum = true;
} else if (return_info.class_name != StringName()) {
@@ -2903,7 +2911,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
ArgumentInterface iarg;
iarg.name = orig_arg_name;
- if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (arginfo.type == Variant::INT && arginfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
iarg.type.cname = arginfo.class_name;
iarg.type.is_enum = true;
} else if (arginfo.class_name != StringName()) {
@@ -3011,7 +3019,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
ArgumentInterface iarg;
iarg.name = orig_arg_name;
- if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (arginfo.type == Variant::INT && arginfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
iarg.type.cname = arginfo.class_name;
iarg.type.is_enum = true;
} else if (arginfo.class_name != StringName()) {
@@ -3075,9 +3083,9 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
List<String> constants;
ClassDB::get_integer_constant_list(type_cname, &constants, true);
- const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map;
+ const HashMap<StringName, ClassDB::ClassInfo::EnumInfo> &enum_map = class_info->enum_map;
- for (const KeyValue<StringName, List<StringName>> &E : enum_map) {
+ for (const KeyValue<StringName, ClassDB::ClassInfo::EnumInfo> &E : enum_map) {
StringName enum_proxy_cname = E.key;
String enum_proxy_name = enum_proxy_cname.operator String();
if (itype.find_property_by_proxy_name(enum_proxy_cname)) {
@@ -3087,7 +3095,8 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
enum_proxy_cname = StringName(enum_proxy_name);
}
EnumInterface ienum(enum_proxy_cname);
- const List<StringName> &enum_constants = E.value;
+ ienum.is_flags = E.value.is_bitfield;
+ const List<StringName> &enum_constants = E.value.constants;
for (const StringName &constant_cname : enum_constants) {
String constant_name = constant_cname.operator String();
int64_t *value = class_info->constant_map.getptr(constant_cname);
@@ -3676,6 +3685,7 @@ void BindingsGenerator::_populate_global_constants() {
if (enum_name != StringName()) {
EnumInterface ienum(enum_name);
+ // TODO: ienum.is_flags is always false for core constants since they don't seem to support bitfield enums
List<EnumInterface>::Element *enum_match = global_enums.find(ienum);
if (enum_match) {
enum_match->get().constants.push_back(iconstant);
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 70c4f12146..1547d0ed2f 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -60,6 +60,7 @@ class BindingsGenerator {
struct EnumInterface {
StringName cname;
List<ConstantInterface> constants;
+ bool is_flags = false;
_FORCE_INLINE_ bool operator==(const EnumInterface &p_ienum) const {
return p_ienum.cname == cname;
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index f7f710f3f1..5e4fe90553 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -47,7 +47,7 @@
#include "../glue/cs_glue_version.gen.h"
#include "../godotsharp_dirs.h"
#include "../mono_gd/gd_mono_marshal.h"
-#include "../utils/osx_utils.h"
+#include "../utils/macos_utils.h"
#include "code_completion.h"
#include "godotsharp_export.h"
@@ -188,8 +188,8 @@ MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_c
return GDMonoMarshal::mono_string_from_godot(error_str);
}
-MonoString *godot_icall_Internal_FullTemplatesDir() {
- String full_templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG);
+MonoString *godot_icall_Internal_FullExportTemplatesDir() {
+ String full_templates_dir = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG);
return GDMonoMarshal::mono_string_from_godot(full_templates_dir);
}
@@ -198,10 +198,10 @@ MonoString *godot_icall_Internal_SimplifyGodotPath(MonoString *p_path) {
return GDMonoMarshal::mono_string_from_godot(path.simplify_path());
}
-MonoBoolean godot_icall_Internal_IsOsxAppBundleInstalled(MonoString *p_bundle_id) {
-#ifdef OSX_ENABLED
+MonoBoolean godot_icall_Internal_IsMacOSAppBundleInstalled(MonoString *p_bundle_id) {
+#ifdef MACOS_ENABLED
String bundle_id = GDMonoMarshal::mono_string_to_godot(p_bundle_id);
- return (MonoBoolean)osx_is_app_bundle_installed(bundle_id);
+ return (MonoBoolean)macos_is_app_bundle_installed(bundle_id);
#else
(void)p_bundle_id; // UNUSED
return (MonoBoolean) false;
@@ -364,9 +364,9 @@ void register_editor_internal_calls() {
// Internals
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_UpdateApiAssembliesFromPrebuilt", godot_icall_Internal_UpdateApiAssembliesFromPrebuilt);
- GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_FullTemplatesDir", godot_icall_Internal_FullTemplatesDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_FullExportTemplatesDir", godot_icall_Internal_FullExportTemplatesDir);
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_SimplifyGodotPath", godot_icall_Internal_SimplifyGodotPath);
- GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_IsOsxAppBundleInstalled", godot_icall_Internal_IsOsxAppBundleInstalled);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_IsMacOSAppBundleInstalled", godot_icall_Internal_IsMacOSAppBundleInstalled);
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotIs32Bits", godot_icall_Internal_GodotIs32Bits);
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotIsRealTDouble", godot_icall_Internal_GodotIsRealTDouble);
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotMainIteration", godot_icall_Internal_GodotMainIteration);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs
new file mode 100644
index 0000000000..0a1c8322d7
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs
@@ -0,0 +1,43 @@
+using System;
+
+namespace Godot
+{
+ /// <summary>
+ /// Attribute that changes the RPC mode for the annotated <c>method</c> to the given <see cref="Mode"/>,
+ /// optionally specifying the <see cref="TransferMode"/> and <see cref="TransferChannel"/> (on supported peers).
+ /// See <see cref="RPCMode"/> and <see cref="TransferMode"/>. By default, methods are not exposed to networking
+ /// (and RPCs).
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
+ public class RPCAttribute : Attribute
+ {
+ /// <summary>
+ /// RPC mode for the annotated method.
+ /// </summary>
+ public RPCMode Mode { get; } = RPCMode.Disabled;
+
+ /// <summary>
+ /// If the method will also be called locally; otherwise, it is only called remotely.
+ /// </summary>
+ public bool CallLocal { get; set; } = false;
+
+ /// <summary>
+ /// Transfer mode for the annotated method.
+ /// </summary>
+ public TransferMode TransferMode { get; set; } = TransferMode.Reliable;
+
+ /// <summary>
+ /// Transfer channel for the annotated mode.
+ /// </summary>
+ public int TransferChannel { get; set; } = 0;
+
+ /// <summary>
+ /// Constructs a <see cref="RPCAttribute"/> instance.
+ /// </summary>
+ /// <param name="mode">The RPC mode to use.</param>
+ public RPCAttribute(RPCMode mode = RPCMode.Authority)
+ {
+ Mode = mode;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs
deleted file mode 100644
index f0d37c344d..0000000000
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace Godot
-{
- /// <summary>
- /// Constructs a new AnyPeerAttribute instance. Members with the AnyPeerAttribute are given authority over their own player.
- /// </summary>
- [AttributeUsage(AttributeTargets.Method)]
- public class AnyPeerAttribute : Attribute { }
-
- /// <summary>
- /// Constructs a new AuthorityAttribute instance. Members with the AuthorityAttribute are given authority over the game.
- /// </summary>
- [AttributeUsage(AttributeTargets.Method)]
- public class AuthorityAttribute : Attribute { }
-}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index 74aa38386f..bb076a9633 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -239,6 +239,27 @@ namespace Godot
}
/// <summary>
+ /// Converts one or more arguments of any type to string in the best way possible and prints them to the console. The following BBCode tags are supported: b, i, u, s, indent, code, url, center, right, color, bgcolor, fgcolor. Color tags only support named colors such as [code]red[/code], [i]not[/i] hexadecimal color codes. Unsupported tags will be left as-is in standard output.
+ /// When printing to standard output, the supported subset of BBCode is converted to ANSI escape codes for the terminal emulator to display. Displaying ANSI escape codes is currently only supported on Linux and macOS. Support for ANSI escape codes may vary across terminal emulators, especially for italic and strikethrough.
+ ///
+ /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/>
+ /// to print error and warning messages instead of <see cref="Print(object[])"/> or <see cref="PrintRich(object[])"/>.
+ /// This distinguishes them from print messages used for debugging purposes,
+ /// while also displaying a stack trace when an error or warning is printed.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// GD.PrintRich("[b]Hello world![/b]"); // Prints out "Hello world!" in bold.
+ /// </code>
+ /// </example>
+ /// <param name="what">Arguments that will be printed.</param>
+ /// </summary>
+ public static void PrintRich(params object[] what)
+ {
+ godot_icall_GD_print_rich(GetPrintParams(what));
+ }
+
+ /// <summary>
/// Prints the current stack trace information to the console.
/// </summary>
public static void PrintStack()
@@ -562,6 +583,9 @@ namespace Godot
internal static extern void godot_icall_GD_print(object[] what);
[MethodImpl(MethodImplOptions.InternalCall)]
+ internal static extern void godot_icall_GD_print_rich(object[] what);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void godot_icall_GD_printerr(object[] what);
[MethodImpl(MethodImplOptions.InternalCall)]
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index 2b820070d6..36b7d0f80f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -198,6 +198,28 @@ namespace Godot
}
/// <summary>
+ /// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by
+ /// the given <paramref name="control1"/>, <paramref name="control2"/> and <paramref name="end"/> points.
+ /// </summary>
+ /// <param name="start">The start value for the interpolation.</param>
+ /// <param name="control1">Control point that defines the bezier curve.</param>
+ /// <param name="control2">Control point that defines the bezier curve.</param>
+ /// <param name="end">The destination value for the interpolation.</param>
+ /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <returns>The resulting value of the interpolation.</returns>
+ public static real_t BezierInterpolate(real_t start, real_t control1, real_t control2, real_t end, real_t t)
+ {
+ // Formula from Wikipedia article on Bezier curves
+ real_t omt = 1 - t;
+ real_t omt2 = omt * omt;
+ real_t omt3 = omt2 * omt;
+ real_t t2 = t * t;
+ real_t t3 = t2 * t;
+
+ return start * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3;
+ }
+
+ /// <summary>
/// Converts an angle expressed in degrees to radians.
/// </summary>
/// <param name="deg">An angle expressed in degrees.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
index 40fb5f8788..9ae01016cb 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
@@ -170,6 +170,21 @@ namespace Godot
}
/// <summary>
+ /// Returns all names concatenated with a slash character (<c>/</c>).
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// var nodepath = new NodePath("Path2D/PathFollow2D/Sprite2D:texture:load_path");
+ /// GD.Print(nodepath.GetConcatenatedNames()); // Path2D/PathFollow2D/Sprite2D
+ /// </code>
+ /// </example>
+ /// <returns>The names concatenated with <c>/</c>.</returns>
+ public string GetConcatenatedNames()
+ {
+ return godot_icall_NodePath_get_concatenated_names(GetPtr(this));
+ }
+
+ /// <summary>
/// Returns all subnames concatenated with a colon character (<c>:</c>)
/// as separator, i.e. the right side of the first colon in a node path.
/// </summary>
@@ -269,6 +284,9 @@ namespace Godot
private static extern IntPtr godot_icall_NodePath_get_as_property_path(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern string godot_icall_NodePath_get_concatenated_names(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
private static extern string godot_icall_NodePath_get_concatenated_subnames(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
index 63af1c5892..fd97a71e47 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
@@ -118,15 +118,15 @@ namespace Godot
/// <summary>
/// Returns <see langword="true"/> if point is inside the plane.
- /// Comparison uses a custom minimum epsilon threshold.
+ /// Comparison uses a custom minimum tolerance threshold.
/// </summary>
/// <param name="point">The point to check.</param>
- /// <param name="epsilon">The tolerance threshold.</param>
+ /// <param name="tolerance">The tolerance threshold.</param>
/// <returns>A <see langword="bool"/> for whether or not the plane has the point.</returns>
- public bool HasPoint(Vector3 point, real_t epsilon = Mathf.Epsilon)
+ public bool HasPoint(Vector3 point, real_t tolerance = Mathf.Epsilon)
{
real_t dist = _normal.Dot(point) - D;
- return Mathf.Abs(dist) <= epsilon;
+ return Mathf.Abs(dist) <= tolerance;
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index 9e990ce83e..7bdbe1c28b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -221,6 +221,27 @@ namespace Godot
}
/// <summary>
+ /// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by this vector
+ /// and the given <paramref name="control1"/>, <paramref name="control2"/> and <paramref name="end"/> points.
+ /// </summary>
+ /// <param name="control1">Control point that defines the bezier curve.</param>
+ /// <param name="control2">Control point that defines the bezier curve.</param>
+ /// <param name="end">The destination vector.</param>
+ /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <returns>The interpolated vector.</returns>
+ public Vector2 BezierInterpolate(Vector2 control1, Vector2 control2, Vector2 end, real_t t)
+ {
+ // Formula from Wikipedia article on Bezier curves
+ real_t omt = 1 - t;
+ real_t omt2 = omt * omt;
+ real_t omt3 = omt2 * omt;
+ real_t t2 = t * t;
+ real_t t3 = t2 * t;
+
+ return this * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3;
+ }
+
+ /// <summary>
/// Returns the normalized vector pointing from this vector to <paramref name="to"/>.
/// </summary>
/// <param name="to">The other vector to point towards.</param>
@@ -522,9 +543,10 @@ namespace Godot
{
real_t startLengthSquared = LengthSquared();
real_t endLengthSquared = to.LengthSquared();
- if (startLengthSquared == 0.0 || endLengthSquared == 0.0) {
- // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
- return Lerp(to, weight);
+ if (startLengthSquared == 0.0 || endLengthSquared == 0.0)
+ {
+ // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
+ return Lerp(to, weight);
}
real_t startLength = Mathf.Sqrt(startLengthSquared);
real_t resultLength = Mathf.Lerp(startLength, Mathf.Sqrt(endLengthSquared), weight);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
index 412a885daa..b61954a84c 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
@@ -461,7 +461,7 @@ namespace Godot
}
/// <summary>
- /// Multiplies each component of the <see cref="Vector2i"/>
+ /// Divides each component of the <see cref="Vector2i"/>
/// by the given <see langword="int"/>.
/// </summary>
/// <param name="vec">The dividend vector.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index 56859da7f2..480165d44a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -214,6 +214,27 @@ namespace Godot
}
/// <summary>
+ /// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by this vector
+ /// and the given <paramref name="control1"/>, <paramref name="control2"/> and <paramref name="end"/> points.
+ /// </summary>
+ /// <param name="control1">Control point that defines the bezier curve.</param>
+ /// <param name="control2">Control point that defines the bezier curve.</param>
+ /// <param name="end">The destination vector.</param>
+ /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <returns>The interpolated vector.</returns>
+ public Vector3 BezierInterpolate(Vector3 control1, Vector3 control2, Vector3 end, real_t t)
+ {
+ // Formula from Wikipedia article on Bezier curves
+ real_t omt = 1 - t;
+ real_t omt2 = omt * omt;
+ real_t omt3 = omt2 * omt;
+ real_t t2 = t * t;
+ real_t t3 = t2 * t;
+
+ return this * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3;
+ }
+
+ /// <summary>
/// Returns the normalized vector pointing from this vector to <paramref name="to"/>.
/// </summary>
/// <param name="to">The other vector to point towards.</param>
@@ -562,9 +583,10 @@ namespace Godot
{
real_t startLengthSquared = LengthSquared();
real_t endLengthSquared = to.LengthSquared();
- if (startLengthSquared == 0.0 || endLengthSquared == 0.0) {
- // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
- return Lerp(to, weight);
+ if (startLengthSquared == 0.0 || endLengthSquared == 0.0)
+ {
+ // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
+ return Lerp(to, weight);
}
real_t startLength = Mathf.Sqrt(startLengthSquared);
real_t resultLength = Mathf.Lerp(startLength, Mathf.Sqrt(endLengthSquared), weight);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
index abfd2ae720..0d4894f206 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
@@ -449,7 +449,7 @@ namespace Godot
}
/// <summary>
- /// Multiplies each component of the <see cref="Vector3i"/>
+ /// Divides each component of the <see cref="Vector3i"/>
/// by the given <see langword="int"/>.
/// </summary>
/// <param name="vec">The dividend vector.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
index 1fcfe74c86..e59f45bbf6 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
@@ -18,7 +18,7 @@
<Compile Include="Core\Attributes\DisableGodotGeneratorsAttribute.cs" />
<Compile Include="Core\Attributes\ExportAttribute.cs" />
<Compile Include="Core\Attributes\GodotMethodAttribute.cs" />
- <Compile Include="Core\Attributes\RPCAttributes.cs" />
+ <Compile Include="Core\Attributes\RPCAttribute.cs" />
<Compile Include="Core\Attributes\ScriptPathAttribute.cs" />
<Compile Include="Core\Attributes\SignalAttribute.cs" />
<Compile Include="Core\Attributes\ToolAttribute.cs" />
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
index 8aead217cf..8b1c2b729e 100644
--- a/modules/mono/glue/gd_glue.cpp
+++ b/modules/mono/glue/gd_glue.cpp
@@ -90,6 +90,27 @@ void godot_icall_GD_print(MonoArray *p_what) {
print_line(str);
}
+void godot_icall_GD_print_rich(MonoArray *p_what) {
+ String str;
+ int length = mono_array_length(p_what);
+
+ for (int i = 0; i < length; i++) {
+ MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
+
+ MonoException *exc = nullptr;
+ String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
+
+ if (exc) {
+ GDMonoUtils::set_pending_exception(exc);
+ return;
+ }
+
+ str += elem_str;
+ }
+
+ print_line_rich(str);
+}
+
void godot_icall_GD_printerr(MonoArray *p_what) {
String str;
int length = mono_array_length(p_what);
@@ -300,6 +321,7 @@ void godot_register_gd_icalls() {
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_pusherror", godot_icall_GD_pusherror);
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_pushwarning", godot_icall_GD_pushwarning);
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_print", godot_icall_GD_print);
+ GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_print_rich", godot_icall_GD_print_rich);
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printerr", godot_icall_GD_printerr);
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printraw", godot_icall_GD_printraw);
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_prints", godot_icall_GD_prints);
diff --git a/modules/mono/glue/nodepath_glue.cpp b/modules/mono/glue/nodepath_glue.cpp
index 0ea9814b1a..16e1509eb0 100644
--- a/modules/mono/glue/nodepath_glue.cpp
+++ b/modules/mono/glue/nodepath_glue.cpp
@@ -68,6 +68,10 @@ MonoString *godot_icall_NodePath_get_subname(NodePath *p_ptr, uint32_t p_idx) {
return GDMonoMarshal::mono_string_from_godot(p_ptr->get_subname(p_idx));
}
+MonoString *godot_icall_NodePath_get_concatenated_names(NodePath *p_ptr) {
+ return GDMonoMarshal::mono_string_from_godot(p_ptr->get_concatenated_names());
+}
+
MonoString *godot_icall_NodePath_get_concatenated_subnames(NodePath *p_ptr) {
return GDMonoMarshal::mono_string_from_godot(p_ptr->get_concatenated_subnames());
}
@@ -85,6 +89,7 @@ void godot_register_nodepath_icalls() {
GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_Dtor", godot_icall_NodePath_Dtor);
GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_operator_String", godot_icall_NodePath_operator_String);
GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_as_property_path", godot_icall_NodePath_get_as_property_path);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_concatenated_names", godot_icall_NodePath_get_concatenated_names);
GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_concatenated_subnames", godot_icall_NodePath_get_concatenated_subnames);
GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name", godot_icall_NodePath_get_name);
GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name_count", godot_icall_NodePath_get_name_count);
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index cb2b60fcce..f17b24e399 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -184,7 +184,7 @@ private:
data_mono_bin_dir = data_mono_root_dir.plus_file("bin");
#endif
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
if (!DirAccess::exists(data_editor_tools_dir)) {
data_editor_tools_dir = exe_dir.plus_file("../Resources/GodotSharp/Tools");
}
@@ -222,7 +222,7 @@ private:
data_mono_bin_dir = data_mono_root_dir.plus_file("bin");
#endif
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
if (!DirAccess::exists(data_mono_root_dir)) {
data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc");
data_mono_lib_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/lib");
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 39a8ef22b7..d3d3bb2bef 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -55,7 +55,7 @@
#ifdef ANDROID_ENABLED
#include "android_mono_config.h"
#include "support/android_support.h"
-#elif defined(IPHONE_ENABLED)
+#elif defined(IOS_ENABLED)
#include "support/ios_support.h"
#endif
@@ -188,7 +188,7 @@ MonoDomain *gd_initialize_mono_runtime() {
MonoDomain *gd_initialize_mono_runtime() {
gd_mono_debug_init();
-#if defined(IPHONE_ENABLED) || defined(ANDROID_ENABLED)
+#if defined(IOS_ENABLED) || defined(ANDROID_ENABLED)
// I don't know whether this actually matters or not
const char *runtime_version = "mobile";
#else
@@ -263,7 +263,7 @@ void GDMono::determine_mono_dirs(String &r_assembly_rootdir, String &r_config_di
if (mono_reg_info.config_dir.length() && DirAccess::exists(mono_reg_info.config_dir)) {
r_config_dir = mono_reg_info.config_dir;
}
-#elif defined(OSX_ENABLED)
+#elif defined(MACOS_ENABLED)
const char *c_assembly_rootdir = mono_assembly_getrootdir();
const char *c_config_dir = mono_get_config_dir();
@@ -343,7 +343,7 @@ void GDMono::initialize() {
#if defined(ANDROID_ENABLED)
gdmono::android::support::initialize();
-#elif defined(IPHONE_ENABLED)
+#elif defined(IOS_ENABLED)
gdmono::ios::support::initialize();
#endif
diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp
index 44a8e26b8f..fd78fae4ad 100644
--- a/modules/mono/mono_gd/gd_mono_cache.cpp
+++ b/modules/mono/mono_gd/gd_mono_cache.cpp
@@ -140,8 +140,11 @@ void CachedData::clear_godot_api_cache() {
field_ExportAttribute_hintString = nullptr;
class_SignalAttribute = nullptr;
class_ToolAttribute = nullptr;
- class_AnyPeerAttribute = nullptr;
- class_AuthorityAttribute = nullptr;
+ class_RPCAttribute = nullptr;
+ property_RPCAttribute_Mode = nullptr;
+ property_RPCAttribute_CallLocal = nullptr;
+ property_RPCAttribute_TransferMode = nullptr;
+ property_RPCAttribute_TransferChannel = nullptr;
class_GodotMethodAttribute = nullptr;
field_GodotMethodAttribute_methodName = nullptr;
class_ScriptPathAttribute = nullptr;
@@ -268,8 +271,11 @@ void update_godot_api_cache() {
CACHE_FIELD_AND_CHECK(ExportAttribute, hintString, CACHED_CLASS(ExportAttribute)->get_field("hintString"));
CACHE_CLASS_AND_CHECK(SignalAttribute, GODOT_API_CLASS(SignalAttribute));
CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute));
- CACHE_CLASS_AND_CHECK(AnyPeerAttribute, GODOT_API_CLASS(AnyPeerAttribute));
- CACHE_CLASS_AND_CHECK(AuthorityAttribute, GODOT_API_CLASS(AuthorityAttribute));
+ CACHE_CLASS_AND_CHECK(RPCAttribute, GODOT_API_CLASS(RPCAttribute));
+ CACHE_PROPERTY_AND_CHECK(RPCAttribute, Mode, CACHED_CLASS(RPCAttribute)->get_property("Mode"));
+ CACHE_PROPERTY_AND_CHECK(RPCAttribute, CallLocal, CACHED_CLASS(RPCAttribute)->get_property("CallLocal"));
+ CACHE_PROPERTY_AND_CHECK(RPCAttribute, TransferMode, CACHED_CLASS(RPCAttribute)->get_property("TransferMode"));
+ CACHE_PROPERTY_AND_CHECK(RPCAttribute, TransferChannel, CACHED_CLASS(RPCAttribute)->get_property("TransferChannel"));
CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute));
CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));
CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute));
diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h
index 92136e1f41..b3b0865608 100644
--- a/modules/mono/mono_gd/gd_mono_cache.h
+++ b/modules/mono/mono_gd/gd_mono_cache.h
@@ -111,8 +111,11 @@ struct CachedData {
GDMonoField *field_ExportAttribute_hintString = nullptr;
GDMonoClass *class_SignalAttribute = nullptr;
GDMonoClass *class_ToolAttribute = nullptr;
- GDMonoClass *class_AnyPeerAttribute = nullptr;
- GDMonoClass *class_AuthorityAttribute = nullptr;
+ GDMonoClass *class_RPCAttribute = nullptr;
+ GDMonoProperty *property_RPCAttribute_Mode = nullptr;
+ GDMonoProperty *property_RPCAttribute_CallLocal = nullptr;
+ GDMonoProperty *property_RPCAttribute_TransferMode = nullptr;
+ GDMonoProperty *property_RPCAttribute_TransferChannel = nullptr;
GDMonoClass *class_GodotMethodAttribute = nullptr;
GDMonoField *field_GodotMethodAttribute_methodName = nullptr;
GDMonoClass *class_ScriptPathAttribute = nullptr;
diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h
index 9fc35f8e31..93ba6a410e 100644
--- a/modules/mono/mono_gd/gd_mono_log.h
+++ b/modules/mono/mono_gd/gd_mono_log.h
@@ -35,7 +35,7 @@
#include "core/typedefs.h"
-#if !defined(JAVASCRIPT_ENABLED) && !defined(IPHONE_ENABLED)
+#if !defined(JAVASCRIPT_ENABLED) && !defined(IOS_ENABLED)
// We have custom mono log callbacks for WASM and iOS
#define GD_MONO_LOG_ENABLED
#endif
diff --git a/modules/mono/mono_gd/gd_mono_method_thunk.h b/modules/mono/mono_gd/gd_mono_method_thunk.h
index bb163b89bc..0180dee3ea 100644
--- a/modules/mono/mono_gd/gd_mono_method_thunk.h
+++ b/modules/mono/mono_gd/gd_mono_method_thunk.h
@@ -39,7 +39,7 @@
#include "gd_mono_method.h"
#include "gd_mono_utils.h"
-#if !defined(JAVASCRIPT_ENABLED) && !defined(IPHONE_ENABLED)
+#if !defined(JAVASCRIPT_ENABLED) && !defined(IOS_ENABLED)
#define HAVE_METHOD_THUNKS
#endif
diff --git a/modules/mono/mono_gd/support/ios_support.h b/modules/mono/mono_gd/support/ios_support.h
index 2f444d5089..03e86df698 100644
--- a/modules/mono/mono_gd/support/ios_support.h
+++ b/modules/mono/mono_gd/support/ios_support.h
@@ -31,7 +31,7 @@
#ifndef IOS_SUPPORT_H
#define IOS_SUPPORT_H
-#if defined(IPHONE_ENABLED)
+#if defined(IOS_ENABLED)
#include "core/string/ustring.h"
@@ -45,6 +45,6 @@ void cleanup();
} // namespace ios
} // namespace gdmono
-#endif // IPHONE_ENABLED
+#endif // IOS_ENABLED
#endif // IOS_SUPPORT_H
diff --git a/modules/mono/mono_gd/support/ios_support.mm b/modules/mono/mono_gd/support/ios_support.mm
index df97dfba49..7c941b9d1e 100644
--- a/modules/mono/mono_gd/support/ios_support.mm
+++ b/modules/mono/mono_gd/support/ios_support.mm
@@ -30,7 +30,7 @@
#include "ios_support.h"
-#if defined(IPHONE_ENABLED)
+#if defined(IOS_ENABLED)
#import <Foundation/Foundation.h>
#include <os/log.h>
@@ -147,4 +147,4 @@ GD_PINVOKE_EXPORT void xamarin_start_wwan(const char *p_uri) {
os_log_error(OS_LOG_DEFAULT, "Not implemented: 'xamarin_start_wwan'");
}
-#endif // IPHONE_ENABLED
+#endif // IOS_ENABLED
diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/macos_utils.cpp
index abb59420eb..cd4f7a827e 100644
--- a/modules/mono/utils/osx_utils.cpp
+++ b/modules/mono/utils/macos_utils.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* osx_utils.cpp */
+/* macos_utils.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,16 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "osx_utils.h"
+#include "macos_utils.h"
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
#include "core/string/print_string.h"
#import <CoreFoundation/CoreFoundation.h>
#import <CoreServices/CoreServices.h>
-bool osx_is_app_bundle_installed(const String &p_bundle_id) {
+bool macos_is_app_bundle_installed(const String &p_bundle_id) {
CFStringRef bundle_id = CFStringCreateWithCString(nullptr, p_bundle_id.utf8(), kCFStringEncodingUTF8);
CFArrayRef result = LSCopyApplicationURLsForBundleIdentifier(bundle_id, nullptr);
CFRelease(bundle_id);
diff --git a/modules/mono/utils/osx_utils.h b/modules/mono/utils/macos_utils.h
index 2f6c6dad51..7892cb2785 100644
--- a/modules/mono/utils/osx_utils.h
+++ b/modules/mono/utils/macos_utils.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* osx_utils.h */
+/* macos_utils.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,13 +30,13 @@
#include "core/string/ustring.h"
-#ifndef OSX_UTILS_H
-#define OSX_UTILS_H
+#ifndef MACOS_UTILS_H
+#define MACOS_UTILS_H
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
-bool osx_is_app_bundle_installed(const String &p_bundle_id);
+bool macos_is_app_bundle_installed(const String &p_bundle_id);
#endif
-#endif // OSX_UTILS_H
+#endif // MACOS_UTILS_H
diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp
index 15a0b28181..a1905dfcfe 100644
--- a/modules/mono/utils/path_utils.cpp
+++ b/modules/mono/utils/path_utils.cpp
@@ -62,7 +62,8 @@ String cwd() {
}
String result;
- if (result.parse_utf16(buffer.ptr())) {
+ result.parse_utf16(buffer.ptr());
+ if (result.is_empty()) {
return ".";
}
return result.simplify_path();
@@ -73,7 +74,7 @@ String cwd() {
}
String result;
- if (result.parse_utf8(buffer)) {
+ if (result.parse_utf8(buffer) != OK) {
return ".";
}
@@ -114,7 +115,8 @@ String realpath(const String &p_path) {
::CloseHandle(hFile);
String result;
- if (result.parse_utf16(buffer.ptr())) {
+ result.parse_utf16(buffer.ptr());
+ if (result.is_empty()) {
return p_path;
}
@@ -127,10 +129,10 @@ String realpath(const String &p_path) {
}
String result;
- bool parse_ok = result.parse_utf8(resolved_path);
+ Error parse_ok = result.parse_utf8(resolved_path);
::free(resolved_path);
- if (parse_ok) {
+ if (parse_ok != OK) {
return p_path;
}
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index 64b68b70af..975f2d8332 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -178,7 +178,7 @@ Error read_all_file_utf8(const String &p_path, String &r_content) {
w[len] = 0;
String source;
- if (source.parse_utf8((const char *)w)) {
+ if (source.parse_utf8((const char *)w) != OK) {
ERR_FAIL_V(ERR_INVALID_DATA);
}
diff --git a/modules/noise/editor/noise_editor_plugin.cpp b/modules/noise/editor/noise_editor_plugin.cpp
index 32c3f0aad4..27a86f45b5 100644
--- a/modules/noise/editor/noise_editor_plugin.cpp
+++ b/modules/noise/editor/noise_editor_plugin.cpp
@@ -54,7 +54,7 @@ public:
set_custom_minimum_size(Size2(0, EDSCALE * PREVIEW_HEIGHT));
_texture_rect = memnew(TextureRect);
- _texture_rect->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ _texture_rect->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
_texture_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_COVERED);
add_child(_texture_rect);
diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub
index 8783e061d2..593d1ff3c1 100644
--- a/modules/openxr/SCsub
+++ b/modules/openxr/SCsub
@@ -35,7 +35,11 @@ if env["platform"] == "android":
# may need to include java parts of the openxr loader
elif env["platform"] == "linuxbsd":
- env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_LINUX", "XR_USE_PLATFORM_XLIB"])
+ env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_LINUX"])
+
+ if env["x11"]:
+ env_thirdparty.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"])
+
# FIXME: Review what needs to be set for Android and macOS.
env_thirdparty.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
elif env["platform"] == "windows":
diff --git a/modules/openxr/doc_classes/OpenXRInterface.xml b/modules/openxr/doc_classes/OpenXRInterface.xml
index 74f708bc95..25bf496de9 100644
--- a/modules/openxr/doc_classes/OpenXRInterface.xml
+++ b/modules/openxr/doc_classes/OpenXRInterface.xml
@@ -5,10 +5,10 @@
</brief_description>
<description>
The OpenXR interface allows Godot to interact with OpenXR runtimes and make it possible to create XR experiences and games.
- Due to the needs of OpenXR this interface works slightly different then other plugin based XR interfaces. It needs to be initialised when Godot starts. You need to enable OpenXR, settings for this can be found in your games project settings under the XR heading. You do need to mark a viewport for use with XR in order for Godot to know which render result should be output to the headset.
+ Due to the needs of OpenXR this interface works slightly different than other plugin based XR interfaces. It needs to be initialised when Godot starts. You need to enable OpenXR, settings for this can be found in your games project settings under the XR heading. You do need to mark a viewport for use with XR in order for Godot to know which render result should be output to the headset.
</description>
<tutorials>
- <link title="OpenXR documentation">$DOCS_URL/tutorials/vr/openxr/index.html</link>
+ <link title="Setting up XR">$DOCS_URL/tutorials/xr/setting_up_xr.html</link>
</tutorials>
<signals>
<signal name="pose_recentered">
diff --git a/modules/openxr/extensions/openxr_vulkan_extension.cpp b/modules/openxr/extensions/openxr_vulkan_extension.cpp
index 2ddf3b8a7d..3d3d4de5b6 100644
--- a/modules/openxr/extensions/openxr_vulkan_extension.cpp
+++ b/modules/openxr/extensions/openxr_vulkan_extension.cpp
@@ -34,7 +34,6 @@
#include "../openxr_api.h"
#include "../openxr_util.h"
#include "servers/rendering/renderer_rd/effects/copy_effects.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_globals.h"
#include "servers/rendering_server.h"
@@ -439,7 +438,6 @@ bool OpenXRVulkanExtension::copy_render_target_to_image(RID p_from_render_target
SwapchainGraphicsData *data = (SwapchainGraphicsData *)p_swapchain_graphics_data;
ERR_FAIL_NULL_V(data, false);
ERR_FAIL_COND_V(p_from_render_target.is_null(), false);
- ERR_FAIL_NULL_V(RendererStorageRD::base_singleton, false);
RID source_image = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(p_from_render_target);
ERR_FAIL_COND_V(source_image.is_null(), false);
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index dcb1f1d744..87e2fae2d0 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -80,8 +80,8 @@ void ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, String p_strin
float fw, fh;
picture->size(&fw, &fh);
- uint32_t width = MIN(fw * p_scale, 16 * 1024);
- uint32_t height = MIN(fh * p_scale, 16 * 1024);
+ uint32_t width = MIN(round(fw * p_scale), 16 * 1024);
+ uint32_t height = MIN(round(fh * p_scale), 16 * 1024);
picture->size(width, height);
std::unique_ptr<tvg::SwCanvas> sw_canvas = tvg::SwCanvas::gen();
diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub
index a46f17311a..2d764a4006 100644
--- a/modules/text_server_adv/SCsub
+++ b/modules/text_server_adv/SCsub
@@ -75,18 +75,18 @@ if env["builtin_harfbuzz"]:
"src/hb-ot-meta.cc",
"src/hb-ot-metrics.cc",
"src/hb-ot-name.cc",
- "src/hb-ot-shape-complex-arabic.cc",
- "src/hb-ot-shape-complex-default.cc",
- "src/hb-ot-shape-complex-hangul.cc",
- "src/hb-ot-shape-complex-hebrew.cc",
- "src/hb-ot-shape-complex-indic-table.cc",
- "src/hb-ot-shape-complex-indic.cc",
- "src/hb-ot-shape-complex-khmer.cc",
- "src/hb-ot-shape-complex-myanmar.cc",
- "src/hb-ot-shape-complex-syllabic.cc",
- "src/hb-ot-shape-complex-thai.cc",
- "src/hb-ot-shape-complex-use.cc",
- "src/hb-ot-shape-complex-vowel-constraints.cc",
+ "src/hb-ot-shaper-arabic.cc",
+ "src/hb-ot-shaper-default.cc",
+ "src/hb-ot-shaper-hangul.cc",
+ "src/hb-ot-shaper-hebrew.cc",
+ "src/hb-ot-shaper-indic-table.cc",
+ "src/hb-ot-shaper-indic.cc",
+ "src/hb-ot-shaper-khmer.cc",
+ "src/hb-ot-shaper-myanmar.cc",
+ "src/hb-ot-shaper-syllabic.cc",
+ "src/hb-ot-shaper-thai.cc",
+ "src/hb-ot-shaper-use.cc",
+ "src/hb-ot-shaper-vowel-constraints.cc",
"src/hb-ot-shape-fallback.cc",
"src/hb-ot-shape-normalize.cc",
"src/hb-ot-shape.cc",
diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct
index 0e36ef6805..0170c007ae 100644
--- a/modules/text_server_adv/gdextension_build/SConstruct
+++ b/modules/text_server_adv/gdextension_build/SConstruct
@@ -220,18 +220,18 @@ thirdparty_harfbuzz_sources = [
"src/hb-ot-meta.cc",
"src/hb-ot-metrics.cc",
"src/hb-ot-name.cc",
- "src/hb-ot-shape-complex-arabic.cc",
- "src/hb-ot-shape-complex-default.cc",
- "src/hb-ot-shape-complex-hangul.cc",
- "src/hb-ot-shape-complex-hebrew.cc",
- "src/hb-ot-shape-complex-indic-table.cc",
- "src/hb-ot-shape-complex-indic.cc",
- "src/hb-ot-shape-complex-khmer.cc",
- "src/hb-ot-shape-complex-myanmar.cc",
- "src/hb-ot-shape-complex-syllabic.cc",
- "src/hb-ot-shape-complex-thai.cc",
- "src/hb-ot-shape-complex-use.cc",
- "src/hb-ot-shape-complex-vowel-constraints.cc",
+ "src/hb-ot-shaper-arabic.cc",
+ "src/hb-ot-shaper-default.cc",
+ "src/hb-ot-shaper-hangul.cc",
+ "src/hb-ot-shaper-hebrew.cc",
+ "src/hb-ot-shaper-indic-table.cc",
+ "src/hb-ot-shaper-indic.cc",
+ "src/hb-ot-shaper-khmer.cc",
+ "src/hb-ot-shaper-myanmar.cc",
+ "src/hb-ot-shaper-syllabic.cc",
+ "src/hb-ot-shaper-thai.cc",
+ "src/hb-ot-shaper-use.cc",
+ "src/hb-ot-shaper-vowel-constraints.cc",
"src/hb-ot-shape-fallback.cc",
"src/hb-ot-shape-normalize.cc",
"src/hb-ot-shape.cc",
@@ -624,15 +624,15 @@ env.Append(CPPDEFINES=["GDEXTENSION"])
env.Append(CPPPATH=["../"])
sources = Glob("../*.cpp")
-if env["platform"] == "osx":
- methods.write_osx_plist(
- f'./bin/libtextserver_advanced.osx.{env["target"]}.framework',
- f'libtextserver_advanced.osx.{env["target"]}',
+if env["platform"] == "macos":
+ methods.write_macos_plist(
+ f'./bin/libtextserver_advanced.macos.{env["target"]}.framework',
+ f'libtextserver_advanced.macos.{env["target"]}',
"org.godotengine.textserver_advanced",
"ICU / HarfBuzz / Graphite Text Server",
)
library = env.SharedLibrary(
- f'./bin/libtextserver_advanced.osx.{env["target"]}.framework/libtextserver_advanced.osx.{env["target"]}',
+ f'./bin/libtextserver_advanced.macos.{env["target"]}.framework/libtextserver_advanced.macos.{env["target"]}',
source=sources,
)
else:
diff --git a/modules/text_server_adv/gdextension_build/methods.py b/modules/text_server_adv/gdextension_build/methods.py
index d404f2851e..3c5229462c 100644
--- a/modules/text_server_adv/gdextension_build/methods.py
+++ b/modules/text_server_adv/gdextension_build/methods.py
@@ -98,7 +98,7 @@ def make_icu_data(target, source, env):
g.write("#endif")
-def write_osx_plist(target, binary_name, identifier, name):
+def write_macos_plist(target, binary_name, identifier, name):
os.makedirs(f"{target}/Resourece/", exist_ok=True)
f = open(f"{target}/Resourece/Info.plist", "w")
diff --git a/modules/text_server_adv/gdextension_build/text_server_adv.gdextension b/modules/text_server_adv/gdextension_build/text_server_adv.gdextension
index 5956476a5e..11ed271ae9 100644
--- a/modules/text_server_adv/gdextension_build/text_server_adv.gdextension
+++ b/modules/text_server_adv/gdextension_build/text_server_adv.gdextension
@@ -8,5 +8,5 @@ linux.64.debug = "bin/libtextserver_advanced.linux.debug.64.so"
linux.64.release = "bin/libtextserver_advanced.linux.release.64.so"
windows.64.debug = "bin/libtextserver_advanced.windows.debug.64.dll"
windows.64.release = "bin/libtextserver_advanced.windows.release.64.dll"
-macos.debug = "bin/libtextserver_advanced.osx.debug.framework"
-macos.release = "bin/libtextserver_advanced.osx.release.framework"
+macos.debug = "bin/libtextserver_advanced.macos.debug.framework"
+macos.release = "bin/libtextserver_advanced.macos.release.framework"
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index c4269a53f4..fe2279df69 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -75,7 +75,7 @@ using namespace core_bind;
hb_font_funcs_t *TextServerAdvanced::funcs = nullptr;
-TextServerAdvanced::bmp_font_t *TextServerAdvanced::_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref) {
+TextServerAdvanced::bmp_font_t *TextServerAdvanced::_bmp_font_create(TextServerAdvanced::FontForSizeAdvanced *p_face, bool p_unref) {
bmp_font_t *bm_font = memnew(bmp_font_t);
if (!bm_font) {
@@ -228,11 +228,11 @@ void TextServerAdvanced::_bmp_free_font_funcs() {
}
}
-void TextServerAdvanced::_bmp_font_set_funcs(hb_font_t *p_font, TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref) {
+void TextServerAdvanced::_bmp_font_set_funcs(hb_font_t *p_font, TextServerAdvanced::FontForSizeAdvanced *p_face, bool p_unref) {
hb_font_set_funcs(p_font, funcs, _bmp_font_create(p_face, p_unref), _bmp_font_destroy);
}
-hb_font_t *TextServerAdvanced::_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, hb_destroy_func_t p_destroy) {
+hb_font_t *TextServerAdvanced::_bmp_font_create(TextServerAdvanced::FontForSizeAdvanced *p_face, hb_destroy_func_t p_destroy) {
hb_font_t *font;
hb_face_t *face = hb_face_create(nullptr, 0);
@@ -375,7 +375,7 @@ int64_t TextServerAdvanced::get_features() const {
void TextServerAdvanced::free_rid(const RID &p_rid) {
_THREAD_SAFE_METHOD_
if (font_owner.owns(p_rid)) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_rid);
font_owner.free(p_rid);
memdelete(fd);
} else if (shaped_owner.owns(p_rid)) {
@@ -476,259 +476,267 @@ bool TextServerAdvanced::is_locale_right_to_left(const String &p_locale) const {
}
}
-_FORCE_INLINE_ void TextServerAdvanced::_insert_feature(const StringName &p_name, int32_t p_tag) {
+_FORCE_INLINE_ void TextServerAdvanced::_insert_feature(const StringName &p_name, int32_t p_tag, Variant::Type p_vtype, bool p_hidden) {
+ FeatureInfo fi;
+ fi.name = p_name;
+ fi.vtype = p_vtype;
+ fi.hidden = p_hidden;
+
feature_sets.insert(p_name, p_tag);
- feature_sets_inv.insert(p_tag, p_name);
+ feature_sets_inv.insert(p_tag, fi);
}
void TextServerAdvanced::_insert_feature_sets() {
// Registered OpenType feature tags.
- _insert_feature("access_all_alternates", HB_TAG('a', 'a', 'l', 't'));
- _insert_feature("above_base_forms", HB_TAG('a', 'b', 'v', 'f'));
- _insert_feature("above_base_mark_positioning", HB_TAG('a', 'b', 'v', 'm'));
- _insert_feature("above_base_substitutions", HB_TAG('a', 'b', 'v', 's'));
- _insert_feature("alternative_fractions", HB_TAG('a', 'f', 'r', 'c'));
- _insert_feature("akhands", HB_TAG('a', 'k', 'h', 'n'));
- _insert_feature("below_base_forms", HB_TAG('b', 'l', 'w', 'f'));
- _insert_feature("below_base_mark_positioning", HB_TAG('b', 'l', 'w', 'm'));
- _insert_feature("below_base_substitutions", HB_TAG('b', 'l', 'w', 's'));
- _insert_feature("contextual_alternates", HB_TAG('c', 'a', 'l', 't'));
- _insert_feature("case_sensitive_forms", HB_TAG('c', 'a', 's', 'e'));
- _insert_feature("glyph_composition", HB_TAG('c', 'c', 'm', 'p'));
- _insert_feature("conjunct_form_after_ro", HB_TAG('c', 'f', 'a', 'r'));
- _insert_feature("conjunct_forms", HB_TAG('c', 'j', 'c', 't'));
- _insert_feature("contextual_ligatures", HB_TAG('c', 'l', 'i', 'g'));
- _insert_feature("centered_cjk_punctuation", HB_TAG('c', 'p', 'c', 't'));
- _insert_feature("capital_spacing", HB_TAG('c', 'p', 's', 'p'));
- _insert_feature("contextual_swash", HB_TAG('c', 's', 'w', 'h'));
- _insert_feature("cursive_positioning", HB_TAG('c', 'u', 'r', 's'));
- _insert_feature("character_variant_01", HB_TAG('c', 'v', '0', '1'));
- _insert_feature("character_variant_02", HB_TAG('c', 'v', '0', '2'));
- _insert_feature("character_variant_03", HB_TAG('c', 'v', '0', '3'));
- _insert_feature("character_variant_04", HB_TAG('c', 'v', '0', '4'));
- _insert_feature("character_variant_05", HB_TAG('c', 'v', '0', '5'));
- _insert_feature("character_variant_06", HB_TAG('c', 'v', '0', '6'));
- _insert_feature("character_variant_07", HB_TAG('c', 'v', '0', '7'));
- _insert_feature("character_variant_08", HB_TAG('c', 'v', '0', '8'));
- _insert_feature("character_variant_09", HB_TAG('c', 'v', '0', '9'));
- _insert_feature("character_variant_10", HB_TAG('c', 'v', '1', '0'));
- _insert_feature("character_variant_11", HB_TAG('c', 'v', '1', '1'));
- _insert_feature("character_variant_12", HB_TAG('c', 'v', '1', '2'));
- _insert_feature("character_variant_13", HB_TAG('c', 'v', '1', '3'));
- _insert_feature("character_variant_14", HB_TAG('c', 'v', '1', '4'));
- _insert_feature("character_variant_15", HB_TAG('c', 'v', '1', '5'));
- _insert_feature("character_variant_16", HB_TAG('c', 'v', '1', '6'));
- _insert_feature("character_variant_17", HB_TAG('c', 'v', '1', '7'));
- _insert_feature("character_variant_18", HB_TAG('c', 'v', '1', '8'));
- _insert_feature("character_variant_19", HB_TAG('c', 'v', '1', '9'));
- _insert_feature("character_variant_20", HB_TAG('c', 'v', '2', '0'));
- _insert_feature("character_variant_21", HB_TAG('c', 'v', '2', '1'));
- _insert_feature("character_variant_22", HB_TAG('c', 'v', '2', '2'));
- _insert_feature("character_variant_23", HB_TAG('c', 'v', '2', '3'));
- _insert_feature("character_variant_24", HB_TAG('c', 'v', '2', '4'));
- _insert_feature("character_variant_25", HB_TAG('c', 'v', '2', '5'));
- _insert_feature("character_variant_26", HB_TAG('c', 'v', '2', '6'));
- _insert_feature("character_variant_27", HB_TAG('c', 'v', '2', '7'));
- _insert_feature("character_variant_28", HB_TAG('c', 'v', '2', '8'));
- _insert_feature("character_variant_29", HB_TAG('c', 'v', '2', '9'));
- _insert_feature("character_variant_30", HB_TAG('c', 'v', '3', '0'));
- _insert_feature("character_variant_31", HB_TAG('c', 'v', '3', '1'));
- _insert_feature("character_variant_32", HB_TAG('c', 'v', '3', '2'));
- _insert_feature("character_variant_33", HB_TAG('c', 'v', '3', '3'));
- _insert_feature("character_variant_34", HB_TAG('c', 'v', '3', '4'));
- _insert_feature("character_variant_35", HB_TAG('c', 'v', '3', '5'));
- _insert_feature("character_variant_36", HB_TAG('c', 'v', '3', '6'));
- _insert_feature("character_variant_37", HB_TAG('c', 'v', '3', '7'));
- _insert_feature("character_variant_38", HB_TAG('c', 'v', '3', '8'));
- _insert_feature("character_variant_39", HB_TAG('c', 'v', '3', '9'));
- _insert_feature("character_variant_40", HB_TAG('c', 'v', '4', '0'));
- _insert_feature("character_variant_41", HB_TAG('c', 'v', '4', '1'));
- _insert_feature("character_variant_42", HB_TAG('c', 'v', '4', '2'));
- _insert_feature("character_variant_43", HB_TAG('c', 'v', '4', '3'));
- _insert_feature("character_variant_44", HB_TAG('c', 'v', '4', '4'));
- _insert_feature("character_variant_45", HB_TAG('c', 'v', '4', '5'));
- _insert_feature("character_variant_46", HB_TAG('c', 'v', '4', '6'));
- _insert_feature("character_variant_47", HB_TAG('c', 'v', '4', '7'));
- _insert_feature("character_variant_48", HB_TAG('c', 'v', '4', '8'));
- _insert_feature("character_variant_49", HB_TAG('c', 'v', '4', '9'));
- _insert_feature("character_variant_50", HB_TAG('c', 'v', '5', '0'));
- _insert_feature("character_variant_51", HB_TAG('c', 'v', '5', '1'));
- _insert_feature("character_variant_52", HB_TAG('c', 'v', '5', '2'));
- _insert_feature("character_variant_53", HB_TAG('c', 'v', '5', '3'));
- _insert_feature("character_variant_54", HB_TAG('c', 'v', '5', '4'));
- _insert_feature("character_variant_55", HB_TAG('c', 'v', '5', '5'));
- _insert_feature("character_variant_56", HB_TAG('c', 'v', '5', '6'));
- _insert_feature("character_variant_57", HB_TAG('c', 'v', '5', '7'));
- _insert_feature("character_variant_58", HB_TAG('c', 'v', '5', '8'));
- _insert_feature("character_variant_59", HB_TAG('c', 'v', '5', '9'));
- _insert_feature("character_variant_60", HB_TAG('c', 'v', '6', '0'));
- _insert_feature("character_variant_61", HB_TAG('c', 'v', '6', '1'));
- _insert_feature("character_variant_62", HB_TAG('c', 'v', '6', '2'));
- _insert_feature("character_variant_63", HB_TAG('c', 'v', '6', '3'));
- _insert_feature("character_variant_64", HB_TAG('c', 'v', '6', '4'));
- _insert_feature("character_variant_65", HB_TAG('c', 'v', '6', '5'));
- _insert_feature("character_variant_66", HB_TAG('c', 'v', '6', '6'));
- _insert_feature("character_variant_67", HB_TAG('c', 'v', '6', '7'));
- _insert_feature("character_variant_68", HB_TAG('c', 'v', '6', '8'));
- _insert_feature("character_variant_69", HB_TAG('c', 'v', '6', '9'));
- _insert_feature("character_variant_70", HB_TAG('c', 'v', '7', '0'));
- _insert_feature("character_variant_71", HB_TAG('c', 'v', '7', '1'));
- _insert_feature("character_variant_72", HB_TAG('c', 'v', '7', '2'));
- _insert_feature("character_variant_73", HB_TAG('c', 'v', '7', '3'));
- _insert_feature("character_variant_74", HB_TAG('c', 'v', '7', '4'));
- _insert_feature("character_variant_75", HB_TAG('c', 'v', '7', '5'));
- _insert_feature("character_variant_76", HB_TAG('c', 'v', '7', '6'));
- _insert_feature("character_variant_77", HB_TAG('c', 'v', '7', '7'));
- _insert_feature("character_variant_78", HB_TAG('c', 'v', '7', '8'));
- _insert_feature("character_variant_79", HB_TAG('c', 'v', '7', '9'));
- _insert_feature("character_variant_80", HB_TAG('c', 'v', '8', '0'));
- _insert_feature("character_variant_81", HB_TAG('c', 'v', '8', '1'));
- _insert_feature("character_variant_82", HB_TAG('c', 'v', '8', '2'));
- _insert_feature("character_variant_83", HB_TAG('c', 'v', '8', '3'));
- _insert_feature("character_variant_84", HB_TAG('c', 'v', '8', '4'));
- _insert_feature("character_variant_85", HB_TAG('c', 'v', '8', '5'));
- _insert_feature("character_variant_86", HB_TAG('c', 'v', '8', '6'));
- _insert_feature("character_variant_87", HB_TAG('c', 'v', '8', '7'));
- _insert_feature("character_variant_88", HB_TAG('c', 'v', '8', '8'));
- _insert_feature("character_variant_89", HB_TAG('c', 'v', '8', '9'));
- _insert_feature("character_variant_90", HB_TAG('c', 'v', '9', '0'));
- _insert_feature("character_variant_91", HB_TAG('c', 'v', '9', '1'));
- _insert_feature("character_variant_92", HB_TAG('c', 'v', '9', '2'));
- _insert_feature("character_variant_93", HB_TAG('c', 'v', '9', '3'));
- _insert_feature("character_variant_94", HB_TAG('c', 'v', '9', '4'));
- _insert_feature("character_variant_95", HB_TAG('c', 'v', '9', '5'));
- _insert_feature("character_variant_96", HB_TAG('c', 'v', '9', '6'));
- _insert_feature("character_variant_97", HB_TAG('c', 'v', '9', '7'));
- _insert_feature("character_variant_98", HB_TAG('c', 'v', '9', '8'));
- _insert_feature("character_variant_99", HB_TAG('c', 'v', '9', '9'));
- _insert_feature("petite_capitals_from_capitals", HB_TAG('c', '2', 'p', 'c'));
- _insert_feature("small_capitals_from_capitals", HB_TAG('c', '2', 's', 'c'));
- _insert_feature("distances", HB_TAG('d', 'i', 's', 't'));
- _insert_feature("discretionary_ligatures", HB_TAG('d', 'l', 'i', 'g'));
- _insert_feature("denominators", HB_TAG('d', 'n', 'o', 'm'));
- _insert_feature("dotless_forms", HB_TAG('d', 't', 'l', 's'));
- _insert_feature("expert_forms", HB_TAG('e', 'x', 'p', 't'));
- _insert_feature("final_glyph_on_line_alternates", HB_TAG('f', 'a', 'l', 't'));
- _insert_feature("terminal_forms_2", HB_TAG('f', 'i', 'n', '2'));
- _insert_feature("terminal_forms_3", HB_TAG('f', 'i', 'n', '3'));
- _insert_feature("terminal_forms", HB_TAG('f', 'i', 'n', 'a'));
- _insert_feature("flattened_accent_forms", HB_TAG('f', 'l', 'a', 'c'));
- _insert_feature("fractions", HB_TAG('f', 'r', 'a', 'c'));
- _insert_feature("full_widths", HB_TAG('f', 'w', 'i', 'd'));
- _insert_feature("half_forms", HB_TAG('h', 'a', 'l', 'f'));
- _insert_feature("halant_forms", HB_TAG('h', 'a', 'l', 'n'));
- _insert_feature("alternate_half_widths", HB_TAG('h', 'a', 'l', 't'));
- _insert_feature("historical_forms", HB_TAG('h', 'i', 's', 't'));
- _insert_feature("horizontal_kana_alternates", HB_TAG('h', 'k', 'n', 'a'));
- _insert_feature("historical_ligatures", HB_TAG('h', 'l', 'i', 'g'));
- _insert_feature("hangul", HB_TAG('h', 'n', 'g', 'l'));
- _insert_feature("hojo_kanji_forms", HB_TAG('h', 'o', 'j', 'o'));
- _insert_feature("half_widths", HB_TAG('h', 'w', 'i', 'd'));
- _insert_feature("initial_forms", HB_TAG('i', 'n', 'i', 't'));
- _insert_feature("isolated_forms", HB_TAG('i', 's', 'o', 'l'));
- _insert_feature("italics", HB_TAG('i', 't', 'a', 'l'));
- _insert_feature("justification_alternates", HB_TAG('j', 'a', 'l', 't'));
- _insert_feature("jis78_forms", HB_TAG('j', 'p', '7', '8'));
- _insert_feature("jis83_forms", HB_TAG('j', 'p', '8', '3'));
- _insert_feature("jis90_forms", HB_TAG('j', 'p', '9', '0'));
- _insert_feature("jis2004_forms", HB_TAG('j', 'p', '0', '4'));
- _insert_feature("kerning", HB_TAG('k', 'e', 'r', 'n'));
- _insert_feature("left_bounds", HB_TAG('l', 'f', 'b', 'd'));
- _insert_feature("standard_ligatures", HB_TAG('l', 'i', 'g', 'a'));
- _insert_feature("leading_jamo_forms", HB_TAG('l', 'j', 'm', 'o'));
- _insert_feature("lining_figures", HB_TAG('l', 'n', 'u', 'm'));
- _insert_feature("localized_forms", HB_TAG('l', 'o', 'c', 'l'));
- _insert_feature("left_to_right_alternates", HB_TAG('l', 't', 'r', 'a'));
- _insert_feature("left_to_right_mirrored_forms", HB_TAG('l', 't', 'r', 'm'));
- _insert_feature("mark_positioning", HB_TAG('m', 'a', 'r', 'k'));
- _insert_feature("medial_forms_2", HB_TAG('m', 'e', 'd', '2'));
- _insert_feature("medial_forms", HB_TAG('m', 'e', 'd', 'i'));
- _insert_feature("mathematical_greek", HB_TAG('m', 'g', 'r', 'k'));
- _insert_feature("mark_to_mark_positioning", HB_TAG('m', 'k', 'm', 'k'));
- _insert_feature("mark_positioning_via_substitution", HB_TAG('m', 's', 'e', 't'));
- _insert_feature("alternate_annotation_forms", HB_TAG('n', 'a', 'l', 't'));
- _insert_feature("nlc_kanji_forms", HB_TAG('n', 'l', 'c', 'k'));
- _insert_feature("nukta_forms", HB_TAG('n', 'u', 'k', 't'));
- _insert_feature("numerators", HB_TAG('n', 'u', 'm', 'r'));
- _insert_feature("oldstyle_figures", HB_TAG('o', 'n', 'u', 'm'));
- _insert_feature("optical_bounds", HB_TAG('o', 'p', 'b', 'd'));
- _insert_feature("ordinals", HB_TAG('o', 'r', 'd', 'n'));
- _insert_feature("ornaments", HB_TAG('o', 'r', 'n', 'm'));
- _insert_feature("proportional_alternate_widths", HB_TAG('p', 'a', 'l', 't'));
- _insert_feature("petite_capitals", HB_TAG('p', 'c', 'a', 'p'));
- _insert_feature("proportional_kana", HB_TAG('p', 'k', 'n', 'a'));
- _insert_feature("proportional_figures", HB_TAG('p', 'n', 'u', 'm'));
- _insert_feature("pre_base_forms", HB_TAG('p', 'r', 'e', 'f'));
- _insert_feature("pre_base_substitutions", HB_TAG('p', 'r', 'e', 's'));
- _insert_feature("post_base_forms", HB_TAG('p', 's', 't', 'f'));
- _insert_feature("post_base_substitutions", HB_TAG('p', 's', 't', 's'));
- _insert_feature("proportional_widths", HB_TAG('p', 'w', 'i', 'd'));
- _insert_feature("quarter_widths", HB_TAG('q', 'w', 'i', 'd'));
- _insert_feature("randomize", HB_TAG('r', 'a', 'n', 'd'));
- _insert_feature("required_contextual_alternates", HB_TAG('r', 'c', 'l', 't'));
- _insert_feature("rakar_forms", HB_TAG('r', 'k', 'r', 'f'));
- _insert_feature("required_ligatures", HB_TAG('r', 'l', 'i', 'g'));
- _insert_feature("reph_forms", HB_TAG('r', 'p', 'h', 'f'));
- _insert_feature("right_bounds", HB_TAG('r', 't', 'b', 'd'));
- _insert_feature("right_to_left_alternates", HB_TAG('r', 't', 'l', 'a'));
- _insert_feature("right_to_left_mirrored_forms", HB_TAG('r', 't', 'l', 'm'));
- _insert_feature("ruby_notation_forms", HB_TAG('r', 'u', 'b', 'y'));
- _insert_feature("required_variation_alternates", HB_TAG('r', 'v', 'r', 'n'));
- _insert_feature("stylistic_alternates", HB_TAG('s', 'a', 'l', 't'));
- _insert_feature("scientific_inferiors", HB_TAG('s', 'i', 'n', 'f'));
- _insert_feature("optical_size", HB_TAG('s', 'i', 'z', 'e'));
- _insert_feature("small_capitals", HB_TAG('s', 'm', 'c', 'p'));
- _insert_feature("simplified_forms", HB_TAG('s', 'm', 'p', 'l'));
- _insert_feature("stylistic_set_01", HB_TAG('s', 's', '0', '1'));
- _insert_feature("stylistic_set_02", HB_TAG('s', 's', '0', '2'));
- _insert_feature("stylistic_set_03", HB_TAG('s', 's', '0', '3'));
- _insert_feature("stylistic_set_04", HB_TAG('s', 's', '0', '4'));
- _insert_feature("stylistic_set_05", HB_TAG('s', 's', '0', '5'));
- _insert_feature("stylistic_set_06", HB_TAG('s', 's', '0', '6'));
- _insert_feature("stylistic_set_07", HB_TAG('s', 's', '0', '7'));
- _insert_feature("stylistic_set_08", HB_TAG('s', 's', '0', '8'));
- _insert_feature("stylistic_set_09", HB_TAG('s', 's', '0', '9'));
- _insert_feature("stylistic_set_10", HB_TAG('s', 's', '1', '0'));
- _insert_feature("stylistic_set_11", HB_TAG('s', 's', '1', '1'));
- _insert_feature("stylistic_set_12", HB_TAG('s', 's', '1', '2'));
- _insert_feature("stylistic_set_13", HB_TAG('s', 's', '1', '3'));
- _insert_feature("stylistic_set_14", HB_TAG('s', 's', '1', '4'));
- _insert_feature("stylistic_set_15", HB_TAG('s', 's', '1', '5'));
- _insert_feature("stylistic_set_16", HB_TAG('s', 's', '1', '6'));
- _insert_feature("stylistic_set_17", HB_TAG('s', 's', '1', '7'));
- _insert_feature("stylistic_set_18", HB_TAG('s', 's', '1', '8'));
- _insert_feature("stylistic_set_19", HB_TAG('s', 's', '1', '9'));
- _insert_feature("stylistic_set_20", HB_TAG('s', 's', '2', '0'));
- _insert_feature("math_script_style_alternates", HB_TAG('s', 's', 't', 'y'));
- _insert_feature("stretching_glyph_decomposition", HB_TAG('s', 't', 'c', 'h'));
- _insert_feature("subscript", HB_TAG('s', 'u', 'b', 's'));
- _insert_feature("superscript", HB_TAG('s', 'u', 'p', 's'));
- _insert_feature("swash", HB_TAG('s', 'w', 's', 'h'));
- _insert_feature("titling", HB_TAG('t', 'i', 't', 'l'));
- _insert_feature("trailing_jamo_forms", HB_TAG('t', 'j', 'm', 'o'));
- _insert_feature("traditional_name_forms", HB_TAG('t', 'n', 'a', 'm'));
- _insert_feature("tabular_figures", HB_TAG('t', 'n', 'u', 'm'));
- _insert_feature("traditional_forms", HB_TAG('t', 'r', 'a', 'd'));
- _insert_feature("third_widths", HB_TAG('t', 'w', 'i', 'd'));
- _insert_feature("unicase", HB_TAG('u', 'n', 'i', 'c'));
- _insert_feature("alternate_vertical_metrics", HB_TAG('v', 'a', 'l', 't'));
- _insert_feature("vattu_variants", HB_TAG('v', 'a', 't', 'u'));
- _insert_feature("vertical_writing", HB_TAG('v', 'e', 'r', 't'));
- _insert_feature("alternate_vertical_half_metrics", HB_TAG('v', 'h', 'a', 'l'));
- _insert_feature("vowel_jamo_forms", HB_TAG('v', 'j', 'm', 'o'));
- _insert_feature("vertical_kana_alternates", HB_TAG('v', 'k', 'n', 'a'));
- _insert_feature("vertical_kerning", HB_TAG('v', 'k', 'r', 'n'));
- _insert_feature("proportional_alternate_vertical_metrics", HB_TAG('v', 'p', 'a', 'l'));
- _insert_feature("vertical_alternates_and_rotation", HB_TAG('v', 'r', 't', '2'));
- _insert_feature("vertical_alternates_for_rotation", HB_TAG('v', 'r', 't', 'r'));
- _insert_feature("slashed_zero", HB_TAG('z', 'e', 'r', 'o'));
+ // Name, Tag, Data Type, Hidden
+ _insert_feature("access_all_alternates", HB_TAG('a', 'a', 'l', 't'), Variant::Type::INT, false);
+ _insert_feature("above_base_forms", HB_TAG('a', 'b', 'v', 'f'), Variant::Type::INT, true);
+ _insert_feature("above_base_mark_positioning", HB_TAG('a', 'b', 'v', 'm'), Variant::Type::INT, true);
+ _insert_feature("above_base_substitutions", HB_TAG('a', 'b', 'v', 's'), Variant::Type::INT, true);
+ _insert_feature("alternative_fractions", HB_TAG('a', 'f', 'r', 'c'), Variant::Type::INT, false);
+ _insert_feature("akhands", HB_TAG('a', 'k', 'h', 'n'), Variant::Type::INT, true);
+ _insert_feature("below_base_forms", HB_TAG('b', 'l', 'w', 'f'), Variant::Type::INT, true);
+ _insert_feature("below_base_mark_positioning", HB_TAG('b', 'l', 'w', 'm'), Variant::Type::INT, true);
+ _insert_feature("below_base_substitutions", HB_TAG('b', 'l', 'w', 's'), Variant::Type::INT, true);
+ _insert_feature("contextual_alternates", HB_TAG('c', 'a', 'l', 't'), Variant::Type::BOOL, false);
+ _insert_feature("case_sensitive_forms", HB_TAG('c', 'a', 's', 'e'), Variant::Type::BOOL, false);
+ _insert_feature("glyph_composition", HB_TAG('c', 'c', 'm', 'p'), Variant::Type::INT, true);
+ _insert_feature("conjunct_form_after_ro", HB_TAG('c', 'f', 'a', 'r'), Variant::Type::INT, true);
+ _insert_feature("contextual_half_width_spacing", HB_TAG('c', 'h', 'w', 's'), Variant::Type::INT, true);
+ _insert_feature("conjunct_forms", HB_TAG('c', 'j', 'c', 't'), Variant::Type::INT, true);
+ _insert_feature("contextual_ligatures", HB_TAG('c', 'l', 'i', 'g'), Variant::Type::BOOL, false);
+ _insert_feature("centered_cjk_punctuation", HB_TAG('c', 'p', 'c', 't'), Variant::Type::BOOL, false);
+ _insert_feature("capital_spacing", HB_TAG('c', 'p', 's', 'p'), Variant::Type::BOOL, false);
+ _insert_feature("contextual_swash", HB_TAG('c', 's', 'w', 'h'), Variant::Type::INT, false);
+ _insert_feature("cursive_positioning", HB_TAG('c', 'u', 'r', 's'), Variant::Type::INT, true);
+ _insert_feature("character_variant_01", HB_TAG('c', 'v', '0', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_02", HB_TAG('c', 'v', '0', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_03", HB_TAG('c', 'v', '0', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_04", HB_TAG('c', 'v', '0', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_05", HB_TAG('c', 'v', '0', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_06", HB_TAG('c', 'v', '0', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_07", HB_TAG('c', 'v', '0', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_08", HB_TAG('c', 'v', '0', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_09", HB_TAG('c', 'v', '0', '9'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_10", HB_TAG('c', 'v', '1', '0'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_11", HB_TAG('c', 'v', '1', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_12", HB_TAG('c', 'v', '1', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_13", HB_TAG('c', 'v', '1', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_14", HB_TAG('c', 'v', '1', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_15", HB_TAG('c', 'v', '1', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_16", HB_TAG('c', 'v', '1', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_17", HB_TAG('c', 'v', '1', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_18", HB_TAG('c', 'v', '1', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_19", HB_TAG('c', 'v', '1', '9'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_20", HB_TAG('c', 'v', '2', '0'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_21", HB_TAG('c', 'v', '2', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_22", HB_TAG('c', 'v', '2', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_23", HB_TAG('c', 'v', '2', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_24", HB_TAG('c', 'v', '2', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_25", HB_TAG('c', 'v', '2', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_26", HB_TAG('c', 'v', '2', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_27", HB_TAG('c', 'v', '2', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_28", HB_TAG('c', 'v', '2', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_29", HB_TAG('c', 'v', '2', '9'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_30", HB_TAG('c', 'v', '3', '0'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_31", HB_TAG('c', 'v', '3', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_32", HB_TAG('c', 'v', '3', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_33", HB_TAG('c', 'v', '3', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_34", HB_TAG('c', 'v', '3', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_35", HB_TAG('c', 'v', '3', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_36", HB_TAG('c', 'v', '3', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_37", HB_TAG('c', 'v', '3', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_38", HB_TAG('c', 'v', '3', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_39", HB_TAG('c', 'v', '3', '9'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_40", HB_TAG('c', 'v', '4', '0'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_41", HB_TAG('c', 'v', '4', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_42", HB_TAG('c', 'v', '4', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_43", HB_TAG('c', 'v', '4', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_44", HB_TAG('c', 'v', '4', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_45", HB_TAG('c', 'v', '4', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_46", HB_TAG('c', 'v', '4', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_47", HB_TAG('c', 'v', '4', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_48", HB_TAG('c', 'v', '4', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_49", HB_TAG('c', 'v', '4', '9'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_50", HB_TAG('c', 'v', '5', '0'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_51", HB_TAG('c', 'v', '5', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_52", HB_TAG('c', 'v', '5', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_53", HB_TAG('c', 'v', '5', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_54", HB_TAG('c', 'v', '5', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_55", HB_TAG('c', 'v', '5', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_56", HB_TAG('c', 'v', '5', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_57", HB_TAG('c', 'v', '5', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_58", HB_TAG('c', 'v', '5', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_59", HB_TAG('c', 'v', '5', '9'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_60", HB_TAG('c', 'v', '6', '0'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_61", HB_TAG('c', 'v', '6', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_62", HB_TAG('c', 'v', '6', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_63", HB_TAG('c', 'v', '6', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_64", HB_TAG('c', 'v', '6', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_65", HB_TAG('c', 'v', '6', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_66", HB_TAG('c', 'v', '6', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_67", HB_TAG('c', 'v', '6', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_68", HB_TAG('c', 'v', '6', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_69", HB_TAG('c', 'v', '6', '9'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_70", HB_TAG('c', 'v', '7', '0'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_71", HB_TAG('c', 'v', '7', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_72", HB_TAG('c', 'v', '7', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_73", HB_TAG('c', 'v', '7', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_74", HB_TAG('c', 'v', '7', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_75", HB_TAG('c', 'v', '7', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_76", HB_TAG('c', 'v', '7', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_77", HB_TAG('c', 'v', '7', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_78", HB_TAG('c', 'v', '7', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_79", HB_TAG('c', 'v', '7', '9'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_80", HB_TAG('c', 'v', '8', '0'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_81", HB_TAG('c', 'v', '8', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_82", HB_TAG('c', 'v', '8', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_83", HB_TAG('c', 'v', '8', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_84", HB_TAG('c', 'v', '8', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_85", HB_TAG('c', 'v', '8', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_86", HB_TAG('c', 'v', '8', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_87", HB_TAG('c', 'v', '8', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_88", HB_TAG('c', 'v', '8', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_89", HB_TAG('c', 'v', '8', '9'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_90", HB_TAG('c', 'v', '9', '0'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_91", HB_TAG('c', 'v', '9', '1'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_92", HB_TAG('c', 'v', '9', '2'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_93", HB_TAG('c', 'v', '9', '3'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_94", HB_TAG('c', 'v', '9', '4'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_95", HB_TAG('c', 'v', '9', '5'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_96", HB_TAG('c', 'v', '9', '6'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_97", HB_TAG('c', 'v', '9', '7'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_98", HB_TAG('c', 'v', '9', '8'), Variant::Type::BOOL, false);
+ _insert_feature("character_variant_99", HB_TAG('c', 'v', '9', '9'), Variant::Type::BOOL, false);
+ _insert_feature("petite_capitals_from_capitals", HB_TAG('c', '2', 'p', 'c'), Variant::Type::BOOL, false);
+ _insert_feature("small_capitals_from_capitals", HB_TAG('c', '2', 's', 'c'), Variant::Type::BOOL, false);
+ _insert_feature("distances", HB_TAG('d', 'i', 's', 't'), Variant::Type::INT, true);
+ _insert_feature("discretionary_ligatures", HB_TAG('d', 'l', 'i', 'g'), Variant::Type::BOOL, false);
+ _insert_feature("denominators", HB_TAG('d', 'n', 'o', 'm'), Variant::Type::BOOL, false);
+ _insert_feature("dotless_forms", HB_TAG('d', 't', 'l', 's'), Variant::Type::INT, true);
+ _insert_feature("expert_forms", HB_TAG('e', 'x', 'p', 't'), Variant::Type::BOOL, true);
+ _insert_feature("final_glyph_on_line_alternates", HB_TAG('f', 'a', 'l', 't'), Variant::Type::INT, false);
+ _insert_feature("terminal_forms_2", HB_TAG('f', 'i', 'n', '2'), Variant::Type::INT, true);
+ _insert_feature("terminal_forms_3", HB_TAG('f', 'i', 'n', '3'), Variant::Type::INT, true);
+ _insert_feature("terminal_forms", HB_TAG('f', 'i', 'n', 'a'), Variant::Type::INT, true);
+ _insert_feature("flattened_accent_forms", HB_TAG('f', 'l', 'a', 'c'), Variant::Type::INT, true);
+ _insert_feature("fractions", HB_TAG('f', 'r', 'a', 'c'), Variant::Type::BOOL, false);
+ _insert_feature("full_widths", HB_TAG('f', 'w', 'i', 'd'), Variant::Type::BOOL, false);
+ _insert_feature("half_forms", HB_TAG('h', 'a', 'l', 'f'), Variant::Type::INT, true);
+ _insert_feature("halant_forms", HB_TAG('h', 'a', 'l', 'n'), Variant::Type::INT, true);
+ _insert_feature("alternate_half_widths", HB_TAG('h', 'a', 'l', 't'), Variant::Type::BOOL, false);
+ _insert_feature("historical_forms", HB_TAG('h', 'i', 's', 't'), Variant::Type::INT, false);
+ _insert_feature("horizontal_kana_alternates", HB_TAG('h', 'k', 'n', 'a'), Variant::Type::BOOL, false);
+ _insert_feature("historical_ligatures", HB_TAG('h', 'l', 'i', 'g'), Variant::Type::BOOL, false);
+ _insert_feature("hangul", HB_TAG('h', 'n', 'g', 'l'), Variant::Type::INT, false);
+ _insert_feature("hojo_kanji_forms", HB_TAG('h', 'o', 'j', 'o'), Variant::Type::INT, false);
+ _insert_feature("half_widths", HB_TAG('h', 'w', 'i', 'd'), Variant::Type::BOOL, false);
+ _insert_feature("initial_forms", HB_TAG('i', 'n', 'i', 't'), Variant::Type::INT, true);
+ _insert_feature("isolated_forms", HB_TAG('i', 's', 'o', 'l'), Variant::Type::INT, true);
+ _insert_feature("italics", HB_TAG('i', 't', 'a', 'l'), Variant::Type::INT, false);
+ _insert_feature("justification_alternates", HB_TAG('j', 'a', 'l', 't'), Variant::Type::INT, false);
+ _insert_feature("jis78_forms", HB_TAG('j', 'p', '7', '8'), Variant::Type::INT, false);
+ _insert_feature("jis83_forms", HB_TAG('j', 'p', '8', '3'), Variant::Type::INT, false);
+ _insert_feature("jis90_forms", HB_TAG('j', 'p', '9', '0'), Variant::Type::INT, false);
+ _insert_feature("jis2004_forms", HB_TAG('j', 'p', '0', '4'), Variant::Type::INT, false);
+ _insert_feature("kerning", HB_TAG('k', 'e', 'r', 'n'), Variant::Type::BOOL, false);
+ _insert_feature("left_bounds", HB_TAG('l', 'f', 'b', 'd'), Variant::Type::INT, false);
+ _insert_feature("standard_ligatures", HB_TAG('l', 'i', 'g', 'a'), Variant::Type::BOOL, false);
+ _insert_feature("leading_jamo_forms", HB_TAG('l', 'j', 'm', 'o'), Variant::Type::INT, true);
+ _insert_feature("lining_figures", HB_TAG('l', 'n', 'u', 'm'), Variant::Type::INT, false);
+ _insert_feature("localized_forms", HB_TAG('l', 'o', 'c', 'l'), Variant::Type::INT, true);
+ _insert_feature("left_to_right_alternates", HB_TAG('l', 't', 'r', 'a'), Variant::Type::INT, true);
+ _insert_feature("left_to_right_mirrored_forms", HB_TAG('l', 't', 'r', 'm'), Variant::Type::INT, true);
+ _insert_feature("mark_positioning", HB_TAG('m', 'a', 'r', 'k'), Variant::Type::INT, true);
+ _insert_feature("medial_forms_2", HB_TAG('m', 'e', 'd', '2'), Variant::Type::INT, true);
+ _insert_feature("medial_forms", HB_TAG('m', 'e', 'd', 'i'), Variant::Type::INT, true);
+ _insert_feature("mathematical_greek", HB_TAG('m', 'g', 'r', 'k'), Variant::Type::BOOL, false);
+ _insert_feature("mark_to_mark_positioning", HB_TAG('m', 'k', 'm', 'k'), Variant::Type::INT, true);
+ _insert_feature("mark_positioning_via_substitution", HB_TAG('m', 's', 'e', 't'), Variant::Type::INT, true);
+ _insert_feature("alternate_annotation_forms", HB_TAG('n', 'a', 'l', 't'), Variant::Type::INT, false);
+ _insert_feature("nlc_kanji_forms", HB_TAG('n', 'l', 'c', 'k'), Variant::Type::INT, false);
+ _insert_feature("nukta_forms", HB_TAG('n', 'u', 'k', 't'), Variant::Type::INT, true);
+ _insert_feature("numerators", HB_TAG('n', 'u', 'm', 'r'), Variant::Type::BOOL, false);
+ _insert_feature("oldstyle_figures", HB_TAG('o', 'n', 'u', 'm'), Variant::Type::INT, false);
+ _insert_feature("optical_bounds", HB_TAG('o', 'p', 'b', 'd'), Variant::Type::INT, true);
+ _insert_feature("ordinals", HB_TAG('o', 'r', 'd', 'n'), Variant::Type::BOOL, false);
+ _insert_feature("ornaments", HB_TAG('o', 'r', 'n', 'm'), Variant::Type::INT, false);
+ _insert_feature("proportional_alternate_widths", HB_TAG('p', 'a', 'l', 't'), Variant::Type::BOOL, false);
+ _insert_feature("petite_capitals", HB_TAG('p', 'c', 'a', 'p'), Variant::Type::BOOL, false);
+ _insert_feature("proportional_kana", HB_TAG('p', 'k', 'n', 'a'), Variant::Type::BOOL, false);
+ _insert_feature("proportional_figures", HB_TAG('p', 'n', 'u', 'm'), Variant::Type::BOOL, false);
+ _insert_feature("pre_base_forms", HB_TAG('p', 'r', 'e', 'f'), Variant::Type::INT, true);
+ _insert_feature("pre_base_substitutions", HB_TAG('p', 'r', 'e', 's'), Variant::Type::INT, true);
+ _insert_feature("post_base_forms", HB_TAG('p', 's', 't', 'f'), Variant::Type::INT, true);
+ _insert_feature("post_base_substitutions", HB_TAG('p', 's', 't', 's'), Variant::Type::INT, true);
+ _insert_feature("proportional_widths", HB_TAG('p', 'w', 'i', 'd'), Variant::Type::BOOL, false);
+ _insert_feature("quarter_widths", HB_TAG('q', 'w', 'i', 'd'), Variant::Type::BOOL, false);
+ _insert_feature("randomize", HB_TAG('r', 'a', 'n', 'd'), Variant::Type::INT, false);
+ _insert_feature("required_contextual_alternates", HB_TAG('r', 'c', 'l', 't'), Variant::Type::BOOL, true);
+ _insert_feature("rakar_forms", HB_TAG('r', 'k', 'r', 'f'), Variant::Type::INT, true);
+ _insert_feature("required_ligatures", HB_TAG('r', 'l', 'i', 'g'), Variant::Type::BOOL, true);
+ _insert_feature("reph_forms", HB_TAG('r', 'p', 'h', 'f'), Variant::Type::INT, true);
+ _insert_feature("right_bounds", HB_TAG('r', 't', 'b', 'd'), Variant::Type::INT, false);
+ _insert_feature("right_to_left_alternates", HB_TAG('r', 't', 'l', 'a'), Variant::Type::INT, true);
+ _insert_feature("right_to_left_mirrored_forms", HB_TAG('r', 't', 'l', 'm'), Variant::Type::INT, true);
+ _insert_feature("ruby_notation_forms", HB_TAG('r', 'u', 'b', 'y'), Variant::Type::INT, false);
+ _insert_feature("required_variation_alternates", HB_TAG('r', 'v', 'r', 'n'), Variant::Type::INT, true);
+ _insert_feature("stylistic_alternates", HB_TAG('s', 'a', 'l', 't'), Variant::Type::INT, false);
+ _insert_feature("scientific_inferiors", HB_TAG('s', 'i', 'n', 'f'), Variant::Type::BOOL, false);
+ _insert_feature("optical_size", HB_TAG('s', 'i', 'z', 'e'), Variant::Type::INT, false);
+ _insert_feature("small_capitals", HB_TAG('s', 'm', 'c', 'p'), Variant::Type::BOOL, false);
+ _insert_feature("simplified_forms", HB_TAG('s', 'm', 'p', 'l'), Variant::Type::INT, false);
+ _insert_feature("stylistic_set_01", HB_TAG('s', 's', '0', '1'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_02", HB_TAG('s', 's', '0', '2'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_03", HB_TAG('s', 's', '0', '3'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_04", HB_TAG('s', 's', '0', '4'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_05", HB_TAG('s', 's', '0', '5'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_06", HB_TAG('s', 's', '0', '6'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_07", HB_TAG('s', 's', '0', '7'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_08", HB_TAG('s', 's', '0', '8'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_09", HB_TAG('s', 's', '0', '9'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_10", HB_TAG('s', 's', '1', '0'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_11", HB_TAG('s', 's', '1', '1'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_12", HB_TAG('s', 's', '1', '2'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_13", HB_TAG('s', 's', '1', '3'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_14", HB_TAG('s', 's', '1', '4'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_15", HB_TAG('s', 's', '1', '5'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_16", HB_TAG('s', 's', '1', '6'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_17", HB_TAG('s', 's', '1', '7'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_18", HB_TAG('s', 's', '1', '8'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_19", HB_TAG('s', 's', '1', '9'), Variant::Type::BOOL, false);
+ _insert_feature("stylistic_set_20", HB_TAG('s', 's', '2', '0'), Variant::Type::BOOL, false);
+ _insert_feature("math_script_style_alternates", HB_TAG('s', 's', 't', 'y'), Variant::Type::INT, true);
+ _insert_feature("stretching_glyph_decomposition", HB_TAG('s', 't', 'c', 'h'), Variant::Type::INT, true);
+ _insert_feature("subscript", HB_TAG('s', 'u', 'b', 's'), Variant::Type::BOOL, false);
+ _insert_feature("superscript", HB_TAG('s', 'u', 'p', 's'), Variant::Type::BOOL, false);
+ _insert_feature("swash", HB_TAG('s', 'w', 's', 'h'), Variant::Type::INT, false);
+ _insert_feature("titling", HB_TAG('t', 'i', 't', 'l'), Variant::Type::BOOL, false);
+ _insert_feature("trailing_jamo_forms", HB_TAG('t', 'j', 'm', 'o'), Variant::Type::INT, true);
+ _insert_feature("traditional_name_forms", HB_TAG('t', 'n', 'a', 'm'), Variant::Type::INT, false);
+ _insert_feature("tabular_figures", HB_TAG('t', 'n', 'u', 'm'), Variant::Type::BOOL, false);
+ _insert_feature("traditional_forms", HB_TAG('t', 'r', 'a', 'd'), Variant::Type::INT, false);
+ _insert_feature("third_widths", HB_TAG('t', 'w', 'i', 'd'), Variant::Type::BOOL, false);
+ _insert_feature("unicase", HB_TAG('u', 'n', 'i', 'c'), Variant::Type::BOOL, false);
+ _insert_feature("alternate_vertical_metrics", HB_TAG('v', 'a', 'l', 't'), Variant::Type::INT, false);
+ _insert_feature("vattu_variants", HB_TAG('v', 'a', 't', 'u'), Variant::Type::INT, true);
+ _insert_feature("vertical_contextual_half_width_spacing", HB_TAG('v', 'c', 'h', 'w'), Variant::Type::BOOL, false);
+ _insert_feature("vertical_alternates", HB_TAG('v', 'e', 'r', 't'), Variant::Type::INT, false);
+ _insert_feature("alternate_vertical_half_metrics", HB_TAG('v', 'h', 'a', 'l'), Variant::Type::BOOL, false);
+ _insert_feature("vowel_jamo_forms", HB_TAG('v', 'j', 'm', 'o'), Variant::Type::INT, true);
+ _insert_feature("vertical_kana_alternates", HB_TAG('v', 'k', 'n', 'a'), Variant::Type::INT, false);
+ _insert_feature("vertical_kerning", HB_TAG('v', 'k', 'r', 'n'), Variant::Type::BOOL, false);
+ _insert_feature("proportional_alternate_vertical_metrics", HB_TAG('v', 'p', 'a', 'l'), Variant::Type::BOOL, false);
+ _insert_feature("vertical_alternates_and_rotation", HB_TAG('v', 'r', 't', '2'), Variant::Type::INT, false);
+ _insert_feature("vertical_alternates_for_rotation", HB_TAG('v', 'r', 't', 'r'), Variant::Type::INT, false);
+ _insert_feature("slashed_zero", HB_TAG('z', 'e', 'r', 'o'), Variant::Type::BOOL, false);
// Registered OpenType variation tag.
- _insert_feature("italic", HB_TAG('i', 't', 'a', 'l'));
- _insert_feature("optical_size", HB_TAG('o', 'p', 's', 'z'));
- _insert_feature("slant", HB_TAG('s', 'l', 'n', 't'));
- _insert_feature("width", HB_TAG('w', 'd', 't', 'h'));
- _insert_feature("weight", HB_TAG('w', 'g', 'h', 't'));
+ _insert_feature("italic", HB_TAG('i', 't', 'a', 'l'), Variant::Type::INT, false);
+ _insert_feature("optical_size", HB_TAG('o', 'p', 's', 'z'), Variant::Type::INT, false);
+ _insert_feature("slant", HB_TAG('s', 'l', 'n', 't'), Variant::Type::INT, false);
+ _insert_feature("width", HB_TAG('w', 'd', 't', 'h'), Variant::Type::INT, false);
+ _insert_feature("weight", HB_TAG('w', 'g', 'h', 't'), Variant::Type::INT, false);
}
int64_t TextServerAdvanced::name_to_tag(const String &p_name) const {
@@ -740,9 +748,23 @@ int64_t TextServerAdvanced::name_to_tag(const String &p_name) const {
return hb_tag_from_string(p_name.replace("custom_", "").ascii().get_data(), -1);
}
+Variant::Type TextServerAdvanced::_get_tag_type(int64_t p_tag) const {
+ if (feature_sets_inv.has(p_tag)) {
+ return feature_sets_inv[p_tag].vtype;
+ }
+ return Variant::Type::INT;
+}
+
+bool TextServerAdvanced::_get_tag_hidden(int64_t p_tag) const {
+ if (feature_sets_inv.has(p_tag)) {
+ return feature_sets_inv[p_tag].hidden;
+ }
+ return false;
+}
+
String TextServerAdvanced::tag_to_name(int64_t p_tag) const {
if (feature_sets_inv.has(p_tag)) {
- return feature_sets_inv[p_tag];
+ return feature_sets_inv[p_tag].name;
}
// No readable name, use tag string.
@@ -756,7 +778,7 @@ String TextServerAdvanced::tag_to_name(int64_t p_tag) const {
/* Font Glyph Rendering */
/*************************************************************************/
-_FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_texture_pos_for_glyph(FontDataForSizeAdvanced *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const {
+_FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_texture_pos_for_glyph(FontForSizeAdvanced *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const {
FontTexturePosition ret;
ret.index = -1;
@@ -953,7 +975,7 @@ void TextServerAdvanced::_generateMTSDF_threaded(uint32_t y, void *p_td) const {
}
}
-_FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(FontDataAdvanced *p_font_data, FontDataForSizeAdvanced *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const {
+_FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(FontAdvanced *p_font_data, FontForSizeAdvanced *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const {
msdfgen::Shape shape;
shape.contours.clear();
@@ -1059,7 +1081,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
#endif
#ifdef MODULE_FREETYPE_ENABLED
-_FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitmap(FontDataForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const {
+_FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitmap(FontForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const {
int w = bitmap.width;
int h = bitmap.rows;
@@ -1136,12 +1158,12 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
/* Font Cache */
/*************************************************************************/
-_FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontDataAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph) const {
+_FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph) const {
ERR_FAIL_COND_V(!_ensure_cache_for_size(p_font_data, p_size), false);
int32_t glyph_index = p_glyph & 0xffffff; // Remove subpixel shifts.
- FontDataForSizeAdvanced *fd = p_font_data->cache[p_size];
+ FontForSizeAdvanced *fd = p_font_data->cache[p_size];
if (fd->glyph_map.has(p_glyph)) {
return fd->glyph_map[p_glyph].found;
}
@@ -1260,13 +1282,13 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontDataAdvanced *p_font_d
return false;
}
-_FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced *p_font_data, const Vector2i &p_size) const {
+_FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size) const {
ERR_FAIL_COND_V(p_size.x <= 0, false);
if (p_font_data->cache.has(p_size)) {
return true;
}
- FontDataForSizeAdvanced *fd = memnew(FontDataForSizeAdvanced);
+ FontForSizeAdvanced *fd = memnew(FontForSizeAdvanced);
fd->size = p_size;
if (p_font_data->data_ptr && (p_font_data->data_size > 0)) {
// Init dynamic font.
@@ -1350,29 +1372,31 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced
}
p_font_data->style_flags = 0;
if (fd->face->style_flags & FT_STYLE_FLAG_BOLD) {
- p_font_data->style_flags |= FONT_BOLD;
+ p_font_data->style_flags.set_flag(FONT_BOLD);
}
if (fd->face->style_flags & FT_STYLE_FLAG_ITALIC) {
- p_font_data->style_flags |= FONT_ITALIC;
+ p_font_data->style_flags.set_flag(FONT_ITALIC);
}
if (fd->face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) {
- p_font_data->style_flags |= FONT_FIXED_WIDTH;
+ p_font_data->style_flags.set_flag(FONT_FIXED_WIDTH);
}
+
+ hb_face_t *hb_face = hb_font_get_face(fd->hb_handle);
// Get supported scripts from OpenType font data.
p_font_data->supported_scripts.clear();
- unsigned int count = hb_ot_layout_table_get_script_tags(hb_font_get_face(fd->hb_handle), HB_OT_TAG_GSUB, 0, nullptr, nullptr);
+ unsigned int count = hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GSUB, 0, nullptr, nullptr);
if (count != 0) {
hb_tag_t *script_tags = (hb_tag_t *)memalloc(count * sizeof(hb_tag_t));
- hb_ot_layout_table_get_script_tags(hb_font_get_face(fd->hb_handle), HB_OT_TAG_GSUB, 0, &count, script_tags);
+ hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GSUB, 0, &count, script_tags);
for (unsigned int i = 0; i < count; i++) {
p_font_data->supported_scripts.insert(script_tags[i]);
}
memfree(script_tags);
}
- count = hb_ot_layout_table_get_script_tags(hb_font_get_face(fd->hb_handle), HB_OT_TAG_GPOS, 0, nullptr, nullptr);
+ count = hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GPOS, 0, nullptr, nullptr);
if (count != 0) {
hb_tag_t *script_tags = (hb_tag_t *)memalloc(count * sizeof(hb_tag_t));
- hb_ot_layout_table_get_script_tags(hb_font_get_face(fd->hb_handle), HB_OT_TAG_GPOS, 0, &count, script_tags);
+ hb_ot_layout_table_get_script_tags(hb_face, HB_OT_TAG_GPOS, 0, &count, script_tags);
for (unsigned int i = 0; i < count; i++) {
p_font_data->supported_scripts.insert(script_tags[i]);
}
@@ -1596,21 +1620,49 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced
// Read OpenType feature tags.
p_font_data->supported_features.clear();
- count = hb_ot_layout_table_get_feature_tags(hb_font_get_face(fd->hb_handle), HB_OT_TAG_GSUB, 0, nullptr, nullptr);
+ count = hb_ot_layout_table_get_feature_tags(hb_face, HB_OT_TAG_GSUB, 0, nullptr, nullptr);
if (count != 0) {
hb_tag_t *feature_tags = (hb_tag_t *)memalloc(count * sizeof(hb_tag_t));
- hb_ot_layout_table_get_feature_tags(hb_font_get_face(fd->hb_handle), HB_OT_TAG_GSUB, 0, &count, feature_tags);
+ hb_ot_layout_table_get_feature_tags(hb_face, HB_OT_TAG_GSUB, 0, &count, feature_tags);
for (unsigned int i = 0; i < count; i++) {
- p_font_data->supported_features[feature_tags[i]] = 1;
+ Dictionary ftr;
+
+ hb_ot_name_id_t lbl_id;
+ if (hb_ot_layout_feature_get_name_ids(hb_face, HB_OT_TAG_GSUB, i, &lbl_id, nullptr, nullptr, nullptr, nullptr)) {
+ PackedInt32Array lbl;
+ unsigned int text_size = hb_ot_name_get_utf32(hb_face, lbl_id, hb_language_from_string(TranslationServer::get_singleton()->get_tool_locale().ascii().get_data(), -1), nullptr, nullptr) + 1;
+ lbl.resize(text_size);
+ memset((uint32_t *)lbl.ptrw(), 0, sizeof(uint32_t) * text_size);
+ hb_ot_name_get_utf32(hb_face, lbl_id, hb_language_from_string(TranslationServer::get_singleton()->get_tool_locale().ascii().get_data(), -1), &text_size, (uint32_t *)lbl.ptrw());
+ ftr["label"] = String((const char32_t *)lbl.ptr());
+ }
+ ftr["type"] = _get_tag_type(feature_tags[i]);
+ ftr["hidden"] = _get_tag_hidden(feature_tags[i]);
+
+ p_font_data->supported_features[feature_tags[i]] = ftr;
}
memfree(feature_tags);
}
- count = hb_ot_layout_table_get_feature_tags(hb_font_get_face(fd->hb_handle), HB_OT_TAG_GPOS, 0, nullptr, nullptr);
+ count = hb_ot_layout_table_get_feature_tags(hb_face, HB_OT_TAG_GPOS, 0, nullptr, nullptr);
if (count != 0) {
hb_tag_t *feature_tags = (hb_tag_t *)memalloc(count * sizeof(hb_tag_t));
- hb_ot_layout_table_get_feature_tags(hb_font_get_face(fd->hb_handle), HB_OT_TAG_GPOS, 0, &count, feature_tags);
+ hb_ot_layout_table_get_feature_tags(hb_face, HB_OT_TAG_GPOS, 0, &count, feature_tags);
for (unsigned int i = 0; i < count; i++) {
- p_font_data->supported_features[feature_tags[i]] = 1;
+ Dictionary ftr;
+
+ hb_ot_name_id_t lbl_id;
+ if (hb_ot_layout_feature_get_name_ids(hb_face, HB_OT_TAG_GPOS, i, &lbl_id, nullptr, nullptr, nullptr, nullptr)) {
+ PackedInt32Array lbl;
+ unsigned int text_size = hb_ot_name_get_utf32(hb_face, lbl_id, hb_language_from_string(TranslationServer::get_singleton()->get_tool_locale().ascii().get_data(), -1), nullptr, nullptr) + 1;
+ lbl.resize(text_size);
+ memset((uint32_t *)lbl.ptrw(), 0, sizeof(uint32_t) * text_size);
+ hb_ot_name_get_utf32(hb_face, lbl_id, hb_language_from_string(TranslationServer::get_singleton()->get_tool_locale().ascii().get_data(), -1), &text_size, (uint32_t *)lbl.ptrw());
+ ftr["label"] = String((const char32_t *)lbl.ptr());
+ }
+ ftr["type"] = _get_tag_type(feature_tags[i]);
+ ftr["hidden"] = _get_tag_hidden(feature_tags[i]);
+
+ p_font_data->supported_features[feature_tags[i]] = ftr;
}
memfree(feature_tags);
}
@@ -1676,8 +1728,8 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced
return true;
}
-_FORCE_INLINE_ void TextServerAdvanced::_font_clear_cache(FontDataAdvanced *p_font_data) {
- for (const KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : p_font_data->cache) {
+_FORCE_INLINE_ void TextServerAdvanced::_font_clear_cache(FontAdvanced *p_font_data) {
+ for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : p_font_data->cache) {
memdelete(E.value);
}
p_font_data->cache.clear();
@@ -1688,7 +1740,7 @@ _FORCE_INLINE_ void TextServerAdvanced::_font_clear_cache(FontDataAdvanced *p_fo
}
hb_font_t *TextServerAdvanced::_font_get_hb_handle(const RID &p_font_rid, int64_t p_size) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, nullptr);
MutexLock lock(fd->mutex);
@@ -1702,13 +1754,13 @@ hb_font_t *TextServerAdvanced::_font_get_hb_handle(const RID &p_font_rid, int64_
RID TextServerAdvanced::create_font() {
_THREAD_SAFE_METHOD_
- FontDataAdvanced *fd = memnew(FontDataAdvanced);
+ FontAdvanced *fd = memnew(FontAdvanced);
return font_owner.make_rid(fd);
}
void TextServerAdvanced::font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1719,7 +1771,7 @@ void TextServerAdvanced::font_set_data(const RID &p_font_rid, const PackedByteAr
}
void TextServerAdvanced::font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1733,7 +1785,7 @@ void TextServerAdvanced::font_set_face_index(const RID &p_font_rid, int64_t p_fa
ERR_FAIL_COND(p_face_index < 0);
ERR_FAIL_COND(p_face_index >= 0x7FFF);
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1744,7 +1796,7 @@ void TextServerAdvanced::font_set_face_index(const RID &p_font_rid, int64_t p_fa
}
int64_t TextServerAdvanced::font_get_face_index(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
MutexLock lock(fd->mutex);
@@ -1752,7 +1804,7 @@ int64_t TextServerAdvanced::font_get_face_index(const RID &p_font_rid) const {
}
int64_t TextServerAdvanced::font_get_face_count(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
MutexLock lock(fd->mutex);
@@ -1792,8 +1844,8 @@ int64_t TextServerAdvanced::font_get_face_count(const RID &p_font_rid) const {
return face_count;
}
-void TextServerAdvanced::font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+void TextServerAdvanced::font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) {
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1802,8 +1854,8 @@ void TextServerAdvanced::font_set_style(const RID &p_font_rid, int64_t /*FontSty
fd->style_flags = p_style;
}
-int64_t /*FontStyle*/ TextServerAdvanced::font_get_style(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+BitField<TextServer::FontStyle> TextServerAdvanced::font_get_style(const RID &p_font_rid) const {
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
MutexLock lock(fd->mutex);
@@ -1813,7 +1865,7 @@ int64_t /*FontStyle*/ TextServerAdvanced::font_get_style(const RID &p_font_rid)
}
void TextServerAdvanced::font_set_style_name(const RID &p_font_rid, const String &p_name) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1823,7 +1875,7 @@ void TextServerAdvanced::font_set_style_name(const RID &p_font_rid, const String
}
String TextServerAdvanced::font_get_style_name(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
MutexLock lock(fd->mutex);
@@ -1833,7 +1885,7 @@ String TextServerAdvanced::font_get_style_name(const RID &p_font_rid) const {
}
void TextServerAdvanced::font_set_name(const RID &p_font_rid, const String &p_name) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1843,7 +1895,7 @@ void TextServerAdvanced::font_set_name(const RID &p_font_rid, const String &p_na
}
String TextServerAdvanced::font_get_name(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
MutexLock lock(fd->mutex);
@@ -1853,7 +1905,7 @@ String TextServerAdvanced::font_get_name(const RID &p_font_rid) const {
}
void TextServerAdvanced::font_set_antialiased(const RID &p_font_rid, bool p_antialiased) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1864,7 +1916,7 @@ void TextServerAdvanced::font_set_antialiased(const RID &p_font_rid, bool p_anti
}
bool TextServerAdvanced::font_is_antialiased(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1872,12 +1924,12 @@ bool TextServerAdvanced::font_is_antialiased(const RID &p_font_rid) const {
}
void TextServerAdvanced::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
if (fd->mipmaps != p_generate_mipmaps) {
- for (KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : fd->cache) {
+ for (KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
for (int i = 0; i < E.value->textures.size(); i++) {
E.value->textures.write[i].dirty = true;
}
@@ -1887,7 +1939,7 @@ void TextServerAdvanced::font_set_generate_mipmaps(const RID &p_font_rid, bool p
}
bool TextServerAdvanced::font_get_generate_mipmaps(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1895,7 +1947,7 @@ bool TextServerAdvanced::font_get_generate_mipmaps(const RID &p_font_rid) const
}
void TextServerAdvanced::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1906,7 +1958,7 @@ void TextServerAdvanced::font_set_multichannel_signed_distance_field(const RID &
}
bool TextServerAdvanced::font_is_multichannel_signed_distance_field(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1914,7 +1966,7 @@ bool TextServerAdvanced::font_is_multichannel_signed_distance_field(const RID &p
}
void TextServerAdvanced::font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1925,7 +1977,7 @@ void TextServerAdvanced::font_set_msdf_pixel_range(const RID &p_font_rid, int64_
}
int64_t TextServerAdvanced::font_get_msdf_pixel_range(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1933,7 +1985,7 @@ int64_t TextServerAdvanced::font_get_msdf_pixel_range(const RID &p_font_rid) con
}
void TextServerAdvanced::font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1944,7 +1996,7 @@ void TextServerAdvanced::font_set_msdf_size(const RID &p_font_rid, int64_t p_msd
}
int64_t TextServerAdvanced::font_get_msdf_size(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1952,7 +2004,7 @@ int64_t TextServerAdvanced::font_get_msdf_size(const RID &p_font_rid) const {
}
void TextServerAdvanced::font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1960,7 +2012,7 @@ void TextServerAdvanced::font_set_fixed_size(const RID &p_font_rid, int64_t p_fi
}
int64_t TextServerAdvanced::font_get_fixed_size(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1968,7 +2020,7 @@ int64_t TextServerAdvanced::font_get_fixed_size(const RID &p_font_rid) const {
}
void TextServerAdvanced::font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1979,7 +2031,7 @@ void TextServerAdvanced::font_set_force_autohinter(const RID &p_font_rid, bool p
}
bool TextServerAdvanced::font_is_force_autohinter(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1987,7 +2039,7 @@ bool TextServerAdvanced::font_is_force_autohinter(const RID &p_font_rid) const {
}
void TextServerAdvanced::font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1998,7 +2050,7 @@ void TextServerAdvanced::font_set_hinting(const RID &p_font_rid, TextServer::Hin
}
TextServer::Hinting TextServerAdvanced::font_get_hinting(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, HINTING_NONE);
MutexLock lock(fd->mutex);
@@ -2006,7 +2058,7 @@ TextServer::Hinting TextServerAdvanced::font_get_hinting(const RID &p_font_rid)
}
void TextServerAdvanced::font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2014,7 +2066,7 @@ void TextServerAdvanced::font_set_subpixel_positioning(const RID &p_font_rid, Te
}
TextServer::SubpixelPositioning TextServerAdvanced::font_get_subpixel_positioning(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, SUBPIXEL_POSITIONING_DISABLED);
MutexLock lock(fd->mutex);
@@ -2022,7 +2074,7 @@ TextServer::SubpixelPositioning TextServerAdvanced::font_get_subpixel_positionin
}
void TextServerAdvanced::font_set_embolden(const RID &p_font_rid, double p_strength) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2033,7 +2085,7 @@ void TextServerAdvanced::font_set_embolden(const RID &p_font_rid, double p_stren
}
double TextServerAdvanced::font_get_embolden(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -2041,7 +2093,7 @@ double TextServerAdvanced::font_get_embolden(const RID &p_font_rid) const {
}
void TextServerAdvanced::font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2052,7 +2104,7 @@ void TextServerAdvanced::font_set_transform(const RID &p_font_rid, const Transfo
}
Transform2D TextServerAdvanced::font_get_transform(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Transform2D());
MutexLock lock(fd->mutex);
@@ -2060,7 +2112,7 @@ Transform2D TextServerAdvanced::font_get_transform(const RID &p_font_rid) const
}
void TextServerAdvanced::font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2071,7 +2123,7 @@ void TextServerAdvanced::font_set_variation_coordinates(const RID &p_font_rid, c
}
Dictionary TextServerAdvanced::font_get_variation_coordinates(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
@@ -2079,7 +2131,7 @@ Dictionary TextServerAdvanced::font_get_variation_coordinates(const RID &p_font_
}
void TextServerAdvanced::font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2090,7 +2142,7 @@ void TextServerAdvanced::font_set_oversampling(const RID &p_font_rid, double p_o
}
double TextServerAdvanced::font_get_oversampling(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -2098,30 +2150,30 @@ double TextServerAdvanced::font_get_oversampling(const RID &p_font_rid) const {
}
Array TextServerAdvanced::font_get_size_cache_list(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Array());
MutexLock lock(fd->mutex);
Array ret;
- for (const KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : fd->cache) {
+ for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
ret.push_back(E.key);
}
return ret;
}
void TextServerAdvanced::font_clear_size_cache(const RID &p_font_rid) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
- for (const KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : fd->cache) {
+ for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
memdelete(E.value);
}
fd->cache.clear();
}
void TextServerAdvanced::font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2132,7 +2184,7 @@ void TextServerAdvanced::font_remove_size_cache(const RID &p_font_rid, const Vec
}
void TextServerAdvanced::font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2143,7 +2195,7 @@ void TextServerAdvanced::font_set_ascent(const RID &p_font_rid, int64_t p_size,
}
double TextServerAdvanced::font_get_ascent(const RID &p_font_rid, int64_t p_size) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -2159,7 +2211,7 @@ double TextServerAdvanced::font_get_ascent(const RID &p_font_rid, int64_t p_size
}
void TextServerAdvanced::font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
Vector2i size = _get_size(fd, p_size);
@@ -2169,7 +2221,7 @@ void TextServerAdvanced::font_set_descent(const RID &p_font_rid, int64_t p_size,
}
double TextServerAdvanced::font_get_descent(const RID &p_font_rid, int64_t p_size) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -2185,7 +2237,7 @@ double TextServerAdvanced::font_get_descent(const RID &p_font_rid, int64_t p_siz
}
void TextServerAdvanced::font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2196,7 +2248,7 @@ void TextServerAdvanced::font_set_underline_position(const RID &p_font_rid, int6
}
double TextServerAdvanced::font_get_underline_position(const RID &p_font_rid, int64_t p_size) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -2212,7 +2264,7 @@ double TextServerAdvanced::font_get_underline_position(const RID &p_font_rid, in
}
void TextServerAdvanced::font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2223,7 +2275,7 @@ void TextServerAdvanced::font_set_underline_thickness(const RID &p_font_rid, int
}
double TextServerAdvanced::font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -2239,7 +2291,7 @@ double TextServerAdvanced::font_get_underline_thickness(const RID &p_font_rid, i
}
void TextServerAdvanced::font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2255,7 +2307,7 @@ void TextServerAdvanced::font_set_scale(const RID &p_font_rid, int64_t p_size, d
}
double TextServerAdvanced::font_get_scale(const RID &p_font_rid, int64_t p_size) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -2270,60 +2322,8 @@ double TextServerAdvanced::font_get_scale(const RID &p_font_rid, int64_t p_size)
}
}
-void TextServerAdvanced::font_set_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing, int64_t p_value) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
- ERR_FAIL_COND(!fd);
-
- MutexLock lock(fd->mutex);
- Vector2i size = _get_size(fd, p_size);
-
- ERR_FAIL_COND(!_ensure_cache_for_size(fd, size));
- switch (p_spacing) {
- case TextServer::SPACING_GLYPH: {
- fd->cache[size]->spacing_glyph = p_value;
- } break;
- case TextServer::SPACING_SPACE: {
- fd->cache[size]->spacing_space = p_value;
- } break;
- default: {
- ERR_FAIL_MSG("Invalid spacing type: " + String::num_int64(p_spacing));
- } break;
- }
-}
-
-int64_t TextServerAdvanced::font_get_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
- ERR_FAIL_COND_V(!fd, 0);
-
- MutexLock lock(fd->mutex);
- Vector2i size = _get_size(fd, p_size);
-
- ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0);
-
- switch (p_spacing) {
- case TextServer::SPACING_GLYPH: {
- if (fd->msdf) {
- return fd->cache[size]->spacing_glyph * (double)p_size / (double)fd->msdf_source_size;
- } else {
- return fd->cache[size]->spacing_glyph;
- }
- } break;
- case TextServer::SPACING_SPACE: {
- if (fd->msdf) {
- return fd->cache[size]->spacing_space * (double)p_size / (double)fd->msdf_source_size;
- } else {
- return fd->cache[size]->spacing_space;
- }
- } break;
- default: {
- ERR_FAIL_V_MSG(0, "Invalid spacing type: " + String::num_int64(p_spacing));
- } break;
- }
- return 0;
-}
-
int64_t TextServerAdvanced::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
MutexLock lock(fd->mutex);
@@ -2335,7 +2335,7 @@ int64_t TextServerAdvanced::font_get_texture_count(const RID &p_font_rid, const
}
void TextServerAdvanced::font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
Vector2i size = _get_size_outline(fd, p_size);
@@ -2345,7 +2345,7 @@ void TextServerAdvanced::font_clear_textures(const RID &p_font_rid, const Vector
}
void TextServerAdvanced::font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2357,7 +2357,7 @@ void TextServerAdvanced::font_remove_texture(const RID &p_font_rid, const Vector
}
void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND(p_image.is_null());
@@ -2383,14 +2383,12 @@ void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vec
img->generate_mipmaps();
}
- tex.texture = Ref<ImageTexture>();
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
tex.dirty = false;
}
Ref<Image> TextServerAdvanced::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Ref<Image>());
MutexLock lock(fd->mutex);
@@ -2407,7 +2405,7 @@ Ref<Image> TextServerAdvanced::font_get_texture_image(const RID &p_font_rid, con
}
void TextServerAdvanced::font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2423,7 +2421,7 @@ void TextServerAdvanced::font_set_texture_offsets(const RID &p_font_rid, const V
}
PackedInt32Array TextServerAdvanced::font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedInt32Array());
MutexLock lock(fd->mutex);
@@ -2436,7 +2434,7 @@ PackedInt32Array TextServerAdvanced::font_get_texture_offsets(const RID &p_font_
}
Array TextServerAdvanced::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Array());
MutexLock lock(fd->mutex);
@@ -2452,7 +2450,7 @@ Array TextServerAdvanced::font_get_glyph_list(const RID &p_font_rid, const Vecto
}
void TextServerAdvanced::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2463,7 +2461,7 @@ void TextServerAdvanced::font_clear_glyphs(const RID &p_font_rid, const Vector2i
}
void TextServerAdvanced::font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2474,7 +2472,7 @@ void TextServerAdvanced::font_remove_glyph(const RID &p_font_rid, const Vector2i
}
double TextServerAdvanced::_get_extra_advance(RID p_font_rid, int p_font_size) const {
- const FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ const FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -2488,7 +2486,7 @@ double TextServerAdvanced::_get_extra_advance(RID p_font_rid, int p_font_size) c
}
Vector2 TextServerAdvanced::font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
MutexLock lock(fd->mutex);
@@ -2516,7 +2514,7 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(const RID &p_font_rid, int64_
}
void TextServerAdvanced::font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2531,7 +2529,7 @@ void TextServerAdvanced::font_set_glyph_advance(const RID &p_font_rid, int64_t p
}
Vector2 TextServerAdvanced::font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
MutexLock lock(fd->mutex);
@@ -2552,7 +2550,7 @@ Vector2 TextServerAdvanced::font_get_glyph_offset(const RID &p_font_rid, const V
}
void TextServerAdvanced::font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2567,7 +2565,7 @@ void TextServerAdvanced::font_set_glyph_offset(const RID &p_font_rid, const Vect
}
Vector2 TextServerAdvanced::font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
MutexLock lock(fd->mutex);
@@ -2588,7 +2586,7 @@ Vector2 TextServerAdvanced::font_get_glyph_size(const RID &p_font_rid, const Vec
}
void TextServerAdvanced::font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2603,7 +2601,7 @@ void TextServerAdvanced::font_set_glyph_size(const RID &p_font_rid, const Vector
}
Rect2 TextServerAdvanced::font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Rect2());
MutexLock lock(fd->mutex);
@@ -2619,7 +2617,7 @@ Rect2 TextServerAdvanced::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
}
void TextServerAdvanced::font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2634,7 +2632,7 @@ void TextServerAdvanced::font_set_glyph_uv_rect(const RID &p_font_rid, const Vec
}
int64_t TextServerAdvanced::font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, -1);
MutexLock lock(fd->mutex);
@@ -2650,7 +2648,7 @@ int64_t TextServerAdvanced::font_get_glyph_texture_idx(const RID &p_font_rid, co
}
void TextServerAdvanced::font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2665,7 +2663,7 @@ void TextServerAdvanced::font_set_glyph_texture_idx(const RID &p_font_rid, const
}
RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, RID());
MutexLock lock(fd->mutex);
@@ -2690,8 +2688,7 @@ RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const
img->generate_mipmaps();
}
if (tex.texture.is_null()) {
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
} else {
tex.texture->update(img);
}
@@ -2705,7 +2702,7 @@ RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const
}
Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Size2());
MutexLock lock(fd->mutex);
@@ -2730,8 +2727,7 @@ Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, con
img->generate_mipmaps();
}
if (tex.texture.is_null()) {
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
} else {
tex.texture->update(img);
}
@@ -2745,7 +2741,7 @@ Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, con
}
Dictionary TextServerAdvanced::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
@@ -2795,7 +2791,7 @@ Dictionary TextServerAdvanced::font_get_glyph_contours(const RID &p_font_rid, in
}
Array TextServerAdvanced::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Array());
MutexLock lock(fd->mutex);
@@ -2804,14 +2800,14 @@ Array TextServerAdvanced::font_get_kerning_list(const RID &p_font_rid, int64_t p
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Array());
Array ret;
- for (const KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : fd->cache) {
+ for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
ret.push_back(E.key);
}
return ret;
}
void TextServerAdvanced::font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2822,7 +2818,7 @@ void TextServerAdvanced::font_clear_kerning_map(const RID &p_font_rid, int64_t p
}
void TextServerAdvanced::font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2833,7 +2829,7 @@ void TextServerAdvanced::font_remove_kerning(const RID &p_font_rid, int64_t p_si
}
void TextServerAdvanced::font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2844,7 +2840,7 @@ void TextServerAdvanced::font_set_kerning(const RID &p_font_rid, int64_t p_size,
}
Vector2 TextServerAdvanced::font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
MutexLock lock(fd->mutex);
@@ -2877,7 +2873,7 @@ Vector2 TextServerAdvanced::font_get_kerning(const RID &p_font_rid, int64_t p_si
}
int64_t TextServerAdvanced::font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), 0, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + ".");
ERR_FAIL_COND_V_MSG((p_variation_selector >= 0xd800 && p_variation_selector <= 0xdfff) || (p_variation_selector > 0x10ffff), 0, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_variation_selector, 16) + ".");
@@ -2902,7 +2898,7 @@ int64_t TextServerAdvanced::font_get_glyph_index(const RID &p_font_rid, int64_t
}
bool TextServerAdvanced::font_has_char(const RID &p_font_rid, int64_t p_char) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), false, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + ".");
@@ -2910,7 +2906,7 @@ bool TextServerAdvanced::font_has_char(const RID &p_font_rid, int64_t p_char) co
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0)), false);
}
- FontDataForSizeAdvanced *at_size = fd->cache.begin()->value;
+ FontForSizeAdvanced *at_size = fd->cache.begin()->value;
#ifdef MODULE_FREETYPE_ENABLED
if (at_size && at_size->face) {
@@ -2921,14 +2917,14 @@ bool TextServerAdvanced::font_has_char(const RID &p_font_rid, int64_t p_char) co
}
String TextServerAdvanced::font_get_supported_chars(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
MutexLock lock(fd->mutex);
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0)), String());
}
- FontDataForSizeAdvanced *at_size = fd->cache.begin()->value;
+ FontForSizeAdvanced *at_size = fd->cache.begin()->value;
String chars;
#ifdef MODULE_FREETYPE_ENABLED
@@ -2954,7 +2950,7 @@ String TextServerAdvanced::font_get_supported_chars(const RID &p_font_rid) const
}
void TextServerAdvanced::font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND_MSG((p_start >= 0xd800 && p_start <= 0xdfff) || (p_start > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_start, 16) + ".");
ERR_FAIL_COND_MSG((p_end >= 0xd800 && p_end <= 0xdfff) || (p_end > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_end, 16) + ".");
@@ -2987,7 +2983,7 @@ void TextServerAdvanced::font_render_range(const RID &p_font_rid, const Vector2i
}
void TextServerAdvanced::font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -3016,7 +3012,7 @@ void TextServerAdvanced::font_render_glyph(const RID &p_font_rid, const Vector2i
}
void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -3062,8 +3058,7 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
img->generate_mipmaps();
}
if (tex.texture.is_null()) {
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
} else {
tex.texture->update(img);
}
@@ -3095,7 +3090,7 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
}
void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -3141,8 +3136,7 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
img->generate_mipmaps();
}
if (tex.texture.is_null()) {
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
} else {
tex.texture->update(img);
}
@@ -3174,7 +3168,7 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
}
bool TextServerAdvanced::font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -3186,7 +3180,7 @@ bool TextServerAdvanced::font_is_language_supported(const RID &p_font_rid, const
}
void TextServerAdvanced::font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -3194,7 +3188,7 @@ void TextServerAdvanced::font_set_language_support_override(const RID &p_font_ri
}
bool TextServerAdvanced::font_get_language_support_override(const RID &p_font_rid, const String &p_language) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -3202,7 +3196,7 @@ bool TextServerAdvanced::font_get_language_support_override(const RID &p_font_ri
}
void TextServerAdvanced::font_remove_language_support_override(const RID &p_font_rid, const String &p_language) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -3210,7 +3204,7 @@ void TextServerAdvanced::font_remove_language_support_override(const RID &p_font
}
PackedStringArray TextServerAdvanced::font_get_language_support_overrides(const RID &p_font_rid) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
MutexLock lock(fd->mutex);
@@ -3222,7 +3216,7 @@ PackedStringArray TextServerAdvanced::font_get_language_support_overrides(const
}
bool TextServerAdvanced::font_is_script_supported(const RID &p_font_rid, const String &p_script) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -3236,7 +3230,7 @@ bool TextServerAdvanced::font_is_script_supported(const RID &p_font_rid, const S
}
void TextServerAdvanced::font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -3244,7 +3238,7 @@ void TextServerAdvanced::font_set_script_support_override(const RID &p_font_rid,
}
bool TextServerAdvanced::font_get_script_support_override(const RID &p_font_rid, const String &p_script) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -3252,7 +3246,7 @@ bool TextServerAdvanced::font_get_script_support_override(const RID &p_font_rid,
}
void TextServerAdvanced::font_remove_script_support_override(const RID &p_font_rid, const String &p_script) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -3260,7 +3254,7 @@ void TextServerAdvanced::font_remove_script_support_override(const RID &p_font_r
}
PackedStringArray TextServerAdvanced::font_get_script_support_overrides(const RID &p_font_rid) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
MutexLock lock(fd->mutex);
@@ -3272,7 +3266,7 @@ PackedStringArray TextServerAdvanced::font_get_script_support_overrides(const RI
}
void TextServerAdvanced::font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -3282,7 +3276,7 @@ void TextServerAdvanced::font_set_opentype_feature_overrides(const RID &p_font_r
}
Dictionary TextServerAdvanced::font_get_opentype_feature_overrides(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
@@ -3290,7 +3284,7 @@ Dictionary TextServerAdvanced::font_get_opentype_feature_overrides(const RID &p_
}
Dictionary TextServerAdvanced::font_supported_feature_list(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
@@ -3300,7 +3294,7 @@ Dictionary TextServerAdvanced::font_supported_feature_list(const RID &p_font_rid
}
Dictionary TextServerAdvanced::font_supported_variation_list(const RID &p_font_rid) const {
- FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
@@ -3580,6 +3574,31 @@ bool TextServerAdvanced::shaped_text_get_preserve_control(const RID &p_shaped) c
return sd->preserve_control;
}
+void TextServerAdvanced::shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) {
+ ERR_FAIL_INDEX((int)p_spacing, 4);
+ ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND(!sd);
+
+ MutexLock lock(sd->mutex);
+ if (sd->extra_spacing[p_spacing] != p_value) {
+ if (sd->parent != RID()) {
+ full_copy(sd);
+ }
+ sd->extra_spacing[p_spacing] = p_value;
+ invalidate(sd, false);
+ }
+}
+
+int64_t TextServerAdvanced::shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const {
+ ERR_FAIL_INDEX_V((int)p_spacing, 4, 0);
+
+ const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V(!sd, 0);
+
+ MutexLock lock(sd->mutex);
+ return sd->extra_spacing[p_spacing];
+}
+
TextServer::Orientation TextServerAdvanced::shaped_text_get_orientation(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, TextServer::ORIENTATION_HORIZONTAL);
@@ -3847,6 +3866,9 @@ RID TextServerAdvanced::shaped_text_substr(const RID &p_shaped, int64_t p_start,
new_sd->direction = sd->direction;
new_sd->custom_punct = sd->custom_punct;
new_sd->para_direction = sd->para_direction;
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ new_sd->extra_spacing[i] = sd->extra_spacing[i];
+ }
if (!_shape_substr(new_sd, sd, p_start, p_length)) {
memdelete(new_sd);
@@ -3972,7 +3994,7 @@ RID TextServerAdvanced::shaped_text_get_parent(const RID &p_shaped) const {
return sd->parent;
}
-double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags) {
+double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
@@ -3988,7 +4010,7 @@ double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double
int start_pos = 0;
int end_pos = sd->glyphs.size() - 1;
- if ((p_jst_flags & JUSTIFICATION_AFTER_LAST_TAB) == JUSTIFICATION_AFTER_LAST_TAB) {
+ if (p_jst_flags.has_flag(JUSTIFICATION_AFTER_LAST_TAB)) {
int start, end, delta;
if (sd->para_direction == DIRECTION_LTR) {
start = sd->glyphs.size() - 1;
@@ -4014,7 +4036,7 @@ double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double
}
double justification_width;
- if ((p_jst_flags & JUSTIFICATION_CONSTRAIN_ELLIPSIS) == JUSTIFICATION_CONSTRAIN_ELLIPSIS) {
+ if (p_jst_flags.has_flag(JUSTIFICATION_CONSTRAIN_ELLIPSIS)) {
if (sd->overrun_trim_data.trim_pos >= 0) {
if (sd->para_direction == DIRECTION_RTL) {
start_pos = sd->overrun_trim_data.trim_pos;
@@ -4029,7 +4051,7 @@ double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double
justification_width = sd->width;
}
- if ((p_jst_flags & JUSTIFICATION_TRIM_EDGE_SPACES) == JUSTIFICATION_TRIM_EDGE_SPACES) {
+ if (p_jst_flags.has_flag(JUSTIFICATION_TRIM_EDGE_SPACES)) {
// Trim spaces.
while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
justification_width -= sd->glyphs[start_pos].advance * sd->glyphs[start_pos].repeat;
@@ -4068,7 +4090,7 @@ double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double
}
}
- if ((elongation_count > 0) && ((p_jst_flags & JUSTIFICATION_KASHIDA) == JUSTIFICATION_KASHIDA)) {
+ if ((elongation_count > 0) && p_jst_flags.has_flag(JUSTIFICATION_KASHIDA)) {
double delta_width_per_kashida = (p_width - justification_width) / elongation_count;
for (int i = start_pos; i <= end_pos; i++) {
Glyph &gl = sd->glyphs.write[i];
@@ -4089,7 +4111,7 @@ double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double
}
}
}
- if ((space_count > 0) && ((p_jst_flags & JUSTIFICATION_WORD_BOUND) == JUSTIFICATION_WORD_BOUND)) {
+ if ((space_count > 0) && p_jst_flags.has_flag(JUSTIFICATION_WORD_BOUND)) {
double delta_width_per_space = (p_width - justification_width) / space_count;
double adv_remain = 0;
for (int i = start_pos; i <= end_pos; i++) {
@@ -4122,7 +4144,7 @@ double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double
sd->fit_width_minimum_reached = true;
}
- if ((p_jst_flags & JUSTIFICATION_CONSTRAIN_ELLIPSIS) != JUSTIFICATION_CONSTRAIN_ELLIPSIS) {
+ if (!p_jst_flags.has_flag(JUSTIFICATION_CONSTRAIN_ELLIPSIS)) {
sd->width = justification_width;
}
@@ -4185,7 +4207,7 @@ double TextServerAdvanced::shaped_text_tab_align(const RID &p_shaped, const Pack
return 0.0;
}
-void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, int64_t p_trim_flags) {
+void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped_line);
ERR_FAIL_COND_MSG(!sd, "ShapedTextDataAdvanced invalid.");
@@ -4197,14 +4219,14 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
sd->text_trimmed = false;
sd->overrun_trim_data.ellipsis_glyph_buf.clear();
- bool add_ellipsis = (p_trim_flags & OVERRUN_ADD_ELLIPSIS) == OVERRUN_ADD_ELLIPSIS;
- bool cut_per_word = (p_trim_flags & OVERRUN_TRIM_WORD_ONLY) == OVERRUN_TRIM_WORD_ONLY;
- bool enforce_ellipsis = (p_trim_flags & OVERRUN_ENFORCE_ELLIPSIS) == OVERRUN_ENFORCE_ELLIPSIS;
- bool justification_aware = (p_trim_flags & OVERRUN_JUSTIFICATION_AWARE) == OVERRUN_JUSTIFICATION_AWARE;
+ bool add_ellipsis = p_trim_flags.has_flag(OVERRUN_ADD_ELLIPSIS);
+ bool cut_per_word = p_trim_flags.has_flag(OVERRUN_TRIM_WORD_ONLY);
+ bool enforce_ellipsis = p_trim_flags.has_flag(OVERRUN_ENFORCE_ELLIPSIS);
+ bool justification_aware = p_trim_flags.has_flag(OVERRUN_JUSTIFICATION_AWARE);
Glyph *sd_glyphs = sd->glyphs.ptrw();
- if ((p_trim_flags & OVERRUN_TRIM) == OVERRUN_NO_TRIM || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) {
+ if (p_trim_flags.has_flag(OVERRUN_TRIM) || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) {
sd->overrun_trim_data.trim_pos = -1;
sd->overrun_trim_data.ellipsis_pos = -1;
return;
@@ -4257,7 +4279,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
int ellipsis_width = 0;
if (add_ellipsis && whitespace_gl_font_rid.is_valid()) {
- ellipsis_width = 3 * dot_adv.x + font_get_spacing(whitespace_gl_font_rid, last_gl_font_size, SPACING_GLYPH) + (cut_per_word ? whitespace_adv.x : 0);
+ ellipsis_width = 3 * dot_adv.x + sd->extra_spacing[SPACING_GLYPH] + (cut_per_word ? whitespace_adv.x : 0);
}
int ell_min_characters = 6;
@@ -4405,7 +4427,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(const RID &p_shaped) {
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);
+ UBreakIterator *bi = ubrk_open(UBRK_LINE, (language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale().ascii().get_data() : 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++) {
@@ -4851,15 +4873,16 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
}
RID f = p_fonts[p_fb_index];
- FontDataAdvanced *fd = font_owner.get_or_null(f);
+ FontAdvanced *fd = font_owner.get_or_null(f);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
Vector2i fss = _get_size(fd, fs);
hb_font_t *hb_font = _font_get_hb_handle(f, fs);
double scale = font_get_scale(f, fs);
- double sp_sp = font_get_spacing(f, fs, SPACING_SPACE);
- double sp_gl = font_get_spacing(f, fs, SPACING_GLYPH);
+ double sp_sp = p_sd->extra_spacing[SPACING_SPACE];
+ double sp_gl = p_sd->extra_spacing[SPACING_GLYPH];
+ bool last_run = (p_sd->end == p_end);
double ea = _get_extra_advance(f, fs);
bool subpos = (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_HALF) || (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_AUTO && fs <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
ERR_FAIL_COND(hb_font == nullptr);
@@ -4873,7 +4896,10 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
}
hb_buffer_set_script(p_sd->hb_buffer, p_script);
- if (!p_sd->spans[p_span].language.is_empty()) {
+ if (p_sd->spans[p_span].language.is_empty()) {
+ hb_language_t lang = hb_language_from_string(TranslationServer::get_singleton()->get_tool_locale().ascii().get_data(), -1);
+ hb_buffer_set_language(p_sd->hb_buffer, lang);
+ } else {
hb_language_t lang = hb_language_from_string(p_sd->spans[p_span].language.ascii().get_data(), -1);
hb_buffer_set_language(p_sd->hb_buffer, lang);
}
@@ -4954,10 +4980,13 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
}
gl.y_off = -Math::round(glyph_pos[i].y_offset / (64.0 / scale));
}
- if (sp_sp && is_whitespace(p_sd->text[glyph_info[i].cluster])) {
- gl.advance += sp_sp;
- } else {
- gl.advance += sp_gl;
+ if (!last_run || i < glyph_count - 1) {
+ // Do not add extra spacing to the last glyph of the string.
+ if (sp_sp && is_whitespace(p_sd->text[glyph_info[i].cluster])) {
+ gl.advance += sp_sp;
+ } else {
+ gl.advance += sp_gl;
+ }
}
if (p_sd->preserve_control) {
@@ -5288,9 +5317,9 @@ Size2 TextServerAdvanced::shaped_text_get_size(const RID &p_shaped) const {
const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
}
if (sd->orientation == TextServer::ORIENTATION_HORIZONTAL) {
- return Size2((sd->text_trimmed ? sd->width_trimmed : sd->width), sd->ascent + sd->descent).ceil();
+ return Size2((sd->text_trimmed ? sd->width_trimmed : sd->width), sd->ascent + sd->descent + sd->extra_spacing[SPACING_TOP] + sd->extra_spacing[SPACING_BOTTOM]).ceil();
} else {
- return Size2(sd->ascent + sd->descent, (sd->text_trimmed ? sd->width_trimmed : sd->width)).ceil();
+ return Size2(sd->ascent + sd->descent + sd->extra_spacing[SPACING_TOP] + sd->extra_spacing[SPACING_BOTTOM], (sd->text_trimmed ? sd->width_trimmed : sd->width)).ceil();
}
}
@@ -5302,7 +5331,7 @@ double TextServerAdvanced::shaped_text_get_ascent(const RID &p_shaped) const {
if (!sd->valid) {
const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
}
- return sd->ascent;
+ return sd->ascent + sd->extra_spacing[SPACING_TOP];
}
double TextServerAdvanced::shaped_text_get_descent(const RID &p_shaped) const {
@@ -5313,7 +5342,7 @@ double TextServerAdvanced::shaped_text_get_descent(const RID &p_shaped) const {
if (!sd->valid) {
const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
}
- return sd->descent;
+ return sd->descent + sd->extra_spacing[SPACING_BOTTOM];
}
double TextServerAdvanced::shaped_text_get_width(const RID &p_shaped) const {
@@ -5627,16 +5656,18 @@ String TextServerAdvanced::strip_diacritics(const String &p_string) const {
}
String TextServerAdvanced::string_to_upper(const String &p_string, const String &p_language) const {
+ const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
+
// Convert to UTF-16.
Char16String utf16 = p_string.utf16();
Vector<char16_t> upper;
UErrorCode err = U_ZERO_ERROR;
- int32_t len = u_strToUpper(nullptr, 0, utf16.get_data(), -1, p_language.ascii().get_data(), &err);
+ int32_t len = u_strToUpper(nullptr, 0, utf16.get_data(), -1, lang.ascii().get_data(), &err);
ERR_FAIL_COND_V_MSG(err != U_BUFFER_OVERFLOW_ERROR, p_string, u_errorName(err));
upper.resize(len);
err = U_ZERO_ERROR;
- u_strToUpper(upper.ptrw(), len, utf16.get_data(), -1, p_language.ascii().get_data(), &err);
+ u_strToUpper(upper.ptrw(), len, utf16.get_data(), -1, lang.ascii().get_data(), &err);
ERR_FAIL_COND_V_MSG(U_FAILURE(err), p_string, u_errorName(err));
// Convert back to UTF-32.
@@ -5644,16 +5675,17 @@ String TextServerAdvanced::string_to_upper(const String &p_string, const String
}
String TextServerAdvanced::string_to_lower(const String &p_string, const String &p_language) const {
+ const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
// Convert to UTF-16.
Char16String utf16 = p_string.utf16();
Vector<char16_t> lower;
UErrorCode err = U_ZERO_ERROR;
- int32_t len = u_strToLower(nullptr, 0, utf16.get_data(), -1, p_language.ascii().get_data(), &err);
+ int32_t len = u_strToLower(nullptr, 0, utf16.get_data(), -1, lang.ascii().get_data(), &err);
ERR_FAIL_COND_V_MSG(err != U_BUFFER_OVERFLOW_ERROR, p_string, u_errorName(err));
lower.resize(len);
err = U_ZERO_ERROR;
- u_strToLower(lower.ptrw(), len, utf16.get_data(), -1, p_language.ascii().get_data(), &err);
+ u_strToLower(lower.ptrw(), len, utf16.get_data(), -1, lang.ascii().get_data(), &err);
ERR_FAIL_COND_V_MSG(U_FAILURE(err), p_string, u_errorName(err));
// Convert back to UTF-32.
@@ -5661,12 +5693,13 @@ String TextServerAdvanced::string_to_lower(const String &p_string, const String
}
PackedInt32Array TextServerAdvanced::string_get_word_breaks(const String &p_string, const String &p_language) const {
+ const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
// Convert to UTF-16.
Char16String utf16 = p_string.utf16();
HashSet<int> breaks;
UErrorCode err = U_ZERO_ERROR;
- UBreakIterator *bi = ubrk_open(UBRK_LINE, p_language.ascii().get_data(), (const UChar *)utf16.get_data(), utf16.length(), &err);
+ UBreakIterator *bi = ubrk_open(UBRK_LINE, lang.ascii().get_data(), (const UChar *)utf16.get_data(), utf16.length(), &err);
if (U_FAILURE(err)) {
// No data loaded - use fallback.
for (int i = 0; i < p_string.length(); i++) {
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index e7690cb70d..a772955d90 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -133,12 +133,19 @@ class TextServerAdvanced : public TextServerExtension {
};
Vector<NumSystemData> num_systems;
+
+ struct FeatureInfo {
+ StringName name;
+ Variant::Type vtype = Variant::INT;
+ bool hidden = false;
+ };
+
HashMap<StringName, int32_t> feature_sets;
- HashMap<int32_t, StringName> feature_sets_inv;
+ HashMap<int32_t, FeatureInfo> feature_sets_inv;
void _insert_num_systems_lang();
void _insert_feature_sets();
- _FORCE_INLINE_ void _insert_feature(const StringName &p_name, int32_t p_tag);
+ _FORCE_INLINE_ void _insert_feature(const StringName &p_name, int32_t p_tag, Variant::Type p_vtype = Variant::INT, bool p_hidden = false);
// ICU support data.
@@ -176,7 +183,7 @@ class TextServerAdvanced : public TextServerExtension {
Vector2 advance;
};
- struct FontDataForSizeAdvanced {
+ struct FontForSizeAdvanced {
double ascent = 0.0;
double descent = 0.0;
double underline_position = 0.0;
@@ -184,9 +191,6 @@ class TextServerAdvanced : public TextServerExtension {
double scale = 1.0;
double oversampling = 1.0;
- int spacing_glyph = 0;
- int spacing_space = 0;
-
Vector2i size;
Vector<FontTexture> textures;
@@ -199,7 +203,7 @@ class TextServerAdvanced : public TextServerExtension {
FT_StreamRec stream;
#endif
- ~FontDataForSizeAdvanced() {
+ ~FontForSizeAdvanced() {
if (hb_handle != nullptr) {
hb_font_destroy(hb_handle);
}
@@ -211,7 +215,7 @@ class TextServerAdvanced : public TextServerExtension {
}
};
- struct FontDataAdvanced {
+ struct FontAdvanced {
Mutex mutex;
bool antialiased = true;
@@ -228,11 +232,11 @@ class TextServerAdvanced : public TextServerExtension {
double embolden = 0.0;
Transform2D transform;
- uint32_t style_flags = 0;
+ BitField<TextServer::FontStyle> style_flags = 0;
String font_name;
String style_name;
- HashMap<Vector2i, FontDataForSizeAdvanced *, VariantHasher, VariantComparator> cache;
+ HashMap<Vector2i, FontForSizeAdvanced *, VariantHasher, VariantComparator> cache;
bool face_init = false;
HashSet<uint32_t> supported_scripts;
@@ -250,28 +254,28 @@ class TextServerAdvanced : public TextServerExtension {
int face_index = 0;
mutable ThreadWorkPool work_pool;
- ~FontDataAdvanced() {
+ ~FontAdvanced() {
work_pool.finish();
- for (const KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : cache) {
+ for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : cache) {
memdelete(E.value);
}
cache.clear();
}
};
- _FORCE_INLINE_ FontTexturePosition find_texture_pos_for_glyph(FontDataForSizeAdvanced *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const;
+ _FORCE_INLINE_ FontTexturePosition find_texture_pos_for_glyph(FontForSizeAdvanced *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const;
#ifdef MODULE_MSDFGEN_ENABLED
- _FORCE_INLINE_ FontGlyph rasterize_msdf(FontDataAdvanced *p_font_data, FontDataForSizeAdvanced *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const;
+ _FORCE_INLINE_ FontGlyph rasterize_msdf(FontAdvanced *p_font_data, FontForSizeAdvanced *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const;
#endif
#ifdef MODULE_FREETYPE_ENABLED
- _FORCE_INLINE_ FontGlyph rasterize_bitmap(FontDataForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const;
+ _FORCE_INLINE_ FontGlyph rasterize_bitmap(FontForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const;
#endif
- _FORCE_INLINE_ bool _ensure_glyph(FontDataAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph) const;
- _FORCE_INLINE_ bool _ensure_cache_for_size(FontDataAdvanced *p_font_data, const Vector2i &p_size) const;
- _FORCE_INLINE_ void _font_clear_cache(FontDataAdvanced *p_font_data);
+ _FORCE_INLINE_ bool _ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph) const;
+ _FORCE_INLINE_ bool _ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size) const;
+ _FORCE_INLINE_ void _font_clear_cache(FontAdvanced *p_font_data);
void _generateMTSDF_threaded(uint32_t y, void *p_td) const;
- _FORCE_INLINE_ Vector2i _get_size(const FontDataAdvanced *p_font_data, int p_size) const {
+ _FORCE_INLINE_ Vector2i _get_size(const FontAdvanced *p_font_data, int p_size) const {
if (p_font_data->msdf) {
return Vector2i(p_font_data->msdf_source_size, 0);
} else if (p_font_data->fixed_size > 0) {
@@ -281,7 +285,7 @@ class TextServerAdvanced : public TextServerExtension {
}
}
- _FORCE_INLINE_ Vector2i _get_size_outline(const FontDataAdvanced *p_font_data, const Vector2i &p_size) const {
+ _FORCE_INLINE_ Vector2i _get_size_outline(const FontAdvanced *p_font_data, const Vector2i &p_size) const {
if (p_font_data->msdf) {
return Vector2i(p_font_data->msdf_source_size, 0);
} else if (p_font_data->fixed_size > 0) {
@@ -292,6 +296,8 @@ class TextServerAdvanced : public TextServerExtension {
}
_FORCE_INLINE_ double _get_extra_advance(RID p_font_rid, int p_font_size) const;
+ _FORCE_INLINE_ Variant::Type _get_tag_type(int64_t p_tag) const;
+ _FORCE_INLINE_ bool _get_tag_hidden(int64_t p_tag) const;
// Shaped text cache data.
struct TrimData {
@@ -351,6 +357,7 @@ class TextServerAdvanced : public TextServerExtension {
double descent = 0.0; // Descent for horizontal layout, 1/2 of width for vertical.
double width = 0.0; // Width for horizontal layout, height for vertical.
double width_trimmed = 0.0;
+ int extra_spacing[4] = { 0, 0, 0, 0 };
double upos = 0.0;
double uthk = 0.0;
@@ -389,7 +396,7 @@ class TextServerAdvanced : public TextServerExtension {
// Common data.
double oversampling = 1.0;
- mutable RID_PtrOwner<FontDataAdvanced> font_owner;
+ mutable RID_PtrOwner<FontAdvanced> font_owner;
mutable RID_PtrOwner<ShapedTextDataAdvanced> shaped_owner;
void _realign(ShapedTextDataAdvanced *p_sd) const;
@@ -407,11 +414,11 @@ class TextServerAdvanced : public TextServerExtension {
static hb_font_funcs_t *funcs;
struct bmp_font_t {
- TextServerAdvanced::FontDataForSizeAdvanced *face = nullptr;
+ TextServerAdvanced::FontForSizeAdvanced *face = nullptr;
bool unref = false; /* Whether to destroy bm_face when done. */
};
- static bmp_font_t *_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref);
+ static bmp_font_t *_bmp_font_create(TextServerAdvanced::FontForSizeAdvanced *p_face, bool p_unref);
static void _bmp_font_destroy(void *p_data);
static hb_bool_t _bmp_get_nominal_glyph(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_unicode, hb_codepoint_t *r_glyph, void *p_user_data);
static hb_position_t _bmp_get_glyph_h_advance(hb_font_t *p_font, void *p_font_data, hb_codepoint_t p_glyph, void *p_user_data);
@@ -422,8 +429,8 @@ class TextServerAdvanced : public TextServerExtension {
static hb_bool_t _bmp_get_font_h_extents(hb_font_t *p_font, void *p_font_data, hb_font_extents_t *r_metrics, void *p_user_data);
static void _bmp_create_font_funcs();
static void _bmp_free_font_funcs();
- static void _bmp_font_set_funcs(hb_font_t *p_font, TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref);
- static hb_font_t *_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, hb_destroy_func_t p_destroy);
+ static void _bmp_font_set_funcs(hb_font_t *p_font, TextServerAdvanced::FontForSizeAdvanced *p_face, bool p_unref);
+ static hb_font_t *_bmp_font_create(TextServerAdvanced::FontForSizeAdvanced *p_face, hb_destroy_func_t p_destroy);
hb_font_t *_font_get_hb_handle(const RID &p_font, int64_t p_font_size) const;
@@ -479,8 +486,8 @@ public:
virtual int64_t font_get_face_count(const RID &p_font_rid) const override;
- virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) override;
- virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const override;
+ virtual void font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) override;
+ virtual BitField<FontStyle> font_get_style(const RID &p_font_rid) const override;
virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) override;
virtual String font_get_style_name(const RID &p_font_rid) const override;
@@ -546,9 +553,6 @@ public:
virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) override;
virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const override;
- virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) override;
- virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const override;
-
virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override;
@@ -646,6 +650,9 @@ public:
virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) override;
virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const override;
+ virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) override;
+ virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const override;
+
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override;
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
@@ -657,7 +664,7 @@ public:
virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override;
virtual RID shaped_text_get_parent(const RID &p_shaped) const override;
- virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
+ virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override;
virtual bool shaped_text_shape(const RID &p_shaped) override;
@@ -669,7 +676,7 @@ public:
virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const override;
virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override;
- virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_t p_trim_flags) override;
+ virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) override;
virtual bool shaped_text_is_ready(const RID &p_shaped) const override;
diff --git a/modules/text_server_fb/gdextension_build/SConstruct b/modules/text_server_fb/gdextension_build/SConstruct
index 6c9e10db18..de0a549900 100644
--- a/modules/text_server_fb/gdextension_build/SConstruct
+++ b/modules/text_server_fb/gdextension_build/SConstruct
@@ -184,15 +184,15 @@ env.Append(CPPDEFINES=["GDEXTENSION"])
env.Append(CPPPATH=["../"])
sources = Glob("../*.cpp")
-if env["platform"] == "osx":
- methods.write_osx_plist(
- f'./bin/libtextserver_fallback.osx.{env["target"]}.framework',
- f'libtextserver_fallback.osx.{env["target"]}',
+if env["platform"] == "macos":
+ methods.write_macos_plist(
+ f'./bin/libtextserver_fallback.macos.{env["target"]}.framework',
+ f'libtextserver_fallback.macos.{env["target"]}',
"org.godotengine.textserver_fallback",
"Fallback Text Server",
)
library = env.SharedLibrary(
- f'./bin/libtextserver_fallback.osx.{env["target"]}.framework/libtextserver_fallback.osx.{env["target"]}',
+ f'./bin/libtextserver_fallback.macos.{env["target"]}.framework/libtextserver_fallback.macos.{env["target"]}',
source=sources,
)
else:
diff --git a/modules/text_server_fb/gdextension_build/methods.py b/modules/text_server_fb/gdextension_build/methods.py
index d404f2851e..3c5229462c 100644
--- a/modules/text_server_fb/gdextension_build/methods.py
+++ b/modules/text_server_fb/gdextension_build/methods.py
@@ -98,7 +98,7 @@ def make_icu_data(target, source, env):
g.write("#endif")
-def write_osx_plist(target, binary_name, identifier, name):
+def write_macos_plist(target, binary_name, identifier, name):
os.makedirs(f"{target}/Resourece/", exist_ok=True)
f = open(f"{target}/Resourece/Info.plist", "w")
diff --git a/modules/text_server_fb/gdextension_build/text_server_fb.gdextension b/modules/text_server_fb/gdextension_build/text_server_fb.gdextension
index 1026c6cb85..9236555d63 100644
--- a/modules/text_server_fb/gdextension_build/text_server_fb.gdextension
+++ b/modules/text_server_fb/gdextension_build/text_server_fb.gdextension
@@ -8,5 +8,5 @@ linux.64.debug = "bin/libtextserver_fallback.linux.debug.64.so"
linux.64.release = "bin/libtextserver_fallback.linux.release.64.so"
windows.64.debug = "bin/libtextserver_fallback.windows.debug.64.dll"
windows.64.release = "bin/libtextserver_fallback.windows.release.64.dll"
-macos.debug = "bin/libtextserver_fallback.osx.debug.framework"
-macos.release = "bin/libtextserver_fallback.osx.release.framework"
+macos.debug = "bin/libtextserver_fallback.macos.debug.framework"
+macos.release = "bin/libtextserver_fallback.macos.release.framework"
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index f93c5909c9..b845beb158 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -104,7 +104,7 @@ int64_t TextServerFallback::get_features() const {
void TextServerFallback::free_rid(const RID &p_rid) {
_THREAD_SAFE_METHOD_
if (font_owner.owns(p_rid)) {
- FontDataFallback *fd = font_owner.get_or_null(p_rid);
+ FontFallback *fd = font_owner.get_or_null(p_rid);
font_owner.free(p_rid);
memdelete(fd);
} else if (shaped_owner.owns(p_rid)) {
@@ -199,7 +199,7 @@ String TextServerFallback::tag_to_name(int64_t p_tag) const {
/* Font Glyph Rendering */
/*************************************************************************/
-_FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_texture_pos_for_glyph(FontDataForSizeFallback *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const {
+_FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_texture_pos_for_glyph(FontForSizeFallback *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const {
FontTexturePosition ret;
ret.index = -1;
@@ -397,7 +397,7 @@ void TextServerFallback::_generateMTSDF_threaded(uint32_t y, void *p_td) const {
}
}
-_FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf(FontDataFallback *p_font_data, FontDataForSizeFallback *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const {
+_FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf(FontFallback *p_font_data, FontForSizeFallback *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const {
msdfgen::Shape shape;
shape.contours.clear();
@@ -502,7 +502,7 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf(
#endif
#ifdef MODULE_FREETYPE_ENABLED
-_FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitmap(FontDataForSizeFallback *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const {
+_FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitmap(FontForSizeFallback *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const {
int w = bitmap.width;
int h = bitmap.rows;
@@ -579,12 +579,12 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma
/* Font Cache */
/*************************************************************************/
-_FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontDataFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph) const {
+_FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph) const {
ERR_FAIL_COND_V(!_ensure_cache_for_size(p_font_data, p_size), false);
int32_t glyph_index = p_glyph & 0xffffff; // Remove subpixel shifts.
- FontDataForSizeFallback *fd = p_font_data->cache[p_size];
+ FontForSizeFallback *fd = p_font_data->cache[p_size];
if (fd->glyph_map.has(p_glyph)) {
return fd->glyph_map[p_glyph].found;
}
@@ -705,13 +705,13 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontDataFallback *p_font_d
return false;
}
-_FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback *p_font_data, const Vector2i &p_size) const {
+_FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_font_data, const Vector2i &p_size) const {
ERR_FAIL_COND_V(p_size.x <= 0, false);
if (p_font_data->cache.has(p_size)) {
return true;
}
- FontDataForSizeFallback *fd = memnew(FontDataForSizeFallback);
+ FontForSizeFallback *fd = memnew(FontForSizeFallback);
fd->size = p_size;
if (p_font_data->data_ptr && (p_font_data->data_size > 0)) {
// Init dynamic font.
@@ -791,13 +791,13 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback
}
p_font_data->style_flags = 0;
if (fd->face->style_flags & FT_STYLE_FLAG_BOLD) {
- p_font_data->style_flags |= FONT_BOLD;
+ p_font_data->style_flags.set_flag(FONT_BOLD);
}
if (fd->face->style_flags & FT_STYLE_FLAG_ITALIC) {
- p_font_data->style_flags |= FONT_ITALIC;
+ p_font_data->style_flags.set_flag(FONT_ITALIC);
}
if (fd->face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) {
- p_font_data->style_flags |= FONT_FIXED_WIDTH;
+ p_font_data->style_flags.set_flag(FONT_FIXED_WIDTH);
}
// Read OpenType variations.
p_font_data->supported_varaitions.clear();
@@ -851,8 +851,8 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback
return true;
}
-_FORCE_INLINE_ void TextServerFallback::_font_clear_cache(FontDataFallback *p_font_data) {
- for (const KeyValue<Vector2i, FontDataForSizeFallback *> &E : p_font_data->cache) {
+_FORCE_INLINE_ void TextServerFallback::_font_clear_cache(FontFallback *p_font_data) {
+ for (const KeyValue<Vector2i, FontForSizeFallback *> &E : p_font_data->cache) {
memdelete(E.value);
}
@@ -864,13 +864,13 @@ _FORCE_INLINE_ void TextServerFallback::_font_clear_cache(FontDataFallback *p_fo
RID TextServerFallback::create_font() {
_THREAD_SAFE_METHOD_
- FontDataFallback *fd = memnew(FontDataFallback);
+ FontFallback *fd = memnew(FontFallback);
return font_owner.make_rid(fd);
}
void TextServerFallback::font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -881,7 +881,7 @@ void TextServerFallback::font_set_data(const RID &p_font_rid, const PackedByteAr
}
void TextServerFallback::font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -891,8 +891,8 @@ void TextServerFallback::font_set_data_ptr(const RID &p_font_rid, const uint8_t
fd->data_size = p_data_size;
}
-void TextServerFallback::font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+void TextServerFallback::font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) {
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -905,7 +905,7 @@ void TextServerFallback::font_set_face_index(const RID &p_font_rid, int64_t p_fa
ERR_FAIL_COND(p_face_index < 0);
ERR_FAIL_COND(p_face_index >= 0x7FFF);
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -916,7 +916,7 @@ void TextServerFallback::font_set_face_index(const RID &p_font_rid, int64_t p_fa
}
int64_t TextServerFallback::font_get_face_index(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
MutexLock lock(fd->mutex);
@@ -924,7 +924,7 @@ int64_t TextServerFallback::font_get_face_index(const RID &p_font_rid) const {
}
int64_t TextServerFallback::font_get_face_count(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
MutexLock lock(fd->mutex);
@@ -964,8 +964,8 @@ int64_t TextServerFallback::font_get_face_count(const RID &p_font_rid) const {
return face_count;
}
-int64_t /*FontStyle*/ TextServerFallback::font_get_style(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+BitField<TextServer::FontStyle> TextServerFallback::font_get_style(const RID &p_font_rid) const {
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
MutexLock lock(fd->mutex);
@@ -975,7 +975,7 @@ int64_t /*FontStyle*/ TextServerFallback::font_get_style(const RID &p_font_rid)
}
void TextServerFallback::font_set_style_name(const RID &p_font_rid, const String &p_name) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -985,7 +985,7 @@ void TextServerFallback::font_set_style_name(const RID &p_font_rid, const String
}
String TextServerFallback::font_get_style_name(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
MutexLock lock(fd->mutex);
@@ -995,7 +995,7 @@ String TextServerFallback::font_get_style_name(const RID &p_font_rid) const {
}
void TextServerFallback::font_set_name(const RID &p_font_rid, const String &p_name) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1005,7 +1005,7 @@ void TextServerFallback::font_set_name(const RID &p_font_rid, const String &p_na
}
String TextServerFallback::font_get_name(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
MutexLock lock(fd->mutex);
@@ -1015,7 +1015,7 @@ String TextServerFallback::font_get_name(const RID &p_font_rid) const {
}
void TextServerFallback::font_set_antialiased(const RID &p_font_rid, bool p_antialiased) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1026,7 +1026,7 @@ void TextServerFallback::font_set_antialiased(const RID &p_font_rid, bool p_anti
}
bool TextServerFallback::font_is_antialiased(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1034,12 +1034,12 @@ bool TextServerFallback::font_is_antialiased(const RID &p_font_rid) const {
}
void TextServerFallback::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
if (fd->mipmaps != p_generate_mipmaps) {
- for (KeyValue<Vector2i, FontDataForSizeFallback *> &E : fd->cache) {
+ for (KeyValue<Vector2i, FontForSizeFallback *> &E : fd->cache) {
for (int i = 0; i < E.value->textures.size(); i++) {
E.value->textures.write[i].dirty = true;
}
@@ -1049,7 +1049,7 @@ void TextServerFallback::font_set_generate_mipmaps(const RID &p_font_rid, bool p
}
bool TextServerFallback::font_get_generate_mipmaps(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1057,7 +1057,7 @@ bool TextServerFallback::font_get_generate_mipmaps(const RID &p_font_rid) const
}
void TextServerFallback::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1068,7 +1068,7 @@ void TextServerFallback::font_set_multichannel_signed_distance_field(const RID &
}
bool TextServerFallback::font_is_multichannel_signed_distance_field(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1076,7 +1076,7 @@ bool TextServerFallback::font_is_multichannel_signed_distance_field(const RID &p
}
void TextServerFallback::font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1087,7 +1087,7 @@ void TextServerFallback::font_set_msdf_pixel_range(const RID &p_font_rid, int64_
}
int64_t TextServerFallback::font_get_msdf_pixel_range(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1095,7 +1095,7 @@ int64_t TextServerFallback::font_get_msdf_pixel_range(const RID &p_font_rid) con
}
void TextServerFallback::font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1106,7 +1106,7 @@ void TextServerFallback::font_set_msdf_size(const RID &p_font_rid, int64_t p_msd
}
int64_t TextServerFallback::font_get_msdf_size(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1114,7 +1114,7 @@ int64_t TextServerFallback::font_get_msdf_size(const RID &p_font_rid) const {
}
void TextServerFallback::font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1122,7 +1122,7 @@ void TextServerFallback::font_set_fixed_size(const RID &p_font_rid, int64_t p_fi
}
int64_t TextServerFallback::font_get_fixed_size(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1130,7 +1130,7 @@ int64_t TextServerFallback::font_get_fixed_size(const RID &p_font_rid) const {
}
void TextServerFallback::font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1141,7 +1141,7 @@ void TextServerFallback::font_set_force_autohinter(const RID &p_font_rid, bool p
}
bool TextServerFallback::font_is_force_autohinter(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -1149,7 +1149,7 @@ bool TextServerFallback::font_is_force_autohinter(const RID &p_font_rid) const {
}
void TextServerFallback::font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1160,7 +1160,7 @@ void TextServerFallback::font_set_hinting(const RID &p_font_rid, TextServer::Hin
}
TextServer::Hinting TextServerFallback::font_get_hinting(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, HINTING_NONE);
MutexLock lock(fd->mutex);
@@ -1168,7 +1168,7 @@ TextServer::Hinting TextServerFallback::font_get_hinting(const RID &p_font_rid)
}
void TextServerFallback::font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1176,7 +1176,7 @@ void TextServerFallback::font_set_subpixel_positioning(const RID &p_font_rid, Te
}
TextServer::SubpixelPositioning TextServerFallback::font_get_subpixel_positioning(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, SUBPIXEL_POSITIONING_DISABLED);
MutexLock lock(fd->mutex);
@@ -1184,7 +1184,7 @@ TextServer::SubpixelPositioning TextServerFallback::font_get_subpixel_positionin
}
void TextServerFallback::font_set_embolden(const RID &p_font_rid, double p_strength) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1195,7 +1195,7 @@ void TextServerFallback::font_set_embolden(const RID &p_font_rid, double p_stren
}
double TextServerFallback::font_get_embolden(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -1203,7 +1203,7 @@ double TextServerFallback::font_get_embolden(const RID &p_font_rid) const {
}
void TextServerFallback::font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1214,7 +1214,7 @@ void TextServerFallback::font_set_transform(const RID &p_font_rid, const Transfo
}
Transform2D TextServerFallback::font_get_transform(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Transform2D());
MutexLock lock(fd->mutex);
@@ -1222,7 +1222,7 @@ Transform2D TextServerFallback::font_get_transform(const RID &p_font_rid) const
}
void TextServerFallback::font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1233,7 +1233,7 @@ void TextServerFallback::font_set_variation_coordinates(const RID &p_font_rid, c
}
Dictionary TextServerFallback::font_get_variation_coordinates(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
@@ -1241,7 +1241,7 @@ Dictionary TextServerFallback::font_get_variation_coordinates(const RID &p_font_
}
void TextServerFallback::font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1252,7 +1252,7 @@ void TextServerFallback::font_set_oversampling(const RID &p_font_rid, double p_o
}
double TextServerFallback::font_get_oversampling(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -1260,30 +1260,30 @@ double TextServerFallback::font_get_oversampling(const RID &p_font_rid) const {
}
Array TextServerFallback::font_get_size_cache_list(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Array());
MutexLock lock(fd->mutex);
Array ret;
- for (const KeyValue<Vector2i, FontDataForSizeFallback *> &E : fd->cache) {
+ for (const KeyValue<Vector2i, FontForSizeFallback *> &E : fd->cache) {
ret.push_back(E.key);
}
return ret;
}
void TextServerFallback::font_clear_size_cache(const RID &p_font_rid) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
- for (const KeyValue<Vector2i, FontDataForSizeFallback *> &E : fd->cache) {
+ for (const KeyValue<Vector2i, FontForSizeFallback *> &E : fd->cache) {
memdelete(E.value);
}
fd->cache.clear();
}
void TextServerFallback::font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1294,7 +1294,7 @@ void TextServerFallback::font_remove_size_cache(const RID &p_font_rid, const Vec
}
void TextServerFallback::font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1305,7 +1305,7 @@ void TextServerFallback::font_set_ascent(const RID &p_font_rid, int64_t p_size,
}
double TextServerFallback::font_get_ascent(const RID &p_font_rid, int64_t p_size) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -1321,7 +1321,7 @@ double TextServerFallback::font_get_ascent(const RID &p_font_rid, int64_t p_size
}
void TextServerFallback::font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
Vector2i size = _get_size(fd, p_size);
@@ -1331,7 +1331,7 @@ void TextServerFallback::font_set_descent(const RID &p_font_rid, int64_t p_size,
}
double TextServerFallback::font_get_descent(const RID &p_font_rid, int64_t p_size) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -1347,7 +1347,7 @@ double TextServerFallback::font_get_descent(const RID &p_font_rid, int64_t p_siz
}
void TextServerFallback::font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1358,7 +1358,7 @@ void TextServerFallback::font_set_underline_position(const RID &p_font_rid, int6
}
double TextServerFallback::font_get_underline_position(const RID &p_font_rid, int64_t p_size) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -1374,7 +1374,7 @@ double TextServerFallback::font_get_underline_position(const RID &p_font_rid, in
}
void TextServerFallback::font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1385,7 +1385,7 @@ void TextServerFallback::font_set_underline_thickness(const RID &p_font_rid, int
}
double TextServerFallback::font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -1401,7 +1401,7 @@ double TextServerFallback::font_get_underline_thickness(const RID &p_font_rid, i
}
void TextServerFallback::font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1417,7 +1417,7 @@ void TextServerFallback::font_set_scale(const RID &p_font_rid, int64_t p_size, d
}
double TextServerFallback::font_get_scale(const RID &p_font_rid, int64_t p_size) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
MutexLock lock(fd->mutex);
@@ -1432,60 +1432,8 @@ double TextServerFallback::font_get_scale(const RID &p_font_rid, int64_t p_size)
}
}
-void TextServerFallback::font_set_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing, int64_t p_value) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
- ERR_FAIL_COND(!fd);
-
- MutexLock lock(fd->mutex);
- Vector2i size = _get_size(fd, p_size);
-
- ERR_FAIL_COND(!_ensure_cache_for_size(fd, size));
- switch (p_spacing) {
- case TextServer::SPACING_GLYPH: {
- fd->cache[size]->spacing_glyph = p_value;
- } break;
- case TextServer::SPACING_SPACE: {
- fd->cache[size]->spacing_space = p_value;
- } break;
- default: {
- ERR_FAIL_MSG("Invalid spacing type: " + String::num_int64(p_spacing));
- } break;
- }
-}
-
-int64_t TextServerFallback::font_get_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
- ERR_FAIL_COND_V(!fd, 0);
-
- MutexLock lock(fd->mutex);
- Vector2i size = _get_size(fd, p_size);
-
- ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0);
-
- switch (p_spacing) {
- case TextServer::SPACING_GLYPH: {
- if (fd->msdf) {
- return fd->cache[size]->spacing_glyph * (double)p_size / (double)fd->msdf_source_size;
- } else {
- return fd->cache[size]->spacing_glyph;
- }
- } break;
- case TextServer::SPACING_SPACE: {
- if (fd->msdf) {
- return fd->cache[size]->spacing_space * (double)p_size / (double)fd->msdf_source_size;
- } else {
- return fd->cache[size]->spacing_space;
- }
- } break;
- default: {
- ERR_FAIL_V_MSG(0, "Invalid spacing type: " + String::num_int64(p_spacing));
- } break;
- }
- return 0;
-}
-
int64_t TextServerFallback::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
MutexLock lock(fd->mutex);
@@ -1497,7 +1445,7 @@ int64_t TextServerFallback::font_get_texture_count(const RID &p_font_rid, const
}
void TextServerFallback::font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
Vector2i size = _get_size_outline(fd, p_size);
@@ -1507,7 +1455,7 @@ void TextServerFallback::font_clear_textures(const RID &p_font_rid, const Vector
}
void TextServerFallback::font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1519,7 +1467,7 @@ void TextServerFallback::font_remove_texture(const RID &p_font_rid, const Vector
}
void TextServerFallback::font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND(p_image.is_null());
@@ -1545,14 +1493,12 @@ void TextServerFallback::font_set_texture_image(const RID &p_font_rid, const Vec
img->generate_mipmaps();
}
- tex.texture = Ref<ImageTexture>();
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
tex.dirty = false;
}
Ref<Image> TextServerFallback::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Ref<Image>());
MutexLock lock(fd->mutex);
@@ -1569,7 +1515,7 @@ Ref<Image> TextServerFallback::font_get_texture_image(const RID &p_font_rid, con
}
void TextServerFallback::font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1585,7 +1531,7 @@ void TextServerFallback::font_set_texture_offsets(const RID &p_font_rid, const V
}
PackedInt32Array TextServerFallback::font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedInt32Array());
MutexLock lock(fd->mutex);
@@ -1598,7 +1544,7 @@ PackedInt32Array TextServerFallback::font_get_texture_offsets(const RID &p_font_
}
Array TextServerFallback::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Array());
MutexLock lock(fd->mutex);
@@ -1614,7 +1560,7 @@ Array TextServerFallback::font_get_glyph_list(const RID &p_font_rid, const Vecto
}
void TextServerFallback::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1625,7 +1571,7 @@ void TextServerFallback::font_clear_glyphs(const RID &p_font_rid, const Vector2i
}
void TextServerFallback::font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1636,7 +1582,7 @@ void TextServerFallback::font_remove_glyph(const RID &p_font_rid, const Vector2i
}
Vector2 TextServerFallback::font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
MutexLock lock(fd->mutex);
@@ -1664,7 +1610,7 @@ Vector2 TextServerFallback::font_get_glyph_advance(const RID &p_font_rid, int64_
}
void TextServerFallback::font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1679,7 +1625,7 @@ void TextServerFallback::font_set_glyph_advance(const RID &p_font_rid, int64_t p
}
Vector2 TextServerFallback::font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
MutexLock lock(fd->mutex);
@@ -1700,7 +1646,7 @@ Vector2 TextServerFallback::font_get_glyph_offset(const RID &p_font_rid, const V
}
void TextServerFallback::font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1715,7 +1661,7 @@ void TextServerFallback::font_set_glyph_offset(const RID &p_font_rid, const Vect
}
Vector2 TextServerFallback::font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
MutexLock lock(fd->mutex);
@@ -1736,7 +1682,7 @@ Vector2 TextServerFallback::font_get_glyph_size(const RID &p_font_rid, const Vec
}
void TextServerFallback::font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1751,7 +1697,7 @@ void TextServerFallback::font_set_glyph_size(const RID &p_font_rid, const Vector
}
Rect2 TextServerFallback::font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Rect2());
MutexLock lock(fd->mutex);
@@ -1767,7 +1713,7 @@ Rect2 TextServerFallback::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
}
void TextServerFallback::font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1782,7 +1728,7 @@ void TextServerFallback::font_set_glyph_uv_rect(const RID &p_font_rid, const Vec
}
int64_t TextServerFallback::font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, -1);
MutexLock lock(fd->mutex);
@@ -1798,7 +1744,7 @@ int64_t TextServerFallback::font_get_glyph_texture_idx(const RID &p_font_rid, co
}
void TextServerFallback::font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1813,7 +1759,7 @@ void TextServerFallback::font_set_glyph_texture_idx(const RID &p_font_rid, const
}
RID TextServerFallback::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, RID());
MutexLock lock(fd->mutex);
@@ -1838,8 +1784,7 @@ RID TextServerFallback::font_get_glyph_texture_rid(const RID &p_font_rid, const
img->generate_mipmaps();
}
if (tex.texture.is_null()) {
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
} else {
tex.texture->update(img);
}
@@ -1853,7 +1798,7 @@ RID TextServerFallback::font_get_glyph_texture_rid(const RID &p_font_rid, const
}
Size2 TextServerFallback::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Size2());
MutexLock lock(fd->mutex);
@@ -1878,8 +1823,7 @@ Size2 TextServerFallback::font_get_glyph_texture_size(const RID &p_font_rid, con
img->generate_mipmaps();
}
if (tex.texture.is_null()) {
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
} else {
tex.texture->update(img);
}
@@ -1893,7 +1837,7 @@ Size2 TextServerFallback::font_get_glyph_texture_size(const RID &p_font_rid, con
}
Dictionary TextServerFallback::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
@@ -1943,7 +1887,7 @@ Dictionary TextServerFallback::font_get_glyph_contours(const RID &p_font_rid, in
}
Array TextServerFallback::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Array());
MutexLock lock(fd->mutex);
@@ -1959,7 +1903,7 @@ Array TextServerFallback::font_get_kerning_list(const RID &p_font_rid, int64_t p
}
void TextServerFallback::font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1970,7 +1914,7 @@ void TextServerFallback::font_clear_kerning_map(const RID &p_font_rid, int64_t p
}
void TextServerFallback::font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1981,7 +1925,7 @@ void TextServerFallback::font_remove_kerning(const RID &p_font_rid, int64_t p_si
}
void TextServerFallback::font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1992,7 +1936,7 @@ void TextServerFallback::font_set_kerning(const RID &p_font_rid, int64_t p_size,
}
Vector2 TextServerFallback::font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
MutexLock lock(fd->mutex);
@@ -2032,7 +1976,7 @@ int64_t TextServerFallback::font_get_glyph_index(const RID &p_font_rid, int64_t
}
bool TextServerFallback::font_has_char(const RID &p_font_rid, int64_t p_char) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), false, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + ".");
@@ -2040,7 +1984,7 @@ bool TextServerFallback::font_has_char(const RID &p_font_rid, int64_t p_char) co
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0)), false);
}
- FontDataForSizeFallback *at_size = fd->cache.begin()->value;
+ FontForSizeFallback *at_size = fd->cache.begin()->value;
#ifdef MODULE_FREETYPE_ENABLED
if (at_size && at_size->face) {
@@ -2051,14 +1995,14 @@ bool TextServerFallback::font_has_char(const RID &p_font_rid, int64_t p_char) co
}
String TextServerFallback::font_get_supported_chars(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
MutexLock lock(fd->mutex);
if (fd->cache.is_empty()) {
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0)), String());
}
- FontDataForSizeFallback *at_size = fd->cache.begin()->value;
+ FontForSizeFallback *at_size = fd->cache.begin()->value;
String chars;
#ifdef MODULE_FREETYPE_ENABLED
@@ -2084,7 +2028,7 @@ String TextServerFallback::font_get_supported_chars(const RID &p_font_rid) const
}
void TextServerFallback::font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND_MSG((p_start >= 0xd800 && p_start <= 0xdfff) || (p_start > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_start, 16) + ".");
ERR_FAIL_COND_MSG((p_end >= 0xd800 && p_end <= 0xdfff) || (p_end > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_end, 16) + ".");
@@ -2117,7 +2061,7 @@ void TextServerFallback::font_render_range(const RID &p_font_rid, const Vector2i
}
void TextServerFallback::font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2146,7 +2090,7 @@ void TextServerFallback::font_render_glyph(const RID &p_font_rid, const Vector2i
}
void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2192,8 +2136,7 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can
img->generate_mipmaps();
}
if (tex.texture.is_null()) {
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
} else {
tex.texture->update(img);
}
@@ -2225,7 +2168,7 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can
}
void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2271,8 +2214,7 @@ void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, const RI
img->generate_mipmaps();
}
if (tex.texture.is_null()) {
- tex.texture.instantiate();
- tex.texture->create_from_image(img);
+ tex.texture = ImageTexture::create_from_image(img);
} else {
tex.texture->update(img);
}
@@ -2304,7 +2246,7 @@ void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, const RI
}
bool TextServerFallback::font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -2316,7 +2258,7 @@ bool TextServerFallback::font_is_language_supported(const RID &p_font_rid, const
}
void TextServerFallback::font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2324,7 +2266,7 @@ void TextServerFallback::font_set_language_support_override(const RID &p_font_ri
}
bool TextServerFallback::font_get_language_support_override(const RID &p_font_rid, const String &p_language) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -2332,7 +2274,7 @@ bool TextServerFallback::font_get_language_support_override(const RID &p_font_ri
}
void TextServerFallback::font_remove_language_support_override(const RID &p_font_rid, const String &p_language) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2340,7 +2282,7 @@ void TextServerFallback::font_remove_language_support_override(const RID &p_font
}
PackedStringArray TextServerFallback::font_get_language_support_overrides(const RID &p_font_rid) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
MutexLock lock(fd->mutex);
@@ -2352,7 +2294,7 @@ PackedStringArray TextServerFallback::font_get_language_support_overrides(const
}
bool TextServerFallback::font_is_script_supported(const RID &p_font_rid, const String &p_script) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -2364,7 +2306,7 @@ bool TextServerFallback::font_is_script_supported(const RID &p_font_rid, const S
}
void TextServerFallback::font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2372,7 +2314,7 @@ void TextServerFallback::font_set_script_support_override(const RID &p_font_rid,
}
bool TextServerFallback::font_get_script_support_override(const RID &p_font_rid, const String &p_script) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
MutexLock lock(fd->mutex);
@@ -2380,7 +2322,7 @@ bool TextServerFallback::font_get_script_support_override(const RID &p_font_rid,
}
void TextServerFallback::font_remove_script_support_override(const RID &p_font_rid, const String &p_script) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2390,7 +2332,7 @@ void TextServerFallback::font_remove_script_support_override(const RID &p_font_r
}
PackedStringArray TextServerFallback::font_get_script_support_overrides(const RID &p_font_rid) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
MutexLock lock(fd->mutex);
@@ -2402,7 +2344,7 @@ PackedStringArray TextServerFallback::font_get_script_support_overrides(const RI
}
void TextServerFallback::font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2412,7 +2354,7 @@ void TextServerFallback::font_set_opentype_feature_overrides(const RID &p_font_r
}
Dictionary TextServerFallback::font_get_opentype_feature_overrides(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
@@ -2424,7 +2366,7 @@ Dictionary TextServerFallback::font_supported_feature_list(const RID &p_font_rid
}
Dictionary TextServerFallback::font_supported_variation_list(const RID &p_font_rid) const {
- FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
MutexLock lock(fd->mutex);
@@ -2630,6 +2572,31 @@ bool TextServerFallback::shaped_text_get_preserve_control(const RID &p_shaped) c
return sd->preserve_control;
}
+void TextServerFallback::shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) {
+ ERR_FAIL_INDEX((int)p_spacing, 4);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND(!sd);
+
+ MutexLock lock(sd->mutex);
+ if (sd->extra_spacing[p_spacing] != p_value) {
+ if (sd->parent != RID()) {
+ full_copy(sd);
+ }
+ sd->extra_spacing[p_spacing] = p_value;
+ invalidate(sd);
+ }
+}
+
+int64_t TextServerFallback::shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const {
+ ERR_FAIL_INDEX_V((int)p_spacing, 4, 0);
+
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V(!sd, 0);
+
+ MutexLock lock(sd->mutex);
+ return sd->extra_spacing[p_spacing];
+}
+
int64_t TextServerFallback::shaped_get_span_count(const RID &p_shaped) const {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0);
@@ -2912,6 +2879,9 @@ RID TextServerFallback::shaped_text_substr(const RID &p_shaped, int64_t p_start,
new_sd->sort_valid = false;
new_sd->upos = sd->upos;
new_sd->uthk = sd->uthk;
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ new_sd->extra_spacing[i] = sd->extra_spacing[i];
+ }
if (p_length > 0) {
new_sd->text = sd->text.substr(p_start - sd->start, p_length);
@@ -2980,7 +2950,7 @@ RID TextServerFallback::shaped_text_get_parent(const RID &p_shaped) const {
return sd->parent;
}
-double TextServerFallback::shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags) {
+double TextServerFallback::shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<JustificationFlag> p_jst_flags) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
@@ -2995,7 +2965,7 @@ double TextServerFallback::shaped_text_fit_to_width(const RID &p_shaped, double
int start_pos = 0;
int end_pos = sd->glyphs.size() - 1;
- if ((p_jst_flags & JUSTIFICATION_AFTER_LAST_TAB) == JUSTIFICATION_AFTER_LAST_TAB) {
+ if (p_jst_flags.has_flag(JUSTIFICATION_AFTER_LAST_TAB)) {
int start, end, delta;
if (sd->para_direction == DIRECTION_LTR) {
start = sd->glyphs.size() - 1;
@@ -3021,7 +2991,7 @@ double TextServerFallback::shaped_text_fit_to_width(const RID &p_shaped, double
}
double justification_width;
- if ((p_jst_flags & JUSTIFICATION_CONSTRAIN_ELLIPSIS) == JUSTIFICATION_CONSTRAIN_ELLIPSIS) {
+ if (p_jst_flags.has_flag(JUSTIFICATION_CONSTRAIN_ELLIPSIS)) {
if (sd->overrun_trim_data.trim_pos >= 0) {
end_pos = sd->overrun_trim_data.trim_pos;
justification_width = sd->width_trimmed;
@@ -3032,7 +3002,7 @@ double TextServerFallback::shaped_text_fit_to_width(const RID &p_shaped, double
justification_width = sd->width;
}
- if ((p_jst_flags & JUSTIFICATION_TRIM_EDGE_SPACES) == JUSTIFICATION_TRIM_EDGE_SPACES) {
+ if (p_jst_flags.has_flag(JUSTIFICATION_TRIM_EDGE_SPACES)) {
// Trim spaces.
while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
justification_width -= sd->glyphs[start_pos].advance * sd->glyphs[start_pos].repeat;
@@ -3064,7 +3034,7 @@ double TextServerFallback::shaped_text_fit_to_width(const RID &p_shaped, double
}
}
- if ((space_count > 0) && ((p_jst_flags & JUSTIFICATION_WORD_BOUND) == JUSTIFICATION_WORD_BOUND)) {
+ if ((space_count > 0) && p_jst_flags.has_flag(JUSTIFICATION_WORD_BOUND)) {
double delta_width_per_space = (p_width - justification_width) / space_count;
for (int i = start_pos; i <= end_pos; i++) {
Glyph &gl = sd->glyphs.write[i];
@@ -3082,7 +3052,7 @@ double TextServerFallback::shaped_text_fit_to_width(const RID &p_shaped, double
sd->fit_width_minimum_reached = true;
}
- if ((p_jst_flags & JUSTIFICATION_CONSTRAIN_ELLIPSIS) != JUSTIFICATION_CONSTRAIN_ELLIPSIS) {
+ if (!p_jst_flags.has_flag(JUSTIFICATION_CONSTRAIN_ELLIPSIS)) {
sd->width = justification_width;
}
@@ -3217,7 +3187,7 @@ bool TextServerFallback::shaped_text_update_justification_ops(const RID &p_shape
return true;
}
-void TextServerFallback::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, int64_t p_trim_flags) {
+void TextServerFallback::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped_line);
ERR_FAIL_COND_MSG(!sd, "ShapedTextDataFallback invalid.");
@@ -3229,14 +3199,14 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
sd->text_trimmed = false;
sd->overrun_trim_data.ellipsis_glyph_buf.clear();
- bool add_ellipsis = (p_trim_flags & OVERRUN_ADD_ELLIPSIS) == OVERRUN_ADD_ELLIPSIS;
- bool cut_per_word = (p_trim_flags & OVERRUN_TRIM_WORD_ONLY) == OVERRUN_TRIM_WORD_ONLY;
- bool enforce_ellipsis = (p_trim_flags & OVERRUN_ENFORCE_ELLIPSIS) == OVERRUN_ENFORCE_ELLIPSIS;
- bool justification_aware = (p_trim_flags & OVERRUN_JUSTIFICATION_AWARE) == OVERRUN_JUSTIFICATION_AWARE;
+ bool add_ellipsis = p_trim_flags.has_flag(OVERRUN_ADD_ELLIPSIS);
+ bool cut_per_word = p_trim_flags.has_flag(OVERRUN_TRIM_WORD_ONLY);
+ bool enforce_ellipsis = p_trim_flags.has_flag(OVERRUN_ENFORCE_ELLIPSIS);
+ bool justification_aware = p_trim_flags.has_flag(OVERRUN_JUSTIFICATION_AWARE);
Glyph *sd_glyphs = sd->glyphs.ptrw();
- if ((p_trim_flags & OVERRUN_TRIM) == OVERRUN_NO_TRIM || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) {
+ if (p_trim_flags.has_flag(OVERRUN_TRIM) || sd_glyphs == nullptr || p_width <= 0 || !(sd->width > p_width || enforce_ellipsis)) {
sd->overrun_trim_data.trim_pos = -1;
sd->overrun_trim_data.ellipsis_pos = -1;
return;
@@ -3289,7 +3259,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
int ellipsis_width = 0;
if (add_ellipsis && whitespace_gl_font_rid.is_valid()) {
- ellipsis_width = 3 * dot_adv.x + font_get_spacing(whitespace_gl_font_rid, last_gl_font_size, SPACING_GLYPH) + (cut_per_word ? whitespace_adv.x : 0);
+ ellipsis_width = 3 * dot_adv.x + sd->extra_spacing[SPACING_GLYPH] + (cut_per_word ? whitespace_adv.x : 0);
}
int ell_min_characters = 6;
@@ -3491,10 +3461,13 @@ bool TextServerFallback::shaped_text_shape(const RID &p_shaped) {
sd->descent = MAX(sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
}
}
- if (font_get_spacing(gl.font_rid, gl.font_size, TextServer::SPACING_SPACE) && is_whitespace(sd->text[j - sd->start])) {
- gl.advance += font_get_spacing(gl.font_rid, gl.font_size, TextServer::SPACING_SPACE);
- } else {
- gl.advance += font_get_spacing(gl.font_rid, gl.font_size, TextServer::SPACING_GLYPH);
+ if (j < sd->end - 1) {
+ // Do not add extra spacing to the last glyph of the string.
+ if (is_whitespace(sd->text[j - sd->start])) {
+ gl.advance += sd->extra_spacing[SPACING_SPACE];
+ } else {
+ gl.advance += sd->extra_spacing[SPACING_GLYPH];
+ }
}
sd->upos = MAX(sd->upos, font_get_underline_position(gl.font_rid, gl.font_size));
sd->uthk = MAX(sd->uthk, font_get_underline_thickness(gl.font_rid, gl.font_size));
@@ -3621,9 +3594,9 @@ Size2 TextServerFallback::shaped_text_get_size(const RID &p_shaped) const {
const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
}
if (sd->orientation == TextServer::ORIENTATION_HORIZONTAL) {
- return Size2(sd->width, sd->ascent + sd->descent).ceil();
+ return Size2(sd->width, sd->ascent + sd->descent + sd->extra_spacing[SPACING_TOP] + sd->extra_spacing[SPACING_BOTTOM]).ceil();
} else {
- return Size2(sd->ascent + sd->descent, sd->width).ceil();
+ return Size2(sd->ascent + sd->descent + sd->extra_spacing[SPACING_TOP] + sd->extra_spacing[SPACING_BOTTOM], sd->width).ceil();
}
}
@@ -3635,7 +3608,7 @@ double TextServerFallback::shaped_text_get_ascent(const RID &p_shaped) const {
if (!sd->valid) {
const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
}
- return sd->ascent;
+ return sd->ascent + sd->extra_spacing[SPACING_TOP];
}
double TextServerFallback::shaped_text_get_descent(const RID &p_shaped) const {
@@ -3646,7 +3619,7 @@ double TextServerFallback::shaped_text_get_descent(const RID &p_shaped) const {
if (!sd->valid) {
const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
}
- return sd->descent;
+ return sd->descent + sd->extra_spacing[SPACING_BOTTOM];
}
double TextServerFallback::shaped_text_get_width(const RID &p_shaped) const {
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index e4c81aed5b..497403afd7 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -144,7 +144,7 @@ class TextServerFallback : public TextServerExtension {
Vector2 advance;
};
- struct FontDataForSizeFallback {
+ struct FontForSizeFallback {
double ascent = 0.0;
double descent = 0.0;
double underline_position = 0.0;
@@ -152,9 +152,6 @@ class TextServerFallback : public TextServerExtension {
double scale = 1.0;
double oversampling = 1.0;
- int spacing_glyph = 0;
- int spacing_space = 0;
-
Vector2i size;
Vector<FontTexture> textures;
@@ -166,7 +163,7 @@ class TextServerFallback : public TextServerExtension {
FT_StreamRec stream;
#endif
- ~FontDataForSizeFallback() {
+ ~FontForSizeFallback() {
#ifdef MODULE_FREETYPE_ENABLED
if (face != nullptr) {
FT_Done_Face(face);
@@ -175,7 +172,7 @@ class TextServerFallback : public TextServerExtension {
}
};
- struct FontDataFallback {
+ struct FontFallback {
Mutex mutex;
bool antialiased = true;
@@ -192,11 +189,11 @@ class TextServerFallback : public TextServerExtension {
double embolden = 0.0;
Transform2D transform;
- uint32_t style_flags = 0;
+ BitField<TextServer::FontStyle> style_flags = 0;
String font_name;
String style_name;
- HashMap<Vector2i, FontDataForSizeFallback *, VariantHasher, VariantComparator> cache;
+ HashMap<Vector2i, FontForSizeFallback *, VariantHasher, VariantComparator> cache;
bool face_init = false;
Dictionary supported_varaitions;
@@ -213,28 +210,28 @@ class TextServerFallback : public TextServerExtension {
mutable ThreadWorkPool work_pool;
- ~FontDataFallback() {
+ ~FontFallback() {
work_pool.finish();
- for (const KeyValue<Vector2i, FontDataForSizeFallback *> &E : cache) {
+ for (const KeyValue<Vector2i, FontForSizeFallback *> &E : cache) {
memdelete(E.value);
}
cache.clear();
}
};
- _FORCE_INLINE_ FontTexturePosition find_texture_pos_for_glyph(FontDataForSizeFallback *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const;
+ _FORCE_INLINE_ FontTexturePosition find_texture_pos_for_glyph(FontForSizeFallback *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const;
#ifdef MODULE_MSDFGEN_ENABLED
- _FORCE_INLINE_ FontGlyph rasterize_msdf(FontDataFallback *p_font_data, FontDataForSizeFallback *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const;
+ _FORCE_INLINE_ FontGlyph rasterize_msdf(FontFallback *p_font_data, FontForSizeFallback *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const;
#endif
#ifdef MODULE_FREETYPE_ENABLED
- _FORCE_INLINE_ FontGlyph rasterize_bitmap(FontDataForSizeFallback *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const;
+ _FORCE_INLINE_ FontGlyph rasterize_bitmap(FontForSizeFallback *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const;
#endif
- _FORCE_INLINE_ bool _ensure_glyph(FontDataFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph) const;
- _FORCE_INLINE_ bool _ensure_cache_for_size(FontDataFallback *p_font_data, const Vector2i &p_size) const;
- _FORCE_INLINE_ void _font_clear_cache(FontDataFallback *p_font_data);
+ _FORCE_INLINE_ bool _ensure_glyph(FontFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph) const;
+ _FORCE_INLINE_ bool _ensure_cache_for_size(FontFallback *p_font_data, const Vector2i &p_size) const;
+ _FORCE_INLINE_ void _font_clear_cache(FontFallback *p_font_data);
void _generateMTSDF_threaded(uint32_t y, void *p_td) const;
- _FORCE_INLINE_ Vector2i _get_size(const FontDataFallback *p_font_data, int p_size) const {
+ _FORCE_INLINE_ Vector2i _get_size(const FontFallback *p_font_data, int p_size) const {
if (p_font_data->msdf) {
return Vector2i(p_font_data->msdf_source_size, 0);
} else if (p_font_data->fixed_size > 0) {
@@ -244,7 +241,7 @@ class TextServerFallback : public TextServerExtension {
}
}
- _FORCE_INLINE_ Vector2i _get_size_outline(const FontDataFallback *p_font_data, const Vector2i &p_size) const {
+ _FORCE_INLINE_ Vector2i _get_size_outline(const FontFallback *p_font_data, const Vector2i &p_size) const {
if (p_font_data->msdf) {
return Vector2i(p_font_data->msdf_source_size, 0);
} else if (p_font_data->fixed_size > 0) {
@@ -312,6 +309,7 @@ class TextServerFallback : public TextServerExtension {
double descent = 0.0; // Descent for horizontal layout, 1/2 of width for vertical.
double width = 0.0; // Width for horizontal layout, height for vertical.
double width_trimmed = 0.0;
+ int extra_spacing[4] = { 0, 0, 0, 0 };
double upos = 0.0;
double uthk = 0.0;
@@ -326,7 +324,7 @@ class TextServerFallback : public TextServerExtension {
// Common data.
double oversampling = 1.0;
- mutable RID_PtrOwner<FontDataFallback> font_owner;
+ mutable RID_PtrOwner<FontFallback> font_owner;
mutable RID_PtrOwner<ShapedTextDataFallback> shaped_owner;
void _realign(ShapedTextDataFallback *p_sd) const;
@@ -370,8 +368,8 @@ public:
virtual int64_t font_get_face_count(const RID &p_font_rid) const override;
- virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) override;
- virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const override;
+ virtual void font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) override;
+ virtual BitField<FontStyle> font_get_style(const RID &p_font_rid) const override;
virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) override;
virtual String font_get_style_name(const RID &p_font_rid) const override;
@@ -437,9 +435,6 @@ public:
virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) override;
virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const override;
- virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) override;
- virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const override;
-
virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override;
@@ -536,6 +531,9 @@ public:
virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) override;
virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const override;
+ virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) override;
+ virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const override;
+
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override;
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
@@ -547,7 +545,7 @@ public:
virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override;
virtual RID shaped_text_get_parent(const RID &p_shaped) const override;
- virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
+ virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override;
virtual bool shaped_text_shape(const RID &p_shaped) override;
@@ -559,7 +557,7 @@ public:
virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const override;
virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override;
- virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_t p_trim_flags) override;
+ virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) override;
virtual bool shaped_text_is_ready(const RID &p_shaped) const override;
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index 77e370849f..c4462ba687 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -331,7 +331,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);
+ texture->set_image(img);
} else {
/* tear down the partial theora setup */
diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp
index ceea0eaf1d..522ed8719b 100644
--- a/modules/visual_script/editor/visual_script_editor.cpp
+++ b/modules/visual_script/editor/visual_script_editor.cpp
@@ -1227,7 +1227,7 @@ void VisualScriptEditor::_member_selected() {
selected = ti->get_metadata(0);
if (ti->get_parent() == members->get_root()->get_first_child()) {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::META);
#else
bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL);
@@ -2208,7 +2208,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
String(d["type"]) == "files" ||
String(d["type"]) == "nodes")) {
if (String(d["type"]) == "obj_property") {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Getter. Hold Shift to drop a generic signature."), find_keycode_name(Key::META)));
#else
const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."));
@@ -2216,7 +2216,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
}
if (String(d["type"]) == "nodes") {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a simple reference to the node."), find_keycode_name(Key::META)));
#else
const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a simple reference to the node."));
@@ -2224,7 +2224,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
}
if (String(d["type"]) == "visual_script_variable_drag") {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Variable Setter."), find_keycode_name(Key::META)));
#else
const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a Variable Setter."));
@@ -2287,7 +2287,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "visual_script_variable_drag") {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool use_set = Input::get_singleton()->is_key_pressed(Key::META);
#else
bool use_set = Input::get_singleton()->is_key_pressed(Key::CTRL);
@@ -2396,7 +2396,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "files") {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool use_preload = Input::get_singleton()->is_key_pressed(Key::META);
#else
bool use_preload = Input::get_singleton()->is_key_pressed(Key::CTRL);
@@ -2459,7 +2459,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
return;
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool use_node = Input::get_singleton()->is_key_pressed(Key::META);
#else
bool use_node = Input::get_singleton()->is_key_pressed(Key::CTRL);
@@ -2524,7 +2524,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
Node *node = Object::cast_to<Node>(obj);
Vector2 pos = _get_pos_in_graph(p_point);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool use_get = Input::get_singleton()->is_key_pressed(Key::META);
#else
bool use_get = Input::get_singleton()->is_key_pressed(Key::CTRL);
@@ -3378,7 +3378,7 @@ void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<Visua
}
void VisualScriptEditor::_selected_connect_node(const String &p_text, const String &p_category, const bool p_connecting) {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::META);
#else
bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL);
@@ -4628,7 +4628,7 @@ VisualScriptEditor::VisualScriptEditor() {
graph = memnew(GraphEdit);
add_child(graph);
graph->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- graph->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ graph->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
graph->set_show_zoom_label(true);
graph->connect("node_selected", callable_mp(this, &VisualScriptEditor::_node_selected));
graph->connect("begin_node_move", callable_mp(this, &VisualScriptEditor::_begin_node_move));
@@ -4717,7 +4717,7 @@ VisualScriptEditor::VisualScriptEditor() {
function_create_dialog = memnew(ConfirmationDialog);
function_create_dialog->set_title(TTR("Create Function"));
function_create_dialog->add_child(function_vb);
- function_create_dialog->get_ok_button()->set_text(TTR("Create"));
+ function_create_dialog->set_ok_button_text(TTR("Create"));
function_create_dialog->get_ok_button()->connect("pressed", callable_mp(this, &VisualScriptEditor::_create_function));
add_child(function_create_dialog);
@@ -4761,7 +4761,7 @@ VisualScriptEditor::VisualScriptEditor() {
graph->connect("connection_to_empty", callable_mp(this, &VisualScriptEditor::_graph_connect_to_empty));
edit_signal_dialog = memnew(AcceptDialog);
- edit_signal_dialog->get_ok_button()->set_text(TTR("Close"));
+ edit_signal_dialog->set_ok_button_text(TTR("Close"));
add_child(edit_signal_dialog);
signal_editor = memnew(VisualScriptEditorSignalEdit);
@@ -4771,7 +4771,7 @@ VisualScriptEditor::VisualScriptEditor() {
edit_signal_edit->edit(signal_editor);
edit_variable_dialog = memnew(AcceptDialog);
- edit_variable_dialog->get_ok_button()->set_text(TTR("Close"));
+ edit_variable_dialog->set_ok_button_text(TTR("Close"));
add_child(edit_variable_dialog);
variable_editor = memnew(VisualScriptEditorVariableEdit);
diff --git a/modules/visual_script/editor/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp
index ae30655301..f98ce5bb26 100644
--- a/modules/visual_script/editor/visual_script_property_selector.cpp
+++ b/modules/visual_script/editor/visual_script_property_selector.cpp
@@ -533,7 +533,7 @@ VisualScriptPropertySelector::VisualScriptPropertySelector() {
scroller->add_child(help_bit);
help_bit->connect("request_hide", callable_mp(this, &VisualScriptPropertySelector::_hide_requested));
- get_ok_button()->set_text(TTR("Open"));
+ set_ok_button_text(TTR("Open"));
get_ok_button()->set_disabled(true);
set_hide_on_ok(false);
}
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index c5bcf23c8e..742fa75bb7 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -2435,6 +2435,9 @@ void VisualScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) c
void VisualScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const {
}
+void VisualScriptLanguage::get_public_annotations(List<MethodInfo> *p_annotations) const {
+}
+
void VisualScriptLanguage::profiling_start() {
}
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index c2e4d0e597..716310f59b 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -599,6 +599,7 @@ public:
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
virtual void get_public_functions(List<MethodInfo> *p_functions) const override;
virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const override;
+ virtual void get_public_annotations(List<MethodInfo> *p_annotations) const override;
virtual void profiling_start() override;
virtual void profiling_stop() override;
diff --git a/modules/webrtc/webrtc_peer_connection_js.cpp b/modules/webrtc/webrtc_peer_connection_js.cpp
index 90e19fe4f1..ee3a302fa2 100644
--- a/modules/webrtc/webrtc_peer_connection_js.cpp
+++ b/modules/webrtc/webrtc_peer_connection_js.cpp
@@ -57,7 +57,7 @@ void WebRTCPeerConnectionJS::_on_error(void *p_obj) {
void WebRTCPeerConnectionJS::_on_data_channel(void *p_obj, int p_id) {
WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(p_obj);
- peer->emit_signal(SNAME("data_channel_received"), Ref<WebRTCDataChannelJS>(new WebRTCDataChannelJS(p_id)));
+ peer->emit_signal(SNAME("data_channel_received"), Ref<WebRTCDataChannel>(memnew(WebRTCDataChannelJS(p_id))));
}
void WebRTCPeerConnectionJS::close() {
diff --git a/modules/webrtc/webrtc_peer_connection_js.h b/modules/webrtc/webrtc_peer_connection_js.h
index 8fa5ea7779..76b8c7fff8 100644
--- a/modules/webrtc/webrtc_peer_connection_js.h
+++ b/modules/webrtc/webrtc_peer_connection_js.h
@@ -52,6 +52,8 @@ extern int godot_js_rtc_pc_datachannel_create(int p_id, const char *p_label, con
}
class WebRTCPeerConnectionJS : public WebRTCPeerConnection {
+ GDCLASS(WebRTCPeerConnectionJS, WebRTCPeerConnection);
+
private:
int _js_id;
ConnectionState _conn_state;
diff --git a/platform/android/SCsub b/platform/android/SCsub
index ad226255bc..d370a4d18d 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -6,6 +6,7 @@ android_files = [
"os_android.cpp",
"android_input_handler.cpp",
"file_access_android.cpp",
+ "file_access_filesystem_jandroid.cpp",
"audio_driver_opensl.cpp",
"dir_access_jandroid.cpp",
"tts_android.cpp",
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 47cfade765..2ff5bf59ea 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -96,22 +96,19 @@ def configure(env):
if env["android_arch"] == "armv7":
target_triple = "armv7a-linux-androideabi"
- bin_utils = "arm-linux-androideabi"
env.extra_suffix = ".armv7" + env.extra_suffix
elif env["android_arch"] == "arm64v8":
target_triple = "aarch64-linux-android"
- bin_utils = target_triple
env.extra_suffix = ".armv8" + env.extra_suffix
elif env["android_arch"] == "x86":
target_triple = "i686-linux-android"
- bin_utils = target_triple
env.extra_suffix = ".x86" + env.extra_suffix
elif env["android_arch"] == "x86_64":
target_triple = "x86_64-linux-android"
- bin_utils = target_triple
env.extra_suffix = ".x86_64" + env.extra_suffix
target_option = ["-target", target_triple + str(get_min_sdk_version(env["ndk_platform"]))]
+ env.Append(ASFLAGS=[target_option, "-c"])
env.Append(CCFLAGS=target_option)
env.Append(LINKFLAGS=target_option)
@@ -152,13 +149,12 @@ def configure(env):
toolchain_path = ndk_root + "/toolchains/llvm/prebuilt/" + host_subpath
compiler_path = toolchain_path + "/bin"
- bin_utils_path = toolchain_path + "/" + bin_utils + "/bin"
env["CC"] = compiler_path + "/clang"
env["CXX"] = compiler_path + "/clang++"
env["AR"] = compiler_path + "/llvm-ar"
env["RANLIB"] = compiler_path + "/llvm-ranlib"
- env["AS"] = bin_utils_path + "/as"
+ env["AS"] = compiler_path + "/clang"
# Disable exceptions and rtti on non-tools (template) builds
if env["tools"]:
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index 5b9eee8117..eb344d3b43 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -31,30 +31,32 @@
#include "dir_access_jandroid.h"
#include "core/string/print_string.h"
-#include "file_access_android.h"
#include "string_android.h"
#include "thread_jandroid.h"
-jobject DirAccessJAndroid::io = nullptr;
+jobject DirAccessJAndroid::dir_access_handler = nullptr;
jclass DirAccessJAndroid::cls = nullptr;
jmethodID DirAccessJAndroid::_dir_open = nullptr;
jmethodID DirAccessJAndroid::_dir_next = nullptr;
jmethodID DirAccessJAndroid::_dir_close = nullptr;
jmethodID DirAccessJAndroid::_dir_is_dir = nullptr;
-
-Ref<DirAccess> DirAccessJAndroid::create_fs() {
- return memnew(DirAccessJAndroid);
-}
+jmethodID DirAccessJAndroid::_dir_exists = nullptr;
+jmethodID DirAccessJAndroid::_file_exists = nullptr;
+jmethodID DirAccessJAndroid::_get_drive_count = nullptr;
+jmethodID DirAccessJAndroid::_get_drive = nullptr;
+jmethodID DirAccessJAndroid::_make_dir = nullptr;
+jmethodID DirAccessJAndroid::_get_space_left = nullptr;
+jmethodID DirAccessJAndroid::_rename = nullptr;
+jmethodID DirAccessJAndroid::_remove = nullptr;
+jmethodID DirAccessJAndroid::_current_is_hidden = nullptr;
Error DirAccessJAndroid::list_dir_begin() {
list_dir_end();
- JNIEnv *env = get_jni_env();
-
- jstring js = env->NewStringUTF(current_dir.utf8().get_data());
- int res = env->CallIntMethod(io, _dir_open, js);
+ int res = dir_open(current_dir);
if (res <= 0) {
return ERR_CANT_OPEN;
}
+
id = res;
return OK;
@@ -62,169 +64,236 @@ Error DirAccessJAndroid::list_dir_begin() {
String DirAccessJAndroid::get_next() {
ERR_FAIL_COND_V(id == 0, "");
+ if (_dir_next) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, "");
+ jstring str = (jstring)env->CallObjectMethod(dir_access_handler, _dir_next, get_access_type(), id);
+ if (!str) {
+ return "";
+ }
- JNIEnv *env = get_jni_env();
- jstring str = (jstring)env->CallObjectMethod(io, _dir_next, id);
- if (!str) {
+ String ret = jstring_to_string((jstring)str, env);
+ env->DeleteLocalRef((jobject)str);
+ return ret;
+ } else {
return "";
}
- String ret = jstring_to_string((jstring)str, env);
- env->DeleteLocalRef((jobject)str);
- return ret;
}
bool DirAccessJAndroid::current_is_dir() const {
- JNIEnv *env = get_jni_env();
-
- return env->CallBooleanMethod(io, _dir_is_dir, id);
+ if (_dir_is_dir) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+ return env->CallBooleanMethod(dir_access_handler, _dir_is_dir, get_access_type(), id);
+ } else {
+ return false;
+ }
}
bool DirAccessJAndroid::current_is_hidden() const {
- return current != "." && current != ".." && current.begins_with(".");
+ if (_current_is_hidden) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+ return env->CallBooleanMethod(dir_access_handler, _current_is_hidden, get_access_type(), id);
+ }
+ return false;
}
void DirAccessJAndroid::list_dir_end() {
if (id == 0) {
return;
}
- JNIEnv *env = get_jni_env();
- env->CallVoidMethod(io, _dir_close, id);
+
+ dir_close(id);
id = 0;
}
int DirAccessJAndroid::get_drive_count() {
- return 0;
+ if (_get_drive_count) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+ return env->CallIntMethod(dir_access_handler, _get_drive_count, get_access_type());
+ } else {
+ return 0;
+ }
}
String DirAccessJAndroid::get_drive(int p_drive) {
- return "";
+ if (_get_drive) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, "");
+ jstring j_drive = (jstring)env->CallObjectMethod(dir_access_handler, _get_drive, get_access_type(), p_drive);
+ if (!j_drive) {
+ return "";
+ }
+
+ String drive = jstring_to_string(j_drive, env);
+ env->DeleteLocalRef(j_drive);
+ return drive;
+ } else {
+ return "";
+ }
}
Error DirAccessJAndroid::change_dir(String p_dir) {
- JNIEnv *env = get_jni_env();
-
- if (p_dir.is_empty() || p_dir == "." || (p_dir == ".." && current_dir.is_empty())) {
+ String new_dir = get_absolute_path(p_dir);
+ if (new_dir == current_dir) {
return OK;
}
- String new_dir;
-
- if (p_dir != "res://" && p_dir.length() > 1 && p_dir.ends_with("/")) {
- p_dir = p_dir.substr(0, p_dir.length() - 1);
- }
-
- if (p_dir.begins_with("/")) {
- new_dir = p_dir.substr(1, p_dir.length());
- } else if (p_dir.begins_with("res://")) {
- new_dir = p_dir.substr(6, p_dir.length());
- } else if (current_dir.is_empty()) {
- new_dir = p_dir;
- } else {
- new_dir = current_dir.plus_file(p_dir);
- }
-
- //test if newdir exists
- new_dir = new_dir.simplify_path();
-
- jstring js = env->NewStringUTF(new_dir.utf8().get_data());
- int res = env->CallIntMethod(io, _dir_open, js);
- env->DeleteLocalRef(js);
- if (res <= 0) {
+ if (!dir_exists(new_dir)) {
return ERR_INVALID_PARAMETER;
}
- env->CallVoidMethod(io, _dir_close, res);
-
current_dir = new_dir;
-
return OK;
}
-String DirAccessJAndroid::get_current_dir(bool p_include_drive) const {
- return "res://" + current_dir;
+String DirAccessJAndroid::get_absolute_path(String p_path) {
+ if (current_dir != "" && p_path == current_dir) {
+ return current_dir;
+ }
+
+ if (p_path.is_relative_path()) {
+ p_path = get_current_dir().plus_file(p_path);
+ }
+
+ p_path = fix_path(p_path);
+ p_path = p_path.simplify_path();
+ return p_path;
}
bool DirAccessJAndroid::file_exists(String p_file) {
- String sd;
- if (current_dir.is_empty()) {
- sd = p_file;
+ if (_file_exists) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+
+ String path = get_absolute_path(p_file);
+ jstring j_path = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(dir_access_handler, _file_exists, get_access_type(), j_path);
+ env->DeleteLocalRef(j_path);
+ return result;
} else {
- sd = current_dir.plus_file(p_file);
+ return false;
}
-
- Ref<FileAccessAndroid> f;
- f.instantiate();
- bool exists = f->file_exists(sd);
-
- return exists;
}
bool DirAccessJAndroid::dir_exists(String p_dir) {
- JNIEnv *env = get_jni_env();
-
- String sd;
-
- if (current_dir.is_empty()) {
- sd = p_dir;
+ if (_dir_exists) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+
+ String path = get_absolute_path(p_dir);
+ jstring j_path = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(dir_access_handler, _dir_exists, get_access_type(), j_path);
+ env->DeleteLocalRef(j_path);
+ return result;
} else {
- if (p_dir.is_relative_path()) {
- sd = current_dir.plus_file(p_dir);
- } else {
- sd = fix_path(p_dir);
- }
- }
-
- String path = sd.simplify_path();
-
- if (path.begins_with("/")) {
- path = path.substr(1, path.length());
- } else if (path.begins_with("res://")) {
- path = path.substr(6, path.length());
+ return false;
}
+}
- jstring js = env->NewStringUTF(path.utf8().get_data());
- int res = env->CallIntMethod(io, _dir_open, js);
- env->DeleteLocalRef(js);
- if (res <= 0) {
- return false;
+Error DirAccessJAndroid::make_dir_recursive(String p_dir) {
+ // Check if the directory exists already
+ if (dir_exists(p_dir)) {
+ return ERR_ALREADY_EXISTS;
}
- env->CallVoidMethod(io, _dir_close, res);
+ if (_make_dir) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, ERR_UNCONFIGURED);
- return true;
+ String path = get_absolute_path(p_dir);
+ jstring j_dir = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(dir_access_handler, _make_dir, get_access_type(), j_dir);
+ env->DeleteLocalRef(j_dir);
+ if (result) {
+ return OK;
+ } else {
+ return FAILED;
+ }
+ } else {
+ return ERR_UNCONFIGURED;
+ }
}
Error DirAccessJAndroid::make_dir(String p_dir) {
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ return make_dir_recursive(p_dir);
}
Error DirAccessJAndroid::rename(String p_from, String p_to) {
- ERR_FAIL_V(ERR_UNAVAILABLE);
-}
+ if (_rename) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, ERR_UNCONFIGURED);
-Error DirAccessJAndroid::remove(String p_name) {
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ String from_path = get_absolute_path(p_from);
+ jstring j_from = env->NewStringUTF(from_path.utf8().get_data());
+
+ String to_path = get_absolute_path(p_to);
+ jstring j_to = env->NewStringUTF(to_path.utf8().get_data());
+
+ bool result = env->CallBooleanMethod(dir_access_handler, _rename, get_access_type(), j_from, j_to);
+ env->DeleteLocalRef(j_from);
+ env->DeleteLocalRef(j_to);
+ if (result) {
+ return OK;
+ } else {
+ return FAILED;
+ }
+ } else {
+ return ERR_UNCONFIGURED;
+ }
}
-String DirAccessJAndroid::get_filesystem_type() const {
- return "APK";
+Error DirAccessJAndroid::remove(String p_name) {
+ if (_remove) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, ERR_UNCONFIGURED);
+
+ String path = get_absolute_path(p_name);
+ jstring j_name = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(dir_access_handler, _remove, get_access_type(), j_name);
+ env->DeleteLocalRef(j_name);
+ if (result) {
+ return OK;
+ } else {
+ return FAILED;
+ }
+ } else {
+ return ERR_UNCONFIGURED;
+ }
}
uint64_t DirAccessJAndroid::get_space_left() {
- return 0;
+ if (_get_space_left) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+ return env->CallLongMethod(dir_access_handler, _get_space_left, get_access_type());
+ } else {
+ return 0;
+ }
}
-void DirAccessJAndroid::setup(jobject p_io) {
+void DirAccessJAndroid::setup(jobject p_dir_access_handler) {
JNIEnv *env = get_jni_env();
- io = p_io;
+ dir_access_handler = env->NewGlobalRef(p_dir_access_handler);
- jclass c = env->GetObjectClass(io);
+ jclass c = env->GetObjectClass(dir_access_handler);
cls = (jclass)env->NewGlobalRef(c);
- _dir_open = env->GetMethodID(cls, "dir_open", "(Ljava/lang/String;)I");
- _dir_next = env->GetMethodID(cls, "dir_next", "(I)Ljava/lang/String;");
- _dir_close = env->GetMethodID(cls, "dir_close", "(I)V");
- _dir_is_dir = env->GetMethodID(cls, "dir_is_dir", "(I)Z");
+ _dir_open = env->GetMethodID(cls, "dirOpen", "(ILjava/lang/String;)I");
+ _dir_next = env->GetMethodID(cls, "dirNext", "(II)Ljava/lang/String;");
+ _dir_close = env->GetMethodID(cls, "dirClose", "(II)V");
+ _dir_is_dir = env->GetMethodID(cls, "dirIsDir", "(II)Z");
+ _dir_exists = env->GetMethodID(cls, "dirExists", "(ILjava/lang/String;)Z");
+ _file_exists = env->GetMethodID(cls, "fileExists", "(ILjava/lang/String;)Z");
+ _get_drive_count = env->GetMethodID(cls, "getDriveCount", "(I)I");
+ _get_drive = env->GetMethodID(cls, "getDrive", "(II)Ljava/lang/String;");
+ _make_dir = env->GetMethodID(cls, "makeDir", "(ILjava/lang/String;)Z");
+ _get_space_left = env->GetMethodID(cls, "getSpaceLeft", "(I)J");
+ _rename = env->GetMethodID(cls, "rename", "(ILjava/lang/String;Ljava/lang/String;)Z");
+ _remove = env->GetMethodID(cls, "remove", "(ILjava/lang/String;)Z");
+ _current_is_hidden = env->GetMethodID(cls, "isCurrentHidden", "(II)Z");
}
DirAccessJAndroid::DirAccessJAndroid() {
@@ -233,3 +302,26 @@ DirAccessJAndroid::DirAccessJAndroid() {
DirAccessJAndroid::~DirAccessJAndroid() {
list_dir_end();
}
+
+int DirAccessJAndroid::dir_open(String p_path) {
+ if (_dir_open) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+
+ String path = get_absolute_path(p_path);
+ jstring js = env->NewStringUTF(path.utf8().get_data());
+ int dirId = env->CallIntMethod(dir_access_handler, _dir_open, get_access_type(), js);
+ env->DeleteLocalRef(js);
+ return dirId;
+ } else {
+ return 0;
+ }
+}
+
+void DirAccessJAndroid::dir_close(int p_id) {
+ if (_dir_close) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ env->CallVoidMethod(dir_access_handler, _dir_close, get_access_type(), p_id);
+ }
+}
diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h
index 0e1b12cb58..d469c9d317 100644
--- a/platform/android/dir_access_jandroid.h
+++ b/platform/android/dir_access_jandroid.h
@@ -32,58 +32,70 @@
#define DIR_ACCESS_JANDROID_H
#include "core/io/dir_access.h"
+#include "drivers/unix/dir_access_unix.h"
#include "java_godot_lib_jni.h"
#include <stdio.h>
-class DirAccessJAndroid : public DirAccess {
- static jobject io;
+/// Android implementation of the DirAccess interface used to provide access to
+/// ACCESS_FILESYSTEM and ACCESS_RESOURCES directory resources.
+/// The implementation use jni in order to comply with Android filesystem
+/// access restriction.
+class DirAccessJAndroid : public DirAccessUnix {
+ static jobject dir_access_handler;
static jclass cls;
static jmethodID _dir_open;
static jmethodID _dir_next;
static jmethodID _dir_close;
static jmethodID _dir_is_dir;
-
- int id = 0;
-
- String current_dir;
- String current;
-
- static Ref<DirAccess> create_fs();
+ static jmethodID _dir_exists;
+ static jmethodID _file_exists;
+ static jmethodID _get_drive_count;
+ static jmethodID _get_drive;
+ static jmethodID _make_dir;
+ static jmethodID _get_space_left;
+ static jmethodID _rename;
+ static jmethodID _remove;
+ static jmethodID _current_is_hidden;
public:
- virtual Error list_dir_begin(); ///< This starts dir listing
- virtual String get_next();
- virtual bool current_is_dir() const;
- virtual bool current_is_hidden() const;
- virtual void list_dir_end(); ///<
+ virtual Error list_dir_begin() override; ///< This starts dir listing
+ virtual String get_next() override;
+ virtual bool current_is_dir() const override;
+ virtual bool current_is_hidden() const override;
+ virtual void list_dir_end() override; ///<
- virtual int get_drive_count();
- virtual String get_drive(int p_drive);
+ virtual int get_drive_count() override;
+ virtual String get_drive(int p_drive) override;
- virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
- virtual String get_current_dir(bool p_include_drive = true) const; ///< return current dir location
+ virtual Error change_dir(String p_dir) override; ///< can be relative or absolute, return false on success
- virtual bool file_exists(String p_file);
- virtual bool dir_exists(String p_dir);
+ virtual bool file_exists(String p_file) override;
+ virtual bool dir_exists(String p_dir) override;
- virtual Error make_dir(String p_dir);
+ virtual Error make_dir(String p_dir) override;
+ virtual Error make_dir_recursive(String p_dir) override;
- virtual Error rename(String p_from, String p_to);
- virtual Error remove(String p_name);
+ virtual Error rename(String p_from, String p_to) override;
+ virtual Error remove(String p_name) override;
- virtual bool is_link(String p_file) { return false; }
- virtual String read_link(String p_file) { return p_file; }
- virtual Error create_link(String p_source, String p_target) { return FAILED; }
+ virtual bool is_link(String p_file) override { return false; }
+ virtual String read_link(String p_file) override { return p_file; }
+ virtual Error create_link(String p_source, String p_target) override { return FAILED; }
- virtual String get_filesystem_type() const;
+ virtual uint64_t get_space_left() override;
- uint64_t get_space_left();
-
- static void setup(jobject p_io);
+ static void setup(jobject p_dir_access_handler);
DirAccessJAndroid();
~DirAccessJAndroid();
+
+private:
+ int id = 0;
+
+ int dir_open(String p_path);
+ void dir_close(int p_id);
+ String get_absolute_path(String p_path);
};
#endif // DIR_ACCESS_JANDROID_H
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index b40c1f5090..2cfb152804 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -123,6 +123,7 @@ static const char *android_perms[] = {
"MANAGE_ACCOUNTS",
"MANAGE_APP_TOKENS",
"MANAGE_DOCUMENTS",
+ "MANAGE_EXTERNAL_STORAGE",
"MASTER_CLEAR",
"MEDIA_CONTENT_CONTROL",
"MODIFY_AUDIO_SETTINGS",
@@ -245,8 +246,7 @@ static const char *APK_ASSETS_DIRECTORY = "res://android/build/assets";
static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets";
static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
-static const int DEFAULT_TARGET_SDK_VERSION = 31; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
-const String SDK_VERSION_RANGE = vformat("%s,%s,1", DEFAULT_MIN_SDK_VERSION, DEFAULT_TARGET_SDK_VERSION);
+static const int DEFAULT_TARGET_SDK_VERSION = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
EditorExportPlatformAndroid *ea = static_cast<EditorExportPlatformAndroid *>(ud);
@@ -277,6 +277,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
}
}
+#ifndef ANDROID_ENABLED
// Check for devices updates
String adb = get_adb_path();
if (FileAccess::exists(adb)) {
@@ -388,6 +389,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
ea->devices_changed.set();
}
}
+#endif
uint64_t sleep = 200;
uint64_t wait = 3000000;
@@ -400,6 +402,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
}
}
+#ifndef ANDROID_ENABLED
if (EditorSettings::get_singleton()->get("export/android/shutdown_adb_on_exit")) {
String adb = get_adb_path();
if (!FileAccess::exists(adb)) {
@@ -410,6 +413,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
args.push_back("kill-server");
OS::get_singleton()->execute(adb, args);
}
+#endif
}
String EditorExportPlatformAndroid::get_project_name(const String &p_name) const {
@@ -748,10 +752,14 @@ Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const Shared
return OK;
}
-bool EditorExportPlatformAndroid::_has_storage_permission(const Vector<String> &p_permissions) {
+bool EditorExportPlatformAndroid::_has_read_write_storage_permission(const Vector<String> &p_permissions) {
return p_permissions.find("android.permission.READ_EXTERNAL_STORAGE") != -1 || p_permissions.find("android.permission.WRITE_EXTERNAL_STORAGE") != -1;
}
+bool EditorExportPlatformAndroid::_has_manage_external_storage_permission(const Vector<String> &p_permissions) {
+ return p_permissions.find("android.permission.MANAGE_EXTERNAL_STORAGE") != -1;
+}
+
void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, Vector<String> &r_permissions) {
const char **aperms = android_perms;
while (*aperms) {
@@ -799,7 +807,7 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPres
_get_permissions(p_preset, p_give_internet, perms);
for (int i = 0; i < perms.size(); i++) {
String permission = perms.get(i);
- if (permission == "android.permission.WRITE_EXTERNAL_STORAGE" || permission == "android.permission.READ_EXTERNAL_STORAGE") {
+ if (permission == "android.permission.WRITE_EXTERNAL_STORAGE" || (permission == "android.permission.READ_EXTERNAL_STORAGE" && _has_manage_external_storage_permission(perms))) {
manifest_text += vformat(" <uses-permission android:name=\"%s\" android:maxSdkVersion=\"29\" />\n", permission);
} else {
manifest_text += vformat(" <uses-permission android:name=\"%s\" />\n", permission);
@@ -807,7 +815,7 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPres
}
manifest_text += _get_xr_features_tag(p_preset);
- manifest_text += _get_application_tag(p_preset, _has_storage_permission(perms));
+ manifest_text += _get_application_tag(p_preset, _has_read_write_storage_permission(perms));
manifest_text += "</manifest>\n";
String manifest_path = vformat("res://android/build/src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release"));
@@ -865,7 +873,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
Vector<String> perms;
// Write permissions into the perms variable.
_get_permissions(p_preset, p_give_internet, perms);
- bool has_storage_permission = _has_storage_permission(perms);
+ bool has_read_write_storage_permission = _has_read_write_storage_permission(perms);
while (ofs < (uint32_t)p_manifest.size()) {
uint32_t chunk = decode_uint32(&p_manifest[ofs]);
@@ -949,7 +957,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
}
if (tname == "application" && attrname == "requestLegacyExternalStorage") {
- encode_uint32(has_storage_permission ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
+ encode_uint32(has_read_write_storage_permission ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
}
if (tname == "application" && attrname == "allowBackup") {
@@ -1682,8 +1690,13 @@ void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPres
void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_options) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_template/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_build/use_custom_build"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_build/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK));
+ // Using String instead of int to default to an empty string (no override) with placeholder for instructions (see GH-62465).
+ // This implies doing validation that the string is a proper int.
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_build/min_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_MIN_SDK_VERSION)), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_build/target_sdk", PROPERTY_HINT_PLACEHOLDER_TEXT, vformat("%d (default)", DEFAULT_TARGET_SDK_VERSION)), ""));
Vector<PluginConfigAndroid> plugins_configs = get_plugins();
for (int i = 0; i < plugins_configs.size(); i++) {
@@ -1710,8 +1723,6 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/min_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_MIN_SDK_VERSION));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/target_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_TARGET_SDK_VERSION));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), ""));
@@ -2039,7 +2050,7 @@ String EditorExportPlatformAndroid::get_apksigner_path() {
bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = false;
- const bool custom_build_enabled = p_preset->get("custom_template/use_custom_build");
+ const bool custom_build_enabled = p_preset->get("custom_build/use_custom_build");
// Look for export templates (first official, and if defined custom templates).
@@ -2201,43 +2212,73 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
if (xr_mode_index != XR_MODE_OPENXR) {
if (hand_tracking > XR_HAND_TRACKING_NONE) {
valid = false;
- err += TTR("\"Hand Tracking\" is only valid when \"Xr Mode\" is \"OpenXR\".");
+ err += TTR("\"Hand Tracking\" is only valid when \"XR Mode\" is \"OpenXR\".");
err += "\n";
}
if (passthrough_mode > XR_PASSTHROUGH_NONE) {
valid = false;
- err += TTR("\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\".");
+ err += TTR("\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\".");
err += "\n";
}
}
- if (int(p_preset->get("custom_template/export_format")) == EXPORT_FORMAT_AAB &&
+ if (int(p_preset->get("custom_build/export_format")) == EXPORT_FORMAT_AAB &&
!custom_build_enabled) {
valid = false;
err += TTR("\"Export AAB\" is only valid when \"Use Custom Build\" is enabled.");
err += "\n";
}
- // Check the min sdk version
- int min_sdk_version = p_preset->get("version/min_sdk");
- if (min_sdk_version != DEFAULT_MIN_SDK_VERSION && !custom_build_enabled) {
- valid = false;
- err += TTR("Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled.");
- err += "\n";
+ // Check the min sdk version.
+ String min_sdk_str = p_preset->get("custom_build/min_sdk");
+ int min_sdk_int = DEFAULT_MIN_SDK_VERSION;
+ if (!min_sdk_str.is_empty()) { // Empty means no override, nothing to do.
+ if (!custom_build_enabled) {
+ valid = false;
+ err += TTR("\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled.");
+ err += "\n";
+ }
+ if (!min_sdk_str.is_valid_int()) {
+ valid = false;
+ err += vformat(TTR("\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid."), min_sdk_str);
+ err += "\n";
+ } else {
+ min_sdk_int = min_sdk_str.to_int();
+ if (min_sdk_int < DEFAULT_MIN_SDK_VERSION) {
+ valid = false;
+ err += vformat(TTR("\"Min SDK\" cannot be lower than %d, which is the version needed by the Godot library."), DEFAULT_MIN_SDK_VERSION);
+ err += "\n";
+ }
+ }
}
- // Check the target sdk version
- int target_sdk_version = p_preset->get("version/target_sdk");
- if (target_sdk_version != DEFAULT_TARGET_SDK_VERSION && !custom_build_enabled) {
- valid = false;
- err += TTR("Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is enabled.");
- err += "\n";
+ // Check the target sdk version.
+ String target_sdk_str = p_preset->get("custom_build/target_sdk");
+ int target_sdk_int = DEFAULT_TARGET_SDK_VERSION;
+ if (!target_sdk_str.is_empty()) { // Empty means no override, nothing to do.
+ if (!custom_build_enabled) {
+ valid = false;
+ err += TTR("\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled.");
+ err += "\n";
+ }
+ if (!target_sdk_str.is_valid_int()) {
+ valid = false;
+ err += vformat(TTR("\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid."), target_sdk_str);
+ err += "\n";
+ } else {
+ target_sdk_int = target_sdk_str.to_int();
+ if (target_sdk_int > DEFAULT_TARGET_SDK_VERSION) {
+ // Warning only, so don't override `valid`.
+ err += vformat(TTR("\"Target SDK\" %d is higher than the default version %d. This may work, but wasn't tested and may be unstable."), target_sdk_int, DEFAULT_TARGET_SDK_VERSION);
+ err += "\n";
+ }
+ }
}
- if (target_sdk_version < min_sdk_version) {
+ if (target_sdk_int < min_sdk_int) {
valid = false;
- err += TTR("\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version.");
+ err += TTR("\"Target SDK\" version must be greater or equal to \"Min SDK\" version.");
err += "\n";
}
@@ -2326,7 +2367,7 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP
}
Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &export_path, EditorProgress &ep) {
- int export_format = int(p_preset->get("custom_template/export_format"));
+ int export_format = int(p_preset->get("custom_build/export_format"));
String export_label = export_format == EXPORT_FORMAT_AAB ? "AAB" : "APK";
String release_keystore = p_preset->get("keystore/release");
String release_username = p_preset->get("keystore/release_user");
@@ -2482,7 +2523,7 @@ String EditorExportPlatformAndroid::join_list(List<String> parts, const String &
}
Error EditorExportPlatformAndroid::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
- int export_format = int(p_preset->get("custom_template/export_format"));
+ int export_format = int(p_preset->get("custom_build/export_format"));
bool should_sign = p_preset->get("package/signed");
return export_project_helper(p_preset, p_debug, p_path, export_format, should_sign, p_flags);
}
@@ -2495,7 +2536,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
EditorProgress ep("export", TTR("Exporting for Android"), 105, true);
- bool use_custom_build = bool(p_preset->get("custom_template/use_custom_build"));
+ bool use_custom_build = bool(p_preset->get("custom_build/use_custom_build"));
bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
bool apk_expansion = p_preset->get("apk_expansion/enable");
Vector<String> enabled_abis = get_enabled_abis(p_preset);
@@ -2623,8 +2664,14 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String package_name = get_package_name(p_preset->get("package/unique_name"));
String version_code = itos(p_preset->get("version/code"));
String version_name = p_preset->get("version/name");
- String min_sdk_version = itos(p_preset->get("version/min_sdk"));
- String target_sdk_version = itos(p_preset->get("version/target_sdk"));
+ String min_sdk_version = p_preset->get("custom_build/min_sdk");
+ if (!min_sdk_version.is_valid_int()) {
+ min_sdk_version = itos(DEFAULT_MIN_SDK_VERSION);
+ }
+ String target_sdk_version = p_preset->get("custom_build/target_sdk");
+ if (!target_sdk_version.is_valid_int()) {
+ target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION);
+ }
String enabled_abi_string = String("|").join(enabled_abis);
String sign_flag = should_sign ? "true" : "false";
String zipalign_flag = "true";
@@ -3071,13 +3118,8 @@ void EditorExportPlatformAndroid::resolve_platform_feature_priorities(const Ref<
}
EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
- Ref<Image> img = memnew(Image(_android_logo));
- logo.instantiate();
- logo->create_from_image(img);
-
- img = Ref<Image>(memnew(Image(_android_run_icon)));
- run_icon.instantiate();
- run_icon->create_from_image(img);
+ logo = ImageTexture::create_from_image(memnew(Image(_android_logo)));
+ run_icon = ImageTexture::create_from_image(memnew(Image(_android_run_icon)));
devices_changed.set();
plugins_changed.set();
diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h
index eeb5aae0f1..15ac8091be 100644
--- a/platform/android/export/export_plugin.h
+++ b/platform/android/export/export_plugin.h
@@ -116,7 +116,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
static Error copy_gradle_so(void *p_userdata, const SharedObject &p_so);
- bool _has_storage_permission(const Vector<String> &p_permissions);
+ bool _has_read_write_storage_permission(const Vector<String> &p_permissions);
+
+ bool _has_manage_external_storage_permission(const Vector<String> &p_permissions);
void _get_permissions(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, Vector<String> &r_permissions);
diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp
index 9a470edfdd..8d370a31a4 100644
--- a/platform/android/export/gradle_export_util.cpp
+++ b/platform/android/export/gradle_export_util.cpp
@@ -254,7 +254,7 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
return manifest_activity_text;
}
-String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission) {
+String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_read_write_storage_permission) {
int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode"));
bool uses_xr = xr_mode_index == XR_MODE_OPENXR;
String manifest_application_text = vformat(
@@ -271,7 +271,7 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
bool_to_string(p_preset->get("user_data_backup/allow")),
bool_to_string(p_preset->get("package/classify_as_game")),
bool_to_string(p_preset->get("package/retain_data_on_uninstall")),
- bool_to_string(p_has_storage_permission));
+ bool_to_string(p_has_read_write_storage_permission));
if (uses_xr) {
bool hand_tracking_enabled = (int)(p_preset->get("xr_features/hand_tracking")) > XR_HAND_TRACKING_NONE;
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index 109852bdfc..7896392d16 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -104,6 +104,6 @@ String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset);
String _get_activity_tag(const Ref<EditorExportPreset> &p_preset);
-String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission);
+String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_read_write_storage_permission);
#endif // GODOT_GRADLE_EXPORT_UTIL_H
diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp
index 4bb8a13bb6..ace7636e6c 100644
--- a/platform/android/file_access_android.cpp
+++ b/platform/android/file_access_android.cpp
@@ -34,14 +34,20 @@
AAssetManager *FileAccessAndroid::asset_manager = nullptr;
-Ref<FileAccess> FileAccessAndroid::create_android() {
- return memnew(FileAccessAndroid);
+String FileAccessAndroid::get_path() const {
+ return path_src;
+}
+
+String FileAccessAndroid::get_path_absolute() const {
+ return absolute_path;
}
Error FileAccessAndroid::_open(const String &p_path, int p_mode_flags) {
_close();
+ path_src = p_path;
String path = fix_path(p_path).simplify_path();
+ absolute_path = path;
if (path.begins_with("/")) {
path = path.substr(1, path.length());
} else if (path.begins_with("res://")) {
@@ -134,7 +140,7 @@ uint64_t FileAccessAndroid::get_buffer(uint8_t *p_dst, uint64_t p_length) const
}
Error FileAccessAndroid::get_error() const {
- return eof ? ERR_FILE_EOF : OK; //not sure what else it may happen
+ return eof ? ERR_FILE_EOF : OK; // not sure what else it may happen
}
void FileAccessAndroid::flush() {
diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h
index c16f74ac43..e6fd8c857b 100644
--- a/platform/android/file_access_android.h
+++ b/platform/android/file_access_android.h
@@ -37,11 +37,12 @@
#include <stdio.h>
class FileAccessAndroid : public FileAccess {
- static Ref<FileAccess> create_android();
mutable AAsset *asset = nullptr;
mutable uint64_t len = 0;
mutable uint64_t pos = 0;
mutable bool eof = false;
+ String absolute_path;
+ String path_src;
void _close();
@@ -51,6 +52,11 @@ public:
virtual Error _open(const String &p_path, int p_mode_flags); // open a file
virtual bool is_open() const; // true when file is open
+ /// returns the path for the current open file
+ virtual String get_path() const;
+ /// returns the absolute path for the current open file
+ virtual String get_path_absolute() const;
+
virtual void seek(uint64_t p_position); // seek to a given position
virtual void seek_end(int64_t p_position = 0); // seek from the end of file
virtual uint64_t get_position() const; // get position in the file
diff --git a/platform/android/file_access_filesystem_jandroid.cpp b/platform/android/file_access_filesystem_jandroid.cpp
new file mode 100644
index 0000000000..c1a48e025e
--- /dev/null
+++ b/platform/android/file_access_filesystem_jandroid.cpp
@@ -0,0 +1,283 @@
+/*************************************************************************/
+/* file_access_filesystem_jandroid.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "file_access_filesystem_jandroid.h"
+#include "core/os/os.h"
+#include "thread_jandroid.h"
+#include <unistd.h>
+
+jobject FileAccessFilesystemJAndroid::file_access_handler = nullptr;
+jclass FileAccessFilesystemJAndroid::cls;
+
+jmethodID FileAccessFilesystemJAndroid::_file_open = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_get_size = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_seek = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_seek_end = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_read = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_tell = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_eof = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_close = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_write = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_flush = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_exists = nullptr;
+jmethodID FileAccessFilesystemJAndroid::_file_last_modified = nullptr;
+
+String FileAccessFilesystemJAndroid::get_path() const {
+ return path_src;
+}
+
+String FileAccessFilesystemJAndroid::get_path_absolute() const {
+ return absolute_path;
+}
+
+Error FileAccessFilesystemJAndroid::_open(const String &p_path, int p_mode_flags) {
+ if (is_open()) {
+ _close();
+ }
+
+ if (_file_open) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, ERR_UNCONFIGURED);
+
+ String path = fix_path(p_path).simplify_path();
+ jstring js = env->NewStringUTF(path.utf8().get_data());
+ int res = env->CallIntMethod(file_access_handler, _file_open, js, p_mode_flags);
+ env->DeleteLocalRef(js);
+
+ if (res <= 0) {
+ switch (res) {
+ case 0:
+ default:
+ return ERR_FILE_CANT_OPEN;
+
+ case -1:
+ return ERR_FILE_NOT_FOUND;
+ }
+ }
+
+ id = res;
+ path_src = p_path;
+ absolute_path = path;
+ return OK;
+ } else {
+ return ERR_UNCONFIGURED;
+ }
+}
+
+void FileAccessFilesystemJAndroid::_close() {
+ if (!is_open()) {
+ return;
+ }
+
+ if (_file_close) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ env->CallVoidMethod(file_access_handler, _file_close, id);
+ }
+ id = 0;
+}
+
+bool FileAccessFilesystemJAndroid::is_open() const {
+ return id != 0;
+}
+
+void FileAccessFilesystemJAndroid::seek(uint64_t p_position) {
+ if (_file_seek) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
+ env->CallVoidMethod(file_access_handler, _file_seek, id, p_position);
+ }
+}
+
+void FileAccessFilesystemJAndroid::seek_end(int64_t p_position) {
+ if (_file_seek_end) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
+ env->CallVoidMethod(file_access_handler, _file_seek_end, id, p_position);
+ }
+}
+
+uint64_t FileAccessFilesystemJAndroid::get_position() const {
+ if (_file_tell) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+ ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
+ return env->CallLongMethod(file_access_handler, _file_tell, id);
+ } else {
+ return 0;
+ }
+}
+
+uint64_t FileAccessFilesystemJAndroid::get_length() const {
+ if (_file_get_size) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+ ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
+ return env->CallLongMethod(file_access_handler, _file_get_size, id);
+ } else {
+ return 0;
+ }
+}
+
+bool FileAccessFilesystemJAndroid::eof_reached() const {
+ if (_file_eof) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+ ERR_FAIL_COND_V_MSG(!is_open(), false, "File must be opened before use.");
+ return env->CallBooleanMethod(file_access_handler, _file_eof, id);
+ } else {
+ return false;
+ }
+}
+
+uint8_t FileAccessFilesystemJAndroid::get_8() const {
+ ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
+ uint8_t byte;
+ get_buffer(&byte, 1);
+ return byte;
+}
+
+uint64_t FileAccessFilesystemJAndroid::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
+ if (_file_read) {
+ ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
+ if (p_length == 0) {
+ return 0;
+ }
+
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, 0);
+
+ jobject j_buffer = env->NewDirectByteBuffer(p_dst, p_length);
+ int length = env->CallIntMethod(file_access_handler, _file_read, id, j_buffer);
+ env->DeleteLocalRef(j_buffer);
+ return length;
+ } else {
+ return 0;
+ }
+}
+
+void FileAccessFilesystemJAndroid::store_8(uint8_t p_dest) {
+ store_buffer(&p_dest, 1);
+}
+
+void FileAccessFilesystemJAndroid::store_buffer(const uint8_t *p_src, uint64_t p_length) {
+ if (_file_write) {
+ ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
+ if (p_length == 0) {
+ return;
+ }
+
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+
+ jobject j_buffer = env->NewDirectByteBuffer((void *)p_src, p_length);
+ env->CallVoidMethod(file_access_handler, _file_write, id, j_buffer);
+ env->DeleteLocalRef(j_buffer);
+ }
+}
+
+Error FileAccessFilesystemJAndroid::get_error() const {
+ if (eof_reached()) {
+ return ERR_FILE_EOF;
+ }
+ return OK;
+}
+
+void FileAccessFilesystemJAndroid::flush() {
+ if (_file_flush) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND(env == nullptr);
+ ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
+ env->CallVoidMethod(file_access_handler, _file_flush, id);
+ }
+}
+
+bool FileAccessFilesystemJAndroid::file_exists(const String &p_path) {
+ if (_file_exists) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+
+ String path = fix_path(p_path).simplify_path();
+ jstring js = env->NewStringUTF(path.utf8().get_data());
+ bool result = env->CallBooleanMethod(file_access_handler, _file_exists, js);
+ env->DeleteLocalRef(js);
+ return result;
+ } else {
+ return false;
+ }
+}
+
+uint64_t FileAccessFilesystemJAndroid::_get_modified_time(const String &p_file) {
+ if (_file_last_modified) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_COND_V(env == nullptr, false);
+
+ String path = fix_path(p_file).simplify_path();
+ jstring js = env->NewStringUTF(path.utf8().get_data());
+ uint64_t result = env->CallLongMethod(file_access_handler, _file_last_modified, js);
+ env->DeleteLocalRef(js);
+ return result;
+ } else {
+ return 0;
+ }
+}
+
+void FileAccessFilesystemJAndroid::setup(jobject p_file_access_handler) {
+ JNIEnv *env = get_jni_env();
+ file_access_handler = env->NewGlobalRef(p_file_access_handler);
+
+ jclass c = env->GetObjectClass(file_access_handler);
+ cls = (jclass)env->NewGlobalRef(c);
+
+ _file_open = env->GetMethodID(cls, "fileOpen", "(Ljava/lang/String;I)I");
+ _file_get_size = env->GetMethodID(cls, "fileGetSize", "(I)J");
+ _file_tell = env->GetMethodID(cls, "fileGetPosition", "(I)J");
+ _file_eof = env->GetMethodID(cls, "isFileEof", "(I)Z");
+ _file_seek = env->GetMethodID(cls, "fileSeek", "(IJ)V");
+ _file_seek_end = env->GetMethodID(cls, "fileSeekFromEnd", "(IJ)V");
+ _file_read = env->GetMethodID(cls, "fileRead", "(ILjava/nio/ByteBuffer;)I");
+ _file_close = env->GetMethodID(cls, "fileClose", "(I)V");
+ _file_write = env->GetMethodID(cls, "fileWrite", "(ILjava/nio/ByteBuffer;)V");
+ _file_flush = env->GetMethodID(cls, "fileFlush", "(I)V");
+ _file_exists = env->GetMethodID(cls, "fileExists", "(Ljava/lang/String;)Z");
+ _file_last_modified = env->GetMethodID(cls, "fileLastModified", "(Ljava/lang/String;)J");
+}
+
+FileAccessFilesystemJAndroid::FileAccessFilesystemJAndroid() {
+ id = 0;
+}
+
+FileAccessFilesystemJAndroid::~FileAccessFilesystemJAndroid() {
+ if (is_open()) {
+ _close();
+ }
+}
diff --git a/platform/android/file_access_filesystem_jandroid.h b/platform/android/file_access_filesystem_jandroid.h
new file mode 100644
index 0000000000..18d5df1628
--- /dev/null
+++ b/platform/android/file_access_filesystem_jandroid.h
@@ -0,0 +1,97 @@
+/*************************************************************************/
+/* file_access_filesystem_jandroid.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef FILE_ACCESS_FILESYSTEM_JANDROID_H
+#define FILE_ACCESS_FILESYSTEM_JANDROID_H
+
+#include "core/io/file_access.h"
+#include "java_godot_lib_jni.h"
+
+class FileAccessFilesystemJAndroid : public FileAccess {
+ static jobject file_access_handler;
+ static jclass cls;
+
+ static jmethodID _file_open;
+ static jmethodID _file_get_size;
+ static jmethodID _file_seek;
+ static jmethodID _file_seek_end;
+ static jmethodID _file_tell;
+ static jmethodID _file_eof;
+ static jmethodID _file_read;
+ static jmethodID _file_write;
+ static jmethodID _file_flush;
+ static jmethodID _file_close;
+ static jmethodID _file_exists;
+ static jmethodID _file_last_modified;
+
+ int id;
+ String absolute_path;
+ String path_src;
+
+ void _close(); ///< close a file
+
+public:
+ virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file
+ virtual bool is_open() const override; ///< true when file is open
+
+ /// returns the path for the current open file
+ virtual String get_path() const override;
+ /// returns the absolute path for the current open file
+ virtual String get_path_absolute() const override;
+
+ virtual void seek(uint64_t p_position) override; ///< seek to a given position
+ virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file
+ virtual uint64_t get_position() const override; ///< get position in the file
+ virtual uint64_t get_length() const override; ///< get size of the file
+
+ virtual bool eof_reached() const override; ///< reading passed EOF
+
+ virtual uint8_t get_8() const override; ///< get a byte
+ virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override;
+
+ virtual Error get_error() const override; ///< get last error
+
+ virtual void flush() override;
+ virtual void store_8(uint8_t p_dest) override; ///< store a byte
+ virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override;
+
+ virtual bool file_exists(const String &p_path) override; ///< return true if a file exists
+
+ static void setup(jobject p_file_access_handler);
+
+ virtual uint64_t _get_modified_time(const String &p_file) override;
+ virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
+
+ FileAccessFilesystemJAndroid();
+ ~FileAccessFilesystemJAndroid();
+};
+
+#endif // FILE_ACCESS_FILESYSTEM_JANDROID_H
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 3daf628e63..fbd97fae0b 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,9 +1,9 @@
ext.versions = [
androidGradlePlugin: '7.0.3',
- compileSdk : 31,
+ compileSdk : 32,
minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION'
- targetSdk : 31, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
- buildTools : '30.0.3',
+ targetSdk : 32, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
+ buildTools : '32.0.0',
kotlinVersion : '1.6.21',
fragmentVersion : '1.3.6',
nexusPublishVersion: '1.1.0',
diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle
index dd167c3880..729966ee69 100644
--- a/platform/android/java/editor/build.gradle
+++ b/platform/android/java/editor/build.gradle
@@ -23,8 +23,7 @@ android {
versionCode getGodotLibraryVersionCode()
versionName getGodotLibraryVersionName()
minSdkVersion versions.minSdk
- //noinspection ExpiredTargetSdkVersion - Restrict to version 29 until https://github.com/godotengine/godot/pull/51815 is submitted
- targetSdkVersion 29 // versions.targetSdk
+ targetSdkVersion versions.targetSdk
missingDimensionStrategy 'products', 'editor'
}
diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml
index 93cbb47400..abf506a83c 100644
--- a/platform/android/java/editor/src/main/AndroidManifest.xml
+++ b/platform/android/java/editor/src/main/AndroidManifest.xml
@@ -14,8 +14,12 @@
android:glEsVersion="0x00020000"
android:required="true" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
+ tools:ignore="ScopedStorage" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
+ android:maxSdkVersion="29"/>
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
+ android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
index a1ade722e8..740f3f48d3 100644
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
@@ -30,10 +30,14 @@
package org.godotengine.editor
+import android.Manifest
import android.content.Intent
+import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Debug
+import android.os.Environment
+import android.widget.Toast
import androidx.window.layout.WindowMetricsCalculator
import org.godotengine.godot.FullScreenGodotApp
import org.godotengine.godot.utils.PermissionsUtil
@@ -68,7 +72,7 @@ open class GodotEditor : FullScreenGodotApp() {
val params = intent.getStringArrayExtra(COMMAND_LINE_PARAMS)
updateCommandLineParams(params)
- if (BuildConfig.BUILD_TYPE == "debug" && WAIT_FOR_DEBUGGER) {
+ if (BuildConfig.BUILD_TYPE == "dev" && WAIT_FOR_DEBUGGER) {
Debug.waitForDebugger()
}
@@ -143,4 +147,50 @@ open class GodotEditor : FullScreenGodotApp() {
* The Godot Android Editor sets its own orientation via its AndroidManifest
*/
protected open fun overrideOrientationRequest() = true
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ // Check if we got the MANAGE_EXTERNAL_STORAGE permission
+ if (requestCode == PermissionsUtil.REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ if (!Environment.isExternalStorageManager()) {
+ Toast.makeText(
+ this,
+ R.string.denied_storage_permission_error_msg,
+ Toast.LENGTH_LONG
+ ).show()
+ }
+ }
+ }
+ }
+
+ override fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array<String?>,
+ grantResults: IntArray
+ ) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ // Check if we got access to the necessary storage permissions
+ if (requestCode == PermissionsUtil.REQUEST_ALL_PERMISSION_REQ_CODE) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ var hasReadAccess = false
+ var hasWriteAccess = false
+ for (i in permissions.indices) {
+ if (Manifest.permission.READ_EXTERNAL_STORAGE == permissions[i] && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
+ hasReadAccess = true
+ }
+ if (Manifest.permission.WRITE_EXTERNAL_STORAGE == permissions[i] && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
+ hasWriteAccess = true
+ }
+ }
+ if (!hasReadAccess || !hasWriteAccess) {
+ Toast.makeText(
+ this,
+ R.string.denied_storage_permission_error_msg,
+ Toast.LENGTH_LONG
+ ).show()
+ }
+ }
+ }
+ }
}
diff --git a/platform/android/java/editor/src/main/res/values/strings.xml b/platform/android/java/editor/src/main/res/values/strings.xml
index e8ce34f34d..837a5d62e1 100644
--- a/platform/android/java/editor/src/main/res/values/strings.xml
+++ b/platform/android/java/editor/src/main/res/values/strings.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="godot_editor_name_string">Godot Editor 4.x</string>
+
+ <string name="denied_storage_permission_error_msg">Missing storage access permission!</string>
</resources>
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index 228d8d45fa..79b5aadf2a 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionName="1.0">
<!-- Should match the mindSdk and targetSdk values in platform/android/java/app/config.gradle -->
- <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="32" />
<application>
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index cafae94d62..28e689e63a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -34,6 +34,8 @@ import static android.content.Context.MODE_PRIVATE;
import static android.content.Context.WINDOW_SERVICE;
import org.godotengine.godot.input.GodotEditText;
+import org.godotengine.godot.io.directory.DirectoryAccessHandler;
+import org.godotengine.godot.io.file.FileAccessHandler;
import org.godotengine.godot.plugin.GodotPlugin;
import org.godotengine.godot.plugin.GodotPluginRegistry;
import org.godotengine.godot.tts.GodotTTS;
@@ -164,9 +166,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private Sensor mMagnetometer;
private Sensor mGyroscope;
- public static GodotIO io;
- public static GodotNetUtils netUtils;
- public static GodotTTS tts;
+ public GodotIO io;
+ public GodotNetUtils netUtils;
+ public GodotTTS tts;
public interface ResultCallback {
void callback(int requestCode, int resultCode, Intent data);
@@ -458,16 +460,26 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
final Activity activity = getActivity();
io = new GodotIO(activity);
- GodotLib.io = io;
netUtils = new GodotNetUtils(activity);
tts = new GodotTTS(activity);
+ Context context = getContext();
+ DirectoryAccessHandler directoryAccessHandler = new DirectoryAccessHandler(context);
+ FileAccessHandler fileAccessHandler = new FileAccessHandler(context);
mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
- GodotLib.initialize(activity, this, activity.getAssets(), use_apk_expansion);
+ GodotLib.initialize(activity,
+ this,
+ activity.getAssets(),
+ io,
+ netUtils,
+ directoryAccessHandler,
+ fileAccessHandler,
+ use_apk_expansion,
+ tts);
result_callback = null;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index a8e3669ac6..0434efdf4c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -36,7 +36,6 @@ import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.content.res.AssetManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
@@ -46,12 +45,10 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
-import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.WindowInsets;
-import java.io.IOException;
import java.util.List;
import java.util.Locale;
@@ -60,7 +57,6 @@ import java.util.Locale;
public class GodotIO {
private static final String TAG = GodotIO.class.getSimpleName();
- private final AssetManager am;
private final Activity activity;
private final String uniqueId;
GodotEditText edit;
@@ -73,100 +69,8 @@ public class GodotIO {
final int SCREEN_SENSOR_PORTRAIT = 5;
final int SCREEN_SENSOR = 6;
- /////////////////////////
- /// DIRECTORIES
- /////////////////////////
-
- static class AssetDir {
- public String[] files;
- public int current;
- public String path;
- }
-
- private int last_dir_id = 1;
-
- private final SparseArray<AssetDir> dirs;
-
- public int dir_open(String path) {
- AssetDir ad = new AssetDir();
- ad.current = 0;
- ad.path = path;
-
- try {
- ad.files = am.list(path);
- // no way to find path is directory or file exactly.
- // but if ad.files.length==0, then it's an empty directory or file.
- if (ad.files.length == 0) {
- return -1;
- }
- } catch (IOException e) {
- System.out.printf("Exception on dir_open: %s\n", e);
- return -1;
- }
-
- ++last_dir_id;
- dirs.put(last_dir_id, ad);
-
- return last_dir_id;
- }
-
- public boolean dir_is_dir(int id) {
- if (dirs.get(id) == null) {
- System.out.printf("dir_next: invalid dir id: %d\n", id);
- return false;
- }
- AssetDir ad = dirs.get(id);
- //System.out.printf("go next: %d,%d\n",ad.current,ad.files.length);
- int idx = ad.current;
- if (idx > 0)
- idx--;
-
- if (idx >= ad.files.length)
- return false;
- String fname = ad.files[idx];
-
- try {
- if (ad.path.equals(""))
- am.open(fname);
- else
- am.open(ad.path + "/" + fname);
- return false;
- } catch (Exception e) {
- return true;
- }
- }
-
- public String dir_next(int id) {
- if (dirs.get(id) == null) {
- System.out.printf("dir_next: invalid dir id: %d\n", id);
- return "";
- }
-
- AssetDir ad = dirs.get(id);
- //System.out.printf("go next: %d,%d\n",ad.current,ad.files.length);
-
- if (ad.current >= ad.files.length) {
- ad.current++;
- return "";
- }
- String r = ad.files[ad.current];
- ad.current++;
- return r;
- }
-
- public void dir_close(int id) {
- if (dirs.get(id) == null) {
- System.out.printf("dir_close: invalid dir id: %d\n", id);
- return;
- }
-
- dirs.remove(id);
- }
-
GodotIO(Activity p_activity) {
- am = p_activity.getAssets();
activity = p_activity;
- dirs = new SparseArray<>();
String androidId = Settings.Secure.getString(activity.getContentResolver(),
Settings.Secure.ANDROID_ID);
if (androidId == null) {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 3182ab0666..e2ae62d9cf 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -31,8 +31,13 @@
package org.godotengine.godot;
import org.godotengine.godot.gl.GodotRenderer;
+import org.godotengine.godot.io.directory.DirectoryAccessHandler;
+import org.godotengine.godot.io.file.FileAccessHandler;
+import org.godotengine.godot.tts.GodotTTS;
+import org.godotengine.godot.utils.GodotNetUtils;
import android.app.Activity;
+import android.content.res.AssetManager;
import android.hardware.SensorEvent;
import android.view.Surface;
@@ -42,8 +47,6 @@ import javax.microedition.khronos.opengles.GL10;
* Wrapper for native library
*/
public class GodotLib {
- public static GodotIO io;
-
static {
System.loadLibrary("godot_android");
}
@@ -51,7 +54,15 @@ public class GodotLib {
/**
* Invoked on the main thread to initialize Godot native layer.
*/
- public static native void initialize(Activity activity, Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
+ public static native void initialize(Activity activity,
+ Godot p_instance,
+ AssetManager p_asset_manager,
+ GodotIO godotIO,
+ GodotNetUtils netUtils,
+ DirectoryAccessHandler directoryAccessHandler,
+ FileAccessHandler fileAccessHandler,
+ boolean use_apk_expansion,
+ GodotTTS tts);
/**
* Invoked on the main thread to clean up Godot native layer.
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt
new file mode 100644
index 0000000000..c7bd55b620
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt
@@ -0,0 +1,114 @@
+/*************************************************************************/
+/* StorageScope.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.io
+
+import android.content.Context
+import android.os.Build
+import android.os.Environment
+import java.io.File
+
+/**
+ * Represents the different storage scopes.
+ */
+internal enum class StorageScope {
+ /**
+ * Covers internal and external directories accessible to the app without restrictions.
+ */
+ APP,
+
+ /**
+ * Covers shared directories (from Android 10 and higher).
+ */
+ SHARED,
+
+ /**
+ * Everything else..
+ */
+ UNKNOWN;
+
+ companion object {
+ /**
+ * Determines which [StorageScope] the given path falls under.
+ */
+ fun getStorageScope(context: Context, path: String?): StorageScope {
+ if (path == null) {
+ return UNKNOWN
+ }
+
+ val pathFile = File(path)
+ if (!pathFile.isAbsolute) {
+ return UNKNOWN
+ }
+
+ val canonicalPathFile = pathFile.canonicalPath
+
+ val internalAppDir = context.filesDir.canonicalPath ?: return UNKNOWN
+ if (canonicalPathFile.startsWith(internalAppDir)) {
+ return APP
+ }
+
+ val internalCacheDir = context.cacheDir.canonicalPath ?: return UNKNOWN
+ if (canonicalPathFile.startsWith(internalCacheDir)) {
+ return APP
+ }
+
+ val externalAppDir = context.getExternalFilesDir(null)?.canonicalPath ?: return UNKNOWN
+ if (canonicalPathFile.startsWith(externalAppDir)) {
+ return APP
+ }
+
+ val sharedDir = Environment.getExternalStorageDirectory().canonicalPath ?: return UNKNOWN
+ if (canonicalPathFile.startsWith(sharedDir)) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ // Before R, apps had access to shared storage so long as they have the right
+ // permissions (and flag on Q).
+ return APP
+ }
+
+ // Post R, access is limited based on the target destination
+ // 'Downloads' and 'Documents' are still accessible
+ val downloadsSharedDir =
+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).canonicalPath
+ ?: return SHARED
+ val documentsSharedDir =
+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).canonicalPath
+ ?: return SHARED
+ if (canonicalPathFile.startsWith(downloadsSharedDir) || canonicalPathFile.startsWith(documentsSharedDir)) {
+ return APP
+ }
+
+ return SHARED
+ }
+
+ return UNKNOWN
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt
new file mode 100644
index 0000000000..098b10ae36
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/AssetsDirectoryAccess.kt
@@ -0,0 +1,177 @@
+/*************************************************************************/
+/* AssetsDirectoryAccess.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.io.directory
+
+import android.content.Context
+import android.util.Log
+import android.util.SparseArray
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.Companion.INVALID_DIR_ID
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.Companion.STARTING_DIR_ID
+import java.io.File
+import java.io.IOException
+
+/**
+ * Handles directories access within the Android assets directory.
+ */
+internal class AssetsDirectoryAccess(context: Context) : DirectoryAccessHandler.DirectoryAccess {
+
+ companion object {
+ private val TAG = AssetsDirectoryAccess::class.java.simpleName
+ }
+
+ private data class AssetDir(val path: String, val files: Array<String>, var current: Int = 0)
+
+ private val assetManager = context.assets
+
+ private var lastDirId = STARTING_DIR_ID
+ private val dirs = SparseArray<AssetDir>()
+
+ private fun getAssetsPath(originalPath: String): String {
+ if (originalPath.startsWith(File.separatorChar)) {
+ return originalPath.substring(1)
+ }
+ return originalPath
+ }
+
+ override fun hasDirId(dirId: Int) = dirs.indexOfKey(dirId) >= 0
+
+ override fun dirOpen(path: String): Int {
+ val assetsPath = getAssetsPath(path) ?: return INVALID_DIR_ID
+ try {
+ val files = assetManager.list(assetsPath) ?: return INVALID_DIR_ID
+ // Empty directories don't get added to the 'assets' directory, so
+ // if ad.files.length > 0 ==> path is directory
+ // if ad.files.length == 0 ==> path is file
+ if (files.isEmpty()) {
+ return INVALID_DIR_ID
+ }
+
+ val ad = AssetDir(assetsPath, files)
+
+ dirs.put(++lastDirId, ad)
+ return lastDirId
+ } catch (e: IOException) {
+ Log.e(TAG, "Exception on dirOpen", e)
+ return INVALID_DIR_ID
+ }
+ }
+
+ override fun dirExists(path: String): Boolean {
+ val assetsPath = getAssetsPath(path)
+ try {
+ val files = assetManager.list(assetsPath) ?: return false
+ // Empty directories don't get added to the 'assets' directory, so
+ // if ad.files.length > 0 ==> path is directory
+ // if ad.files.length == 0 ==> path is file
+ return files.isNotEmpty()
+ } catch (e: IOException) {
+ Log.e(TAG, "Exception on dirExists", e)
+ return false
+ }
+ }
+
+ override fun fileExists(path: String): Boolean {
+ val assetsPath = getAssetsPath(path) ?: return false
+ try {
+ val files = assetManager.list(assetsPath) ?: return false
+ // Empty directories don't get added to the 'assets' directory, so
+ // if ad.files.length > 0 ==> path is directory
+ // if ad.files.length == 0 ==> path is file
+ return files.isEmpty()
+ } catch (e: IOException) {
+ Log.e(TAG, "Exception on fileExists", e)
+ return false
+ }
+ }
+
+ override fun dirIsDir(dirId: Int): Boolean {
+ val ad: AssetDir = dirs[dirId]
+
+ var idx = ad.current
+ if (idx > 0) {
+ idx--
+ }
+
+ if (idx >= ad.files.size) {
+ return false
+ }
+
+ val fileName = ad.files[idx]
+ // List the contents of $fileName. If it's a file, it will be empty, otherwise it'll be a
+ // directory
+ val filePath = if (ad.path == "") fileName else "${ad.path}/${fileName}"
+ val fileContents = assetManager.list(filePath)
+ return (fileContents?.size?: 0) > 0
+ }
+
+ override fun isCurrentHidden(dirId: Int): Boolean {
+ val ad = dirs[dirId]
+
+ var idx = ad.current
+ if (idx > 0) {
+ idx--
+ }
+
+ if (idx >= ad.files.size) {
+ return false
+ }
+
+ val fileName = ad.files[idx]
+ return fileName.startsWith('.')
+ }
+
+ override fun dirNext(dirId: Int): String {
+ val ad: AssetDir = dirs[dirId]
+
+ if (ad.current >= ad.files.size) {
+ ad.current++
+ return ""
+ }
+
+ return ad.files[ad.current++]
+ }
+
+ override fun dirClose(dirId: Int) {
+ dirs.remove(dirId)
+ }
+
+ override fun getDriveCount() = 0
+
+ override fun getDrive(drive: Int) = ""
+
+ override fun makeDir(dir: String) = false
+
+ override fun getSpaceLeft() = 0L
+
+ override fun rename(from: String, to: String) = false
+
+ override fun remove(filename: String) = false
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt
new file mode 100644
index 0000000000..fedcf4843f
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt
@@ -0,0 +1,224 @@
+/*************************************************************************/
+/* DirectoryAccessHandler.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.io.directory
+
+import android.content.Context
+import android.util.Log
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.AccessType.ACCESS_FILESYSTEM
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.AccessType.ACCESS_RESOURCES
+
+/**
+ * Handles files and directories access and manipulation for the Android platform
+ */
+class DirectoryAccessHandler(context: Context) {
+
+ companion object {
+ private val TAG = DirectoryAccessHandler::class.java.simpleName
+
+ internal const val INVALID_DIR_ID = -1
+ internal const val STARTING_DIR_ID = 1
+
+ private fun getAccessTypeFromNative(accessType: Int): AccessType? {
+ return when (accessType) {
+ ACCESS_RESOURCES.nativeValue -> ACCESS_RESOURCES
+ ACCESS_FILESYSTEM.nativeValue -> ACCESS_FILESYSTEM
+ else -> null
+ }
+ }
+ }
+
+ private enum class AccessType(val nativeValue: Int) {
+ ACCESS_RESOURCES(0), ACCESS_FILESYSTEM(2)
+ }
+
+ internal interface DirectoryAccess {
+ fun dirOpen(path: String): Int
+ fun dirNext(dirId: Int): String
+ fun dirClose(dirId: Int)
+ fun dirIsDir(dirId: Int): Boolean
+ fun dirExists(path: String): Boolean
+ fun fileExists(path: String): Boolean
+ fun hasDirId(dirId: Int): Boolean
+ fun isCurrentHidden(dirId: Int): Boolean
+ fun getDriveCount() : Int
+ fun getDrive(drive: Int): String
+ fun makeDir(dir: String): Boolean
+ fun getSpaceLeft(): Long
+ fun rename(from: String, to: String): Boolean
+ fun remove(filename: String): Boolean
+ }
+
+ private val assetsDirAccess = AssetsDirectoryAccess(context)
+ private val fileSystemDirAccess = FilesystemDirectoryAccess(context)
+
+ private fun hasDirId(accessType: AccessType, dirId: Int): Boolean {
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.hasDirId(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.hasDirId(dirId)
+ }
+ }
+
+ fun dirOpen(nativeAccessType: Int, path: String?): Int {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (path == null || accessType == null) {
+ return INVALID_DIR_ID
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirOpen(path)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirOpen(path)
+ }
+ }
+
+ fun dirNext(nativeAccessType: Int, dirId: Int): String {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (accessType == null || !hasDirId(accessType, dirId)) {
+ Log.w(TAG, "dirNext: Invalid dir id: $dirId")
+ return ""
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirNext(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirNext(dirId)
+ }
+ }
+
+ fun dirClose(nativeAccessType: Int, dirId: Int) {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (accessType == null || !hasDirId(accessType, dirId)) {
+ Log.w(TAG, "dirClose: Invalid dir id: $dirId")
+ return
+ }
+
+ when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirClose(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirClose(dirId)
+ }
+ }
+
+ fun dirIsDir(nativeAccessType: Int, dirId: Int): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (accessType == null || !hasDirId(accessType, dirId)) {
+ Log.w(TAG, "dirIsDir: Invalid dir id: $dirId")
+ return false
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirIsDir(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirIsDir(dirId)
+ }
+ }
+
+ fun isCurrentHidden(nativeAccessType: Int, dirId: Int): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (accessType == null || !hasDirId(accessType, dirId)) {
+ return false
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.isCurrentHidden(dirId)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.isCurrentHidden(dirId)
+ }
+ }
+
+ fun dirExists(nativeAccessType: Int, path: String?): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (path == null || accessType == null) {
+ return false
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.dirExists(path)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.dirExists(path)
+ }
+ }
+
+ fun fileExists(nativeAccessType: Int, path: String?): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType)
+ if (path == null || accessType == null) {
+ return false
+ }
+
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.fileExists(path)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.fileExists(path)
+ }
+ }
+
+ fun getDriveCount(nativeAccessType: Int): Int {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return 0
+ return when(accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.getDriveCount()
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.getDriveCount()
+ }
+ }
+
+ fun getDrive(nativeAccessType: Int, drive: Int): String {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return ""
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.getDrive(drive)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.getDrive(drive)
+ }
+ }
+
+ fun makeDir(nativeAccessType: Int, dir: String): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return false
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.makeDir(dir)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.makeDir(dir)
+ }
+ }
+
+ fun getSpaceLeft(nativeAccessType: Int): Long {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return 0L
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.getSpaceLeft()
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.getSpaceLeft()
+ }
+ }
+
+ fun rename(nativeAccessType: Int, from: String, to: String): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return false
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.rename(from, to)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.rename(from, to)
+ }
+ }
+
+ fun remove(nativeAccessType: Int, filename: String): Boolean {
+ val accessType = getAccessTypeFromNative(nativeAccessType) ?: return false
+ return when (accessType) {
+ ACCESS_RESOURCES -> assetsDirAccess.remove(filename)
+ ACCESS_FILESYSTEM -> fileSystemDirAccess.remove(filename)
+ }
+ }
+
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt
new file mode 100644
index 0000000000..c3acf42568
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt
@@ -0,0 +1,230 @@
+/*************************************************************************/
+/* FileSystemDirectoryAccess.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.io.directory
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Build
+import android.os.storage.StorageManager
+import android.util.Log
+import android.util.SparseArray
+import org.godotengine.godot.io.StorageScope
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.Companion.INVALID_DIR_ID
+import org.godotengine.godot.io.directory.DirectoryAccessHandler.Companion.STARTING_DIR_ID
+import org.godotengine.godot.io.file.FileAccessHandler
+import java.io.File
+
+/**
+ * Handles directories access with the internal and external filesystem.
+ */
+internal class FilesystemDirectoryAccess(private val context: Context):
+ DirectoryAccessHandler.DirectoryAccess {
+
+ companion object {
+ private val TAG = FilesystemDirectoryAccess::class.java.simpleName
+ }
+
+ private data class DirData(val dirFile: File, val files: Array<File>, var current: Int = 0)
+
+ private val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
+ private var lastDirId = STARTING_DIR_ID
+ private val dirs = SparseArray<DirData>()
+
+ private fun inScope(path: String): Boolean {
+ // Directory access is available for shared storage on Android 11+
+ // On Android 10, access is also available as long as the `requestLegacyExternalStorage`
+ // tag is available.
+ return StorageScope.getStorageScope(context, path) != StorageScope.UNKNOWN
+ }
+
+ override fun hasDirId(dirId: Int) = dirs.indexOfKey(dirId) >= 0
+
+ override fun dirOpen(path: String): Int {
+ if (!inScope(path)) {
+ Log.w(TAG, "Path $path is not accessible.")
+ return INVALID_DIR_ID
+ }
+
+ // Check this is a directory.
+ val dirFile = File(path)
+ if (!dirFile.isDirectory) {
+ return INVALID_DIR_ID
+ }
+
+ // Get the files in the directory
+ val files = dirFile.listFiles()?: return INVALID_DIR_ID
+
+ // Create the data representing this directory
+ val dirData = DirData(dirFile, files)
+
+ dirs.put(++lastDirId, dirData)
+ return lastDirId
+ }
+
+ override fun dirExists(path: String): Boolean {
+ if (!inScope(path)) {
+ Log.w(TAG, "Path $path is not accessible.")
+ return false
+ }
+
+ try {
+ return File(path).isDirectory
+ } catch (e: SecurityException) {
+ return false
+ }
+ }
+
+ override fun fileExists(path: String) = FileAccessHandler.fileExists(context, path)
+
+ override fun dirNext(dirId: Int): String {
+ val dirData = dirs[dirId]
+ if (dirData.current >= dirData.files.size) {
+ dirData.current++
+ return ""
+ }
+
+ return dirData.files[dirData.current++].name
+ }
+
+ override fun dirClose(dirId: Int) {
+ dirs.remove(dirId)
+ }
+
+ override fun dirIsDir(dirId: Int): Boolean {
+ val dirData = dirs[dirId]
+
+ var index = dirData.current
+ if (index > 0) {
+ index--
+ }
+
+ if (index >= dirData.files.size) {
+ return false
+ }
+
+ return dirData.files[index].isDirectory
+ }
+
+ override fun isCurrentHidden(dirId: Int): Boolean {
+ val dirData = dirs[dirId]
+
+ var index = dirData.current
+ if (index > 0) {
+ index--
+ }
+
+ if (index >= dirData.files.size) {
+ return false
+ }
+
+ return dirData.files[index].isHidden
+ }
+
+ override fun getDriveCount(): Int {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ storageManager.storageVolumes.size
+ } else {
+ 0
+ }
+ }
+
+ override fun getDrive(drive: Int): String {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+ return ""
+ }
+
+ if (drive < 0 || drive >= storageManager.storageVolumes.size) {
+ return ""
+ }
+
+ val storageVolume = storageManager.storageVolumes[drive]
+ return storageVolume.getDescription(context)
+ }
+
+ override fun makeDir(dir: String): Boolean {
+ if (!inScope(dir)) {
+ Log.w(TAG, "Directory $dir is not accessible.")
+ return false
+ }
+
+ try {
+ val dirFile = File(dir)
+ return dirFile.isDirectory || dirFile.mkdirs()
+ } catch (e: SecurityException) {
+ return false
+ }
+ }
+
+ @SuppressLint("UsableSpace")
+ override fun getSpaceLeft() = context.getExternalFilesDir(null)?.usableSpace ?: 0L
+
+ override fun rename(from: String, to: String): Boolean {
+ if (!inScope(from) || !inScope(to)) {
+ Log.w(TAG, "Argument filenames are not accessible:\n" +
+ "from: $from\n" +
+ "to: $to")
+ return false
+ }
+
+ return try {
+ val fromFile = File(from)
+ if (fromFile.isDirectory) {
+ fromFile.renameTo(File(to))
+ } else {
+ FileAccessHandler.renameFile(context, from, to)
+ }
+ } catch (e: SecurityException) {
+ false
+ }
+ }
+
+ override fun remove(filename: String): Boolean {
+ if (!inScope(filename)) {
+ Log.w(TAG, "Filename $filename is not accessible.")
+ return false
+ }
+
+ return try {
+ val deleteFile = File(filename)
+ if (deleteFile.exists()) {
+ if (deleteFile.isDirectory) {
+ deleteFile.delete()
+ } else {
+ FileAccessHandler.removeFile(context, filename)
+ }
+ } else {
+ true
+ }
+ } catch (e: SecurityException) {
+ false
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt
new file mode 100644
index 0000000000..aef1bed8ce
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt
@@ -0,0 +1,186 @@
+/*************************************************************************/
+/* DataAccess.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.io.file
+
+import android.content.Context
+import android.os.Build
+import android.util.Log
+import org.godotengine.godot.io.StorageScope
+import java.io.IOException
+import java.nio.ByteBuffer
+import java.nio.channels.FileChannel
+import kotlin.math.max
+
+/**
+ * Base class for file IO operations.
+ *
+ * Its derived instances provide concrete implementations to handle regular file access, as well
+ * as file access through the media store API on versions of Android were scoped storage is enabled.
+ */
+internal abstract class DataAccess(private val filePath: String) {
+
+ companion object {
+ private val TAG = DataAccess::class.java.simpleName
+
+ fun generateDataAccess(
+ storageScope: StorageScope,
+ context: Context,
+ filePath: String,
+ accessFlag: FileAccessFlags
+ ): DataAccess? {
+ return when (storageScope) {
+ StorageScope.APP -> FileData(filePath, accessFlag)
+
+ StorageScope.SHARED -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ MediaStoreData(context, filePath, accessFlag)
+ } else {
+ null
+ }
+
+ StorageScope.UNKNOWN -> null
+ }
+ }
+
+ fun fileExists(storageScope: StorageScope, context: Context, path: String): Boolean {
+ return when(storageScope) {
+ StorageScope.APP -> FileData.fileExists(path)
+ StorageScope.SHARED -> MediaStoreData.fileExists(context, path)
+ StorageScope.UNKNOWN -> false
+ }
+ }
+
+ fun fileLastModified(storageScope: StorageScope, context: Context, path: String): Long {
+ return when(storageScope) {
+ StorageScope.APP -> FileData.fileLastModified(path)
+ StorageScope.SHARED -> MediaStoreData.fileLastModified(context, path)
+ StorageScope.UNKNOWN -> 0L
+ }
+ }
+
+ fun removeFile(storageScope: StorageScope, context: Context, path: String): Boolean {
+ return when(storageScope) {
+ StorageScope.APP -> FileData.delete(path)
+ StorageScope.SHARED -> MediaStoreData.delete(context, path)
+ StorageScope.UNKNOWN -> false
+ }
+ }
+
+ fun renameFile(storageScope: StorageScope, context: Context, from: String, to: String): Boolean {
+ return when(storageScope) {
+ StorageScope.APP -> FileData.rename(from, to)
+ StorageScope.SHARED -> MediaStoreData.rename(context, from, to)
+ StorageScope.UNKNOWN -> false
+ }
+ }
+ }
+
+ protected abstract val fileChannel: FileChannel
+ internal var endOfFile = false
+ private set
+
+ fun close() {
+ try {
+ fileChannel.close()
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception when closing file $filePath.", e)
+ }
+ }
+
+ fun flush() {
+ try {
+ fileChannel.force(false)
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception when flushing file $filePath.", e)
+ }
+ }
+
+ fun seek(position: Long) {
+ try {
+ fileChannel.position(position)
+ if (position <= size()) {
+ endOfFile = false
+ }
+ } catch (e: Exception) {
+ Log.w(TAG, "Exception when seeking file $filePath.", e)
+ }
+ }
+
+ fun seekFromEnd(positionFromEnd: Long) {
+ val positionFromBeginning = max(0, size() - positionFromEnd)
+ seek(positionFromBeginning)
+ }
+
+ fun position(): Long {
+ return try {
+ fileChannel.position()
+ } catch (e: IOException) {
+ Log.w(
+ TAG,
+ "Exception when retrieving position for file $filePath.",
+ e
+ )
+ 0L
+ }
+ }
+
+ fun size() = try {
+ fileChannel.size()
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception when retrieving size for file $filePath.", e)
+ 0L
+ }
+
+ fun read(buffer: ByteBuffer): Int {
+ return try {
+ val readBytes = fileChannel.read(buffer)
+ if (readBytes == -1) {
+ endOfFile = true
+ 0
+ } else {
+ readBytes
+ }
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception while reading from file $filePath.", e)
+ 0
+ }
+ }
+
+ fun write(buffer: ByteBuffer) {
+ try {
+ val writtenBytes = fileChannel.write(buffer)
+ if (writtenBytes > 0) {
+ endOfFile = false
+ }
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception while writing to file $filePath.", e)
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessFlags.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessFlags.kt
new file mode 100644
index 0000000000..c6b242a4b6
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessFlags.kt
@@ -0,0 +1,87 @@
+/*************************************************************************/
+/* FileAccessFlags.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.io.file
+
+/**
+ * Android representation of Godot native access flags.
+ */
+internal enum class FileAccessFlags(val nativeValue: Int) {
+ /**
+ * Opens the file for read operations.
+ * The cursor is positioned at the beginning of the file.
+ */
+ READ(1),
+
+ /**
+ * Opens the file for write operations.
+ * The file is created if it does not exist, and truncated if it does.
+ */
+ WRITE(2),
+
+ /**
+ * Opens the file for read and write operations.
+ * Does not truncate the file. The cursor is positioned at the beginning of the file.
+ */
+ READ_WRITE(3),
+
+ /**
+ * Opens the file for read and write operations.
+ * The file is created if it does not exist, and truncated if it does.
+ * The cursor is positioned at the beginning of the file.
+ */
+ WRITE_READ(7);
+
+ fun getMode(): String {
+ return when (this) {
+ READ -> "r"
+ WRITE -> "w"
+ READ_WRITE, WRITE_READ -> "rw"
+ }
+ }
+
+ fun shouldTruncate(): Boolean {
+ return when (this) {
+ READ, READ_WRITE -> false
+ WRITE, WRITE_READ -> true
+ }
+ }
+
+ companion object {
+ fun fromNativeModeFlags(modeFlag: Int): FileAccessFlags? {
+ for (flag in values()) {
+ if (flag.nativeValue == modeFlag) {
+ return flag
+ }
+ }
+ return null
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt
new file mode 100644
index 0000000000..a4e0a82d6e
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt
@@ -0,0 +1,202 @@
+/*************************************************************************/
+/* FileAccessHandler.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.io.file
+
+import android.content.Context
+import android.util.Log
+import android.util.SparseArray
+import org.godotengine.godot.io.StorageScope
+import java.io.FileNotFoundException
+import java.nio.ByteBuffer
+
+/**
+ * Handles regular and media store file access and interactions.
+ */
+class FileAccessHandler(val context: Context) {
+
+ companion object {
+ private val TAG = FileAccessHandler::class.java.simpleName
+
+ private const val FILE_NOT_FOUND_ERROR_ID = -1
+ private const val INVALID_FILE_ID = 0
+ private const val STARTING_FILE_ID = 1
+
+ fun fileExists(context: Context, path: String?): Boolean {
+ val storageScope = StorageScope.getStorageScope(context, path)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return false
+ }
+
+ return try {
+ DataAccess.fileExists(storageScope, context, path!!)
+ } catch (e: SecurityException) {
+ false
+ }
+ }
+
+ fun removeFile(context: Context, path: String?): Boolean {
+ val storageScope = StorageScope.getStorageScope(context, path)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return false
+ }
+
+ return try {
+ DataAccess.removeFile(storageScope, context, path!!)
+ } catch (e: Exception) {
+ false
+ }
+ }
+
+ fun renameFile(context: Context, from: String?, to: String?): Boolean {
+ val storageScope = StorageScope.getStorageScope(context, from)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return false
+ }
+
+ return try {
+ DataAccess.renameFile(storageScope, context, from!!, to!!)
+ } catch (e: Exception) {
+ false
+ }
+ }
+ }
+
+ private val files = SparseArray<DataAccess>()
+ private var lastFileId = STARTING_FILE_ID
+
+ private fun hasFileId(fileId: Int) = files.indexOfKey(fileId) >= 0
+
+ fun fileOpen(path: String?, modeFlags: Int): Int {
+ val storageScope = StorageScope.getStorageScope(context, path)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return INVALID_FILE_ID
+ }
+
+ try {
+ val accessFlag = FileAccessFlags.fromNativeModeFlags(modeFlags) ?: return INVALID_FILE_ID
+ val dataAccess = DataAccess.generateDataAccess(storageScope, context, path!!, accessFlag) ?: return INVALID_FILE_ID
+
+ files.put(++lastFileId, dataAccess)
+ return lastFileId
+ } catch (e: FileNotFoundException) {
+ return FILE_NOT_FOUND_ERROR_ID
+ } catch (e: Exception) {
+ Log.w(TAG, "Error while opening $path", e)
+ return INVALID_FILE_ID
+ }
+ }
+
+ fun fileGetSize(fileId: Int): Long {
+ if (!hasFileId(fileId)) {
+ return 0L
+ }
+
+ return files[fileId].size()
+ }
+
+ fun fileSeek(fileId: Int, position: Long) {
+ if (!hasFileId(fileId)) {
+ return
+ }
+
+ files[fileId].seek(position)
+ }
+
+ fun fileSeekFromEnd(fileId: Int, position: Long) {
+ if (!hasFileId(fileId)) {
+ return
+ }
+
+ files[fileId].seekFromEnd(position)
+ }
+
+ fun fileRead(fileId: Int, byteBuffer: ByteBuffer?): Int {
+ if (!hasFileId(fileId) || byteBuffer == null) {
+ return 0
+ }
+
+ return files[fileId].read(byteBuffer)
+ }
+
+ fun fileWrite(fileId: Int, byteBuffer: ByteBuffer?) {
+ if (!hasFileId(fileId) || byteBuffer == null) {
+ return
+ }
+
+ files[fileId].write(byteBuffer)
+ }
+
+ fun fileFlush(fileId: Int) {
+ if (!hasFileId(fileId)) {
+ return
+ }
+
+ files[fileId].flush()
+ }
+
+ fun fileExists(path: String?) = Companion.fileExists(context, path)
+
+ fun fileLastModified(filepath: String?): Long {
+ val storageScope = StorageScope.getStorageScope(context, filepath)
+ if (storageScope == StorageScope.UNKNOWN) {
+ return 0L
+ }
+
+ return try {
+ DataAccess.fileLastModified(storageScope, context, filepath!!)
+ } catch (e: SecurityException) {
+ 0L
+ }
+ }
+
+ fun fileGetPosition(fileId: Int): Long {
+ if (!hasFileId(fileId)) {
+ return 0L
+ }
+
+ return files[fileId].position()
+ }
+
+ fun isFileEof(fileId: Int): Boolean {
+ if (!hasFileId(fileId)) {
+ return false
+ }
+
+ return files[fileId].endOfFile
+ }
+
+ fun fileClose(fileId: Int) {
+ if (hasFileId(fileId)) {
+ files[fileId].close()
+ files.remove(fileId)
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileData.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileData.kt
new file mode 100644
index 0000000000..5af694ad99
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileData.kt
@@ -0,0 +1,93 @@
+/*************************************************************************/
+/* FileData.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.io.file
+
+import java.io.File
+import java.io.FileOutputStream
+import java.io.RandomAccessFile
+import java.nio.channels.FileChannel
+
+/**
+ * Implementation of [DataAccess] which handles regular (not scoped) file access and interactions.
+ */
+internal class FileData(filePath: String, accessFlag: FileAccessFlags) : DataAccess(filePath) {
+
+ companion object {
+ private val TAG = FileData::class.java.simpleName
+
+ fun fileExists(path: String): Boolean {
+ return try {
+ File(path).isFile
+ } catch (e: SecurityException) {
+ false
+ }
+ }
+
+ fun fileLastModified(filepath: String): Long {
+ return try {
+ File(filepath).lastModified()
+ } catch (e: SecurityException) {
+ 0L
+ }
+ }
+
+ fun delete(filepath: String): Boolean {
+ return try {
+ File(filepath).delete()
+ } catch (e: Exception) {
+ false
+ }
+ }
+
+ fun rename(from: String, to: String): Boolean {
+ return try {
+ val fromFile = File(from)
+ fromFile.renameTo(File(to))
+ } catch (e: Exception) {
+ false
+ }
+ }
+ }
+
+ override val fileChannel: FileChannel
+
+ init {
+ if (accessFlag == FileAccessFlags.WRITE) {
+ fileChannel = FileOutputStream(filePath, !accessFlag.shouldTruncate()).channel
+ } else {
+ fileChannel = RandomAccessFile(filePath, accessFlag.getMode()).channel
+ }
+
+ if (accessFlag.shouldTruncate()) {
+ fileChannel.truncate(0)
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/MediaStoreData.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/MediaStoreData.kt
new file mode 100644
index 0000000000..81a7dd1705
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/MediaStoreData.kt
@@ -0,0 +1,284 @@
+/*************************************************************************/
+/* MediaStoreData.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.io.file
+
+import android.content.ContentUris
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import android.net.Uri
+import android.os.Build
+import android.os.Environment
+import android.provider.MediaStore
+import androidx.annotation.RequiresApi
+
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileNotFoundException
+import java.io.FileOutputStream
+import java.nio.channels.FileChannel
+
+/**
+ * Implementation of [DataAccess] which handles access and interactions with file and data
+ * under scoped storage via the MediaStore API.
+ */
+@RequiresApi(Build.VERSION_CODES.Q)
+internal class MediaStoreData(context: Context, filePath: String, accessFlag: FileAccessFlags) :
+ DataAccess(filePath) {
+
+ private data class DataItem(
+ val id: Long,
+ val uri: Uri,
+ val displayName: String,
+ val relativePath: String,
+ val size: Int,
+ val dateModified: Int,
+ val mediaType: Int
+ )
+
+ companion object {
+ private val TAG = MediaStoreData::class.java.simpleName
+
+ private val COLLECTION = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
+
+ private val PROJECTION = arrayOf(
+ MediaStore.Files.FileColumns._ID,
+ MediaStore.Files.FileColumns.DISPLAY_NAME,
+ MediaStore.Files.FileColumns.RELATIVE_PATH,
+ MediaStore.Files.FileColumns.SIZE,
+ MediaStore.Files.FileColumns.DATE_MODIFIED,
+ MediaStore.Files.FileColumns.MEDIA_TYPE,
+ )
+
+ private const val SELECTION_BY_PATH = "${MediaStore.Files.FileColumns.DISPLAY_NAME} = ? " +
+ " AND ${MediaStore.Files.FileColumns.RELATIVE_PATH} = ?"
+
+ private fun getSelectionByPathArguments(path: String): Array<String> {
+ return arrayOf(getMediaStoreDisplayName(path), getMediaStoreRelativePath(path))
+ }
+
+ private const val SELECTION_BY_ID = "${MediaStore.Files.FileColumns._ID} = ? "
+
+ private fun getSelectionByIdArgument(id: Long) = arrayOf(id.toString())
+
+ private fun getMediaStoreDisplayName(path: String) = File(path).name
+
+ private fun getMediaStoreRelativePath(path: String): String {
+ val pathFile = File(path)
+ val environmentDir = Environment.getExternalStorageDirectory()
+ var relativePath = (pathFile.parent?.replace(environmentDir.absolutePath, "") ?: "").trim('/')
+ if (relativePath.isNotBlank()) {
+ relativePath += "/"
+ }
+ return relativePath
+ }
+
+ private fun queryById(context: Context, id: Long): List<DataItem> {
+ val query = context.contentResolver.query(
+ COLLECTION,
+ PROJECTION,
+ SELECTION_BY_ID,
+ getSelectionByIdArgument(id),
+ null
+ )
+ return dataItemFromCursor(query)
+ }
+
+ private fun queryByPath(context: Context, path: String): List<DataItem> {
+ val query = context.contentResolver.query(
+ COLLECTION,
+ PROJECTION,
+ SELECTION_BY_PATH,
+ getSelectionByPathArguments(path),
+ null
+ )
+ return dataItemFromCursor(query)
+ }
+
+ private fun dataItemFromCursor(query: Cursor?): List<DataItem> {
+ query?.use { cursor ->
+ cursor.count
+ if (cursor.count == 0) {
+ return emptyList()
+ }
+ val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)
+ val displayNameColumn =
+ cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME)
+ val relativePathColumn =
+ cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.RELATIVE_PATH)
+ val sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE)
+ val dateModifiedColumn =
+ cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATE_MODIFIED)
+ val mediaTypeColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MEDIA_TYPE)
+
+ val result = ArrayList<DataItem>()
+ while (cursor.moveToNext()) {
+ val id = cursor.getLong(idColumn)
+ result.add(
+ DataItem(
+ id,
+ ContentUris.withAppendedId(COLLECTION, id),
+ cursor.getString(displayNameColumn),
+ cursor.getString(relativePathColumn),
+ cursor.getInt(sizeColumn),
+ cursor.getInt(dateModifiedColumn),
+ cursor.getInt(mediaTypeColumn)
+ )
+ )
+ }
+ return result
+ }
+ return emptyList()
+ }
+
+ private fun addFile(context: Context, path: String): DataItem? {
+ val fileDetails = ContentValues().apply {
+ put(MediaStore.Files.FileColumns._ID, 0)
+ put(MediaStore.Files.FileColumns.DISPLAY_NAME, getMediaStoreDisplayName(path))
+ put(MediaStore.Files.FileColumns.RELATIVE_PATH, getMediaStoreRelativePath(path))
+ }
+
+ context.contentResolver.insert(COLLECTION, fileDetails) ?: return null
+
+ // File was successfully added, let's retrieve its info
+ val infos = queryByPath(context, path)
+ if (infos.isEmpty()) {
+ return null
+ }
+
+ return infos[0]
+ }
+
+ fun delete(context: Context, path: String): Boolean {
+ val itemsToDelete = queryByPath(context, path)
+ if (itemsToDelete.isEmpty()) {
+ return false
+ }
+
+ val resolver = context.contentResolver
+ var itemsDeleted = 0
+ for (item in itemsToDelete) {
+ itemsDeleted += resolver.delete(item.uri, null, null)
+ }
+
+ return itemsDeleted > 0
+ }
+
+ fun fileExists(context: Context, path: String): Boolean {
+ return queryByPath(context, path).isNotEmpty()
+ }
+
+ fun fileLastModified(context: Context, path: String): Long {
+ val result = queryByPath(context, path)
+ if (result.isEmpty()) {
+ return 0L
+ }
+
+ val dataItem = result[0]
+ return dataItem.dateModified.toLong()
+ }
+
+ fun rename(context: Context, from: String, to: String): Boolean {
+ // Ensure the source exists.
+ val sources = queryByPath(context, from)
+ if (sources.isEmpty()) {
+ return false
+ }
+
+ // Take the first source
+ val source = sources[0]
+
+ // Set up the updated values
+ val updatedDetails = ContentValues().apply {
+ put(MediaStore.Files.FileColumns.DISPLAY_NAME, getMediaStoreDisplayName(to))
+ put(MediaStore.Files.FileColumns.RELATIVE_PATH, getMediaStoreRelativePath(to))
+ }
+
+ val updated = context.contentResolver.update(
+ source.uri,
+ updatedDetails,
+ SELECTION_BY_ID,
+ getSelectionByIdArgument(source.id)
+ )
+ return updated > 0
+ }
+ }
+
+ private val id: Long
+ private val uri: Uri
+ override val fileChannel: FileChannel
+
+ init {
+ val contentResolver = context.contentResolver
+ val dataItems = queryByPath(context, filePath)
+
+ val dataItem = when (accessFlag) {
+ FileAccessFlags.READ -> {
+ // The file should already exist
+ if (dataItems.isEmpty()) {
+ throw FileNotFoundException("Unable to access file $filePath")
+ }
+
+ val dataItem = dataItems[0]
+ dataItem
+ }
+
+ FileAccessFlags.WRITE, FileAccessFlags.READ_WRITE, FileAccessFlags.WRITE_READ -> {
+ // Create the file if it doesn't exist
+ val dataItem = if (dataItems.isEmpty()) {
+ addFile(context, filePath)
+ } else {
+ dataItems[0]
+ }
+
+ if (dataItem == null) {
+ throw FileNotFoundException("Unable to access file $filePath")
+ }
+ dataItem
+ }
+ }
+
+ id = dataItem.id
+ uri = dataItem.uri
+
+ val parcelFileDescriptor = contentResolver.openFileDescriptor(uri, accessFlag.getMode())
+ ?: throw IllegalStateException("Unable to access file descriptor")
+ fileChannel = if (accessFlag == FileAccessFlags.READ) {
+ FileInputStream(parcelFileDescriptor.fileDescriptor).channel
+ } else {
+ FileOutputStream(parcelFileDescriptor.fileDescriptor).channel
+ }
+
+ if (accessFlag.shouldTruncate()) {
+ fileChannel.truncate(0)
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
index e5b4f41153..57db0709f0 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
@@ -32,10 +32,14 @@ package org.godotengine.godot.utils;
import android.Manifest;
import android.app.Activity;
+import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
+import android.net.Uri;
import android.os.Build;
+import android.os.Environment;
+import android.provider.Settings;
import android.util.Log;
import androidx.core.content.ContextCompat;
@@ -53,7 +57,8 @@ public final class PermissionsUtil {
static final int REQUEST_RECORD_AUDIO_PERMISSION = 1;
static final int REQUEST_CAMERA_PERMISSION = 2;
static final int REQUEST_VIBRATE_PERMISSION = 3;
- static final int REQUEST_ALL_PERMISSION_REQ_CODE = 1001;
+ public static final int REQUEST_ALL_PERMISSION_REQ_CODE = 1001;
+ public static final int REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE = 2002;
private PermissionsUtil() {
}
@@ -108,13 +113,26 @@ public final class PermissionsUtil {
if (manifestPermissions.length == 0)
return true;
- List<String> dangerousPermissions = new ArrayList<>();
+ List<String> requestedPermissions = new ArrayList<>();
for (String manifestPermission : manifestPermissions) {
try {
- PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
- int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
- if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) != PackageManager.PERMISSION_GRANTED) {
- dangerousPermissions.add(manifestPermission);
+ if (manifestPermission.equals(Manifest.permission.MANAGE_EXTERNAL_STORAGE)) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
+ try {
+ Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
+ intent.setData(Uri.parse(String.format("package:%s", activity.getPackageName())));
+ activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE);
+ } catch (Exception ignored) {
+ Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
+ activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE);
+ }
+ }
+ } else {
+ PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
+ int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
+ if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) != PackageManager.PERMISSION_GRANTED) {
+ requestedPermissions.add(manifestPermission);
+ }
}
} catch (PackageManager.NameNotFoundException e) {
// Skip this permission and continue.
@@ -122,13 +140,12 @@ public final class PermissionsUtil {
}
}
- if (dangerousPermissions.isEmpty()) {
+ if (requestedPermissions.isEmpty()) {
// If list is empty, all of dangerous permissions were granted.
return true;
}
- String[] requestedPermissions = dangerousPermissions.toArray(new String[0]);
- activity.requestPermissions(requestedPermissions, REQUEST_ALL_PERMISSION_REQ_CODE);
+ activity.requestPermissions(requestedPermissions.toArray(new String[0]), REQUEST_ALL_PERMISSION_REQ_CODE);
return false;
}
@@ -148,13 +165,19 @@ public final class PermissionsUtil {
if (manifestPermissions.length == 0)
return manifestPermissions;
- List<String> dangerousPermissions = new ArrayList<>();
+ List<String> grantedPermissions = new ArrayList<>();
for (String manifestPermission : manifestPermissions) {
try {
- PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
- int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
- if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) == PackageManager.PERMISSION_GRANTED) {
- dangerousPermissions.add(manifestPermission);
+ if (manifestPermission.equals(Manifest.permission.MANAGE_EXTERNAL_STORAGE)) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && Environment.isExternalStorageManager()) {
+ grantedPermissions.add(manifestPermission);
+ }
+ } else {
+ PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
+ int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
+ if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) == PackageManager.PERMISSION_GRANTED) {
+ grantedPermissions.add(manifestPermission);
+ }
}
} catch (PackageManager.NameNotFoundException e) {
// Skip this permission and continue.
@@ -162,7 +185,7 @@ public final class PermissionsUtil {
}
}
- return dangerousPermissions.toArray(new String[0]);
+ return grantedPermissions.toArray(new String[0]);
}
/**
@@ -177,7 +200,7 @@ public final class PermissionsUtil {
if (permission.equals(p))
return true;
}
- } catch (PackageManager.NameNotFoundException e) {
+ } catch (PackageManager.NameNotFoundException ignored) {
}
return false;
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index eaffe14b13..f4de4acfad 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -43,6 +43,7 @@
#include "dir_access_jandroid.h"
#include "display_server_android.h"
#include "file_access_android.h"
+#include "file_access_filesystem_jandroid.h"
#include "jni_utils.h"
#include "main/main.h"
#include "net_socket_android.h"
@@ -78,13 +79,13 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei
}
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject godot_instance, jobject p_asset_manager, jboolean p_use_apk_expansion) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_activity, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion, jobject p_godot_tts) {
JavaVM *jvm;
env->GetJavaVM(&jvm);
// create our wrapper classes
- godot_java = new GodotJavaWrapper(env, activity, godot_instance);
- godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env));
+ godot_java = new GodotJavaWrapper(env, p_activity, p_godot_instance);
+ godot_io_java = new GodotIOJavaWrapper(env, p_godot_io);
init_thread_jandroid(jvm, env);
@@ -92,9 +93,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
FileAccessAndroid::asset_manager = AAssetManager_fromJava(env, amgr);
- DirAccessJAndroid::setup(godot_io_java->get_instance());
- NetSocketAndroid::setup(godot_java->get_member_object("netUtils", "Lorg/godotengine/godot/utils/GodotNetUtils;", env));
- TTS_Android::setup(godot_java->get_member_object("tts", "Lorg/godotengine/godot/tts/GodotTTS;", env));
+ DirAccessJAndroid::setup(p_directory_access_handler);
+ FileAccessFilesystemJAndroid::setup(p_file_access_handler);
+ NetSocketAndroid::setup(p_net_utils);
+ TTS_Android::setup(p_godot_tts);
os_android = new OS_Android(godot_java, godot_io_java, p_use_apk_expansion);
@@ -157,6 +159,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jc
memfree(cmdline);
}
+ // Note: --help and --version return ERR_HELP, but this should be translated to 0 if exit codes are propagated.
if (err != OK) {
return; // should exit instead and print the error
}
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index aa8d67cf46..de16f197b8 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -37,7 +37,7 @@
// These functions can be called from within JAVA and are the means by which our JAVA implementation calls back into our C++ code.
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject godot_instance, jobject p_asset_manager, jboolean p_use_apk_expansion);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_activity, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion, jobject p_godot_tts);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jobject p_surface, jint p_width, jint p_height);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 6674428de8..0f551e7f4f 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -40,6 +40,7 @@
#include "dir_access_jandroid.h"
#include "file_access_android.h"
+#include "file_access_filesystem_jandroid.h"
#include "net_socket_android.h"
#include <dlfcn.h>
@@ -93,7 +94,7 @@ void OS_Android::initialize_core() {
}
#endif
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
- FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_FILESYSTEM);
+ FileAccess::make_default<FileAccessFilesystemJAndroid>(FileAccess::ACCESS_FILESYSTEM);
#ifdef TOOLS_ENABLED
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_RESOURCES);
@@ -105,7 +106,7 @@ void OS_Android::initialize_core() {
}
#endif
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_USERDATA);
- DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_FILESYSTEM);
+ DirAccess::make_default<DirAccessJAndroid>(DirAccess::ACCESS_FILESYSTEM);
NetSocketAndroid::make_default();
}
@@ -300,6 +301,33 @@ String OS_Android::get_system_dir(SystemDir p_dir, bool p_shared_storage) const
return godot_io_java->get_system_dir(p_dir, p_shared_storage);
}
+Error OS_Android::move_to_trash(const String &p_path) {
+ Ref<DirAccess> da_ref = DirAccess::create_for_path(p_path);
+ if (da_ref.is_null()) {
+ return FAILED;
+ }
+
+ // Check if it's a directory
+ if (da_ref->dir_exists(p_path)) {
+ Error err = da_ref->change_dir(p_path);
+ if (err) {
+ return err;
+ }
+ // This is directory, let's erase its contents
+ err = da_ref->erase_contents_recursive();
+ if (err) {
+ return err;
+ }
+ // Remove the top directory
+ return da_ref->remove(p_path);
+ } else if (da_ref->file_exists(p_path)) {
+ // This is a file, let's remove it.
+ return da_ref->remove(p_path);
+ } else {
+ return FAILED;
+ }
+}
+
void OS_Android::set_display_size(const Size2i &p_size) {
display_size = p_size;
}
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 3f607eac48..96c06d715c 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -122,6 +122,8 @@ public:
virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override;
+ virtual Error move_to_trash(const String &p_path) override;
+
void vibrate_handheld(int p_duration_ms) override;
virtual String get_config_path() const override;
diff --git a/platform/iphone/SCsub b/platform/ios/SCsub
index 5e10bf5646..bf12ab6dd7 100644
--- a/platform/iphone/SCsub
+++ b/platform/ios/SCsub
@@ -2,16 +2,16 @@
Import("env")
-iphone_lib = [
- "godot_iphone.mm",
- "os_iphone.mm",
+ios_lib = [
+ "godot_ios.mm",
+ "os_ios.mm",
"main.m",
"app_delegate.mm",
"view_controller.mm",
"ios.mm",
- "vulkan_context_iphone.mm",
- "display_server_iphone.mm",
- "joypad_iphone.mm",
+ "vulkan_context_ios.mm",
+ "display_server_ios.mm",
+ "joypad_ios.mm",
"godot_view.mm",
"tts_ios.mm",
"display_layer.mm",
@@ -23,7 +23,7 @@ iphone_lib = [
]
env_ios = env.Clone()
-ios_lib = env_ios.add_library("iphone", iphone_lib)
+ios_lib = env_ios.add_library("ios", ios_lib)
# (iOS) Enable module support
env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
@@ -32,9 +32,9 @@ env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
def combine_libs(target=None, source=None, env=None):
lib_path = target[0].srcnode().abspath
if "osxcross" in env:
- libtool = "$IPHONEPATH/usr/bin/${ios_triple}libtool"
+ libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}libtool"
else:
- libtool = "$IPHONEPATH/usr/bin/libtool"
+ libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/libtool"
env.Execute(
libtool + ' -static -o "' + lib_path + '" ' + " ".join([('"' + lib.srcnode().abspath + '"') for lib in source])
)
diff --git a/platform/iphone/api/api.cpp b/platform/ios/api/api.cpp
index f2e6fd7a7a..00c76a9256 100644
--- a/platform/iphone/api/api.cpp
+++ b/platform/ios/api/api.cpp
@@ -30,19 +30,19 @@
#include "api.h"
-#if defined(IPHONE_ENABLED)
+#if defined(IOS_ENABLED)
-void register_iphone_api() {
+void register_ios_api() {
godot_ios_plugins_initialize();
}
-void unregister_iphone_api() {
+void unregister_ios_api() {
godot_ios_plugins_deinitialize();
}
#else
-void register_iphone_api() {}
-void unregister_iphone_api() {}
+void register_ios_api() {}
+void unregister_ios_api() {}
#endif
diff --git a/platform/iphone/api/api.h b/platform/ios/api/api.h
index ece91a9f1a..c7fd4ce77b 100644
--- a/platform/iphone/api/api.h
+++ b/platform/ios/api/api.h
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef IPHONE_API_H
-#define IPHONE_API_H
+#ifndef IOS_API_H
+#define IOS_API_H
-#if defined(IPHONE_ENABLED)
+#if defined(IOS_ENABLED)
extern void godot_ios_plugins_initialize();
extern void godot_ios_plugins_deinitialize();
#endif
-void register_iphone_api();
-void unregister_iphone_api();
+void register_ios_api();
+void unregister_ios_api();
-#endif // IPHONE_API_H
+#endif // IOS_API_H
diff --git a/platform/iphone/app_delegate.h b/platform/ios/app_delegate.h
index 0ec1dc071b..0ec1dc071b 100644
--- a/platform/iphone/app_delegate.h
+++ b/platform/ios/app_delegate.h
diff --git a/platform/iphone/app_delegate.mm b/platform/ios/app_delegate.mm
index c5c9b5a5f9..fb183d52d4 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/ios/app_delegate.mm
@@ -34,7 +34,7 @@
#include "drivers/coreaudio/audio_driver_coreaudio.h"
#import "godot_view.h"
#include "main/main.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#import "view_controller.h"
#import <AVFoundation/AVFoundation.h>
@@ -45,8 +45,8 @@
extern int gargc;
extern char **gargv;
-extern int iphone_main(int, char **, String, String);
-extern void iphone_finish();
+extern int ios_main(int, char **, String, String);
+extern void ios_finish();
@implementation AppDelegate
@@ -71,7 +71,7 @@ static ViewController *mainViewController = nil;
paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [paths objectAtIndex:0];
- int err = iphone_main(gargc, gargv, String::utf8([documentsDirectory UTF8String]), String::utf8([cacheDirectory UTF8String]));
+ int err = ios_main(gargc, gargv, String::utf8([documentsDirectory UTF8String]), String::utf8([cacheDirectory UTF8String]));
if (err != 0) {
// bail, things did not go very well for us, should probably output a message on screen with our error code...
@@ -106,10 +106,10 @@ static ViewController *mainViewController = nil;
if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
NSLog(@"Audio interruption began");
- OSIPhone::get_singleton()->on_focus_out();
+ OS_IOS::get_singleton()->on_focus_out();
} else if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeEnded]]) {
NSLog(@"Audio interruption ended");
- OSIPhone::get_singleton()->on_focus_in();
+ OS_IOS::get_singleton()->on_focus_in();
}
}
}
@@ -121,7 +121,7 @@ static ViewController *mainViewController = nil;
}
- (void)applicationWillTerminate:(UIApplication *)application {
- iphone_finish();
+ ios_finish();
}
// When application goes to background (e.g. user switches to another app or presses Home),
@@ -135,11 +135,11 @@ static ViewController *mainViewController = nil;
// notification panel by swiping from the upper part of the screen.
- (void)applicationWillResignActive:(UIApplication *)application {
- OSIPhone::get_singleton()->on_focus_out();
+ OS_IOS::get_singleton()->on_focus_out();
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
- OSIPhone::get_singleton()->on_focus_in();
+ OS_IOS::get_singleton()->on_focus_in();
}
- (void)dealloc {
diff --git a/platform/iphone/detect.py b/platform/ios/detect.py
index 392a0151be..67c90b10a0 100644
--- a/platform/iphone/detect.py
+++ b/platform/ios/detect.py
@@ -23,11 +23,11 @@ def get_opts():
return [
(
- "IPHONEPATH",
- "Path to iPhone toolchain",
+ "IOS_TOOLCHAIN_PATH",
+ "Path to iOS toolchain",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
),
- ("IPHONESDK", "Path to the iPhone SDK", ""),
+ ("IOS_SDK_PATH", "Path to the iOS SDK", ""),
BoolVariable("ios_simulator", "Build for iOS Simulator", False),
BoolVariable("ios_exceptions", "Enable exceptions", False),
("ios_triple", "Triple for ios toolchain", ""),
@@ -75,10 +75,10 @@ def configure(env):
if "OSXCROSS_IOS" in os.environ:
env["osxcross"] = True
- env["ENV"]["PATH"] = env["IPHONEPATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]
+ env["ENV"]["PATH"] = env["IOS_TOOLCHAIN_PATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]
- compiler_path = "$IPHONEPATH/usr/bin/${ios_triple}"
- s_compiler_path = "$IPHONEPATH/Developer/usr/bin/"
+ compiler_path = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}"
+ s_compiler_path = "$IOS_TOOLCHAIN_PATH/Developer/usr/bin/"
ccache_path = os.environ.get("CCACHE")
if ccache_path is None:
@@ -97,11 +97,13 @@ def configure(env):
## Compile flags
if env["ios_simulator"]:
- detect_darwin_sdk_path("iphonesimulator", env)
+ detect_darwin_sdk_path("iossimulator", env)
+ env.Append(ASFLAGS=["-mios-simulator-version-min=13.0"])
env.Append(CCFLAGS=["-mios-simulator-version-min=13.0"])
env.extra_suffix = ".simulator" + env.extra_suffix
else:
- detect_darwin_sdk_path("iphone", env)
+ detect_darwin_sdk_path("ios", env)
+ env.Append(ASFLAGS=["-miphoneos-version-min=11.0"])
env.Append(CCFLAGS=["-miphoneos-version-min=11.0"])
if env["arch"] == "x86_64":
@@ -110,18 +112,20 @@ def configure(env):
CCFLAGS=(
"-fobjc-arc -arch x86_64"
" -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks"
- " -fasm-blocks -isysroot $IPHONESDK"
+ " -fasm-blocks -isysroot $IOS_SDK_PATH"
).split()
)
+ env.Append(ASFLAGS=["-arch", "x86_64"])
elif env["arch"] == "arm64":
env.Append(
CCFLAGS=(
"-fobjc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing"
" -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits"
" -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies"
- " -isysroot $IPHONESDK".split()
+ " -isysroot $IOS_SDK_PATH".split()
)
)
+ env.Append(ASFLAGS=["-arch", "arm64"])
env.Append(CPPDEFINES=["NEED_LONG_INT"])
# Disable exceptions on non-tools (template) builds
@@ -131,18 +135,18 @@ def configure(env):
else:
env.Append(CCFLAGS=["-fno-exceptions"])
- # Temp fix for ABS/MAX/MIN macros in iPhone SDK blocking compilation
+ # Temp fix for ABS/MAX/MIN macros in iOS SDK blocking compilation
env.Append(CCFLAGS=["-Wno-ambiguous-macro"])
env.Prepend(
CPPPATH=[
- "$IPHONESDK/usr/include",
- "$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers",
+ "$IOS_SDK_PATH/usr/include",
+ "$IOS_SDK_PATH/System/Library/Frameworks/AudioUnit.framework/Headers",
]
)
- env.Prepend(CPPPATH=["#platform/iphone"])
- env.Append(CPPDEFINES=["IPHONE_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED"])
+ env.Prepend(CPPPATH=["#platform/ios"])
+ env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED"])
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
diff --git a/platform/iphone/device_metrics.h b/platform/ios/device_metrics.h
index b9fb9b2fd9..b9fb9b2fd9 100644
--- a/platform/iphone/device_metrics.h
+++ b/platform/ios/device_metrics.h
diff --git a/platform/iphone/device_metrics.m b/platform/ios/device_metrics.m
index ec4dd8130d..ec4dd8130d 100644
--- a/platform/iphone/device_metrics.m
+++ b/platform/ios/device_metrics.m
diff --git a/platform/iphone/display_layer.h b/platform/ios/display_layer.h
index a17c75dba1..a17c75dba1 100644
--- a/platform/iphone/display_layer.h
+++ b/platform/ios/display_layer.h
diff --git a/platform/iphone/display_layer.mm b/platform/ios/display_layer.mm
index 92e81448ac..7c83494768 100644
--- a/platform/iphone/display_layer.mm
+++ b/platform/ios/display_layer.mm
@@ -32,9 +32,9 @@
#include "core/config/project_settings.h"
#include "core/os/keyboard.h"
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#include "main/main.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#include "servers/audio_server.h"
#import <AudioToolbox/AudioServices.h>
diff --git a/platform/iphone/display_server_iphone.h b/platform/ios/display_server_ios.h
index 7af222e3f8..bfd611adb7 100644
--- a/platform/iphone/display_server_iphone.h
+++ b/platform/ios/display_server_ios.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* display_server_iphone.h */
+/* display_server_ios.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef display_server_iphone_h
-#define display_server_iphone_h
+#ifndef display_server_ios_h
+#define display_server_ios_h
#include "core/input/input.h"
#include "servers/display_server.h"
@@ -38,7 +38,7 @@
#include "drivers/vulkan/rendering_device_vulkan.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
-#include "vulkan_context_iphone.h"
+#include "vulkan_context_ios.h"
#import <QuartzCore/CAMetalLayer.h>
#ifdef USE_VOLK
@@ -48,13 +48,13 @@
#endif
#endif
-class DisplayServerIPhone : public DisplayServer {
- GDCLASS(DisplayServerIPhone, DisplayServer)
+class DisplayServerIOS : public DisplayServer {
+ GDCLASS(DisplayServerIOS, DisplayServer)
_THREAD_SAFE_CLASS_
#if defined(VULKAN_ENABLED)
- VulkanContextIPhone *context_vulkan = nullptr;
+ VulkanContextIOS *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif
@@ -73,15 +73,15 @@ class DisplayServerIPhone : public DisplayServer {
void perform_event(const Ref<InputEvent> &p_event);
- DisplayServerIPhone(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
- ~DisplayServerIPhone();
+ DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ ~DisplayServerIOS();
public:
String rendering_driver;
- static DisplayServerIPhone *get_singleton();
+ static DisplayServerIOS *get_singleton();
- static void register_iphone_driver();
+ static void register_ios_driver();
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
@@ -214,4 +214,4 @@ public:
void resize_window(CGSize size);
};
-#endif /* display_server_iphone_h */
+#endif /* DISPLAY_SERVER_IOS_H */
diff --git a/platform/iphone/display_server_iphone.mm b/platform/ios/display_server_ios.mm
index 573ee9b7a8..73d4a2a427 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/ios/display_server_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* display_server_iphone.mm */
+/* display_server_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#import "app_delegate.h"
#include "core/config/project_settings.h"
@@ -37,20 +37,20 @@
#import "godot_view.h"
#include "ios.h"
#import "keyboard_input_view.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#include "tts_ios.h"
#import "view_controller.h"
#import <Foundation/Foundation.h>
#import <sys/utsname.h>
-static const float kDisplayServerIPhoneAcceleration = 1;
+static const float kDisplayServerIOSAcceleration = 1.f;
-DisplayServerIPhone *DisplayServerIPhone::get_singleton() {
- return (DisplayServerIPhone *)DisplayServer::get_singleton();
+DisplayServerIOS *DisplayServerIOS::get_singleton() {
+ return (DisplayServerIOS *)DisplayServer::get_singleton();
}
-DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver;
// Init TTS
@@ -101,7 +101,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo
rendering_device_vulkan = nullptr;
if (rendering_driver == "vulkan") {
- context_vulkan = memnew(VulkanContextIPhone);
+ context_vulkan = memnew(VulkanContextIOS);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
@@ -136,7 +136,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo
r_error = OK;
}
-DisplayServerIPhone::~DisplayServerIPhone() {
+DisplayServerIOS::~DisplayServerIOS() {
#if defined(VULKAN_ENABLED)
if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
@@ -152,11 +152,11 @@ DisplayServerIPhone::~DisplayServerIPhone() {
#endif
}
-DisplayServer *DisplayServerIPhone::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- return memnew(DisplayServerIPhone(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerIOS::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
}
-Vector<String> DisplayServerIPhone::get_rendering_drivers_func() {
+Vector<String> DisplayServerIOS::get_rendering_drivers_func() {
Vector<String> drivers;
#if defined(VULKAN_ENABLED)
@@ -169,51 +169,52 @@ Vector<String> DisplayServerIPhone::get_rendering_drivers_func() {
return drivers;
}
-void DisplayServerIPhone::register_iphone_driver() {
- register_create_function("iphone", create_func, get_rendering_drivers_func);
+void DisplayServerIOS::register_ios_driver() {
+ register_create_function("iOS", create_func, get_rendering_drivers_func);
}
// MARK: Events
-void DisplayServerIPhone::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
window_resize_callback = p_callable;
}
-void DisplayServerIPhone::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
window_event_callback = p_callable;
}
-void DisplayServerIPhone::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
input_event_callback = p_callable;
}
-void DisplayServerIPhone::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
input_text_callback = p_callable;
}
-void DisplayServerIPhone::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerIOS::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
// Probably not supported for iOS
}
-void DisplayServerIPhone::process_events() {
+void DisplayServerIOS::process_events() {
+ Input::get_singleton()->flush_buffered_events();
}
-void DisplayServerIPhone::_dispatch_input_events(const Ref<InputEvent> &p_event) {
- DisplayServerIPhone::get_singleton()->send_input_event(p_event);
+void DisplayServerIOS::_dispatch_input_events(const Ref<InputEvent> &p_event) {
+ DisplayServerIOS::get_singleton()->send_input_event(p_event);
}
-void DisplayServerIPhone::send_input_event(const Ref<InputEvent> &p_event) const {
+void DisplayServerIOS::send_input_event(const Ref<InputEvent> &p_event) const {
_window_callback(input_event_callback, p_event);
}
-void DisplayServerIPhone::send_input_text(const String &p_text) const {
+void DisplayServerIOS::send_input_text(const String &p_text) const {
_window_callback(input_text_callback, p_text);
}
-void DisplayServerIPhone::send_window_event(DisplayServer::WindowEvent p_event) const {
+void DisplayServerIOS::send_window_event(DisplayServer::WindowEvent p_event) const {
_window_callback(window_event_callback, int(p_event));
}
-void DisplayServerIPhone::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
+void DisplayServerIOS::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
if (!p_callable.is_null()) {
const Variant *argp = &p_arg;
Variant ret;
@@ -226,7 +227,7 @@ void DisplayServerIPhone::_window_callback(const Callable &p_callable, const Var
// MARK: Touches
-void DisplayServerIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click) {
+void DisplayServerIOS::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click) {
if (!GLOBAL_DEF("debug/disable_touch", false)) {
Ref<InputEventScreenTouch> ev;
ev.instantiate();
@@ -238,7 +239,7 @@ void DisplayServerIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_presse
}
}
-void DisplayServerIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) {
+void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) {
if (!GLOBAL_DEF("debug/disable_touch", false)) {
Ref<InputEventScreenDrag> ev;
ev.instantiate();
@@ -249,17 +250,17 @@ void DisplayServerIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int
}
}
-void DisplayServerIPhone::perform_event(const Ref<InputEvent> &p_event) {
+void DisplayServerIOS::perform_event(const Ref<InputEvent> &p_event) {
Input::get_singleton()->parse_input_event(p_event);
}
-void DisplayServerIPhone::touches_cancelled(int p_idx) {
+void DisplayServerIOS::touches_cancelled(int p_idx) {
touch_press(p_idx, -1, -1, false, false);
}
// MARK: Keyboard
-void DisplayServerIPhone::key(Key p_key, bool p_pressed) {
+void DisplayServerIOS::key(Key p_key, bool p_pressed) {
Ref<InputEventKey> ev;
ev.instantiate();
ev->set_echo(false);
@@ -272,31 +273,31 @@ void DisplayServerIPhone::key(Key p_key, bool p_pressed) {
// MARK: Motion
-void DisplayServerIPhone::update_gravity(float p_x, float p_y, float p_z) {
+void DisplayServerIOS::update_gravity(float p_x, float p_y, float p_z) {
Input::get_singleton()->set_gravity(Vector3(p_x, p_y, p_z));
}
-void DisplayServerIPhone::update_accelerometer(float p_x, float p_y, float p_z) {
+void DisplayServerIOS::update_accelerometer(float p_x, float p_y, float p_z) {
// Found out the Z should not be negated! Pass as is!
Vector3 v_accelerometer = Vector3(
- p_x / kDisplayServerIPhoneAcceleration,
- p_y / kDisplayServerIPhoneAcceleration,
- p_z / kDisplayServerIPhoneAcceleration);
+ p_x / kDisplayServerIOSAcceleration,
+ p_y / kDisplayServerIOSAcceleration,
+ p_z / kDisplayServerIOSAcceleration);
Input::get_singleton()->set_accelerometer(v_accelerometer);
}
-void DisplayServerIPhone::update_magnetometer(float p_x, float p_y, float p_z) {
+void DisplayServerIOS::update_magnetometer(float p_x, float p_y, float p_z) {
Input::get_singleton()->set_magnetometer(Vector3(p_x, p_y, p_z));
}
-void DisplayServerIPhone::update_gyroscope(float p_x, float p_y, float p_z) {
+void DisplayServerIOS::update_gyroscope(float p_x, float p_y, float p_z) {
Input::get_singleton()->set_gyroscope(Vector3(p_x, p_y, p_z));
}
// MARK: -
-bool DisplayServerIPhone::has_feature(Feature p_feature) const {
+bool DisplayServerIOS::has_feature(Feature p_feature) const {
switch (p_feature) {
// case FEATURE_CURSOR_SHAPE:
// case FEATURE_CUSTOM_CURSOR_SHAPE:
@@ -321,46 +322,46 @@ bool DisplayServerIPhone::has_feature(Feature p_feature) const {
}
}
-String DisplayServerIPhone::get_name() const {
- return "iPhone";
+String DisplayServerIOS::get_name() const {
+ return "iOS";
}
-bool DisplayServerIPhone::tts_is_speaking() const {
+bool DisplayServerIOS::tts_is_speaking() const {
ERR_FAIL_COND_V(!tts, false);
return [tts isSpeaking];
}
-bool DisplayServerIPhone::tts_is_paused() const {
+bool DisplayServerIOS::tts_is_paused() const {
ERR_FAIL_COND_V(!tts, false);
return [tts isPaused];
}
-Array DisplayServerIPhone::tts_get_voices() const {
+Array DisplayServerIOS::tts_get_voices() const {
ERR_FAIL_COND_V(!tts, Array());
return [tts getVoices];
}
-void DisplayServerIPhone::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
+void DisplayServerIOS::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
ERR_FAIL_COND(!tts);
[tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt];
}
-void DisplayServerIPhone::tts_pause() {
+void DisplayServerIOS::tts_pause() {
ERR_FAIL_COND(!tts);
[tts pauseSpeaking];
}
-void DisplayServerIPhone::tts_resume() {
+void DisplayServerIOS::tts_resume() {
ERR_FAIL_COND(!tts);
[tts resumeSpeaking];
}
-void DisplayServerIPhone::tts_stop() {
+void DisplayServerIOS::tts_stop() {
ERR_FAIL_COND(!tts);
[tts stopSpeaking];
}
-Rect2i DisplayServerIPhone::get_display_safe_area() const {
+Rect2i DisplayServerIOS::get_display_safe_area() const {
if (@available(iOS 11, *)) {
UIEdgeInsets insets = UIEdgeInsetsZero;
UIView *view = AppDelegate.viewController.godotView;
@@ -376,15 +377,15 @@ Rect2i DisplayServerIPhone::get_display_safe_area() const {
}
}
-int DisplayServerIPhone::get_screen_count() const {
+int DisplayServerIOS::get_screen_count() const {
return 1;
}
-Point2i DisplayServerIPhone::screen_get_position(int p_screen) const {
+Point2i DisplayServerIOS::screen_get_position(int p_screen) const {
return Size2i();
}
-Size2i DisplayServerIPhone::screen_get_size(int p_screen) const {
+Size2i DisplayServerIOS::screen_get_size(int p_screen) const {
CALayer *layer = AppDelegate.viewController.godotView.renderingLayer;
if (!layer) {
@@ -394,11 +395,11 @@ Size2i DisplayServerIPhone::screen_get_size(int p_screen) const {
return Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_scale(p_screen);
}
-Rect2i DisplayServerIPhone::screen_get_usable_rect(int p_screen) const {
+Rect2i DisplayServerIOS::screen_get_usable_rect(int p_screen) const {
return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
}
-int DisplayServerIPhone::screen_get_dpi(int p_screen) const {
+int DisplayServerIOS::screen_get_dpi(int p_screen) const {
struct utsname systemInfo;
uname(&systemInfo);
@@ -435,25 +436,25 @@ int DisplayServerIPhone::screen_get_dpi(int p_screen) const {
}
}
-float DisplayServerIPhone::screen_get_refresh_rate(int p_screen) const {
+float DisplayServerIOS::screen_get_refresh_rate(int p_screen) const {
return [UIScreen mainScreen].maximumFramesPerSecond;
}
-float DisplayServerIPhone::screen_get_scale(int p_screen) const {
+float DisplayServerIOS::screen_get_scale(int p_screen) const {
return [UIScreen mainScreen].nativeScale;
}
-Vector<DisplayServer::WindowID> DisplayServerIPhone::get_window_list() const {
+Vector<DisplayServer::WindowID> DisplayServerIOS::get_window_list() const {
Vector<DisplayServer::WindowID> list;
list.push_back(MAIN_WINDOW_ID);
return list;
}
-DisplayServer::WindowID DisplayServerIPhone::get_window_at_screen_position(const Point2i &p_position) const {
+DisplayServer::WindowID DisplayServerIOS::get_window_at_screen_position(const Point2i &p_position) const {
return MAIN_WINDOW_ID;
}
-int64_t DisplayServerIPhone::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+int64_t DisplayServerIOS::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: {
@@ -471,120 +472,120 @@ int64_t DisplayServerIPhone::window_get_native_handle(HandleType p_handle_type,
}
}
-void DisplayServerIPhone::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
+void DisplayServerIOS::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
window_attached_instance_id = p_instance;
}
-ObjectID DisplayServerIPhone::window_get_attached_instance_id(WindowID p_window) const {
+ObjectID DisplayServerIOS::window_get_attached_instance_id(WindowID p_window) const {
return window_attached_instance_id;
}
-void DisplayServerIPhone::window_set_title(const String &p_title, WindowID p_window) {
+void DisplayServerIOS::window_set_title(const String &p_title, WindowID p_window) {
// Probably not supported for iOS
}
-int DisplayServerIPhone::window_get_current_screen(WindowID p_window) const {
+int DisplayServerIOS::window_get_current_screen(WindowID p_window) const {
return SCREEN_OF_MAIN_WINDOW;
}
-void DisplayServerIPhone::window_set_current_screen(int p_screen, WindowID p_window) {
+void DisplayServerIOS::window_set_current_screen(int p_screen, WindowID p_window) {
// Probably not supported for iOS
}
-Point2i DisplayServerIPhone::window_get_position(WindowID p_window) const {
+Point2i DisplayServerIOS::window_get_position(WindowID p_window) const {
return Point2i();
}
-void DisplayServerIPhone::window_set_position(const Point2i &p_position, WindowID p_window) {
+void DisplayServerIOS::window_set_position(const Point2i &p_position, WindowID p_window) {
// Probably not supported for single window iOS app
}
-void DisplayServerIPhone::window_set_transient(WindowID p_window, WindowID p_parent) {
+void DisplayServerIOS::window_set_transient(WindowID p_window, WindowID p_parent) {
// Probably not supported for iOS
}
-void DisplayServerIPhone::window_set_max_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerIOS::window_set_max_size(const Size2i p_size, WindowID p_window) {
// Probably not supported for iOS
}
-Size2i DisplayServerIPhone::window_get_max_size(WindowID p_window) const {
+Size2i DisplayServerIOS::window_get_max_size(WindowID p_window) const {
return Size2i();
}
-void DisplayServerIPhone::window_set_min_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerIOS::window_set_min_size(const Size2i p_size, WindowID p_window) {
// Probably not supported for iOS
}
-Size2i DisplayServerIPhone::window_get_min_size(WindowID p_window) const {
+Size2i DisplayServerIOS::window_get_min_size(WindowID p_window) const {
return Size2i();
}
-void DisplayServerIPhone::window_set_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerIOS::window_set_size(const Size2i p_size, WindowID p_window) {
// Probably not supported for iOS
}
-Size2i DisplayServerIPhone::window_get_size(WindowID p_window) const {
+Size2i DisplayServerIOS::window_get_size(WindowID p_window) const {
CGRect screenBounds = [UIScreen mainScreen].bounds;
return Size2i(screenBounds.size.width, screenBounds.size.height) * screen_get_max_scale();
}
-Size2i DisplayServerIPhone::window_get_real_size(WindowID p_window) const {
+Size2i DisplayServerIOS::window_get_real_size(WindowID p_window) const {
return window_get_size(p_window);
}
-void DisplayServerIPhone::window_set_mode(WindowMode p_mode, WindowID p_window) {
+void DisplayServerIOS::window_set_mode(WindowMode p_mode, WindowID p_window) {
// Probably not supported for iOS
}
-DisplayServer::WindowMode DisplayServerIPhone::window_get_mode(WindowID p_window) const {
+DisplayServer::WindowMode DisplayServerIOS::window_get_mode(WindowID p_window) const {
return WindowMode::WINDOW_MODE_FULLSCREEN;
}
-bool DisplayServerIPhone::window_is_maximize_allowed(WindowID p_window) const {
+bool DisplayServerIOS::window_is_maximize_allowed(WindowID p_window) const {
return false;
}
-void DisplayServerIPhone::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
+void DisplayServerIOS::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
// Probably not supported for iOS
}
-bool DisplayServerIPhone::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
+bool DisplayServerIOS::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
return false;
}
-void DisplayServerIPhone::window_request_attention(WindowID p_window) {
+void DisplayServerIOS::window_request_attention(WindowID p_window) {
// Probably not supported for iOS
}
-void DisplayServerIPhone::window_move_to_foreground(WindowID p_window) {
+void DisplayServerIOS::window_move_to_foreground(WindowID p_window) {
// Probably not supported for iOS
}
-float DisplayServerIPhone::screen_get_max_scale() const {
+float DisplayServerIOS::screen_get_max_scale() const {
return screen_get_scale(SCREEN_OF_MAIN_WINDOW);
}
-void DisplayServerIPhone::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) {
+void DisplayServerIOS::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) {
screen_orientation = p_orientation;
}
-DisplayServer::ScreenOrientation DisplayServerIPhone::screen_get_orientation(int p_screen) const {
+DisplayServer::ScreenOrientation DisplayServerIOS::screen_get_orientation(int p_screen) const {
return screen_orientation;
}
-bool DisplayServerIPhone::window_can_draw(WindowID p_window) const {
+bool DisplayServerIOS::window_can_draw(WindowID p_window) const {
return true;
}
-bool DisplayServerIPhone::can_any_window_draw() const {
+bool DisplayServerIOS::can_any_window_draw() const {
return true;
}
-bool DisplayServerIPhone::screen_is_touchscreen(int p_screen) const {
+bool DisplayServerIOS::screen_is_touchscreen(int p_screen) const {
return true;
}
-void DisplayServerIPhone::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) {
+void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) {
NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()];
[AppDelegate.viewController.keyboardView
@@ -594,37 +595,37 @@ void DisplayServerIPhone::virtual_keyboard_show(const String &p_existing_text, c
cursorEnd:p_cursor_end];
}
-void DisplayServerIPhone::virtual_keyboard_hide() {
+void DisplayServerIOS::virtual_keyboard_hide() {
[AppDelegate.viewController.keyboardView resignFirstResponder];
}
-void DisplayServerIPhone::virtual_keyboard_set_height(int height) {
+void DisplayServerIOS::virtual_keyboard_set_height(int height) {
virtual_keyboard_height = height * screen_get_max_scale();
}
-int DisplayServerIPhone::virtual_keyboard_get_height() const {
+int DisplayServerIOS::virtual_keyboard_get_height() const {
return virtual_keyboard_height;
}
-void DisplayServerIPhone::clipboard_set(const String &p_text) {
+void DisplayServerIOS::clipboard_set(const String &p_text) {
[UIPasteboard generalPasteboard].string = [NSString stringWithUTF8String:p_text.utf8()];
}
-String DisplayServerIPhone::clipboard_get() const {
+String DisplayServerIOS::clipboard_get() const {
NSString *text = [UIPasteboard generalPasteboard].string;
return String::utf8([text UTF8String]);
}
-void DisplayServerIPhone::screen_set_keep_on(bool p_enable) {
+void DisplayServerIOS::screen_set_keep_on(bool p_enable) {
[UIApplication sharedApplication].idleTimerDisabled = p_enable;
}
-bool DisplayServerIPhone::screen_is_kept_on() const {
+bool DisplayServerIOS::screen_is_kept_on() const {
return [UIApplication sharedApplication].idleTimerDisabled;
}
-void DisplayServerIPhone::resize_window(CGSize viewSize) {
+void DisplayServerIOS::resize_window(CGSize viewSize) {
Size2i size = Size2i(viewSize.width, viewSize.height) * screen_get_max_scale();
#if defined(VULKAN_ENABLED)
@@ -637,14 +638,14 @@ void DisplayServerIPhone::resize_window(CGSize viewSize) {
_window_callback(window_resize_callback, resize_rect);
}
-void DisplayServerIPhone::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+void DisplayServerIOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
#endif
}
-DisplayServer::VSyncMode DisplayServerIPhone::window_get_vsync_mode(WindowID p_window) const {
+DisplayServer::VSyncMode DisplayServerIOS::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
return context_vulkan->get_vsync_mode(p_window);
diff --git a/platform/iphone/export/export.cpp b/platform/ios/export/export.cpp
index 3b02e661c1..1531c2bde5 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/ios/export/export.cpp
@@ -32,7 +32,7 @@
#include "export_plugin.h"
-void register_iphone_exporter() {
+void register_ios_exporter() {
Ref<EditorExportPlatformIOS> platform;
platform.instantiate();
diff --git a/platform/osx/export/export.h b/platform/ios/export/export.h
index b386337a09..756a1356ea 100644
--- a/platform/osx/export/export.h
+++ b/platform/ios/export/export.h
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef OSX_EXPORT_H
-#define OSX_EXPORT_H
+#ifndef IOS_EXPORT_H
+#define IOS_EXPORT_H
-void register_osx_exporter();
+void register_ios_exporter();
-#endif // OSX_EXPORT_H
+#endif // IOS_EXPORT_H
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp
index 4cf1c279eb..a2e80d33fd 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/ios/export/export_plugin.cpp
@@ -418,7 +418,7 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
}
// !BAS! I'm assuming the 9 in the original code was a typo. I've added -1 or else it seems to also be adding our terminating zero...
- // should apply the same fix in our OSX export.
+ // should apply the same fix in our macOS export.
CharString cs = strnew.utf8();
pfile.resize(cs.size() - 1);
for (int i = 0; i < cs.size() - 1; i++) {
@@ -1394,7 +1394,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
if (src_pkg_name.is_empty()) {
String err;
- src_pkg_name = find_export_template("iphone.zip", &err);
+ src_pkg_name = find_export_template("ios.zip", &err);
if (src_pkg_name.is_empty()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found."));
return ERR_FILE_NOT_FOUND;
@@ -1444,7 +1444,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
return ERR_SKIP;
}
- String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".xcframework";
+ String library_to_use = "libgodot.ios." + String(p_debug ? "debug" : "release") + ".xcframework";
print_line("Static framework: " + library_to_use);
String pkg_name;
@@ -1502,7 +1502,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
int ret = unzGoToFirstFile(src_pkg_zip);
Vector<uint8_t> project_file_data;
while (ret == UNZ_OK) {
-#if defined(OSX_ENABLED) || defined(X11_ENABLED)
+#if defined(MACOS_ENABLED) || defined(X11_ENABLED)
bool is_execute = false;
#endif
@@ -1527,17 +1527,17 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
//write
- file = file.replace_first("iphone/", "");
+ file = file.replace_first("ios/", "");
if (files_to_parse.has(file)) {
_fix_config_file(p_preset, data, config_data, p_debug);
- } else if (file.begins_with("libgodot.iphone")) {
+ } else if (file.begins_with("libgodot.ios")) {
if (!file.begins_with(library_to_use) || file.ends_with(String("/empty"))) {
ret = unzGoToNextFile(src_pkg_zip);
continue; //ignore!
}
found_library = true;
-#if defined(OSX_ENABLED) || defined(X11_ENABLED)
+#if defined(MACOS_ENABLED) || defined(X11_ENABLED)
is_execute = true;
#endif
file = file.replace(library_to_use, binary_name + ".xcframework");
@@ -1580,7 +1580,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
f->store_buffer(data.ptr(), data.size());
}
-#if defined(OSX_ENABLED) || defined(X11_ENABLED)
+#if defined(MACOS_ENABLED) || defined(X11_ENABLED)
if (is_execute) {
// we need execute rights on this file
chmod(file.utf8().get_data(), 0755);
@@ -1725,7 +1725,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
f->store_buffer(project_file_data.ptr(), project_file_data.size());
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
{
if (ep.step("Code-signing dylibs", 2)) {
return ERR_SKIP;
@@ -1790,7 +1790,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
// Look for export templates (first official, and if defined custom templates).
- bool dvalid = exists_export_template("iphone.zip", &err);
+ bool dvalid = exists_export_template("ios.zip", &err);
bool rvalid = dvalid; // Both in the same ZIP.
if (p_preset->get("custom_template/debug") != "") {
@@ -1838,12 +1838,8 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
}
EditorExportPlatformIOS::EditorExportPlatformIOS() {
- Ref<Image> img = memnew(Image(_iphone_logo));
- logo.instantiate();
- logo->create_from_image(img);
-
+ logo = ImageTexture::create_from_image(memnew(Image(_ios_logo)));
plugins_changed.set();
-
check_for_changes_thread.start(_check_for_changes_poll_thread, this);
}
diff --git a/platform/iphone/export/export_plugin.h b/platform/ios/export/export_plugin.h
index 1db7418e3f..a30cb4644f 100644
--- a/platform/iphone/export/export_plugin.h
+++ b/platform/ios/export/export_plugin.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef IPHONE_EXPORT_PLUGIN_H
-#define IPHONE_EXPORT_PLUGIN_H
+#ifndef IOS_EXPORT_PLUGIN_H
+#define IOS_EXPORT_PLUGIN_H
#include "core/config/project_settings.h"
#include "core/io/file_access.h"
@@ -43,7 +43,7 @@
#include "editor/editor_export.h"
#include "editor/editor_settings.h"
#include "main/splash.gen.h"
-#include "platform/iphone/logo.gen.h"
+#include "platform/ios/logo.gen.h"
#include "string.h"
#include "godot_plugin_config.h"
diff --git a/platform/iphone/export/godot_plugin_config.cpp b/platform/ios/export/godot_plugin_config.cpp
index 9118b95337..9118b95337 100644
--- a/platform/iphone/export/godot_plugin_config.cpp
+++ b/platform/ios/export/godot_plugin_config.cpp
diff --git a/platform/iphone/export/godot_plugin_config.h b/platform/ios/export/godot_plugin_config.h
index 9ef8aa8c6d..d2a2de4947 100644
--- a/platform/iphone/export/godot_plugin_config.h
+++ b/platform/ios/export/godot_plugin_config.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef IPHONE_GODOT_PLUGIN_CONFIG_H
-#define IPHONE_GODOT_PLUGIN_CONFIG_H
+#ifndef IOS_GODOT_PLUGIN_CONFIG_H
+#define IOS_GODOT_PLUGIN_CONFIG_H
#include "core/error/error_list.h"
#include "core/io/config_file.h"
diff --git a/platform/iphone/godot_app_delegate.h b/platform/ios/godot_app_delegate.h
index 703a906bda..703a906bda 100644
--- a/platform/iphone/godot_app_delegate.h
+++ b/platform/ios/godot_app_delegate.h
diff --git a/platform/iphone/godot_app_delegate.m b/platform/ios/godot_app_delegate.m
index 84347f9a30..84347f9a30 100644
--- a/platform/iphone/godot_app_delegate.m
+++ b/platform/ios/godot_app_delegate.m
diff --git a/platform/iphone/godot_iphone.mm b/platform/ios/godot_ios.mm
index 49474ef554..5f3e786b8a 100644
--- a/platform/iphone/godot_iphone.mm
+++ b/platform/ios/godot_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_iphone.mm */
+/* godot_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,17 +30,17 @@
#include "core/string/ustring.h"
#include "main/main.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-static OSIPhone *os = nullptr;
+static OS_IOS *os = nullptr;
int add_path(int, char **);
int add_cmdline(int, char **);
-int iphone_main(int, char **, String);
+int ios_main(int, char **, String);
int add_path(int p_argc, char **p_args) {
NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"];
@@ -74,7 +74,7 @@ int add_cmdline(int p_argc, char **p_args) {
return p_argc;
}
-int iphone_main(int argc, char **argv, String data_dir, String cache_dir) {
+int ios_main(int argc, char **argv, String data_dir, String cache_dir) {
size_t len = strlen(argv[0]);
while (len--) {
@@ -91,11 +91,11 @@ int iphone_main(int argc, char **argv, String data_dir, String cache_dir) {
chdir(path);
}
- printf("godot_iphone %s\n", argv[0]);
+ printf("godot_ios %s\n", argv[0]);
char cwd[512];
getcwd(cwd, sizeof(cwd));
printf("cwd %s\n", cwd);
- os = new OSIPhone(data_dir, cache_dir);
+ os = new OS_IOS(data_dir, cache_dir);
// We must override main when testing is enabled
TEST_MAIN_OVERRIDE
@@ -112,7 +112,10 @@ int iphone_main(int argc, char **argv, String data_dir, String cache_dir) {
Error err = Main::setup(fargv[0], argc - 1, &fargv[1], false);
printf("setup %i\n", err);
- if (err != OK) {
+
+ if (err == ERR_HELP) { // Returned by --help and --version, so success.
+ return 0;
+ } else if (err != OK) {
return 255;
}
@@ -121,8 +124,8 @@ int iphone_main(int argc, char **argv, String data_dir, String cache_dir) {
return 0;
}
-void iphone_finish() {
- printf("iphone_finish\n");
+void ios_finish() {
+ printf("ios_finish\n");
Main::cleanup();
delete os;
}
diff --git a/platform/iphone/godot_view.h b/platform/ios/godot_view.h
index fcb97fa63a..fcb97fa63a 100644
--- a/platform/iphone/godot_view.h
+++ b/platform/ios/godot_view.h
diff --git a/platform/iphone/godot_view.mm b/platform/ios/godot_view.mm
index e48dd2e507..9ed219508c 100644
--- a/platform/iphone/godot_view.mm
+++ b/platform/ios/godot_view.mm
@@ -33,7 +33,7 @@
#include "core/os/keyboard.h"
#include "core/string/ustring.h"
#import "display_layer.h"
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#import "godot_view_gesture_recognizer.h"
#import "godot_view_renderer.h"
@@ -281,8 +281,8 @@ static const float earth_gravity = 9.80665;
self.renderingLayer.frame = self.bounds;
[self.renderingLayer layoutDisplayLayer];
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->resize_window(self.bounds.size);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->resize_window(self.bounds.size);
}
}
@@ -348,7 +348,7 @@ static const float earth_gravity = 9.80665;
int tid = [self getTouchIDForTouch:touch];
ERR_FAIL_COND(tid == -1);
CGPoint touchPoint = [touch locationInView:self];
- DisplayServerIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1);
+ DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1);
}
}
}
@@ -362,7 +362,7 @@ static const float earth_gravity = 9.80665;
ERR_FAIL_COND(tid == -1);
CGPoint touchPoint = [touch locationInView:self];
CGPoint prev_point = [touch previousLocationInView:self];
- DisplayServerIPhone::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor);
+ DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor);
}
}
}
@@ -376,7 +376,7 @@ static const float earth_gravity = 9.80665;
ERR_FAIL_COND(tid == -1);
[self removeTouch:touch];
CGPoint touchPoint = [touch locationInView:self];
- DisplayServerIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false);
+ DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false);
}
}
}
@@ -388,7 +388,7 @@ static const float earth_gravity = 9.80665;
UITouch *touch = [tlist objectAtIndex:i];
int tid = [self getTouchIDForTouch:touch];
ERR_FAIL_COND(tid == -1);
- DisplayServerIPhone::get_singleton()->touches_cancelled(tid);
+ DisplayServerIOS::get_singleton()->touches_cancelled(tid);
}
}
[self clearTouches];
@@ -452,28 +452,28 @@ static const float earth_gravity = 9.80665;
switch (interfaceOrientation) {
case UIInterfaceOrientationLandscapeLeft: {
- DisplayServerIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z);
- DisplayServerIPhone::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z);
- DisplayServerIPhone::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z);
- DisplayServerIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z);
+ DisplayServerIOS::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z);
+ DisplayServerIOS::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z);
+ DisplayServerIOS::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z);
+ DisplayServerIOS::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z);
} break;
case UIInterfaceOrientationLandscapeRight: {
- DisplayServerIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z);
- DisplayServerIPhone::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z);
- DisplayServerIPhone::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z);
- DisplayServerIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z);
+ DisplayServerIOS::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z);
+ DisplayServerIOS::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z);
+ DisplayServerIOS::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z);
+ DisplayServerIOS::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z);
} break;
case UIInterfaceOrientationPortraitUpsideDown: {
- DisplayServerIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z);
- DisplayServerIPhone::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z);
- DisplayServerIPhone::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z);
- DisplayServerIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z);
+ DisplayServerIOS::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z);
+ DisplayServerIOS::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z);
+ DisplayServerIOS::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z);
+ DisplayServerIOS::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z);
} break;
default: { // assume portrait
- DisplayServerIPhone::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z);
- DisplayServerIPhone::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z);
- DisplayServerIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z);
- DisplayServerIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z);
+ DisplayServerIOS::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z);
+ DisplayServerIOS::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z);
+ DisplayServerIOS::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z);
+ DisplayServerIOS::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z);
} break;
}
}
diff --git a/platform/iphone/godot_view_gesture_recognizer.h b/platform/ios/godot_view_gesture_recognizer.h
index 9fd8a6b222..9fd8a6b222 100644
--- a/platform/iphone/godot_view_gesture_recognizer.h
+++ b/platform/ios/godot_view_gesture_recognizer.h
diff --git a/platform/iphone/godot_view_gesture_recognizer.mm b/platform/ios/godot_view_gesture_recognizer.mm
index 49a92add5e..49a92add5e 100644
--- a/platform/iphone/godot_view_gesture_recognizer.mm
+++ b/platform/ios/godot_view_gesture_recognizer.mm
diff --git a/platform/iphone/godot_view_renderer.h b/platform/ios/godot_view_renderer.h
index b3ee23ae4f..b3ee23ae4f 100644
--- a/platform/iphone/godot_view_renderer.h
+++ b/platform/ios/godot_view_renderer.h
diff --git a/platform/iphone/godot_view_renderer.mm b/platform/ios/godot_view_renderer.mm
index 32477ae41c..140410fbef 100644
--- a/platform/iphone/godot_view_renderer.mm
+++ b/platform/ios/godot_view_renderer.mm
@@ -32,9 +32,9 @@
#include "core/config/project_settings.h"
#include "core/os/keyboard.h"
-#import "display_server_iphone.h"
+#import "display_server_ios.h"
#include "main/main.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#include "servers/audio_server.h"
#import <AudioToolbox/AudioServices.h>
@@ -69,7 +69,7 @@
if (!self.hasStartedMain) {
self.hasStartedMain = YES;
- OSIPhone::get_singleton()->start();
+ OS_IOS::get_singleton()->start();
return YES;
}
@@ -108,11 +108,11 @@
}
- (void)renderOnView:(UIView *)view {
- if (!OSIPhone::get_singleton()) {
+ if (!OS_IOS::get_singleton()) {
return;
}
- OSIPhone::get_singleton()->iterate();
+ OS_IOS::get_singleton()->iterate();
}
@end
diff --git a/platform/iphone/ios.h b/platform/ios/ios.h
index 0607d7b395..0607d7b395 100644
--- a/platform/iphone/ios.h
+++ b/platform/ios/ios.h
diff --git a/platform/iphone/ios.mm b/platform/ios/ios.mm
index 79baae028a..79baae028a 100644
--- a/platform/iphone/ios.mm
+++ b/platform/ios/ios.mm
diff --git a/platform/iphone/joypad_iphone.h b/platform/ios/joypad_ios.h
index 37e272a2c9..66c4b090bc 100644
--- a/platform/iphone/joypad_iphone.h
+++ b/platform/ios/joypad_ios.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad_iphone.h */
+/* joypad_ios.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,7 +30,7 @@
#import <GameController/GameController.h>
-@interface JoypadIPhoneObserver : NSObject
+@interface JoypadIOSObserver : NSObject
- (void)startObserving;
- (void)startProcessing;
@@ -38,13 +38,13 @@
@end
-class JoypadIPhone {
+class JoypadIOS {
private:
- JoypadIPhoneObserver *observer;
+ JoypadIOSObserver *observer;
public:
- JoypadIPhone();
- ~JoypadIPhone();
+ JoypadIOS();
+ ~JoypadIOS();
void start_processing();
};
diff --git a/platform/iphone/joypad_iphone.mm b/platform/ios/joypad_ios.mm
index 9c2feeaaca..e147cb2527 100644
--- a/platform/iphone/joypad_iphone.mm
+++ b/platform/ios/joypad_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad_iphone.mm */
+/* joypad_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#import "joypad_iphone.h"
+#import "joypad_ios.h"
#include "core/config/project_settings.h"
#include "drivers/coreaudio/audio_driver_coreaudio.h"
@@ -36,27 +36,27 @@
#import "godot_view.h"
-#include "os_iphone.h"
+#include "os_ios.h"
-JoypadIPhone::JoypadIPhone() {
- observer = [[JoypadIPhoneObserver alloc] init];
+JoypadIOS::JoypadIOS() {
+ observer = [[JoypadIOSObserver alloc] init];
[observer startObserving];
}
-JoypadIPhone::~JoypadIPhone() {
+JoypadIOS::~JoypadIOS() {
if (observer) {
[observer finishObserving];
observer = nil;
}
}
-void JoypadIPhone::start_processing() {
+void JoypadIOS::start_processing() {
if (observer) {
[observer startProcessing];
}
}
-@interface JoypadIPhoneObserver ()
+@interface JoypadIOSObserver ()
@property(assign, nonatomic) BOOL isObserving;
@property(assign, nonatomic) BOOL isProcessing;
@@ -65,7 +65,7 @@ void JoypadIPhone::start_processing() {
@end
-@implementation JoypadIPhoneObserver
+@implementation JoypadIOSObserver
- (instancetype)init {
self = [super init];
diff --git a/platform/iphone/keyboard_input_view.h b/platform/ios/keyboard_input_view.h
index 33fa5d571a..33fa5d571a 100644
--- a/platform/iphone/keyboard_input_view.h
+++ b/platform/ios/keyboard_input_view.h
diff --git a/platform/iphone/keyboard_input_view.mm b/platform/ios/keyboard_input_view.mm
index f2a7b22483..76e3f23c9d 100644
--- a/platform/iphone/keyboard_input_view.mm
+++ b/platform/ios/keyboard_input_view.mm
@@ -31,8 +31,8 @@
#import "keyboard_input_view.h"
#include "core/os/keyboard.h"
-#include "display_server_iphone.h"
-#include "os_iphone.h"
+#include "display_server_ios.h"
+#include "os_ios.h"
@interface GodotKeyboardInputView () <UITextViewDelegate>
@@ -115,8 +115,8 @@
- (void)deleteText:(NSInteger)charactersToDelete {
for (int i = 0; i < charactersToDelete; i++) {
- DisplayServerIPhone::get_singleton()->key(Key::BACKSPACE, true);
- DisplayServerIPhone::get_singleton()->key(Key::BACKSPACE, false);
+ DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, true);
+ DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, false);
}
}
@@ -138,8 +138,8 @@
break;
}
- DisplayServerIPhone::get_singleton()->key((Key)character, true);
- DisplayServerIPhone::get_singleton()->key((Key)character, false);
+ DisplayServerIOS::get_singleton()->key((Key)character, true);
+ DisplayServerIOS::get_singleton()->key((Key)character, false);
}
}
diff --git a/platform/iphone/logo.png b/platform/ios/logo.png
index 966d8aa70a..966d8aa70a 100644
--- a/platform/iphone/logo.png
+++ b/platform/ios/logo.png
Binary files differ
diff --git a/platform/iphone/main.m b/platform/ios/main.m
index acfa7ab731..acfa7ab731 100644
--- a/platform/iphone/main.m
+++ b/platform/ios/main.m
diff --git a/platform/iphone/os_iphone.h b/platform/ios/os_ios.h
index d03403bbb4..bbc77d48de 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/ios/os_ios.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* os_iphone.h */
+/* os_ios.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,24 +28,24 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef IPHONE_ENABLED
+#ifdef IOS_ENABLED
-#ifndef OS_IPHONE_H
-#define OS_IPHONE_H
+#ifndef OS_IOS_H
+#define OS_IOS_H
#include "drivers/coreaudio/audio_driver_coreaudio.h"
#include "drivers/unix/os_unix.h"
#include "ios.h"
-#include "joypad_iphone.h"
+#include "joypad_ios.h"
#include "servers/audio_server.h"
#include "servers/rendering/renderer_compositor.h"
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
-#include "platform/iphone/vulkan_context_iphone.h"
+#include "platform/ios/vulkan_context_ios.h"
#endif
-class OSIPhone : public OS_Unix {
+class OS_IOS : public OS_Unix {
private:
static HashMap<String, void *> dynamic_symbol_lookup_table;
friend void register_dynamic_symbol(char *name, void *address);
@@ -54,7 +54,7 @@ private:
iOS *ios = nullptr;
- JoypadIPhone *joypad_iphone = nullptr;
+ JoypadIOS *joypad_ios = nullptr;
MainLoop *main_loop = nullptr;
@@ -79,10 +79,10 @@ private:
void deinitialize_modules();
public:
- static OSIPhone *get_singleton();
+ static OS_IOS *get_singleton();
- OSIPhone(String p_data_dir, String p_cache_dir);
- ~OSIPhone();
+ OS_IOS(String p_data_dir, String p_cache_dir);
+ ~OS_IOS();
void initialize_modules();
@@ -119,6 +119,6 @@ public:
void on_focus_in();
};
-#endif // OS_IPHONE_H
+#endif // OS_IOS_H
-#endif // IPHONE_ENABLED
+#endif // IOS_ENABLED
diff --git a/platform/iphone/os_iphone.mm b/platform/ios/os_ios.mm
index 95b06b728e..880315209e 100644
--- a/platform/iphone/os_iphone.mm
+++ b/platform/ios/os_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* os_iphone.mm */
+/* os_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,16 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef IPHONE_ENABLED
+#ifdef IOS_ENABLED
-#include "os_iphone.h"
+#include "os_ios.h"
#import "app_delegate.h"
#include "core/config/project_settings.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/file_access_pack.h"
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#include "drivers/unix/syslog_logger.h"
#import "godot_view.h"
#include "main/main.h"
@@ -65,7 +65,7 @@ typedef void (*init_callback)();
static init_callback *ios_init_callbacks = nullptr;
static int ios_init_callbacks_count = 0;
static int ios_init_callbacks_capacity = 0;
-HashMap<String, void *> OSIPhone::dynamic_symbol_lookup_table;
+HashMap<String, void *> OS_IOS::dynamic_symbol_lookup_table;
void add_ios_init_callback(init_callback cb) {
if (ios_init_callbacks_count == ios_init_callbacks_capacity) {
@@ -82,14 +82,14 @@ void add_ios_init_callback(init_callback cb) {
}
void register_dynamic_symbol(char *name, void *address) {
- OSIPhone::dynamic_symbol_lookup_table[String(name)] = address;
+ OS_IOS::dynamic_symbol_lookup_table[String(name)] = address;
}
-OSIPhone *OSIPhone::get_singleton() {
- return (OSIPhone *)OS::get_singleton();
+OS_IOS *OS_IOS::get_singleton() {
+ return (OS_IOS *)OS::get_singleton();
}
-OSIPhone::OSIPhone(String p_data_dir, String p_cache_dir) {
+OS_IOS::OS_IOS(String p_data_dir, String p_cache_dir) {
for (int i = 0; i < ios_init_callbacks_count; ++i) {
ios_init_callbacks[i]();
}
@@ -116,37 +116,37 @@ OSIPhone::OSIPhone(String p_data_dir, String p_cache_dir) {
AudioDriverManager::add_driver(&audio_driver);
- DisplayServerIPhone::register_iphone_driver();
+ DisplayServerIOS::register_ios_driver();
}
-OSIPhone::~OSIPhone() {}
+OS_IOS::~OS_IOS() {}
-void OSIPhone::alert(const String &p_alert, const String &p_title) {
+void OS_IOS::alert(const String &p_alert, const String &p_title) {
const CharString utf8_alert = p_alert.utf8();
const CharString utf8_title = p_title.utf8();
iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
}
-void OSIPhone::initialize_core() {
+void OS_IOS::initialize_core() {
OS_Unix::initialize_core();
set_user_data_dir(user_data_dir);
}
-void OSIPhone::initialize() {
+void OS_IOS::initialize() {
initialize_core();
}
-void OSIPhone::initialize_modules() {
+void OS_IOS::initialize_modules() {
ios = memnew(iOS);
Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", ios));
- joypad_iphone = memnew(JoypadIPhone);
+ joypad_ios = memnew(JoypadIOS);
}
-void OSIPhone::deinitialize_modules() {
- if (joypad_iphone) {
- memdelete(joypad_iphone);
+void OS_IOS::deinitialize_modules() {
+ if (joypad_ios) {
+ memdelete(joypad_ios);
}
if (ios) {
@@ -154,7 +154,7 @@ void OSIPhone::deinitialize_modules() {
}
}
-void OSIPhone::set_main_loop(MainLoop *p_main_loop) {
+void OS_IOS::set_main_loop(MainLoop *p_main_loop) {
main_loop = p_main_loop;
if (main_loop) {
@@ -162,11 +162,11 @@ void OSIPhone::set_main_loop(MainLoop *p_main_loop) {
}
}
-MainLoop *OSIPhone::get_main_loop() const {
+MainLoop *OS_IOS::get_main_loop() const {
return main_loop;
}
-void OSIPhone::delete_main_loop() {
+void OS_IOS::delete_main_loop() {
if (main_loop) {
main_loop->finalize();
memdelete(main_loop);
@@ -175,7 +175,7 @@ void OSIPhone::delete_main_loop() {
main_loop = nullptr;
}
-bool OSIPhone::iterate() {
+bool OS_IOS::iterate() {
if (!main_loop) {
return true;
}
@@ -187,15 +187,15 @@ bool OSIPhone::iterate() {
return Main::iteration();
}
-void OSIPhone::start() {
+void OS_IOS::start() {
Main::start();
- if (joypad_iphone) {
- joypad_iphone->start_processing();
+ if (joypad_ios) {
+ joypad_ios->start_processing();
}
}
-void OSIPhone::finalize() {
+void OS_IOS::finalize() {
deinitialize_modules();
// Already gets called
@@ -204,7 +204,7 @@ void OSIPhone::finalize() {
// MARK: Dynamic Libraries
-Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
+Error OS_IOS::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
if (p_path.length() == 0) {
p_library_handle = RTLD_SELF;
@@ -217,16 +217,16 @@ Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handl
return OS_Unix::open_dynamic_library(p_path, p_library_handle, p_also_set_library_path, r_resolved_path);
}
-Error OSIPhone::close_dynamic_library(void *p_library_handle) {
+Error OS_IOS::close_dynamic_library(void *p_library_handle) {
if (p_library_handle == RTLD_SELF) {
return OK;
}
return OS_Unix::close_dynamic_library(p_library_handle);
}
-Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
+Error OS_IOS::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
if (p_library_handle == RTLD_SELF) {
- void **ptr = OSIPhone::dynamic_symbol_lookup_table.getptr(p_name);
+ void **ptr = OS_IOS::dynamic_symbol_lookup_table.getptr(p_name);
if (ptr) {
p_symbol_handle = *ptr;
return OK;
@@ -235,11 +235,11 @@ Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const
return OS_Unix::get_dynamic_library_symbol_handle(p_library_handle, p_name, p_symbol_handle, p_optional);
}
-String OSIPhone::get_name() const {
+String OS_IOS::get_name() const {
return "iOS";
}
-String OSIPhone::get_model_name() const {
+String OS_IOS::get_model_name() const {
String model = ios->get_model();
if (model != "") {
return model;
@@ -248,7 +248,7 @@ String OSIPhone::get_model_name() const {
return OS_Unix::get_model_name();
}
-Error OSIPhone::shell_open(String p_uri) {
+Error OS_IOS::shell_open(String p_uri) {
NSString *urlPath = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()];
NSURL *url = [NSURL URLWithString:urlPath];
@@ -263,21 +263,21 @@ Error OSIPhone::shell_open(String p_uri) {
return OK;
}
-void OSIPhone::set_user_data_dir(String p_dir) {
+void OS_IOS::set_user_data_dir(String p_dir) {
Ref<DirAccess> da = DirAccess::open(p_dir);
user_data_dir = da->get_current_dir();
printf("setting data dir to %s from %s\n", user_data_dir.utf8().get_data(), p_dir.utf8().get_data());
}
-String OSIPhone::get_user_data_dir() const {
+String OS_IOS::get_user_data_dir() const {
return user_data_dir;
}
-String OSIPhone::get_cache_path() const {
+String OS_IOS::get_cache_path() const {
return cache_dir;
}
-String OSIPhone::get_locale() const {
+String OS_IOS::get_locale() const {
NSString *preferedLanguage = [NSLocale preferredLanguages].firstObject;
if (preferedLanguage) {
@@ -288,12 +288,12 @@ String OSIPhone::get_locale() const {
return String::utf8([localeIdentifier UTF8String]).replace("-", "_");
}
-String OSIPhone::get_unique_id() const {
+String OS_IOS::get_unique_id() const {
NSString *uuid = [UIDevice currentDevice].identifierForVendor.UUIDString;
return String::utf8([uuid UTF8String]);
}
-String OSIPhone::get_processor_name() const {
+String OS_IOS::get_processor_name() const {
char buffer[256];
size_t buffer_len = 256;
if (sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_len, NULL, 0) == 0) {
@@ -302,7 +302,7 @@ String OSIPhone::get_processor_name() const {
ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string."));
}
-void OSIPhone::vibrate_handheld(int p_duration_ms) {
+void OS_IOS::vibrate_handheld(int p_duration_ms) {
if (ios->supports_haptic_engine()) {
ios->vibrate_haptic_engine((float)p_duration_ms / 1000.f);
} else {
@@ -311,16 +311,16 @@ void OSIPhone::vibrate_handheld(int p_duration_ms) {
}
}
-bool OSIPhone::_check_internal_feature_support(const String &p_feature) {
+bool OS_IOS::_check_internal_feature_support(const String &p_feature) {
return p_feature == "mobile";
}
-void OSIPhone::on_focus_out() {
+void OS_IOS::on_focus_out() {
if (is_focused) {
is_focused = false;
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
}
[AppDelegate.viewController.godotView stopRendering];
@@ -329,12 +329,12 @@ void OSIPhone::on_focus_out() {
}
}
-void OSIPhone::on_focus_in() {
+void OS_IOS::on_focus_in() {
if (!is_focused) {
is_focused = true;
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
}
[AppDelegate.viewController.godotView startRendering];
@@ -343,4 +343,4 @@ void OSIPhone::on_focus_in() {
}
}
-#endif // IPHONE_ENABLED
+#endif // IOS_ENABLED
diff --git a/platform/iphone/platform_config.h b/platform/ios/platform_config.h
index fed77d8932..fed77d8932 100644
--- a/platform/iphone/platform_config.h
+++ b/platform/ios/platform_config.h
diff --git a/platform/iphone/tts_ios.h b/platform/ios/tts_ios.h
index 064316b0b2..064316b0b2 100644
--- a/platform/iphone/tts_ios.h
+++ b/platform/ios/tts_ios.h
diff --git a/platform/iphone/tts_ios.mm b/platform/ios/tts_ios.mm
index a079d02add..a079d02add 100644
--- a/platform/iphone/tts_ios.mm
+++ b/platform/ios/tts_ios.mm
diff --git a/platform/iphone/view_controller.h b/platform/ios/view_controller.h
index c8b37a4d11..c8b37a4d11 100644
--- a/platform/iphone/view_controller.h
+++ b/platform/ios/view_controller.h
diff --git a/platform/iphone/view_controller.mm b/platform/ios/view_controller.mm
index 4f4ef4f046..43669d3f94 100644
--- a/platform/iphone/view_controller.mm
+++ b/platform/ios/view_controller.mm
@@ -30,11 +30,11 @@
#import "view_controller.h"
#include "core/config/project_settings.h"
-#include "display_server_iphone.h"
+#include "display_server_ios.h"
#import "godot_view.h"
#import "godot_view_renderer.h"
#import "keyboard_input_view.h"
-#include "os_iphone.h"
+#include "os_ios.h"
#import <AVFoundation/AVFoundation.h>
#import <GameController/GameController.h>
@@ -168,11 +168,11 @@
}
- (BOOL)shouldAutorotate {
- if (!DisplayServerIPhone::get_singleton()) {
+ if (!DisplayServerIOS::get_singleton()) {
return NO;
}
- switch (DisplayServerIPhone::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
+ switch (DisplayServerIOS::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
case DisplayServer::SCREEN_SENSOR:
case DisplayServer::SCREEN_SENSOR_LANDSCAPE:
case DisplayServer::SCREEN_SENSOR_PORTRAIT:
@@ -183,11 +183,11 @@
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
- if (!DisplayServerIPhone::get_singleton()) {
+ if (!DisplayServerIOS::get_singleton()) {
return UIInterfaceOrientationMaskAll;
}
- switch (DisplayServerIPhone::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
+ switch (DisplayServerIOS::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
case DisplayServer::SCREEN_PORTRAIT:
return UIInterfaceOrientationMaskPortrait;
case DisplayServer::SCREEN_REVERSE_LANDSCAPE:
@@ -226,14 +226,14 @@
CGRect rawFrame = [value CGRectValue];
CGRect keyboardFrame = [self.view convertRect:rawFrame fromView:nil];
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->virtual_keyboard_set_height(keyboardFrame.size.height);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->virtual_keyboard_set_height(keyboardFrame.size.height);
}
}
- (void)keyboardHidden:(NSNotification *)notification {
- if (DisplayServerIPhone::get_singleton()) {
- DisplayServerIPhone::get_singleton()->virtual_keyboard_set_height(0);
+ if (DisplayServerIOS::get_singleton()) {
+ DisplayServerIOS::get_singleton()->virtual_keyboard_set_height(0);
}
}
diff --git a/platform/iphone/vulkan_context_iphone.h b/platform/ios/vulkan_context_ios.h
index 7576525755..e9c09e087a 100644
--- a/platform/iphone/vulkan_context_iphone.h
+++ b/platform/ios/vulkan_context_ios.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vulkan_context_iphone.h */
+/* vulkan_context_ios.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,21 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VULKAN_CONTEXT_IPHONE_H
-#define VULKAN_CONTEXT_IPHONE_H
+#ifndef VULKAN_CONTEXT_IOS_H
+#define VULKAN_CONTEXT_IOS_H
#include "drivers/vulkan/vulkan_context.h"
#import <UIKit/UIKit.h>
-class VulkanContextIPhone : public VulkanContext {
+class VulkanContextIOS : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height);
- VulkanContextIPhone();
- ~VulkanContextIPhone();
+ VulkanContextIOS();
+ ~VulkanContextIOS();
};
-#endif // VULKAN_CONTEXT_IPHONE_H
+#endif // VULKAN_CONTEXT_IOS_H
diff --git a/platform/iphone/vulkan_context_iphone.mm b/platform/ios/vulkan_context_ios.mm
index 17cb0f6009..09cd369aa5 100644
--- a/platform/iphone/vulkan_context_iphone.mm
+++ b/platform/ios/vulkan_context_ios.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vulkan_context_iphone.mm */
+/* vulkan_context_ios.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,18 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "vulkan_context_iphone.h"
+#include "vulkan_context_ios.h"
#ifdef USE_VOLK
#include <volk.h>
#else
#include <vulkan/vulkan.h>
#endif
-const char *VulkanContextIPhone::_get_platform_surface_extension() const {
+const char *VulkanContextIOS::_get_platform_surface_extension() const {
return VK_MVK_IOS_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height) {
+Error VulkanContextIOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height) {
VkIOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
@@ -54,6 +54,6 @@ Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, Di
return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
-VulkanContextIPhone::VulkanContextIPhone() {}
+VulkanContextIOS::VulkanContextIOS() {}
-VulkanContextIPhone::~VulkanContextIPhone() {}
+VulkanContextIOS::~VulkanContextIOS() {}
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index a96c539a1f..4edd6c793a 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -236,7 +236,7 @@ void DisplayServerJavaScript::mouse_move_callback(double p_x, double p_y, double
const char *DisplayServerJavaScript::godot2dom_cursor(DisplayServer::CursorShape p_shape) {
switch (p_shape) {
case DisplayServer::CURSOR_ARROW:
- return "auto";
+ return "default";
case DisplayServer::CURSOR_IBEAM:
return "text";
case DisplayServer::CURSOR_POINTING_HAND:
@@ -270,7 +270,7 @@ const char *DisplayServerJavaScript::godot2dom_cursor(DisplayServer::CursorShape
case DisplayServer::CURSOR_HELP:
return "help";
default:
- return "auto";
+ return "default";
}
}
diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp
index 901580c140..e2ae45627e 100644
--- a/platform/javascript/export/export_plugin.cpp
+++ b/platform/javascript/export/export_plugin.cpp
@@ -661,13 +661,8 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
server.instantiate();
server_thread.start(_server_thread_poll, this);
- Ref<Image> img = memnew(Image(_javascript_logo));
- logo.instantiate();
- logo->create_from_image(img);
-
- img = Ref<Image>(memnew(Image(_javascript_run_icon)));
- run_icon.instantiate();
- run_icon->create_from_image(img);
+ logo = ImageTexture::create_from_image(memnew(Image(_javascript_logo)));
+ run_icon = ImageTexture::create_from_image(memnew(Image(_javascript_run_icon)));
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
if (theme.is_valid()) {
diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js
index 2e5e1ed0d1..9c4b6c2012 100644
--- a/platform/javascript/js/engine/config.js
+++ b/platform/javascript/js/engine/config.js
@@ -334,6 +334,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
locale = navigator.languages ? navigator.languages[0] : navigator.language;
locale = locale.split('.')[0];
}
+ locale = locale.replace('-', '_');
const onExit = this.onExit;
// Godot configuration.
diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub
index 09a432eae2..636a3c7db2 100644
--- a/platform/linuxbsd/SCsub
+++ b/platform/linuxbsd/SCsub
@@ -12,7 +12,7 @@ common_linuxbsd = [
"freedesktop_screensaver.cpp",
]
-if "x11" in env and env["x11"]:
+if env["x11"]:
common_linuxbsd += [
"gl_manager_x11.cpp",
"detect_prime_x11.cpp",
@@ -20,13 +20,13 @@ if "x11" in env and env["x11"]:
"key_mapping_x11.cpp",
]
-if "speechd" in env and env["speechd"]:
- common_linuxbsd.append(["speechd-so_wrap.c", "tts_linux.cpp"])
+ if env["vulkan"]:
+ common_linuxbsd.append("vulkan_context_x11.cpp")
-if "vulkan" in env and env["vulkan"]:
- common_linuxbsd.append("vulkan_context_x11.cpp")
+if env["speechd"]:
+ common_linuxbsd.append(["speechd-so_wrap.c", "tts_linux.cpp"])
-if "udev" in env and env["udev"]:
+if env["udev"]:
common_linuxbsd.append("libudev-so_wrap.c")
prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_linuxbsd)
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 19cf341c85..065250c40e 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -1,6 +1,7 @@
import os
import platform
import sys
+from methods import get_compiler_version, using_gcc
def is_active():
@@ -15,47 +16,11 @@ def can_build():
if os.name != "posix" or sys.platform == "darwin":
return False
- # Check the minimal dependencies
- x11_error = os.system("pkg-config --version > /dev/null")
- if x11_error:
+ pkgconf_error = os.system("pkg-config --version > /dev/null")
+ if pkgconf_error:
print("Error: pkg-config not found. Aborting.")
return False
- x11_error = os.system("pkg-config x11 --modversion > /dev/null")
- if x11_error:
- print("Error: X11 libraries not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xcursor --modversion > /dev/null")
- if x11_error:
- print("Error: Xcursor library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xinerama --modversion > /dev/null")
- if x11_error:
- print("Error: Xinerama library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xext --modversion > /dev/null")
- if x11_error:
- print("Error: Xext library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xrandr --modversion > /dev/null")
- if x11_error:
- print("Error: XrandR library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xrender --modversion > /dev/null")
- if x11_error:
- print("Error: XRender library not found. Aborting.")
- return False
-
- x11_error = os.system("pkg-config xi --modversion > /dev/null")
- if x11_error:
- print("Error: Xi library not found. Aborting.")
- return False
-
return True
@@ -63,9 +28,9 @@ def get_opts():
from SCons.Variables import BoolVariable, EnumVariable
return [
+ EnumVariable("linker", "Linker program", "default", ("default", "bfd", "gold", "lld", "mold")),
BoolVariable("use_llvm", "Use the LLVM compiler", False),
- BoolVariable("use_lld", "Use the LLD linker", False),
- BoolVariable("use_thinlto", "Use ThinLTO", False),
+ BoolVariable("use_thinlto", "Use ThinLTO (LLVM only, requires linker=lld, implies use_lto=yes)", False),
BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True),
BoolVariable("use_coverage", "Test Godot coverage", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
@@ -147,15 +112,32 @@ def configure(env):
env["CXX"] = "clang++"
env.extra_suffix = ".llvm" + env.extra_suffix
- if env["use_lld"]:
- if env["use_llvm"]:
- env.Append(LINKFLAGS=["-fuse-ld=lld"])
- if env["use_thinlto"]:
- # A convenience so you don't need to write use_lto too when using SCons
- env["use_lto"] = True
+ if env["linker"] != "default":
+ print("Using linker program: " + env["linker"])
+ if env["linker"] == "mold" and using_gcc(env): # GCC < 12.1 doesn't support -fuse-ld=mold.
+ cc_version = get_compiler_version(env)
+ cc_semver = (int(cc_version["major"]), int(cc_version["minor"]))
+ if cc_semver < (12, 1):
+ found_wrapper = False
+ for path in ["/usr/libexec", "/usr/local/libexec", "/usr/lib", "/usr/local/lib"]:
+ if os.path.isfile(path + "/mold/ld"):
+ env.Append(LINKFLAGS=["-B" + path + "/mold"])
+ found_wrapper = True
+ break
+ if not found_wrapper:
+ print("Couldn't locate mold installation path. Make sure it's installed in /usr or /usr/local.")
+ sys.exit(255)
+ else:
+ env.Append(LINKFLAGS=["-fuse-ld=mold"])
else:
- print("Using LLD with GCC is not supported yet. Try compiling with 'use_llvm=yes'.")
+ env.Append(LINKFLAGS=["-fuse-ld=%s" % env["linker"]])
+
+ if env["use_thinlto"]:
+ if not env["use_llvm"] or env["linker"] != "lld":
+ print("ThinLTO is only compatible with LLVM and the LLD linker, use `use_llvm=yes linker=lld`.")
sys.exit(255)
+ else:
+ env["use_lto"] = True # ThinLTO implies LTO
if env["use_coverage"]:
env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"])
@@ -200,33 +182,32 @@ def configure(env):
env.Append(LINKFLAGS=["-fsanitize=memory"])
if env["use_lto"]:
- if not env["use_llvm"] and env.GetOption("num_jobs") > 1:
+ if env["use_thinlto"]:
+ env.Append(CCFLAGS=["-flto=thin"])
+ env.Append(LINKFLAGS=["-flto=thin"])
+ elif not env["use_llvm"] and env.GetOption("num_jobs") > 1:
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto=" + str(env.GetOption("num_jobs"))])
else:
- if env["use_lld"] and env["use_thinlto"]:
- env.Append(CCFLAGS=["-flto=thin"])
- env.Append(LINKFLAGS=["-flto=thin"])
- else:
- env.Append(CCFLAGS=["-flto"])
- env.Append(LINKFLAGS=["-flto"])
+ env.Append(CCFLAGS=["-flto"])
+ env.Append(LINKFLAGS=["-flto"])
if not env["use_llvm"]:
env["RANLIB"] = "gcc-ranlib"
env["AR"] = "gcc-ar"
env.Append(CCFLAGS=["-pipe"])
- env.Append(LINKFLAGS=["-pipe"])
## Dependencies
- env.ParseConfig("pkg-config x11 --cflags --libs")
- env.ParseConfig("pkg-config xcursor --cflags --libs")
- env.ParseConfig("pkg-config xinerama --cflags --libs")
- env.ParseConfig("pkg-config xext --cflags --libs")
- env.ParseConfig("pkg-config xrandr --cflags --libs")
- env.ParseConfig("pkg-config xrender --cflags --libs")
- env.ParseConfig("pkg-config xi --cflags --libs")
+ if env["x11"]:
+ env.ParseConfig("pkg-config x11 --cflags --libs")
+ env.ParseConfig("pkg-config xcursor --cflags --libs")
+ env.ParseConfig("pkg-config xinerama --cflags --libs")
+ env.ParseConfig("pkg-config xext --cflags --libs")
+ env.ParseConfig("pkg-config xrandr --cflags --libs")
+ env.ParseConfig("pkg-config xrender --cflags --libs")
+ env.ParseConfig("pkg-config xi --cflags --libs")
if env["touch"]:
env.Append(CPPDEFINES=["TOUCH_ENABLED"])
@@ -382,8 +363,9 @@ def configure(env):
# No pkgconfig file so far, hardcode expected lib name.
env.Append(LIBS=["glslang", "SPIRV"])
- env.Append(CPPDEFINES=["GLES3_ENABLED"])
- env.ParseConfig("pkg-config gl --cflags --libs")
+ if env["opengl3"]:
+ env.Append(CPPDEFINES=["GLES3_ENABLED"])
+ env.ParseConfig("pkg-config gl --cflags --libs")
env.Append(LIBS=["pthread"])
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 4aec111022..d4267d3c02 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -196,6 +196,7 @@ bool DisplayServerX11::_refresh_device_info() {
xi.absolute_devices.clear();
xi.touch_devices.clear();
+ xi.pen_inverted_devices.clear();
int dev_count;
XIDeviceInfo *info = XIQueryDevice(x11_display, XIAllDevices, &dev_count);
@@ -205,7 +206,7 @@ bool DisplayServerX11::_refresh_device_info() {
if (!dev->enabled) {
continue;
}
- if (!(dev->use == XIMasterPointer || dev->use == XIFloatingSlave)) {
+ if (!(dev->use == XISlavePointer || dev->use == XIFloatingSlave)) {
continue;
}
@@ -274,6 +275,7 @@ bool DisplayServerX11::_refresh_device_info() {
xi.pen_pressure_range[dev->deviceid] = Vector2(pressure_min, pressure_max);
xi.pen_tilt_x_range[dev->deviceid] = Vector2(tilt_x_min, tilt_x_max);
xi.pen_tilt_y_range[dev->deviceid] = Vector2(tilt_y_min, tilt_y_max);
+ xi.pen_inverted_devices[dev->deviceid] = String(dev->name).findn("eraser") > 0;
}
XIFreeDeviceInfo(info);
@@ -1487,8 +1489,8 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window
XMoveResizeWindow(x11_display, wd.x11_window, position.x, position.y, size.x, size.y);
} else {
if (p_screen != window_get_current_screen(p_window)) {
- Point2i position = screen_get_position(p_screen);
- XMoveWindow(x11_display, wd.x11_window, position.x, position.y);
+ 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);
}
}
}
@@ -1817,6 +1819,52 @@ bool DisplayServerX11::_window_maximize_check(WindowID p_window, const char *p_a
return retval;
}
+bool DisplayServerX11::_window_fullscreen_check(WindowID p_window) const {
+ ERR_FAIL_COND_V(!windows.has(p_window), false);
+ const WindowData &wd = windows[p_window];
+
+ // Using EWMH -- Extended Window Manager Hints
+ Atom property = XInternAtom(x11_display, "_NET_WM_STATE", False);
+ Atom type;
+ int format;
+ unsigned long len;
+ unsigned long remaining;
+ unsigned char *data = nullptr;
+ bool retval = false;
+
+ if (property == None) {
+ return retval;
+ }
+
+ int result = XGetWindowProperty(
+ x11_display,
+ wd.x11_window,
+ property,
+ 0,
+ 1024,
+ False,
+ XA_ATOM,
+ &type,
+ &format,
+ &len,
+ &remaining,
+ &data);
+
+ if (result == Success) {
+ Atom *atoms = (Atom *)data;
+ Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);
+ for (uint64_t i = 0; i < len; i++) {
+ if (atoms[i] == wm_fullscreen) {
+ retval = true;
+ break;
+ }
+ }
+ XFree(data);
+ }
+
+ return retval;
+}
+
bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const {
_THREAD_SAFE_METHOD_
return _window_maximize_check(p_window, "_NET_WM_ALLOWED_ACTIONS");
@@ -3438,7 +3486,7 @@ void DisplayServerX11::process_events() {
} break;
case XI_RawMotion: {
XIRawEvent *raw_event = (XIRawEvent *)event_data;
- int device_id = raw_event->deviceid;
+ int device_id = raw_event->sourceid;
// Determine the axis used (called valuators in XInput for some forsaken reason)
// Mask is a bitmask indicating which axes are involved.
@@ -3504,6 +3552,11 @@ void DisplayServerX11::process_events() {
values++;
}
+ HashMap<int, bool>::Iterator pen_inverted = xi.pen_inverted_devices.find(device_id);
+ if (pen_inverted) {
+ xi.pen_inverted = pen_inverted->value;
+ }
+
// https://bugs.freedesktop.org/show_bug.cgi?id=71609
// http://lists.libsdl.org/pipermail/commits-libsdl.org/2015-June/000282.html
if (raw_event->time == xi.last_relative_time && rel_x == xi.relative_motion.x && rel_y == xi.relative_motion.y) {
@@ -3604,6 +3657,8 @@ void DisplayServerX11::process_events() {
case Expose: {
DEBUG_LOG_X11("[%u] Expose window=%lu (%u), count='%u' \n", frame, event.xexpose.window, window_id, event.xexpose.count);
+ windows[window_id].fullscreen = _window_fullscreen_check(window_id);
+
Main::force_redraw();
} break;
@@ -3936,6 +3991,7 @@ void DisplayServerX11::process_events() {
mm->set_pressure(bool(mouse_get_button_state() & MouseButton::MASK_LEFT) ? 1.0f : 0.0f);
}
mm->set_tilt(xi.tilt);
+ mm->set_pen_inverted(xi.pen_inverted);
_get_key_modifier_state(event.xmotion.state, mm);
mm->set_button_mask((MouseButton)mouse_get_button_state());
@@ -4119,13 +4175,17 @@ void DisplayServerX11::process_events() {
void DisplayServerX11::release_rendering_thread() {
#if defined(GLES3_ENABLED)
- gl_manager->release_current();
+ if (gl_manager) {
+ gl_manager->release_current();
+ }
#endif
}
void DisplayServerX11::make_rendering_thread() {
#if defined(GLES3_ENABLED)
- gl_manager->make_current();
+ if (gl_manager) {
+ gl_manager->make_current();
+ }
#endif
}
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 4beeddd3a8..9ce6a557db 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -201,10 +201,12 @@ class DisplayServerX11 : public DisplayServer {
HashMap<int, Vector2> pen_pressure_range;
HashMap<int, Vector2> pen_tilt_x_range;
HashMap<int, Vector2> pen_tilt_y_range;
+ HashMap<int, bool> pen_inverted_devices;
XIEventMask all_event_mask;
HashMap<int, Vector2> state;
double pressure;
bool pressure_supported;
+ bool pen_inverted;
Vector2 tilt;
Vector2 mouse_pos_to_filter;
Vector2 relative_motion;
@@ -265,6 +267,7 @@ class DisplayServerX11 : public DisplayServer {
void _update_real_mouse_position(const WindowData &wd);
bool _window_maximize_check(WindowID p_window, const char *p_atom_name) const;
+ bool _window_fullscreen_check(WindowID p_window) const;
void _update_size_hints(WindowID p_window);
void _set_wm_fullscreen(WindowID p_window, bool p_enabled);
void _set_wm_maximized(WindowID p_window, bool p_enabled);
diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp
index 965b969ba8..4240e9adc0 100644
--- a/platform/linuxbsd/export/export.cpp
+++ b/platform/linuxbsd/export/export.cpp
@@ -35,12 +35,7 @@
void register_linuxbsd_exporter() {
Ref<EditorExportPlatformLinuxBSD> platform;
platform.instantiate();
-
- Ref<Image> img = memnew(Image(_linuxbsd_logo));
- Ref<ImageTexture> logo;
- logo.instantiate();
- logo->create_from_image(img);
- platform->set_logo(logo);
+ platform->set_logo(ImageTexture::create_from_image(memnew(Image(_linuxbsd_logo))));
platform->set_name("Linux/X11");
platform->set_extension("x86_32");
platform->set_extension("x86_64", "binary_format/64_bits");
diff --git a/platform/linuxbsd/godot_linuxbsd.cpp b/platform/linuxbsd/godot_linuxbsd.cpp
index 9fe00568fb..91a260182e 100644
--- a/platform/linuxbsd/godot_linuxbsd.cpp
+++ b/platform/linuxbsd/godot_linuxbsd.cpp
@@ -61,6 +61,10 @@ int main(int argc, char *argv[]) {
Error err = Main::setup(argv[0], argc - 1, &argv[1]);
if (err != OK) {
free(cwd);
+
+ if (err == ERR_HELP) { // Returned by --help and --version, so success.
+ return 0;
+ }
return 255;
}
diff --git a/platform/macos/SCsub b/platform/macos/SCsub
new file mode 100644
index 0000000000..d0856c709a
--- /dev/null
+++ b/platform/macos/SCsub
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+
+Import("env")
+
+from platform_methods import run_in_subprocess
+import platform_macos_builders
+
+files = [
+ "os_macos.mm",
+ "godot_application.mm",
+ "godot_application_delegate.mm",
+ "crash_handler_macos.mm",
+ "macos_terminal_logger.mm",
+ "display_server_macos.mm",
+ "godot_content_view.mm",
+ "godot_window_delegate.mm",
+ "godot_window.mm",
+ "key_mapping_macos.mm",
+ "godot_main_macos.mm",
+ "dir_access_macos.mm",
+ "tts_macos.mm",
+ "joypad_macos.cpp",
+ "vulkan_context_macos.mm",
+ "gl_manager_macos_legacy.mm",
+]
+
+prog = env.add_program("#bin/godot", files)
+
+if env["debug_symbols"] and env["separate_debug_symbols"]:
+ env.AddPostAction(prog, run_in_subprocess(platform_macos_builders.make_debug_macos))
diff --git a/platform/osx/crash_handler_osx.h b/platform/macos/crash_handler_macos.h
index 72938e5e0a..c9b0e77dc4 100644
--- a/platform/osx/crash_handler_osx.h
+++ b/platform/macos/crash_handler_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* crash_handler_osx.h */
+/* crash_handler_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CRASH_HANDLER_OSX_H
-#define CRASH_HANDLER_OSX_H
+#ifndef CRASH_HANDLER_MACOS_H
+#define CRASH_HANDLER_MACOS_H
class CrashHandler {
bool disabled;
@@ -44,4 +44,4 @@ public:
~CrashHandler();
};
-#endif // CRASH_HANDLER_OSX_H
+#endif // CRASH_HANDLER_MACOS_H
diff --git a/platform/osx/crash_handler_osx.mm b/platform/macos/crash_handler_macos.mm
index a798ba3b46..74bd012f0c 100644
--- a/platform/osx/crash_handler_osx.mm
+++ b/platform/macos/crash_handler_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* crash_handler_osx.mm */
+/* crash_handler_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "crash_handler_osx.h"
+#include "crash_handler_macos.h"
#include "core/config/project_settings.h"
#include "core/os/os.h"
diff --git a/platform/osx/detect.py b/platform/macos/detect.py
index 8d848d2094..20e7afa772 100644
--- a/platform/osx/detect.py
+++ b/platform/macos/detect.py
@@ -8,7 +8,7 @@ def is_active():
def get_name():
- return "OSX"
+ return "macOS"
def can_build():
@@ -24,7 +24,7 @@ def get_opts():
return [
("osxcross_sdk", "OSXCross SDK version", "darwin16"),
("MACOS_SDK_PATH", "Path to the macOS SDK", ""),
- ("VULKAN_SDK_PATH", "Path to the Vulkan SDK", ""),
+ ("vulkan_sdk_path", "Path to the Vulkan SDK", ""),
EnumVariable("macports_clang", "Build using Clang from MacPorts", "no", ("no", "5.0", "devel")),
BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
@@ -36,7 +36,38 @@ def get_opts():
def get_flags():
- return []
+ return [
+ ("use_volk", False),
+ ]
+
+
+def get_mvk_sdk_path():
+ def int_or_zero(i):
+ try:
+ return int(i)
+ except:
+ return 0
+
+ def ver_parse(a):
+ return [int_or_zero(i) for i in a.split(".")]
+
+ dirname = os.path.expanduser("~/VulkanSDK")
+ files = os.listdir(dirname)
+
+ ver_file = "0.0.0.0"
+ ver_num = ver_parse(ver_file)
+
+ for file in files:
+ if os.path.isdir(os.path.join(dirname, file)):
+ ver_comp = ver_parse(file)
+ lib_name = os.path.join(
+ os.path.join(dirname, file), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/libMoltenVK.a"
+ )
+ if os.path.isfile(lib_name) and ver_comp > ver_num:
+ ver_num = ver_comp
+ ver_file = file
+
+ return os.path.join(os.path.join(dirname, ver_file), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/")
def configure(env):
@@ -67,7 +98,7 @@ def configure(env):
## Architecture
- # Mac OS X no longer runs on 32-bit since 10.7 which is unsupported since 2014
+ # macOS no longer runs on 32-bit since 10.7 which is unsupported since 2014
# As such, we only support 64-bit
env["bits"] = "64"
@@ -79,10 +110,12 @@ def configure(env):
if env["arch"] == "arm64":
print("Building for macOS 11.0+, platform arm64.")
+ env.Append(ASFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
else:
print("Building for macOS 10.12+, platform x86_64.")
+ env.Append(ASFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
@@ -101,7 +134,7 @@ def configure(env):
env["CC"] = "clang"
env["CXX"] = "clang++"
- detect_darwin_sdk_path("osx", env)
+ detect_darwin_sdk_path("macos", env)
env.Append(CCFLAGS=["-isysroot", "$MACOS_SDK_PATH"])
env.Append(LINKFLAGS=["-isysroot", "$MACOS_SDK_PATH"])
@@ -158,8 +191,10 @@ def configure(env):
## Flags
- env.Prepend(CPPPATH=["#platform/osx"])
- env.Append(CPPDEFINES=["OSX_ENABLED", "UNIX_ENABLED", "APPLE_STYLE_KEYS", "COREAUDIO_ENABLED", "COREMIDI_ENABLED"])
+ env.Prepend(CPPPATH=["#platform/macos"])
+ env.Append(
+ CPPDEFINES=["MACOS_ENABLED", "UNIX_ENABLED", "APPLE_STYLE_KEYS", "COREAUDIO_ENABLED", "COREMIDI_ENABLED"]
+ )
env.Append(
LINKFLAGS=[
"-framework",
@@ -197,4 +232,22 @@ def configure(env):
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
env.Append(LINKFLAGS=["-framework", "Metal", "-framework", "QuartzCore", "-framework", "IOSurface"])
if not env["use_volk"]:
- env.Append(LINKFLAGS=["-L$VULKAN_SDK_PATH/MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/", "-lMoltenVK"])
+ env.Append(LINKFLAGS=["-lMoltenVK"])
+ mvk_found = False
+ if env["vulkan_sdk_path"] != "":
+ mvk_path = os.path.join(
+ os.path.expanduser(env["vulkan_sdk_path"]), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/"
+ )
+ if os.path.isfile(os.path.join(mvk_path, "libMoltenVK.a")):
+ mvk_found = True
+ env.Append(LINKFLAGS=["-L" + mvk_path])
+ if not mvk_found:
+ mvk_path = get_mvk_sdk_path()
+ if os.path.isfile(os.path.join(mvk_path, "libMoltenVK.a")):
+ mvk_found = True
+ env.Append(LINKFLAGS=["-L" + mvk_path])
+ if not mvk_found:
+ print(
+ "MoltenVK SDK installation directory not found, use 'vulkan_sdk_path' SCons parameter to specify SDK path."
+ )
+ sys.exit(255)
diff --git a/platform/osx/dir_access_osx.h b/platform/macos/dir_access_macos.h
index 3c66c81d4f..2b234ad96c 100644
--- a/platform/osx/dir_access_osx.h
+++ b/platform/macos/dir_access_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* dir_access_osx.h */
+/* dir_access_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DIR_ACCESS_OSX_H
-#define DIR_ACCESS_OSX_H
+#ifndef DIR_ACCESS_MACOS_H
+#define DIR_ACCESS_MACOS_H
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
@@ -41,7 +41,7 @@
#include "core/io/dir_access.h"
#include "drivers/unix/dir_access_unix.h"
-class DirAccessOSX : public DirAccessUnix {
+class DirAccessMacOS : public DirAccessUnix {
protected:
virtual String fix_unicode_name(const char *p_name) const;
diff --git a/platform/osx/dir_access_osx.mm b/platform/macos/dir_access_macos.mm
index 6bafb9470d..8f3906c6b8 100644
--- a/platform/osx/dir_access_osx.mm
+++ b/platform/macos/dir_access_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* dir_access_osx.mm */
+/* dir_access_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "dir_access_osx.h"
+#include "dir_access_macos.h"
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
@@ -37,7 +37,7 @@
#import <AppKit/NSWorkspace.h>
#import <Foundation/Foundation.h>
-String DirAccessOSX::fix_unicode_name(const char *p_name) const {
+String DirAccessMacOS::fix_unicode_name(const char *p_name) const {
String fname;
NSString *nsstr = [[NSString stringWithUTF8String:p_name] precomposedStringWithCanonicalMapping];
@@ -46,14 +46,14 @@ String DirAccessOSX::fix_unicode_name(const char *p_name) const {
return fname;
}
-int DirAccessOSX::get_drive_count() {
+int DirAccessMacOS::get_drive_count() {
NSArray *res_keys = [NSArray arrayWithObjects:NSURLVolumeURLKey, NSURLIsSystemImmutableKey, nil];
NSArray *vols = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:res_keys options:NSVolumeEnumerationSkipHiddenVolumes];
return [vols count];
}
-String DirAccessOSX::get_drive(int p_drive) {
+String DirAccessMacOS::get_drive(int p_drive) {
NSArray *res_keys = [NSArray arrayWithObjects:NSURLVolumeURLKey, NSURLIsSystemImmutableKey, nil];
NSArray *vols = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:res_keys options:NSVolumeEnumerationSkipHiddenVolumes];
int count = [vols count];
@@ -68,7 +68,7 @@ String DirAccessOSX::get_drive(int p_drive) {
return volname;
}
-bool DirAccessOSX::is_hidden(const String &p_name) {
+bool DirAccessMacOS::is_hidden(const String &p_name) {
String f = get_current_dir().plus_file(p_name);
NSURL *url = [NSURL fileURLWithPath:@(f.utf8().get_data())];
NSNumber *hidden = nil;
diff --git a/platform/osx/display_server_osx.h b/platform/macos/display_server_macos.h
index 9575cb29a2..41031ec81b 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/macos/display_server_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* display_server_osx.h */
+/* display_server_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DISPLAY_SERVER_OSX_H
-#define DISPLAY_SERVER_OSX_H
+#ifndef DISPLAY_SERVER_MACOS_H
+#define DISPLAY_SERVER_MACOS_H
#define BitMap _QDBitMap // Suppress deprecated QuickDraw definition.
@@ -37,12 +37,12 @@
#include "servers/display_server.h"
#if defined(GLES3_ENABLED)
-#include "gl_manager_osx_legacy.h"
+#include "gl_manager_macos_legacy.h"
#endif // GLES3_ENABLED
#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h"
-#include "platform/osx/vulkan_context_osx.h"
+#include "platform/macos/vulkan_context_macos.h"
#endif // VULKAN_ENABLED
#import <AppKit/AppKit.h>
@@ -54,15 +54,15 @@
#undef BitMap
#undef CursorShape
-class DisplayServerOSX : public DisplayServer {
- GDCLASS(DisplayServerOSX, DisplayServer)
+class DisplayServerMacOS : public DisplayServer {
+ GDCLASS(DisplayServerMacOS, DisplayServer)
_THREAD_SAFE_CLASS_
public:
struct KeyEvent {
WindowID window_id = INVALID_WINDOW_ID;
- unsigned int osx_state = false;
+ unsigned int macos_state = false;
bool pressed = false;
bool echo = false;
bool raw = false;
@@ -115,10 +115,10 @@ public:
private:
#if defined(GLES3_ENABLED)
- GLManager_OSX *gl_manager = nullptr;
+ GLManager_MacOS *gl_manager = nullptr;
#endif
#if defined(VULKAN_ENABLED)
- VulkanContextOSX *context_vulkan = nullptr;
+ VulkanContextMacOS *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif
String rendering_driver;
@@ -203,7 +203,7 @@ public:
void send_event(NSEvent *p_event);
void send_window_event(const WindowData &p_wd, WindowEvent p_event);
void release_pressed_events();
- void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) const;
+ void get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const;
void update_mouse_pos(WindowData &p_wd, NSPoint p_location_in_window);
void push_to_key_event_buffer(const KeyEvent &p_event);
void update_im_text(const Point2i &p_selection, const String &p_text);
@@ -397,10 +397,10 @@ public:
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
- static void register_osx_driver();
+ static void register_macos_driver();
- DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
- ~DisplayServerOSX();
+ DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ ~DisplayServerMacOS();
};
-#endif // DISPLAY_SERVER_OSX_H
+#endif // DISPLAY_SERVER_MACOS_H
diff --git a/platform/osx/display_server_osx.mm b/platform/macos/display_server_macos.mm
index b6a5813bd0..07ba5d7497 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/macos/display_server_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* display_server_osx.mm */
+/* display_server_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,16 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "display_server_osx.h"
+#include "display_server_macos.h"
#include "godot_content_view.h"
#include "godot_menu_item.h"
#include "godot_window.h"
#include "godot_window_delegate.h"
-#include "key_mapping_osx.h"
-#include "os_osx.h"
+#include "key_mapping_macos.h"
+#include "os_macos.h"
-#include "tts_osx.h"
+#include "tts_macos.h"
#include "core/io/marshalls.h"
#include "core/math/geometry_2d.h"
@@ -60,7 +60,7 @@
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
-const NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) const {
+const NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) const {
const NSMenu *menu = nullptr;
if (p_menu_root == "") {
// Main menu.
@@ -81,7 +81,7 @@ const NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) const
return menu;
}
-NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) {
+NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) {
NSMenu *menu = nullptr;
if (p_menu_root == "") {
// Main menu.
@@ -105,7 +105,7 @@ NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) {
return menu;
}
-DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) {
+DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) {
WindowID id;
const float scale = screen_get_max_scale();
{
@@ -193,7 +193,7 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V
return id;
}
-void DisplayServerOSX::_update_window_style(WindowData p_wd) {
+void DisplayServerMacOS::_update_window_style(WindowData p_wd) {
bool borderless_full = false;
if (p_wd.borderless) {
@@ -222,7 +222,7 @@ void DisplayServerOSX::_update_window_style(WindowData p_wd) {
}
}
-void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) {
+void DisplayServerMacOS::_set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) {
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
@@ -267,7 +267,7 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
}
}
-void DisplayServerOSX::_update_displays_arrangement() {
+void DisplayServerMacOS::_update_displays_arrangement() {
origin = Point2i();
for (int i = 0; i < get_screen_count(); i++) {
@@ -282,20 +282,20 @@ void DisplayServerOSX::_update_displays_arrangement() {
displays_arrangement_dirty = false;
}
-Point2i DisplayServerOSX::_get_screens_origin() const {
+Point2i DisplayServerMacOS::_get_screens_origin() const {
// Returns the native top-left screen coordinate of the smallest rectangle
// that encompasses all screens. Needed in get_screen_position(),
// window_get_position, and window_set_position()
// to convert between OS X native screen coordinates and the ones expected by Godot.
if (displays_arrangement_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_displays_arrangement();
+ const_cast<DisplayServerMacOS *>(this)->_update_displays_arrangement();
}
return origin;
}
-Point2i DisplayServerOSX::_get_native_screen_position(int p_screen) const {
+Point2i DisplayServerMacOS::_get_native_screen_position(int p_screen) const {
NSArray *screenArray = [NSScreen screens];
if ((NSUInteger)p_screen < [screenArray count]) {
NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
@@ -306,18 +306,18 @@ Point2i DisplayServerOSX::_get_native_screen_position(int p_screen) const {
return Point2i();
}
-void DisplayServerOSX::_displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+void DisplayServerMacOS::_displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) {
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->displays_arrangement_dirty = true;
}
}
-void DisplayServerOSX::_dispatch_input_events(const Ref<InputEvent> &p_event) {
- ((DisplayServerOSX *)(get_singleton()))->_dispatch_input_event(p_event);
+void DisplayServerMacOS::_dispatch_input_events(const Ref<InputEvent> &p_event) {
+ ((DisplayServerMacOS *)(get_singleton()))->_dispatch_input_event(p_event);
}
-void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) {
+void DisplayServerMacOS::_dispatch_input_event(const Ref<InputEvent> &p_event) {
_THREAD_SAFE_METHOD_
if (!in_dispatch_input_event) {
in_dispatch_input_event = true;
@@ -364,12 +364,12 @@ void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) {
}
}
-void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) {
+void DisplayServerMacOS::_push_input(const Ref<InputEvent> &p_event) {
Ref<InputEvent> ev = p_event;
Input::get_singleton()->parse_input_event(ev);
}
-void DisplayServerOSX::_process_key_events() {
+void DisplayServerMacOS::_process_key_events() {
Ref<InputEventKey> k;
for (int i = 0; i < key_event_pos; i++) {
const KeyEvent &ke = key_event_buffer[i];
@@ -378,7 +378,7 @@ void DisplayServerOSX::_process_key_events() {
k.instantiate();
k->set_window_id(ke.window_id);
- get_key_modifier_state(ke.osx_state, k);
+ get_key_modifier_state(ke.macos_state, k);
k->set_pressed(ke.pressed);
k->set_echo(ke.echo);
k->set_keycode(ke.keycode);
@@ -392,7 +392,7 @@ void DisplayServerOSX::_process_key_events() {
k.instantiate();
k->set_window_id(ke.window_id);
- get_key_modifier_state(ke.osx_state, k);
+ get_key_modifier_state(ke.macos_state, k);
k->set_pressed(ke.pressed);
k->set_echo(ke.echo);
k->set_keycode(Key::NONE);
@@ -405,7 +405,7 @@ void DisplayServerOSX::_process_key_events() {
k.instantiate();
k->set_window_id(ke.window_id);
- get_key_modifier_state(ke.osx_state, k);
+ get_key_modifier_state(ke.macos_state, k);
k->set_pressed(ke.pressed);
k->set_echo(ke.echo);
k->set_keycode(ke.keycode);
@@ -423,7 +423,7 @@ void DisplayServerOSX::_process_key_events() {
key_event_pos = 0;
}
-void DisplayServerOSX::_update_keyboard_layouts() {
+void DisplayServerMacOS::_update_keyboard_layouts() {
kbd_layouts.clear();
current_layout = 0;
@@ -468,14 +468,14 @@ void DisplayServerOSX::_update_keyboard_layouts() {
keyboard_layout_dirty = false;
}
-void DisplayServerOSX::_keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info) {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+void DisplayServerMacOS::_keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info) {
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->keyboard_layout_dirty = true;
}
}
-NSImage *DisplayServerOSX::_convert_to_nsimg(Ref<Image> &p_image) const {
+NSImage *DisplayServerMacOS::_convert_to_nsimg(Ref<Image> &p_image) const {
p_image->convert(Image::FORMAT_RGBA8);
NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
@@ -509,7 +509,7 @@ NSImage *DisplayServerOSX::_convert_to_nsimg(Ref<Image> &p_image) const {
return nsimg;
}
-NSCursor *DisplayServerOSX::_cursor_from_selector(SEL p_selector, SEL p_fallback) {
+NSCursor *DisplayServerMacOS::_cursor_from_selector(SEL p_selector, SEL p_fallback) {
if ([NSCursor respondsToSelector:p_selector]) {
id object = [NSCursor performSelector:p_selector];
if ([object isKindOfClass:[NSCursor class]]) {
@@ -523,11 +523,11 @@ NSCursor *DisplayServerOSX::_cursor_from_selector(SEL p_selector, SEL p_fallback
return [NSCursor arrowCursor];
}
-NSMenu *DisplayServerOSX::get_dock_menu() const {
+NSMenu *DisplayServerMacOS::get_dock_menu() const {
return dock_menu;
}
-void DisplayServerOSX::menu_callback(id p_sender) {
+void DisplayServerMacOS::menu_callback(id p_sender) {
if (![p_sender representedObject]) {
return;
}
@@ -560,15 +560,15 @@ void DisplayServerOSX::menu_callback(id p_sender) {
}
}
-bool DisplayServerOSX::has_window(WindowID p_window) const {
+bool DisplayServerMacOS::has_window(WindowID p_window) const {
return windows.has(p_window);
}
-DisplayServerOSX::WindowData &DisplayServerOSX::get_window(WindowID p_window) {
+DisplayServerMacOS::WindowData &DisplayServerMacOS::get_window(WindowID p_window) {
return windows[p_window];
}
-void DisplayServerOSX::send_event(NSEvent *p_event) {
+void DisplayServerMacOS::send_event(NSEvent *p_event) {
// Special case handling of command-period, which is traditionally a special
// shortcut in macOS and doesn't arrive at our regular keyDown handler.
if ([p_event type] == NSEventTypeKeyDown) {
@@ -577,7 +577,7 @@ void DisplayServerOSX::send_event(NSEvent *p_event) {
k.instantiate();
get_key_modifier_state([p_event modifierFlags], k);
- k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID);
+ k->set_window_id(DisplayServerMacOS::INVALID_WINDOW_ID);
k->set_pressed(true);
k->set_keycode(Key::PERIOD);
k->set_physical_keycode(Key::PERIOD);
@@ -588,7 +588,7 @@ void DisplayServerOSX::send_event(NSEvent *p_event) {
}
}
-void DisplayServerOSX::send_window_event(const WindowData &wd, WindowEvent p_event) {
+void DisplayServerMacOS::send_window_event(const WindowData &wd, WindowEvent p_event) {
_THREAD_SAFE_METHOD_
if (!wd.event_callback.is_null()) {
@@ -600,21 +600,21 @@ void DisplayServerOSX::send_window_event(const WindowData &wd, WindowEvent p_eve
}
}
-void DisplayServerOSX::release_pressed_events() {
+void DisplayServerMacOS::release_pressed_events() {
_THREAD_SAFE_METHOD_
if (Input::get_singleton()) {
Input::get_singleton()->release_pressed_events();
}
}
-void DisplayServerOSX::get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) const {
- r_state->set_shift_pressed((p_osx_state & NSEventModifierFlagShift));
- r_state->set_ctrl_pressed((p_osx_state & NSEventModifierFlagControl));
- r_state->set_alt_pressed((p_osx_state & NSEventModifierFlagOption));
- r_state->set_meta_pressed((p_osx_state & NSEventModifierFlagCommand));
+void DisplayServerMacOS::get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const {
+ r_state->set_shift_pressed((p_macos_state & NSEventModifierFlagShift));
+ r_state->set_ctrl_pressed((p_macos_state & NSEventModifierFlagControl));
+ r_state->set_alt_pressed((p_macos_state & NSEventModifierFlagOption));
+ r_state->set_meta_pressed((p_macos_state & NSEventModifierFlagCommand));
}
-void DisplayServerOSX::update_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_location_in_window) {
+void DisplayServerMacOS::update_mouse_pos(DisplayServerMacOS::WindowData &p_wd, NSPoint p_location_in_window) {
const NSRect content_rect = [p_wd.window_view frame];
const float scale = screen_get_max_scale();
p_wd.mouse_pos.x = p_location_in_window.x * scale;
@@ -622,33 +622,33 @@ void DisplayServerOSX::update_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPo
Input::get_singleton()->set_mouse_position(p_wd.mouse_pos);
}
-void DisplayServerOSX::push_to_key_event_buffer(const DisplayServerOSX::KeyEvent &p_event) {
+void DisplayServerMacOS::push_to_key_event_buffer(const DisplayServerMacOS::KeyEvent &p_event) {
if (key_event_pos >= key_event_buffer.size()) {
key_event_buffer.resize(1 + key_event_pos);
}
key_event_buffer.write[key_event_pos++] = p_event;
}
-void DisplayServerOSX::update_im_text(const Point2i &p_selection, const String &p_text) {
+void DisplayServerMacOS::update_im_text(const Point2i &p_selection, const String &p_text) {
im_selection = p_selection;
im_text = p_text;
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
}
-void DisplayServerOSX::set_last_focused_window(WindowID p_window) {
+void DisplayServerMacOS::set_last_focused_window(WindowID p_window) {
last_focused_window = p_window;
}
-void DisplayServerOSX::set_is_resizing(bool p_is_resizing) {
+void DisplayServerMacOS::set_is_resizing(bool p_is_resizing) {
is_resizing = p_is_resizing;
}
-bool DisplayServerOSX::get_is_resizing() const {
+bool DisplayServerMacOS::get_is_resizing() const {
return is_resizing;
}
-void DisplayServerOSX::window_update(WindowID p_window) {
+void DisplayServerMacOS::window_update(WindowID p_window) {
#if defined(GLES3_ENABLED)
if (gl_manager) {
gl_manager->window_update(p_window);
@@ -656,7 +656,7 @@ void DisplayServerOSX::window_update(WindowID p_window) {
#endif
}
-void DisplayServerOSX::window_destroy(WindowID p_window) {
+void DisplayServerMacOS::window_destroy(WindowID p_window) {
#if defined(GLES3_ENABLED)
if (gl_manager) {
gl_manager->window_destroy(p_window);
@@ -670,7 +670,7 @@ void DisplayServerOSX::window_destroy(WindowID p_window) {
windows.erase(p_window);
}
-void DisplayServerOSX::window_resize(WindowID p_window, int p_width, int p_height) {
+void DisplayServerMacOS::window_resize(WindowID p_window, int p_width, int p_height) {
#if defined(GLES3_ENABLED)
if (gl_manager) {
gl_manager->window_resize(p_window, p_width, p_height);
@@ -683,7 +683,7 @@ void DisplayServerOSX::window_resize(WindowID p_window, int p_width, int p_heigh
#endif
}
-bool DisplayServerOSX::has_feature(Feature p_feature) const {
+bool DisplayServerMacOS::has_feature(Feature p_feature) const {
switch (p_feature) {
case FEATURE_GLOBAL_MENU:
case FEATURE_SUBWINDOWS:
@@ -709,16 +709,16 @@ bool DisplayServerOSX::has_feature(Feature p_feature) const {
return false;
}
-String DisplayServerOSX::get_name() const {
- return "OSX";
+String DisplayServerMacOS::get_name() const {
+ return "macOS";
}
-void DisplayServerOSX::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -731,17 +731,17 @@ void DisplayServerOSX::global_menu_add_item(const String &p_menu_root, const Str
obj->checkable_type = CHECKABLE_TYPE_NONE;
obj->max_states = 0;
obj->state = 0;
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -754,17 +754,17 @@ void DisplayServerOSX::global_menu_add_check_item(const String &p_menu_root, con
obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX;
obj->max_states = 0;
obj->state = 0;
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -786,17 +786,17 @@ void DisplayServerOSX::global_menu_add_icon_item(const String &p_menu_root, cons
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
}
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -818,17 +818,17 @@ void DisplayServerOSX::global_menu_add_icon_check_item(const String &p_menu_root
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
}
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -841,17 +841,17 @@ void DisplayServerOSX::global_menu_add_radio_check_item(const String &p_menu_roo
obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON;
obj->max_states = 0;
obj->state = 0;
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -873,17 +873,17 @@ void DisplayServerOSX::global_menu_add_icon_radio_check_item(const String &p_men
obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS);
[menu_item setImage:_convert_to_nsimg(obj->img)];
}
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
+void DisplayServerMacOS::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
if (menu) {
- String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK);
NSMenuItem *menu_item;
if (p_index != -1) {
menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index];
@@ -896,12 +896,12 @@ void DisplayServerOSX::global_menu_add_multistate_item(const String &p_menu_root
obj->checkable_type = CHECKABLE_TYPE_NONE;
obj->max_states = p_max_states;
obj->state = p_default_state;
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)];
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)];
[menu_item setRepresentedObject:obj];
}
}
-void DisplayServerOSX::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index) {
+void DisplayServerMacOS::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -926,7 +926,7 @@ void DisplayServerOSX::global_menu_add_submenu_item(const String &p_menu_root, c
}
}
-void DisplayServerOSX::global_menu_add_separator(const String &p_menu_root, int p_index) {
+void DisplayServerMacOS::global_menu_add_separator(const String &p_menu_root, int p_index) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -939,7 +939,7 @@ void DisplayServerOSX::global_menu_add_separator(const String &p_menu_root, int
}
}
-int DisplayServerOSX::global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const {
+int DisplayServerMacOS::global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -950,7 +950,7 @@ int DisplayServerOSX::global_menu_get_item_index_from_text(const String &p_menu_
return -1;
}
-int DisplayServerOSX::global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const {
+int DisplayServerMacOS::global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -969,7 +969,7 @@ int DisplayServerOSX::global_menu_get_item_index_from_tag(const String &p_menu_r
return -1;
}
-bool DisplayServerOSX::global_menu_is_item_checked(const String &p_menu_root, int p_idx) const {
+bool DisplayServerMacOS::global_menu_is_item_checked(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -982,7 +982,7 @@ bool DisplayServerOSX::global_menu_is_item_checked(const String &p_menu_root, in
return false;
}
-bool DisplayServerOSX::global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const {
+bool DisplayServerMacOS::global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -998,7 +998,7 @@ bool DisplayServerOSX::global_menu_is_item_checkable(const String &p_menu_root,
return false;
}
-bool DisplayServerOSX::global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const {
+bool DisplayServerMacOS::global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1014,7 +1014,7 @@ bool DisplayServerOSX::global_menu_is_item_radio_checkable(const String &p_menu_
return false;
}
-Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_root, int p_idx) const {
+Callable DisplayServerMacOS::global_menu_get_item_callback(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1030,7 +1030,7 @@ Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_ro
return Callable();
}
-Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const {
+Variant DisplayServerMacOS::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1046,7 +1046,7 @@ Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, in
return Variant();
}
-String DisplayServerOSX::global_menu_get_item_text(const String &p_menu_root, int p_idx) const {
+String DisplayServerMacOS::global_menu_get_item_text(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1059,7 +1059,7 @@ String DisplayServerOSX::global_menu_get_item_text(const String &p_menu_root, in
return String();
}
-String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const {
+String DisplayServerMacOS::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1079,7 +1079,7 @@ String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root,
return String();
}
-Key DisplayServerOSX::global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const {
+Key DisplayServerMacOS::global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1110,7 +1110,7 @@ Key DisplayServerOSX::global_menu_get_item_accelerator(const String &p_menu_root
return Key::NONE;
}
-bool DisplayServerOSX::global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const {
+bool DisplayServerMacOS::global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1123,7 +1123,7 @@ bool DisplayServerOSX::global_menu_is_item_disabled(const String &p_menu_root, i
return false;
}
-String DisplayServerOSX::global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const {
+String DisplayServerMacOS::global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1136,7 +1136,7 @@ String DisplayServerOSX::global_menu_get_item_tooltip(const String &p_menu_root,
return String();
}
-int DisplayServerOSX::global_menu_get_item_state(const String &p_menu_root, int p_idx) const {
+int DisplayServerMacOS::global_menu_get_item_state(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1152,7 +1152,7 @@ int DisplayServerOSX::global_menu_get_item_state(const String &p_menu_root, int
return 0;
}
-int DisplayServerOSX::global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const {
+int DisplayServerMacOS::global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1168,7 +1168,7 @@ int DisplayServerOSX::global_menu_get_item_max_states(const String &p_menu_root,
return 0;
}
-Ref<Texture2D> DisplayServerOSX::global_menu_get_item_icon(const String &p_menu_root, int p_idx) const {
+Ref<Texture2D> DisplayServerMacOS::global_menu_get_item_icon(const String &p_menu_root, int p_idx) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1178,10 +1178,7 @@ Ref<Texture2D> DisplayServerOSX::global_menu_get_item_icon(const String &p_menu_
GodotMenuItem *obj = [menu_item representedObject];
if (obj) {
if (obj->img.is_valid()) {
- Ref<ImageTexture> txt;
- txt.instantiate();
- txt->create_from_image(obj->img);
- return txt;
+ return ImageTexture::create_from_image(obj->img);
}
}
}
@@ -1189,7 +1186,7 @@ Ref<Texture2D> DisplayServerOSX::global_menu_get_item_icon(const String &p_menu_
return Ref<Texture2D>();
}
-void DisplayServerOSX::global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked) {
+void DisplayServerMacOS::global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1208,7 +1205,7 @@ void DisplayServerOSX::global_menu_set_item_checked(const String &p_menu_root, i
}
}
-void DisplayServerOSX::global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
+void DisplayServerMacOS::global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1224,7 +1221,7 @@ void DisplayServerOSX::global_menu_set_item_checkable(const String &p_menu_root,
}
}
-void DisplayServerOSX::global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
+void DisplayServerMacOS::global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1240,7 +1237,7 @@ void DisplayServerOSX::global_menu_set_item_radio_checkable(const String &p_menu
}
}
-void DisplayServerOSX::global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback) {
+void DisplayServerMacOS::global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1256,7 +1253,7 @@ void DisplayServerOSX::global_menu_set_item_callback(const String &p_menu_root,
}
}
-void DisplayServerOSX::global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) {
+void DisplayServerMacOS::global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1272,7 +1269,7 @@ void DisplayServerOSX::global_menu_set_item_tag(const String &p_menu_root, int p
}
}
-void DisplayServerOSX::global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text) {
+void DisplayServerMacOS::global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1287,7 +1284,7 @@ void DisplayServerOSX::global_menu_set_item_text(const String &p_menu_root, int
}
}
-void DisplayServerOSX::global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu) {
+void DisplayServerMacOS::global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1311,7 +1308,7 @@ void DisplayServerOSX::global_menu_set_item_submenu(const String &p_menu_root, i
}
}
-void DisplayServerOSX::global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode) {
+void DisplayServerMacOS::global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1321,14 +1318,14 @@ void DisplayServerOSX::global_menu_set_item_accelerator(const String &p_menu_roo
}
NSMenuItem *menu_item = [menu itemAtIndex:p_idx];
if (menu_item) {
- [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_keycode)];
- String keycode = KeyMappingOSX::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK);
+ [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_keycode)];
+ String keycode = KeyMappingMacOS::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK);
[menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]];
}
}
}
-void DisplayServerOSX::global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled) {
+void DisplayServerMacOS::global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1343,7 +1340,7 @@ void DisplayServerOSX::global_menu_set_item_disabled(const String &p_menu_root,
}
}
-void DisplayServerOSX::global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip) {
+void DisplayServerMacOS::global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1358,7 +1355,7 @@ void DisplayServerOSX::global_menu_set_item_tooltip(const String &p_menu_root, i
}
}
-void DisplayServerOSX::global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state) {
+void DisplayServerMacOS::global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1376,7 +1373,7 @@ void DisplayServerOSX::global_menu_set_item_state(const String &p_menu_root, int
}
}
-void DisplayServerOSX::global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states) {
+void DisplayServerMacOS::global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1394,7 +1391,7 @@ void DisplayServerOSX::global_menu_set_item_max_states(const String &p_menu_root
}
}
-void DisplayServerOSX::global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon) {
+void DisplayServerMacOS::global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1421,7 +1418,7 @@ void DisplayServerOSX::global_menu_set_item_icon(const String &p_menu_root, int
}
}
-int DisplayServerOSX::global_menu_get_item_count(const String &p_menu_root) const {
+int DisplayServerMacOS::global_menu_get_item_count(const String &p_menu_root) const {
_THREAD_SAFE_METHOD_
const NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1432,7 +1429,7 @@ int DisplayServerOSX::global_menu_get_item_count(const String &p_menu_root) cons
}
}
-void DisplayServerOSX::global_menu_remove_item(const String &p_menu_root, int p_idx) {
+void DisplayServerMacOS::global_menu_remove_item(const String &p_menu_root, int p_idx) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1444,7 +1441,7 @@ void DisplayServerOSX::global_menu_remove_item(const String &p_menu_root, int p_
}
}
-void DisplayServerOSX::global_menu_clear(const String &p_menu_root) {
+void DisplayServerMacOS::global_menu_clear(const String &p_menu_root) {
_THREAD_SAFE_METHOD_
NSMenu *menu = _get_menu_root(p_menu_root);
@@ -1458,42 +1455,42 @@ void DisplayServerOSX::global_menu_clear(const String &p_menu_root) {
}
}
-bool DisplayServerOSX::tts_is_speaking() const {
+bool DisplayServerMacOS::tts_is_speaking() const {
ERR_FAIL_COND_V(!tts, false);
return [tts isSpeaking];
}
-bool DisplayServerOSX::tts_is_paused() const {
+bool DisplayServerMacOS::tts_is_paused() const {
ERR_FAIL_COND_V(!tts, false);
return [tts isPaused];
}
-Array DisplayServerOSX::tts_get_voices() const {
+Array DisplayServerMacOS::tts_get_voices() const {
ERR_FAIL_COND_V(!tts, Array());
return [tts getVoices];
}
-void DisplayServerOSX::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
+void DisplayServerMacOS::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
ERR_FAIL_COND(!tts);
[tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt];
}
-void DisplayServerOSX::tts_pause() {
+void DisplayServerMacOS::tts_pause() {
ERR_FAIL_COND(!tts);
[tts pauseSpeaking];
}
-void DisplayServerOSX::tts_resume() {
+void DisplayServerMacOS::tts_resume() {
ERR_FAIL_COND(!tts);
[tts resumeSpeaking];
}
-void DisplayServerOSX::tts_stop() {
+void DisplayServerMacOS::tts_stop() {
ERR_FAIL_COND(!tts);
[tts stopSpeaking];
}
-Error DisplayServerOSX::dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) {
+Error DisplayServerMacOS::dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) {
_THREAD_SAFE_METHOD_
NSAlert *window = [[NSAlert alloc] init];
@@ -1531,7 +1528,7 @@ Error DisplayServerOSX::dialog_show(String p_title, String p_description, Vector
return OK;
}
-Error DisplayServerOSX::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) {
+Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) {
_THREAD_SAFE_METHOD_
NSAlert *window = [[NSAlert alloc] init];
@@ -1563,7 +1560,7 @@ Error DisplayServerOSX::dialog_input_text(String p_title, String p_description,
return OK;
}
-void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
+void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
_THREAD_SAFE_METHOD_
if (p_mode == mouse_mode) {
@@ -1618,11 +1615,11 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
}
}
-DisplayServer::MouseMode DisplayServerOSX::mouse_get_mode() const {
+DisplayServer::MouseMode DisplayServerMacOS::mouse_get_mode() const {
return mouse_mode;
}
-bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp) {
+bool DisplayServerMacOS::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp) {
_THREAD_SAFE_METHOD_
if (ignore_warp) {
@@ -1644,7 +1641,7 @@ bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSP
List<WarpEvent>::Element *F = warp_events.front();
while (F) {
if (F->get().timestamp < p_timestamp) {
- List<DisplayServerOSX::WarpEvent>::Element *E = F;
+ List<DisplayServerMacOS::WarpEvent>::Element *E = F;
r_delta.x -= E->get().delta.x;
r_delta.y -= E->get().delta.y;
F = F->next();
@@ -1672,7 +1669,7 @@ bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSP
// Save warp data.
last_warp = [[NSProcessInfo processInfo] systemUptime];
- DisplayServerOSX::WarpEvent ev;
+ DisplayServerMacOS::WarpEvent ev;
ev.timestamp = last_warp;
ev.delta = r_delta;
warp_events.push_back(ev);
@@ -1681,7 +1678,7 @@ bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSP
return false;
}
-void DisplayServerOSX::warp_mouse(const Point2i &p_position) {
+void DisplayServerMacOS::warp_mouse(const Point2i &p_position) {
_THREAD_SAFE_METHOD_
if (mouse_mode != MOUSE_MODE_CAPTURED) {
@@ -1708,7 +1705,7 @@ void DisplayServerOSX::warp_mouse(const Point2i &p_position) {
}
}
-Point2i DisplayServerOSX::mouse_get_position() const {
+Point2i DisplayServerMacOS::mouse_get_position() const {
_THREAD_SAFE_METHOD_
const NSPoint mouse_pos = [NSEvent mouseLocation];
@@ -1727,15 +1724,15 @@ Point2i DisplayServerOSX::mouse_get_position() const {
return Vector2i();
}
-void DisplayServerOSX::mouse_set_button_state(MouseButton p_state) {
+void DisplayServerMacOS::mouse_set_button_state(MouseButton p_state) {
last_button_state = p_state;
}
-MouseButton DisplayServerOSX::mouse_get_button_state() const {
+MouseButton DisplayServerMacOS::mouse_get_button_state() const {
return last_button_state;
}
-void DisplayServerOSX::clipboard_set(const String &p_text) {
+void DisplayServerMacOS::clipboard_set(const String &p_text) {
_THREAD_SAFE_METHOD_
NSString *copiedString = [NSString stringWithUTF8String:p_text.utf8().get_data()];
@@ -1746,7 +1743,7 @@ void DisplayServerOSX::clipboard_set(const String &p_text) {
[pasteboard writeObjects:copiedStringArray];
}
-String DisplayServerOSX::clipboard_get() const {
+String DisplayServerMacOS::clipboard_get() const {
_THREAD_SAFE_METHOD_
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
@@ -1767,14 +1764,14 @@ String DisplayServerOSX::clipboard_get() const {
return ret;
}
-int DisplayServerOSX::get_screen_count() const {
+int DisplayServerMacOS::get_screen_count() const {
_THREAD_SAFE_METHOD_
NSArray *screenArray = [NSScreen screens];
return [screenArray count];
}
-Point2i DisplayServerOSX::screen_get_position(int p_screen) const {
+Point2i DisplayServerMacOS::screen_get_position(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1788,7 +1785,7 @@ Point2i DisplayServerOSX::screen_get_position(int p_screen) const {
return position;
}
-Size2i DisplayServerOSX::screen_get_size(int p_screen) const {
+Size2i DisplayServerMacOS::screen_get_size(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1805,7 +1802,7 @@ Size2i DisplayServerOSX::screen_get_size(int p_screen) const {
return Size2i();
}
-int DisplayServerOSX::screen_get_dpi(int p_screen) const {
+int DisplayServerMacOS::screen_get_dpi(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1829,7 +1826,7 @@ int DisplayServerOSX::screen_get_dpi(int p_screen) const {
return 72;
}
-float DisplayServerOSX::screen_get_scale(int p_screen) const {
+float DisplayServerMacOS::screen_get_scale(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1847,14 +1844,14 @@ float DisplayServerOSX::screen_get_scale(int p_screen) const {
return 1.f;
}
-float DisplayServerOSX::screen_get_max_scale() const {
+float DisplayServerMacOS::screen_get_max_scale() const {
_THREAD_SAFE_METHOD_
// Note: Do not update max display scale on screen configuration change, existing editor windows can't be rescaled on the fly.
return display_max_scale;
}
-Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
+Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1876,7 +1873,7 @@ Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
return Rect2i();
}
-float DisplayServerOSX::screen_get_refresh_rate(int p_screen) const {
+float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -1894,7 +1891,7 @@ float DisplayServerOSX::screen_get_refresh_rate(int p_screen) const {
return SCREEN_REFRESH_RATE_FALLBACK;
}
-Vector<DisplayServer::WindowID> DisplayServerOSX::get_window_list() const {
+Vector<DisplayServer::WindowID> DisplayServerMacOS::get_window_list() const {
_THREAD_SAFE_METHOD_
Vector<int> ret;
@@ -1904,7 +1901,7 @@ Vector<DisplayServer::WindowID> DisplayServerOSX::get_window_list() const {
return ret;
}
-DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
WindowID id = _create_window(p_mode, p_vsync_mode, p_rect);
@@ -1917,7 +1914,7 @@ DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, V
return id;
}
-void DisplayServerOSX::show_window(WindowID p_id) {
+void DisplayServerMacOS::show_window(WindowID p_id) {
WindowData &wd = windows[p_id];
popup_open(p_id);
@@ -1928,7 +1925,7 @@ void DisplayServerOSX::show_window(WindowID p_id) {
}
}
-void DisplayServerOSX::delete_sub_window(WindowID p_id) {
+void DisplayServerMacOS::delete_sub_window(WindowID p_id) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_id));
@@ -1940,7 +1937,7 @@ void DisplayServerOSX::delete_sub_window(WindowID p_id) {
[wd.window_object close];
}
-void DisplayServerOSX::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1948,7 +1945,7 @@ void DisplayServerOSX::window_set_rect_changed_callback(const Callable &p_callab
wd.rect_changed_callback = p_callable;
}
-void DisplayServerOSX::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1956,7 +1953,7 @@ void DisplayServerOSX::window_set_window_event_callback(const Callable &p_callab
wd.event_callback = p_callable;
}
-void DisplayServerOSX::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1964,21 +1961,21 @@ void DisplayServerOSX::window_set_input_event_callback(const Callable &p_callabl
wd.input_event_callback = p_callable;
}
-void DisplayServerOSX::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
wd.input_text_callback = p_callable;
}
-void DisplayServerOSX::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerMacOS::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
wd.drop_files_callback = p_callable;
}
-void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window) {
+void DisplayServerMacOS::window_set_title(const String &p_title, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1987,7 +1984,7 @@ void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window
[wd.window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]];
}
-void DisplayServerOSX::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {
+void DisplayServerMacOS::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1996,7 +1993,7 @@ void DisplayServerOSX::window_set_mouse_passthrough(const Vector<Vector2> &p_reg
wd.mpath = p_region;
}
-int DisplayServerOSX::window_get_current_screen(WindowID p_window) const {
+int DisplayServerMacOS::window_get_current_screen(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), -1);
const WindowData &wd = windows[p_window];
@@ -2005,12 +2002,16 @@ int DisplayServerOSX::window_get_current_screen(WindowID p_window) const {
return (index == NSNotFound) ? 0 : index;
}
-void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window) {
+void DisplayServerMacOS::window_set_current_screen(int p_screen, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
+ if (window_get_current_screen(p_window) == p_screen) {
+ return;
+ }
+
bool was_fullscreen = false;
if (wd.fullscreen) {
// Temporary exit fullscreen mode to move window.
@@ -2027,7 +2028,7 @@ void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window
}
}
-void DisplayServerOSX::window_set_exclusive(WindowID p_window, bool p_exclusive) {
+void DisplayServerMacOS::window_set_exclusive(WindowID p_window, bool p_exclusive) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
@@ -2045,7 +2046,7 @@ void DisplayServerOSX::window_set_exclusive(WindowID p_window, bool p_exclusive)
}
}
-Point2i DisplayServerOSX::window_get_position(WindowID p_window) const {
+Point2i DisplayServerMacOS::window_get_position(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Point2i());
@@ -2068,7 +2069,7 @@ Point2i DisplayServerOSX::window_get_position(WindowID p_window) const {
return pos;
}
-void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p_window) {
+void DisplayServerMacOS::window_set_position(const Point2i &p_position, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2096,7 +2097,7 @@ void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p
update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
}
-void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent) {
+void DisplayServerMacOS::window_set_transient(WindowID p_window, WindowID p_parent) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(p_window == p_parent);
@@ -2135,7 +2136,7 @@ void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent
}
}
-void DisplayServerOSX::window_set_max_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerMacOS::window_set_max_size(const Size2i p_size, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2155,7 +2156,7 @@ void DisplayServerOSX::window_set_max_size(const Size2i p_size, WindowID p_windo
}
}
-Size2i DisplayServerOSX::window_get_max_size(WindowID p_window) const {
+Size2i DisplayServerMacOS::window_get_max_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -2163,7 +2164,7 @@ Size2i DisplayServerOSX::window_get_max_size(WindowID p_window) const {
return wd.max_size;
}
-void DisplayServerOSX::window_set_min_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerMacOS::window_set_min_size(const Size2i p_size, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2183,7 +2184,7 @@ void DisplayServerOSX::window_set_min_size(const Size2i p_size, WindowID p_windo
}
}
-Size2i DisplayServerOSX::window_get_min_size(WindowID p_window) const {
+Size2i DisplayServerMacOS::window_get_min_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -2192,7 +2193,7 @@ Size2i DisplayServerOSX::window_get_min_size(WindowID p_window) const {
return wd.min_size;
}
-void DisplayServerOSX::window_set_size(const Size2i p_size, WindowID p_window) {
+void DisplayServerMacOS::window_set_size(const Size2i p_size, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2216,7 +2217,7 @@ void DisplayServerOSX::window_set_size(const Size2i p_size, WindowID p_window) {
_update_window_style(wd);
}
-Size2i DisplayServerOSX::window_get_size(WindowID p_window) const {
+Size2i DisplayServerMacOS::window_get_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -2224,7 +2225,7 @@ Size2i DisplayServerOSX::window_get_size(WindowID p_window) const {
return wd.size;
}
-Size2i DisplayServerOSX::window_get_real_size(WindowID p_window) const {
+Size2i DisplayServerMacOS::window_get_real_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -2233,7 +2234,7 @@ Size2i DisplayServerOSX::window_get_real_size(WindowID p_window) const {
return Size2i(frame.size.width, frame.size.height) * screen_get_max_scale();
}
-void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) {
+void DisplayServerMacOS::window_set_mode(WindowMode p_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2302,7 +2303,7 @@ void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) {
}
}
-DisplayServer::WindowMode DisplayServerOSX::window_get_mode(WindowID p_window) const {
+DisplayServer::WindowMode DisplayServerMacOS::window_get_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), WINDOW_MODE_WINDOWED);
@@ -2324,11 +2325,11 @@ DisplayServer::WindowMode DisplayServerOSX::window_get_mode(WindowID p_window) c
return WINDOW_MODE_WINDOWED;
}
-bool DisplayServerOSX::window_is_maximize_allowed(WindowID p_window) const {
+bool DisplayServerMacOS::window_is_maximize_allowed(WindowID p_window) const {
return true;
}
-void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
+void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2403,7 +2404,7 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
}
}
-bool DisplayServerOSX::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
+bool DisplayServerMacOS::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), false);
@@ -2439,12 +2440,12 @@ bool DisplayServerOSX::window_get_flag(WindowFlags p_flag, WindowID p_window) co
return false;
}
-void DisplayServerOSX::window_request_attention(WindowID p_window) {
+void DisplayServerMacOS::window_request_attention(WindowID p_window) {
// It's app global, ignore window id.
[NSApp requestUserAttention:NSCriticalRequest];
}
-void DisplayServerOSX::window_move_to_foreground(WindowID p_window) {
+void DisplayServerMacOS::window_move_to_foreground(WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2458,11 +2459,11 @@ void DisplayServerOSX::window_move_to_foreground(WindowID p_window) {
}
}
-bool DisplayServerOSX::window_can_draw(WindowID p_window) const {
+bool DisplayServerMacOS::window_can_draw(WindowID p_window) const {
return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED;
}
-bool DisplayServerOSX::can_any_window_draw() const {
+bool DisplayServerMacOS::can_any_window_draw() const {
_THREAD_SAFE_METHOD_
for (const KeyValue<WindowID, WindowData> &E : windows) {
@@ -2473,7 +2474,7 @@ bool DisplayServerOSX::can_any_window_draw() const {
return false;
}
-void DisplayServerOSX::window_set_ime_active(const bool p_active, WindowID p_window) {
+void DisplayServerMacOS::window_set_ime_active(const bool p_active, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2486,7 +2487,7 @@ void DisplayServerOSX::window_set_ime_active(const bool p_active, WindowID p_win
}
}
-void DisplayServerOSX::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
+void DisplayServerMacOS::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -2495,7 +2496,7 @@ void DisplayServerOSX::window_set_ime_position(const Point2i &p_pos, WindowID p_
wd.im_position = p_pos;
}
-DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Point2i &p_position) const {
+DisplayServer::WindowID DisplayServerMacOS::get_window_at_screen_position(const Point2i &p_position) const {
Point2i position = p_position;
position.y *= -1;
position += _get_screens_origin();
@@ -2510,7 +2511,7 @@ 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 {
+int64_t DisplayServerMacOS::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: {
@@ -2528,27 +2529,27 @@ int64_t DisplayServerOSX::window_get_native_handle(HandleType p_handle_type, Win
}
}
-void DisplayServerOSX::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
+void DisplayServerMacOS::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
windows[p_window].instance_id = p_instance;
}
-ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) const {
+ObjectID DisplayServerMacOS::window_get_attached_instance_id(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), ObjectID());
return windows[p_window].instance_id;
}
-void DisplayServerOSX::gl_window_make_current(DisplayServer::WindowID p_window_id) {
+void DisplayServerMacOS::gl_window_make_current(DisplayServer::WindowID p_window_id) {
#if defined(GLES3_ENABLED)
gl_manager->window_make_current(p_window_id);
#endif
}
-void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+void DisplayServerMacOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(GLES3_ENABLED)
if (gl_manager) {
@@ -2562,7 +2563,7 @@ void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mo
#endif
}
-DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const {
+DisplayServer::VSyncMode DisplayServerMacOS::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
#if defined(GLES3_ENABLED)
if (gl_manager) {
@@ -2577,15 +2578,15 @@ DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_wind
return DisplayServer::VSYNC_ENABLED;
}
-Point2i DisplayServerOSX::ime_get_selection() const {
+Point2i DisplayServerMacOS::ime_get_selection() const {
return im_selection;
}
-String DisplayServerOSX::ime_get_text() const {
+String DisplayServerMacOS::ime_get_text() const {
return im_text;
}
-void DisplayServerOSX::cursor_update_shape() {
+void DisplayServerMacOS::cursor_update_shape() {
_THREAD_SAFE_METHOD_
if (cursors[cursor_shape] != nullptr) {
@@ -2649,7 +2650,7 @@ void DisplayServerOSX::cursor_update_shape() {
}
}
-void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) {
+void DisplayServerMacOS::cursor_set_shape(CursorShape p_shape) {
_THREAD_SAFE_METHOD_
ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
@@ -2667,11 +2668,11 @@ void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) {
cursor_update_shape();
}
-DisplayServerOSX::CursorShape DisplayServerOSX::cursor_get_shape() const {
+DisplayServerMacOS::CursorShape DisplayServerMacOS::cursor_get_shape() const {
return cursor_shape;
}
-void DisplayServerOSX::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
_THREAD_SAFE_METHOD_
if (p_cursor.is_valid()) {
@@ -2783,20 +2784,20 @@ void DisplayServerOSX::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu
}
}
-bool DisplayServerOSX::get_swap_cancel_ok() {
+bool DisplayServerMacOS::get_swap_cancel_ok() {
return false;
}
-int DisplayServerOSX::keyboard_get_layout_count() const {
+int DisplayServerMacOS::keyboard_get_layout_count() const {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
return kbd_layouts.size();
}
-void DisplayServerOSX::keyboard_set_current_layout(int p_index) {
+void DisplayServerMacOS::keyboard_set_current_layout(int p_index) {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
ERR_FAIL_INDEX(p_index, kbd_layouts.size());
@@ -2824,44 +2825,44 @@ void DisplayServerOSX::keyboard_set_current_layout(int p_index) {
}
}
-int DisplayServerOSX::keyboard_get_current_layout() const {
+int DisplayServerMacOS::keyboard_get_current_layout() const {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
return current_layout;
}
-String DisplayServerOSX::keyboard_get_layout_language(int p_index) const {
+String DisplayServerMacOS::keyboard_get_layout_language(int p_index) const {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), "");
return kbd_layouts[p_index].code;
}
-String DisplayServerOSX::keyboard_get_layout_name(int p_index) const {
+String DisplayServerMacOS::keyboard_get_layout_name(int p_index) const {
if (keyboard_layout_dirty) {
- const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts();
+ const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts();
}
ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), "");
return kbd_layouts[p_index].name;
}
-Key DisplayServerOSX::keyboard_get_keycode_from_physical(Key p_keycode) const {
+Key DisplayServerMacOS::keyboard_get_keycode_from_physical(Key p_keycode) const {
if (p_keycode == Key::PAUSE) {
return p_keycode;
}
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK;
- unsigned int osx_keycode = KeyMappingOSX::unmap_key((Key)keycode_no_mod);
- return (Key)(KeyMappingOSX::remap_key(osx_keycode, 0) | modifiers);
+ unsigned int macos_keycode = KeyMappingMacOS::unmap_key((Key)keycode_no_mod);
+ return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0) | modifiers);
}
-void DisplayServerOSX::process_events() {
+void DisplayServerMacOS::process_events() {
_THREAD_SAFE_METHOD_
while (true) {
@@ -2904,7 +2905,7 @@ void DisplayServerOSX::process_events() {
}
}
-void DisplayServerOSX::force_process_and_drop_events() {
+void DisplayServerMacOS::force_process_and_drop_events() {
_THREAD_SAFE_METHOD_
drop_events = true;
@@ -2912,19 +2913,21 @@ void DisplayServerOSX::force_process_and_drop_events() {
drop_events = false;
}
-void DisplayServerOSX::release_rendering_thread() {
+void DisplayServerMacOS::release_rendering_thread() {
}
-void DisplayServerOSX::make_rendering_thread() {
+void DisplayServerMacOS::make_rendering_thread() {
}
-void DisplayServerOSX::swap_buffers() {
+void DisplayServerMacOS::swap_buffers() {
#if defined(GLES3_ENABLED)
- gl_manager->swap_buffers();
+ if (gl_manager) {
+ gl_manager->swap_buffers();
+ }
#endif
}
-void DisplayServerOSX::set_native_icon(const String &p_filename) {
+void DisplayServerMacOS::set_native_icon(const String &p_filename) {
_THREAD_SAFE_METHOD_
Ref<FileAccess> f = FileAccess::open(p_filename, FileAccess::READ);
@@ -2944,7 +2947,7 @@ void DisplayServerOSX::set_native_icon(const String &p_filename) {
[NSApp setApplicationIconImage:icon];
}
-void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
+void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) {
_THREAD_SAFE_METHOD_
Ref<Image> img = p_icon;
@@ -2983,15 +2986,15 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
[NSApp setApplicationIconImage:nsimg];
}
-DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.", "Unable to initialize Video driver");
}
return ds;
}
-Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
+Vector<String> DisplayServerMacOS::get_rendering_drivers_func() {
Vector<String> drivers;
#if defined(VULKAN_ENABLED)
@@ -3004,11 +3007,11 @@ Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
return drivers;
}
-void DisplayServerOSX::register_osx_driver() {
- register_create_function("osx", create_func, get_rendering_drivers_func);
+void DisplayServerMacOS::register_macos_driver() {
+ register_create_function("macos", create_func, get_rendering_drivers_func);
}
-DisplayServer::WindowID DisplayServerOSX::window_get_active_popup() const {
+DisplayServer::WindowID DisplayServerMacOS::window_get_active_popup() const {
const List<WindowID>::Element *E = popup_list.back();
if (E) {
return E->get();
@@ -3017,7 +3020,7 @@ DisplayServer::WindowID DisplayServerOSX::window_get_active_popup() const {
}
}
-void DisplayServerOSX::window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) {
+void DisplayServerMacOS::window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -3025,7 +3028,7 @@ void DisplayServerOSX::window_set_popup_safe_rect(WindowID p_window, const Rect2
wd.parent_safe_rect = p_rect;
}
-Rect2i DisplayServerOSX::window_get_popup_safe_rect(WindowID p_window) const {
+Rect2i DisplayServerMacOS::window_get_popup_safe_rect(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Rect2i());
@@ -3033,7 +3036,7 @@ Rect2i DisplayServerOSX::window_get_popup_safe_rect(WindowID p_window) const {
return wd.parent_safe_rect;
}
-void DisplayServerOSX::popup_open(WindowID p_window) {
+void DisplayServerMacOS::popup_open(WindowID p_window) {
_THREAD_SAFE_METHOD_
WindowData &wd = windows[p_window];
@@ -3051,7 +3054,7 @@ void DisplayServerOSX::popup_open(WindowID p_window) {
}
}
if (C) {
- send_window_event(windows[C->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ send_window_event(windows[C->get()], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
}
if (was_empty && popup_list.is_empty()) {
@@ -3063,7 +3066,7 @@ void DisplayServerOSX::popup_open(WindowID p_window) {
}
}
-void DisplayServerOSX::popup_close(WindowID p_window) {
+void DisplayServerMacOS::popup_close(WindowID p_window) {
_THREAD_SAFE_METHOD_
bool was_empty = popup_list.is_empty();
@@ -3073,7 +3076,7 @@ void DisplayServerOSX::popup_close(WindowID p_window) {
WindowID win_id = E->get();
popup_list.erase(E);
- send_window_event(windows[win_id], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ send_window_event(windows[win_id], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
E = F;
}
if (!was_empty && popup_list.is_empty()) {
@@ -3082,7 +3085,7 @@ void DisplayServerOSX::popup_close(WindowID p_window) {
}
}
-bool DisplayServerOSX::mouse_process_popups(bool p_close) {
+bool DisplayServerMacOS::mouse_process_popups(bool p_close) {
_THREAD_SAFE_METHOD_
bool was_empty = popup_list.is_empty();
@@ -3091,7 +3094,7 @@ bool DisplayServerOSX::mouse_process_popups(bool p_close) {
// Close all popups.
List<WindowID>::Element *E = popup_list.front();
if (E) {
- send_window_event(windows[E->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ send_window_event(windows[E->get()], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
closed = true;
}
if (!was_empty) {
@@ -3123,7 +3126,7 @@ bool DisplayServerOSX::mouse_process_popups(bool p_close) {
}
}
if (C) {
- send_window_event(windows[C->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ send_window_event(windows[C->get()], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
closed = true;
}
if (!was_empty && popup_list.is_empty()) {
@@ -3134,7 +3137,7 @@ bool DisplayServerOSX::mouse_process_popups(bool p_close) {
return closed;
}
-DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -3161,7 +3164,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
CGDisplayRegisterReconfigurationCallback(_displays_arrangement_changed, nullptr);
// Init TTS
- tts = [[TTS_OSX alloc] init];
+ tts = [[TTS_MacOS alloc] init];
NSMenuItem *menu_item;
NSString *title;
@@ -3215,8 +3218,8 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
- GLManager_OSX::ContextType opengl_api_type = GLManager_OSX::GLES_3_0_COMPATIBLE;
- gl_manager = memnew(GLManager_OSX(opengl_api_type));
+ GLManager_MacOS::ContextType opengl_api_type = GLManager_MacOS::GLES_3_0_COMPATIBLE;
+ gl_manager = memnew(GLManager_MacOS(opengl_api_type));
if (gl_manager->initialize() != OK) {
memdelete(gl_manager);
gl_manager = nullptr;
@@ -3228,7 +3231,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
#endif
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
- context_vulkan = memnew(VulkanContextOSX);
+ context_vulkan = memnew(VulkanContextMacOS);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
@@ -3265,7 +3268,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
#endif
}
-DisplayServerOSX::~DisplayServerOSX() {
+DisplayServerMacOS::~DisplayServerMacOS() {
// Destroy all windows.
for (HashMap<WindowID, WindowData>::Iterator E = windows.begin(); E;) {
HashMap<WindowID, WindowData>::Iterator F = E;
diff --git a/platform/osx/export/codesign.cpp b/platform/macos/export/codesign.cpp
index fd044c00cc..fd044c00cc 100644
--- a/platform/osx/export/codesign.cpp
+++ b/platform/macos/export/codesign.cpp
diff --git a/platform/osx/export/codesign.h b/platform/macos/export/codesign.h
index 3a08c0ea86..3a08c0ea86 100644
--- a/platform/osx/export/codesign.h
+++ b/platform/macos/export/codesign.h
diff --git a/platform/osx/export/export.cpp b/platform/macos/export/export.cpp
index bd35b39e9e..ff7457081f 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/macos/export/export.cpp
@@ -32,11 +32,11 @@
#include "export_plugin.h"
-void register_osx_exporter() {
+void register_macos_exporter() {
EDITOR_DEF("export/macos/force_builtin_codesign", false);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::BOOL, "export/macos/force_builtin_codesign", PROPERTY_HINT_NONE));
- Ref<EditorExportPlatformOSX> platform;
+ Ref<EditorExportPlatformMacOS> platform;
platform.instantiate();
EditorExport::get_singleton()->add_export_platform(platform);
diff --git a/platform/iphone/export/export.h b/platform/macos/export/export.h
index adb3c23957..260c691209 100644
--- a/platform/iphone/export/export.h
+++ b/platform/macos/export/export.h
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef IPHONE_EXPORT_H
-#define IPHONE_EXPORT_H
+#ifndef MACOS_EXPORT_H
+#define MACOS_EXPORT_H
-void register_iphone_exporter();
+void register_macos_exporter();
-#endif // IPHONE_EXPORT_H
+#endif // MACOS_EXPORT_H
diff --git a/platform/osx/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp
index 7010709123..8cb69997d9 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/macos/export/export_plugin.cpp
@@ -37,7 +37,7 @@
#include "modules/modules_enabled.gen.h" // For regex.
-void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
+void EditorExportPlatformMacOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
if (p_preset->get("texture_format/s3tc")) {
r_features->push_back("s3tc");
}
@@ -51,7 +51,7 @@ void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset>
r_features->push_back("64");
}
-bool EditorExportPlatformOSX::get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const {
+bool EditorExportPlatformMacOS::get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const {
// These options are not supported by built-in codesign, used on non macOS host.
if (!OS::get_singleton()->has_feature("macos")) {
if (p_option == "codesign/identity" || p_option == "codesign/timestamp" || p_option == "codesign/hardened_runtime" || p_option == "codesign/custom_options" || p_option.begins_with("notarization/")) {
@@ -68,7 +68,7 @@ bool EditorExportPlatformOSX::get_export_option_visibility(const String &p_optio
return true;
}
-void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) {
+void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
@@ -214,7 +214,7 @@ void _rgba8_to_packbits_encode(int p_ch, int p_size, Vector<uint8_t> &p_source,
memcpy(&p_dest.write[ofs], result.ptr(), res_size);
}
-void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
+void EditorExportPlatformMacOS::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
Ref<ImageTexture> it = memnew(ImageTexture);
Vector<uint8_t> data;
@@ -252,7 +252,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
if (icon_infos[i].is_png) {
// Encode PNG icon.
- it->create_from_image(copy);
+ it->set_image(copy);
String path = EditorPaths::get_singleton()->get_cache_dir().plus_file("icon.png");
ResourceSaver::save(path, it);
@@ -320,7 +320,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
p_data = data;
}
-void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) {
+void EditorExportPlatformMacOS::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) {
String str;
String strnew;
str.parse_utf8((const char *)plist.ptr(), plist.size());
@@ -407,14 +407,14 @@ void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset
}
/**
- * If we're running the OSX version of the Godot editor we'll:
+ * If we're running the macOS version of the Godot editor we'll:
* - export our application bundle to a temporary folder
* - attempt to code sign it
* - and then wrap it up in a DMG
*/
-Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
-#ifdef OSX_ENABLED
+Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
+#ifdef MACOS_ENABLED
List<String> args;
args.push_back("altool");
@@ -468,7 +468,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset
return OK;
}
-Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn) {
+Error EditorExportPlatformMacOS::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn) {
bool force_builtin_codesign = EditorSettings::get_singleton()->get("export/macos/force_builtin_codesign");
bool ad_hoc = (p_preset->get("codesign/identity") == "" || p_preset->get("codesign/identity") == "-");
@@ -476,7 +476,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
print_verbose("using built-in codesign...");
#ifdef MODULE_REGEX_ENABLED
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
if (p_preset->get("codesign/timestamp") && p_warn) {
add_message(EXPORT_MESSAGE_INFO, TTR("Code Signing"), TTR("Timestamping is not compatible with ad-hoc signature, and was disabled!"));
}
@@ -566,9 +566,9 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
}
}
-Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path,
+Error EditorExportPlatformMacOS::_code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path,
const String &p_ent_path, bool p_should_error_on_non_code) {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
static Vector<String> extensions_to_sign;
if (extensions_to_sign.is_empty()) {
@@ -615,7 +615,7 @@ Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset
return OK;
}
-Error EditorExportPlatformOSX::_copy_and_sign_files(Ref<DirAccess> &dir_access, const String &p_src_path,
+Error EditorExportPlatformMacOS::_copy_and_sign_files(Ref<DirAccess> &dir_access, const String &p_src_path,
const String &p_in_app_path, bool p_sign_enabled,
const Ref<EditorExportPreset> &p_preset, const String &p_ent_path,
bool p_should_error_on_non_code_sign) {
@@ -644,14 +644,14 @@ Error EditorExportPlatformOSX::_copy_and_sign_files(Ref<DirAccess> &dir_access,
return err;
}
-Error EditorExportPlatformOSX::_export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin,
+Error EditorExportPlatformMacOS::_export_macos_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin,
const String &p_app_path_name, Ref<DirAccess> &dir_access,
bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset,
const String &p_ent_path) {
Error error{ OK };
- const Vector<String> &osx_plugins{ p_editor_export_plugin->get_osx_plugin_files() };
- for (int i = 0; i < osx_plugins.size(); ++i) {
- String src_path{ ProjectSettings::get_singleton()->globalize_path(osx_plugins[i]) };
+ const Vector<String> &macos_plugins{ p_editor_export_plugin->get_macos_plugin_files() };
+ for (int i = 0; i < macos_plugins.size(); ++i) {
+ String src_path{ ProjectSettings::get_singleton()->globalize_path(macos_plugins[i]) };
String path_in_app{ p_app_path_name + "/Contents/PlugIns/" + src_path.get_file() };
error = _copy_and_sign_files(dir_access, src_path, path_in_app, p_sign_enabled, p_preset, p_ent_path, false);
if (error != OK) {
@@ -661,7 +661,7 @@ Error EditorExportPlatformOSX::_export_osx_plugins_for(Ref<EditorExportPlugin> p
return error;
}
-Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) {
+Error EditorExportPlatformMacOS::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) {
List<String> args;
if (FileAccess::exists(p_dmg_path)) {
@@ -697,7 +697,7 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin
return OK;
}
-Error EditorExportPlatformOSX::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) {
+Error EditorExportPlatformMacOS::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE);
if (f.is_null()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), vformat(TTR("Could not open file \"%s\"."), p_path));
@@ -706,19 +706,30 @@ Error EditorExportPlatformOSX::_export_debug_script(const Ref<EditorExportPreset
f->store_line("#!/bin/sh");
f->store_line("echo -ne '\\033c\\033]0;" + p_app_name + "\\a'");
- f->store_line("function realpath() { python -c \"import os,sys; print(os.path.realpath(sys.argv[1]))\" \"$0\"; }");
- f->store_line("base_path=\"$(dirname \"$(realpath \"$0\")\")\"");
- f->store_line("\"$base_path/" + p_pkg_name + "\" \"$@\"");
+ f->store_line("");
+ f->store_line("function app_realpath() {");
+ f->store_line(" SOURCE=$1");
+ f->store_line(" while [ -h \"$SOURCE\" ]; do");
+ f->store_line(" DIR=$(dirname \"$SOURCE\")");
+ f->store_line(" SOURCE=$(readlink \"$SOURCE\")");
+ f->store_line(" [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE");
+ f->store_line(" done");
+ f->store_line(" echo \"$( cd -P \"$( dirname \"$SOURCE\" )\" >/dev/null 2>&1 && pwd )\"");
+ f->store_line("}");
+ f->store_line("");
+ f->store_line("BASE_PATH=\"$(app_realpath \"${BASH_SOURCE[0]}\")\"");
+ f->store_line("\"$BASE_PATH/" + p_pkg_name + "\" \"$@\"");
+ f->store_line("");
return OK;
}
-Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
String src_pkg_name;
- EditorProgress ep("export", "Exporting for OSX", 3, true);
+ EditorProgress ep("export", "Exporting for macOS", 3, true);
if (p_debug) {
src_pkg_name = p_preset->get("custom_template/debug");
@@ -728,7 +739,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (src_pkg_name.is_empty()) {
String err;
- src_pkg_name = find_export_template("osx.zip", &err);
+ src_pkg_name = find_export_template("macos.zip", &err);
if (src_pkg_name.is_empty()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found."));
return ERR_FILE_NOT_FOUND;
@@ -755,7 +766,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
int ret = unzGoToFirstFile(src_pkg_zip);
- String binary_to_use = "godot_osx_" + String(p_debug ? "debug" : "release") + ".64";
+ String binary_to_use = "godot_macos_" + String(p_debug ? "debug" : "release") + ".64";
String pkg_name;
if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") {
@@ -984,7 +995,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
unzCloseCurrentFile(src_pkg_zip);
// Write.
- file = file.replace_first("osx_template.app/", "");
+ file = file.replace_first("macos_template.app/", "");
if (((info.external_fa >> 16L) & 0120000) == 0120000) {
#ifndef UNIX_ENABLED
@@ -1053,19 +1064,19 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
if (data.size() > 0) {
- if (file.find("/data.mono.osx.64.release_debug/") != -1) {
+ if (file.find("/data.mono.macos.64.release_debug/") != -1) {
if (!p_debug) {
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release_debug/", "/GodotSharp/");
+ file = file.replace("/data.mono.macos.64.release_debug/", "/GodotSharp/");
}
- if (file.find("/data.mono.osx.64.release/") != -1) {
+ if (file.find("/data.mono.macos.64.release/") != -1) {
if (p_debug) {
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release/", "/GodotSharp/");
+ file = file.replace("/data.mono.macos.64.release/", "/GodotSharp/");
}
if (file.ends_with(".dylib")) {
@@ -1086,6 +1097,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
Ref<FileAccess> f = FileAccess::open(file, FileAccess::WRITE);
if (f.is_valid()) {
f->store_buffer(data.ptr(), data.size());
+ f.unref();
if (is_execute) {
// chmod with 0755 if the file is executable.
FileAccess::set_unix_permissions(file, 0755);
@@ -1298,7 +1310,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
bool ad_hoc = true;
if (err == OK) {
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
String sign_identity = p_preset->get("codesign/identity");
#else
String sign_identity = "-";
@@ -1329,7 +1341,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
Vector<Ref<EditorExportPlugin>> export_plugins{ EditorExport::get_singleton()->get_export_plugins() };
for (int i = 0; i < export_plugins.size(); ++i) {
- err = _export_osx_plugins_for(export_plugins[i], tmp_app_path_name, da, sign_enabled, p_preset, ent_path);
+ err = _export_macos_plugins_for(export_plugins[i], tmp_app_path_name, da, sign_enabled, p_preset, ent_path);
if (err != OK) {
break;
}
@@ -1386,7 +1398,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool noto_enabled = p_preset->get("notarization/enable");
if (err == OK && noto_enabled) {
if (export_format == "app") {
@@ -1419,7 +1431,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
return err;
}
-void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name) {
+void EditorExportPlatformMacOS::_zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name) {
String dir = p_folder.is_empty() ? p_root_path : p_root_path.plus_file(p_folder);
Ref<DirAccess> da = DirAccess::open(dir);
@@ -1536,7 +1548,7 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
da->list_dir_end();
}
-bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+bool EditorExportPlatformMacOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = false;
@@ -1559,7 +1571,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
// Look for export templates (official templates, check only is custom templates are not set).
if (!dvalid || !rvalid) {
- dvalid = exists_export_template("osx.zip", &err);
+ dvalid = exists_export_template("macos.zip", &err);
rvalid = dvalid; // Both in the same ZIP.
}
@@ -1575,7 +1587,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
bool sign_enabled = p_preset->get("codesign/enable");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool noto_enabled = p_preset->get("notarization/enable");
bool ad_hoc = ((p_preset->get("codesign/identity") == "") || (p_preset->get("codesign/identity") == "-"));
@@ -1664,11 +1676,9 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
return valid;
}
-EditorExportPlatformOSX::EditorExportPlatformOSX() {
- Ref<Image> img = memnew(Image(_osx_logo));
- logo.instantiate();
- logo->create_from_image(img);
+EditorExportPlatformMacOS::EditorExportPlatformMacOS() {
+ logo = ImageTexture::create_from_image(memnew(Image(_macos_logo)));
}
-EditorExportPlatformOSX::~EditorExportPlatformOSX() {
+EditorExportPlatformMacOS::~EditorExportPlatformMacOS() {
}
diff --git a/platform/osx/export/export_plugin.h b/platform/macos/export/export_plugin.h
index ec97d4139f..410ec22545 100644
--- a/platform/osx/export/export_plugin.h
+++ b/platform/macos/export/export_plugin.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef OSX_EXPORT_PLUGIN_H
-#define OSX_EXPORT_PLUGIN_H
+#ifndef MACOS_EXPORT_PLUGIN_H
+#define MACOS_EXPORT_PLUGIN_H
#include "core/config/project_settings.h"
#include "core/io/dir_access.h"
@@ -41,12 +41,12 @@
#include "core/version.h"
#include "editor/editor_export.h"
#include "editor/editor_settings.h"
-#include "platform/osx/logo.gen.h"
+#include "platform/macos/logo.gen.h"
#include <sys/stat.h>
-class EditorExportPlatformOSX : public EditorExportPlatform {
- GDCLASS(EditorExportPlatformOSX, EditorExportPlatform);
+class EditorExportPlatformMacOS : public EditorExportPlatform {
+ GDCLASS(EditorExportPlatformMacOS, EditorExportPlatform);
int version_code = 0;
@@ -61,7 +61,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
Error _copy_and_sign_files(Ref<DirAccess> &dir_access, const String &p_src_path, const String &p_in_app_path,
bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset, const String &p_ent_path,
bool p_should_error_on_non_code_sign);
- Error _export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, const String &p_app_path_name,
+ Error _export_macos_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, const String &p_app_path_name,
Ref<DirAccess> &dir_access, bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset,
const String &p_ent_path);
Error _create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name);
@@ -69,7 +69,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
Error _export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path);
bool use_codesign() const { return true; }
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
bool use_dmg() const { return true; }
#else
bool use_dmg() const { return false; }
@@ -130,8 +130,8 @@ public:
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override {
}
- EditorExportPlatformOSX();
- ~EditorExportPlatformOSX();
+ EditorExportPlatformMacOS();
+ ~EditorExportPlatformMacOS();
};
#endif
diff --git a/platform/osx/export/lipo.cpp b/platform/macos/export/lipo.cpp
index 82baf18c52..82baf18c52 100644
--- a/platform/osx/export/lipo.cpp
+++ b/platform/macos/export/lipo.cpp
diff --git a/platform/osx/export/lipo.h b/platform/macos/export/lipo.h
index 0e419be17e..0e419be17e 100644
--- a/platform/osx/export/lipo.h
+++ b/platform/macos/export/lipo.h
diff --git a/platform/osx/export/macho.cpp b/platform/macos/export/macho.cpp
index e6e67eff06..e6e67eff06 100644
--- a/platform/osx/export/macho.cpp
+++ b/platform/macos/export/macho.cpp
diff --git a/platform/osx/export/macho.h b/platform/macos/export/macho.h
index 6cfc3c44f5..6cfc3c44f5 100644
--- a/platform/osx/export/macho.h
+++ b/platform/macos/export/macho.h
diff --git a/platform/osx/export/plist.cpp b/platform/macos/export/plist.cpp
index 36de9dd34b..36de9dd34b 100644
--- a/platform/osx/export/plist.cpp
+++ b/platform/macos/export/plist.cpp
diff --git a/platform/osx/export/plist.h b/platform/macos/export/plist.h
index ba9eaec196..ba9eaec196 100644
--- a/platform/osx/export/plist.h
+++ b/platform/macos/export/plist.h
diff --git a/platform/osx/gl_manager_osx_legacy.h b/platform/macos/gl_manager_macos_legacy.h
index 2d4913a7a6..9f866f2b32 100644
--- a/platform/osx/gl_manager_osx_legacy.h
+++ b/platform/macos/gl_manager_macos_legacy.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* gl_manager_osx_legacy.h */
+/* gl_manager_macos_legacy.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GL_MANAGER_OSX_LEGACY_H
-#define GL_MANAGER_OSX_LEGACY_H
+#ifndef GL_MANAGER_MACOS_LEGACY_H
+#define GL_MANAGER_MACOS_LEGACY_H
-#if defined(OSX_ENABLED) && defined(GLES3_ENABLED)
+#if defined(MACOS_ENABLED) && defined(GLES3_ENABLED)
#include "core/error/error_list.h"
#include "core/os/os.h"
@@ -42,7 +42,7 @@
#import <ApplicationServices/ApplicationServices.h>
#import <CoreVideo/CoreVideo.h>
-class GLManager_OSX {
+class GLManager_MacOS {
public:
enum ContextType {
GLES_3_0_COMPATIBLE,
@@ -89,9 +89,9 @@ public:
void set_use_vsync(bool p_use);
bool is_using_vsync() const;
- GLManager_OSX(ContextType p_context_type);
- ~GLManager_OSX();
+ GLManager_MacOS(ContextType p_context_type);
+ ~GLManager_MacOS();
};
-#endif // OSX_ENABLED && GLES3_ENABLED
-#endif // GL_MANAGER_OSX_LEGACY_H
+#endif // MACOS_ENABLED && GLES3_ENABLED
+#endif // GL_MANAGER_MACOS_LEGACY_H
diff --git a/platform/osx/gl_manager_osx_legacy.mm b/platform/macos/gl_manager_macos_legacy.mm
index c769d7f5c5..e6bb7aaa85 100644
--- a/platform/osx/gl_manager_osx_legacy.mm
+++ b/platform/macos/gl_manager_macos_legacy.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* gl_manager_osx_legacy.mm */
+/* gl_manager_macos_legacy.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "gl_manager_osx_legacy.h"
+#include "gl_manager_macos_legacy.h"
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
#ifdef GLES3_ENABLED
#include <stdio.h>
#include <stdlib.h>
-Error GLManager_OSX::create_context(GLWindow &win) {
+Error GLManager_MacOS::create_context(GLWindow &win) {
NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAClosestPolicy,
@@ -62,7 +62,7 @@ Error GLManager_OSX::create_context(GLWindow &win) {
return OK;
}
-Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) {
+Error GLManager_MacOS::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) {
GLWindow win;
win.width = p_width;
win.height = p_height;
@@ -78,7 +78,7 @@ Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_vie
return OK;
}
-void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
+void GLManager_MacOS::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
if (!windows.has(p_window_id)) {
return;
}
@@ -102,7 +102,7 @@ void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_wid
[win.context update];
}
-int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) {
+int GLManager_MacOS::window_get_width(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return 0;
}
@@ -111,7 +111,7 @@ int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) {
return win.width;
}
-int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) {
+int GLManager_MacOS::window_get_height(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return 0;
}
@@ -120,7 +120,7 @@ int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) {
return win.height;
}
-void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) {
+void GLManager_MacOS::window_destroy(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return;
}
@@ -132,7 +132,7 @@ void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) {
windows.erase(p_window_id);
}
-void GLManager_OSX::release_current() {
+void GLManager_MacOS::release_current() {
if (current_window == DisplayServer::INVALID_WINDOW_ID) {
return;
}
@@ -140,7 +140,7 @@ void GLManager_OSX::release_current() {
[NSOpenGLContext clearCurrentContext];
}
-void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) {
+void GLManager_MacOS::window_make_current(DisplayServer::WindowID p_window_id) {
if (current_window == p_window_id) {
return;
}
@@ -154,7 +154,7 @@ void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) {
current_window = p_window_id;
}
-void GLManager_OSX::make_current() {
+void GLManager_MacOS::make_current() {
if (current_window == DisplayServer::INVALID_WINDOW_ID) {
return;
}
@@ -166,13 +166,13 @@ void GLManager_OSX::make_current() {
[win.context makeCurrentContext];
}
-void GLManager_OSX::swap_buffers() {
+void GLManager_MacOS::swap_buffers() {
for (const KeyValue<DisplayServer::WindowID, GLWindow> &E : windows) {
[E.value.context flushBuffer];
}
}
-void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) {
+void GLManager_MacOS::window_update(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return;
}
@@ -181,7 +181,7 @@ void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) {
[win.context update];
}
-void GLManager_OSX::window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled) {
+void GLManager_MacOS::window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled) {
if (!windows.has(p_window_id)) {
return;
}
@@ -197,11 +197,11 @@ void GLManager_OSX::window_set_per_pixel_transparency_enabled(DisplayServer::Win
[win.context update];
}
-Error GLManager_OSX::initialize() {
+Error GLManager_MacOS::initialize() {
return OK;
}
-void GLManager_OSX::set_use_vsync(bool p_use) {
+void GLManager_MacOS::set_use_vsync(bool p_use) {
use_vsync = p_use;
CGLContextObj ctx = CGLGetCurrentContext();
@@ -212,17 +212,17 @@ void GLManager_OSX::set_use_vsync(bool p_use) {
}
}
-bool GLManager_OSX::is_using_vsync() const {
+bool GLManager_MacOS::is_using_vsync() const {
return use_vsync;
}
-GLManager_OSX::GLManager_OSX(ContextType p_context_type) {
+GLManager_MacOS::GLManager_MacOS(ContextType p_context_type) {
context_type = p_context_type;
}
-GLManager_OSX::~GLManager_OSX() {
+GLManager_MacOS::~GLManager_MacOS() {
release_current();
}
#endif // GLES3_ENABLED
-#endif // OSX
+#endif // MACOS_ENABLED
diff --git a/platform/osx/godot_application.h b/platform/macos/godot_application.h
index 8d48a659f3..8d48a659f3 100644
--- a/platform/osx/godot_application.h
+++ b/platform/macos/godot_application.h
diff --git a/platform/osx/godot_application.mm b/platform/macos/godot_application.mm
index 13313a025a..3f71c77fd1 100644
--- a/platform/osx/godot_application.mm
+++ b/platform/macos/godot_application.mm
@@ -30,12 +30,12 @@
#include "godot_application.h"
-#include "display_server_osx.h"
+#include "display_server_macos.h"
@implementation GodotApplication
- (void)sendEvent:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
if ([event type] == NSEventTypeLeftMouseDown || [event type] == NSEventTypeRightMouseDown || [event type] == NSEventTypeOtherMouseDown) {
if (ds->mouse_process_popups()) {
diff --git a/platform/osx/godot_application_delegate.h b/platform/macos/godot_application_delegate.h
index 8eec762d8f..f5b67b580f 100644
--- a/platform/osx/godot_application_delegate.h
+++ b/platform/macos/godot_application_delegate.h
@@ -40,6 +40,7 @@
- (void)forceUnbundledWindowActivationHackStep1;
- (void)forceUnbundledWindowActivationHackStep2;
- (void)forceUnbundledWindowActivationHackStep3;
+- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
@end
#endif // GODOT_APPLICATION_DELEGATE_H
diff --git a/platform/osx/godot_application_delegate.mm b/platform/macos/godot_application_delegate.mm
index dc82075c44..bacdcc2bc4 100644
--- a/platform/osx/godot_application_delegate.mm
+++ b/platform/macos/godot_application_delegate.mm
@@ -30,8 +30,8 @@
#include "godot_application_delegate.h"
-#include "display_server_osx.h"
-#include "os_osx.h"
+#include "display_server_macos.h"
+#include "os_macos.h"
@implementation GodotApplicationDelegate
@@ -67,8 +67,54 @@
}
}
+- (id)init {
+ self = [super init];
+
+ NSAppleEventManager *aem = [NSAppleEventManager sharedAppleEventManager];
+ [aem setEventHandler:self andSelector:@selector(handleAppleEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
+ [aem setEventHandler:self andSelector:@selector(handleAppleEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];
+
+ return self;
+}
+
+- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
+ OS_MacOS *os = (OS_MacOS *)OS::get_singleton();
+ if (!event || !os) {
+ return;
+ }
+
+ List<String> args;
+ if (([event eventClass] == kInternetEventClass) && ([event eventID] == kAEGetURL)) {
+ // Opening URL scheme.
+ NSString *url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
+ args.push_back(vformat("--uri=\"%s\"", String::utf8([url UTF8String])));
+ }
+
+ if (([event eventClass] == kCoreEventClass) && ([event eventID] == kAEOpenDocuments)) {
+ // Opening file association.
+ NSAppleEventDescriptor *files = [event paramDescriptorForKeyword:keyDirectObject];
+ if (files) {
+ NSInteger count = [files numberOfItems];
+ for (NSInteger i = 1; i <= count; i++) {
+ NSURL *url = [NSURL URLWithString:[[files descriptorAtIndex:i] stringValue]];
+ args.push_back(String::utf8([url.path UTF8String]));
+ }
+ }
+ }
+
+ if (!args.is_empty()) {
+ if (os->get_main_loop()) {
+ // Application is already running, open a new instance with the URL/files as command line arguments.
+ os->create_instance(args);
+ } else {
+ // Application is just started, add to the list of command line arguments and continue.
+ os->set_cmdline_platform_args(args);
+ }
+ }
+}
+
- (void)applicationDidResignActive:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->mouse_process_popups(true);
}
@@ -84,14 +130,14 @@
}
- (void)globalMenuCallback:(id)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
return ds->menu_callback(sender);
}
}
- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
return ds->get_dock_menu();
} else {
@@ -99,35 +145,16 @@
}
}
-- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
- // Note: may be called called before main loop init!
- OS_OSX *os = (OS_OSX *)OS::get_singleton();
- if (os) {
- os->set_open_with_filename(String::utf8([filename UTF8String]));
- }
-
-#ifdef TOOLS_ENABLED
- // Open new instance.
- if (os && os->get_main_loop()) {
- List<String> args;
- args.push_back(os->get_open_with_filename());
- String exec = os->get_executable_path();
- os->create_process(exec, args);
- }
-#endif
- return YES;
-}
-
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
- ds->send_window_event(ds->get_window(DisplayServerOSX::MAIN_WINDOW_ID), DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ ds->send_window_event(ds->get_window(DisplayServerMacOS::MAIN_WINDOW_ID), DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
}
return NSTerminateCancel;
}
- (void)showAbout:(id)sender {
- OS_OSX *os = (OS_OSX *)OS::get_singleton();
+ OS_MacOS *os = (OS_MacOS *)OS::get_singleton();
if (os && os->get_main_loop()) {
os->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT);
}
diff --git a/platform/osx/godot_content_view.h b/platform/macos/godot_content_view.h
index 7942d716dc..353305aec1 100644
--- a/platform/osx/godot_content_view.h
+++ b/platform/macos/godot_content_view.h
@@ -52,6 +52,7 @@
bool ime_input_event_in_progress;
bool mouse_down_control;
bool ignore_momentum_scroll;
+ bool last_pen_inverted;
}
- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor;
diff --git a/platform/osx/godot_content_view.mm b/platform/macos/godot_content_view.mm
index e96f0a8098..9ca7498a15 100644
--- a/platform/osx/godot_content_view.mm
+++ b/platform/macos/godot_content_view.mm
@@ -30,8 +30,8 @@
#include "godot_content_view.h"
-#include "display_server_osx.h"
-#include "key_mapping_osx.h"
+#include "display_server_macos.h"
+#include "key_mapping_macos.h"
@implementation GodotContentView
@@ -42,6 +42,7 @@
ime_input_event_in_progress = false;
mouse_down_control = false;
ignore_momentum_scroll = false;
+ last_pen_inverted = false;
[self updateTrackingAreas];
if (@available(macOS 10.13, *)) {
@@ -55,7 +56,7 @@
return self;
}
-- (void)setWindowID:(DisplayServerOSX::WindowID)wid {
+- (void)setWindowID:(DisplayServerMacOS::WindowID)wid {
window_id = wid;
}
@@ -66,7 +67,7 @@
}
- (void)updateLayer {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
ds->window_update(window_id);
[super updateLayer];
}
@@ -105,12 +106,12 @@
return;
}
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (wd.im_active) {
ime_input_event_in_progress = true;
ds->update_im_text(Point2i(selectedRange.location, selectedRange.length), String::utf8([[marked_text mutableString] UTF8String]));
@@ -125,12 +126,12 @@
ime_input_event_in_progress = false;
[[marked_text mutableString] setString:@""];
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (wd.im_active) {
ds->update_im_text(Point2i(), String());
}
@@ -149,12 +150,12 @@
}
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return NSMakeRect(0, 0, 0, 0);
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
const NSRect content_rect = [wd.window_view frame];
const float scale = ds->screen_get_max_scale();
NSRect point_in_window_rect = NSMakeRect(wd.im_position.x / scale, content_rect.size.height - (wd.im_position.y / scale) - 1, 0, 0);
@@ -190,7 +191,7 @@
return;
}
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
[self cancelComposition];
return;
@@ -209,10 +210,10 @@
continue;
}
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = true;
ke.echo = false;
ke.raw = false; // IME input event.
@@ -236,12 +237,12 @@
}
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return NO;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (!wd.drop_files_callback.is_null()) {
Vector<String> files;
NSPasteboard *pboard = [sender draggingPasteboard];
@@ -275,12 +276,12 @@
// MARK: Focus
- (BOOL)canBecomeKeyView {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return YES;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
return !wd.no_focus && !wd.is_popup;
}
@@ -291,7 +292,7 @@
// MARK: Mouse
- (void)cursorUpdate:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds) {
return;
}
@@ -300,12 +301,12 @@
}
- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
MouseButton last_button_state = ds->mouse_get_button_state();
if (pressed) {
@@ -355,12 +356,12 @@
}
- (void)mouseMoved:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
NSPoint delta = NSMakePoint([event deltaX], [event deltaY]);
NSPoint mpos = [event locationInWindow];
@@ -377,9 +378,15 @@
ds->update_mouse_pos(wd, mpos);
mm->set_position(wd.mouse_pos);
mm->set_pressure([event pressure]);
- if ([event subtype] == NSEventSubtypeTabletPoint) {
+ NSEventSubtype subtype = [event subtype];
+ if (subtype == NSEventSubtypeTabletPoint) {
const NSPoint p = [event tilt];
mm->set_tilt(Vector2(p.x, p.y));
+ mm->set_pen_inverted(last_pen_inverted);
+ } else if (subtype == NSEventSubtypeTabletProximity) {
+ // Check if using the eraser end of pen only on proximity event.
+ last_pen_inverted = [event pointingDeviceType] == NSPointingDeviceTypeEraser;
+ mm->set_pen_inverted(last_pen_inverted);
}
mm->set_global_position(wd.mouse_pos);
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
@@ -431,38 +438,38 @@
}
- (void)mouseExited:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) {
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_EXIT);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_MOUSE_EXIT);
}
}
- (void)mouseEntered:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) {
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_ENTER);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_MOUSE_ENTER);
}
ds->cursor_update_shape();
}
- (void)magnifyWithEvent:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
Ref<InputEventMagnifyGesture> ev;
ev.instantiate();
@@ -490,12 +497,12 @@
// MARK: Keyboard
- (void)keyDown:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ignore_momentum_scroll = true;
@@ -504,7 +511,7 @@
NSString *characters = [event characters];
NSUInteger length = [characters length];
- if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]))) {
+ if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]))) {
// Fallback unicode character handler used if IME is not active.
Char16String text;
text.resize([characters length] + 1);
@@ -516,28 +523,28 @@
for (int i = 0; i < u32text.length(); i++) {
const char32_t codepoint = u32text[i];
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = true;
ke.echo = [event isARepeat];
- ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]);
- ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]);
+ ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]);
+ ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]);
ke.raw = true;
ke.unicode = codepoint;
ds->push_to_key_event_buffer(ke);
}
} else {
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = true;
ke.echo = [event isARepeat];
- ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]);
- ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]);
+ ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]);
+ ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]);
ke.raw = false;
ke.unicode = 0;
@@ -552,7 +559,7 @@
}
- (void)flagsChanged:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
@@ -560,7 +567,7 @@
// Ignore all input if IME input is in progress
if (!ime_input_event_in_progress) {
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
ke.echo = false;
@@ -601,9 +608,9 @@
return;
}
- ke.osx_state = mod;
- ke.keycode = KeyMappingOSX::remap_key(key, mod);
- ke.physical_keycode = KeyMappingOSX::translate_key(key);
+ ke.macos_state = mod;
+ ke.keycode = KeyMappingMacOS::remap_key(key, mod);
+ ke.physical_keycode = KeyMappingMacOS::translate_key(key);
ke.unicode = 0;
ds->push_to_key_event_buffer(ke);
@@ -611,12 +618,12 @@
}
- (void)keyUp:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
// Ignore all input if IME input is in progress.
if (!ime_input_event_in_progress) {
@@ -624,7 +631,7 @@
NSUInteger length = [characters length];
// Fallback unicode character handler used if IME is not active.
- if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]))) {
+ if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]))) {
Char16String text;
text.resize([characters length] + 1);
[characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])];
@@ -634,28 +641,28 @@
for (int i = 0; i < u32text.length(); i++) {
const char32_t codepoint = u32text[i];
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = false;
ke.echo = [event isARepeat];
- ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]);
- ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]);
+ ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]);
+ ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]);
ke.raw = true;
ke.unicode = codepoint;
ds->push_to_key_event_buffer(ke);
}
} else {
- DisplayServerOSX::KeyEvent ke;
+ DisplayServerMacOS::KeyEvent ke;
ke.window_id = window_id;
- ke.osx_state = [event modifierFlags];
+ ke.macos_state = [event modifierFlags];
ke.pressed = false;
ke.echo = [event isARepeat];
- ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]);
- ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]);
+ ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]);
+ ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]);
ke.raw = true;
ke.unicode = 0;
@@ -667,12 +674,12 @@
// MARK: Scroll and pan
- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
MouseButton mask = mouse_button_to_mask(button);
Ref<InputEventMouseButton> sc;
@@ -706,12 +713,12 @@
}
- (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
Ref<InputEventPanGesture> pg;
pg.instantiate();
@@ -725,12 +732,12 @@
}
- (void)scrollWheel:(NSEvent *)event {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->update_mouse_pos(wd, [event locationInWindow]);
double delta_x = [event scrollingDeltaX];
diff --git a/platform/osx/godot_main_osx.mm b/platform/macos/godot_main_macos.mm
index 053a7f4a1d..66071f1404 100644
--- a/platform/osx/godot_main_osx.mm
+++ b/platform/macos/godot_main_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_main_osx.mm */
+/* godot_main_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,7 +30,7 @@
#include "main/main.h"
-#include "os_osx.h"
+#include "os_macos.h"
#include <string.h>
#include <unistd.h>
@@ -68,22 +68,17 @@ int main(int argc, char **argv) {
printf("Current path: %s\n", cwd);
#endif
- OS_OSX os;
+ OS_MacOS os;
Error err;
// We must override main when testing is enabled.
TEST_MAIN_OVERRIDE
- if (os.get_open_with_filename() != "") {
- char *argv_c = (char *)malloc(os.get_open_with_filename().utf8().size());
- memcpy(argv_c, os.get_open_with_filename().utf8().get_data(), os.get_open_with_filename().utf8().size());
- err = Main::setup(argv[0], 1, &argv_c);
- free(argv_c);
- } else {
- err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]);
- }
+ err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]);
- if (err != OK) {
+ if (err == ERR_HELP) { // Returned by --help and --version, so success.
+ return 0;
+ } else if (err != OK) {
return 255;
}
diff --git a/platform/osx/godot_menu_item.h b/platform/macos/godot_menu_item.h
index 2c12897f10..2c12897f10 100644
--- a/platform/osx/godot_menu_item.h
+++ b/platform/macos/godot_menu_item.h
diff --git a/platform/osx/godot_window.h b/platform/macos/godot_window.h
index 16ff101142..16ff101142 100644
--- a/platform/osx/godot_window.h
+++ b/platform/macos/godot_window.h
diff --git a/platform/osx/godot_window.mm b/platform/macos/godot_window.mm
index d43853a94b..e205e7546d 100644
--- a/platform/osx/godot_window.mm
+++ b/platform/macos/godot_window.mm
@@ -30,7 +30,7 @@
#include "godot_window.h"
-#include "display_server_osx.h"
+#include "display_server_macos.h"
@implementation GodotWindow
@@ -40,29 +40,29 @@
return self;
}
-- (void)setWindowID:(DisplayServerOSX::WindowID)wid {
+- (void)setWindowID:(DisplayServerMacOS::WindowID)wid {
window_id = wid;
}
- (BOOL)canBecomeKeyWindow {
// Required for NSWindowStyleMaskBorderless windows.
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return YES;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
return !wd.no_focus && !wd.is_popup;
}
- (BOOL)canBecomeMainWindow {
// Required for NSWindowStyleMaskBorderless windows.
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return YES;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
return !wd.no_focus && !wd.is_popup;
}
diff --git a/platform/osx/godot_window_delegate.h b/platform/macos/godot_window_delegate.h
index 8a1f681fcd..8a1f681fcd 100644
--- a/platform/osx/godot_window_delegate.h
+++ b/platform/macos/godot_window_delegate.h
diff --git a/platform/osx/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm
index 521127f01b..e1e88274f0 100644
--- a/platform/osx/godot_window_delegate.mm
+++ b/platform/macos/godot_window_delegate.mm
@@ -30,7 +30,7 @@
#include "godot_window_delegate.h"
-#include "display_server_osx.h"
+#include "display_server_macos.h"
@implementation GodotWindowDelegate
@@ -39,42 +39,42 @@
}
- (BOOL)windowShouldClose:(id)sender {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return YES;
}
- ds->send_window_event(ds->get_window(window_id), DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
+ ds->send_window_event(ds->get_window(window_id), DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
return NO;
}
- (void)windowWillClose:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
ds->popup_close(window_id);
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
while (wd.transient_children.size()) {
- ds->window_set_transient(*wd.transient_children.begin(), DisplayServerOSX::INVALID_WINDOW_ID);
+ ds->window_set_transient(*wd.transient_children.begin(), DisplayServerMacOS::INVALID_WINDOW_ID);
}
- if (wd.transient_parent != DisplayServerOSX::INVALID_WINDOW_ID) {
- ds->window_set_transient(window_id, DisplayServerOSX::INVALID_WINDOW_ID);
+ if (wd.transient_parent != DisplayServerMacOS::INVALID_WINDOW_ID) {
+ ds->window_set_transient(window_id, DisplayServerMacOS::INVALID_WINDOW_ID);
}
ds->window_destroy(window_id);
}
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
wd.fullscreen = true;
// Reset window size limits.
[wd.window_object setContentMinSize:NSMakeSize(0, 0)];
@@ -85,12 +85,12 @@
}
- (void)windowDidExitFullScreen:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
wd.fullscreen = false;
// Set window size limits.
@@ -119,12 +119,12 @@
}
- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
CGFloat new_scale_factor = [wd.window_object backingScaleFactor];
CGFloat old_scale_factor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
@@ -137,7 +137,7 @@
wd.size.width = content_rect.size.width * scale;
wd.size.height = content_rect.size.height * scale;
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_DPI_CHANGE);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_DPI_CHANGE);
CALayer *layer = [wd.window_view layer];
if (layer) {
@@ -150,26 +150,26 @@
}
- (void)windowWillStartLiveResize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->set_is_resizing(true);
}
}
- (void)windowDidEndLiveResize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (ds) {
ds->set_is_resizing(false);
}
}
- (void)windowDidResize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
const NSRect content_rect = [wd.window_view frame];
const float scale = ds->screen_get_max_scale();
wd.size.width = content_rect.size.width * scale;
@@ -192,12 +192,12 @@
}
- (void)windowDidMove:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->release_pressed_events();
if (!wd.rect_changed_callback.is_null()) {
@@ -210,12 +210,12 @@
}
- (void)windowDidBecomeKey:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (ds->mouse_get_mode() == DisplayServer::MOUSE_MODE_CAPTURED) {
const NSRect content_rect = [wd.window_view frame];
@@ -228,43 +228,43 @@
}
ds->set_last_focused_window(window_id);
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN);
}
- (void)windowDidResignKey:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->release_pressed_events();
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT);
}
- (void)windowDidMiniaturize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->release_pressed_events();
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT);
}
- (void)windowDidDeminiaturize:(NSNotification *)notification {
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) {
return;
}
- DisplayServerOSX::WindowData &wd = ds->get_window(window_id);
+ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
ds->set_last_focused_window(window_id);
- ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN);
}
@end
diff --git a/platform/osx/joypad_osx.cpp b/platform/macos/joypad_macos.cpp
index be9567e17c..1ddcfec1b5 100644
--- a/platform/osx/joypad_osx.cpp
+++ b/platform/macos/joypad_macos.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad_osx.cpp */
+/* joypad_macos.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "joypad_osx.h"
+#include "joypad_macos.h"
#include <machine/endian.h>
#define GODOT_JOY_LOOP_RUN_MODE CFSTR("GodotJoypad")
-static JoypadOSX *self = nullptr;
+static JoypadMacOS *self = nullptr;
joypad::joypad() {
ff_constant_force.lMagnitude = 10000;
@@ -235,7 +235,7 @@ static bool is_joypad(IOHIDDeviceRef p_device_ref) {
return true;
}
-void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
+void JoypadMacOS::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
if (p_res != kIOReturnSuccess || have_device(p_device)) {
return;
}
@@ -258,7 +258,7 @@ void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
IOHIDDeviceScheduleWithRunLoop(p_device, CFRunLoopGetCurrent(), GODOT_JOY_LOOP_RUN_MODE);
}
-void JoypadOSX::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) {
+void JoypadMacOS::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) {
int device = get_joy_ref(p_device);
ERR_FAIL_COND(device == -1);
@@ -278,7 +278,7 @@ static String _hex_str(uint8_t p_byte) {
return ret;
}
-bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) {
+bool JoypadMacOS::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) {
p_joy->device_ref = p_device_ref;
// Get device name.
String name;
@@ -445,7 +445,7 @@ static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offse
return hat_value;
}
-void JoypadOSX::poll_joypads() const {
+void JoypadMacOS::poll_joypads() const {
while (CFRunLoopRunInMode(GODOT_JOY_LOOP_RUN_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) {
// No-op. Pending callbacks will fire.
}
@@ -456,7 +456,7 @@ static float axis_correct(int p_value, int p_min, int p_max) {
return 2.0f * (p_value - p_min) / (p_max - p_min) - 1.0f;
}
-void JoypadOSX::process_joypads() {
+void JoypadMacOS::process_joypads() {
poll_joypads();
for (int i = 0; i < device_list.size(); i++) {
@@ -494,7 +494,7 @@ void JoypadOSX::process_joypads() {
}
}
-void JoypadOSX::joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp) {
+void JoypadMacOS::joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp) {
joypad *joy = &device_list.write[get_joy_index(p_id)];
joy->ff_timestamp = p_timestamp;
joy->ff_effect.dwDuration = p_duration * FF_SECONDS;
@@ -503,13 +503,13 @@ void JoypadOSX::joypad_vibration_start(int p_id, float p_magnitude, float p_dura
FFEffectStart(joy->ff_object, 1, 0);
}
-void JoypadOSX::joypad_vibration_stop(int p_id, uint64_t p_timestamp) {
+void JoypadMacOS::joypad_vibration_stop(int p_id, uint64_t p_timestamp) {
joypad *joy = &device_list.write[get_joy_index(p_id)];
joy->ff_timestamp = p_timestamp;
FFEffectStop(joy->ff_object);
}
-int JoypadOSX::get_joy_index(int p_id) const {
+int JoypadMacOS::get_joy_index(int p_id) const {
for (int i = 0; i < device_list.size(); i++) {
if (device_list[i].id == p_id) {
return i;
@@ -518,7 +518,7 @@ int JoypadOSX::get_joy_index(int p_id) const {
return -1;
}
-int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const {
+int JoypadMacOS::get_joy_ref(IOHIDDeviceRef p_device) const {
for (int i = 0; i < device_list.size(); i++) {
if (device_list[i].device_ref == p_device) {
return i;
@@ -527,7 +527,7 @@ int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const {
return -1;
}
-bool JoypadOSX::have_device(IOHIDDeviceRef p_device) const {
+bool JoypadMacOS::have_device(IOHIDDeviceRef p_device) const {
for (int i = 0; i < device_list.size(); i++) {
if (device_list[i].device_ref == p_device) {
return true;
@@ -561,7 +561,7 @@ static CFDictionaryRef create_match_dictionary(const UInt32 page, const UInt32 u
return retval;
}
-void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const {
+void JoypadMacOS::config_hid_manager(CFArrayRef p_matching_array) const {
CFRunLoopRef runloop = CFRunLoopGetCurrent();
IOReturn ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
ERR_FAIL_COND(ret != kIOReturnSuccess);
@@ -576,7 +576,7 @@ void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const {
}
}
-JoypadOSX::JoypadOSX(Input *in) {
+JoypadMacOS::JoypadMacOS(Input *in) {
self = this;
input = in;
@@ -604,7 +604,7 @@ JoypadOSX::JoypadOSX(Input *in) {
}
}
-JoypadOSX::~JoypadOSX() {
+JoypadMacOS::~JoypadMacOS() {
for (int i = 0; i < device_list.size(); i++) {
device_list.write[i].free();
}
diff --git a/platform/osx/joypad_osx.h b/platform/macos/joypad_macos.h
index 3f89048ce6..4b14fed6d5 100644
--- a/platform/osx/joypad_osx.h
+++ b/platform/macos/joypad_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* joypad_osx.h */
+/* joypad_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef JOYPADOSX_H
-#define JOYPADOSX_H
+#ifndef JOYPAD_MACOS_H
+#define JOYPAD_MACOS_H
#ifdef MACOS_10_0_4
#import <IOKit/hidsystem/IOHIDUsageTables.h>
@@ -88,7 +88,7 @@ struct joypad {
joypad();
};
-class JoypadOSX {
+class JoypadMacOS {
enum {
JOYPADS_MAX = 16,
};
@@ -117,8 +117,8 @@ public:
void _device_added(IOReturn p_res, IOHIDDeviceRef p_device);
void _device_removed(IOReturn p_res, IOHIDDeviceRef p_device);
- JoypadOSX(Input *in);
- ~JoypadOSX();
+ JoypadMacOS(Input *in);
+ ~JoypadMacOS();
};
-#endif // JOYPADOSX_H
+#endif // JOYPAD_MACOS_H
diff --git a/platform/osx/key_mapping_osx.h b/platform/macos/key_mapping_macos.h
index 252cc907bb..fc5b791e44 100644
--- a/platform/osx/key_mapping_osx.h
+++ b/platform/macos/key_mapping_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* key_mapping_osx.h */
+/* key_mapping_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef KEY_MAPPING_OSX_H
-#define KEY_MAPPING_OSX_H
+#ifndef KEY_MAPPING_MACOS_H
+#define KEY_MAPPING_MACOS_H
#include "core/os/keyboard.h"
-class KeyMappingOSX {
- KeyMappingOSX() {}
+class KeyMappingMacOS {
+ KeyMappingMacOS() {}
static bool is_numpad_key(unsigned int key);
@@ -49,4 +49,4 @@ public:
static unsigned int keycode_get_native_mask(Key p_keycode);
};
-#endif // KEY_MAPPING_OSX_H
+#endif // KEY_MAPPING_MACOS_H
diff --git a/platform/osx/key_mapping_osx.mm b/platform/macos/key_mapping_macos.mm
index 0bf6bc7d1c..f6cff7124b 100644
--- a/platform/osx/key_mapping_osx.mm
+++ b/platform/macos/key_mapping_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* key_mapping_osx.mm */
+/* key_mapping_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "key_mapping_osx.h"
+#include "key_mapping_macos.h"
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
-bool KeyMappingOSX::is_numpad_key(unsigned int key) {
+bool KeyMappingMacOS::is_numpad_key(unsigned int key) {
static const unsigned int table[] = {
0x41, /* kVK_ANSI_KeypadDecimal */
0x43, /* kVK_ANSI_KeypadMultiply */
@@ -65,7 +65,7 @@ bool KeyMappingOSX::is_numpad_key(unsigned int key) {
}
// Keyboard symbol translation table.
-static const Key _osx_to_godot_table[128] = {
+static const Key _macos_to_godot_table[128] = {
/* 00 */ Key::A,
/* 01 */ Key::S,
/* 02 */ Key::D,
@@ -197,18 +197,18 @@ static const Key _osx_to_godot_table[128] = {
};
// Translates a OS X keycode to a Godot keycode.
-Key KeyMappingOSX::translate_key(unsigned int key) {
+Key KeyMappingMacOS::translate_key(unsigned int key) {
if (key >= 128) {
return Key::UNKNOWN;
}
- return _osx_to_godot_table[key];
+ return _macos_to_godot_table[key];
}
-// Translates a Godot keycode back to a OSX keycode.
-unsigned int KeyMappingOSX::unmap_key(Key key) {
+// Translates a Godot keycode back to a macOS keycode.
+unsigned int KeyMappingMacOS::unmap_key(Key key) {
for (int i = 0; i <= 126; i++) {
- if (_osx_to_godot_table[i] == key) {
+ if (_macos_to_godot_table[i] == key) {
return i;
}
}
@@ -279,7 +279,7 @@ static const _KeyCodeMap _keycodes[55] = {
};
// Remap key according to current keyboard layout.
-Key KeyMappingOSX::remap_key(unsigned int key, unsigned int state) {
+Key KeyMappingMacOS::remap_key(unsigned int key, unsigned int state) {
if (is_numpad_key(key)) {
return translate_key(key);
}
@@ -463,7 +463,7 @@ static const _KeyCodeText _native_keycodes[] = {
/* clang-format on */
};
-String KeyMappingOSX::keycode_get_native_string(Key p_keycode) {
+String KeyMappingMacOS::keycode_get_native_string(Key p_keycode) {
const _KeyCodeText *kct = &_native_keycodes[0];
while (kct->text) {
@@ -475,7 +475,7 @@ String KeyMappingOSX::keycode_get_native_string(Key p_keycode) {
return String();
}
-unsigned int KeyMappingOSX::keycode_get_native_mask(Key p_keycode) {
+unsigned int KeyMappingMacOS::keycode_get_native_mask(Key p_keycode) {
unsigned int mask = 0;
if ((p_keycode & KeyModifierMask::CTRL) != Key::NONE) {
mask |= NSEventModifierFlagControl;
diff --git a/platform/osx/logo.png b/platform/macos/logo.png
index b5a660b165..b5a660b165 100644
--- a/platform/osx/logo.png
+++ b/platform/macos/logo.png
Binary files differ
diff --git a/platform/osx/osx_terminal_logger.h b/platform/macos/macos_terminal_logger.h
index 8413509c4b..bad2c1d657 100644
--- a/platform/osx/osx_terminal_logger.h
+++ b/platform/macos/macos_terminal_logger.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* osx_terminal_logger.h */
+/* macos_terminal_logger.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,17 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef OSX_TERMINAL_LOGGER_H
-#define OSX_TERMINAL_LOGGER_H
+#ifndef MACOS_TERMINAL_LOGGER_H
+#define MACOS_TERMINAL_LOGGER_H
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
#include "core/io/logger.h"
-class OSXTerminalLogger : public StdLogger {
+class MacOSTerminalLogger : public StdLogger {
public:
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) override;
};
-#endif // OSX_ENABLED
-#endif // OSX_TERMINAL_LOGGER_H
+#endif // MACOS_ENABLED
+#endif // MACOS_TERMINAL_LOGGER_H
diff --git a/platform/osx/osx_terminal_logger.mm b/platform/macos/macos_terminal_logger.mm
index 48e26f42bf..b5ea2938ee 100644
--- a/platform/osx/osx_terminal_logger.mm
+++ b/platform/macos/macos_terminal_logger.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* osx_terminal_logger.mm */
+/* macos_terminal_logger.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "osx_terminal_logger.h"
+#include "macos_terminal_logger.h"
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
#include <os/log.h>
-void OSXTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) {
+void MacOSTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) {
if (!should_log(true)) {
return;
}
@@ -79,4 +79,4 @@ void OSXTerminalLogger::log_error(const char *p_function, const char *p_file, in
}
}
-#endif // OSX_ENABLED
+#endif // MACOS_ENABLED
diff --git a/platform/osx/os_osx.h b/platform/macos/os_macos.h
index e4ec411c96..914cdb9af7 100644
--- a/platform/osx/os_osx.h
+++ b/platform/macos/os_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* os_osx.h */
+/* os_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,21 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef OS_OSX_H
-#define OS_OSX_H
+#ifndef OS_MACOS_H
+#define OS_MACOS_H
#include "core/input/input.h"
-#include "crash_handler_osx.h"
+#include "crash_handler_macos.h"
#include "drivers/coreaudio/audio_driver_coreaudio.h"
#include "drivers/coremidi/midi_driver_coremidi.h"
#include "drivers/unix/os_unix.h"
-#include "joypad_osx.h"
+#include "joypad_macos.h"
#include "servers/audio_server.h"
-class OS_OSX : public OS_Unix {
+class OS_MacOS : public OS_Unix {
bool force_quit = false;
- JoypadOSX *joypad_osx = nullptr;
+ JoypadMacOS *joypad_macos = nullptr;
#ifdef COREAUDIO_ENABLED
AudioDriverCoreAudio audio_driver;
@@ -57,7 +57,7 @@ class OS_OSX : public OS_Unix {
MainLoop *main_loop = nullptr;
- String open_with_filename;
+ List<String> launch_service_args;
static _FORCE_INLINE_ String get_framework_executable(const String &p_path);
static void pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context);
@@ -73,8 +73,8 @@ protected:
virtual void delete_main_loop() override;
public:
- String get_open_with_filename() const;
- void set_open_with_filename(const String &p_path);
+ virtual void set_cmdline_platform_args(const List<String> &p_args);
+ virtual List<String> get_cmdline_platform_args() const override;
virtual String get_name() const override;
@@ -113,8 +113,8 @@ public:
void run();
- OS_OSX();
- ~OS_OSX();
+ OS_MacOS();
+ ~OS_MacOS();
};
#endif
diff --git a/platform/osx/os_osx.mm b/platform/macos/os_macos.mm
index a8fa56e34b..2c6cd7de0b 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/macos/os_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* os_osx.mm */
+/* os_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,16 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "os_osx.h"
+#include "os_macos.h"
#include "core/version_generated.gen.h"
#include "main/main.h"
-#include "dir_access_osx.h"
-#include "display_server_osx.h"
+#include "dir_access_macos.h"
+#include "display_server_macos.h"
#include "godot_application.h"
#include "godot_application_delegate.h"
-#include "osx_terminal_logger.h"
+#include "macos_terminal_logger.h"
#include <dlfcn.h>
#include <libproc.h>
@@ -45,7 +45,7 @@
#include <os/log.h>
#include <sys/sysctl.h>
-_FORCE_INLINE_ String OS_OSX::get_framework_executable(const String &p_path) {
+_FORCE_INLINE_ String OS_MacOS::get_framework_executable(const String &p_path) {
// Append framework executable name, or return as is if p_path is not a framework.
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (da->dir_exists(p_path) && da->file_exists(p_path.plus_file(p_path.get_file().get_basename()))) {
@@ -55,10 +55,10 @@ _FORCE_INLINE_ String OS_OSX::get_framework_executable(const String &p_path) {
}
}
-void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) {
+void OS_MacOS::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) {
// Prevent main loop from sleeping and redraw window during resize / modal popups.
- DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton();
+ DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (get_singleton()->get_main_loop() && ds && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD || !ds->get_is_resizing())) {
Main::force_redraw();
if (!Main::is_iterating()) { // Avoid cyclic loop.
@@ -69,13 +69,13 @@ void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActi
CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping.
}
-void OS_OSX::initialize() {
+void OS_MacOS::initialize() {
crash_handler.initialize();
initialize_core();
}
-String OS_OSX::get_processor_name() const {
+String OS_MacOS::get_processor_name() const {
char buffer[256];
size_t buffer_len = 256;
if (sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_len, NULL, 0) == 0) {
@@ -84,35 +84,35 @@ String OS_OSX::get_processor_name() const {
ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string."));
}
-void OS_OSX::initialize_core() {
+void OS_MacOS::initialize_core() {
OS_Unix::initialize_core();
- DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_RESOURCES);
- DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_USERDATA);
- DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_FILESYSTEM);
+ DirAccess::make_default<DirAccessMacOS>(DirAccess::ACCESS_RESOURCES);
+ DirAccess::make_default<DirAccessMacOS>(DirAccess::ACCESS_USERDATA);
+ DirAccess::make_default<DirAccessMacOS>(DirAccess::ACCESS_FILESYSTEM);
}
-void OS_OSX::finalize() {
+void OS_MacOS::finalize() {
#ifdef COREMIDI_ENABLED
midi_driver.close();
#endif
delete_main_loop();
- if (joypad_osx) {
- memdelete(joypad_osx);
+ if (joypad_macos) {
+ memdelete(joypad_macos);
}
}
-void OS_OSX::initialize_joypads() {
- joypad_osx = memnew(JoypadOSX(Input::get_singleton()));
+void OS_MacOS::initialize_joypads() {
+ joypad_macos = memnew(JoypadMacOS(Input::get_singleton()));
}
-void OS_OSX::set_main_loop(MainLoop *p_main_loop) {
+void OS_MacOS::set_main_loop(MainLoop *p_main_loop) {
main_loop = p_main_loop;
}
-void OS_OSX::delete_main_loop() {
+void OS_MacOS::delete_main_loop() {
if (!main_loop) {
return;
}
@@ -121,19 +121,19 @@ void OS_OSX::delete_main_loop() {
main_loop = nullptr;
}
-String OS_OSX::get_open_with_filename() const {
- return open_with_filename;
+void OS_MacOS::set_cmdline_platform_args(const List<String> &p_args) {
+ launch_service_args = p_args;
}
-void OS_OSX::set_open_with_filename(const String &p_path) {
- open_with_filename = p_path;
+List<String> OS_MacOS::get_cmdline_platform_args() const {
+ return launch_service_args;
}
-String OS_OSX::get_name() const {
+String OS_MacOS::get_name() const {
return "macOS";
}
-void OS_OSX::alert(const String &p_alert, const String &p_title) {
+void OS_MacOS::alert(const String &p_alert, const String &p_title) {
NSAlert *window = [[NSAlert alloc] init];
NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()];
NSString *ns_alert = [NSString stringWithUTF8String:p_alert.utf8().get_data()];
@@ -150,7 +150,7 @@ void OS_OSX::alert(const String &p_alert, const String &p_title) {
}
}
-Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
+Error OS_MacOS::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
String path = get_framework_executable(p_path);
if (!FileAccess::exists(path)) {
@@ -173,11 +173,11 @@ Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle,
return OK;
}
-MainLoop *OS_OSX::get_main_loop() const {
+MainLoop *OS_MacOS::get_main_loop() const {
return main_loop;
}
-String OS_OSX::get_config_path() const {
+String OS_MacOS::get_config_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
if (has_environment("XDG_CONFIG_HOME")) {
if (get_environment("XDG_CONFIG_HOME").is_absolute_path()) {
@@ -192,7 +192,7 @@ String OS_OSX::get_config_path() const {
return ".";
}
-String OS_OSX::get_data_path() const {
+String OS_MacOS::get_data_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
if (has_environment("XDG_DATA_HOME")) {
if (get_environment("XDG_DATA_HOME").is_absolute_path()) {
@@ -204,7 +204,7 @@ String OS_OSX::get_data_path() const {
return get_config_path();
}
-String OS_OSX::get_cache_path() const {
+String OS_MacOS::get_cache_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
if (has_environment("XDG_CACHE_HOME")) {
if (get_environment("XDG_CACHE_HOME").is_absolute_path()) {
@@ -219,7 +219,7 @@ String OS_OSX::get_cache_path() const {
return get_config_path();
}
-String OS_OSX::get_bundle_resource_dir() const {
+String OS_MacOS::get_bundle_resource_dir() const {
String ret;
NSBundle *main = [NSBundle mainBundle];
@@ -230,7 +230,7 @@ String OS_OSX::get_bundle_resource_dir() const {
return ret;
}
-String OS_OSX::get_bundle_icon_path() const {
+String OS_MacOS::get_bundle_icon_path() const {
String ret;
NSBundle *main = [NSBundle mainBundle];
@@ -244,11 +244,11 @@ String OS_OSX::get_bundle_icon_path() const {
}
// Get properly capitalized engine name for system paths
-String OS_OSX::get_godot_dir_name() const {
+String OS_MacOS::get_godot_dir_name() const {
return String(VERSION_SHORT_NAME).capitalize();
}
-String OS_OSX::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
+String OS_MacOS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
NSSearchPathDirectory id;
bool found = true;
@@ -287,7 +287,7 @@ String OS_OSX::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
return ret;
}
-Error OS_OSX::shell_open(String p_uri) {
+Error OS_MacOS::shell_open(String p_uri) {
NSString *string = [NSString stringWithUTF8String:p_uri.utf8().get_data()];
NSURL *uri = [[NSURL alloc] initWithString:string];
// Escape special characters in filenames
@@ -298,12 +298,12 @@ Error OS_OSX::shell_open(String p_uri) {
return OK;
}
-String OS_OSX::get_locale() const {
+String OS_MacOS::get_locale() const {
NSString *locale_code = [[NSLocale preferredLanguages] objectAtIndex:0];
return String([locale_code UTF8String]).replace("-", "_");
}
-String OS_OSX::get_executable_path() const {
+String OS_MacOS::get_executable_path() const {
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
int pid = getpid();
pid_t ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf));
@@ -317,7 +317,7 @@ String OS_OSX::get_executable_path() const {
}
}
-Error OS_OSX::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id, bool p_open_console) {
+Error OS_MacOS::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id, bool p_open_console) {
// Use NSWorkspace if path is an .app bundle.
NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())];
NSBundle *bundle = [NSBundle bundleWithURL:url];
@@ -375,7 +375,7 @@ Error OS_OSX::create_process(const String &p_path, const List<String> &p_argumen
}
}
-Error OS_OSX::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) {
+Error OS_MacOS::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) {
// If executable is bundled, always execute editor instances as an app bundle to ensure app window is registered and activated correctly.
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
if (nsappname != nil) {
@@ -387,7 +387,7 @@ Error OS_OSX::create_instance(const List<String> &p_arguments, ProcessID *r_chil
}
}
-String OS_OSX::get_unique_id() const {
+String OS_MacOS::get_unique_id() const {
static String serial_number;
if (serial_number.is_empty()) {
@@ -412,19 +412,19 @@ String OS_OSX::get_unique_id() const {
return serial_number;
}
-bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
+bool OS_MacOS::_check_internal_feature_support(const String &p_feature) {
return p_feature == "pc";
}
-void OS_OSX::disable_crash_handler() {
+void OS_MacOS::disable_crash_handler() {
crash_handler.disable();
}
-bool OS_OSX::is_disable_crash_handler() const {
+bool OS_MacOS::is_disable_crash_handler() const {
return crash_handler.is_disabled();
}
-Error OS_OSX::move_to_trash(const String &p_path) {
+Error OS_MacOS::move_to_trash(const String &p_path) {
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())];
NSError *err;
@@ -437,7 +437,7 @@ Error OS_OSX::move_to_trash(const String &p_path) {
return OK;
}
-void OS_OSX::run() {
+void OS_MacOS::run() {
force_quit = false;
if (!main_loop) {
@@ -452,7 +452,7 @@ void OS_OSX::run() {
if (DisplayServer::get_singleton()) {
DisplayServer::get_singleton()->process_events(); // Get rid of pending events.
}
- joypad_osx->process_joypads();
+ joypad_macos->process_joypads();
if (Main::iteration()) {
quit = true;
@@ -465,19 +465,19 @@ void OS_OSX::run() {
main_loop->finalize();
}
-OS_OSX::OS_OSX() {
+OS_MacOS::OS_MacOS() {
main_loop = nullptr;
force_quit = false;
Vector<Logger *> loggers;
- loggers.push_back(memnew(OSXTerminalLogger));
+ loggers.push_back(memnew(MacOSTerminalLogger));
_set_logger(memnew(CompositeLogger(loggers)));
#ifdef COREAUDIO_ENABLED
AudioDriverManager::add_driver(&audio_driver);
#endif
- DisplayServerOSX::register_osx_driver();
+ DisplayServerMacOS::register_macos_driver();
// Implicitly create shared NSApplication instance.
[GodotApplication sharedApplication];
@@ -518,7 +518,7 @@ OS_OSX::OS_OSX() {
[NSApp activateIgnoringOtherApps:YES];
}
-OS_OSX::~OS_OSX() {
+OS_MacOS::~OS_MacOS() {
CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
CFRelease(pre_wait_observer);
}
diff --git a/platform/osx/platform_config.h b/platform/macos/platform_config.h
index e114606b82..e114606b82 100644
--- a/platform/osx/platform_config.h
+++ b/platform/macos/platform_config.h
diff --git a/platform/osx/platform_osx_builders.py b/platform/macos/platform_macos_builders.py
index 953ed479db..3a1cc92bd2 100644
--- a/platform/osx/platform_osx_builders.py
+++ b/platform/macos/platform_macos_builders.py
@@ -7,7 +7,7 @@ import os
from platform_methods import subprocess_main
-def make_debug_osx(target, source, env):
+def make_debug_macos(target, source, env):
if env["macports_clang"] != "no":
mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local")
mpclangver = env["macports_clang"]
diff --git a/platform/osx/tts_osx.h b/platform/macos/tts_macos.h
index 449418e48f..344676868a 100644
--- a/platform/osx/tts_osx.h
+++ b/platform/macos/tts_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* tts_osx.h */
+/* tts_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef TTS_OSX_H
-#define TTS_OSX_H
+#ifndef TTS_MACOS_H
+#define TTS_MACOS_H
#include "core/string/ustring.h"
#include "core/templates/list.h"
@@ -45,7 +45,7 @@
#import <AVFoundation/AVFoundation.h>
#endif
-@interface TTS_OSX : NSObject <AVSpeechSynthesizerDelegate> {
+@interface TTS_MacOS : NSObject <AVSpeechSynthesizerDelegate> {
// AVSpeechSynthesizer
bool speaking;
HashMap<id, int> ids;
@@ -68,4 +68,4 @@
- (Array)getVoices;
@end
-#endif // TTS_OSX_H
+#endif // TTS_MACOS_H
diff --git a/platform/osx/tts_osx.mm b/platform/macos/tts_macos.mm
index e6a5236cd9..3c101b9531 100644
--- a/platform/osx/tts_osx.mm
+++ b/platform/macos/tts_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* tts_osx.mm */
+/* tts_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "tts_osx.h"
+#include "tts_macos.h"
-@implementation TTS_OSX
+@implementation TTS_MacOS
- (id)init {
self = [super init];
diff --git a/platform/osx/vulkan_context_osx.h b/platform/macos/vulkan_context_macos.h
index ade0f4a4c9..4dc6a12756 100644
--- a/platform/osx/vulkan_context_osx.h
+++ b/platform/macos/vulkan_context_macos.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vulkan_context_osx.h */
+/* vulkan_context_macos.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,20 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VULKAN_DEVICE_OSX_H
-#define VULKAN_DEVICE_OSX_H
+#ifndef VULKAN_DEVICE_MACOS_H
+#define VULKAN_DEVICE_MACOS_H
#include "drivers/vulkan/vulkan_context.h"
#import <AppKit/AppKit.h>
-class VulkanContextOSX : public VulkanContext {
+class VulkanContextMacOS : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height);
- VulkanContextOSX();
- ~VulkanContextOSX();
+ VulkanContextMacOS();
+ ~VulkanContextMacOS();
};
-#endif // VULKAN_DEVICE_OSX_H
+#endif // VULKAN_DEVICE_MACOS_H
diff --git a/platform/osx/vulkan_context_osx.mm b/platform/macos/vulkan_context_macos.mm
index bdabc24c28..cf317f3c68 100644
--- a/platform/osx/vulkan_context_osx.mm
+++ b/platform/macos/vulkan_context_macos.mm
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vulkan_context_osx.mm */
+/* vulkan_context_macos.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,18 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "vulkan_context_osx.h"
+#include "vulkan_context_macos.h"
#ifdef USE_VOLK
#include <volk.h>
#else
#include <vulkan/vulkan.h>
#endif
-const char *VulkanContextOSX::_get_platform_surface_extension() const {
+const char *VulkanContextMacOS::_get_platform_surface_extension() const {
return VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height) {
+Error VulkanContextMacOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height) {
VkMacOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
@@ -52,8 +52,8 @@ Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, Displ
return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
-VulkanContextOSX::VulkanContextOSX() {
+VulkanContextMacOS::VulkanContextMacOS() {
}
-VulkanContextOSX::~VulkanContextOSX() {
+VulkanContextMacOS::~VulkanContextMacOS() {
}
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
deleted file mode 100644
index 3a4c95613d..0000000000
--- a/platform/osx/SCsub
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-
-from platform_methods import run_in_subprocess
-import platform_osx_builders
-
-files = [
- "os_osx.mm",
- "godot_application.mm",
- "godot_application_delegate.mm",
- "crash_handler_osx.mm",
- "osx_terminal_logger.mm",
- "display_server_osx.mm",
- "godot_content_view.mm",
- "godot_window_delegate.mm",
- "godot_window.mm",
- "key_mapping_osx.mm",
- "godot_main_osx.mm",
- "dir_access_osx.mm",
- "tts_osx.mm",
- "joypad_osx.cpp",
- "vulkan_context_osx.mm",
- "gl_manager_osx_legacy.mm",
-]
-
-prog = env.add_program("#bin/godot", files)
-
-if env["debug_symbols"] and env["separate_debug_symbols"]:
- env.AddPostAction(prog, run_in_subprocess(platform_osx_builders.make_debug_osx))
diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp
index 01683c656c..19b43d50be 100644
--- a/platform/uwp/export/export_plugin.cpp
+++ b/platform/uwp/export/export_plugin.cpp
@@ -503,7 +503,5 @@ void EditorExportPlatformUWP::resolve_platform_feature_priorities(const Ref<Edit
}
EditorExportPlatformUWP::EditorExportPlatformUWP() {
- Ref<Image> img = memnew(Image(_uwp_logo));
- logo.instantiate();
- logo->create_from_image(img);
+ logo = ImageTexture::create_from_image(memnew(Image(_uwp_logo)));
}
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 998b0882b3..f9988b23bc 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -656,7 +656,9 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
void DisplayServerWindows::gl_window_make_current(DisplayServer::WindowID p_window_id) {
#if defined(GLES3_ENABLED)
- gl_manager->window_make_current(p_window_id);
+ if (gl_manager) {
+ gl_manager->window_make_current(p_window_id);
+ }
#endif
}
@@ -2380,7 +2382,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
case WM_MOUSELEAVE: {
old_invalid = true;
- outside = true;
+ windows[window_id].mouse_outside = true;
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
@@ -2490,6 +2492,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
windows[window_id].last_tilt = Vector2();
}
+ windows[window_id].last_pen_inverted = packet.pkStatus & TPS_INVERT;
+
POINT coords;
GetCursorPos(&coords);
ScreenToClient(windows[window_id].hWnd, &coords);
@@ -2508,6 +2512,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_pressure(windows[window_id].last_pressure);
mm->set_tilt(windows[window_id].last_tilt);
+ mm->set_pen_inverted(windows[window_id].last_pen_inverted);
mm->set_button_mask(last_button_state);
@@ -2607,7 +2612,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
- if (outside) {
+ if (windows[window_id].mouse_outside) {
// Mouse enter.
if (mouse_mode != MOUSE_MODE_CAPTURED) {
@@ -2617,7 +2622,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
cursor_set_shape(c);
- outside = false;
+ windows[window_id].mouse_outside = false;
// Once-off notification, must call again.
track_mouse_leave_event(hWnd);
@@ -2640,6 +2645,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
if ((pen_info.penMask & PEN_MASK_TILT_X) && (pen_info.penMask & PEN_MASK_TILT_Y)) {
mm->set_tilt(Vector2((float)pen_info.tiltX / 90, (float)pen_info.tiltY / 90));
}
+ mm->set_pen_inverted(pen_info.penFlags & (PEN_FLAG_INVERTED | PEN_FLAG_ERASER));
mm->set_ctrl_pressed(GetKeyState(VK_CONTROL) < 0);
mm->set_shift_pressed(GetKeyState(VK_SHIFT) < 0);
@@ -2707,7 +2713,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
- if (outside) {
+ if (windows[window_id].mouse_outside) {
// Mouse enter.
if (mouse_mode != MOUSE_MODE_CAPTURED) {
@@ -2717,7 +2723,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
cursor_set_shape(c);
- outside = false;
+ windows[window_id].mouse_outside = false;
// Once-off notification, must call again.
track_mouse_leave_event(hWnd);
@@ -2742,14 +2748,17 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} else {
windows[window_id].last_tilt = Vector2();
windows[window_id].last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
+ windows[window_id].last_pen_inverted = false;
}
} else {
windows[window_id].last_tilt = Vector2();
windows[window_id].last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
+ windows[window_id].last_pen_inverted = false;
}
mm->set_pressure(windows[window_id].last_pressure);
mm->set_tilt(windows[window_id].last_tilt);
+ mm->set_pen_inverted(windows[window_id].last_pen_inverted);
mm->set_button_mask(last_button_state);
@@ -3360,8 +3369,8 @@ void DisplayServerWindows::_update_tablet_ctx(const String &p_old_driver, const
if ((p_new_driver == "wintab") && wintab_available) {
wintab_WTInfo(WTI_DEFSYSCTX, 0, &wd.wtlc);
wd.wtlc.lcOptions |= CXO_MESSAGES;
- wd.wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
- wd.wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
+ wd.wtlc.lcPktData = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
+ wd.wtlc.lcMoveMask = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
wd.wtlc.lcPktMode = 0;
wd.wtlc.lcOutOrgX = 0;
wd.wtlc.lcOutExtX = wd.wtlc.lcInExtX;
@@ -3449,6 +3458,12 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
windows.erase(id);
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create Windows OS window.");
}
+ if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
+ wd.fullscreen = true;
+ if (p_mode == WINDOW_MODE_FULLSCREEN) {
+ wd.multiwindow_fs = true;
+ }
+ }
if (p_mode != WINDOW_MODE_FULLSCREEN && p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
wd.pre_fs_valid = true;
}
@@ -3484,8 +3499,8 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
if ((tablet_get_current_driver() == "wintab") && wintab_available) {
wintab_WTInfo(WTI_DEFSYSCTX, 0, &wd.wtlc);
wd.wtlc.lcOptions |= CXO_MESSAGES;
- wd.wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
- wd.wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
+ wd.wtlc.lcPktData = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
+ wd.wtlc.lcMoveMask = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
wd.wtlc.lcPktMode = 0;
wd.wtlc.lcOutOrgX = 0;
wd.wtlc.lcOutExtX = wd.wtlc.lcInExtX;
@@ -3599,8 +3614,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
old_invalid = true;
mouse_mode = MOUSE_MODE_VISIBLE;
- outside = true;
-
rendering_driver = p_rendering_driver;
// Init TTS
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index fc89517774..ddbf674c64 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -82,10 +82,13 @@
#define DVC_ROTATION 18
#define CXO_MESSAGES 0x0004
+#define PK_STATUS 0x0002
#define PK_NORMAL_PRESSURE 0x0400
#define PK_TANGENT_PRESSURE 0x0800
#define PK_ORIENTATION 0x1000
+#define TPS_INVERT 0x0010 /* 1.1 */
+
typedef struct tagLOGCONTEXTW {
WCHAR lcName[40];
UINT lcOptions;
@@ -137,6 +140,7 @@ typedef struct tagORIENTATION {
} ORIENTATION;
typedef struct tagPACKET {
+ int pkStatus;
int pkNormalPressure;
int pkTangentPressure;
ORIENTATION pkOrientation;
@@ -158,6 +162,14 @@ typedef UINT32 POINTER_FLAGS;
typedef UINT32 PEN_FLAGS;
typedef UINT32 PEN_MASK;
+#ifndef PEN_FLAG_INVERTED
+#define PEN_FLAG_INVERTED 0x00000002
+#endif
+
+#ifndef PEN_FLAG_ERASER
+#define PEN_FLAG_ERASER 0x00000004
+#endif
+
#ifndef PEN_MASK_PRESSURE
#define PEN_MASK_PRESSURE 0x00000001
#endif
@@ -301,7 +313,6 @@ class DisplayServerWindows : public DisplayServer {
int key_event_pos;
bool old_invalid;
- bool outside;
int old_x, old_y;
Point2i center;
@@ -357,11 +368,13 @@ class DisplayServerWindows : public DisplayServer {
int min_pressure;
int max_pressure;
bool tilt_supported;
+ bool pen_inverted = false;
bool block_mm = false;
int last_pressure_update;
float last_pressure;
Vector2 last_tilt;
+ bool last_pen_inverted = false;
HBITMAP hBitmap; //DIB section for layered window
uint8_t *dib_data = nullptr;
@@ -373,6 +386,7 @@ class DisplayServerWindows : public DisplayServer {
Size2 window_rect;
Point2 last_pos;
+ bool mouse_outside = true;
ObjectID instance_id;
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index 0fa2913218..af19f24f09 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -48,12 +48,7 @@ void register_windows_exporter() {
Ref<EditorExportPlatformWindows> platform;
platform.instantiate();
-
- Ref<Image> img = memnew(Image(_windows_logo));
- Ref<ImageTexture> logo;
- logo.instantiate();
- logo->create_from_image(img);
- platform->set_logo(logo);
+ platform->set_logo(ImageTexture::create_from_image(memnew(Image(_windows_logo))));
platform->set_name("Windows Desktop");
platform->set_os_name("Windows");
diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp
index 8de3ef294a..72920d2816 100644
--- a/platform/windows/godot_windows.cpp
+++ b/platform/windows/godot_windows.cpp
@@ -166,6 +166,10 @@ int widechar_main(int argc, wchar_t **argv) {
delete[] argv_utf8[i];
}
delete[] argv_utf8;
+
+ if (err == ERR_HELP) { // Returned by --help and --version, so success.
+ return 0;
+ }
return 255;
}
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index 221d52bc20..d56c7b8811 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -138,8 +138,11 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &property) const {
if (property.name == "frame") {
property.hint = PROPERTY_HINT_RANGE;
- if (frames->has_animation(animation) && frames->get_frame_count(animation) > 1) {
+ if (frames->has_animation(animation) && frames->get_frame_count(animation) > 0) {
property.hint_string = "0," + itos(frames->get_frame_count(animation) - 1) + ",1";
+ } else {
+ // Avoid an error, `hint_string` is required for `PROPERTY_HINT_RANGE`.
+ property.hint_string = "0,0,1";
}
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 2616d1f09e..76b354805c 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -439,7 +439,7 @@ void Camera2D::clear_current() {
void Camera2D::set_limit(Side p_side, int p_limit) {
ERR_FAIL_INDEX((int)p_side, 4);
limit[p_side] = p_limit;
- update();
+ _update_scroll();
}
int Camera2D::get_limit(Side p_side) const {
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 913003c7e6..4155d0797f 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -243,7 +243,7 @@ bool CPUParticles2D::get_fractional_delta() const {
}
TypedArray<String> CPUParticles2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+ TypedArray<String> warnings = Node2D::get_configuration_warnings();
CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr());
@@ -314,6 +314,8 @@ void CPUParticles2D::set_param_max(Parameter p_param, real_t p_value) {
if (parameters_min[p_param] > parameters_max[p_param]) {
set_param_min(p_param, p_value);
}
+
+ update_configuration_warnings();
}
real_t CPUParticles2D::get_param_max(Parameter p_param) const {
@@ -374,6 +376,8 @@ void CPUParticles2D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv
default: {
}
}
+
+ update_configuration_warnings();
}
Ref<Curve> CPUParticles2D::get_param_curve(Parameter p_param) const {
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index 6edd75e62a..a869cf2525 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -141,7 +141,6 @@ void GPUParticles2D::set_process_material(const Ref<Material> &p_material) {
void GPUParticles2D::set_trail_enabled(bool p_enabled) {
trail_enabled = p_enabled;
RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_length);
- update_configuration_warnings();
update();
RS::get_singleton()->particles_set_transform_align(particles, p_enabled ? RS::PARTICLES_TRANSFORM_ALIGN_Y_TO_VELOCITY : RS::PARTICLES_TRANSFORM_ALIGN_DISABLED);
@@ -297,7 +296,7 @@ bool GPUParticles2D::get_interpolate() const {
}
TypedArray<String> GPUParticles2D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+ TypedArray<String> warnings = Node2D::get_configuration_warnings();
if (RenderingServer::get_singleton()->is_low_end()) {
warnings.push_back(RTR("GPU-based particles are not supported by the OpenGL video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles2D\" option for this purpose."));
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 5a451a6dab..a5f7faffef 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -87,16 +87,19 @@ void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent2D::_avoidance_done);
+ ADD_GROUP("Pathfinding", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:px"), "set_path_desired_distance", "get_path_desired_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:px"), "set_target_desired_distance", "get_target_desired_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1,suffix:px"), "set_path_max_distance", "get_path_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
+
+ ADD_GROUP("Avoidance", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01,suffix:px"), "set_radius", "get_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_dist", PROPERTY_HINT_RANGE, "0.1,100000,0.01,suffix:px"), "set_neighbor_dist", "get_neighbor_dist");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:s"), "set_time_horizon", "get_time_horizon");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01,suffix:px/s"), "set_max_speed", "get_max_speed");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1,suffix:px"), "set_path_max_distance", "get_path_max_distance");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_SIGNAL(MethodInfo("path_changed"));
ADD_SIGNAL(MethodInfo("target_reached"));
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index ba90a275e6..9862c4bfb1 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -87,13 +87,13 @@ bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
void Path2D::_notification(int p_what) {
switch (p_what) {
- // Draw the curve if navigation debugging is enabled.
+ // Draw the curve if path debugging is enabled.
case NOTIFICATION_DRAW: {
if (!curve.is_valid()) {
break;
}
- if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) {
+ if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_paths_hint()) {
return;
}
@@ -102,12 +102,10 @@ void Path2D::_notification(int p_what) {
}
#ifdef TOOLS_ENABLED
- const real_t line_width = 2 * EDSCALE;
+ const real_t line_width = get_tree()->get_debug_paths_width() * EDSCALE;
#else
- const real_t line_width = 2;
+ const real_t line_width = get_tree()->get_debug_paths_width();
#endif
- const Color color = Color(0.5, 0.6, 1.0, 0.7);
-
_cached_draw_pts.resize(curve->get_point_count() * 8);
int count = 0;
@@ -119,7 +117,7 @@ void Path2D::_notification(int p_what) {
}
}
- draw_polyline(_cached_draw_pts, color, line_width, true);
+ draw_polyline(_cached_draw_pts, get_tree()->get_debug_paths_color(), line_width, true);
} break;
}
}
@@ -129,7 +127,7 @@ void Path2D::_curve_changed() {
return;
}
- if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) {
+ if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_paths_hint()) {
return;
}
@@ -306,6 +304,7 @@ void PathFollow2D::_bind_methods() {
}
void PathFollow2D::set_offset(real_t p_offset) {
+ ERR_FAIL_COND(!isfinite(p_offset));
offset = p_offset;
if (path) {
if (path->get_curve().is_valid()) {
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 9c4b0feea2..cf8b6b8f94 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1158,6 +1158,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
rs->canvas_item_set_transform(canvas_item, xform);
rs->canvas_item_set_light_mask(canvas_item, get_light_mask());
+ rs->canvas_item_set_z_as_relative_to_parent(canvas_item, true);
rs->canvas_item_set_z_index(canvas_item, z_index);
rs->canvas_item_set_default_texture_filter(canvas_item, RS::CanvasItemTextureFilter(get_texture_filter()));
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 0ac94b9d45..012bf01df9 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -130,7 +130,7 @@ public:
}
String to_string() const {
- return vformat("Constraint {pos:%s, bit:%d, terrain:%d, priotity:%d}", base_cell_coords, bit, terrain, priority);
+ return vformat("Constraint {pos:%s, bit:%d, terrain:%d, priority:%d}", base_cell_coords, bit, terrain, priority);
}
Vector2i get_base_cell_coords() const {
diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp
index d0aeffb166..fbd5b5b65b 100644
--- a/scene/3d/bone_attachment_3d.cpp
+++ b/scene/3d/bone_attachment_3d.cpp
@@ -376,6 +376,24 @@ void BoneAttachment3D::on_bone_pose_update(int p_bone_index) {
}
}
}
+#ifdef TOOLS_ENABLED
+void BoneAttachment3D::_notify_skeleton_bones_renamed(Node *p_base_scene, Skeleton3D *p_skeleton, Ref<BoneMap> p_bone_map) {
+ const Skeleton3D *parent = nullptr;
+ if (use_external_skeleton) {
+ if (external_skeleton_node_cache.is_valid()) {
+ parent = Object::cast_to<Skeleton3D>(ObjectDB::get_instance(external_skeleton_node_cache));
+ }
+ } else {
+ parent = Object::cast_to<Skeleton3D>(get_parent());
+ }
+ if (parent && parent == p_skeleton) {
+ StringName bn = p_bone_map->find_profile_bone_name(bone_name);
+ if (bn) {
+ set_bone_name(bn);
+ }
+ }
+}
+#endif // TOOLS_ENABLED
BoneAttachment3D::BoneAttachment3D() {
}
@@ -398,6 +416,9 @@ void BoneAttachment3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_use_external_skeleton"), &BoneAttachment3D::get_use_external_skeleton);
ClassDB::bind_method(D_METHOD("set_external_skeleton", "external_skeleton"), &BoneAttachment3D::set_external_skeleton);
ClassDB::bind_method(D_METHOD("get_external_skeleton"), &BoneAttachment3D::get_external_skeleton);
+#ifdef TOOLS_ENABLED
+ ClassDB::bind_method(D_METHOD("_notify_skeleton_bones_renamed"), &BoneAttachment3D::_notify_skeleton_bones_renamed);
+#endif // TOOLS_ENABLED
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bone_name"), "set_bone_name", "get_bone_name");
ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_idx"), "set_bone_idx", "get_bone_idx");
diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h
index 395dfde1d7..137360b141 100644
--- a/scene/3d/bone_attachment_3d.h
+++ b/scene/3d/bone_attachment_3d.h
@@ -32,6 +32,9 @@
#define BONE_ATTACHMENT_H
#include "scene/3d/skeleton_3d.h"
+#ifdef TOOLS_ENABLED
+#include "scene/resources/bone_map.h"
+#endif // TOOLS_ENABLED
class BoneAttachment3D : public Node3D {
GDCLASS(BoneAttachment3D, Node3D);
@@ -68,6 +71,9 @@ protected:
void _notification(int p_what);
static void _bind_methods();
+#ifdef TOOLS_ENABLED
+ virtual void _notify_skeleton_bones_renamed(Node *p_base_scene, Skeleton3D *p_skeleton, Ref<BoneMap> p_bone_map);
+#endif // TOOLS_ENABLED
public:
virtual TypedArray<String> get_configuration_warnings() const override;
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index 8585f3bdfc..4df0c37ad6 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -164,6 +164,8 @@ void CPUParticles3D::set_mesh(const Ref<Mesh> &p_mesh) {
} else {
RS::get_singleton()->multimesh_set_mesh(multimesh, RID());
}
+
+ update_configuration_warnings();
}
Ref<Mesh> CPUParticles3D::get_mesh() const {
@@ -187,7 +189,7 @@ bool CPUParticles3D::get_fractional_delta() const {
}
TypedArray<String> CPUParticles3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+ TypedArray<String> warnings = GeometryInstance3D::get_configuration_warnings();
bool mesh_found = false;
bool anim_material_found = false;
@@ -266,6 +268,8 @@ void CPUParticles3D::set_param_min(Parameter p_param, real_t p_value) {
if (parameters_min[p_param] > parameters_max[p_param]) {
set_param_max(p_param, p_value);
}
+
+ update_configuration_warnings();
}
real_t CPUParticles3D::get_param_min(Parameter p_param) const {
@@ -276,10 +280,13 @@ real_t CPUParticles3D::get_param_min(Parameter p_param) const {
void CPUParticles3D::set_param_max(Parameter p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
+
parameters_max[p_param] = p_value;
if (parameters_min[p_param] > parameters_max[p_param]) {
set_param_min(p_param, p_value);
}
+
+ update_configuration_warnings();
}
real_t CPUParticles3D::get_param_max(Parameter p_param) const {
@@ -340,6 +347,8 @@ void CPUParticles3D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv
default: {
}
}
+
+ update_configuration_warnings();
}
Ref<Curve> CPUParticles3D::get_param_curve(Parameter p_param) const {
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index ab07f33ace..01cab493ec 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -72,7 +72,7 @@ real_t Decal::get_albedo_mix() const {
}
void Decal::set_upper_fade(real_t p_fade) {
- upper_fade = p_fade;
+ upper_fade = MAX(p_fade, 0.0);
RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade);
}
@@ -81,7 +81,7 @@ real_t Decal::get_upper_fade() const {
}
void Decal::set_lower_fade(real_t p_fade) {
- lower_fade = p_fade;
+ lower_fade = MAX(p_fade, 0.0);
RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade);
}
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index d18c452ca7..b352114c7f 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -270,7 +270,7 @@ bool GPUParticles3D::get_interpolate() const {
}
TypedArray<String> GPUParticles3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+ TypedArray<String> warnings = GeometryInstance3D::get_configuration_warnings();
if (RenderingServer::get_singleton()->is_low_end()) {
warnings.push_back(RTR("GPU-based particles are not supported by the OpenGL video driver.\nUse the CPUParticles3D node instead. You can use the \"Convert to CPUParticles3D\" option for this purpose."));
diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp
index 0849b2c631..bc435c5451 100644
--- a/scene/3d/label_3d.cpp
+++ b/scene/3d/label_3d.cpp
@@ -53,10 +53,6 @@ void Label3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label3D::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &Label3D::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &Label3D::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &Label3D::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features"), &Label3D::clear_opentype_features);
-
ClassDB::bind_method(D_METHOD("set_language", "language"), &Label3D::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &Label3D::get_language);
@@ -140,7 +136,7 @@ void Label3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_modulate"), "set_outline_modulate", "get_outline_modulate");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, ""), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,127,1,suffix:px"), "set_font_size", "get_font_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px"), "set_font_size", "get_font_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1,suffix:px"), "set_outline_size", "get_outline_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom"), "set_vertical_alignment", "get_vertical_alignment");
@@ -148,12 +144,12 @@ void Label3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_spacing", PROPERTY_HINT_NONE, "suffix:px"), "set_line_spacing", "get_line_spacing");
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width", PROPERTY_HINT_NONE, "suffix:px"), "set_width", "get_width");
- 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("Locale", "");
+ ADD_GROUP("BiDi", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left"), "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, "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");
BIND_ENUM_CONSTANT(FLAG_SHADED);
BIND_ENUM_CONSTANT(FLAG_DOUBLE_SIDED);
@@ -166,56 +162,6 @@ void Label3D::_bind_methods() {
BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
}
-bool Label3D::_set(const StringName &p_name, const Variant &p_value) {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- int value = p_value;
- if (value == -1) {
- if (opentype_features.has(tag)) {
- opentype_features.erase(tag);
- dirty_font = true;
- _queue_update();
- }
- } else {
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
- opentype_features[tag] = value;
- dirty_font = true;
- _queue_update();
- }
- }
- notify_property_list_changed();
- return true;
- }
-
- return false;
-}
-
-bool Label3D::_get(const StringName &p_name, Variant &r_ret) const {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- if (opentype_features.has(tag)) {
- r_ret = opentype_features[tag];
- return true;
- } else {
- r_ret = -1;
- return true;
- }
- }
- return false;
-}
-
-void Label3D::_get_property_list(List<PropertyInfo> *p_list) const {
- for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
- String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
- }
- p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
-}
-
void Label3D::_validate_property(PropertyInfo &property) const {
if (property.name == "material_override" || property.name == "material_overlay") {
property.usage = PROPERTY_USAGE_NO_EDITOR;
@@ -280,7 +226,7 @@ Ref<TriangleMesh> Label3D::generate_triangle_mesh() const {
float total_h = 0.0;
float max_line_w = 0.0;
for (int i = 0; i < lines_rid.size(); i++) {
- total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
+ total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
max_line_w = MAX(max_line_w, TS->shaped_text_get_width(lines_rid[i]));
}
@@ -370,15 +316,8 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset,
bool msdf = TS->font_is_multichannel_signed_distance_field(p_glyph.font_rid);
- uint64_t mat_hash;
- if (tex != RID()) {
- mat_hash = hash_one_uint64(tex.get_id());
- } else {
- mat_hash = hash_one_uint64(0);
- }
- mat_hash = hash_fmix32(hash_murmur3_one_64(p_priority | (p_outline_size << 31), mat_hash));
-
- if (!surfaces.has(mat_hash)) {
+ SurfaceKey key = SurfaceKey(tex.get_id(), p_priority, p_outline_size);
+ if (!surfaces.has(key)) {
SurfaceData surf;
surf.material = RenderingServer::get_singleton()->material_create();
// Set defaults for material, names need to match up those in StandardMaterial3D
@@ -407,9 +346,9 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset,
surf.z_shift = p_priority * pixel_size;
}
- surfaces[mat_hash] = surf;
+ surfaces[key] = surf;
}
- SurfaceData &s = surfaces[mat_hash];
+ SurfaceData &s = surfaces[key];
s.mesh_vertices.resize((s.offset + 1) * 4);
s.mesh_normals.resize((s.offset + 1) * 4);
@@ -464,7 +403,7 @@ void Label3D::_shape() {
aabb = AABB();
// Clear materials.
- for (const KeyValue<uint64_t, SurfaceData> &E : surfaces) {
+ for (const KeyValue<SurfaceKey, SurfaceData> &E : surfaces) {
RenderingServer::get_singleton()->free(E.value.material);
}
surfaces.clear();
@@ -478,7 +417,10 @@ void Label3D::_shape() {
TS->shaped_text_set_direction(text_rid, text_direction);
String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
- TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, language);
+ TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, font->get_opentype_features(), language);
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
+ }
Array stt;
if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) {
@@ -494,7 +436,10 @@ void Label3D::_shape() {
} else if (dirty_font) {
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_set_span_update_font(text_rid, i, font->get_rids(), font_size, font->get_opentype_features());
+ }
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
}
dirty_font = false;
@@ -507,10 +452,10 @@ void Label3D::_shape() {
}
lines_rid.clear();
- uint16_t autowrap_flags = TextServer::BREAK_MANDATORY;
+ BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY;
switch (autowrap_mode) {
case TextServer::AUTOWRAP_WORD_SMART:
- autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY;
+ autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY;
break;
case TextServer::AUTOWRAP_WORD:
autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY;
@@ -541,7 +486,7 @@ void Label3D::_shape() {
// Generate surfaces and materials.
float total_h = 0.0;
for (int i = 0; i < lines_rid.size(); i++) {
- total_h += (TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing) * pixel_size;
+ total_h += (TS->shaped_text_get_size(lines_rid[i]).y + line_spacing) * pixel_size;
}
float vbegin = 0.0;
@@ -577,7 +522,7 @@ void Label3D::_shape() {
} break;
}
offset.x += lbl_offset.x * pixel_size;
- offset.y -= (TS->shaped_text_get_ascent(lines_rid[i]) + font->get_spacing(TextServer::SPACING_TOP)) * pixel_size;
+ offset.y -= TS->shaped_text_get_ascent(lines_rid[i]) * pixel_size;
if (outline_modulate.a != 0.0 && outline_size > 0) {
// Outline surfaces.
@@ -591,10 +536,10 @@ void Label3D::_shape() {
for (int j = 0; j < gl_size; j++) {
_generate_glyph_surfaces(glyphs[j], offset, modulate, render_priority);
}
- offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing + font->get_spacing(TextServer::SPACING_BOTTOM)) * pixel_size;
+ offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing) * pixel_size;
}
- for (const KeyValue<uint64_t, SurfaceData> &E : surfaces) {
+ for (const KeyValue<SurfaceKey, SurfaceData> &E : surfaces) {
Array mesh_array;
mesh_array.resize(RS::ARRAY_MAX);
mesh_array[RS::ARRAY_VERTEX] = E.value.mesh_vertices;
@@ -664,29 +609,6 @@ TextServer::Direction Label3D::get_text_direction() const {
return text_direction;
}
-void Label3D::clear_opentype_features() {
- opentype_features.clear();
- dirty_font = true;
- _queue_update();
-}
-
-void Label3D::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_font = true;
- _queue_update();
- }
-}
-
-int Label3D::get_opentype_feature(const String &p_name) const {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag)) {
- return -1;
- }
- return opentype_features[tag];
-}
-
void Label3D::set_language(const String &p_language) {
if (language != p_language) {
language = p_language;
@@ -788,7 +710,7 @@ Ref<Font> Label3D::_get_font_or_default() const {
theme_font.unref();
}
- if (font_override.is_valid() && font_override->get_data_count() > 0) {
+ if (font_override.is_valid()) {
return font_override;
}
@@ -1018,7 +940,7 @@ Label3D::~Label3D() {
TS->free_rid(text_rid);
RenderingServer::get_singleton()->free(mesh);
- for (KeyValue<uint64_t, SurfaceData> E : surfaces) {
+ for (KeyValue<SurfaceKey, SurfaceData> E : surfaces) {
RenderingServer::get_singleton()->free(E.value.material);
}
surfaces.clear();
diff --git a/scene/3d/label_3d.h b/scene/3d/label_3d.h
index 7766bca068..4498e89517 100644
--- a/scene/3d/label_3d.h
+++ b/scene/3d/label_3d.h
@@ -76,7 +76,29 @@ private:
RID material;
};
- HashMap<uint64_t, SurfaceData> surfaces;
+ struct SurfaceKey {
+ uint64_t texture_id;
+ int32_t priority;
+ int32_t outline_size;
+
+ bool operator==(const SurfaceKey &p_b) const {
+ return (texture_id == p_b.texture_id) && (priority == p_b.priority) && (outline_size == p_b.outline_size);
+ }
+
+ SurfaceKey(uint64_t p_texture_id, int p_priority, int p_outline_size) {
+ texture_id = p_texture_id;
+ priority = p_priority;
+ outline_size = p_outline_size;
+ }
+ };
+
+ struct SurfaceKeyHasher {
+ _FORCE_INLINE_ static uint32_t hash(const SurfaceKey &p_a) {
+ return hash_murmur3_buffer(&p_a, sizeof(SurfaceKey));
+ }
+ };
+
+ HashMap<SurfaceKey, SurfaceData, SurfaceKeyHasher> surfaces;
HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER;
VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_CENTER;
@@ -100,7 +122,6 @@ private:
float line_spacing = 0.f;
- Dictionary opentype_features;
String language;
TextServer::Direction text_direction = TextServer::DIRECTION_AUTO;
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
@@ -128,9 +149,6 @@ protected:
static void _bind_methods();
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
void _validate_property(PropertyInfo &property) const override;
void _im_update();
@@ -158,10 +176,6 @@ public:
void set_text_direction(TextServer::Direction p_text_direction);
TextServer::Direction get_text_direction() const;
- void set_opentype_feature(const String &p_name, int p_value);
- int get_opentype_feature(const String &p_name) const;
- void clear_opentype_features();
-
void set_language(const String &p_language);
String get_language() const;
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index abe942b97a..e805d28ed3 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -146,7 +146,7 @@ Array LightmapGIData::_get_light_textures_data() const {
texture_image->create(slice_width, slice_height * texture_slice_count, false, images[0]->get_format());
for (int j = 0; j < texture_slice_count; j++) {
- texture_image->blit_rect(images[i * slices_per_texture + j], Rect2(0, 0, slice_width, slice_height), Point2(0, slice_height * j));
+ texture_image->blit_rect(images[i * slices_per_texture + j], Rect2i(0, 0, slice_width, slice_height), Point2i(0, slice_height * j));
}
String texture_path = texture_count > 1 ? base_name + "_" + itos(i) + ".exr" : base_name + ".exr";
@@ -291,7 +291,7 @@ void LightmapGIData::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_probe_data", "data"), &LightmapGIData::_set_probe_data);
ClassDB::bind_method(D_METHOD("_get_probe_data"), &LightmapGIData::_get_probe_data);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_texture", PROPERTY_HINT_RESOURCE_TYPE, "TextureLayered", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK), "set_light_texture", "get_light_texture"); // property usage default but no save
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_texture", PROPERTY_HINT_RESOURCE_TYPE, "TextureLayered", PROPERTY_USAGE_EDITOR), "set_light_texture", "get_light_texture"); // property usage default but no save
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "light_textures", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_light_textures_data", "_get_light_textures_data");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uses_spherical_harmonics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_uses_spherical_harmonics", "is_using_spherical_harmonics");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "user_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_user_data", "_get_user_data");
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index e5ec444335..3752713d6a 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -91,18 +91,21 @@ void NavigationAgent3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent3D::_avoidance_done);
+ ADD_GROUP("Pathfinding", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_path_desired_distance", "get_path_desired_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_target_desired_distance", "get_target_desired_distance");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_radius", "get_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,suffix:m"), "set_agent_height_offset", "get_agent_height_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1,suffix:m"), "set_path_max_distance", "get_path_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
+
+ ADD_GROUP("Avoidance", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_radius", "get_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_dist", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:m"), "set_neighbor_dist", "get_neighbor_dist");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.01,100,0.01,suffix:s"), "set_time_horizon", "get_time_horizon");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:m/s"), "set_max_speed", "get_max_speed");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1,suffix:m"), "set_path_max_distance", "get_path_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_SIGNAL(MethodInfo("path_changed"));
ADD_SIGNAL(MethodInfo("target_reached"));
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 4c00250162..04b1081516 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -237,6 +237,28 @@ void Node3D::set_quaternion(const Quaternion &p_quaternion) {
}
}
+Vector3 Node3D::get_global_position() const {
+ return get_global_transform().get_origin();
+}
+
+void Node3D::set_global_position(const Vector3 &p_position) {
+ Transform3D transform = get_global_transform();
+ transform.set_origin(p_position);
+ set_global_transform(transform);
+}
+
+Vector3 Node3D::get_global_rotation() const {
+ return get_global_transform().get_basis().get_euler();
+}
+
+void Node3D::set_global_rotation(const Vector3 &p_euler_rad) {
+ Transform3D transform = get_global_transform();
+ Basis new_basis = transform.get_basis();
+ new_basis.set_euler(p_euler_rad);
+ transform.set_basis(new_basis);
+ set_global_transform(transform);
+}
+
void Node3D::set_transform(const Transform3D &p_transform) {
data.local_transform = p_transform;
data.dirty = DIRTY_EULER_ROTATION_AND_SCALE; // Make rot/scale dirty.
@@ -950,8 +972,14 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_quaternion"), &Node3D::get_quaternion);
ClassDB::bind_method(D_METHOD("set_basis", "basis"), &Node3D::set_basis);
ClassDB::bind_method(D_METHOD("get_basis"), &Node3D::get_basis);
+
ClassDB::bind_method(D_METHOD("set_global_transform", "global"), &Node3D::set_global_transform);
ClassDB::bind_method(D_METHOD("get_global_transform"), &Node3D::get_global_transform);
+ ClassDB::bind_method(D_METHOD("set_global_position", "position"), &Node3D::set_global_position);
+ ClassDB::bind_method(D_METHOD("get_global_position"), &Node3D::get_global_position);
+ ClassDB::bind_method(D_METHOD("set_global_rotation", "radians"), &Node3D::set_global_rotation);
+ ClassDB::bind_method(D_METHOD("get_global_rotation"), &Node3D::get_global_rotation);
+
ClassDB::bind_method(D_METHOD("get_parent_node_3d"), &Node3D::get_parent_node_3d);
ClassDB::bind_method(D_METHOD("set_ignore_transform_notification", "enabled"), &Node3D::set_ignore_transform_notification);
ClassDB::bind_method(D_METHOD("set_as_top_level", "enable"), &Node3D::set_as_top_level);
@@ -1034,6 +1062,9 @@ void Node3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_edit_mode", PROPERTY_HINT_ENUM, "Euler,Quaternion,Basis"), "set_rotation_edit_mode", "get_rotation_edit_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_order", PROPERTY_HINT_ENUM, "XYZ,XZY,YXZ,YZX,ZXY,ZYX"), "set_rotation_order", "get_rotation_order");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level");
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "global_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_position", "get_global_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "global_rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_rotation", "get_global_rotation");
ADD_GROUP("Visibility", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "visibility_parent", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GeometryInstance3D"), "set_visibility_parent", "get_visibility_parent");
diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h
index cfd88585e4..b1e129798d 100644
--- a/scene/3d/node_3d.h
+++ b/scene/3d/node_3d.h
@@ -182,12 +182,18 @@ public:
void set_rotation(const Vector3 &p_euler_rad);
void set_scale(const Vector3 &p_scale);
+ void set_global_position(const Vector3 &p_position);
+ void set_global_rotation(const Vector3 &p_euler_rad);
+
Vector3 get_position() const;
RotationOrder get_rotation_order() const;
Vector3 get_rotation() const;
Vector3 get_scale() const;
+ Vector3 get_global_position() const;
+ Vector3 get_global_rotation() const;
+
void set_transform(const Transform3D &p_transform);
void set_basis(const Basis &p_basis);
void set_quaternion(const Quaternion &p_quaternion);
diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp
index e13cf6f9c8..1f10337b4c 100644
--- a/scene/3d/path_3d.cpp
+++ b/scene/3d/path_3d.cpp
@@ -30,6 +30,92 @@
#include "path_3d.h"
+Path3D::Path3D() {
+ SceneTree *st = SceneTree::get_singleton();
+ if (st && st->is_debugging_paths_hint()) {
+ debug_instance = RS::get_singleton()->instance_create();
+ set_notify_transform(true);
+ _update_debug_mesh();
+ }
+}
+
+Path3D::~Path3D() {
+ if (debug_instance.is_valid()) {
+ RS::get_singleton()->free(debug_instance);
+ }
+ if (debug_mesh.is_valid()) {
+ RS::get_singleton()->free(debug_mesh->get_rid());
+ }
+}
+
+void Path3D::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ SceneTree *st = SceneTree::get_singleton();
+ if (st && st->is_debugging_paths_hint()) {
+ _update_debug_mesh();
+ }
+ } break;
+
+ case NOTIFICATION_EXIT_TREE: {
+ SceneTree *st = SceneTree::get_singleton();
+ if (st && st->is_debugging_paths_hint()) {
+ RS::get_singleton()->instance_set_visible(debug_instance, false);
+ }
+ } break;
+
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+ if (is_inside_tree() && debug_instance.is_valid()) {
+ RS::get_singleton()->instance_set_transform(debug_instance, get_global_transform());
+ }
+ } break;
+ }
+}
+
+void Path3D::_update_debug_mesh() {
+ SceneTree *st = SceneTree::get_singleton();
+ if (!(st && st->is_debugging_paths_hint())) {
+ return;
+ }
+
+ if (!debug_mesh.is_valid()) {
+ debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
+ }
+
+ if (!(curve.is_valid())) {
+ RS::get_singleton()->instance_set_visible(debug_instance, false);
+ return;
+ }
+ if (curve->get_point_count() < 2) {
+ RS::get_singleton()->instance_set_visible(debug_instance, false);
+ return;
+ }
+
+ Vector<Vector3> vertex_array;
+
+ for (int i = 1; i < curve->get_point_count(); i++) {
+ Vector3 line_end = curve->get_point_position(i);
+ Vector3 line_start = curve->get_point_position(i - 1);
+ vertex_array.push_back(line_start);
+ vertex_array.push_back(line_end);
+ }
+
+ Array mesh_array;
+ mesh_array.resize(Mesh::ARRAY_MAX);
+ mesh_array[Mesh::ARRAY_VERTEX] = vertex_array;
+
+ debug_mesh->clear_surfaces();
+ debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, mesh_array);
+
+ RS::get_singleton()->instance_set_base(debug_instance, debug_mesh->get_rid());
+ RS::get_singleton()->mesh_surface_set_material(debug_mesh->get_rid(), 0, st->get_debug_paths_material()->get_rid());
+ if (is_inside_tree()) {
+ RS::get_singleton()->instance_set_scenario(debug_instance, get_world_3d()->get_scenario());
+ RS::get_singleton()->instance_set_transform(debug_instance, get_global_transform());
+ RS::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree());
+ }
+}
+
void Path3D::_curve_changed() {
if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
update_gizmos();
@@ -48,6 +134,10 @@ void Path3D::_curve_changed() {
}
}
}
+ SceneTree *st = SceneTree::get_singleton();
+ if (st && st->is_debugging_paths_hint()) {
+ _update_debug_mesh();
+ }
}
void Path3D::set_curve(const Ref<Curve3D> &p_curve) {
@@ -307,6 +397,7 @@ void PathFollow3D::_bind_methods() {
}
void PathFollow3D::set_offset(real_t p_offset) {
+ ERR_FAIL_COND(!isfinite(p_offset));
prev_offset = offset;
offset = p_offset;
diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h
index cb67a044d1..7c7284534e 100644
--- a/scene/3d/path_3d.h
+++ b/scene/3d/path_3d.h
@@ -41,14 +41,23 @@ class Path3D : public Node3D {
void _curve_changed();
+ RID debug_instance;
+ Ref<ArrayMesh> debug_mesh;
+
+private:
+ void _update_debug_mesh();
+
protected:
+ void _notification(int p_what);
+
static void _bind_methods();
public:
void set_curve(const Ref<Curve3D> &p_curve);
Ref<Curve3D> get_curve() const;
- Path3D() {}
+ Path3D();
+ ~Path3D();
};
class PathFollow3D : public Node3D {
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index fbd5f31dd5..b342660b85 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -639,6 +639,7 @@ void Skeleton3D::remove_bone_child(int p_bone, int p_child) {
}
Vector<int> Skeleton3D::get_parentless_bones() {
+ _update_process_order();
return parentless_bones;
}
@@ -765,8 +766,6 @@ void Skeleton3D::_make_dirty() {
}
void Skeleton3D::localize_rests() {
- _update_process_order();
-
Vector<int> bones_to_process = get_parentless_bones();
while (bones_to_process.size() > 0) {
int current_bone_idx = bones_to_process[0];
@@ -958,7 +957,6 @@ Ref<Skin> Skeleton3D::create_skin_from_rest_transforms() {
skin.instantiate();
skin->set_bind_count(bones.size());
- _update_process_order(); // Just in case.
// Pose changed, rebuild cache of inverses.
const Bone *bonesptr = bones.ptr();
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 55b55d924c..cb6354f7a8 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -1034,8 +1034,11 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &property) const {
if (property.name == "frame") {
property.hint = PROPERTY_HINT_RANGE;
- if (frames->has_animation(animation) && frames->get_frame_count(animation) > 1) {
+ if (frames->has_animation(animation) && frames->get_frame_count(animation) > 0) {
property.hint_string = "0," + itos(frames->get_frame_count(animation) - 1) + ",1";
+ } else {
+ // Avoid an error, `hint_string` is required for `PROPERTY_HINT_RANGE`.
+ property.hint_string = "0,0,1";
}
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index 6df50bc491..69917f6992 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -471,7 +471,6 @@ void GeometryInstance3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_end", "get_visibility_range_end");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_end_margin", "get_visibility_range_end_margin");
ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_range_fade_mode", PROPERTY_HINT_ENUM, "Disabled,Self,Dependencies"), "set_visibility_range_fade_mode", "get_visibility_range_fade_mode");
- //ADD_SIGNAL( MethodInfo("visibility_changed"));
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF);
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_ON);
@@ -494,7 +493,6 @@ void GeometryInstance3D::_bind_methods() {
}
GeometryInstance3D::GeometryInstance3D() {
- //RS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0);
}
GeometryInstance3D::~GeometryInstance3D() {
diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h
index e5f98bd65e..9e0d9b9a2a 100644
--- a/scene/3d/visual_instance_3d.h
+++ b/scene/3d/visual_instance_3d.h
@@ -126,7 +126,7 @@ private:
float extra_cull_margin = 0.0;
LightmapScale lightmap_scale = LIGHTMAP_SCALE_1X;
- GIMode gi_mode = GI_MODE_DISABLED;
+ GIMode gi_mode = GI_MODE_STATIC;
bool ignore_occlusion_culling = false;
const StringName *_instance_uniform_get_remap(const StringName p_name) const;
diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp
index d81b59b3fc..ae231026a7 100644
--- a/scene/3d/voxel_gi.cpp
+++ b/scene/3d/voxel_gi.cpp
@@ -272,7 +272,8 @@ VoxelGI::Subdiv VoxelGI::get_subdiv() const {
}
void VoxelGI::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
+ // Prevent very small extents as these break baking if other extents are set very high.
+ extents = Vector3(MAX(1.0, p_extents.x), MAX(1.0, p_extents.y), MAX(1.0, p_extents.z));
update_gizmos();
}
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index 594f98410e..d9a5adc883 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -78,6 +78,9 @@ void AnimationNodeBlendSpace1D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_value_label", "text"), &AnimationNodeBlendSpace1D::set_value_label);
ClassDB::bind_method(D_METHOD("get_value_label"), &AnimationNodeBlendSpace1D::get_value_label);
+ ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlendSpace1D::set_use_sync);
+ ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlendSpace1D::is_using_sync);
+
ClassDB::bind_method(D_METHOD("_add_blend_point", "index", "node"), &AnimationNodeBlendSpace1D::_add_blend_point);
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
@@ -89,6 +92,7 @@ void AnimationNodeBlendSpace1D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_max_space", "get_max_space");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_snap", "get_snap");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "value_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_value_label", "get_value_label");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_use_sync", "is_using_sync");
}
void AnimationNodeBlendSpace1D::get_child_nodes(List<ChildNode> *r_child_nodes) {
@@ -211,6 +215,14 @@ String AnimationNodeBlendSpace1D::get_value_label() const {
return value_label;
}
+void AnimationNodeBlendSpace1D::set_use_sync(bool p_sync) {
+ sync = p_sync;
+}
+
+bool AnimationNodeBlendSpace1D::is_using_sync() const {
+ return sync;
+}
+
void AnimationNodeBlendSpace1D::_add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node) {
if (p_index == blend_points_used) {
add_blend_point(p_node, 0);
@@ -226,7 +238,7 @@ double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_see
if (blend_points_used == 1) {
// only one point available, just play that animation
- return blend_node(blend_points[0].name, blend_points[0].node, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, false);
+ return blend_node(blend_points[0].name, blend_points[0].node, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, true);
}
double blend_pos = get_parameter(blend_position);
@@ -295,9 +307,12 @@ double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_see
double max_time_remaining = 0.0;
for (int i = 0; i < blend_points_used; i++) {
- double remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, weights[i], FILTER_IGNORE, false);
-
- max_time_remaining = MAX(max_time_remaining, remaining);
+ if (i == point_lower || i == point_higher) {
+ double remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, weights[i], FILTER_IGNORE, true);
+ max_time_remaining = MAX(max_time_remaining, remaining);
+ } else {
+ blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, 0, FILTER_IGNORE, sync);
+ }
}
return max_time_remaining;
diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h
index b2075c8c93..346e8a3a2f 100644
--- a/scene/animation/animation_blend_space_1d.h
+++ b/scene/animation/animation_blend_space_1d.h
@@ -63,6 +63,8 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode {
StringName blend_position = "blend_position";
protected:
+ bool sync = false;
+
virtual void _validate_property(PropertyInfo &property) const override;
static void _bind_methods();
@@ -93,6 +95,9 @@ public:
void set_value_label(const String &p_label);
String get_value_label() const;
+ void set_use_sync(bool p_sync);
+ bool is_using_sync() const;
+
double process(double p_time, bool p_seek, bool p_seek_root) override;
String get_caption() const override;
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index acdce2d7de..0f77befd9d 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -502,7 +502,7 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_see
for (int j = 0; j < 3; j++) {
if (i == triangle_points[j]) {
//blend with the given weight
- double t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, blend_weights[j], FILTER_IGNORE, false);
+ double t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, blend_weights[j], FILTER_IGNORE, true);
if (first || t < mind) {
mind = t;
first = false;
@@ -513,8 +513,7 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_see
}
if (!found) {
- //ignore
- blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, 0, FILTER_IGNORE, false);
+ blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, 0, FILTER_IGNORE, sync);
}
}
} else {
@@ -539,16 +538,22 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_see
na_n->set_backward(na_c->is_backward());
}
//see how much animation remains
- from = length_internal - blend_node(blend_points[closest].name, blend_points[closest].node, p_time, false, p_seek_root, 0.0, FILTER_IGNORE, false);
+ from = length_internal - blend_node(blend_points[closest].name, blend_points[closest].node, p_time, false, p_seek_root, 0.0, FILTER_IGNORE, true);
}
- mind = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, p_seek_root, 1.0, FILTER_IGNORE, false);
+ mind = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, p_seek_root, 1.0, FILTER_IGNORE, true);
length_internal = from + mind;
closest = new_closest;
} else {
- mind = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, false);
+ mind = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, true);
+ }
+
+ for (int i = 0; i < blend_points_used; i++) {
+ if (i != closest) {
+ blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, 0, FILTER_IGNORE, sync);
+ }
}
}
@@ -604,6 +609,14 @@ AnimationNodeBlendSpace2D::BlendMode AnimationNodeBlendSpace2D::get_blend_mode()
return blend_mode;
}
+void AnimationNodeBlendSpace2D::set_use_sync(bool p_sync) {
+ sync = p_sync;
+}
+
+bool AnimationNodeBlendSpace2D::is_using_sync() const {
+ return sync;
+}
+
void AnimationNodeBlendSpace2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_blend_point", "node", "pos", "at_index"), &AnimationNodeBlendSpace2D::add_blend_point, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_blend_point_position", "point", "pos"), &AnimationNodeBlendSpace2D::set_blend_point_position);
@@ -644,6 +657,9 @@ void AnimationNodeBlendSpace2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_blend_mode", "mode"), &AnimationNodeBlendSpace2D::set_blend_mode);
ClassDB::bind_method(D_METHOD("get_blend_mode"), &AnimationNodeBlendSpace2D::get_blend_mode);
+ ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlendSpace2D::set_use_sync);
+ ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlendSpace2D::is_using_sync);
+
ClassDB::bind_method(D_METHOD("_update_triangles"), &AnimationNodeBlendSpace2D::_update_triangles);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_auto_triangles", "get_auto_triangles");
@@ -661,6 +677,7 @@ void AnimationNodeBlendSpace2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "x_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_x_label", "get_x_label");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "y_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_y_label", "get_y_label");
ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Interpolated,Discrete,Carry", PROPERTY_USAGE_NO_EDITOR), "set_blend_mode", "get_blend_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_use_sync", "is_using_sync");
ADD_SIGNAL(MethodInfo("triangles_updated"));
BIND_ENUM_CONSTANT(BLEND_MODE_INTERPOLATED);
diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h
index 01f53ed25a..689b96e356 100644
--- a/scene/animation/animation_blend_space_2d.h
+++ b/scene/animation/animation_blend_space_2d.h
@@ -88,6 +88,8 @@ protected:
void _tree_changed();
protected:
+ bool sync = false;
+
virtual void _validate_property(PropertyInfo &property) const override;
static void _bind_methods();
@@ -137,6 +139,9 @@ public:
void set_blend_mode(BlendMode p_blend_mode);
BlendMode get_blend_mode() const;
+ void set_use_sync(bool p_sync);
+ bool is_using_sync() const;
+
virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) override;
AnimationNodeBlendSpace2D();
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 1d537837bd..d0aac931c0 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -104,11 +104,11 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_seek_r
if (anim->get_loop_mode() == Animation::LOOP_PINGPONG) {
if (!Math::is_zero_approx(anim_size)) {
if ((int)Math::floor(abs(time - prev_time) / anim_size) % 2 == 0) {
- if (prev_time > 0 && time <= 0) {
+ if (prev_time >= 0 && time < 0) {
backward = !backward;
pingponged = -1;
}
- if (prev_time < anim_size && time >= anim_size) {
+ if (prev_time <= anim_size && time > anim_size) {
backward = !backward;
pingponged = 1;
}
@@ -179,6 +179,26 @@ AnimationNodeAnimation::AnimationNodeAnimation() {
////////////////////////////////////////////////////////
+void AnimationNodeSync::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeSync::set_use_sync);
+ ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeSync::is_using_sync);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
+}
+
+void AnimationNodeSync::set_use_sync(bool p_sync) {
+ sync = p_sync;
+}
+
+bool AnimationNodeSync::is_using_sync() const {
+ return sync;
+}
+
+AnimationNodeSync::AnimationNodeSync() {
+}
+
+////////////////////////////////////////////////////////
+
void AnimationNodeOneShot::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::BOOL, active));
r_list->push_back(PropertyInfo(Variant::BOOL, prev_active, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE));
@@ -276,7 +296,7 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_seek_roo
}
if (!active) {
- return blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, !sync);
+ return blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, sync);
}
}
@@ -313,12 +333,12 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_seek_roo
double main_rem;
if (mix == MIX_MODE_ADD) {
- main_rem = blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, !sync);
+ main_rem = blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, sync);
} else {
- main_rem = blend_input(0, p_time, p_seek, p_seek_root, 1.0 - blend, FILTER_BLEND, !sync);
+ main_rem = blend_input(0, p_time, p_seek, p_seek_root, 1.0 - blend, FILTER_BLEND, sync);
}
- double os_rem = blend_input(1, os_seek ? time : p_time, os_seek, p_seek_root, blend, FILTER_PASS, false);
+ double os_rem = blend_input(1, os_seek ? time : p_time, os_seek, p_seek_root, blend, FILTER_PASS, true);
if (do_start) {
remaining = os_rem;
@@ -343,14 +363,6 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_seek_roo
return MAX(main_rem, remaining);
}
-void AnimationNodeOneShot::set_use_sync(bool p_sync) {
- sync = p_sync;
-}
-
-bool AnimationNodeOneShot::is_using_sync() const {
- return sync;
-}
-
void AnimationNodeOneShot::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_fadein_time", "time"), &AnimationNodeOneShot::set_fadein_time);
ClassDB::bind_method(D_METHOD("get_fadein_time"), &AnimationNodeOneShot::get_fadein_time);
@@ -370,9 +382,6 @@ void AnimationNodeOneShot::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mix_mode", "mode"), &AnimationNodeOneShot::set_mix_mode);
ClassDB::bind_method(D_METHOD("get_mix_mode"), &AnimationNodeOneShot::get_mix_mode);
- 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,suffix:s"), "set_fadein_time", "get_fadein_time");
@@ -384,9 +393,6 @@ void AnimationNodeOneShot::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "autorestart_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater,suffix:s"), "set_autorestart_delay", "get_autorestart_delay");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "autorestart_random_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater,suffix:s"), "set_autorestart_random_delay", "get_autorestart_random_delay");
- ADD_GROUP("", "");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
-
BIND_ENUM_CONSTANT(MIX_MODE_BLEND);
BIND_ENUM_CONSTANT(MIX_MODE_ADD);
}
@@ -410,31 +416,19 @@ String AnimationNodeAdd2::get_caption() const {
return "Add2";
}
-void AnimationNodeAdd2::set_use_sync(bool p_sync) {
- sync = p_sync;
-}
-
-bool AnimationNodeAdd2::is_using_sync() const {
- return sync;
-}
-
bool AnimationNodeAdd2::has_filter() const {
return true;
}
double AnimationNodeAdd2::process(double p_time, bool p_seek, bool p_seek_root) {
double amount = get_parameter(add_amount);
- double rem0 = blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, !sync);
- blend_input(1, p_time, p_seek, p_seek_root, amount, FILTER_PASS, !sync);
+ double rem0 = blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, sync);
+ blend_input(1, p_time, p_seek, p_seek_root, amount, FILTER_PASS, sync);
return rem0;
}
void AnimationNodeAdd2::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd2::set_use_sync);
- ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd2::is_using_sync);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
AnimationNodeAdd2::AnimationNodeAdd2() {
@@ -456,32 +450,20 @@ String AnimationNodeAdd3::get_caption() const {
return "Add3";
}
-void AnimationNodeAdd3::set_use_sync(bool p_sync) {
- sync = p_sync;
-}
-
-bool AnimationNodeAdd3::is_using_sync() const {
- return sync;
-}
-
bool AnimationNodeAdd3::has_filter() const {
return true;
}
double AnimationNodeAdd3::process(double p_time, bool p_seek, bool p_seek_root) {
double amount = get_parameter(add_amount);
- blend_input(0, p_time, p_seek, p_seek_root, MAX(0, -amount), FILTER_PASS, !sync);
- double rem0 = blend_input(1, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, !sync);
- blend_input(2, p_time, p_seek, p_seek_root, MAX(0, amount), FILTER_PASS, !sync);
+ blend_input(0, p_time, p_seek, p_seek_root, MAX(0, -amount), FILTER_PASS, sync);
+ double rem0 = blend_input(1, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, sync);
+ blend_input(2, p_time, p_seek, p_seek_root, MAX(0, amount), FILTER_PASS, sync);
return rem0;
}
void AnimationNodeAdd3::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd3::set_use_sync);
- ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd3::is_using_sync);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
AnimationNodeAdd3::AnimationNodeAdd3() {
@@ -507,29 +489,17 @@ String AnimationNodeBlend2::get_caption() const {
double AnimationNodeBlend2::process(double p_time, bool p_seek, bool p_seek_root) {
double amount = get_parameter(blend_amount);
- double rem0 = blend_input(0, p_time, p_seek, p_seek_root, 1.0 - amount, FILTER_BLEND, !sync);
- double rem1 = blend_input(1, p_time, p_seek, p_seek_root, amount, FILTER_PASS, !sync);
+ double rem0 = blend_input(0, p_time, p_seek, p_seek_root, 1.0 - amount, FILTER_BLEND, sync);
+ double rem1 = blend_input(1, p_time, p_seek, p_seek_root, amount, FILTER_PASS, sync);
return amount > 0.5 ? rem1 : rem0; //hacky but good enough
}
-void AnimationNodeBlend2::set_use_sync(bool p_sync) {
- sync = p_sync;
-}
-
-bool AnimationNodeBlend2::is_using_sync() const {
- return sync;
-}
-
bool AnimationNodeBlend2::has_filter() const {
return true;
}
void AnimationNodeBlend2::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlend2::set_use_sync);
- ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlend2::is_using_sync);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
AnimationNodeBlend2::AnimationNodeBlend2() {
@@ -551,35 +521,22 @@ String AnimationNodeBlend3::get_caption() const {
return "Blend3";
}
-void AnimationNodeBlend3::set_use_sync(bool p_sync) {
- sync = p_sync;
-}
-
-bool AnimationNodeBlend3::is_using_sync() const {
- return sync;
-}
-
double AnimationNodeBlend3::process(double p_time, bool p_seek, bool p_seek_root) {
double amount = get_parameter(blend_amount);
- double rem0 = blend_input(0, p_time, p_seek, p_seek_root, MAX(0, -amount), FILTER_IGNORE, !sync);
- double rem1 = blend_input(1, p_time, p_seek, p_seek_root, 1.0 - ABS(amount), FILTER_IGNORE, !sync);
- double rem2 = blend_input(2, p_time, p_seek, p_seek_root, MAX(0, amount), FILTER_IGNORE, !sync);
+ double rem0 = blend_input(0, p_time, p_seek, p_seek_root, MAX(0, -amount), FILTER_IGNORE, sync);
+ double rem1 = blend_input(1, p_time, p_seek, p_seek_root, 1.0 - ABS(amount), FILTER_IGNORE, sync);
+ double rem2 = blend_input(2, p_time, p_seek, p_seek_root, MAX(0, amount), FILTER_IGNORE, sync);
return amount > 0.5 ? rem2 : (amount < -0.5 ? rem0 : rem1); //hacky but good enough
}
void AnimationNodeBlend3::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlend3::set_use_sync);
- ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlend3::is_using_sync);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
AnimationNodeBlend3::AnimationNodeBlend3() {
add_input("-blend");
add_input("in");
add_input("+blend");
- sync = false;
}
/////////////////////////////////
@@ -599,9 +556,9 @@ String AnimationNodeTimeScale::get_caption() const {
double AnimationNodeTimeScale::process(double p_time, bool p_seek, bool p_seek_root) {
double scale = get_parameter(this->scale);
if (p_seek) {
- return blend_input(0, p_time, true, p_seek_root, 1.0, FILTER_IGNORE, false);
+ return blend_input(0, p_time, true, p_seek_root, 1.0, FILTER_IGNORE, true);
} else {
- return blend_input(0, p_time * scale, false, p_seek_root, 1.0, FILTER_IGNORE, false);
+ return blend_input(0, p_time * scale, false, p_seek_root, 1.0, FILTER_IGNORE, true);
}
}
@@ -629,13 +586,13 @@ String AnimationNodeTimeSeek::get_caption() const {
double AnimationNodeTimeSeek::process(double p_time, bool p_seek, bool p_seek_root) {
double seek_pos = get_parameter(this->seek_pos);
if (p_seek) {
- return blend_input(0, p_time, true, p_seek_root, 1.0, FILTER_IGNORE, false);
+ return blend_input(0, p_time, true, p_seek_root, 1.0, FILTER_IGNORE, true);
} else if (seek_pos >= 0) {
- double ret = blend_input(0, seek_pos, true, true, 1.0, FILTER_IGNORE, false);
+ double ret = blend_input(0, seek_pos, true, true, 1.0, FILTER_IGNORE, true);
set_parameter(this->seek_pos, -1.0); //reset
return ret;
} else {
- return blend_input(0, p_time, false, p_seek_root, 1.0, FILTER_IGNORE, false);
+ return blend_input(0, p_time, false, p_seek_root, 1.0, FILTER_IGNORE, true);
}
}
@@ -727,6 +684,14 @@ float AnimationNodeTransition::get_cross_fade_time() const {
return xfade;
}
+void AnimationNodeTransition::set_from_start(bool p_from_start) {
+ from_start = p_from_start;
+}
+
+bool AnimationNodeTransition::is_from_start() const {
+ return from_start;
+}
+
double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_seek_root) {
int current = get_parameter(this->current);
int prev = get_parameter(this->prev);
@@ -753,9 +718,15 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_seek_
double rem = 0.0;
+ for (int i = 0; i < enabled_inputs; i++) {
+ if (i != current && i != prev) {
+ blend_input(i, p_time, p_seek, p_seek_root, 0, FILTER_IGNORE, sync);
+ }
+ }
+
if (prev < 0) { // process current animation, check for transition
- rem = blend_input(current, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, false);
+ rem = blend_input(current, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, true);
if (p_seek) {
time = p_time;
@@ -771,18 +742,18 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_seek_
float blend = xfade == 0 ? 0 : (prev_xfading / xfade);
- if (!p_seek && switched) { //just switched, seek to start of current
+ if (from_start && !p_seek && switched) { //just switched, seek to start of current
- rem = blend_input(current, 0, true, p_seek_root, 1.0 - blend, FILTER_IGNORE, false);
+ rem = blend_input(current, 0, true, p_seek_root, 1.0 - blend, FILTER_IGNORE, true);
} else {
- rem = blend_input(current, p_time, p_seek, p_seek_root, 1.0 - blend, FILTER_IGNORE, false);
+ rem = blend_input(current, p_time, p_seek, p_seek_root, 1.0 - blend, FILTER_IGNORE, true);
}
- if (p_seek) { // don't seek prev animation
- blend_input(prev, 0, false, p_seek_root, blend, FILTER_IGNORE, false);
+ if (p_seek) {
+ blend_input(prev, p_time, true, p_seek_root, blend, FILTER_IGNORE, true);
time = p_time;
} else {
- blend_input(prev, p_time, false, p_seek_root, blend, FILTER_IGNORE, false);
+ blend_input(prev, p_time, false, p_seek_root, blend, FILTER_IGNORE, true);
time += p_time;
prev_xfading -= p_time;
if (prev_xfading < 0) {
@@ -824,8 +795,12 @@ void AnimationNodeTransition::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_cross_fade_time", "time"), &AnimationNodeTransition::set_cross_fade_time);
ClassDB::bind_method(D_METHOD("get_cross_fade_time"), &AnimationNodeTransition::get_cross_fade_time);
+ ClassDB::bind_method(D_METHOD("set_from_start", "from_start"), &AnimationNodeTransition::set_from_start);
+ ClassDB::bind_method(D_METHOD("is_from_start"), &AnimationNodeTransition::is_from_start);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,64,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_enabled_inputs", "get_enabled_inputs");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01,suffix:s"), "set_cross_fade_time", "get_cross_fade_time");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "from_start"), "set_from_start", "is_from_start");
for (int i = 0; i < MAX_INPUTS; i++) {
ADD_PROPERTYI(PropertyInfo(Variant::STRING, "input_" + itos(i) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_input_caption", "get_input_caption", i);
@@ -846,7 +821,7 @@ String AnimationNodeOutput::get_caption() const {
}
double AnimationNodeOutput::process(double p_time, bool p_seek, bool p_seek_root) {
- return blend_input(0, p_time, p_seek, p_seek_root, 1.0);
+ return blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, true);
}
AnimationNodeOutput::AnimationNodeOutput() {
@@ -1060,7 +1035,7 @@ String AnimationNodeBlendTree::get_caption() const {
double AnimationNodeBlendTree::process(double p_time, bool p_seek, bool p_seek_root) {
Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node;
- return _blend_node("output", nodes[SceneStringNames::get_singleton()->output].connections, this, output, p_time, p_seek, p_seek_root, 1.0);
+ return _blend_node("output", nodes[SceneStringNames::get_singleton()->output].connections, this, output, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, true);
}
void AnimationNodeBlendTree::get_node_list(List<StringName> *r_list) {
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 0a2305b8d6..d35ff04f30 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -77,8 +77,23 @@ private:
VARIANT_ENUM_CAST(AnimationNodeAnimation::PlayMode)
-class AnimationNodeOneShot : public AnimationNode {
- GDCLASS(AnimationNodeOneShot, AnimationNode);
+class AnimationNodeSync : public AnimationNode {
+ GDCLASS(AnimationNodeSync, AnimationNode);
+
+protected:
+ bool sync = false;
+
+ static void _bind_methods();
+
+public:
+ void set_use_sync(bool p_sync);
+ bool is_using_sync() const;
+
+ AnimationNodeSync();
+};
+
+class AnimationNodeOneShot : public AnimationNodeSync {
+ GDCLASS(AnimationNodeOneShot, AnimationNodeSync);
public:
enum MixMode {
@@ -95,8 +110,6 @@ private:
float autorestart_random_delay = 0.0;
MixMode mix = MIX_MODE_BLEND;
- bool sync = false;
-
/* bool active;
bool do_start;
float time;
@@ -134,9 +147,6 @@ public:
void set_mix_mode(MixMode p_mix);
MixMode get_mix_mode() const;
- void set_use_sync(bool p_sync);
- bool is_using_sync() const;
-
virtual bool has_filter() const override;
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
@@ -145,11 +155,10 @@ public:
VARIANT_ENUM_CAST(AnimationNodeOneShot::MixMode)
-class AnimationNodeAdd2 : public AnimationNode {
- GDCLASS(AnimationNodeAdd2, AnimationNode);
+class AnimationNodeAdd2 : public AnimationNodeSync {
+ GDCLASS(AnimationNodeAdd2, AnimationNodeSync);
StringName add_amount = PNAME("add_amount");
- bool sync = false;
protected:
static void _bind_methods();
@@ -160,20 +169,16 @@ public:
virtual String get_caption() const override;
- void set_use_sync(bool p_sync);
- bool is_using_sync() const;
-
virtual bool has_filter() const override;
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
AnimationNodeAdd2();
};
-class AnimationNodeAdd3 : public AnimationNode {
- GDCLASS(AnimationNodeAdd3, AnimationNode);
+class AnimationNodeAdd3 : public AnimationNodeSync {
+ GDCLASS(AnimationNodeAdd3, AnimationNodeSync);
StringName add_amount = PNAME("add_amount");
- bool sync = false;
protected:
static void _bind_methods();
@@ -184,20 +189,16 @@ public:
virtual String get_caption() const override;
- void set_use_sync(bool p_sync);
- bool is_using_sync() const;
-
virtual bool has_filter() const override;
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
AnimationNodeAdd3();
};
-class AnimationNodeBlend2 : public AnimationNode {
- GDCLASS(AnimationNodeBlend2, AnimationNode);
+class AnimationNodeBlend2 : public AnimationNodeSync {
+ GDCLASS(AnimationNodeBlend2, AnimationNodeSync);
StringName blend_amount = PNAME("blend_amount");
- bool sync = false;
protected:
static void _bind_methods();
@@ -209,18 +210,14 @@ public:
virtual String get_caption() const override;
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
- void set_use_sync(bool p_sync);
- bool is_using_sync() const;
-
virtual bool has_filter() const override;
AnimationNodeBlend2();
};
-class AnimationNodeBlend3 : public AnimationNode {
- GDCLASS(AnimationNodeBlend3, AnimationNode);
+class AnimationNodeBlend3 : public AnimationNodeSync {
+ GDCLASS(AnimationNodeBlend3, AnimationNodeSync);
StringName blend_amount = PNAME("blend_amount");
- bool sync;
protected:
static void _bind_methods();
@@ -231,9 +228,6 @@ public:
virtual String get_caption() const override;
- void set_use_sync(bool p_sync);
- bool is_using_sync() const;
-
double process(double p_time, bool p_seek, bool p_seek_root) override;
AnimationNodeBlend3();
};
@@ -276,8 +270,8 @@ public:
AnimationNodeTimeSeek();
};
-class AnimationNodeTransition : public AnimationNode {
- GDCLASS(AnimationNodeTransition, AnimationNode);
+class AnimationNodeTransition : public AnimationNodeSync {
+ GDCLASS(AnimationNodeTransition, AnimationNodeSync);
enum {
MAX_INPUTS = 32
@@ -304,6 +298,7 @@ class AnimationNodeTransition : public AnimationNode {
StringName prev_current = "prev_current";
float xfade = 0.0;
+ bool from_start = true;
void _update_inputs();
@@ -329,6 +324,9 @@ public:
void set_cross_fade_time(float p_fade);
float get_cross_fade_time() const;
+ void set_from_start(bool p_from_start);
+ bool is_from_start() const;
+
double process(double p_time, bool p_seek, bool p_seek_root) override;
AnimationNodeTransition();
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 8dcf538b8f..fe08e849a1 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -68,6 +68,34 @@ StringName AnimationNodeStateMachineTransition::get_advance_condition_name() con
return advance_condition_name;
}
+void AnimationNodeStateMachineTransition::set_advance_expression(const String &p_expression) {
+ advance_expression = p_expression;
+
+ String advance_expression_stripped = advance_expression.strip_edges();
+ if (advance_expression_stripped == String()) {
+ expression.unref();
+ return;
+ }
+
+ if (expression.is_null()) {
+ expression.instantiate();
+ }
+
+ expression->parse(advance_expression_stripped);
+}
+
+String AnimationNodeStateMachineTransition::get_advance_expression() const {
+ return advance_expression;
+}
+
+void AnimationNodeStateMachineTransition::set_advance_expression_base_node(const NodePath &p_expression_base_node) {
+ advance_expression_base_node = p_expression_base_node;
+}
+
+NodePath AnimationNodeStateMachineTransition::get_advance_expression_base_node() const {
+ return advance_expression_base_node;
+}
+
void AnimationNodeStateMachineTransition::set_xfade_time(float p_xfade) {
ERR_FAIL_COND(p_xfade < 0);
xfade = p_xfade;
@@ -115,11 +143,22 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_priority", "priority"), &AnimationNodeStateMachineTransition::set_priority);
ClassDB::bind_method(D_METHOD("get_priority"), &AnimationNodeStateMachineTransition::get_priority);
+ ClassDB::bind_method(D_METHOD("set_advance_expression", "text"), &AnimationNodeStateMachineTransition::set_advance_expression);
+ ClassDB::bind_method(D_METHOD("get_advance_expression"), &AnimationNodeStateMachineTransition::get_advance_expression);
+
+ ClassDB::bind_method(D_METHOD("set_advance_expression_base_node", "path"), &AnimationNodeStateMachineTransition::set_advance_expression_base_node);
+ ClassDB::bind_method(D_METHOD("get_advance_expression_base_node"), &AnimationNodeStateMachineTransition::get_advance_expression_base_node);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01,suffix:s"), "set_xfade_time", "get_xfade_time");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,32,1"), "set_priority", "get_priority");
+ ADD_GROUP("Switch", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,At End"), "set_switch_mode", "get_switch_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_advance"), "set_auto_advance", "has_auto_advance");
+ ADD_GROUP("Advance", "advance_");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "advance_condition"), "set_advance_condition", "get_advance_condition");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01,suffix:s"), "set_xfade_time", "get_xfade_time");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,32,1"), "set_priority", "get_priority");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "advance_expression", PROPERTY_HINT_EXPRESSION, ""), "set_advance_expression", "get_advance_expression");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "advance_expression_base_node"), "set_advance_expression_base_node", "get_advance_expression_base_node");
+ ADD_GROUP("Disabling", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
BIND_ENUM_CONSTANT(SWITCH_MODE_IMMEDIATE);
@@ -356,7 +395,7 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
current = p_state_machine->start_node;
}
- len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_seek_root, 1.0, AnimationNode::FILTER_IGNORE, false);
+ len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_seek_root, 1.0, AnimationNode::FILTER_IGNORE, true);
pos_current = 0;
}
@@ -381,10 +420,10 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
}
}
- float rem = p_state_machine->blend_node(current, p_state_machine->states[current].node, p_time, p_seek, p_seek_root, fade_blend, AnimationNode::FILTER_IGNORE, false);
+ float rem = p_state_machine->blend_node(current, p_state_machine->states[current].node, p_time, p_seek, p_seek_root, fade_blend, AnimationNode::FILTER_IGNORE, true);
if (fading_from != StringName()) {
- p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, p_seek_root, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, false);
+ p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, p_seek_root, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, true);
}
//guess playback position
@@ -538,12 +577,12 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
}
current = next;
if (switch_mode == AnimationNodeStateMachineTransition::SWITCH_MODE_SYNC) {
- len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_seek_root, 0, AnimationNode::FILTER_IGNORE, false);
+ len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_seek_root, 0, AnimationNode::FILTER_IGNORE, true);
pos_current = MIN(pos_current, len_current);
- p_state_machine->blend_node(current, p_state_machine->states[current].node, pos_current, true, p_seek_root, 0, AnimationNode::FILTER_IGNORE, false);
+ p_state_machine->blend_node(current, p_state_machine->states[current].node, pos_current, true, p_seek_root, 0, AnimationNode::FILTER_IGNORE, true);
} else {
- len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_seek_root, 0, AnimationNode::FILTER_IGNORE, false);
+ len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_seek_root, 0, AnimationNode::FILTER_IGNORE, true);
pos_current = 0;
}
@@ -577,6 +616,29 @@ bool AnimationNodeStateMachinePlayback::_check_advance_condition(const Ref<Anima
return true;
}
+ if (transition->expression.is_valid()) {
+ AnimationTree *tree_base = state_machine->get_animation_tree();
+ ERR_FAIL_COND_V(tree_base == nullptr, false);
+
+ NodePath advance_expression_base_node_path;
+ if (!transition->advance_expression_base_node.is_empty()) {
+ advance_expression_base_node_path = transition->advance_expression_base_node;
+ } else {
+ advance_expression_base_node_path = tree_base->get_advance_expression_base_node();
+ }
+
+ Node *expression_base = tree_base->get_node_or_null(advance_expression_base_node_path);
+ if (expression_base) {
+ Ref<Expression> exp = transition->expression;
+ bool ret = exp->execute(Array(), tree_base, false, Engine::get_singleton()->is_editor_hint()); // Avoids allowing the user to crash the system with an expression by only allowing const calls.
+ if (!exp->has_execute_failed()) {
+ if (ret) {
+ return true;
+ }
+ }
+ }
+ }
+
return false;
}
diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h
index 20f2d6f858..d4e58ca3d3 100644
--- a/scene/animation/animation_node_state_machine.h
+++ b/scene/animation/animation_node_state_machine.h
@@ -31,6 +31,7 @@
#ifndef ANIMATION_NODE_STATE_MACHINE_H
#define ANIMATION_NODE_STATE_MACHINE_H
+#include "core/math/expression.h"
#include "scene/animation/animation_tree.h"
class AnimationNodeStateMachineTransition : public Resource {
@@ -51,6 +52,11 @@ private:
float xfade = 0.0;
bool disabled = false;
int priority = 1;
+ String advance_expression;
+ NodePath advance_expression_base_node;
+
+ friend class AnimationNodeStateMachinePlayback;
+ Ref<Expression> expression;
protected:
static void _bind_methods();
@@ -67,6 +73,12 @@ public:
StringName get_advance_condition_name() const;
+ void set_advance_expression(const String &p_expression);
+ String get_advance_expression() const;
+
+ void set_advance_expression_base_node(const NodePath &p_expression_base_node);
+ NodePath get_advance_expression_base_node() const;
+
void set_xfade_time(float p_xfade);
float get_xfade_time() const;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 2afe9ac35f..2e87dbf9da 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -283,10 +283,12 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov
setup_pass++;
for (int i = 0; i < a->get_track_count(); i++) {
+ p_anim->node_cache.write[i] = nullptr;
+
if (!a->track_is_enabled(i)) {
continue;
}
- p_anim->node_cache.write[i] = nullptr;
+
Ref<Resource> resource;
Vector<StringName> leftover_path;
Node *child = parent->get_node_and_resource(a->track_get_path(i), resource, leftover_path);
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index bcd49d75fa..4b80f571ae 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -136,6 +136,11 @@ double AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode
return t;
}
+AnimationTree *AnimationNode::get_animation_tree() const {
+ ERR_FAIL_COND_V(!state, nullptr);
+ return state->tree;
+}
+
void AnimationNode::make_invalid(const String &p_reason) {
ERR_FAIL_COND(!state);
state->valid = false;
@@ -145,7 +150,7 @@ void AnimationNode::make_invalid(const String &p_reason) {
state->invalid_reasons += String::utf8("• ") + p_reason;
}
-double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool p_seek_root, real_t p_blend, FilterAction p_filter, bool p_optimize) {
+double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool p_seek_root, real_t p_blend, FilterAction p_filter, bool p_sync) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -164,7 +169,7 @@ double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool
//inputs.write[p_input].last_pass = state->last_pass;
real_t activity = 0.0;
- double ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_seek_root, 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_seek_root, p_blend, p_filter, p_sync, &activity);
Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
@@ -175,11 +180,11 @@ double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool
return ret;
}
-double AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_seek_root, 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_seek_root, p_blend, p_filter, p_optimize);
+double AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_seek_root, real_t p_blend, FilterAction p_filter, bool p_sync) {
+ return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_seek_root, p_blend, p_filter, p_sync);
}
-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, bool p_seek_root, 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, bool p_seek_root, real_t p_blend, FilterAction p_filter, bool p_sync, real_t *r_max) {
ERR_FAIL_COND_V(!p_node.is_valid(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -287,9 +292,11 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri
}
// If tracks for blending don't exist for one of the animations, Rest or RESET animation is blended as init animation instead.
- // Then, blend weight is 0 means that the init animation blend weight is 1.
+ // Then blend weight is 0 means that the init animation blend weight is 1.
+ // In that case, processing only the animation with the lacking track will not process the lacking track, and will not properly apply the Reset value.
+ // This means that all tracks which the animations in the branch that may be blended have must be processed.
// Therefore, the blending process must be executed even if the blend weight is 0.
- if (!p_seek && p_optimize && !any_valid) {
+ if (!p_seek && !p_sync && !any_valid) {
return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_seek_root, p_connections);
}
return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_seek_root, p_connections);
@@ -423,8 +430,8 @@ void AnimationNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_filters"), &AnimationNode::_get_filters);
ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "seek_root", "blend", "pingponged"), &AnimationNode::blend_animation, DEFVAL(0));
- ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "seek_root", "blend", "filter", "optimize"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "seek_root", "blend", "filter", "optimize"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "seek_root", "blend", "filter", "sync"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "seek_root", "blend", "filter", "sync"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true));
ClassDB::bind_method(D_METHOD("set_parameter", "name", "value"), &AnimationNode::set_parameter);
ClassDB::bind_method(D_METHOD("get_parameter", "name"), &AnimationNode::get_parameter);
@@ -1704,6 +1711,14 @@ NodePath AnimationTree::get_animation_player() const {
return animation_player;
}
+void AnimationTree::set_advance_expression_base_node(const NodePath &p_advance_expression_base_node) {
+ advance_expression_base_node = p_advance_expression_base_node;
+}
+
+NodePath AnimationTree::get_advance_expression_base_node() const {
+ return advance_expression_base_node;
+}
+
bool AnimationTree::is_state_invalid() const {
return !state.valid;
}
@@ -1899,6 +1914,9 @@ void AnimationTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_animation_player", "root"), &AnimationTree::set_animation_player);
ClassDB::bind_method(D_METHOD("get_animation_player"), &AnimationTree::get_animation_player);
+ ClassDB::bind_method(D_METHOD("set_advance_expression_base_node", "node"), &AnimationTree::set_advance_expression_base_node);
+ ClassDB::bind_method(D_METHOD("get_advance_expression_base_node"), &AnimationTree::get_advance_expression_base_node);
+
ClassDB::bind_method(D_METHOD("set_root_motion_track", "path"), &AnimationTree::set_root_motion_track);
ClassDB::bind_method(D_METHOD("get_root_motion_track"), &AnimationTree::get_root_motion_track);
@@ -1912,6 +1930,8 @@ void AnimationTree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "advance_expression_base_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node"), "set_advance_expression_base_node", "get_advance_expression_base_node");
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback");
ADD_GROUP("Root Motion", "root_motion_");
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index b646efede4..4f9a330a89 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -99,14 +99,15 @@ public:
Array _get_filters() const;
void _set_filters(const Array &p_filters);
friend class AnimationNodeBlendTree;
- 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, bool p_seek_root, 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, bool p_seek_root, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, real_t *r_max = nullptr);
protected:
void blend_animation(const StringName &p_animation, double p_time, double p_delta, bool p_seeked, bool p_seek_root, 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, bool p_seek_root, 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, bool p_seek_root, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
+ double blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_seek_root, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true);
+ double blend_input(int p_input, double p_time, bool p_seek, bool p_seek_root, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true);
void make_invalid(const String &p_reason);
+ AnimationTree *get_animation_tree() const;
static void _bind_methods();
@@ -270,6 +271,7 @@ private:
HashSet<TrackCache *> playing_caches;
Ref<AnimationNode> root;
+ NodePath advance_expression_base_node = NodePath(String("."));
AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE;
bool active = false;
@@ -332,6 +334,9 @@ public:
void set_animation_player(const NodePath &p_player);
NodePath get_animation_player() const;
+ void set_advance_expression_base_node(const NodePath &p_advance_expression_base_node);
+ NodePath get_advance_expression_base_node() const;
+
TypedArray<String> get_configuration_warnings() const override;
bool is_state_invalid() const;
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 1371c9cd57..a67f850a86 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -347,7 +347,6 @@ void Button::_notification(int p_what) {
if (outline_size > 0 && font_outline_color.a > 0) {
text_buf->draw_outline(ci, text_ofs, outline_size, font_outline_color);
}
-
text_buf->draw(ci, text_ofs, color);
} break;
}
@@ -363,7 +362,7 @@ void Button::_shape() {
} else {
text_buf->set_direction((TextServer::Direction)text_direction);
}
- text_buf->add_string(xl_text, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
+ text_buf->add_string(xl_text, font, font_size, language);
text_buf->set_text_overrun_behavior(overrun_behavior);
}
@@ -409,29 +408,6 @@ Control::TextDirection Button::get_text_direction() const {
return text_direction;
}
-void Button::clear_opentype_features() {
- opentype_features.clear();
- _shape();
- update();
-}
-
-void Button::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;
- _shape();
- update();
- }
-}
-
-int Button::get_opentype_feature(const String &p_name) const {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag)) {
- return -1;
- }
- return opentype_features[tag];
-}
-
void Button::set_language(const String &p_language) {
if (language != p_language) {
language = p_language;
@@ -512,56 +488,6 @@ HorizontalAlignment Button::get_icon_alignment() const {
return icon_alignment;
}
-bool Button::_set(const StringName &p_name, const Variant &p_value) {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- int value = p_value;
- if (value == -1) {
- if (opentype_features.has(tag)) {
- opentype_features.erase(tag);
- _shape();
- update();
- }
- } else {
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
- opentype_features[tag] = value;
- _shape();
- update();
- }
- }
- notify_property_list_changed();
- return true;
- }
-
- return false;
-}
-
-bool Button::_get(const StringName &p_name, Variant &r_ret) const {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- if (opentype_features.has(tag)) {
- r_ret = opentype_features[tag];
- return true;
- } else {
- r_ret = -1;
- return true;
- }
- }
- return false;
-}
-
-void Button::_get_property_list(List<PropertyInfo> *p_list) const {
- for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
- String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
- }
- p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
-}
-
void Button::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_text", "text"), &Button::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &Button::get_text);
@@ -569,9 +495,6 @@ void Button::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &Button::get_text_overrun_behavior);
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Button::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &Button::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &Button::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &Button::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features"), &Button::clear_opentype_features);
ClassDB::bind_method(D_METHOD("set_language", "language"), &Button::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &Button::get_language);
ClassDB::bind_method(D_METHOD("set_button_icon", "texture"), &Button::set_icon);
@@ -588,8 +511,6 @@ void Button::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_expand_icon"), &Button::is_expand_icon);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
- 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::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text");
@@ -597,11 +518,15 @@ void Button::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior");
ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_icon_alignment", "get_icon_alignment");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_icon"), "set_expand_icon", "is_expand_icon");
+
+ ADD_GROUP("BiDi", "");
+ 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");
}
Button::Button(const String &p_text) {
text_buf.instantiate();
- text_buf->set_flags(TextServer::BREAK_MANDATORY);
+ text_buf->set_break_flags(TextServer::BREAK_MANDATORY);
set_mouse_filter(MOUSE_FILTER_STOP);
set_text(p_text);
diff --git a/scene/gui/button.h b/scene/gui/button.h
index a1d71195cb..7a29cba677 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -43,7 +43,6 @@ private:
String xl_text;
Ref<TextParagraph> text_buf;
- Dictionary opentype_features;
String language;
TextDirection text_direction = TEXT_DIRECTION_AUTO;
TextServer::OverrunBehavior overrun_behavior = TextServer::OVERRUN_NO_TRIMMING;
@@ -62,10 +61,6 @@ protected:
void _notification(int p_what);
static void _bind_methods();
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
-
public:
virtual Size2 get_minimum_size() const override;
@@ -78,10 +73,6 @@ public:
void set_text_direction(TextDirection p_text_direction);
TextDirection get_text_direction() const;
- void set_opentype_feature(const String &p_name, int p_value);
- int get_opentype_feature(const String &p_name) const;
- void clear_opentype_features();
-
void set_language(const String &p_language);
String get_language() const;
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 22e9763929..8968c1cc17 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -46,7 +46,7 @@ void CodeEdit::_notification(int p_what) {
line_spacing = get_theme_constant(SNAME("line_spacing"));
set_gutter_width(main_gutter, get_line_height());
- set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', 0, font_size).width);
+ set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', font_size).width);
set_gutter_width(fold_gutter, get_line_height() / 1.2);
breakpoint_color = get_theme_color(SNAME("breakpoint_color"));
@@ -68,6 +68,7 @@ void CodeEdit::_notification(int p_what) {
code_completion_max_lines = get_theme_constant(SNAME("completion_lines"));
code_completion_scroll_width = get_theme_constant(SNAME("completion_scroll_width"));
code_completion_scroll_color = get_theme_color(SNAME("completion_scroll_color"));
+ code_completion_scroll_hovered_color = get_theme_color(SNAME("completion_scroll_hovered_color"));
code_completion_background_color = get_theme_color(SNAME("completion_background_color"));
code_completion_selected_color = get_theme_color(SNAME("completion_selected_color"));
code_completion_existing_color = get_theme_color(SNAME("completion_existing_color"));
@@ -85,7 +86,7 @@ void CodeEdit::_notification(int p_what) {
if (line_length_guideline_columns.size() > 0) {
const int xmargin_beg = style_normal->get_margin(SIDE_LEFT) + get_total_gutter_width();
const int xmargin_end = size.width - style_normal->get_margin(SIDE_RIGHT) - (is_drawing_minimap() ? get_minimap_width() : 0);
- const float char_size = font->get_char_size('0', 0, font_size).width;
+ const float char_size = font->get_char_size('0', font_size).width;
for (int i = 0; i < line_length_guideline_columns.size(); i++) {
const int xoffset = xmargin_beg + char_size * (int)line_length_guideline_columns[i] - get_h_scroll();
@@ -122,7 +123,7 @@ void CodeEdit::_notification(int p_what) {
}
const int scroll_width = code_completion_options_count > code_completion_max_lines ? code_completion_scroll_width : 0;
- const int code_completion_base_width = font->get_string_size(code_completion_base, font_size).width;
+ const int code_completion_base_width = font->get_string_size(code_completion_base, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
if (caret_pos.x - code_completion_base_width + code_completion_rect.size.width + scroll_width > get_size().width) {
code_completion_rect.position.x = get_size().width - code_completion_rect.size.width - scroll_width;
} else {
@@ -134,6 +135,9 @@ void CodeEdit::_notification(int p_what) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(code_completion_rect.position, code_completion_rect.size + Size2(scroll_width, 0)), code_completion_background_color);
}
+ code_completion_scroll_rect.position = code_completion_rect.position + Vector2(code_completion_rect.size.width, 0);
+ code_completion_scroll_rect.size = Vector2(scroll_width, code_completion_rect.size.height);
+
code_completion_line_ofs = CLAMP(code_completion_current_selected - lines / 2, 0, code_completion_options_count - lines);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(code_completion_rect.position.x, code_completion_rect.position.y + (code_completion_current_selected - code_completion_line_ofs) * row_height), Size2(code_completion_rect.size.width, row_height)), code_completion_selected_color);
@@ -174,8 +178,8 @@ void CodeEdit::_notification(int p_what) {
for (int j = 0; j < code_completion_options[l].matches.size(); j++) {
Pair<int, int> match = code_completion_options[l].matches[j];
- int match_offset = font->get_string_size(code_completion_options[l].display.substr(0, match.first), font_size).width;
- int match_len = font->get_string_size(code_completion_options[l].display.substr(match.first, match.second), font_size).width;
+ int match_offset = font->get_string_size(code_completion_options[l].display.substr(0, match.first), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
+ int match_len = font->get_string_size(code_completion_options[l].display.substr(match.first, match.second), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
draw_rect(Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), code_completion_existing_color);
}
@@ -185,9 +189,11 @@ void CodeEdit::_notification(int p_what) {
/* Draw a small scroll rectangle to show a position in the options. */
if (scroll_width) {
+ Color scroll_color = is_code_completion_scroll_hovered || is_code_completion_scroll_pressed ? code_completion_scroll_hovered_color : code_completion_scroll_color;
+
float r = (float)code_completion_max_lines / code_completion_options_count;
float o = (float)code_completion_line_ofs / code_completion_options_count;
- draw_rect(Rect2(code_completion_rect.position.x + code_completion_rect.size.width, code_completion_rect.position.y + o * code_completion_rect.size.y, scroll_width, code_completion_rect.size.y * r), code_completion_scroll_color);
+ draw_rect(Rect2(code_completion_rect.position.x + code_completion_rect.size.width, code_completion_rect.position.y + o * code_completion_rect.size.y, scroll_width, code_completion_rect.size.y * r), scroll_color);
}
}
@@ -202,11 +208,11 @@ void CodeEdit::_notification(int p_what) {
int max_width = 0;
for (int i = 0; i < line_count; i++) {
- max_width = MAX(max_width, font->get_string_size(code_hint_lines[i], font_size).x);
+ max_width = MAX(max_width, font->get_string_size(code_hint_lines[i], HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x);
}
Size2 minsize = sb->get_minimum_size() + Size2(max_width, line_count * font_height + (line_spacing * line_count - 1));
- int offset = font->get_string_size(code_hint_lines[0].substr(0, code_hint_lines[0].find(String::chr(0xFFFF))), font_size).x;
+ int offset = font->get_string_size(code_hint_lines[0].substr(0, code_hint_lines[0].find(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x;
if (code_hint_xpos == -0xFFFF) {
code_hint_xpos = get_caret_draw_pos().x - offset;
}
@@ -226,8 +232,8 @@ void CodeEdit::_notification(int p_what) {
int begin = 0;
int end = 0;
if (line.contains(String::chr(0xFFFF))) {
- begin = font->get_string_size(line.substr(0, line.find(String::chr(0xFFFF))), font_size).x;
- end = font->get_string_size(line.substr(0, line.rfind(String::chr(0xFFFF))), font_size).x;
+ begin = font->get_string_size(line.substr(0, line.find(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x;
+ end = font->get_string_size(line.substr(0, line.rfind(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x;
}
Point2 round_ofs = hint_ofs + sb->get_offset() + Vector2(0, font->get_ascent(font_size) + font_height * i + yofs);
@@ -260,6 +266,12 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
return;
}
+ if (is_code_completion_scroll_pressed && mb->get_button_index() == MouseButton::LEFT) {
+ is_code_completion_scroll_pressed = false;
+ update();
+ return;
+ }
+
if (code_completion_active && code_completion_rect.has_point(mb->get_position())) {
if (!mb->is_pressed()) {
return;
@@ -289,7 +301,21 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
break;
}
return;
+ } else if (code_completion_active && code_completion_scroll_rect.has_point(mb->get_position())) {
+ if (mb->get_button_index() != MouseButton::LEFT) {
+ return;
+ }
+
+ if (mb->is_pressed()) {
+ is_code_completion_scroll_pressed = true;
+
+ _update_scroll_selected_line(mb->get_position().y);
+ update();
+ }
+
+ return;
}
+
cancel_code_completion();
set_code_hint("");
@@ -354,6 +380,18 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
set_symbol_lookup_word_as_valid(false);
}
}
+
+ bool scroll_hovered = code_completion_scroll_rect.has_point(mpos);
+ if (is_code_completion_scroll_hovered != scroll_hovered) {
+ is_code_completion_scroll_hovered = scroll_hovered;
+ update();
+ }
+
+ if (is_code_completion_scroll_pressed) {
+ _update_scroll_selected_line(mpos.y);
+ update();
+ return;
+ }
}
Ref<InputEventKey> k = p_gui_input;
@@ -369,7 +407,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
/* Ctrl + Hover symbols */
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
if (k->get_keycode() == Key::META) {
#else
if (k->get_keycode() == Key::CTRL) {
@@ -546,6 +584,10 @@ Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const {
return CURSOR_ARROW;
}
+ if (code_completion_active && code_completion_scroll_rect.has_point(p_pos)) {
+ return CURSOR_ARROW;
+ }
+
Point2i pos = get_line_column_at_pos(p_pos, false);
int line = pos.y;
int col = pos.x;
@@ -2697,6 +2739,13 @@ TypedArray<String> CodeEdit::_get_delimiters(DelimiterType p_type) const {
}
/* Code Completion */
+void CodeEdit::_update_scroll_selected_line(float p_mouse_y) {
+ float percent = (float)(p_mouse_y - code_completion_scroll_rect.position.y) / code_completion_scroll_rect.size.height;
+ percent = CLAMP(percent, 0.0f, 1.0f);
+
+ code_completion_current_selected = (int)(percent * (code_completion_options.size() - 1));
+}
+
void CodeEdit::_filter_code_completion_candidates_impl() {
int line_height = get_line_height();
@@ -2746,7 +2795,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
offset = line_height;
}
- max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
+ max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
code_completion_options.push_back(option);
}
@@ -2857,7 +2906,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
if (string_to_complete.length() == 0) {
code_completion_options.push_back(option);
- max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
+ max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
continue;
}
@@ -2963,7 +3012,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
option.matches.append_array(ssq_matches);
completion_options_subseq.push_back(option);
}
- max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
+ max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
} else if (!*ssq_lower) { // Matched the whole subsequence in s_lower.
option.matches.clear();
@@ -2980,7 +3029,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
option.matches.append_array(ssq_lower_matches);
completion_options_subseq_casei.push_back(option);
}
- max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
+ max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
}
}
@@ -3036,7 +3085,7 @@ void CodeEdit::_text_changed() {
}
if (font.is_valid()) {
- set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', 0, font_size).width);
+ set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', font_size).width);
}
lc = get_line_count();
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index ccf046c612..a431d8a5b2 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -203,22 +203,27 @@ private:
int code_completion_max_lines = 7;
int code_completion_scroll_width = 0;
Color code_completion_scroll_color = Color(0, 0, 0, 0);
+ Color code_completion_scroll_hovered_color = Color(0, 0, 0, 0);
Color code_completion_background_color = Color(0, 0, 0, 0);
Color code_completion_selected_color = Color(0, 0, 0, 0);
Color code_completion_existing_color = Color(0, 0, 0, 0);
bool code_completion_active = false;
+ bool is_code_completion_scroll_hovered = false;
+ bool is_code_completion_scroll_pressed = false;
Vector<ScriptLanguage::CodeCompletionOption> code_completion_options;
int code_completion_line_ofs = 0;
int code_completion_current_selected = 0;
int code_completion_longest_line = 0;
Rect2i code_completion_rect;
+ Rect2i code_completion_scroll_rect;
HashSet<char32_t> code_completion_prefixes;
List<ScriptLanguage::CodeCompletionOption> code_completion_option_submitted;
List<ScriptLanguage::CodeCompletionOption> code_completion_option_sources;
String code_completion_base;
+ void _update_scroll_selected_line(float p_mouse_y);
void _filter_code_completion_candidates_impl();
/* Line length guidelines */
diff --git a/scene/gui/color_mode.cpp b/scene/gui/color_mode.cpp
new file mode 100644
index 0000000000..af78d67e5a
--- /dev/null
+++ b/scene/gui/color_mode.cpp
@@ -0,0 +1,330 @@
+/*************************************************************************/
+/* color_mode.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "color_mode.h"
+
+#include "core/math/color.h"
+#include "scene/gui/slider.h"
+#include "thirdparty/misc/ok_color.h"
+
+ColorMode::ColorMode(ColorPicker *p_color_picker) {
+ color_picker = p_color_picker;
+}
+
+String ColorModeRGB::get_slider_label(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
+ return labels[idx];
+}
+
+float ColorModeRGB::get_slider_max(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider max value.");
+ Color color = color_picker->get_pick_color();
+ return next_power_of_2(MAX(255, color.components[idx] * 255.0)) - 1;
+}
+
+float ColorModeRGB::get_slider_value(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider value.");
+ return color_picker->get_pick_color().components[idx] * 255;
+}
+
+Color ColorModeRGB::get_color() const {
+ Vector<float> values = color_picker->get_active_slider_values();
+ Color color;
+ for (int i = 0; i < 4; i++) {
+ color.components[i] = values[i] / 255.0;
+ }
+ return color;
+}
+
+void ColorModeRGB::slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ HSlider *slider = color_picker->get_slider(p_which);
+ Size2 size = slider->get_size();
+ Color left_color;
+ Color right_color;
+ Color color = color_picker->get_pick_color();
+ const real_t margin = 4 * color_picker->get_theme_default_base_scale();
+
+ if (p_which == ColorPicker::SLIDER_COUNT) {
+ slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else {
+ left_color = Color(
+ p_which == 0 ? 0 : color.r,
+ p_which == 1 ? 0 : color.g,
+ p_which == 2 ? 0 : color.b);
+ right_color = Color(
+ p_which == 0 ? 1 : color.r,
+ p_which == 1 ? 1 : color.g,
+ p_which == 2 ? 1 : color.b);
+ }
+
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ slider->draw_polygon(pos, col);
+}
+
+String ColorModeHSV::get_slider_label(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
+ return labels[idx];
+}
+
+float ColorModeHSV::get_slider_max(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider max value.");
+ return slider_max[idx];
+}
+
+float ColorModeHSV::get_slider_value(int idx) const {
+ switch (idx) {
+ case 0:
+ return color_picker->get_pick_color().get_h() * 360.0;
+ case 1:
+ return color_picker->get_pick_color().get_s() * 100.0;
+ case 2:
+ return color_picker->get_pick_color().get_v() * 100.0;
+ case 3:
+ return Math::round(color_picker->get_pick_color().components[3] * 255.0);
+ default:
+ ERR_FAIL_V_MSG(0, "Couldn't get slider value.");
+ }
+}
+
+Color ColorModeHSV::get_color() const {
+ Vector<float> values = color_picker->get_active_slider_values();
+ Color color;
+ color.set_hsv(values[0] / 360.0, values[1] / 100.0, values[2] / 100.0, values[3] / 255.0);
+ return color;
+}
+
+void ColorModeHSV::slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ HSlider *slider = color_picker->get_slider(p_which);
+ Size2 size = slider->get_size();
+ Color left_color;
+ Color right_color;
+ Color color = color_picker->get_pick_color();
+ const real_t margin = 4 * color_picker->get_theme_default_base_scale();
+
+ if (p_which == ColorPicker::SLIDER_COUNT) {
+ slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else if (p_which == 0) {
+ Ref<Texture2D> hue = color_picker->get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
+ slider->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
+ slider->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(slider->get_size().x, margin)), false, Color(1, 1, 1), true);
+ return;
+ } else {
+ Color s_col;
+ Color v_col;
+ s_col.set_hsv(color.get_h(), 0, color.get_v());
+ left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
+ s_col.set_hsv(color.get_h(), 1, color.get_v());
+ v_col.set_hsv(color.get_h(), color.get_s(), 1);
+ right_color = (p_which == 1) ? s_col : v_col;
+ }
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ slider->draw_polygon(pos, col);
+}
+
+String ColorModeRAW::get_slider_label(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
+ return labels[idx];
+}
+
+float ColorModeRAW::get_slider_max(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider max value.");
+ return slider_max[idx];
+}
+
+float ColorModeRAW::get_slider_value(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider value.");
+ return color_picker->get_pick_color().components[idx];
+}
+
+Color ColorModeRAW::get_color() const {
+ Vector<float> values = color_picker->get_active_slider_values();
+ Color color;
+ for (int i = 0; i < 4; i++) {
+ color.components[i] = values[i];
+ }
+ return color;
+}
+
+void ColorModeRAW::slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ HSlider *slider = color_picker->get_slider(p_which);
+ Size2 size = slider->get_size();
+ Color left_color;
+ Color right_color;
+ Color color = color_picker->get_pick_color();
+ const real_t margin = 4 * color_picker->get_theme_default_base_scale();
+
+ if (p_which == ColorPicker::SLIDER_COUNT) {
+ slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ slider->draw_polygon(pos, col);
+ }
+}
+
+bool ColorModeRAW::apply_theme() const {
+ for (int i = 0; i < 4; i++) {
+ HSlider *slider = color_picker->get_slider(i);
+ slider->remove_theme_icon_override("grabber");
+ slider->remove_theme_icon_override("grabber_highlight");
+ slider->remove_theme_style_override("slider");
+ slider->remove_theme_style_override("grabber_area");
+ slider->remove_theme_style_override("grabber_area_highlight");
+ }
+
+ return true;
+}
+
+String ColorModeOKHSL::get_slider_label(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 3, String(), "Couldn't get slider label.");
+ return labels[idx];
+}
+
+float ColorModeOKHSL::get_slider_max(int idx) const {
+ ERR_FAIL_INDEX_V_MSG(idx, 4, 0, "Couldn't get slider max value.");
+ return slider_max[idx];
+}
+
+float ColorModeOKHSL::get_slider_value(int idx) const {
+ switch (idx) {
+ case 0:
+ return color_picker->get_pick_color().get_ok_hsl_h() * 360.0;
+ case 1:
+ return color_picker->get_pick_color().get_ok_hsl_s() * 100.0;
+ case 2:
+ return color_picker->get_pick_color().get_ok_hsl_l() * 100.0;
+ case 3:
+ return Math::round(color_picker->get_pick_color().components[3] * 255.0);
+ default:
+ ERR_FAIL_V_MSG(0, "Couldn't get slider value.");
+ }
+}
+
+Color ColorModeOKHSL::get_color() const {
+ Vector<float> values = color_picker->get_active_slider_values();
+ Color color;
+ color.set_ok_hsl(values[0] / 360.0, values[1] / 100.0, values[2] / 100.0, values[3] / 255.0);
+ return color;
+}
+
+void ColorModeOKHSL::slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ HSlider *slider = color_picker->get_slider(p_which);
+ Size2 size = slider->get_size();
+ Color left_color;
+ Color right_color;
+ Color color = color_picker->get_pick_color();
+ const real_t margin = 4 * color_picker->get_theme_default_base_scale();
+
+ if (p_which == ColorPicker::SLIDER_COUNT) {
+ slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else if (p_which == 0) {
+ Ref<Texture2D> hue = color_picker->get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
+ slider->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
+ slider->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(slider->get_size().x, margin)), false, Color(1, 1, 1), true);
+ return;
+ } else {
+ Color s_col;
+ Color v_col;
+ s_col.set_ok_hsl(color.get_h(), 0, color.get_v());
+ left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
+ s_col.set_ok_hsl(color.get_h(), 1, color.get_v());
+ v_col.set_ok_hsl(color.get_h(), color.get_s(), 1);
+ right_color = (p_which == 1) ? s_col : v_col;
+ }
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ slider->draw_polygon(pos, col);
+}
diff --git a/scene/gui/color_mode.h b/scene/gui/color_mode.h
new file mode 100644
index 0000000000..8a19699c40
--- /dev/null
+++ b/scene/gui/color_mode.h
@@ -0,0 +1,143 @@
+/*************************************************************************/
+/* color_mode.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef COLOR_MODE_H
+#define COLOR_MODE_H
+
+#include "scene/gui/color_picker.h"
+
+struct Color;
+
+class ColorMode {
+public:
+ ColorPicker *color_picker = nullptr;
+
+ virtual String get_name() const = 0;
+
+ virtual int get_slider_count() const { return 3; };
+ virtual float get_slider_step() const = 0;
+ virtual String get_slider_label(int idx) const = 0;
+ virtual float get_slider_max(int idx) const = 0;
+ virtual float get_slider_value(int idx) const = 0;
+
+ virtual Color get_color() const = 0;
+
+ virtual void slider_draw(int p_which) = 0;
+ virtual bool apply_theme() const { return false; }
+ virtual ColorPicker::PickerShapeType get_shape_override() const { return ColorPicker::SHAPE_MAX; }
+
+ ColorMode(ColorPicker *p_color_picker);
+ virtual ~ColorMode(){};
+};
+
+class ColorModeHSV : public ColorMode {
+public:
+ String labels[3] = { "H", "S", "V" };
+ float slider_max[4] = { 359, 100, 100, 255 };
+
+ virtual String get_name() const override { return "HSV"; }
+
+ virtual float get_slider_step() const override { return 1.0; }
+ virtual String get_slider_label(int idx) const override;
+ virtual float get_slider_max(int idx) const override;
+ virtual float get_slider_value(int idx) const override;
+
+ virtual Color get_color() const override;
+
+ virtual void slider_draw(int p_which) override;
+
+ ColorModeHSV(ColorPicker *p_color_picker) :
+ ColorMode(p_color_picker){};
+};
+
+class ColorModeRGB : public ColorMode {
+public:
+ String labels[3] = { "R", "G", "B" };
+
+ virtual String get_name() const override { return "RGB"; }
+
+ virtual float get_slider_step() const override { return 1; }
+ virtual String get_slider_label(int idx) const override;
+ virtual float get_slider_max(int idx) const override;
+ virtual float get_slider_value(int idx) const override;
+
+ virtual Color get_color() const override;
+
+ virtual void slider_draw(int p_which) override;
+
+ ColorModeRGB(ColorPicker *p_color_picker) :
+ ColorMode(p_color_picker){};
+};
+
+class ColorModeRAW : public ColorMode {
+public:
+ String labels[3] = { "R", "G", "B" };
+ float slider_max[4] = { 100, 100, 100, 1 };
+
+ virtual String get_name() const override { return "RAW"; }
+
+ virtual float get_slider_step() const override { return 0.01; }
+ virtual String get_slider_label(int idx) const override;
+ virtual float get_slider_max(int idx) const override;
+ virtual float get_slider_value(int idx) const override;
+
+ virtual Color get_color() const override;
+
+ virtual void slider_draw(int p_which) override;
+ virtual bool apply_theme() const override;
+
+ ColorModeRAW(ColorPicker *p_color_picker) :
+ ColorMode(p_color_picker){};
+};
+
+class ColorModeOKHSL : public ColorMode {
+public:
+ String labels[3] = { "H", "S", "L" };
+ float slider_max[4] = { 359, 100, 100, 255 };
+
+ virtual String get_name() const override { return "OKHSL"; }
+
+ virtual float get_slider_step() const override { return 1.0; }
+ virtual String get_slider_label(int idx) const override;
+ virtual float get_slider_max(int idx) const override;
+ virtual float get_slider_value(int idx) const override;
+
+ virtual Color get_color() const override;
+
+ virtual void slider_draw(int p_which) override;
+ virtual ColorPicker::PickerShapeType get_shape_override() const override { return ColorPicker::SHAPE_OKHSL_CIRCLE; }
+
+ ColorModeOKHSL(ColorPicker *p_color_picker) :
+ ColorMode(p_color_picker){};
+
+ ~ColorModeOKHSL(){};
+};
+
+#endif // COLOR_MODE_H
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 28d645e8f6..bfe5ee335b 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -34,7 +34,7 @@
#include "core/math/color.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
-#include "scene/main/window.h"
+#include "scene/gui/color_mode.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_settings.h"
@@ -75,10 +75,14 @@ void ColorPicker::_notification(int p_what) {
wheel_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("sv_width")), get_theme_constant(SNAME("sv_height"))));
wheel_margin->add_theme_constant_override("margin_bottom", 8 * get_theme_default_base_scale());
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < SLIDER_COUNT; i++) {
labels[i]->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0));
set_offset((Side)i, get_offset((Side)i) + get_theme_constant(SNAME("margin")));
}
+ alpha_label->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0));
+ set_offset((Side)0, get_offset((Side)0) + get_theme_constant(SNAME("margin")));
+
+ _reset_theme();
if (Engine::get_singleton()->is_editor_hint()) {
// Adjust for the width of the "Script" icon.
@@ -194,75 +198,38 @@ void ColorPicker::set_focus_on_line_edit() {
}
void ColorPicker::_update_controls() {
- const char *rgb[3] = { "R", "G", "B" };
- const char *hsv[3] = { "H", "S", "V" };
- const char *hsl[3] = { "H", "S", "L" };
- if (hsv_mode_enabled && picker_type == SHAPE_OKHSL_CIRCLE) {
- for (int i = 0; i < 3; i++) {
- labels[i]->set_text(hsl[i]);
- }
- } else if (hsv_mode_enabled && picker_type != SHAPE_OKHSL_CIRCLE) {
- for (int i = 0; i < 3; i++) {
- labels[i]->set_text(hsv[i]);
- }
- } else {
- for (int i = 0; i < 3; i++) {
- labels[i]->set_text(rgb[i]);
- }
+ int mode_sliders_count = modes[current_mode]->get_slider_count();
+
+ for (int i = current_slider_count; i < mode_sliders_count; i++) {
+ sliders[i]->show();
+ labels[i]->show();
+ values[i]->show();
}
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
- btn_hsv->set_text(RTR("OKHSL"));
- } else {
- btn_hsv->set_text(RTR("HSV"));
- }
- if (hsv_mode_enabled) {
- set_raw_mode(false);
- set_hsv_mode(true);
- btn_raw->set_disabled(true);
- } else if (raw_mode_enabled) {
- set_raw_mode(true);
- set_hsv_mode(false);
- btn_raw->set_disabled(false);
- btn_hsv->set_disabled(true);
- } else {
- set_raw_mode(false);
- set_hsv_mode(false);
- btn_raw->set_disabled(false);
- btn_hsv->set_disabled(false);
- }
-
- if (raw_mode_enabled) {
- for (int i = 0; i < 3; i++) {
- scroll[i]->remove_theme_icon_override("grabber");
- scroll[i]->remove_theme_icon_override("grabber_highlight");
- scroll[i]->remove_theme_style_override("slider");
- scroll[i]->remove_theme_style_override("grabber_area");
- scroll[i]->remove_theme_style_override("grabber_area_highlight");
- }
- } else {
- Ref<StyleBoxEmpty> style_box_empty(memnew(StyleBoxEmpty));
- Ref<Texture2D> bar_arrow = get_theme_icon(SNAME("bar_arrow"));
-
- for (int i = 0; i < 4; i++) {
- scroll[i]->add_theme_icon_override("grabber", bar_arrow);
- scroll[i]->add_theme_icon_override("grabber_highlight", bar_arrow);
- scroll[i]->add_theme_style_override("slider", style_box_empty);
- scroll[i]->add_theme_style_override("grabber_area", style_box_empty);
- scroll[i]->add_theme_style_override("grabber_area_highlight", style_box_empty);
- }
+ for (int i = mode_sliders_count; i < current_slider_count; i++) {
+ sliders[i]->hide();
+ labels[i]->hide();
+ values[i]->hide();
}
+ current_slider_count = mode_sliders_count;
+
+ for (int i = 0; i < current_slider_count; i++) {
+ labels[i]->set_text(modes[current_mode]->get_slider_label(i));
+ }
+ alpha_label->set_text("A");
+
+ slider_theme_modified = modes[current_mode]->apply_theme();
if (edit_alpha) {
- values[3]->show();
- scroll[3]->show();
- labels[3]->show();
+ alpha_value->show();
+ alpha_slider->show();
+ alpha_label->show();
} else {
- values[3]->hide();
- scroll[3]->hide();
- labels[3]->hide();
+ alpha_value->hide();
+ alpha_slider->hide();
+ alpha_label->hide();
}
- switch (picker_type) {
+ switch (_get_actual_shape()) {
case SHAPE_HSV_RECTANGLE:
wheel_edit->hide();
w_edit->show();
@@ -297,7 +264,7 @@ void ColorPicker::_update_controls() {
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
color = p_color;
if (color != last_color) {
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (_get_actual_shape() == SHAPE_OKHSL_CIRCLE) {
h = color.get_ok_hsl_h();
s = color.get_ok_hsl_s();
v = color.get_ok_hsl_l();
@@ -353,27 +320,93 @@ void ColorPicker::_value_changed(double) {
return;
}
- if (hsv_mode_enabled) {
- h = scroll[0]->get_value() / 360.0;
- s = scroll[1]->get_value() / 100.0;
- v = scroll[2]->get_value() / 100.0;
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
- color.set_ok_hsl(h, s, v, Math::round(scroll[3]->get_value() / 255.0));
- } else {
- color.set_hsv(h, s, v, Math::round(scroll[3]->get_value() / 255.0));
- }
+ color = modes[current_mode]->get_color();
+ if (current_mode == MODE_HSV || current_mode == MODE_OKHSL) {
+ h = sliders[0]->get_value() / 360.0;
+ s = sliders[1]->get_value() / 100.0;
+ v = sliders[2]->get_value() / 100.0;
last_color = color;
- } else {
- for (int i = 0; i < 4; i++) {
- color.components[i] = scroll[i]->get_value() / (raw_mode_enabled ? 1.0 : 255.0);
- }
}
_set_pick_color(color, false);
emit_signal(SNAME("color_changed"), color);
}
+void ColorPicker::add_mode(ColorMode *p_mode) {
+ modes.push_back(p_mode);
+ mode_option_button->add_item(RTR(p_mode->get_name()));
+}
+
+void ColorPicker::create_slider(GridContainer *gc, int idx) {
+ Label *l = memnew(Label());
+ l->set_v_size_flags(SIZE_SHRINK_CENTER);
+ gc->add_child(l);
+
+ HSlider *s = memnew(HSlider);
+ s->set_v_size_flags(SIZE_SHRINK_CENTER);
+ s->set_focus_mode(FOCUS_NONE);
+ gc->add_child(s);
+
+ SpinBox *v = memnew(SpinBox);
+ s->share(v);
+ gc->add_child(v);
+ v->get_line_edit()->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter));
+ v->get_line_edit()->connect("focus_exited", callable_mp(this, &ColorPicker::_focus_exit));
+
+ s->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ s->connect("value_changed", callable_mp(this, &ColorPicker::_value_changed));
+ s->connect("draw", callable_mp(this, &ColorPicker::_slider_draw), make_binds(idx));
+
+ if (idx < SLIDER_COUNT) {
+ sliders[idx] = s;
+ values[idx] = v;
+ labels[idx] = l;
+ } else {
+ alpha_slider = s;
+ alpha_value = v;
+ alpha_label = l;
+ }
+}
+
+HSlider *ColorPicker::get_slider(int idx) {
+ if (idx < SLIDER_COUNT) {
+ return sliders[idx];
+ }
+ return alpha_slider;
+}
+
+Vector<float> ColorPicker::get_active_slider_values() {
+ Vector<float> values;
+ for (int i = 0; i < current_slider_count; i++) {
+ values.push_back(sliders[i]->get_value());
+ }
+ values.push_back(alpha_slider->get_value());
+ return values;
+}
+
+ColorPicker::PickerShapeType ColorPicker::_get_actual_shape() const {
+ return modes[current_mode]->get_shape_override() != SHAPE_MAX ? modes[current_mode]->get_shape_override() : current_shape;
+}
+
+void ColorPicker::_reset_theme() {
+ Ref<StyleBoxEmpty> style_box_empty(memnew(StyleBoxEmpty));
+
+ for (int i = 0; i < SLIDER_COUNT; i++) {
+ sliders[i]->add_theme_icon_override("grabber", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker")));
+ sliders[i]->add_theme_icon_override("grabber_highlight", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker")));
+ sliders[i]->add_theme_style_override("slider", style_box_empty);
+ sliders[i]->add_theme_style_override("grabber_area", style_box_empty);
+ sliders[i]->add_theme_style_override("grabber_area_highlight", style_box_empty);
+ }
+ alpha_slider->add_theme_icon_override("grabber", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker")));
+ alpha_slider->add_theme_icon_override("grabber_highlight", get_theme_icon(SNAME("bar_arrow"), SNAME("ColorPicker")));
+ alpha_slider->add_theme_style_override("slider", style_box_empty);
+ alpha_slider->add_theme_style_override("grabber_area", style_box_empty);
+ alpha_slider->add_theme_style_override("grabber_area_highlight", style_box_empty);
+}
+
void ColorPicker::_html_submitted(const String &p_html) {
if (updating || text_is_constructor || !c_text->is_visible()) {
return;
@@ -397,35 +430,15 @@ void ColorPicker::_update_color(bool p_update_sliders) {
updating = true;
if (p_update_sliders) {
- if (hsv_mode_enabled) {
- for (int i = 0; i < 4; i++) {
- scroll[i]->set_step(1.0);
- }
- scroll[0]->set_max(359);
- scroll[0]->set_value(h * 360.0);
- scroll[1]->set_max(100);
- scroll[1]->set_value(s * 100.0);
- scroll[2]->set_max(100);
- scroll[2]->set_value(v * 100.0);
- scroll[3]->set_max(255);
- scroll[3]->set_value(Math::round(color.components[3] * 255.0));
- } else {
- for (int i = 0; i < 4; i++) {
- if (raw_mode_enabled) {
- scroll[i]->set_step(0.01);
- scroll[i]->set_max(100);
- if (i == 3) {
- scroll[i]->set_max(1);
- }
- scroll[i]->set_value(color.components[i]);
- } else {
- scroll[i]->set_step(1);
- const float byte_value = Math::round(color.components[i] * 255.0);
- scroll[i]->set_max(next_power_of_2(MAX(255, byte_value)) - 1);
- scroll[i]->set_value(byte_value);
- }
- }
+ float step = modes[current_mode]->get_slider_step();
+ for (int i = 0; i < current_slider_count; i++) {
+ sliders[i]->set_max(modes[current_mode]->get_slider_max(i));
+ sliders[i]->set_step(step);
+ sliders[i]->set_value(modes[current_mode]->get_slider_value(i));
}
+ alpha_slider->set_max(modes[current_mode]->get_slider_max(current_slider_count));
+ alpha_slider->set_step(step);
+ alpha_slider->set_value(modes[current_mode]->get_slider_value(current_slider_count));
}
_update_text_value();
@@ -433,9 +446,10 @@ void ColorPicker::_update_color(bool p_update_sliders) {
sample->update();
uv_edit->update();
w_edit->update();
- for (int i = 0; i < 4; i++) {
- scroll[i]->update();
+ for (int i = 0; i < current_slider_count; i++) {
+ sliders[i]->update();
}
+ alpha_slider->update();
wheel->update();
wheel_uv->update();
updating = false;
@@ -481,15 +495,16 @@ Color ColorPicker::get_pick_color() const {
return color;
}
-void ColorPicker::set_picker_shape(PickerShapeType p_picker_type) {
- ERR_FAIL_INDEX(p_picker_type, SHAPE_MAX);
- picker_type = p_picker_type;
+void ColorPicker::set_picker_shape(PickerShapeType p_shape) {
+ ERR_FAIL_INDEX(p_shape, SHAPE_MAX);
+ current_shape = p_shape;
+
_update_controls();
_update_color();
}
ColorPicker::PickerShapeType ColorPicker::get_picker_shape() const {
- return picker_type;
+ return current_shape;
}
inline int ColorPicker::_get_preset_size() {
@@ -505,6 +520,21 @@ void ColorPicker::_add_preset_button(int p_size, const Color &p_color) {
preset_container->add_child(btn_preset);
}
+void ColorPicker::_set_color_mode(ColorModeType p_mode) {
+ if (slider_theme_modified) {
+ _reset_theme();
+ }
+
+ current_mode = p_mode;
+
+ if (!is_inside_tree()) {
+ return;
+ }
+
+ _update_controls();
+ _update_color();
+}
+
void ColorPicker::add_preset(const Color &p_color) {
if (presets.find(p_color)) {
presets.move_to_back(presets.find(p_color));
@@ -564,46 +594,14 @@ PackedColorArray ColorPicker::get_presets() const {
return arr;
}
-void ColorPicker::set_hsv_mode(bool p_enabled) {
- if (hsv_mode_enabled == p_enabled || raw_mode_enabled) {
- return;
- }
- hsv_mode_enabled = p_enabled;
- if (btn_hsv->is_pressed() != p_enabled) {
- btn_hsv->set_pressed(p_enabled);
- }
-
- if (!is_inside_tree()) {
- return;
- }
-
- _update_controls();
- _update_color();
-}
-
-bool ColorPicker::is_hsv_mode() const {
- return hsv_mode_enabled;
-}
-
-void ColorPicker::set_raw_mode(bool p_enabled) {
- if (raw_mode_enabled == p_enabled || hsv_mode_enabled) {
- return;
- }
- raw_mode_enabled = p_enabled;
- if (btn_raw->is_pressed() != p_enabled) {
- btn_raw->set_pressed(p_enabled);
- }
-
- if (!is_inside_tree()) {
- return;
- }
-
- _update_controls();
- _update_color();
+void ColorPicker::set_color_mode(ColorModeType p_mode) {
+ ERR_FAIL_INDEX(p_mode, MODE_MAX);
+ mode_option_button->select(p_mode);
+ _set_color_mode(p_mode);
}
-bool ColorPicker::is_raw_mode() const {
- return raw_mode_enabled;
+ColorPicker::ColorModeType ColorPicker::get_color_mode() const {
+ return current_mode;
}
void ColorPicker::set_deferred_mode(bool p_enabled) {
@@ -690,6 +688,8 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
if (!c) {
return;
}
+
+ PickerShapeType actual_shape = _get_actual_shape();
if (p_which == 0) {
Vector<Point2> points;
Vector<Color> colors;
@@ -697,7 +697,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
Color col = color;
Vector2 center = c->get_size() / 2.0;
- switch (picker_type) {
+ switch (actual_shape) {
case SHAPE_HSV_WHEEL: {
points.resize(4);
colors.resize(4);
@@ -759,7 +759,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
Ref<Texture2D> cursor = get_theme_icon(SNAME("picker_cursor"), SNAME("ColorPicker"));
int x;
int y;
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) {
x = center.x + (center.x * Math::cos(h * Math_TAU) * s) - (cursor->get_width() / 2);
y = center.y + (center.y * Math::sin(h * Math_TAU) * s) - (cursor->get_height() / 2);
} else {
@@ -773,7 +773,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
c->draw_texture(cursor, Point2(x, y));
col.set_hsv(h, 1, 1);
- if (picker_type == SHAPE_HSV_WHEEL) {
+ if (actual_shape == SHAPE_HSV_WHEEL) {
points.resize(4);
double h1 = h - (0.5 / 360);
double h2 = h + (0.5 / 360);
@@ -785,14 +785,14 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
} else if (p_which == 1) {
- if (picker_type == SHAPE_HSV_RECTANGLE) {
+ if (actual_shape == SHAPE_HSV_RECTANGLE) {
Ref<Texture2D> hue = get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
c->draw_texture_rect(hue, Rect2(Point2(), c->get_size()));
int y = c->get_size().y - c->get_size().y * (1.0 - h);
Color col;
col.set_hsv(h, 1, 1);
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
- } else if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ } else if (actual_shape == SHAPE_OKHSL_CIRCLE) {
Vector<Point2> points;
Vector<Color> colors;
Color col;
@@ -811,7 +811,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
int y = c->get_size().y - c->get_size().y * CLAMP(v, 0, 1);
col.set_ok_hsl(h, 1, v);
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
- } else if (picker_type == SHAPE_VHS_CIRCLE) {
+ } else if (actual_shape == SHAPE_VHS_CIRCLE) {
Vector<Point2> points;
Vector<Color> colors;
Color col;
@@ -833,87 +833,24 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
} else if (p_which == 2) {
c->draw_rect(Rect2(Point2(), c->get_size()), Color(1, 1, 1));
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) {
circle_mat->set_shader_param("v", v);
}
}
}
void ColorPicker::_slider_draw(int p_which) {
- Vector<Vector2> pos;
- pos.resize(4);
- Vector<Color> col;
- col.resize(4);
- Size2 size = scroll[p_which]->get_size();
- Color left_color;
- Color right_color;
- const real_t margin = 4 * get_theme_default_base_scale();
-
- if (p_which == 3) {
- scroll[p_which]->draw_texture_rect(get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
-
- left_color = color;
- left_color.a = 0;
- right_color = color;
- right_color.a = 1;
- } else {
- if (raw_mode_enabled) {
- return;
- }
- if (hsv_mode_enabled) {
- if (p_which == 0) {
- Ref<Texture2D> hue = get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
- scroll[p_which]->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
- scroll[p_which]->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(scroll[p_which]->get_size().x, margin)), false, Color(1, 1, 1), true);
- return;
- }
- Color s_col;
- Color v_col;
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
- s_col.set_ok_hsl(h, 0, v);
- } else {
- s_col.set_hsv(h, 0, v);
- }
- left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
- s_col.set_ok_hsl(h, 1, v);
- v_col.set_ok_hsl(h, s, 1);
- } else {
- s_col.set_hsv(h, 1, v);
- v_col.set_hsv(h, s, 1);
- }
- right_color = (p_which == 1) ? s_col : v_col;
- } else {
- left_color = Color(
- p_which == 0 ? 0 : color.r,
- p_which == 1 ? 0 : color.g,
- p_which == 2 ? 0 : color.b);
- right_color = Color(
- p_which == 0 ? 1 : color.r,
- p_which == 1 ? 1 : color.g,
- p_which == 2 ? 1 : color.b);
- }
- }
-
- col.set(0, left_color);
- col.set(1, right_color);
- col.set(2, right_color);
- col.set(3, left_color);
- pos.set(0, Vector2(0, margin));
- pos.set(1, Vector2(size.x, margin));
- pos.set(2, Vector2(size.x, margin * 2));
- pos.set(3, Vector2(0, margin * 2));
-
- scroll[p_which]->draw_polygon(pos, col);
+ modes[current_mode]->slider_draw(p_which);
}
void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
Ref<InputEventMouseButton> bev = p_event;
+ PickerShapeType current_picker = _get_actual_shape();
if (bev.is_valid()) {
if (bev->is_pressed() && bev->get_button_index() == MouseButton::LEFT) {
Vector2 center = c->get_size() / 2.0;
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (current_picker == SHAPE_VHS_CIRCLE || current_picker == SHAPE_OKHSL_CIRCLE) {
real_t dist = center.distance_to(bev->get_position());
if (dist <= center.x) {
real_t rad = center.angle_to_point(bev->get_position());
@@ -951,11 +888,12 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
}
}
changing_color = true;
- if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (current_picker == SHAPE_OKHSL_CIRCLE) {
color.set_ok_hsl(h, s, v, color.a);
- } else if (picker_type != SHAPE_OKHSL_CIRCLE) {
+ } else {
color.set_hsv(h, s, v, color.a);
}
+
last_color = color;
set_pick_color(color);
@@ -981,7 +919,7 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
}
Vector2 center = c->get_size() / 2.0;
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (current_picker == SHAPE_VHS_CIRCLE || current_picker == SHAPE_OKHSL_CIRCLE) {
real_t dist = center.distance_to(mev->get_position());
real_t rad = center.angle_to_point(mev->get_position());
h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
@@ -1002,9 +940,9 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
v = 1.0 - (y - corner_y) / real_size.y;
}
}
- if (picker_type != SHAPE_OKHSL_CIRCLE) {
+ if (current_picker != SHAPE_OKHSL_CIRCLE) {
color.set_hsv(h, s, v, color.a);
- } else if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ } else {
color.set_ok_hsl(h, s, v, color.a);
}
last_color = color;
@@ -1018,12 +956,13 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> bev = p_event;
+ PickerShapeType actual_shape = _get_actual_shape();
if (bev.is_valid()) {
if (bev->is_pressed() && bev->get_button_index() == MouseButton::LEFT) {
changing_color = true;
float y = CLAMP((float)bev->get_position().y, 0, w_edit->get_size().height);
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) {
v = 1.0 - (y / w_edit->get_size().height);
} else {
h = y / w_edit->get_size().height;
@@ -1031,9 +970,9 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
} else {
changing_color = false;
}
- if (picker_type != SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape != SHAPE_OKHSL_CIRCLE) {
color.set_hsv(h, s, v, color.a);
- } else if (picker_type == SHAPE_OKHSL_CIRCLE) {
+ } else {
color.set_ok_hsl(h, s, v, color.a);
}
last_color = color;
@@ -1053,16 +992,18 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
return;
}
float y = CLAMP((float)mev->get_position().y, 0, w_edit->get_size().height);
- if (picker_type == SHAPE_VHS_CIRCLE || picker_type == SHAPE_OKHSL_CIRCLE) {
+ if (actual_shape == SHAPE_VHS_CIRCLE || actual_shape == SHAPE_OKHSL_CIRCLE) {
v = 1.0 - (y / w_edit->get_size().height);
} else {
h = y / w_edit->get_size().height;
}
- if (hsv_mode_enabled && picker_type != SHAPE_OKHSL_CIRCLE) {
+
+ if (current_mode == MODE_HSV) {
color.set_hsv(h, s, v, color.a);
- } else if (hsv_mode_enabled && picker_type == SHAPE_OKHSL_CIRCLE) {
+ } else if (current_mode == MODE_OKHSL) {
color.set_ok_hsl(h, s, v, color.a);
}
+
last_color = color;
set_pick_color(color);
_update_color();
@@ -1130,7 +1071,7 @@ void ColorPicker::_screen_pick_pressed() {
screen = memnew(Control);
r->add_child(screen);
screen->set_as_top_level(true);
- screen->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ screen->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
screen->set_default_cursor_shape(CURSOR_POINTING_HAND);
screen->connect("gui_input", callable_mp(this, &ColorPicker::_screen_input));
// It immediately toggles off in the first press otherwise.
@@ -1153,21 +1094,30 @@ void ColorPicker::_focus_enter() {
c_text->select(0, 0);
}
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < current_slider_count; i++) {
if (values[i]->get_line_edit()->has_focus() && !has_ctext_focus) {
values[i]->get_line_edit()->select_all();
} else {
values[i]->get_line_edit()->select(0, 0);
}
}
+ if (alpha_value->get_line_edit()->has_focus() && !has_ctext_focus) {
+ alpha_value->get_line_edit()->select_all();
+ } else {
+ alpha_value->get_line_edit()->select(0, 0);
+ }
}
void ColorPicker::_focus_exit() {
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < current_slider_count; i++) {
if (!values[i]->get_line_edit()->get_menu()->is_visible()) {
values[i]->get_line_edit()->select(0, 0);
}
}
+ if (!alpha_value->get_line_edit()->get_menu()->is_visible()) {
+ alpha_value->get_line_edit()->select(0, 0);
+ }
+
c_text->select(0, 0);
}
@@ -1207,12 +1157,10 @@ bool ColorPicker::are_presets_visible() const {
void ColorPicker::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorPicker::set_pick_color);
ClassDB::bind_method(D_METHOD("get_pick_color"), &ColorPicker::get_pick_color);
- ClassDB::bind_method(D_METHOD("set_hsv_mode", "enabled"), &ColorPicker::set_hsv_mode);
- ClassDB::bind_method(D_METHOD("is_hsv_mode"), &ColorPicker::is_hsv_mode);
- ClassDB::bind_method(D_METHOD("set_raw_mode", "enabled"), &ColorPicker::set_raw_mode);
- ClassDB::bind_method(D_METHOD("is_raw_mode"), &ColorPicker::is_raw_mode);
ClassDB::bind_method(D_METHOD("set_deferred_mode", "mode"), &ColorPicker::set_deferred_mode);
ClassDB::bind_method(D_METHOD("is_deferred_mode"), &ColorPicker::is_deferred_mode);
+ ClassDB::bind_method(D_METHOD("set_color_mode", "color_mode"), &ColorPicker::set_color_mode);
+ ClassDB::bind_method(D_METHOD("get_color_mode"), &ColorPicker::get_color_mode);
ClassDB::bind_method(D_METHOD("set_edit_alpha", "show"), &ColorPicker::set_edit_alpha);
ClassDB::bind_method(D_METHOD("is_editing_alpha"), &ColorPicker::is_editing_alpha);
ClassDB::bind_method(D_METHOD("set_presets_enabled", "enabled"), &ColorPicker::set_presets_enabled);
@@ -1222,13 +1170,12 @@ void ColorPicker::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_preset", "color"), &ColorPicker::add_preset);
ClassDB::bind_method(D_METHOD("erase_preset", "color"), &ColorPicker::erase_preset);
ClassDB::bind_method(D_METHOD("get_presets"), &ColorPicker::get_presets);
- ClassDB::bind_method(D_METHOD("set_picker_shape", "picker"), &ColorPicker::set_picker_shape);
+ ClassDB::bind_method(D_METHOD("set_picker_shape", "shape"), &ColorPicker::set_picker_shape);
ClassDB::bind_method(D_METHOD("get_picker_shape"), &ColorPicker::get_picker_shape);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_pick_color", "get_pick_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hsv_mode"), "set_hsv_mode", "is_hsv_mode");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "raw_mode"), "set_raw_mode", "is_raw_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "color_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW,OKHSL"), "set_color_mode", "get_color_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deferred_mode"), "set_deferred_mode", "is_deferred_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle,OKHSL Circle"), "set_picker_shape", "get_picker_shape");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "presets_enabled"), "set_presets_enabled", "are_presets_enabled");
@@ -1238,6 +1185,11 @@ void ColorPicker::_bind_methods() {
ADD_SIGNAL(MethodInfo("preset_added", PropertyInfo(Variant::COLOR, "color")));
ADD_SIGNAL(MethodInfo("preset_removed", PropertyInfo(Variant::COLOR, "color")));
+ BIND_ENUM_CONSTANT(MODE_RGB);
+ BIND_ENUM_CONSTANT(MODE_HSV);
+ BIND_ENUM_CONSTANT(MODE_RAW);
+ BIND_ENUM_CONSTANT(MODE_OKHSL);
+
BIND_ENUM_CONSTANT(SHAPE_HSV_RECTANGLE);
BIND_ENUM_CONSTANT(SHAPE_HSV_WHEEL);
BIND_ENUM_CONSTANT(SHAPE_VHS_CIRCLE);
@@ -1250,6 +1202,7 @@ ColorPicker::ColorPicker() :
add_child(hb_edit, false, INTERNAL_MODE_FRONT);
hb_edit->set_v_size_flags(SIZE_EXPAND_FILL);
+ uv_edit = memnew(Control);
hb_edit->add_child(uv_edit);
uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(uv_edit));
uv_edit->set_mouse_filter(MOUSE_FILTER_PASS);
@@ -1260,11 +1213,13 @@ ColorPicker::ColorPicker() :
HBoxContainer *hb_smpl = memnew(HBoxContainer);
add_child(hb_smpl, false, INTERNAL_MODE_FRONT);
+ sample = memnew(TextureRect);
hb_smpl->add_child(sample);
sample->set_h_size_flags(SIZE_EXPAND_FILL);
sample->connect("gui_input", callable_mp(this, &ColorPicker::_sample_input));
sample->connect("draw", callable_mp(this, &ColorPicker::_sample_draw));
+ btn_pick = memnew(Button);
btn_pick->set_flat(true);
hb_smpl->add_child(btn_pick);
btn_pick->set_toggle_mode(true);
@@ -1277,51 +1232,35 @@ ColorPicker::ColorPicker() :
add_child(memnew(HSeparator), false, INTERNAL_MODE_FRONT);
VBoxContainer *vbr = memnew(VBoxContainer);
+
add_child(vbr, false, INTERNAL_MODE_FRONT);
vbr->set_h_size_flags(SIZE_EXPAND_FILL);
- for (int i = 0; i < 4; i++) {
- HBoxContainer *hbc = memnew(HBoxContainer);
+ GridContainer *gc = memnew(GridContainer);
- labels[i] = memnew(Label());
- labels[i]->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0));
- labels[i]->set_v_size_flags(SIZE_SHRINK_CENTER);
- hbc->add_child(labels[i]);
+ vbr->add_child(gc);
+ gc->set_h_size_flags(SIZE_EXPAND_FILL);
+ gc->set_columns(3);
- scroll[i] = memnew(HSlider);
- scroll[i]->set_v_size_flags(SIZE_SHRINK_CENTER);
- scroll[i]->set_focus_mode(FOCUS_NONE);
- hbc->add_child(scroll[i]);
-
- values[i] = memnew(SpinBox);
- scroll[i]->share(values[i]);
- hbc->add_child(values[i]);
- values[i]->get_line_edit()->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter));
- values[i]->get_line_edit()->connect("focus_exited", callable_mp(this, &ColorPicker::_focus_exit));
-
- scroll[i]->set_min(0);
- scroll[i]->set_page(0);
- scroll[i]->set_h_size_flags(SIZE_EXPAND_FILL);
-
- scroll[i]->connect("value_changed", callable_mp(this, &ColorPicker::_value_changed));
- scroll[i]->connect("draw", callable_mp(this, &ColorPicker::_slider_draw), make_binds(i));
-
- vbr->add_child(hbc);
+ for (int i = 0; i < SLIDER_COUNT + 1; i++) {
+ create_slider(gc, i);
}
- labels[3]->set_text("A");
+ alpha_label->set_text("A");
HBoxContainer *hhb = memnew(HBoxContainer);
vbr->add_child(hhb);
- hhb->add_child(btn_hsv);
- btn_hsv->set_text(RTR("HSV"));
- btn_hsv->connect("toggled", callable_mp(this, &ColorPicker::set_hsv_mode));
+ mode_option_button = memnew(OptionButton);
- hhb->add_child(btn_raw);
- btn_raw->set_text(RTR("Raw"));
- btn_raw->connect("toggled", callable_mp(this, &ColorPicker::set_raw_mode));
+ hhb->add_child(mode_option_button);
+ add_mode(new ColorModeRGB(this));
+ add_mode(new ColorModeHSV(this));
+ add_mode(new ColorModeRAW(this));
+ add_mode(new ColorModeOKHSL(this));
+ mode_option_button->connect("item_selected", callable_mp(this, &ColorPicker::_set_color_mode));
+ text_type = memnew(Button);
hhb->add_child(text_type);
text_type->set_text("#");
text_type->set_tooltip(RTR("Switch between hexadecimal and code values."));
@@ -1332,12 +1271,14 @@ ColorPicker::ColorPicker() :
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
}
+ c_text = memnew(LineEdit);
hhb->add_child(c_text);
c_text->set_h_size_flags(SIZE_EXPAND_FILL);
c_text->connect("text_submitted", callable_mp(this, &ColorPicker::_html_submitted));
c_text->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter));
c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit));
+ wheel_edit = memnew(AspectRatioContainer);
wheel_edit->set_h_size_flags(SIZE_EXPAND_FILL);
wheel_edit->set_v_size_flags(SIZE_EXPAND_FILL);
hb_edit->add_child(wheel_edit);
@@ -1347,41 +1288,53 @@ ColorPicker::ColorPicker() :
circle_mat.instantiate();
circle_mat->set_shader(circle_shader);
+ wheel_margin = memnew(MarginContainer);
wheel_margin->add_theme_constant_override("margin_bottom", 8);
wheel_edit->add_child(wheel_margin);
+ wheel = memnew(Control);
wheel_margin->add_child(wheel);
wheel->set_mouse_filter(MOUSE_FILTER_PASS);
wheel->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(2, wheel));
+ wheel_uv = memnew(Control);
wheel_margin->add_child(wheel_uv);
wheel_uv->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(wheel_uv));
wheel_uv->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, wheel_uv));
+ w_edit = memnew(Control);
hb_edit->add_child(w_edit);
w_edit->set_h_size_flags(SIZE_FILL);
w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input));
w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(1, w_edit));
- picker_type = SHAPE_HSV_RECTANGLE;
_update_controls();
updating = false;
set_pick_color(Color(1, 1, 1));
+ preset_separator = memnew(HSeparator);
add_child(preset_separator, false, INTERNAL_MODE_FRONT);
+ preset_container = memnew(GridContainer);
preset_container->set_h_size_flags(SIZE_EXPAND_FILL);
preset_container->set_columns(preset_column_count);
add_child(preset_container, false, INTERNAL_MODE_FRONT);
+ btn_add_preset = memnew(Button);
btn_add_preset->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER);
btn_add_preset->set_tooltip(RTR("Add current color as a preset."));
btn_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed));
preset_container->add_child(btn_add_preset);
}
+ColorPicker::~ColorPicker() {
+ for (int i = 0; i < modes.size(); i++) {
+ delete modes[i];
+ }
+}
+
/////////////////
void ColorPickerButton::_about_to_popup() {
@@ -1503,7 +1456,7 @@ void ColorPickerButton::_update_picker() {
popup = memnew(PopupPanel);
popup->set_wrap_controls(true);
picker = memnew(ColorPicker);
- picker->set_anchors_and_offsets_preset(PRESET_WIDE);
+ picker->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
popup->add_child(picker);
add_child(popup, false, INTERNAL_MODE_FRONT);
picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed));
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 953be032ec..e219c78319 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -34,16 +34,23 @@
#include "scene/gui/aspect_ratio_container.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
-#include "scene/gui/check_button.h"
+#include "scene/gui/control.h"
#include "scene/gui/grid_container.h"
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
+#include "scene/gui/option_button.h"
#include "scene/gui/popup.h"
#include "scene/gui/separator.h"
#include "scene/gui/slider.h"
#include "scene/gui/spin_box.h"
#include "scene/gui/texture_rect.h"
+class ColorMode;
+class ColorModeRGB;
+class ColorModeHSV;
+class ColorModeRAW;
+class ColorModeOKHSL;
+
class ColorPresetButton : public BaseButton {
GDCLASS(ColorPresetButton, BaseButton);
@@ -64,6 +71,15 @@ class ColorPicker : public BoxContainer {
GDCLASS(ColorPicker, BoxContainer);
public:
+ enum ColorModeType {
+ MODE_RGB,
+ MODE_HSV,
+ MODE_RAW,
+ MODE_OKHSL,
+
+ MODE_MAX
+ };
+
enum PickerShapeType {
SHAPE_HSV_RECTANGLE,
SHAPE_HSV_WHEEL,
@@ -73,38 +89,52 @@ public:
SHAPE_MAX
};
+ static const int SLIDER_COUNT = 4;
+
private:
static Ref<Shader> wheel_shader;
static Ref<Shader> circle_shader;
static Ref<Shader> circle_ok_color_shader;
static List<Color> preset_cache;
+ int current_slider_count = SLIDER_COUNT;
+
+ bool slider_theme_modified = true;
+
+ Vector<ColorMode *> modes;
+
Control *screen = nullptr;
- Control *uv_edit = memnew(Control);
- Control *w_edit = memnew(Control);
- AspectRatioContainer *wheel_edit = memnew(AspectRatioContainer);
- MarginContainer *wheel_margin = memnew(MarginContainer);
+ Control *uv_edit = nullptr;
+ Control *w_edit = nullptr;
+ AspectRatioContainer *wheel_edit = nullptr;
+ MarginContainer *wheel_margin = nullptr;
Ref<ShaderMaterial> wheel_mat;
Ref<ShaderMaterial> circle_mat;
- Control *wheel = memnew(Control);
- Control *wheel_uv = memnew(Control);
- TextureRect *sample = memnew(TextureRect);
- GridContainer *preset_container = memnew(GridContainer);
- HSeparator *preset_separator = memnew(HSeparator);
- Button *btn_add_preset = memnew(Button);
- Button *btn_pick = memnew(Button);
- CheckButton *btn_hsv = memnew(CheckButton);
- CheckButton *btn_raw = memnew(CheckButton);
- HSlider *scroll[4];
- SpinBox *values[4];
- Label *labels[4];
- Button *text_type = memnew(Button);
- LineEdit *c_text = memnew(LineEdit);
+ Control *wheel = nullptr;
+ Control *wheel_uv = nullptr;
+ TextureRect *sample = nullptr;
+ GridContainer *preset_container = nullptr;
+ HSeparator *preset_separator = nullptr;
+ Button *btn_add_preset = nullptr;
+ Button *btn_pick = nullptr;
+
+ OptionButton *mode_option_button = nullptr;
+
+ HSlider *sliders[SLIDER_COUNT];
+ SpinBox *values[SLIDER_COUNT];
+ Label *labels[SLIDER_COUNT];
+ Button *text_type = nullptr;
+ LineEdit *c_text = nullptr;
+
+ HSlider *alpha_slider = nullptr;
+ SpinBox *alpha_value = nullptr;
+ Label *alpha_label = nullptr;
bool edit_alpha = true;
Size2i ms;
bool text_is_constructor = false;
- PickerShapeType picker_type = SHAPE_HSV_WHEEL;
+ PickerShapeType current_shape = SHAPE_HSV_RECTANGLE;
+ ColorModeType current_mode = MODE_RGB;
const int preset_column_count = 9;
int prev_preset_size = 0;
@@ -114,8 +144,6 @@ private:
Color old_color;
bool display_old_color = false;
- bool raw_mode_enabled = false;
- bool hsv_mode_enabled = false;
bool deferred_mode_enabled = false;
bool updating = true;
bool changing_color = false;
@@ -128,6 +156,9 @@ private:
float v = 0.0;
Color last_color;
+ PickerShapeType _get_actual_shape() const;
+ void create_slider(GridContainer *gc, int idx);
+ void _reset_theme();
void _html_submitted(const String &p_html);
void _value_changed(double);
void _update_controls();
@@ -152,14 +183,21 @@ private:
inline int _get_preset_size();
void _add_preset_button(int p_size, const Color &p_color);
+ void _set_color_mode(ColorModeType p_mode);
+
protected:
void _notification(int);
static void _bind_methods();
public:
+ HSlider *get_slider(int idx);
+ Vector<float> get_active_slider_values();
+
static void init_shaders();
static void finish_shaders();
+ void add_mode(ColorMode *p_mode);
+
void set_edit_alpha(bool p_show);
bool is_editing_alpha() const;
@@ -173,7 +211,7 @@ public:
void set_display_old_color(bool p_enabled);
bool is_displaying_old_color() const;
- void set_picker_shape(PickerShapeType p_picker_type);
+ void set_picker_shape(PickerShapeType p_shape);
PickerShapeType get_picker_shape() const;
void add_preset(const Color &p_color);
@@ -181,11 +219,8 @@ public:
PackedColorArray get_presets() const;
void _update_presets();
- void set_hsv_mode(bool p_enabled);
- bool is_hsv_mode() const;
-
- void set_raw_mode(bool p_enabled);
- bool is_raw_mode() const;
+ void set_color_mode(ColorModeType p_mode);
+ ColorModeType get_color_mode() const;
void set_deferred_mode(bool p_enabled);
bool is_deferred_mode() const;
@@ -199,6 +234,7 @@ public:
void set_focus_on_line_edit();
ColorPicker();
+ ~ColorPicker();
};
class ColorPickerButton : public Button {
@@ -239,4 +275,5 @@ public:
};
VARIANT_ENUM_CAST(ColorPicker::PickerShapeType);
+VARIANT_ENUM_CAST(ColorPicker::ColorModeType);
#endif // COLOR_PICKER_H
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 118e77c009..686045901c 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1115,7 +1115,7 @@ Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const String
Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
const Ref<Font> *font = data.font_override.getptr(p_name);
- if (font && (*font)->get_data_count() > 0) {
+ if (font) {
return *font;
}
}
@@ -1642,7 +1642,7 @@ void Control::_set_anchors_layout_preset(int p_preset) {
case PRESET_BOTTOM_WIDE:
case PRESET_VCENTER_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_offsets_preset(preset, LayoutPresetMode::PRESET_MODE_MINSIZE);
break;
}
@@ -1718,7 +1718,7 @@ int Control::_get_anchors_layout_preset() const {
}
if (left == ANCHOR_BEGIN && right == ANCHOR_END && top == ANCHOR_BEGIN && bottom == ANCHOR_END) {
- return (int)LayoutPreset::PRESET_WIDE;
+ return (int)LayoutPreset::PRESET_FULL_RECT;
}
// Does not match any preset, return "Custom".
@@ -1737,7 +1737,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets) {
case PRESET_BOTTOM_WIDE:
case PRESET_LEFT_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_anchor(SIDE_LEFT, ANCHOR_BEGIN, p_keep_offsets);
break;
@@ -1765,7 +1765,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets) {
case PRESET_RIGHT_WIDE:
case PRESET_TOP_WIDE:
case PRESET_VCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_anchor(SIDE_TOP, ANCHOR_BEGIN, p_keep_offsets);
break;
@@ -1807,7 +1807,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets) {
case PRESET_RIGHT_WIDE:
case PRESET_BOTTOM_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_anchor(SIDE_RIGHT, ANCHOR_END, p_keep_offsets);
break;
}
@@ -1835,7 +1835,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets) {
case PRESET_RIGHT_WIDE:
case PRESET_BOTTOM_WIDE:
case PRESET_VCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_anchor(SIDE_BOTTOM, ANCHOR_END, p_keep_offsets);
break;
}
@@ -1870,7 +1870,7 @@ void Control::set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz
case PRESET_BOTTOM_WIDE:
case PRESET_LEFT_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
data.offset[0] = x * (0.0 - data.anchor[0]) + p_margin + parent_rect.position.x;
break;
@@ -1898,7 +1898,7 @@ void Control::set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz
case PRESET_RIGHT_WIDE:
case PRESET_TOP_WIDE:
case PRESET_VCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
data.offset[1] = parent_rect.size.y * (0.0 - data.anchor[1]) + p_margin + parent_rect.position.y;
break;
@@ -1940,7 +1940,7 @@ void Control::set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz
case PRESET_RIGHT_WIDE:
case PRESET_BOTTOM_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
data.offset[2] = x * (1.0 - data.anchor[2]) - p_margin + parent_rect.position.x;
break;
}
@@ -1968,7 +1968,7 @@ void Control::set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz
case PRESET_RIGHT_WIDE:
case PRESET_BOTTOM_WIDE:
case PRESET_VCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
data.offset[3] = parent_rect.size.y * (1.0 - data.anchor[3]) - p_margin + parent_rect.position.y;
break;
}
@@ -2003,7 +2003,7 @@ void Control::set_grow_direction_preset(LayoutPreset p_preset) {
case PRESET_BOTTOM_WIDE:
case PRESET_VCENTER_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_h_grow_direction(GrowDirection::GROW_DIRECTION_BOTH);
break;
}
@@ -2031,7 +2031,7 @@ void Control::set_grow_direction_preset(LayoutPreset p_preset) {
case PRESET_RIGHT_WIDE:
case PRESET_VCENTER_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_v_grow_direction(GrowDirection::GROW_DIRECTION_BOTH);
break;
}
@@ -2344,7 +2344,7 @@ void Control::set_focus_mode(FocusMode p_focus_mode) {
static Control *_next_control(Control *p_from) {
if (p_from->is_set_as_top_level()) {
- return nullptr; // can't go above
+ return nullptr; // Can't go above.
}
Control *parent = Object::cast_to<Control>(p_from->get_parent());
@@ -2364,7 +2364,7 @@ static Control *_next_control(Control *p_from) {
return c;
}
- //no next in parent, try the same in parent
+ // No next in parent, try the same in parent.
return _next_control(parent);
}
@@ -2388,7 +2388,7 @@ Control *Control::find_next_valid_focus() const {
}
}
- // find next child
+ // Find next child.
Control *next_child = nullptr;
@@ -2404,7 +2404,7 @@ Control *Control::find_next_valid_focus() const {
if (!next_child) {
next_child = _next_control(from);
- if (!next_child) { //nothing else.. go up and find either window or subwindow
+ if (!next_child) { // Nothing else. Go up and find either window or subwindow.
next_child = const_cast<Control *>(this);
while (next_child && !next_child->is_set_as_top_level()) {
next_child = cast_to<Control>(next_child->get_parent());
@@ -2422,7 +2422,7 @@ Control *Control::find_next_valid_focus() const {
}
}
- if (next_child == this) { // no next control->
+ if (next_child == from || next_child == this) { // No next control.
return (get_focus_mode() == FOCUS_ALL) ? next_child : nullptr;
}
if (next_child) {
@@ -2454,7 +2454,7 @@ static Control *_prev_control(Control *p_from) {
return p_from;
}
- //no prev in parent, try the same in parent
+ // No prev in parent, try the same in parent.
return _prev_control(child);
}
@@ -2478,12 +2478,12 @@ Control *Control::find_prev_valid_focus() const {
}
}
- // find prev child
+ // Find prev child.
Control *prev_child = nullptr;
if (from->is_set_as_top_level() || !Object::cast_to<Control>(from->get_parent())) {
- //find last of the children
+ // Find last of the children.
prev_child = _prev_control(from);
@@ -2506,7 +2506,7 @@ Control *Control::find_prev_valid_focus() const {
}
}
- if (prev_child == this) { // no prev control->
+ if (prev_child == from || prev_child == this) { // No prev control.
return (get_focus_mode() == FOCUS_ALL) ? prev_child : nullptr;
}
@@ -3300,7 +3300,7 @@ void Control::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode");
ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION);
- const String anchors_presets_options = "Custom:-1,PresetWide:15,"
+ const String anchors_presets_options = "Custom:-1,PresetFullRect:15,"
"PresetTopLeft:0,PresetTopRight:1,PresetBottomRight:3,PresetBottomLeft:2,"
"PresetCenterLeft:4,PresetCenterTop:5,PresetCenterRight:6,PresetCenterBottom:7,PresetCenter:8,"
"PresetLeftWide:9,PresetTopWide:10,PresetRightWide:11,PresetBottomWide:12,PresetVCenterWide:13,PresetHCenterWide:14";
@@ -3408,7 +3408,7 @@ void Control::_bind_methods() {
BIND_ENUM_CONSTANT(PRESET_BOTTOM_WIDE);
BIND_ENUM_CONSTANT(PRESET_VCENTER_WIDE);
BIND_ENUM_CONSTANT(PRESET_HCENTER_WIDE);
- BIND_ENUM_CONSTANT(PRESET_WIDE);
+ BIND_ENUM_CONSTANT(PRESET_FULL_RECT);
BIND_ENUM_CONSTANT(PRESET_MODE_MINSIZE);
BIND_ENUM_CONSTANT(PRESET_MODE_KEEP_WIDTH);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index f18dd99bff..50cf9faeed 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -116,7 +116,7 @@ public:
PRESET_BOTTOM_WIDE,
PRESET_VCENTER_WIDE,
PRESET_HCENTER_WIDE,
- PRESET_WIDE
+ PRESET_FULL_RECT
};
enum LayoutPresetMode {
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index a2b05ee50d..44e2bb89eb 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -161,6 +161,14 @@ bool AcceptDialog::has_autowrap() {
return label->get_autowrap_mode() != TextServer::AUTOWRAP_OFF;
}
+void AcceptDialog::set_ok_button_text(String p_ok_button_text) {
+ ok->set_text(p_ok_button_text);
+}
+
+String AcceptDialog::get_ok_button_text() const {
+ return ok->get_text();
+}
+
void AcceptDialog::register_text_enter(Control *p_line_edit) {
ERR_FAIL_NULL(p_line_edit);
LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit);
@@ -262,7 +270,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin
Button *AcceptDialog::add_cancel_button(const String &p_cancel) {
String c = p_cancel;
if (p_cancel.is_empty()) {
- c = RTR("Cancel");
+ c = "Cancel";
}
Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c);
b->connect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed));
@@ -306,11 +314,15 @@ void AcceptDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text"), &AcceptDialog::get_text);
ClassDB::bind_method(D_METHOD("set_autowrap", "autowrap"), &AcceptDialog::set_autowrap);
ClassDB::bind_method(D_METHOD("has_autowrap"), &AcceptDialog::has_autowrap);
+ ClassDB::bind_method(D_METHOD("set_ok_button_text", "text"), &AcceptDialog::set_ok_button_text);
+ ClassDB::bind_method(D_METHOD("get_ok_button_text"), &AcceptDialog::get_ok_button_text);
ADD_SIGNAL(MethodInfo("confirmed"));
ADD_SIGNAL(MethodInfo("cancelled"));
ADD_SIGNAL(MethodInfo("custom_action", PropertyInfo(Variant::STRING_NAME, "action")));
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "ok_button_text"), "set_ok_button_text", "get_ok_button_text");
+
ADD_GROUP("Dialog", "dialog");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "dialog_text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dialog_hide_on_ok"), "set_hide_on_ok", "get_hide_on_ok");
@@ -349,7 +361,7 @@ AcceptDialog::AcceptDialog() {
hbc->add_spacer();
ok = memnew(Button);
- ok->set_text(RTR("OK"));
+ ok->set_text("OK");
hbc->add_child(ok);
hbc->add_spacer();
@@ -365,8 +377,20 @@ AcceptDialog::~AcceptDialog() {
// ConfirmationDialog
+void ConfirmationDialog::set_cancel_button_text(String p_cancel_button_text) {
+ cancel->set_text(p_cancel_button_text);
+}
+
+String ConfirmationDialog::get_cancel_button_text() const {
+ return cancel->get_text();
+}
+
void ConfirmationDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_cancel_button"), &ConfirmationDialog::get_cancel_button);
+ ClassDB::bind_method(D_METHOD("set_cancel_button_text"), &ConfirmationDialog::set_cancel_button_text);
+ ClassDB::bind_method(D_METHOD("get_cancel_button_text"), &ConfirmationDialog::get_cancel_button_text);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "cancel_button_text"), "set_cancel_button_text", "get_cancel_button_text");
}
Button *ConfirmationDialog::get_cancel_button() {
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 41fd9c0a10..711361de88 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -97,6 +97,9 @@ public:
void set_autowrap(bool p_autowrap);
bool has_autowrap();
+ void set_ok_button_text(String p_ok_button_text);
+ String get_ok_button_text() const;
+
AcceptDialog();
~AcceptDialog();
};
@@ -110,6 +113,10 @@ protected:
public:
Button *get_cancel_button();
+
+ void set_cancel_button_text(String p_cancel_button_text);
+ String get_cancel_button_text() const;
+
ConfirmationDialog();
};
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 0e0f8bde83..65bc359e2e 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -170,7 +170,11 @@ Vector<String> FileDialog::get_selected_files() const {
};
void FileDialog::update_dir() {
- dir->set_text(dir_access->get_current_dir(false));
+ if (root_prefix.is_empty()) {
+ dir->set_text(dir_access->get_current_dir(false));
+ } else {
+ dir->set_text(dir_access->get_current_dir(false).trim_prefix(root_prefix).trim_prefix("/"));
+ }
if (drives->is_visible()) {
if (dir_access->get_current_dir().is_network_share_path()) {
@@ -188,10 +192,8 @@ void FileDialog::update_dir() {
}
void FileDialog::_dir_submitted(String p_dir) {
- dir_access->change_dir(p_dir);
+ _change_dir(root_prefix.plus_file(p_dir));
file->set_text("");
- invalidate();
- update_dir();
_push_history();
}
@@ -378,9 +380,7 @@ bool FileDialog::_is_open_should_be_disabled() {
}
void FileDialog::_go_up() {
- dir_access->change_dir("..");
- update_file_list();
- update_dir();
+ _change_dir("..");
_push_history();
}
@@ -390,9 +390,7 @@ void FileDialog::_go_back() {
}
local_history_pos--;
- dir_access->change_dir(local_history[local_history_pos]);
- update_file_list();
- update_dir();
+ _change_dir(local_history[local_history_pos]);
dir_prev->set_disabled(local_history_pos == 0);
dir_next->set_disabled(local_history_pos == local_history.size() - 1);
@@ -404,9 +402,7 @@ void FileDialog::_go_forward() {
}
local_history_pos++;
- dir_access->change_dir(local_history[local_history_pos]);
- update_file_list();
- update_dir();
+ _change_dir(local_history[local_history_pos]);
dir_prev->set_disabled(local_history_pos == 0);
dir_next->set_disabled(local_history_pos == local_history.size() - 1);
@@ -423,10 +419,10 @@ void FileDialog::deselect_all() {
switch (mode) {
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(RTR("Select Current Folder"));
+ set_ok_button_text(RTR("Select Current Folder"));
break;
case FILE_MODE_OPEN_ANY:
case FILE_MODE_SAVE_FILE:
@@ -450,7 +446,7 @@ void FileDialog::_tree_selected() {
if (!d["dir"]) {
file->set_text(d["name"]);
} else if (mode == FILE_MODE_OPEN_DIR) {
- get_ok_button()->set_text(RTR("Select This Folder"));
+ set_ok_button_text(RTR("Select This Folder"));
}
get_ok_button()->set_disabled(_is_open_should_be_disabled());
@@ -465,12 +461,10 @@ void FileDialog::_tree_item_activated() {
Dictionary d = ti->get_metadata(0);
if (d["dir"]) {
- dir_access->change_dir(d["name"]);
+ _change_dir(d["name"]);
if (mode == FILE_MODE_OPEN_FILE || mode == FILE_MODE_OPEN_FILES || mode == FILE_MODE_OPEN_DIR || mode == FILE_MODE_OPEN_ANY) {
file->set_text("");
}
- call_deferred(SNAME("_update_file_list"));
- call_deferred(SNAME("_update_dir"));
_push_history();
} else {
_action_pressed();
@@ -486,7 +480,12 @@ void FileDialog::update_file_name() {
String filter_str = filters[idx];
String file_str = file->get_text();
String base_name = file_str.get_basename();
- file_str = base_name + "." + filter_str.strip_edges().to_lower();
+ Vector<String> filter_substr = filter_str.split(";");
+ if (filter_substr.size() >= 2) {
+ file_str = base_name + "." + filter_substr[0].strip_edges().get_extension().to_lower();
+ } else {
+ file_str = base_name + "." + filter_str.strip_edges().get_extension().to_lower();
+ }
file->set_text(file_str);
}
}
@@ -674,9 +673,13 @@ void FileDialog::clear_filters() {
invalidate();
}
-void FileDialog::add_filter(const String &p_filter) {
+void FileDialog::add_filter(const String &p_filter, const String &p_description) {
ERR_FAIL_COND_MSG(p_filter.begins_with("."), "Filter must be \"filename.extension\", can't start with dot.");
- filters.push_back(p_filter);
+ if (p_description.is_empty()) {
+ filters.push_back(p_filter);
+ } else {
+ filters.push_back(vformat("%s ; %s", p_filter, p_description));
+ }
update_filters();
invalidate();
}
@@ -704,9 +707,7 @@ String FileDialog::get_current_path() const {
}
void FileDialog::set_current_dir(const String &p_dir) {
- dir_access->change_dir(p_dir);
- update_dir();
- invalidate();
+ _change_dir(p_dir);
_push_history();
}
@@ -732,6 +733,27 @@ void FileDialog::set_current_path(const String &p_path) {
}
}
+void FileDialog::set_root_subfolder(const String &p_root) {
+ root_subfolder = p_root;
+ ERR_FAIL_COND_MSG(!dir_access->dir_exists(p_root), "root_subfolder must be an existing sub-directory.");
+
+ local_history.clear();
+ local_history_pos = -1;
+
+ dir_access->change_dir(root_subfolder);
+ if (root_subfolder.is_empty()) {
+ root_prefix = "";
+ } else {
+ root_prefix = dir_access->get_current_dir();
+ }
+ invalidate();
+ update_dir();
+}
+
+String FileDialog::get_root_subfolder() const {
+ return root_subfolder;
+}
+
void FileDialog::set_mode_overrides_title(bool p_override) {
mode_overrides_title = p_override;
}
@@ -746,35 +768,35 @@ void FileDialog::set_file_mode(FileMode p_mode) {
mode = p_mode;
switch (mode) {
case FILE_MODE_OPEN_FILE:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open a File"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open File(s)"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(RTR("Select Current Folder"));
+ set_ok_button_text(RTR("Select Current Folder"));
if (mode_overrides_title) {
set_title(TTRC("Open a Directory"));
}
makedir->show();
break;
case FILE_MODE_OPEN_ANY:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open a File or Directory"));
}
makedir->show();
break;
case FILE_MODE_SAVE_FILE:
- get_ok_button()->set_text(RTR("Save"));
+ set_ok_button_text(RTR("Save"));
if (mode_overrides_title) {
set_title(TTRC("Save a File"));
}
@@ -810,6 +832,8 @@ void FileDialog::set_access(Access p_access) {
} break;
}
access = p_access;
+ root_prefix = "";
+ root_subfolder = "";
_update_drives();
invalidate();
update_filters();
@@ -832,10 +856,8 @@ FileDialog::Access FileDialog::get_access() const {
void FileDialog::_make_dir_confirm() {
Error err = dir_access->make_dir(makedirname->get_text().strip_edges());
if (err == OK) {
- dir_access->change_dir(makedirname->get_text().strip_edges());
- invalidate();
+ _change_dir(makedirname->get_text().strip_edges());
update_filters();
- update_dir();
_push_history();
} else {
mkdirerr->popup_centered(Size2(250, 50));
@@ -850,11 +872,25 @@ void FileDialog::_make_dir() {
void FileDialog::_select_drive(int p_idx) {
String d = drives->get_item_text(p_idx);
- dir_access->change_dir(d);
+ _change_dir(d);
file->set_text("");
+ _push_history();
+}
+
+void FileDialog::_change_dir(const String &p_new_dir) {
+ if (root_prefix.is_empty()) {
+ dir_access->change_dir(p_new_dir);
+ } else {
+ String old_dir = dir_access->get_current_dir();
+ dir_access->change_dir(p_new_dir);
+ if (!dir_access->get_current_dir(false).begins_with(root_prefix)) {
+ dir_access->change_dir(old_dir);
+ return;
+ }
+ }
+
invalidate();
update_dir();
- _push_history();
}
void FileDialog::_update_drives(bool p_select) {
@@ -887,7 +923,7 @@ void FileDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_cancel_pressed"), &FileDialog::_cancel_pressed);
ClassDB::bind_method(D_METHOD("clear_filters"), &FileDialog::clear_filters);
- ClassDB::bind_method(D_METHOD("add_filter", "filter"), &FileDialog::add_filter);
+ ClassDB::bind_method(D_METHOD("add_filter", "filter", "description"), &FileDialog::add_filter, DEFVAL(""));
ClassDB::bind_method(D_METHOD("set_filters", "filters"), &FileDialog::set_filters);
ClassDB::bind_method(D_METHOD("get_filters"), &FileDialog::get_filters);
ClassDB::bind_method(D_METHOD("get_current_dir"), &FileDialog::get_current_dir);
@@ -904,6 +940,8 @@ void FileDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line_edit"), &FileDialog::get_line_edit);
ClassDB::bind_method(D_METHOD("set_access", "access"), &FileDialog::set_access);
ClassDB::bind_method(D_METHOD("get_access"), &FileDialog::get_access);
+ ClassDB::bind_method(D_METHOD("set_root_subfolder", "dir"), &FileDialog::set_root_subfolder);
+ ClassDB::bind_method(D_METHOD("get_root_subfolder"), &FileDialog::get_root_subfolder);
ClassDB::bind_method(D_METHOD("set_show_hidden_files", "show"), &FileDialog::set_show_hidden_files);
ClassDB::bind_method(D_METHOD("is_showing_hidden_files"), &FileDialog::is_showing_hidden_files);
ClassDB::bind_method(D_METHOD("_update_file_name"), &FileDialog::update_file_name);
@@ -916,6 +954,7 @@ void FileDialog::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "mode_overrides_title"), "set_mode_overrides_title", "is_mode_overriding_title");
ADD_PROPERTY(PropertyInfo(Variant::INT, "file_mode", PROPERTY_HINT_ENUM, "Open File,Open Files,Open Folder,Open Any,Save"), "set_file_mode", "get_file_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User Data,File System"), "set_access", "get_access");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "root_subfolder"), "set_root_subfolder", "get_root_subfolder");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "filters"), "set_filters", "get_filters");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_hidden_files"), "set_show_hidden_files", "is_showing_hidden_files");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir", PROPERTY_HINT_DIR, "", PROPERTY_USAGE_NONE), "set_current_dir", "get_current_dir");
@@ -1021,7 +1060,7 @@ FileDialog::FileDialog() {
message = memnew(Label);
message->hide();
- message->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ message->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
tree->add_child(message);
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 2e326d2949..017c9d8d4f 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -101,6 +101,8 @@ private:
void _push_history();
bool mode_overrides_title = true;
+ String root_subfolder;
+ String root_prefix;
static bool default_show_hidden_files;
bool show_hidden_files = false;
@@ -131,6 +133,7 @@ private:
void _go_back();
void _go_forward();
+ void _change_dir(const String &p_new_dir);
void _update_drives(bool p_select = true);
virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
@@ -148,7 +151,7 @@ protected:
public:
void popup_file_dialog();
void clear_filters();
- void add_filter(const String &p_filter);
+ void add_filter(const String &p_filter, const String &p_description = "");
void set_filters(const Vector<String> &p_filters);
Vector<String> get_filters() const;
@@ -162,6 +165,9 @@ public:
void set_current_file(const String &p_file);
void set_current_path(const String &p_path);
+ void set_root_subfolder(const String &p_root);
+ String get_root_subfolder() const;
+
void set_mode_overrides_title(bool p_override);
bool is_mode_overriding_title() const;
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 0690acbe16..cc27a6b7c2 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -382,7 +382,7 @@ void GradientEdit::_color_changed(const Color &p_color) {
emit_signal(SNAME("ramp_changed"));
}
-void GradientEdit::set_ramp(const Vector<real_t> &p_offsets, const Vector<Color> &p_colors) {
+void GradientEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) {
ERR_FAIL_COND(p_offsets.size() != p_colors.size());
points.clear();
for (int i = 0; i < p_offsets.size(); i++) {
@@ -396,8 +396,8 @@ void GradientEdit::set_ramp(const Vector<real_t> &p_offsets, const Vector<Color>
update();
}
-Vector<real_t> GradientEdit::get_offsets() const {
- Vector<real_t> ret;
+Vector<float> GradientEdit::get_offsets() const {
+ Vector<float> ret;
for (int i = 0; i < points.size(); i++) {
ret.push_back(points[i].offset);
}
@@ -437,6 +437,10 @@ ColorPicker *GradientEdit::get_picker() {
return picker;
}
+PopupPanel *GradientEdit::get_popup() {
+ return popup;
+}
+
void GradientEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("ramp_changed"));
}
diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h
index 4e3c6525f9..b7c99f1f1c 100644
--- a/scene/gui/gradient_edit.h
+++ b/scene/gui/gradient_edit.h
@@ -67,14 +67,15 @@ protected:
static void _bind_methods();
public:
- void set_ramp(const Vector<real_t> &p_offsets, const Vector<Color> &p_colors);
- Vector<real_t> get_offsets() const;
+ void set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors);
+ Vector<float> get_offsets() const;
Vector<Color> get_colors() const;
void set_points(Vector<Gradient::Point> &p_points);
Vector<Gradient::Point> &get_points();
void set_interpolation_mode(Gradient::InterpolationMode p_interp_mode);
Gradient::InterpolationMode get_interpolation_mode();
ColorPicker *get_picker();
+ PopupPanel *get_popup();
virtual Size2 get_minimum_size() const override;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index c219eafbf7..e30759aa3e 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -2376,7 +2376,7 @@ GraphEdit::GraphEdit() {
top_layer = memnew(GraphEditFilter(this));
add_child(top_layer, false, INTERNAL_MODE_BACK);
top_layer->set_mouse_filter(MOUSE_FILTER_PASS);
- top_layer->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ top_layer->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
top_layer->connect("draw", callable_mp(this, &GraphEdit::_top_layer_draw));
top_layer->connect("gui_input", callable_mp(this, &GraphEdit::_top_layer_input));
top_layer->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key));
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 87706cd0d7..92016ca42e 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -44,26 +44,6 @@ struct _MinSizeCache {
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- int value = p_value;
- if (value == -1) {
- if (opentype_features.has(tag)) {
- opentype_features.erase(tag);
- _shape();
- update();
- }
- } else {
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
- opentype_features[tag] = value;
- _shape();
- update();
- }
- }
- notify_property_list_changed();
- return true;
- }
if (!str.begins_with("slot/")) {
return false;
@@ -106,18 +86,6 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- if (opentype_features.has(tag)) {
- r_ret = opentype_features[tag];
- return true;
- } else {
- r_ret = -1;
- return true;
- }
- }
-
if (!str.begins_with("slot/")) {
return false;
}
@@ -156,12 +124,6 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
}
void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
- for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
- String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
- }
- p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
-
int idx = 0;
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
@@ -471,7 +433,7 @@ void GraphNode::_shape() {
} else {
title_buf->set_direction((TextServer::Direction)text_direction);
}
- title_buf->add_string(title, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
+ title_buf->add_string(title, font, font_size, language);
}
#ifdef TOOLS_ENABLED
@@ -726,29 +688,6 @@ Control::TextDirection GraphNode::get_text_direction() const {
return text_direction;
}
-void GraphNode::clear_opentype_features() {
- opentype_features.clear();
- _shape();
- update();
-}
-
-void GraphNode::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;
- _shape();
- update();
- }
-}
-
-int GraphNode::get_opentype_feature(const String &p_name) const {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag)) {
- return -1;
- }
- return opentype_features[tag];
-}
-
void GraphNode::set_language(const String &p_language) {
if (language != p_language) {
language = p_language;
@@ -1043,9 +982,6 @@ void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_title"), &GraphNode::get_title);
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &GraphNode::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &GraphNode::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &GraphNode::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &GraphNode::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features"), &GraphNode::clear_opentype_features);
ClassDB::bind_method(D_METHOD("set_language", "language"), &GraphNode::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &GraphNode::get_language);
@@ -1105,8 +1041,6 @@ void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_overlay"), &GraphNode::get_overlay);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
- 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::VECTOR2, "position_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_position_offset", "get_position_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizable"), "set_resizable", "is_resizable");
@@ -1114,6 +1048,10 @@ void GraphNode::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "comment"), "set_comment", "is_comment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "overlay", PROPERTY_HINT_ENUM, "Disabled,Breakpoint,Position"), "set_overlay", "get_overlay");
+ ADD_GROUP("BiDi", "");
+ 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_SIGNAL(MethodInfo("position_offset_changed"));
ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx")));
ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to")));
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index f6c943dc89..0651eb5cc9 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -60,7 +60,6 @@ private:
String title;
Ref<TextLine> title_buf;
- Dictionary opentype_features;
String language;
TextDirection text_direction = TEXT_DIRECTION_AUTO;
@@ -148,10 +147,6 @@ public:
void set_text_direction(TextDirection p_text_direction);
TextDirection get_text_direction() const;
- void set_opentype_feature(const String &p_name, int p_value);
- int get_opentype_feature(const String &p_name) const;
- void clear_opentype_features();
-
void set_language(const String &p_language);
String get_language() const;
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index 6f8518a7b0..eaa6943ad2 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -41,8 +41,6 @@ void GridContainer::_notification(int p_what) {
int hsep = get_theme_constant(SNAME("h_separation"));
int vsep = get_theme_constant(SNAME("v_separation"));
- int max_col = MIN(get_child_count(), columns);
- int max_row = ceil((float)get_child_count() / (float)columns);
// Compute the per-column/per-row data.
int valid_controls_index = 0;
@@ -79,6 +77,9 @@ void GridContainer::_notification(int p_what) {
}
}
+ int max_col = MIN(valid_controls_index, columns);
+ int max_row = ceil((float)valid_controls_index / (float)columns);
+
// Consider all empty columns expanded.
for (int i = valid_controls_index; i < columns; i++) {
col_expanded.insert(i);
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index aeb5338022..d0a25972f8 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -43,11 +43,11 @@ void ItemList::_shape(int p_idx) {
} else {
item.text_buf->set_direction((TextServer::Direction)item.text_direction);
}
- item.text_buf->add_string(item.text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), item.opentype_features, (!item.language.is_empty()) ? item.language : TranslationServer::get_singleton()->get_tool_locale());
+ item.text_buf->add_string(item.text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), item.language);
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
- item.text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
+ item.text_buf->set_break_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
} else {
- item.text_buf->set_flags(TextServer::BREAK_NONE);
+ item.text_buf->set_break_flags(TextServer::BREAK_NONE);
}
item.text_buf->set_text_overrun_behavior(text_overrun_behavior);
item.text_buf->set_max_lines_visible(max_text_lines);
@@ -117,35 +117,6 @@ Control::TextDirection ItemList::get_item_text_direction(int p_idx) const {
return items[p_idx].text_direction;
}
-void ItemList::clear_item_opentype_features(int p_idx) {
- ERR_FAIL_INDEX(p_idx, items.size());
- items.write[p_idx].opentype_features.clear();
- _shape(p_idx);
- update();
-}
-
-void ItemList::set_item_opentype_feature(int p_idx, const String &p_name, int p_value) {
- if (p_idx < 0) {
- p_idx += get_item_count();
- }
- ERR_FAIL_INDEX(p_idx, items.size());
- int32_t tag = TS->name_to_tag(p_name);
- if (!items[p_idx].opentype_features.has(tag) || (int)items[p_idx].opentype_features[tag] != p_value) {
- items.write[p_idx].opentype_features[tag] = p_value;
- _shape(p_idx);
- update();
- }
-}
-
-int ItemList::get_item_opentype_feature(int p_idx, const String &p_name) const {
- ERR_FAIL_INDEX_V(p_idx, items.size(), -1);
- int32_t tag = TS->name_to_tag(p_name);
- if (!items[p_idx].opentype_features.has(tag)) {
- return -1;
- }
- return items[p_idx].opentype_features[tag];
-}
-
void ItemList::set_item_language(int p_idx, const String &p_language) {
if (p_idx < 0) {
p_idx += get_item_count();
@@ -499,10 +470,10 @@ void ItemList::set_max_text_lines(int p_lines) {
max_text_lines = p_lines;
for (int i = 0; i < items.size(); i++) {
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
- items.write[i].text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
+ items.write[i].text_buf->set_break_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
items.write[i].text_buf->set_max_lines_visible(p_lines);
} else {
- items.write[i].text_buf->set_flags(TextServer::BREAK_NONE);
+ items.write[i].text_buf->set_break_flags(TextServer::BREAK_NONE);
}
}
shape_changed = true;
@@ -540,9 +511,9 @@ void ItemList::set_icon_mode(IconMode p_mode) {
icon_mode = p_mode;
for (int i = 0; i < items.size(); i++) {
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
- items.write[i].text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
+ items.write[i].text_buf->set_break_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
} else {
- items.write[i].text_buf->set_flags(TextServer::BREAK_NONE);
+ items.write[i].text_buf->set_break_flags(TextServer::BREAK_NONE);
}
}
shape_changed = true;
@@ -1656,10 +1627,6 @@ void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_item_text_direction", "idx", "direction"), &ItemList::set_item_text_direction);
ClassDB::bind_method(D_METHOD("get_item_text_direction", "idx"), &ItemList::get_item_text_direction);
- ClassDB::bind_method(D_METHOD("set_item_opentype_feature", "idx", "tag", "value"), &ItemList::set_item_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_item_opentype_feature", "idx", "tag"), &ItemList::get_item_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_item_opentype_features", "idx"), &ItemList::clear_item_opentype_features);
-
ClassDB::bind_method(D_METHOD("set_item_language", "idx", "language"), &ItemList::set_item_language);
ClassDB::bind_method(D_METHOD("get_item_language", "idx"), &ItemList::get_item_language);
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index a15b090149..c7d87da0b5 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -58,7 +58,6 @@ private:
Ref<Texture2D> tag_icon;
String text;
Ref<TextParagraph> text_buf;
- Dictionary opentype_features;
String language;
TextDirection text_direction = TEXT_DIRECTION_AUTO;
@@ -145,10 +144,6 @@ public:
void set_item_text_direction(int p_idx, TextDirection p_text_direction);
TextDirection get_item_text_direction(int p_idx) const;
- void set_item_opentype_feature(int p_idx, const String &p_name, int p_value);
- int get_item_opentype_feature(int p_idx, const String &p_name) const;
- void clear_item_opentype_features(int p_idx);
-
void set_item_language(int p_idx, const String &p_language);
String get_item_language(int p_idx) const;
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 82ab7c2e18..8094812203 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -31,6 +31,7 @@
#include "label.h"
#include "core/config/project_settings.h"
+#include "core/core_string_names.h"
#include "core/string/print_string.h"
#include "core/string/translation.h"
@@ -64,17 +65,18 @@ bool Label::is_uppercase() const {
}
int Label::get_line_height(int p_line) const {
- Ref<Font> font = get_theme_font(SNAME("font"));
+ Ref<Font> font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
if (p_line >= 0 && p_line < lines_rid.size()) {
- return TS->shaped_text_get_size(lines_rid[p_line]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM);
+ return TS->shaped_text_get_size(lines_rid[p_line]).y;
} else if (lines_rid.size() > 0) {
int h = 0;
for (int i = 0; i < lines_rid.size(); i++) {
- h = MAX(h, TS->shaped_text_get_size(lines_rid[i]).y) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM);
+ h = MAX(h, TS->shaped_text_get_size(lines_rid[i]).y);
}
return h;
} else {
- return font->get_height(get_theme_font_size(SNAME("font_size")));
+ int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
+ return font->get_height(font_size);
}
}
@@ -83,7 +85,6 @@ void Label::_shape() {
int width = (get_size().width - style->get_minimum_size().width);
if (dirty || font_dirty) {
- String lang = (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale();
if (dirty) {
TS->shaped_text_clear(text_rid);
}
@@ -92,21 +93,24 @@ void Label::_shape() {
} else {
TS->shaped_text_set_direction(text_rid, (TextServer::Direction)text_direction);
}
- const Ref<Font> &font = get_theme_font(SNAME("font"));
- int font_size = get_theme_font_size(SNAME("font_size"));
+ const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
+ int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
ERR_FAIL_COND(font.is_null());
- String text = (uppercase) ? TS->string_to_upper(xl_text, lang) : xl_text;
+ String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) {
text = text.substr(0, visible_chars);
}
if (dirty) {
- TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, lang);
+ TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, font->get_opentype_features(), language);
} 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_set_span_update_font(text_rid, i, font->get_rids(), font_size, font->get_opentype_features());
}
}
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
+ }
TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, text));
dirty = false;
font_dirty = false;
@@ -119,10 +123,10 @@ void Label::_shape() {
}
lines_rid.clear();
- uint16_t autowrap_flags = TextServer::BREAK_MANDATORY;
+ BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY;
switch (autowrap_mode) {
case TextServer::AUTOWRAP_WORD_SMART:
- autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY;
+ autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY;
break;
case TextServer::AUTOWRAP_WORD:
autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY;
@@ -156,23 +160,23 @@ void Label::_shape() {
}
if (lines_dirty) {
- uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIM;
+ BitField<TextServer::TextOverrunFlag> overrun_flags = TextServer::OVERRUN_NO_TRIM;
switch (overrun_behavior) {
case TextServer::OVERRUN_TRIM_WORD_ELLIPSIS:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
- overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY);
+ overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS);
break;
case TextServer::OVERRUN_TRIM_ELLIPSIS:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS);
break;
case TextServer::OVERRUN_TRIM_WORD:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY);
break;
case TextServer::OVERRUN_TRIM_CHAR:
- overrun_flags |= TextServer::OVERRUN_TRIM;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
break;
case TextServer::OVERRUN_NO_TRIMMING:
break;
@@ -184,7 +188,7 @@ void Label::_shape() {
int visible_lines = get_visible_line_count();
bool lines_hidden = visible_lines > 0 && visible_lines < lines_rid.size();
if (lines_hidden) {
- overrun_flags |= TextServer::OVERRUN_ENFORCE_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_ENFORCE_ELLIPSIS);
}
if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) {
for (int i = 0; i < lines_rid.size(); i++) {
@@ -202,7 +206,7 @@ void Label::_shape() {
for (int i = 0; i < lines_rid.size(); i++) {
if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) {
TS->shaped_text_fit_to_width(lines_rid[i], width);
- overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE;
+ overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE);
TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags);
TS->shaped_text_fit_to_width(lines_rid[i], width, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS);
} else {
@@ -221,9 +225,8 @@ void Label::_shape() {
}
void Label::_update_visible() {
- int line_spacing = get_theme_constant(SNAME("line_spacing"), SNAME("Label"));
+ int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"), SNAME("Label"));
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"), SNAME("Label"));
- Ref<Font> font = get_theme_font(SNAME("font"));
int lines_visible = lines_rid.size();
if (max_lines_visible >= 0 && lines_visible > max_lines_visible) {
@@ -233,7 +236,7 @@ void Label::_update_visible() {
minsize.height = 0;
int last_line = MIN(lines_rid.size(), lines_visible + lines_skipped);
for (int64_t i = lines_skipped; i < last_line; i++) {
- minsize.height += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
+ minsize.height += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
if (minsize.height > (get_size().height - style->get_minimum_size().height + line_spacing)) {
break;
}
@@ -293,17 +296,19 @@ void Label::_notification(int p_what) {
RID ci = get_canvas_item();
+ bool has_settings = settings.is_valid();
+
Size2 string_size;
Size2 size = get_size();
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"));
- Ref<Font> font = get_theme_font(SNAME("font"));
- Color font_color = get_theme_color(SNAME("font_color"));
- Color font_shadow_color = get_theme_color(SNAME("font_shadow_color"));
- Point2 shadow_ofs(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y")));
- int line_spacing = get_theme_constant(SNAME("line_spacing"));
- Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
- int outline_size = get_theme_constant(SNAME("outline_size"));
- int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size"));
+ Ref<Font> font = (has_settings && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
+ Color font_color = has_settings ? settings->get_font_color() : get_theme_color(SNAME("font_color"));
+ Color font_shadow_color = has_settings ? settings->get_shadow_color() : get_theme_color(SNAME("font_shadow_color"));
+ Point2 shadow_ofs = has_settings ? settings->get_shadow_offset() : Point2(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y")));
+ int line_spacing = has_settings ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"));
+ Color font_outline_color = has_settings ? settings->get_outline_color() : get_theme_color(SNAME("font_outline_color"));
+ int outline_size = has_settings ? settings->get_outline_size() : get_theme_constant(SNAME("outline_size"));
+ int shadow_outline_size = has_settings ? settings->get_shadow_size() : get_theme_constant(SNAME("shadow_outline_size"));
bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL);
bool rtl_layout = is_layout_rtl();
@@ -314,7 +319,7 @@ void Label::_notification(int p_what) {
// Get number of lines to fit to the height.
for (int64_t i = lines_skipped; i < lines_rid.size(); i++) {
- total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
+ total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
break;
}
@@ -334,7 +339,7 @@ void Label::_notification(int p_what) {
int total_glyphs = 0;
total_h = 0;
for (int64_t i = lines_skipped; i < last_line; i++) {
- total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
+ total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
total_glyphs += TS->shaped_text_get_glyph_count(lines_rid[i]) + TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]);
}
int visible_glyphs = total_glyphs * percent_visible;
@@ -374,7 +379,7 @@ void Label::_notification(int p_what) {
for (int i = lines_skipped; i < last_line; i++) {
Size2 line_size = TS->shaped_text_get_size(lines_rid[i]);
ofs.x = 0;
- ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + font->get_spacing(TextServer::SPACING_TOP);
+ ofs.y += TS->shaped_text_get_ascent(lines_rid[i]);
switch (horizontal_alignment) {
case HORIZONTAL_ALIGNMENT_FILL:
if (rtl && autowrap_mode != TextServer::AUTOWRAP_OFF) {
@@ -527,7 +532,7 @@ void Label::_notification(int p_what) {
}
}
}
- ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing + font->get_spacing(TextServer::SPACING_BOTTOM);
+ ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing;
}
} break;
@@ -550,8 +555,10 @@ Size2 Label::get_minimum_size() const {
Size2 min_size = minsize;
- Ref<Font> font = get_theme_font(SNAME("font"));
- min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size(SNAME("font_size"))) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM));
+ const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
+ int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
+
+ min_size.height = MAX(min_size.height, font->get_height(font_size) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM));
Size2 min_style = get_theme_stylebox(SNAME("normal"))->get_minimum_size();
if (autowrap_mode != TextServer::AUTOWRAP_OFF) {
@@ -576,13 +583,12 @@ int Label::get_line_count() const {
}
int Label::get_visible_line_count() const {
- Ref<Font> font = get_theme_font(SNAME("font"));
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"));
- int line_spacing = get_theme_constant(SNAME("line_spacing"));
+ int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"));
int lines_visible = 0;
float total_h = 0.0;
for (int64_t i = lines_skipped; i < lines_rid.size(); i++) {
- total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
+ total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
break;
}
@@ -639,6 +645,28 @@ void Label::set_text(const String &p_string) {
update_minimum_size();
}
+void Label::_invalidate() {
+ font_dirty = true;
+ update();
+}
+
+void Label::set_label_settings(const Ref<LabelSettings> &p_settings) {
+ if (settings != p_settings) {
+ if (settings.is_valid()) {
+ settings->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate));
+ }
+ settings = p_settings;
+ if (settings.is_valid()) {
+ settings->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate), varray(), CONNECT_REFERENCE_COUNTED);
+ }
+ _invalidate();
+ }
+}
+
+Ref<LabelSettings> Label::get_label_settings() const {
+ return settings;
+}
+
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) {
@@ -674,29 +702,6 @@ Control::TextDirection Label::get_text_direction() const {
return text_direction;
}
-void Label::clear_opentype_features() {
- opentype_features.clear();
- font_dirty = true;
- update();
-}
-
-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;
- font_dirty = true;
- update();
- }
-}
-
-int Label::get_opentype_feature(const String &p_name) const {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag)) {
- return -1;
- }
- return opentype_features[tag];
-}
-
void Label::set_language(const String &p_language) {
if (language != p_language) {
language = p_language;
@@ -818,56 +823,6 @@ int Label::get_total_character_count() const {
return xl_text.length();
}
-bool Label::_set(const StringName &p_name, const Variant &p_value) {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- int value = p_value;
- if (value == -1) {
- if (opentype_features.has(tag)) {
- opentype_features.erase(tag);
- font_dirty = true;
- update();
- }
- } else {
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
- opentype_features[tag] = value;
- font_dirty = true;
- update();
- }
- }
- notify_property_list_changed();
- return true;
- }
-
- return false;
-}
-
-bool Label::_get(const StringName &p_name, Variant &r_ret) const {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- if (opentype_features.has(tag)) {
- r_ret = opentype_features[tag];
- return true;
- } else {
- r_ret = -1;
- return true;
- }
- }
- return false;
-}
-
-void Label::_get_property_list(List<PropertyInfo> *p_list) const {
- for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
- String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
- }
- p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
-}
-
void Label::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &Label::set_horizontal_alignment);
ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &Label::get_horizontal_alignment);
@@ -875,11 +830,10 @@ void Label::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_vertical_alignment"), &Label::get_vertical_alignment);
ClassDB::bind_method(D_METHOD("set_text", "text"), &Label::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &Label::get_text);
+ ClassDB::bind_method(D_METHOD("set_label_settings", "settings"), &Label::set_label_settings);
+ ClassDB::bind_method(D_METHOD("get_label_settings"), &Label::get_label_settings);
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &Label::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &Label::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &Label::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features"), &Label::clear_opentype_features);
ClassDB::bind_method(D_METHOD("set_language", "language"), &Label::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &Label::get_language);
ClassDB::bind_method(D_METHOD("set_autowrap_mode", "autowrap_mode"), &Label::set_autowrap_mode);
@@ -910,6 +864,7 @@ void Label::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override_options"), &Label::get_structured_text_bidi_override_options);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "label_settings", PROPERTY_HINT_RESOURCE_TYPE, "LabelSettings"), "set_label_settings", "get_label_settings");
ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_vertical_alignment", "get_vertical_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
@@ -924,11 +879,9 @@ void Label::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters_behavior", PROPERTY_HINT_ENUM, "Characters Before Shaping,Characters After Shaping,Glyphs (Layout Direction),Glyphs (Left-to-Right),Glyphs (Right-to-Left)"), "set_visible_characters_behavior", "get_visible_characters_behavior");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible");
- ADD_GROUP("Locale", "");
+ ADD_GROUP("BiDi", "");
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_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");
}
diff --git a/scene/gui/label.h b/scene/gui/label.h
index fac3d75a1b..3734fce1bb 100644
--- a/scene/gui/label.h
+++ b/scene/gui/label.h
@@ -32,6 +32,7 @@
#define LABEL_H
#include "scene/gui/control.h"
+#include "scene/resources/label_settings.h"
class Label : public Control {
GDCLASS(Label, Control);
@@ -53,7 +54,6 @@ private:
RID text_rid;
Vector<RID> lines_rid;
- Dictionary opentype_features;
String language;
TextDirection text_direction = TEXT_DIRECTION_AUTO;
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
@@ -66,18 +66,17 @@ private:
int lines_skipped = 0;
int max_lines_visible = -1;
+ Ref<LabelSettings> settings;
+
void _update_visible();
void _shape();
+ void _invalidate();
protected:
void _notification(int p_what);
static void _bind_methods();
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
-
public:
virtual Size2 get_minimum_size() const override;
@@ -90,13 +89,12 @@ public:
void set_text(const String &p_string);
String get_text() const;
+ void set_label_settings(const Ref<LabelSettings> &p_settings);
+ Ref<LabelSettings> get_label_settings() const;
+
void set_text_direction(TextDirection p_text_direction);
TextDirection get_text_direction() const;
- void set_opentype_feature(const String &p_name, int p_value);
- int get_opentype_feature(const String &p_name) const;
- void clear_opentype_features();
-
void set_language(const String &p_language);
String get_language() const;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 540250c8e9..39f8f23cd8 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -744,6 +744,17 @@ void LineEdit::_notification(int p_what) {
update();
} break;
+ case NOTIFICATION_INTERNAL_PROCESS: {
+ if (caret_blinking) {
+ caret_blink_timer += get_process_delta_time();
+
+ if (caret_blink_timer >= caret_blink_speed) {
+ caret_blink_timer = 0.0;
+ _toggle_draw_caret();
+ }
+ }
+ } break;
+
case NOTIFICATION_DRAW: {
if ((!has_focus() && !(menu && menu->has_focus()) && !caret_force_displayed) || !window_has_focus) {
draw_caret = false;
@@ -776,7 +787,7 @@ void LineEdit::_notification(int p_what) {
int x_ofs = 0;
bool using_placeholder = text.is_empty() && ime_text.is_empty();
float text_width = TS->shaped_text_get_size(text_rid).x;
- float text_height = TS->shaped_text_get_size(text_rid).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM);
+ float text_height = TS->shaped_text_get_size(text_rid).y;
switch (alignment) {
case HORIZONTAL_ALIGNMENT_FILL:
@@ -991,8 +1002,9 @@ void LineEdit::_notification(int p_what) {
case NOTIFICATION_FOCUS_ENTER: {
if (!caret_force_displayed) {
if (caret_blink_enabled) {
- if (caret_blink_timer->is_stopped()) {
- caret_blink_timer->start();
+ if (!caret_blinking) {
+ caret_blinking = true;
+ caret_blink_timer = 0.0;
}
} else {
draw_caret = true;
@@ -1010,7 +1022,7 @@ void LineEdit::_notification(int p_what) {
case NOTIFICATION_FOCUS_EXIT: {
if (caret_blink_enabled && !caret_force_displayed) {
- caret_blink_timer->stop();
+ caret_blinking = false;
}
if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
@@ -1318,14 +1330,16 @@ bool LineEdit::is_caret_blink_enabled() const {
void LineEdit::set_caret_blink_enabled(const bool p_enabled) {
caret_blink_enabled = p_enabled;
+ set_process_internal(p_enabled);
if (has_focus() || caret_force_displayed) {
if (p_enabled) {
- if (caret_blink_timer->is_stopped()) {
- caret_blink_timer->start();
+ if (!caret_blinking) {
+ caret_blinking = true;
+ caret_blink_timer = 0.0;
}
} else {
- caret_blink_timer->stop();
+ caret_blinking = false;
}
}
@@ -1345,20 +1359,19 @@ void LineEdit::set_caret_force_displayed(const bool p_enabled) {
}
float LineEdit::get_caret_blink_speed() const {
- return caret_blink_timer->get_wait_time();
+ return caret_blink_speed;
}
void LineEdit::set_caret_blink_speed(const float p_speed) {
ERR_FAIL_COND(p_speed <= 0);
- caret_blink_timer->set_wait_time(p_speed);
+ caret_blink_speed = p_speed;
}
void LineEdit::_reset_caret_blink_timer() {
if (caret_blink_enabled) {
draw_caret = true;
if (has_focus()) {
- caret_blink_timer->stop();
- caret_blink_timer->start();
+ caret_blink_timer = 0.0;
update();
}
}
@@ -1438,29 +1451,6 @@ Control::TextDirection LineEdit::get_text_direction() const {
return text_direction;
}
-void LineEdit::clear_opentype_features() {
- opentype_features.clear();
- _shape();
- update();
-}
-
-void LineEdit::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;
- _shape();
- update();
- }
-}
-
-int LineEdit::get_opentype_feature(const String &p_name) const {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag)) {
- return -1;
- }
- return opentype_features[tag];
-}
-
void LineEdit::set_language(const String &p_language) {
if (language != p_language) {
language = p_language;
@@ -1675,7 +1665,7 @@ Size2 LineEdit::get_minimum_size() const {
Size2 min_size;
// Minimum size of text.
- float em_space_size = font->get_char_size('M', 0, font_size).x;
+ float em_space_size = font->get_char_size('M', font_size).x;
min_size.width = get_theme_constant(SNAME("minimum_character_width")) * em_space_size;
if (expand_to_text_length) {
@@ -1683,7 +1673,7 @@ Size2 LineEdit::get_minimum_size() const {
min_size.width = MAX(min_size.width, full_width + em_space_size);
}
- min_size.height = MAX(TS->shaped_text_get_size(text_rid).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM), font->get_height(font_size));
+ min_size.height = MAX(TS->shaped_text_get_size(text_rid).y, font->get_height(font_size));
// Take icons into account.
int icon_max_width = 0;
@@ -2142,7 +2132,10 @@ void LineEdit::_shape() {
const Ref<Font> &font = get_theme_font(SNAME("font"));
int font_size = get_theme_font_size(SNAME("font_size"));
ERR_FAIL_COND(font.is_null());
- TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
+ TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, font->get_opentype_features(), language);
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
+ }
TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, t));
full_width = TS->shaped_text_get_size(text_rid).x;
@@ -2223,56 +2216,6 @@ Key LineEdit::_get_menu_action_accelerator(const String &p_action) {
}
}
-bool LineEdit::_set(const StringName &p_name, const Variant &p_value) {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- int value = p_value;
- if (value == -1) {
- if (opentype_features.has(tag)) {
- opentype_features.erase(tag);
- _shape();
- update();
- }
- } else {
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
- opentype_features[tag] = value;
- _shape();
- update();
- }
- }
- notify_property_list_changed();
- return true;
- }
-
- return false;
-}
-
-bool LineEdit::_get(const StringName &p_name, Variant &r_ret) const {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- if (opentype_features.has(tag)) {
- r_ret = opentype_features[tag];
- return true;
- } else {
- r_ret = -1;
- return true;
- }
- }
- return false;
-}
-
-void LineEdit::_get_property_list(List<PropertyInfo> *p_list) const {
- for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
- String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
- }
- p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
-}
-
void LineEdit::_validate_property(PropertyInfo &property) const {
if (!caret_blink_enabled && property.name == "caret_blink_speed") {
property.usage = PROPERTY_USAGE_NO_EDITOR;
@@ -2298,9 +2241,6 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_draw_control_chars", "enable"), &LineEdit::set_draw_control_chars);
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &LineEdit::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &LineEdit::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &LineEdit::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &LineEdit::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features"), &LineEdit::clear_opentype_features);
ClassDB::bind_method(D_METHOD("set_language", "language"), &LineEdit::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &LineEdit::get_language);
ClassDB::bind_method(D_METHOD("set_structured_text_bidi_override", "parser"), &LineEdit::set_structured_text_bidi_override);
@@ -2406,18 +2346,20 @@ void LineEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
- 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::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars");
- 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("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");
ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_column", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_caret_column", "get_caret_column");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_force_displayed"), "set_caret_force_displayed", "is_caret_force_displayed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled");
+
+ ADD_GROUP("BiDi", "");
+ 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, "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");
}
void LineEdit::_ensure_menu() {
@@ -2508,10 +2450,6 @@ LineEdit::LineEdit(const String &p_placeholder) {
set_mouse_filter(MOUSE_FILTER_STOP);
set_process_unhandled_key_input(true);
- caret_blink_timer = memnew(Timer);
- add_child(caret_blink_timer, false, INTERNAL_MODE_FRONT);
- caret_blink_timer->set_wait_time(0.65);
- caret_blink_timer->connect("timeout", callable_mp(this, &LineEdit::_toggle_draw_caret));
set_caret_blink_enabled(false);
set_placeholder(p_placeholder);
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 0fb178fca4..557da35bfd 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -105,7 +105,6 @@ private:
int scroll_offset = 0;
int max_length = 0; // 0 for no maximum.
- Dictionary opentype_features;
String language;
TextDirection text_direction = TEXT_DIRECTION_AUTO;
TextDirection input_direction = TEXT_DIRECTION_LTR;
@@ -160,7 +159,9 @@ private:
bool caret_blink_enabled = false;
bool caret_force_displayed = false;
bool draw_caret = true;
- Timer *caret_blink_timer = nullptr;
+ float caret_blink_speed = 0.65;
+ double caret_blink_timer = 0.0;
+ bool caret_blinking = false;
bool _is_over_clear_button(const Point2 &p_pos) const;
@@ -208,9 +209,6 @@ protected:
virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
virtual void gui_input(const Ref<InputEvent> &p_event) override;
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
void _validate_property(PropertyInfo &property) const override;
public:
@@ -246,10 +244,6 @@ public:
void set_text_direction(TextDirection p_text_direction);
TextDirection get_text_direction() const;
- void set_opentype_feature(const String &p_name, int p_value);
- int get_opentype_feature(const String &p_name) const;
- void clear_opentype_features();
-
void set_language(const String &p_language);
String get_language() const;
diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp
index dca6437519..30c0bb3321 100644
--- a/scene/gui/link_button.cpp
+++ b/scene/gui/link_button.cpp
@@ -43,7 +43,7 @@ void LinkButton::_shape() {
text_buf->set_direction((TextServer::Direction)text_direction);
}
TS->shaped_text_set_bidi_override(text_buf->get_rid(), structured_text_parser(st_parser, st_args, xl_text));
- text_buf->add_string(xl_text, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
+ text_buf->add_string(xl_text, font, font_size, language);
}
void LinkButton::set_text(const String &p_text) {
@@ -96,29 +96,6 @@ Control::TextDirection LinkButton::get_text_direction() const {
return text_direction;
}
-void LinkButton::clear_opentype_features() {
- opentype_features.clear();
- _shape();
- update();
-}
-
-void LinkButton::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;
- _shape();
- update();
- }
-}
-
-int LinkButton::get_opentype_feature(const String &p_name) const {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag)) {
- return -1;
- }
- return opentype_features[tag];
-}
-
void LinkButton::set_language(const String &p_language) {
if (language != p_language) {
language = p_language;
@@ -237,64 +214,11 @@ void LinkButton::_notification(int p_what) {
}
}
-bool LinkButton::_set(const StringName &p_name, const Variant &p_value) {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- int value = p_value;
- if (value == -1) {
- if (opentype_features.has(tag)) {
- opentype_features.erase(tag);
- _shape();
- update();
- }
- } else {
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
- opentype_features[tag] = value;
- _shape();
- update();
- }
- }
- notify_property_list_changed();
- return true;
- }
-
- return false;
-}
-
-bool LinkButton::_get(const StringName &p_name, Variant &r_ret) const {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- if (opentype_features.has(tag)) {
- r_ret = opentype_features[tag];
- return true;
- } else {
- r_ret = -1;
- return true;
- }
- }
- return false;
-}
-
-void LinkButton::_get_property_list(List<PropertyInfo> *p_list) const {
- for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
- String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
- }
- p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
-}
-
void LinkButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_text", "text"), &LinkButton::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &LinkButton::get_text);
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &LinkButton::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &LinkButton::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &LinkButton::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &LinkButton::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features"), &LinkButton::clear_opentype_features);
ClassDB::bind_method(D_METHOD("set_language", "language"), &LinkButton::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &LinkButton::get_language);
ClassDB::bind_method(D_METHOD("set_underline_mode", "underline_mode"), &LinkButton::set_underline_mode);
@@ -309,10 +233,11 @@ void LinkButton::_bind_methods() {
BIND_ENUM_CONSTANT(UNDERLINE_MODE_NEVER);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_mode");
+
+ ADD_GROUP("BiDi", "");
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, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_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");
}
diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h
index 6d2dcbde84..54a31f06ce 100644
--- a/scene/gui/link_button.h
+++ b/scene/gui/link_button.h
@@ -50,7 +50,6 @@ private:
Ref<TextLine> text_buf;
UnderlineMode underline_mode = UNDERLINE_MODE_ALWAYS;
- Dictionary opentype_features;
String language;
TextDirection text_direction = TEXT_DIRECTION_AUTO;
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
@@ -63,10 +62,6 @@ protected:
void _notification(int p_what);
static void _bind_methods();
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
-
public:
void set_text(const String &p_text);
String get_text() const;
@@ -80,10 +75,6 @@ public:
void set_text_direction(TextDirection p_text_direction);
TextDirection get_text_direction() const;
- void set_opentype_feature(const String &p_name, int p_value);
- int get_opentype_feature(const String &p_name) const;
- void clear_opentype_features();
-
void set_language(const String &p_language);
String get_language() const;
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 5931c112eb..928bab8842 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -760,11 +760,11 @@ void PopupMenu::_shape_item(int p_item) {
} else {
items.write[p_item].text_buf->set_direction((TextServer::Direction)items[p_item].text_direction);
}
- items.write[p_item].text_buf->add_string(items.write[p_item].xl_text, font, font_size, items[p_item].opentype_features, !items[p_item].language.is_empty() ? items[p_item].language : TranslationServer::get_singleton()->get_tool_locale());
+ items.write[p_item].text_buf->add_string(items.write[p_item].xl_text, font, font_size, items[p_item].language);
items.write[p_item].accel_text_buf->clear();
items.write[p_item].accel_text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
- items.write[p_item].accel_text_buf->add_string(_get_accel_text(items.write[p_item]), font, font_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
+ items.write[p_item].accel_text_buf->add_string(_get_accel_text(items.write[p_item]), font, font_size);
items.write[p_item].dirty = false;
}
}
@@ -1067,29 +1067,6 @@ void PopupMenu::set_item_text_direction(int p_item, Control::TextDirection p_tex
}
}
-void PopupMenu::clear_item_opentype_features(int p_item) {
- if (p_item < 0) {
- p_item += get_item_count();
- }
- ERR_FAIL_INDEX(p_item, items.size());
- items.write[p_item].opentype_features.clear();
- items.write[p_item].dirty = true;
- control->update();
-}
-
-void PopupMenu::set_item_opentype_feature(int p_item, const String &p_name, int p_value) {
- if (p_item < 0) {
- p_item += get_item_count();
- }
- ERR_FAIL_INDEX(p_item, items.size());
- int32_t tag = TS->name_to_tag(p_name);
- if (!items[p_item].opentype_features.has(tag) || (int)items[p_item].opentype_features[tag] != p_value) {
- items.write[p_item].opentype_features[tag] = p_value;
- items.write[p_item].dirty = true;
- control->update();
- }
-}
-
void PopupMenu::set_item_language(int p_item, const String &p_language) {
if (p_item < 0) {
p_item += get_item_count();
@@ -1195,15 +1172,6 @@ Control::TextDirection PopupMenu::get_item_text_direction(int p_item) const {
return items[p_item].text_direction;
}
-int PopupMenu::get_item_opentype_feature(int p_item, const String &p_name) const {
- ERR_FAIL_INDEX_V(p_item, items.size(), -1);
- int32_t tag = TS->name_to_tag(p_name);
- if (!items[p_item].opentype_features.has(tag)) {
- return -1;
- }
- return items[p_item].opentype_features[tag];
-}
-
String PopupMenu::get_item_language(int p_item) const {
ERR_FAIL_INDEX_V(p_item, items.size(), "");
return items[p_item].language;
@@ -1853,7 +1821,6 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_item_text", "index", "text"), &PopupMenu::set_item_text);
ClassDB::bind_method(D_METHOD("set_item_text_direction", "index", "direction"), &PopupMenu::set_item_text_direction);
- ClassDB::bind_method(D_METHOD("set_item_opentype_feature", "index", "tag", "value"), &PopupMenu::set_item_opentype_feature);
ClassDB::bind_method(D_METHOD("set_item_language", "index", "language"), &PopupMenu::set_item_language);
ClassDB::bind_method(D_METHOD("set_item_icon", "index", "icon"), &PopupMenu::set_item_icon);
ClassDB::bind_method(D_METHOD("set_item_checked", "index", "checked"), &PopupMenu::set_item_checked);
@@ -1876,8 +1843,6 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_text", "index"), &PopupMenu::get_item_text);
ClassDB::bind_method(D_METHOD("get_item_text_direction", "index"), &PopupMenu::get_item_text_direction);
- ClassDB::bind_method(D_METHOD("get_item_opentype_feature", "index", "tag"), &PopupMenu::get_item_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_item_opentype_features", "index"), &PopupMenu::clear_item_opentype_features);
ClassDB::bind_method(D_METHOD("get_item_language", "index"), &PopupMenu::get_item_language);
ClassDB::bind_method(D_METHOD("get_item_icon", "index"), &PopupMenu::get_item_icon);
ClassDB::bind_method(D_METHOD("is_item_checked", "index"), &PopupMenu::is_item_checked);
@@ -1944,7 +1909,7 @@ void PopupMenu::popup(const Rect2 &p_bounds) {
PopupMenu::PopupMenu() {
// Margin Container
margin_container = memnew(MarginContainer);
- margin_container->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ margin_container->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
add_child(margin_container, false, INTERNAL_MODE_FRONT);
margin_container->connect("draw", callable_mp(this, &PopupMenu::_draw_background));
@@ -1956,7 +1921,7 @@ PopupMenu::PopupMenu() {
// The control which will display the items
control = memnew(Control);
control->set_clip_contents(false);
- control->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ control->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
control->set_h_size_flags(Control::SIZE_EXPAND_FILL);
control->set_v_size_flags(Control::SIZE_EXPAND_FILL);
scroll_container->add_child(control, false, INTERNAL_MODE_FRONT);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 8218c6122e..daa38b0e6d 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -47,7 +47,6 @@ class PopupMenu : public Popup {
Ref<TextLine> text_buf;
Ref<TextLine> accel_text_buf;
- Dictionary opentype_features;
String language;
Control::TextDirection text_direction = Control::TEXT_DIRECTION_AUTO;
@@ -171,8 +170,6 @@ public:
void set_item_text(int p_idx, const String &p_text);
void set_item_text_direction(int p_idx, Control::TextDirection p_text_direction);
- void set_item_opentype_feature(int p_idx, const String &p_name, int p_value);
- void clear_item_opentype_features(int p_idx);
void set_item_language(int p_idx, const String &p_language);
void set_item_icon(int p_idx, const Ref<Texture2D> &p_icon);
void set_item_checked(int p_idx, bool p_checked);
@@ -195,7 +192,6 @@ public:
String get_item_text(int p_idx) const;
Control::TextDirection get_item_text_direction(int p_idx) const;
- int get_item_opentype_feature(int p_idx, const String &p_name) const;
String get_item_language(int p_idx) const;
int get_item_idx_from_text(const String &text) const;
Ref<Texture2D> get_item_icon(int p_idx) const;
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 0516c8e722..94e0944628 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -149,7 +149,12 @@ RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item
return it;
}
} break;
- case ITEM_NEWLINE:
+ case ITEM_NEWLINE: {
+ offset += 1;
+ if (offset == p_position) {
+ return it;
+ }
+ } break;
case ITEM_IMAGE:
case ITEM_TABLE: {
offset += 1;
@@ -227,8 +232,10 @@ void RichTextLabel::_update_line_font(ItemFrame *p_frame, int p_line, const Ref<
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);
+ TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font->get_opentype_features());
+ for (int j = 0; j < TextServer::SPACING_MAX; j++) {
+ TS->shaped_text_set_spacing(t, TextServer::SpacingType(j), font->get_spacing(TextServer::SpacingType(j)));
+ }
}
}
@@ -263,7 +270,7 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font
if (tab_size > 0) { // Align inline tabs.
Vector<float> tabs;
- tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width);
+ tabs.push_back(tab_size * p_base_font->get_char_size(' ', p_base_font_size).width);
l.text_buf->tab_align(tabs);
}
@@ -424,10 +431,10 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
Line &l = p_frame->lines[p_line];
MutexLock lock(l.text_buf->get_mutex());
- uint16_t autowrap_flags = TextServer::BREAK_MANDATORY;
+ BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY;
switch (autowrap_mode) {
case TextServer::AUTOWRAP_WORD_SMART:
- autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY;
+ autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY;
break;
case TextServer::AUTOWRAP_WORD:
autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY;
@@ -441,7 +448,8 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
// Clear cache.
l.text_buf->clear();
- l.text_buf->set_flags(autowrap_flags | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_TRIM_EDGE_SPACES);
+ l.text_buf->set_break_flags(autowrap_flags);
+ l.text_buf->set_justification_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 +461,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
if (tab_size > 0) { // Align inline tabs.
Vector<float> tabs;
- tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width);
+ tabs.push_back(tab_size * p_base_font->get_char_size(' ', p_base_font_size).width);
l.text_buf->tab_align(tabs);
}
@@ -483,7 +491,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
if (font_size == -1) {
font_size = p_base_font_size;
}
- l.text_buf->add_string("\n", font, font_size, Dictionary(), "");
+ l.text_buf->add_string("\n", font, font_size);
text += "\n";
l.char_count++;
remaining_characters--;
@@ -498,7 +506,6 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
if (font_size == -1) {
font_size = p_base_font_size;
}
- Dictionary font_ftr = _find_font_features(it);
String lang = _find_language(it);
String tx = t->text;
if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING && visible_characters >= 0 && remaining_characters >= 0) {
@@ -506,7 +513,7 @@ float 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, (uint64_t)it);
+ l.text_buf->add_string(tx, font, font_size, lang, (uint64_t)it);
text += tx;
l.char_count += tx.length();
} break;
@@ -837,7 +844,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
//draw_rect(Rect2(p_ofs + off, TS->shaped_text_get_size(rid)), Color(1,0,0), false, 2); //DEBUG_RECTS
- off.y += TS->shaped_text_get_ascent(rid) + l.text_buf->get_spacing_top();
+ off.y += TS->shaped_text_get_ascent(rid);
// Draw inlined objects.
Array objects = TS->shaped_text_get_objects(rid);
for (int i = 0; i < objects.size(); i++) {
@@ -1299,7 +1306,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
// Draw foreground color box
_draw_fbg_boxes(ci, rid, fbg_line_off, it_from, it_to, chr_range.x, chr_range.y, 1);
- off.y += TS->shaped_text_get_descent(rid) + l.text_buf->get_spacing_bottom();
+ off.y += TS->shaped_text_get_descent(rid);
}
return line_count;
@@ -1343,6 +1350,8 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
float RichTextLabel::_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, int *r_click_line, Item **r_click_item, int *r_click_char, bool p_table) {
Vector2 off;
+ bool line_clicked = false;
+ float text_rect_begin = 0.0;
int char_pos = -1;
Line &l = p_frame->lines[p_line];
MutexLock lock(l.text_buf->get_mutex());
@@ -1394,7 +1403,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
} break;
}
- off.y += TS->shaped_text_get_ascent(rid) + l.text_buf->get_spacing_top();
+ off.y += TS->shaped_text_get_ascent(rid);
Array objects = TS->shaped_text_get_objects(rid);
for (int i = 0; i < objects.size(); i++) {
@@ -1468,7 +1477,11 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
}
if (p_click.y >= rect.position.y && p_click.y <= rect.position.y + rect.size.y) {
- char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
+ if ((!rtl && p_click.x >= rect.position.x) || (rtl && p_click.x <= rect.position.x + rect.size.x)) {
+ char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
+ }
+ line_clicked = true;
+ text_rect_begin = rtl ? rect.position.x + rect.size.x : rect.position.x;
}
// If table hit was detected, and line hit is in the table bounds use table hit.
@@ -1491,27 +1504,42 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
return table_offy;
}
- off.y += TS->shaped_text_get_descent(rid) + l.text_buf->get_spacing_bottom() + get_theme_constant(SNAME("line_separation"));
+ off.y += TS->shaped_text_get_descent(rid) + get_theme_constant(SNAME("line_separation"));
}
// Text line hit.
- if (char_pos >= 0) {
+ if (line_clicked) {
// Find item.
if (r_click_item != nullptr) {
Item *it = p_frame->lines[p_line].from;
Item *it_to = (p_line + 1 < (int)p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr;
- if (char_pos == p_frame->lines[p_line].char_count) {
- // Selection after the end of line, select last item.
- if (it_to != nullptr) {
- *r_click_item = _get_prev_item(it_to);
- } else {
- for (Item *i = it; i; i = _get_next_item(i)) {
- *r_click_item = i;
+ if (char_pos >= 0) {
+ *r_click_item = _get_item_at_pos(it, it_to, char_pos);
+ } else {
+ int stop = text_rect_begin;
+ *r_click_item = _find_indentable(it);
+ while (*r_click_item) {
+ Ref<Font> font = _find_font(*r_click_item);
+ if (!font.is_valid()) {
+ font = get_theme_font(SNAME("normal_font"));
+ }
+ int font_size = _find_font_size(*r_click_item);
+ if (font_size == -1) {
+ font_size = get_theme_font_size(SNAME("normal_font_size"));
}
+ if (rtl) {
+ stop += tab_size * font->get_char_size(' ', font_size).width;
+ if (stop > p_click.x) {
+ break;
+ }
+ } else {
+ stop -= tab_size * font->get_char_size(' ', font_size).width;
+ if (stop < p_click.x) {
+ break;
+ }
+ }
+ *r_click_item = _find_indentable((*r_click_item)->parent);
}
- } else {
- // Selection in the line.
- *r_click_item = _get_item_at_pos(it, it_to, char_pos);
}
}
@@ -2068,6 +2096,19 @@ void RichTextLabel::_find_frame(Item *p_item, ItemFrame **r_frame, int *r_line)
}
}
+RichTextLabel::Item *RichTextLabel::_find_indentable(Item *p_item) {
+ Item *indentable = p_item;
+
+ while (indentable) {
+ if (indentable->type == ITEM_INDENT || indentable->type == ITEM_LIST) {
+ return indentable;
+ }
+ indentable = indentable->parent;
+ }
+
+ return indentable;
+}
+
Ref<Font> RichTextLabel::_find_font(Item *p_item) {
Item *fontitem = p_item;
@@ -2113,21 +2154,6 @@ int RichTextLabel::_find_outline_size(Item *p_item, int p_default) {
return p_default;
}
-Dictionary RichTextLabel::_find_font_features(Item *p_item) {
- Item *ffitem = p_item;
-
- while (ffitem) {
- if (ffitem->type == ITEM_FONT_FEATURES) {
- ItemFontFeatures *fi = static_cast<ItemFontFeatures *>(ffitem);
- return fi->opentype_features;
- }
-
- ffitem = ffitem->parent;
- }
-
- return Dictionary();
-}
-
RichTextLabel::ItemDropcap *RichTextLabel::_find_dc_item(Item *p_item) {
Item *item = p_item;
@@ -2204,7 +2230,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int
if (font_size == -1) {
font_size = p_base_font_size;
}
- margin += tab_size * font->get_char_size(' ', 0, font_size).width;
+ margin += tab_size * font->get_char_size(' ', font_size).width;
} else if (item->type == ITEM_LIST) {
Ref<Font> font = _find_font(item);
@@ -2215,7 +2241,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int
if (font_size == -1) {
font_size = p_base_font_size;
}
- margin += tab_size * font->get_char_size(' ', 0, font_size).width;
+ margin += tab_size * font->get_char_size(' ', font_size).width;
}
item = item->parent;
@@ -2584,8 +2610,8 @@ void RichTextLabel::_process_line_caches() {
MutexLock data_lock(data_mutex);
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"));
+ Ref<Font> base_font = get_theme_font(SNAME("normal_font"));
int ctrl_height = get_size().height;
int fi = main->first_invalid_line.load();
int total_chars = (fi == 0) ? 0 : (main->lines[fi].char_offset + main->lines[fi].char_count);
@@ -2950,25 +2976,14 @@ void RichTextLabel::push_font_size(int p_font_size) {
_add_item(item, true);
}
-void RichTextLabel::push_font_features(const Dictionary &p_features) {
- _stop_thread();
- MutexLock data_lock(data_mutex);
-
- ERR_FAIL_COND(current->type == ITEM_TABLE);
- ItemFontFeatures *item = memnew(ItemFontFeatures);
-
- item->opentype_features = p_features;
- _add_item(item, true);
-}
-
-void RichTextLabel::push_outline_size(int p_font_size) {
+void RichTextLabel::push_outline_size(int p_ol_size) {
_stop_thread();
MutexLock data_lock(data_mutex);
ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemOutlineSize *item = memnew(ItemOutlineSize);
- item->outline_size = p_font_size;
+ item->outline_size = p_ol_size;
_add_item(item, true);
}
@@ -3840,8 +3855,8 @@ void RichTextLabel::append_text(const String &p_bbcode) {
tag_stack.push_front("hint");
} else if (tag.begins_with("dropcap")) {
Vector<String> subtag = tag.substr(5, tag.length()).split(" ");
- Ref<Font> f = get_theme_font(SNAME("normal_font"));
int fs = get_theme_font_size(SNAME("normal_font_size")) * 3;
+ Ref<Font> f = get_theme_font(SNAME("normal_font"));
Color color = get_theme_color(SNAME("default_color"));
Color outline_color = get_theme_color(SNAME("outline_color"));
int outline_size = get_theme_constant(SNAME("outline_size"));
@@ -3974,64 +3989,127 @@ void RichTextLabel::append_text(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front("outline_color");
- } else if (tag.begins_with("font=")) {
- String fnt = tag.substr(5, tag.length());
-
- Ref<Font> font = ResourceLoader::load(fnt, "Font");
- if (font.is_valid()) {
- push_font(font);
- } else {
- push_font(normal_font);
- }
-
- pos = brk_end + 1;
- tag_stack.push_front("font");
} else if (tag.begins_with("font_size=")) {
int fnt_size = tag.substr(10, tag.length()).to_int();
push_font_size(fnt_size);
pos = brk_end + 1;
tag_stack.push_front("font_size");
+
} else if (tag.begins_with("opentype_features=")) {
String fnt_ftr = tag.substr(18, tag.length());
Vector<String> subtag = fnt_ftr.split(",");
- Dictionary ftrs;
- for (int i = 0; i < subtag.size(); i++) {
- Vector<String> subtag_a = subtag[i].split("=");
- if (subtag_a.size() == 2) {
- ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
- } else if (subtag_a.size() == 1) {
- ftrs[TS->name_to_tag(subtag_a[0])] = 1;
+ if (subtag.size() > 0) {
+ Ref<Font> font = _find_font(current);
+ if (font.is_null()) {
+ font = normal_font;
+ }
+ Ref<FontVariation> fc;
+ fc.instantiate();
+ fc->set_base_font(font);
+ Dictionary features;
+ for (int i = 0; i < subtag.size(); i++) {
+ Vector<String> subtag_a = subtag[i].split("=");
+ if (subtag_a.size() == 2) {
+ features[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
+ } else if (subtag_a.size() == 1) {
+ features[TS->name_to_tag(subtag_a[0])] = 1;
+ }
}
+ fc->set_opentype_features(features);
+ push_font(fc);
}
- push_font_features(ftrs);
pos = brk_end + 1;
tag_stack.push_front("opentype_features");
+
+ } else if (tag.begins_with("font=")) {
+ String fnt = tag.substr(5, tag.length());
+
+ Ref<Font> fc = ResourceLoader::load(fnt, "Font");
+ if (fc.is_valid()) {
+ push_font(fc);
+ }
+
+ pos = brk_end + 1;
+ tag_stack.push_front("font");
+
} else if (tag.begins_with("font ")) {
Vector<String> subtag = tag.substr(2, tag.length()).split(" ");
+ Ref<FontVariation> fc;
+ fc.instantiate();
for (int i = 1; i < subtag.size(); i++) {
Vector<String> subtag_a = subtag[i].split("=", true, 2);
if (subtag_a.size() == 2) {
if (subtag_a[0] == "name" || subtag_a[0] == "n") {
String fnt = subtag_a[1];
- Ref<Font> font = ResourceLoader::load(fnt, "Font");
- if (font.is_valid()) {
- push_font(font);
- } else {
- push_font(normal_font);
+ Ref<Font> font_data = ResourceLoader::load(fnt, "Font");
+ if (font_data.is_valid()) {
+ fc->set_base_font(font_data);
}
} else if (subtag_a[0] == "size" || subtag_a[0] == "s") {
int fnt_size = subtag_a[1].to_int();
- push_font_size(fnt_size);
+ if (fnt_size > 0) {
+ push_font_size(fnt_size);
+ }
+ } else if (subtag_a[0] == "glyph_spacing" || subtag_a[0] == "gl") {
+ int spacing = subtag_a[1].to_int();
+ fc->set_spacing(TextServer::SPACING_GLYPH, spacing);
+ } else if (subtag_a[0] == "space_spacing" || subtag_a[0] == "sp") {
+ int spacing = subtag_a[1].to_int();
+ fc->set_spacing(TextServer::SPACING_SPACE, spacing);
+ } else if (subtag_a[0] == "top_spacing" || subtag_a[0] == "top") {
+ int spacing = subtag_a[1].to_int();
+ fc->set_spacing(TextServer::SPACING_TOP, spacing);
+ } else if (subtag_a[0] == "bottom_spacing" || subtag_a[0] == "bt") {
+ int spacing = subtag_a[1].to_int();
+ fc->set_spacing(TextServer::SPACING_BOTTOM, spacing);
+ } else if (subtag_a[0] == "embolden" || subtag_a[0] == "emb") {
+ float emb = subtag_a[1].to_float();
+ fc->set_variation_embolden(emb);
+ } else if (subtag_a[0] == "face_index" || subtag_a[0] == "fi") {
+ int fi = subtag_a[1].to_int();
+ fc->set_variation_face_index(fi);
+ } else if (subtag_a[0] == "slant" || subtag_a[0] == "sln") {
+ float slant = subtag_a[1].to_float();
+ fc->set_variation_transform(Transform2D(1.0, slant, 0.0, 1.0, 0.0, 0.0));
+ } else if (subtag_a[0] == "opentype_variation" || subtag_a[0] == "otv") {
+ Dictionary variations;
+ if (!subtag_a[1].is_empty()) {
+ Vector<String> variation_tags = subtag_a[1].split(",");
+ for (int j = 0; j < variation_tags.size(); j++) {
+ Vector<String> subtag_b = variation_tags[j].split("=");
+ if (subtag_b.size() == 2) {
+ variations[TS->name_to_tag(subtag_b[0])] = subtag_b[1].to_float();
+ }
+ }
+ fc->set_variation_opentype(variations);
+ }
+ } else if (subtag_a[0] == "opentype_features" || subtag_a[0] == "otf") {
+ Dictionary features;
+ if (!subtag_a[1].is_empty()) {
+ Vector<String> feature_tags = subtag_a[1].split(",");
+ for (int j = 0; j < feature_tags.size(); j++) {
+ Vector<String> subtag_b = feature_tags[j].split("=");
+ if (subtag_b.size() == 2) {
+ features[TS->name_to_tag(subtag_b[0])] = subtag_b[1].to_float();
+ } else if (subtag_b.size() == 1) {
+ features[TS->name_to_tag(subtag_b[0])] = 1;
+ }
+ }
+ fc->set_opentype_features(features);
+ }
}
}
}
-
+ push_font(fc);
pos = brk_end + 1;
tag_stack.push_front("font");
+
} else if (tag.begins_with("outline_size=")) {
int fnt_size = tag.substr(13, tag.length()).to_int();
- push_outline_size(fnt_size);
+ if (fnt_size > 0) {
+ push_outline_size(fnt_size);
+ }
pos = brk_end + 1;
tag_stack.push_front("outline_size");
@@ -4854,7 +4932,6 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);
ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);
ClassDB::bind_method(D_METHOD("push_font_size", "font_size"), &RichTextLabel::push_font_size);
- ClassDB::bind_method(D_METHOD("push_font_features", "opentype_features"), &RichTextLabel::push_font_features);
ClassDB::bind_method(D_METHOD("push_normal"), &RichTextLabel::push_normal);
ClassDB::bind_method(D_METHOD("push_bold"), &RichTextLabel::push_bold);
ClassDB::bind_method(D_METHOD("push_bold_italics"), &RichTextLabel::push_bold_italics);
@@ -5018,11 +5095,9 @@ void RichTextLabel::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled");
- ADD_GROUP("Locale", "");
+ ADD_GROUP("BiDi", "");
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_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");
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index c697320976..c123f38c01 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -186,11 +186,6 @@ private:
ItemFontSize() { type = ITEM_FONT_SIZE; }
};
- struct ItemFontFeatures : public Item {
- Dictionary opentype_features;
- ItemFontFeatures() { type = ITEM_FONT_FEATURES; }
- };
-
struct ItemColor : public Item {
Color color;
ItemColor() { type = ITEM_COLOR; }
@@ -464,11 +459,11 @@ private:
String _roman(int p_num, bool p_capitalize) const;
String _letters(int p_num, bool p_capitalize) const;
+ Item *_find_indentable(Item *p_item);
Item *_get_item_at_pos(Item *p_item_from, Item *p_item_to, int p_position);
void _find_frame(Item *p_item, ItemFrame **r_frame, int *r_line);
- Ref<Font> _find_font(Item *p_item);
int _find_font_size(Item *p_item);
- Dictionary _find_font_features(Item *p_item);
+ Ref<Font> _find_font(Item *p_item);
int _find_outline_size(Item *p_item, int p_default);
ItemList *_find_list_item(Item *p_item);
ItemDropcap *_find_dc_item(Item *p_item);
@@ -525,7 +520,6 @@ public:
void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0));
void push_font(const Ref<Font> &p_font);
void push_font_size(int p_font_size);
- void push_font_features(const Dictionary &p_features);
void push_outline_size(int p_font_size);
void push_normal();
void push_bold();
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 5e548fa629..9efab27e3a 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -319,6 +319,7 @@ void ScrollContainer::_update_dimensions() {
fit_child_in_rect(c, r);
}
+ update_scrollbars();
update();
}
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 4b680f72cf..64c07007dc 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -96,15 +96,15 @@ void Slider::gui_input(const Ref<InputEvent> &p_event) {
if (grab.active) {
Size2i size = get_size();
Ref<Texture2D> grabber = get_theme_icon(SNAME("grabber"));
- float motion = (orientation == VERTICAL ? mm->get_position().y : mm->get_position().x) - grab.pos;
+ double motion = (orientation == VERTICAL ? mm->get_position().y : mm->get_position().x) - grab.pos;
if (orientation == VERTICAL) {
motion = -motion;
}
- float areasize = orientation == VERTICAL ? size.height - grabber->get_size().height : size.width - grabber->get_size().width;
+ double areasize = orientation == VERTICAL ? size.height - grabber->get_size().height : size.width - grabber->get_size().width;
if (areasize <= 0) {
return;
}
- float umotion = motion / float(areasize);
+ double umotion = motion / double(areasize);
set_as_ratio(grab.uvalue + umotion);
}
}
@@ -180,7 +180,7 @@ void Slider::_notification(int p_what) {
if (orientation == VERTICAL) {
int widget_width = style->get_minimum_size().width + style->get_center_size().width;
- float areasize = size.height - grabber->get_size().height;
+ double areasize = size.height - grabber->get_size().height;
style->draw(ci, Rect2i(Point2i(size.width / 2 - widget_width / 2, 0), Size2i(widget_width, size.height)));
grabber_area->draw(ci, Rect2i(Point2i((size.width - widget_width) / 2, size.height - areasize * ratio - grabber->get_size().height / 2), Size2i(widget_width, areasize * ratio + grabber->get_size().height / 2)));
@@ -197,7 +197,7 @@ void Slider::_notification(int p_what) {
grabber->draw(ci, Point2i(size.width / 2 - grabber->get_size().width / 2, size.height - ratio * areasize - grabber->get_size().height));
} else {
int widget_height = style->get_minimum_size().height + style->get_center_size().height;
- float areasize = size.width - grabber->get_size().width;
+ double areasize = size.width - grabber->get_size().width;
style->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(size.width, widget_height)));
grabber_area->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(areasize * ratio + grabber->get_size().width / 2, widget_height)));
@@ -218,11 +218,11 @@ void Slider::_notification(int p_what) {
}
}
-void Slider::set_custom_step(float p_custom_step) {
+void Slider::set_custom_step(double p_custom_step) {
custom_step = p_custom_step;
}
-float Slider::get_custom_step() const {
+double Slider::get_custom_step() const {
return custom_step;
}
diff --git a/scene/gui/slider.h b/scene/gui/slider.h
index 5fbfee2aec..5abaee27aa 100644
--- a/scene/gui/slider.h
+++ b/scene/gui/slider.h
@@ -38,14 +38,14 @@ class Slider : public Range {
struct Grab {
int pos = 0;
- float uvalue = 0.0;
+ double uvalue = 0.0;
bool active = false;
} grab;
int ticks = 0;
bool mouse_inside = false;
Orientation orientation;
- float custom_step = -1.0;
+ double custom_step = -1.0;
bool editable = true;
bool scrollable = true;
@@ -58,8 +58,8 @@ protected:
public:
virtual Size2 get_minimum_size() const override;
- void set_custom_step(float p_custom_step);
- float get_custom_step() const;
+ void set_custom_step(double p_custom_step);
+ double get_custom_step() const;
void set_ticks(int p_count);
int get_ticks() const;
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 890e349afb..a4733c455f 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -167,7 +167,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
if (drag.enabled) {
drag.diff_y += mm->get_relative().y;
- float diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8f) * SIGN(drag.diff_y);
+ double diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8) * SIGN(drag.diff_y);
set_value(CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max()));
} else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) {
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
@@ -319,7 +319,7 @@ SpinBox::SpinBox() {
line_edit = memnew(LineEdit);
add_child(line_edit, false, INTERNAL_MODE_FRONT);
- line_edit->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ line_edit->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
line_edit->set_mouse_filter(MOUSE_FILTER_PASS);
line_edit->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index d118b28334..1b1abbcf8e 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -56,11 +56,11 @@ class SpinBox : public Range {
void _line_edit_input(const Ref<InputEvent> &p_event);
struct Drag {
- float base_val = 0.0;
+ double base_val = 0.0;
bool allowed = false;
bool enabled = false;
Vector2 capture_pos;
- float diff_y = 0.0;
+ double diff_y = 0.0;
} drag;
void _line_edit_focus_exit();
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index b4c90596f9..d36a364677 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -311,7 +311,7 @@ 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[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].language);
}
void TabBar::_notification(int p_what) {
@@ -667,48 +667,6 @@ Control::TextDirection TabBar::get_tab_text_direction(int p_tab) const {
return tabs[p_tab].text_direction;
}
-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;
- }
- return tabs[p_tab].opentype_features[tag];
-}
-
void TabBar::set_tab_language(int p_tab, const String &p_language) {
ERR_FAIL_INDEX(p_tab, tabs.size());
@@ -1553,9 +1511,6 @@ void TabBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tab_title", "tab_idx"), &TabBar::get_tab_title);
ClassDB::bind_method(D_METHOD("set_tab_text_direction", "tab_idx", "direction"), &TabBar::set_tab_text_direction);
ClassDB::bind_method(D_METHOD("get_tab_text_direction", "tab_idx"), &TabBar::get_tab_text_direction);
- ClassDB::bind_method(D_METHOD("set_tab_opentype_feature", "tab_idx", "tag", "values"), &TabBar::set_tab_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_tab_opentype_feature", "tab_idx", "tag"), &TabBar::get_tab_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_tab_opentype_features", "tab_idx"), &TabBar::clear_tab_opentype_features);
ClassDB::bind_method(D_METHOD("set_tab_language", "tab_idx", "language"), &TabBar::set_tab_language);
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);
diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h
index 548a2e62af..d123385e47 100644
--- a/scene/gui/tab_bar.h
+++ b/scene/gui/tab_bar.h
@@ -57,7 +57,6 @@ private:
String text;
String xl_text;
- Dictionary opentype_features;
String language;
Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED;
@@ -137,10 +136,6 @@ public:
void set_tab_text_direction(int p_tab, TextDirection p_text_direction);
TextDirection get_tab_text_direction(int p_tab) const;
- void set_tab_opentype_feature(int p_tab, const String &p_name, int p_value);
- int get_tab_opentype_feature(int p_tab, const String &p_name) const;
- void clear_tab_opentype_features(int p_tab);
-
void set_tab_language(int p_tab, const String &p_language);
String get_tab_language(int p_tab) const;
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index fa929344d4..12f91a9873 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -233,7 +233,7 @@ void TabContainer::_repaint() {
if (i == current) {
c->show();
- c->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ c->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
if (tabs_visible) {
c->set_offset(SIDE_TOP, _get_top_margin());
@@ -312,7 +312,7 @@ Vector<Control *> TabContainer::_get_tab_controls() const {
Vector<Control *> controls;
for (int i = 0; i < get_child_count(); i++) {
Control *control = Object::cast_to<Control>(get_child(i));
- if (!control || control->is_set_as_top_level() || control == tab_bar) {
+ if (!control || control->is_set_as_top_level() || control == tab_bar || control == child_removing) {
continue;
}
@@ -549,7 +549,12 @@ void TabContainer::remove_child_notify(Node *p_child) {
return;
}
- tab_bar->remove_tab(get_tab_idx_from_control(c));
+ int idx = get_tab_idx_from_control(c);
+
+ // Before this, the tab control has not changed; after this, the tab control has changed.
+ child_removing = p_child;
+ tab_bar->remove_tab(idx);
+ child_removing = nullptr;
_update_margins();
if (get_tab_count() == 0) {
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index 9adaa0d844..60c8130939 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -46,6 +46,7 @@ class TabContainer : public Container {
bool drag_to_rearrange_enabled = false;
bool use_hidden_tabs_for_min_size = false;
bool theme_changing = false;
+ Node *child_removing = nullptr;
int _get_top_margin() const;
Vector<Control *> _get_tab_controls() const;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 5506616b7a..06553cd0f6 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -75,14 +75,6 @@ int TextEdit::Text::get_tab_size() const {
return tab_size;
}
-void TextEdit::Text::set_font_features(const Dictionary &p_features) {
- if (opentype_features.hash() == p_features.hash()) {
- return;
- }
- opentype_features = p_features;
- is_dirty = true;
-}
-
void TextEdit::Text::set_direction_and_language(TextServer::Direction p_direction, const String &p_language) {
if (direction == p_direction && language == p_language) {
return;
@@ -178,7 +170,7 @@ void TextEdit::Text::_calculate_max_line_width() {
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) {
+ if (font.is_null()) {
return; // Not in tree?
}
@@ -191,14 +183,14 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, bool p_text_chan
text.write[p_line].data_buf->set_preserve_control(draw_control_chars);
if (p_ime_text.length() > 0) {
if (p_text_changed) {
- text.write[p_line].data_buf->add_string(p_ime_text, font, font_size, opentype_features, language);
+ text.write[p_line].data_buf->add_string(p_ime_text, font, font_size, 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 {
if (p_text_changed) {
- text.write[p_line].data_buf->add_string(text[p_line].data, font, font_size, opentype_features, language);
+ text.write[p_line].data_buf->add_string(text[p_line].data, font, font_size, 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);
@@ -209,14 +201,17 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, bool p_text_chan
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);
+ TS->shaped_set_span_update_font(r, i, font->get_rids(), font_size, font->get_opentype_features());
+ }
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(r, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
}
}
// Apply tab align.
if (tab_size > 0) {
Vector<float> tabs;
- tabs.push_back(font->get_char_size(' ', 0, font_size).width * tab_size);
+ tabs.push_back(font->get_char_size(' ', font_size).width * tab_size);
text.write[p_line].data_buf->tab_align(tabs);
}
@@ -255,7 +250,7 @@ void TextEdit::Text::invalidate_all_lines() {
if (tab_size_dirty) {
if (tab_size > 0) {
Vector<float> tabs;
- tabs.push_back(font->get_char_size(' ', 0, font_size).width * tab_size);
+ tabs.push_back(font->get_char_size(' ', font_size).width * tab_size);
text.write[i].data_buf->tab_align(tabs);
}
// Tabs have changes, force width update.
@@ -277,7 +272,7 @@ void TextEdit::Text::invalidate_font() {
max_width = -1;
line_height = -1;
- if (!font.is_null() && font_size > 0) {
+ if (font.is_valid() && font_size > 0) {
font_height = font->get_height(font_size);
}
@@ -295,7 +290,7 @@ void TextEdit::Text::invalidate_all() {
max_width = -1;
line_height = -1;
- if (!font.is_null() && font_size > 0) {
+ if (font.is_valid() && font_size > 0) {
font_height = font->get_height(font_size);
}
@@ -973,7 +968,7 @@ void TextEdit::_notification(int p_what) {
// Give visual indication of empty selected line.
if (selection.active && line >= selection.from_line && line <= selection.to_line && char_margin >= xmargin_beg) {
- float char_w = font->get_char_size(' ', 0, font_size).width;
+ float char_w = font->get_char_size(' ', font_size).width;
if (rtl) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - xmargin_beg - ofs_x - char_w, ofs_y, char_w, row_height), selection_color);
} else {
@@ -1071,7 +1066,7 @@ void TextEdit::_notification(int p_what) {
// Draw line.
RID rid = ldata->get_line_rid(line_wrap_index);
- float text_height = TS->shaped_text_get_size(rid).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM);
+ float text_height = TS->shaped_text_get_size(rid).y;
if (rtl) {
char_margin = size.width - char_margin - TS->shaped_text_get_size(rid).x;
@@ -1222,7 +1217,7 @@ void TextEdit::_notification(int p_what) {
if (brace_open_mismatch) {
current_color = brace_mismatch_color;
}
- Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, font->get_underline_thickness(font_size));
+ Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1));
draw_rect(rect, current_color);
}
@@ -1231,7 +1226,7 @@ void TextEdit::_notification(int p_what) {
if (brace_close_mismatch) {
current_color = brace_mismatch_color;
}
- Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, font->get_underline_thickness(font_size));
+ Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1));
draw_rect(rect, current_color);
}
}
@@ -1355,7 +1350,7 @@ void TextEdit::_notification(int p_what) {
ts_caret.l_caret.size.y = caret_width;
}
if (ts_caret.l_caret.position.x >= TS->shaped_text_get_size(rid).x) {
- ts_caret.l_caret.size.x = font->get_char_size('m', 0, font_size).x;
+ ts_caret.l_caret.size.x = font->get_char_size('m', font_size).x;
} else {
ts_caret.l_caret.size.x = 3 * caret_width;
}
@@ -2573,7 +2568,7 @@ void TextEdit::_update_placeholder() {
placeholder_data_buf->set_width(text.get_width());
placeholder_data_buf->set_direction((TextServer::Direction)text_direction);
placeholder_data_buf->set_preserve_control(draw_control_chars);
- placeholder_data_buf->add_string(placeholder_text, font, font_size, opentype_features, language);
+ placeholder_data_buf->add_string(placeholder_text, font, font_size, language);
placeholder_bidi_override = structured_text_parser(st_parser, st_args, placeholder_text);
if (placeholder_bidi_override.is_empty()) {
@@ -2582,7 +2577,7 @@ void TextEdit::_update_placeholder() {
if (get_tab_size() > 0) {
Vector<float> tabs;
- tabs.push_back(font->get_char_size(' ', 0, font_size).width * get_tab_size());
+ tabs.push_back(font->get_char_size(' ', font_size).width * get_tab_size());
placeholder_data_buf->tab_align(tabs);
}
@@ -2653,7 +2648,6 @@ void TextEdit::_update_caches() {
dir = (TextServer::Direction)text_direction;
}
text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
- text.set_font_features(opentype_features);
text.set_draw_control_chars(draw_control_chars);
text.set_font(font);
text.set_font_size(font_size);
@@ -2668,7 +2662,11 @@ void TextEdit::_update_caches() {
/* General overrides. */
Size2 TextEdit::get_minimum_size() const {
- return style_normal->get_minimum_size();
+ Size2 size = style_normal->get_minimum_size();
+ if (fit_content_height) {
+ size.y += content_height_cache;
+ }
+ return size;
}
bool TextEdit::is_text_field() const {
@@ -2854,33 +2852,6 @@ Control::TextDirection TextEdit::get_text_direction() const {
return text_direction;
}
-void TextEdit::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;
- text.set_font_features(opentype_features);
- text.invalidate_font();
- _update_placeholder();
- update();
- }
-}
-
-int TextEdit::get_opentype_feature(const String &p_name) const {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag)) {
- return -1;
- }
- return opentype_features[tag];
-}
-
-void TextEdit::clear_opentype_features() {
- opentype_features.clear();
- text.set_font_features(opentype_features);
- text.invalidate_font();
- _update_placeholder();
- update();
-}
-
void TextEdit::set_language(const String &p_language) {
if (language != p_language) {
language = p_language;
@@ -4499,6 +4470,18 @@ float TextEdit::get_v_scroll_speed() const {
return v_scroll_speed;
}
+void TextEdit::set_fit_content_height_enabled(const bool p_enabled) {
+ if (fit_content_height == p_enabled) {
+ return;
+ }
+ fit_content_height = p_enabled;
+ update_minimum_size();
+}
+
+bool TextEdit::is_fit_content_height_enabled() const {
+ return fit_content_height;
+}
+
double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const {
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
ERR_FAIL_COND_V(p_wrap_index < 0, 0);
@@ -5055,10 +5038,6 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &TextEdit::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &TextEdit::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &TextEdit::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &TextEdit::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features"), &TextEdit::clear_opentype_features);
-
ClassDB::bind_method(D_METHOD("set_language", "language"), &TextEdit::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &TextEdit::get_language);
@@ -5091,6 +5070,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_text", "text"), &TextEdit::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &TextEdit::get_text);
+
ClassDB::bind_method(D_METHOD("get_line_count"), &TextEdit::get_line_count);
ClassDB::bind_method(D_METHOD("set_placeholder", "text"), &TextEdit::set_placeholder);
@@ -5297,7 +5277,7 @@ void TextEdit::_bind_methods() {
/* Viewport. */
// Scrolling.
- ClassDB::bind_method(D_METHOD("set_smooth_scroll_enable", "enable"), &TextEdit::set_smooth_scroll_enabled);
+ ClassDB::bind_method(D_METHOD("set_smooth_scroll_enabled", "enable"), &TextEdit::set_smooth_scroll_enabled);
ClassDB::bind_method(D_METHOD("is_smooth_scroll_enabled"), &TextEdit::is_smooth_scroll_enabled);
ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &TextEdit::set_v_scroll);
@@ -5312,6 +5292,9 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_v_scroll_speed", "speed"), &TextEdit::set_v_scroll_speed);
ClassDB::bind_method(D_METHOD("get_v_scroll_speed"), &TextEdit::get_v_scroll_speed);
+ ClassDB::bind_method(D_METHOD("set_fit_content_height_enabled"), &TextEdit::set_fit_content_height_enabled);
+ ClassDB::bind_method(D_METHOD("is_fit_content_height_enabled"), &TextEdit::is_fit_content_height_enabled);
+
ClassDB::bind_method(D_METHOD("get_scroll_pos_for_line", "line", "wrap_index"), &TextEdit::get_scroll_pos_for_line, DEFVAL(0));
// Visible lines.
@@ -5408,8 +5391,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::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::BOOL, "editable"), "set_editable", "is_editable");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
@@ -5431,11 +5412,12 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "syntax_highlighter", PROPERTY_HINT_RESOURCE_TYPE, "SyntaxHighlighter", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_syntax_highlighter", "get_syntax_highlighter");
ADD_GROUP("Scroll", "scroll_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_smooth"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_smooth"), "set_smooth_scroll_enabled", "is_smooth_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scroll_v_scroll_speed", PROPERTY_HINT_NONE, "suffix:px/s"), "set_v_scroll_speed", "get_v_scroll_speed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_past_end_of_file"), "set_scroll_past_end_of_file_enabled", "is_scroll_past_end_of_file_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scroll_vertical", PROPERTY_HINT_NONE, "suffix:px"), "set_v_scroll", "get_v_scroll");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal", PROPERTY_HINT_NONE, "suffix:px"), "set_h_scroll", "get_h_scroll");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_fit_content_height"), "set_fit_content_height_enabled", "is_fit_content_height_enabled");
ADD_GROUP("Minimap", "minimap_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "minimap_draw"), "set_draw_minimap", "is_drawing_minimap");
@@ -5448,7 +5430,9 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_move_on_right_click"), "set_move_caret_on_right_click_enabled", "is_move_caret_on_right_click_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled");
- ADD_GROUP("Structured Text", "structured_text_");
+ ADD_GROUP("BiDi", "");
+ 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, "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");
@@ -5473,60 +5457,6 @@ void TextEdit::_bind_methods() {
ProjectSettings::get_singleton()->set_custom_property_info("gui/common/text_edit_undo_stack_max_size", PropertyInfo(Variant::INT, "gui/common/text_edit_undo_stack_max_size", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); // No negative numbers.
}
-bool TextEdit::_set(const StringName &p_name, const Variant &p_value) {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- int value = p_value;
- if (value == -1) {
- if (opentype_features.has(tag)) {
- opentype_features.erase(tag);
- text.set_font_features(opentype_features);
- text.invalidate_font();
- _update_placeholder();
- update();
- }
- } else {
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
- opentype_features[tag] = value;
- text.set_font_features(opentype_features);
- text.invalidate_font();
- _update_placeholder();
- update();
- }
- }
- notify_property_list_changed();
- return true;
- }
-
- return false;
-}
-
-bool TextEdit::_get(const StringName &p_name, Variant &r_ret) const {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- if (opentype_features.has(tag)) {
- r_ret = opentype_features[tag];
- return true;
- } else {
- r_ret = -1;
- return true;
- }
- }
- return false;
-}
-
-void TextEdit::_get_property_list(List<PropertyInfo> *p_list) const {
- for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
- String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
- }
- p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
-}
-
/* Internal API for CodeEdit. */
// Line hiding.
void TextEdit::_set_hiding_enabled(bool p_enabled) {
@@ -6197,6 +6127,11 @@ void TextEdit::_update_scrollbars() {
total_width += minimap_width;
}
+ content_height_cache = MAX(total_rows, 1) * get_line_height();
+ if (fit_content_height) {
+ update_minimum_size();
+ }
+
updating_scrolls = true;
if (total_rows > visible_rows) {
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 9de2982d0a..6711cf8c7f 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -160,7 +160,6 @@ private:
int font_size = -1;
int font_height = 0;
- Dictionary opentype_features;
String language;
TextServer::Direction direction = TextServer::DIRECTION_AUTO;
bool draw_control_chars = false;
@@ -180,7 +179,6 @@ private:
int get_tab_size() const;
void set_font(const Ref<Font> &p_font);
void set_font_size(int p_font_size);
- void set_font_features(const Dictionary &p_features);
void set_direction_and_language(TextServer::Direction p_direction, const String &p_language);
void set_draw_control_chars(bool p_enabled);
@@ -271,7 +269,6 @@ private:
TextDirection text_direction = TEXT_DIRECTION_AUTO;
TextDirection input_direction = TEXT_DIRECTION_LTR;
- Dictionary opentype_features;
String language = "";
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
@@ -456,6 +453,8 @@ private:
HScrollBar *h_scroll = nullptr;
VScrollBar *v_scroll = nullptr;
+ float content_height_cache = 0.0;
+ bool fit_content_height = false;
bool scroll_past_end_of_file_enabled = false;
// Smooth scrolling.
@@ -579,10 +578,6 @@ protected:
static void _bind_methods();
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
-
/* Internal API for CodeEdit, pending public API. */
// brace matching
bool highlight_matching_braces_enabled = false;
@@ -648,10 +643,6 @@ public:
void set_text_direction(TextDirection p_text_direction);
TextDirection get_text_direction() const;
- void set_opentype_feature(const String &p_name, int p_value);
- int get_opentype_feature(const String &p_name) const;
- void clear_opentype_features();
-
void set_language(const String &p_language);
String get_language() const;
@@ -684,6 +675,7 @@ public:
void set_text(const String &p_text);
String get_text() const;
+
int get_line_count() const;
void set_placeholder(const String &p_text);
@@ -851,6 +843,9 @@ public:
void set_v_scroll_speed(float p_speed);
float get_v_scroll_speed() const;
+ void set_fit_content_height_enabled(const bool p_enabled);
+ bool is_fit_content_height_enabled() const;
+
double get_scroll_pos_for_line(int p_line, int p_wrap_index = 0) const;
// Visible lines.
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index d3e7540790..2c4cba4954 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -303,37 +303,6 @@ Control::TextDirection TreeItem::get_text_direction(int p_column) const {
return cells[p_column].text_direction;
}
-void TreeItem::clear_opentype_features(int p_column) {
- ERR_FAIL_INDEX(p_column, cells.size());
-
- cells.write[p_column].opentype_features.clear();
- cells.write[p_column].dirty = true;
- cells.write[p_column].cached_minimum_size_dirty = true;
-
- _changed_notify(p_column);
-}
-
-void TreeItem::set_opentype_feature(int p_column, const String &p_name, int p_value) {
- ERR_FAIL_INDEX(p_column, cells.size());
- int32_t tag = TS->name_to_tag(p_name);
- if (!cells[p_column].opentype_features.has(tag) || (int)cells[p_column].opentype_features[tag] != p_value) {
- cells.write[p_column].opentype_features[tag] = p_value;
- cells.write[p_column].dirty = true;
- cells.write[p_column].cached_minimum_size_dirty = true;
-
- _changed_notify(p_column);
- }
-}
-
-int TreeItem::get_opentype_feature(int p_column, const String &p_name) const {
- ERR_FAIL_INDEX_V(p_column, cells.size(), -1);
- int32_t tag = TS->name_to_tag(p_name);
- if (!cells[p_column].opentype_features.has(tag)) {
- return -1;
- }
- return cells[p_column].opentype_features[tag];
-}
-
void TreeItem::set_structured_text_bidi_override(int p_column, TextServer::StructuredTextParser p_parser) {
ERR_FAIL_INDEX(p_column, cells.size());
@@ -1269,10 +1238,6 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_text_direction", "column", "direction"), &TreeItem::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction", "column"), &TreeItem::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "column", "tag", "value"), &TreeItem::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "column", "tag"), &TreeItem::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features", "column"), &TreeItem::clear_opentype_features);
-
ClassDB::bind_method(D_METHOD("set_structured_text_bidi_override", "column", "parser"), &TreeItem::set_structured_text_bidi_override);
ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override", "column"), &TreeItem::get_structured_text_bidi_override);
@@ -1667,7 +1632,7 @@ void Tree::update_column(int p_col) {
columns.write[p_col].text_buf->set_direction((TextServer::Direction)columns[p_col].text_direction);
}
- columns.write[p_col].text_buf->add_string(columns[p_col].title, cache.font, cache.font_size, columns[p_col].opentype_features, !columns[p_col].language.is_empty() ? columns[p_col].language : TranslationServer::get_singleton()->get_tool_locale());
+ columns.write[p_col].text_buf->add_string(columns[p_col].title, cache.font, cache.font_size, columns[p_col].language);
}
void Tree::update_item_cell(TreeItem *p_item, int p_col) {
@@ -1725,7 +1690,7 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) {
} else {
font_size = cache.font_size;
}
- p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].opentype_features, !p_item->cells[p_col].language.is_empty() ? p_item->cells[p_col].language : TranslationServer::get_singleton()->get_tool_locale());
+ p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].language);
TS->shaped_text_set_bidi_override(p_item->cells[p_col].text_buf->get_rid(), structured_text_parser(p_item->cells[p_col].st_parser, p_item->cells[p_col].st_args, valtext));
p_item->cells.write[p_col].dirty = false;
}
@@ -2850,6 +2815,9 @@ void Tree::value_editor_changed(double p_value) {
TreeItem::Cell &c = popup_edited_item->cells.write[popup_edited_item_col];
c.val = p_value;
+
+ text_editor->set_text(String::num(c.val, Math::range_step_decimals(c.step)));
+
item_edited(popup_edited_item_col, popup_edited_item);
update();
}
@@ -3002,6 +2970,15 @@ void Tree::_go_down() {
accept_event();
}
+bool Tree::_scroll(bool p_horizontal, float p_pages) {
+ ScrollBar *scroll = p_horizontal ? (ScrollBar *)h_scroll : (ScrollBar *)v_scroll;
+
+ double prev_value = scroll->get_value();
+ scroll->set_value(scroll->get_value() + scroll->get_page() * p_pages);
+
+ return scroll->get_value() != prev_value;
+}
+
void Tree::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
@@ -3516,17 +3493,25 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) {
} break;
case MouseButton::WHEEL_UP: {
- double prev_value = v_scroll->get_value();
- v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * mb->get_factor() / 8);
- if (v_scroll->get_value() != prev_value) {
+ if (_scroll(false, -mb->get_factor() / 8)) {
accept_event();
}
} break;
case MouseButton::WHEEL_DOWN: {
- double prev_value = v_scroll->get_value();
- v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * mb->get_factor() / 8);
- if (v_scroll->get_value() != prev_value) {
+ if (_scroll(false, mb->get_factor() / 8)) {
+ accept_event();
+ }
+
+ } break;
+ case MouseButton::WHEEL_LEFT: {
+ if (_scroll(true, -mb->get_factor() / 8)) {
+ accept_event();
+ }
+
+ } break;
+ case MouseButton::WHEEL_RIGHT: {
+ if (_scroll(true, mb->get_factor() / 8)) {
accept_event();
}
@@ -4192,7 +4177,7 @@ int Tree::get_column_minimum_width(int p_column) const {
// Check if the visible title of the column is wider.
if (show_column_titles) {
- min_width = MAX(cache.font->get_string_size(columns[p_column].title, cache.font_size).width + cache.bg->get_margin(SIDE_LEFT) + cache.bg->get_margin(SIDE_RIGHT), min_width);
+ min_width = MAX(cache.font->get_string_size(columns[p_column].title, HORIZONTAL_ALIGNMENT_LEFT, -1, cache.font_size).width + cache.bg->get_margin(SIDE_LEFT) + cache.bg->get_margin(SIDE_RIGHT), min_width);
}
if (!columns[p_column].clip_content) {
@@ -4471,32 +4456,6 @@ Control::TextDirection Tree::get_column_title_direction(int p_column) const {
return columns[p_column].text_direction;
}
-void Tree::clear_column_title_opentype_features(int p_column) {
- ERR_FAIL_INDEX(p_column, columns.size());
- columns.write[p_column].opentype_features.clear();
- update_column(p_column);
- update();
-}
-
-void Tree::set_column_title_opentype_feature(int p_column, const String &p_name, int p_value) {
- ERR_FAIL_INDEX(p_column, columns.size());
- int32_t tag = TS->name_to_tag(p_name);
- if (!columns[p_column].opentype_features.has(tag) || (int)columns[p_column].opentype_features[tag] != p_value) {
- columns.write[p_column].opentype_features[tag] = p_value;
- update_column(p_column);
- update();
- }
-}
-
-int Tree::get_column_title_opentype_feature(int p_column, const String &p_name) const {
- ERR_FAIL_INDEX_V(p_column, columns.size(), -1);
- int32_t tag = TS->name_to_tag(p_name);
- if (!columns[p_column].opentype_features.has(tag)) {
- return -1;
- }
- return columns[p_column].opentype_features[tag];
-}
-
void Tree::set_column_title_language(int p_column, const String &p_language) {
ERR_FAIL_INDEX(p_column, columns.size());
if (columns[p_column].language != p_language) {
@@ -4983,10 +4942,6 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_column_title_direction", "column", "direction"), &Tree::set_column_title_direction);
ClassDB::bind_method(D_METHOD("get_column_title_direction", "column"), &Tree::get_column_title_direction);
- ClassDB::bind_method(D_METHOD("set_column_title_opentype_feature", "column", "tag", "value"), &Tree::set_column_title_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_column_title_opentype_feature", "column", "tag"), &Tree::get_column_title_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_column_title_opentype_features", "column"), &Tree::clear_column_title_opentype_features);
-
ClassDB::bind_method(D_METHOD("set_column_title_language", "column", "language"), &Tree::set_column_title_language);
ClassDB::bind_method(D_METHOD("get_column_title_language", "column"), &Tree::get_column_title_language);
@@ -5063,7 +5018,7 @@ Tree::Tree() {
popup_editor_vb = memnew(VBoxContainer);
popup_editor->add_child(popup_editor_vb);
popup_editor_vb->add_theme_constant_override("separation", 0);
- popup_editor_vb->set_anchors_and_offsets_preset(PRESET_WIDE);
+ popup_editor_vb->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
text_editor = memnew(LineEdit);
popup_editor_vb->add_child(text_editor);
text_editor->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 0a8dd3204a..1690e7ac57 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -63,7 +63,6 @@ private:
String text;
String suffix;
Ref<TextLine> text_buf;
- Dictionary opentype_features;
String language;
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
Array st_args;
@@ -220,10 +219,6 @@ public:
void set_text_direction(int p_column, Control::TextDirection p_text_direction);
Control::TextDirection get_text_direction(int p_column) const;
- void set_opentype_feature(int p_column, const String &p_name, int p_value);
- int get_opentype_feature(int p_column, const String &p_name) const;
- void clear_opentype_features(int p_column);
-
void set_structured_text_bidi_override(int p_column, TextServer::StructuredTextParser p_parser);
TextServer::StructuredTextParser get_structured_text_bidi_override(int p_column) const;
@@ -429,7 +424,6 @@ private:
bool clip_content = false;
String title;
Ref<TextLine> text_buf;
- Dictionary opentype_features;
String language;
Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED;
ColumnInfo() {
@@ -616,6 +610,8 @@ private:
void _go_down();
void _go_up();
+ bool _scroll(bool p_horizontal, float p_pages);
+
protected:
static void _bind_methods();
@@ -666,10 +662,6 @@ public:
void set_column_title_direction(int p_column, Control::TextDirection p_text_direction);
Control::TextDirection get_column_title_direction(int p_column) const;
- void set_column_title_opentype_feature(int p_column, const String &p_name, int p_value);
- int get_column_title_opentype_feature(int p_column, const String &p_name) const;
- void clear_column_title_opentype_features(int p_column);
-
void set_column_title_language(int p_column, const String &p_language);
String get_column_title_language(int p_column) const;
diff --git a/scene/gui/video_stream_player.h b/scene/gui/video_stream_player.h
index d2822a989b..913e7905b6 100644
--- a/scene/gui/video_stream_player.h
+++ b/scene/gui/video_stream_player.h
@@ -64,7 +64,7 @@ class VideoStreamPlayer : public Control {
bool autoplay = false;
float volume = 1.0;
double last_audio_time = 0.0;
- bool expand = true;
+ bool expand = false;
bool loops = false;
int buffering_ms = 500;
int audio_track = 0;
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 3dc358a6c2..e298805aca 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -230,16 +230,16 @@ void CanvasItem::_enter_canvas() {
RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, canvas);
- group = "root_canvas" + itos(canvas.get_id());
+ canvas_group = "root_canvas" + itos(canvas.get_id());
- add_to_group(group);
+ add_to_group(canvas_group);
if (canvas_layer) {
canvas_layer->reset_sort_index();
} else {
get_viewport()->gui_reset_canvas_sort_index();
}
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, group, SNAME("_top_level_raise_self"));
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, SNAME("_top_level_raise_self"));
} else {
CanvasItem *parent = get_parent_item();
@@ -258,7 +258,10 @@ void CanvasItem::_exit_canvas() {
notification(NOTIFICATION_EXIT_CANVAS, true); //reverse the notification
RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, RID());
canvas_layer = nullptr;
- group = StringName();
+ if (canvas_group != StringName()) {
+ remove_from_group(canvas_group);
+ canvas_group = StringName();
+ }
}
void CanvasItem::_notification(int p_what) {
@@ -319,8 +322,8 @@ void CanvasItem::_notification(int p_what) {
break;
}
- if (group != StringName()) {
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, group, "_top_level_raise_self");
+ if (canvas_group != StringName()) {
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, "_top_level_raise_self");
} else {
CanvasItem *p = get_parent_item();
ERR_FAIL_COND(!p);
@@ -658,24 +661,48 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex
RenderingServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid);
}
-void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
+void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
+ ERR_FAIL_COND(p_font.is_null());
+
+ p_font->draw_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_modulate, p_jst_flags, p_direction, p_orientation);
+}
+
+void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
+ ERR_FAIL_COND(p_font.is_null());
+
+ p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation);
+}
+
+void CanvasItem::draw_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
+ ERR_FAIL_COND(p_font.is_null());
+
+ p_font->draw_string_outline(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_size, p_modulate, p_jst_flags, p_direction, p_orientation);
+}
+
+void CanvasItem::draw_multiline_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
- p_font->draw_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
+
+ p_font->draw_multiline_string_outline(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_size, p_modulate, p_brk_flags, p_jst_flags, p_direction, p_orientation);
}
-void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
+void CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, const Color &p_modulate) const {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
+ ERR_FAIL_COND(p_char.length() != 1);
ERR_FAIL_COND(p_font.is_null());
- p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
+
+ p_font->draw_char(canvas_item, p_pos, p_char[0], p_font_size, p_modulate);
}
-real_t CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate) const {
- ERR_FAIL_COND_V_MSG(!drawing, 0.f, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL_COND_V(p_font.is_null(), 0.f);
- ERR_FAIL_COND_V(p_char.length() != 1, 0.f);
+void CanvasItem::draw_char_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, int p_size, const Color &p_modulate) const {
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
+ ERR_FAIL_COND(p_char.length() != 1);
+ ERR_FAIL_COND(p_font.is_null());
- return p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.get_data()[0], p_size, p_modulate, p_outline_size, p_outline_modulate);
+ p_font->draw_char_outline(canvas_item, p_pos, p_char[0], p_font_size, p_size, p_modulate);
}
void CanvasItem::_notify_transform(CanvasItem *p_node) {
@@ -900,9 +927,12 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width"), &CanvasItem::draw_primitive, DEFVAL(Ref<Texture2D>()), DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture"), &CanvasItem::draw_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()));
- ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
- ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
- ClassDB::bind_method(D_METHOD("draw_char", "font", "pos", "char", "next", "size", "modulate", "outline_size", "outline_modulate"), &CanvasItem::draw_char, DEFVAL(""), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)));
+ ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "font_size", "modulate", "jst_flags", "direction", "orientation"), &CanvasItem::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
+ ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "brk_flags", "jst_flags", "direction", "orientation"), &CanvasItem::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
+ ClassDB::bind_method(D_METHOD("draw_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "jst_flags", "direction", "orientation"), &CanvasItem::draw_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
+ ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "jst_flags", "direction", "orientation"), &CanvasItem::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
+ ClassDB::bind_method(D_METHOD("draw_char", "font", "pos", "char", "font_size", "modulate"), &CanvasItem::draw_char, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)));
+ ClassDB::bind_method(D_METHOD("draw_char_outline", "font", "pos", "char", "font_size", "size", "modulate"), &CanvasItem::draw_char_outline, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture"), &CanvasItem::draw_multimesh);
ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform, DEFVAL(0.0), DEFVAL(Size2(1.0, 1.0)));
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index ad64f1ab5e..f5df6512ee 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -70,7 +70,7 @@ private:
mutable SelfList<Node> xform_change;
RID canvas_item;
- StringName group;
+ StringName canvas_group;
CanvasLayer *canvas_layer = nullptr;
@@ -235,9 +235,14 @@ public:
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1));
void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture);
- void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
- void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
- real_t draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const;
+ void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+ void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+
+ void draw_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_size = 1, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+ void draw_multiline_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+
+ void draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
+ void draw_char_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));
void draw_set_transform_matrix(const Transform2D &p_matrix);
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 545ff68b72..b4701637a4 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -439,9 +439,9 @@ void Node::set_physics_process(bool p_process) {
data.physics_process = p_process;
if (data.physics_process) {
- add_to_group("physics_process", false);
+ add_to_group(SNAME("_physics_process"), false);
} else {
- remove_from_group("physics_process");
+ remove_from_group(SNAME("_physics_process"));
}
}
@@ -457,9 +457,9 @@ void Node::set_physics_process_internal(bool p_process_internal) {
data.physics_process_internal = p_process_internal;
if (data.physics_process_internal) {
- add_to_group("physics_process_internal", false);
+ add_to_group(SNAME("_physics_process_internal"), false);
} else {
- remove_from_group("physics_process_internal");
+ remove_from_group(SNAME("_physics_process_internal"));
}
}
@@ -770,9 +770,9 @@ void Node::set_process(bool p_process) {
data.process = p_process;
if (data.process) {
- add_to_group("process", false);
+ add_to_group(SNAME("_process"), false);
} else {
- remove_from_group("process");
+ remove_from_group(SNAME("_process"));
}
}
@@ -788,9 +788,9 @@ void Node::set_process_internal(bool p_process_internal) {
data.process_internal = p_process_internal;
if (data.process_internal) {
- add_to_group("process_internal", false);
+ add_to_group(SNAME("_process_internal"), false);
} else {
- remove_from_group("process_internal");
+ remove_from_group(SNAME("_process_internal"));
}
}
@@ -807,19 +807,19 @@ void Node::set_process_priority(int p_priority) {
}
if (is_processing()) {
- data.tree->make_group_changed("process");
+ data.tree->make_group_changed(SNAME("_process"));
}
if (is_processing_internal()) {
- data.tree->make_group_changed("process_internal");
+ data.tree->make_group_changed(SNAME("_process_internal"));
}
if (is_physics_processing()) {
- data.tree->make_group_changed("physics_process");
+ data.tree->make_group_changed(SNAME("_physics_process"));
}
if (is_physics_processing_internal()) {
- data.tree->make_group_changed("physics_process_internal");
+ data.tree->make_group_changed(SNAME("_physics_process_internal"));
}
}
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index dd77877c7d..66482f65dc 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -34,6 +34,7 @@
#include "core/debugger/engine_debugger.h"
#include "core/input/input.h"
#include "core/io/dir_access.h"
+#include "core/io/image_loader.h"
#include "core/io/marshalls.h"
#include "core/io/resource_loader.h"
#include "core/multiplayer/multiplayer_api.h"
@@ -412,9 +413,9 @@ bool SceneTree::physics_process(double p_time) {
emit_signal(SNAME("physics_frame"));
- _notify_group_pause(SNAME("physics_process_internal"), Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
+ _notify_group_pause(SNAME("_physics_process_internal"), Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
call_group(SNAME("_picking_viewports"), SNAME("_process_picking"));
- _notify_group_pause(SNAME("physics_process"), Node::NOTIFICATION_PHYSICS_PROCESS);
+ _notify_group_pause(SNAME("_physics_process"), Node::NOTIFICATION_PHYSICS_PROCESS);
_flush_ugc();
MessageQueue::get_singleton()->flush(); //small little hack
@@ -449,8 +450,8 @@ bool SceneTree::process(double p_time) {
flush_transform_notifications();
- _notify_group_pause(SNAME("process_internal"), Node::NOTIFICATION_INTERNAL_PROCESS);
- _notify_group_pause(SNAME("process"), Node::NOTIFICATION_PROCESS);
+ _notify_group_pause(SNAME("_process_internal"), Node::NOTIFICATION_INTERNAL_PROCESS);
+ _notify_group_pause(SNAME("_process"), Node::NOTIFICATION_PROCESS);
_flush_ugc();
MessageQueue::get_singleton()->flush(); //small little hack
@@ -659,6 +660,14 @@ bool SceneTree::is_debugging_collisions_hint() const {
return debug_collisions_hint;
}
+void SceneTree::set_debug_paths_hint(bool p_enabled) {
+ debug_paths_hint = p_enabled;
+}
+
+bool SceneTree::is_debugging_paths_hint() const {
+ return debug_paths_hint;
+}
+
void SceneTree::set_debug_navigation_hint(bool p_enabled) {
debug_navigation_hint = p_enabled;
}
@@ -684,6 +693,22 @@ Color SceneTree::get_debug_collision_contact_color() const {
return debug_collision_contact_color;
}
+void SceneTree::set_debug_paths_color(const Color &p_color) {
+ debug_paths_color = p_color;
+}
+
+Color SceneTree::get_debug_paths_color() const {
+ return debug_paths_color;
+}
+
+void SceneTree::set_debug_paths_width(float p_width) {
+ debug_paths_width = p_width;
+}
+
+float SceneTree::get_debug_paths_width() const {
+ return debug_paths_width;
+}
+
void SceneTree::set_debug_navigation_color(const Color &p_color) {
debug_navigation_color = p_color;
}
@@ -700,6 +725,23 @@ Color SceneTree::get_debug_navigation_disabled_color() const {
return debug_navigation_disabled_color;
}
+Ref<Material> SceneTree::get_debug_paths_material() {
+ if (debug_paths_material.is_valid()) {
+ return debug_paths_material;
+ }
+
+ Ref<StandardMaterial3D> _debug_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+ _debug_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ _debug_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
+ _debug_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
+ _debug_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ _debug_material->set_albedo(get_debug_paths_color());
+
+ debug_paths_material = _debug_material;
+
+ return debug_paths_material;
+}
+
Ref<Material> SceneTree::get_debug_navigation_material() {
if (navigation_material.is_valid()) {
return navigation_material;
@@ -1207,6 +1249,8 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_debug_collisions_hint", "enable"), &SceneTree::set_debug_collisions_hint);
ClassDB::bind_method(D_METHOD("is_debugging_collisions_hint"), &SceneTree::is_debugging_collisions_hint);
+ ClassDB::bind_method(D_METHOD("set_debug_paths_hint", "enable"), &SceneTree::set_debug_paths_hint);
+ ClassDB::bind_method(D_METHOD("is_debugging_paths_hint"), &SceneTree::is_debugging_paths_hint);
ClassDB::bind_method(D_METHOD("set_debug_navigation_hint", "enable"), &SceneTree::set_debug_navigation_hint);
ClassDB::bind_method(D_METHOD("is_debugging_navigation_hint"), &SceneTree::is_debugging_navigation_hint);
@@ -1268,6 +1312,7 @@ void SceneTree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_accept_quit"), "set_auto_accept_quit", "is_auto_accept_quit");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "quit_on_go_back"), "set_quit_on_go_back", "is_quit_on_go_back");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_collisions_hint"), "set_debug_collisions_hint", "is_debugging_collisions_hint");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_paths_hint"), "set_debug_paths_hint", "is_debugging_paths_hint");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_navigation_hint"), "set_debug_navigation_hint", "is_debugging_navigation_hint");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "paused"), "set_pause", "is_paused");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "edited_scene_root", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_edited_scene_root", "get_edited_scene_root");
@@ -1344,6 +1389,8 @@ SceneTree::SceneTree() {
}
debug_collisions_color = GLOBAL_DEF("debug/shapes/collision/shape_color", Color(0.0, 0.6, 0.7, 0.42));
debug_collision_contact_color = GLOBAL_DEF("debug/shapes/collision/contact_color", Color(1.0, 0.2, 0.1, 0.8));
+ debug_paths_color = GLOBAL_DEF("debug/shapes/paths/geometry_color", Color(0.1, 1.0, 0.7, 0.4));
+ debug_paths_width = GLOBAL_DEF("debug/shapes/paths/geometry_width", 2.0);
debug_navigation_color = GLOBAL_DEF("debug/shapes/navigation/geometry_color", Color(0.1, 1.0, 0.7, 0.4));
debug_navigation_disabled_color = GLOBAL_DEF("debug/shapes/navigation/disabled_geometry_color", Color(1.0, 0.7, 0.1, 0.4));
collision_debug_contacts = GLOBAL_DEF("debug/shapes/collision/max_contacts_displayed", 10000);
@@ -1400,25 +1447,48 @@ SceneTree::SceneTree() {
bool snap_2d_vertices = GLOBAL_DEF("rendering/2d/snap/snap_2d_vertices_to_pixel", false);
root->set_snap_2d_vertices_to_pixel(snap_2d_vertices);
- int shadowmap_size = GLOBAL_DEF("rendering/shadows/shadow_atlas/size", 4096);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
- GLOBAL_DEF("rendering/shadows/shadow_atlas/size.mobile", 2048);
- bool shadowmap_16_bits = GLOBAL_DEF("rendering/shadows/shadow_atlas/16_bits", true);
- int atlas_q0 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_0_subdiv", 2);
- int atlas_q1 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_1_subdiv", 2);
- int atlas_q2 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_2_subdiv", 3);
- int atlas_q3 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_3_subdiv", 4);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
-
- root->set_shadow_atlas_size(shadowmap_size);
- root->set_shadow_atlas_16_bits(shadowmap_16_bits);
- root->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
- root->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
- root->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
- root->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
+ // We setup VRS for the main viewport here, in the editor this will have little effect.
+ const int vrs_mode = GLOBAL_DEF("rendering/vrs/mode", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/vrs/mode", PropertyInfo(Variant::INT, "rendering/vrs/mode", PROPERTY_HINT_ENUM, String::utf8("Disabled,Texture,XR")));
+ root->set_vrs_mode(Viewport::VRSMode(vrs_mode));
+ const String vrs_texture_path = String(GLOBAL_DEF("rendering/vrs/texture", String())).strip_edges();
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/vrs/texture",
+ PropertyInfo(Variant::STRING,
+ "rendering/vrs/texture",
+ PROPERTY_HINT_FILE, "*.png"));
+ if (vrs_mode == 1 && !vrs_texture_path.is_empty()) {
+ Ref<Image> vrs_image;
+ vrs_image.instantiate();
+ Error load_err = ImageLoader::load_image(vrs_texture_path, vrs_image);
+ if (load_err) {
+ ERR_PRINT("Non-existing or invalid VRS texture at '" + vrs_texture_path + "'.");
+ } else {
+ Ref<ImageTexture> vrs_texture;
+ vrs_texture.instantiate();
+ vrs_texture->create_from_image(vrs_image);
+ root->set_vrs_texture(vrs_texture);
+ }
+ }
+
+ int shadowmap_size = GLOBAL_DEF("rendering/shadows/positional_shadow/atlas_size", 4096);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/positional_shadow/atlas_size", PropertyInfo(Variant::INT, "rendering/shadows/positional_shadow/atlas_size", PROPERTY_HINT_RANGE, "256,16384"));
+ GLOBAL_DEF("rendering/shadows/positional_shadow/atlas_size.mobile", 2048);
+ bool shadowmap_16_bits = GLOBAL_DEF("rendering/shadows/positional_shadow/atlas_16_bits", true);
+ int atlas_q0 = GLOBAL_DEF("rendering/shadows/positional_shadow/atlas_quadrant_0_subdiv", 2);
+ int atlas_q1 = GLOBAL_DEF("rendering/shadows/positional_shadow/atlas_quadrant_1_subdiv", 2);
+ int atlas_q2 = GLOBAL_DEF("rendering/shadows/positional_shadow/atlas_quadrant_2_subdiv", 3);
+ int atlas_q3 = GLOBAL_DEF("rendering/shadows/positional_shadow/atlas_quadrant_3_subdiv", 4);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/positional_shadow/atlas_quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/positional_shadow/atlas_quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/positional_shadow/atlas_quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/positional_shadow/atlas_quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/positional_shadow/atlas_quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/positional_shadow/atlas_quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/positional_shadow/atlas_quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/positional_shadow/atlas_quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+
+ root->set_positional_shadow_atlas_size(shadowmap_size);
+ root->set_positional_shadow_atlas_16_bits(shadowmap_16_bits);
+ root->set_positional_shadow_atlas_quadrant_subdiv(0, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q0));
+ root->set_positional_shadow_atlas_quadrant_subdiv(1, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q1));
+ root->set_positional_shadow_atlas_quadrant_subdiv(2, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q2));
+ root->set_positional_shadow_atlas_quadrant_subdiv(3, Viewport::PositionalShadowAtlasQuadrantSubdiv(atlas_q3));
Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_DEF("rendering/2d/sdf/oversize", 1)));
root->set_sdf_oversize(sdf_oversize);
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 67a17a69f2..a512feacc8 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -90,13 +90,14 @@ private:
Window *root = nullptr;
uint64_t tree_version = 1;
- double physics_process_time = 1.0;
- double process_time = 1.0;
+ double physics_process_time = 0.0;
+ double process_time = 0.0;
bool accept_quit = true;
bool quit_on_go_back = true;
#ifdef DEBUG_ENABLED
bool debug_collisions_hint = false;
+ bool debug_paths_hint = false;
bool debug_navigation_hint = false;
#endif
bool paused = false;
@@ -146,9 +147,12 @@ private:
Color debug_collisions_color;
Color debug_collision_contact_color;
+ Color debug_paths_color;
+ float debug_paths_width = 1.0f;
Color debug_navigation_color;
Color debug_navigation_disabled_color;
Ref<ArrayMesh> debug_contact_mesh;
+ Ref<Material> debug_paths_material;
Ref<Material> navigation_material;
Ref<Material> navigation_disabled_material;
Ref<Material> collision_material;
@@ -297,12 +301,18 @@ public:
void set_debug_collisions_hint(bool p_enabled);
bool is_debugging_collisions_hint() const;
+ void set_debug_paths_hint(bool p_enabled);
+ bool is_debugging_paths_hint() const;
+
void set_debug_navigation_hint(bool p_enabled);
bool is_debugging_navigation_hint() const;
#else
void set_debug_collisions_hint(bool p_enabled) {}
bool is_debugging_collisions_hint() const { return false; }
+ void set_debug_paths_hint(bool p_enabled) {}
+ bool is_debugging_paths_hint() const { return false; }
+
void set_debug_navigation_hint(bool p_enabled) {}
bool is_debugging_navigation_hint() const { return false; }
#endif
@@ -313,12 +323,19 @@ public:
void set_debug_collision_contact_color(const Color &p_color);
Color get_debug_collision_contact_color() const;
+ void set_debug_paths_color(const Color &p_color);
+ Color get_debug_paths_color() const;
+
+ void set_debug_paths_width(float p_width);
+ float get_debug_paths_width() const;
+
void set_debug_navigation_color(const Color &p_color);
Color get_debug_navigation_color() const;
void set_debug_navigation_disabled_color(const Color &p_color);
Color get_debug_navigation_disabled_color() const;
+ Ref<Material> get_debug_paths_material();
Ref<Material> get_debug_navigation_material();
Ref<Material> get_debug_navigation_disabled_material();
Ref<Material> get_debug_collision_material();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 1ad011f867..c2fa1ace8d 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -219,7 +219,7 @@ void Viewport::_sub_window_update(Window *p_window) {
int close_h_ofs = p_window->get_theme_constant(SNAME("close_h_offset"));
int close_v_ofs = p_window->get_theme_constant(SNAME("close_v_offset"));
- TextLine title_text = TextLine(p_window->atr(p_window->get_title()), title_font, font_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
+ TextLine title_text = TextLine(p_window->atr(p_window->get_title()), title_font, font_size);
title_text.set_width(r.size.width - panel->get_minimum_size().x - close_h_ofs);
title_text.set_direction(p_window->is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
int x = (r.size.width - title_text.get_size().x) / 2;
@@ -1037,44 +1037,44 @@ Ref<ViewportTexture> Viewport::get_texture() const {
return default_texture;
}
-void Viewport::set_shadow_atlas_size(int p_size) {
- shadow_atlas_size = p_size;
- RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size, shadow_atlas_16_bits);
+void Viewport::set_positional_shadow_atlas_size(int p_size) {
+ positional_shadow_atlas_size = p_size;
+ RS::get_singleton()->viewport_set_positional_shadow_atlas_size(viewport, p_size, positional_shadow_atlas_16_bits);
}
-int Viewport::get_shadow_atlas_size() const {
- return shadow_atlas_size;
+int Viewport::get_positional_shadow_atlas_size() const {
+ return positional_shadow_atlas_size;
}
-void Viewport::set_shadow_atlas_16_bits(bool p_16_bits) {
- if (shadow_atlas_16_bits == p_16_bits) {
+void Viewport::set_positional_shadow_atlas_16_bits(bool p_16_bits) {
+ if (positional_shadow_atlas_16_bits == p_16_bits) {
return;
}
- shadow_atlas_16_bits = p_16_bits;
- RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, shadow_atlas_size, shadow_atlas_16_bits);
+ positional_shadow_atlas_16_bits = p_16_bits;
+ RS::get_singleton()->viewport_set_positional_shadow_atlas_size(viewport, positional_shadow_atlas_size, positional_shadow_atlas_16_bits);
}
-bool Viewport::get_shadow_atlas_16_bits() const {
- return shadow_atlas_16_bits;
+bool Viewport::get_positional_shadow_atlas_16_bits() const {
+ return positional_shadow_atlas_16_bits;
}
-void Viewport::set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv) {
+void Viewport::set_positional_shadow_atlas_quadrant_subdiv(int p_quadrant, PositionalShadowAtlasQuadrantSubdiv p_subdiv) {
ERR_FAIL_INDEX(p_quadrant, 4);
ERR_FAIL_INDEX(p_subdiv, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
- if (shadow_atlas_quadrant_subdiv[p_quadrant] == p_subdiv) {
+ if (positional_shadow_atlas_quadrant_subdiv[p_quadrant] == p_subdiv) {
return;
}
- shadow_atlas_quadrant_subdiv[p_quadrant] = p_subdiv;
+ positional_shadow_atlas_quadrant_subdiv[p_quadrant] = p_subdiv;
static const int subdiv[SHADOW_ATLAS_QUADRANT_SUBDIV_MAX] = { 0, 1, 4, 16, 64, 256, 1024 };
- RS::get_singleton()->viewport_set_shadow_atlas_quadrant_subdivision(viewport, p_quadrant, subdiv[p_subdiv]);
+ RS::get_singleton()->viewport_set_positional_shadow_atlas_quadrant_subdivision(viewport, p_quadrant, subdiv[p_subdiv]);
}
-Viewport::ShadowAtlasQuadrantSubdiv Viewport::get_shadow_atlas_quadrant_subdiv(int p_quadrant) const {
+Viewport::PositionalShadowAtlasQuadrantSubdiv Viewport::get_positional_shadow_atlas_quadrant_subdiv(int p_quadrant) const {
ERR_FAIL_INDEX_V(p_quadrant, 4, SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED);
- return shadow_atlas_quadrant_subdiv[p_quadrant];
+ return positional_shadow_atlas_quadrant_subdiv[p_quadrant];
}
Transform2D Viewport::_get_input_pre_xform() const {
@@ -1215,7 +1215,7 @@ void Viewport::_gui_show_tooltip() {
panel->connect("mouse_entered", callable_mp(this, &Viewport::_gui_cancel_tooltip));
}
- base_tooltip->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ base_tooltip->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
panel->set_transient(true);
panel->set_flag(Window::FLAG_NO_FOCUS, true);
@@ -3080,6 +3080,41 @@ Viewport::DefaultCanvasItemTextureRepeat Viewport::get_default_canvas_item_textu
return default_canvas_item_texture_repeat;
}
+void Viewport::set_vrs_mode(Viewport::VRSMode p_vrs_mode) {
+ // Note, set this even if not supported on this hardware, it will only be used if it is but we want to save the value as set by the user.
+ vrs_mode = p_vrs_mode;
+
+ switch (p_vrs_mode) {
+ case VRS_TEXTURE: {
+ RS::get_singleton()->viewport_set_vrs_mode(viewport, RS::VIEWPORT_VRS_TEXTURE);
+ } break;
+ case VRS_XR: {
+ RS::get_singleton()->viewport_set_vrs_mode(viewport, RS::VIEWPORT_VRS_XR);
+ } break;
+ default: {
+ RS::get_singleton()->viewport_set_vrs_mode(viewport, RS::VIEWPORT_VRS_DISABLED);
+ } break;
+ }
+
+ notify_property_list_changed();
+}
+
+Viewport::VRSMode Viewport::get_vrs_mode() const {
+ return vrs_mode;
+}
+
+void Viewport::set_vrs_texture(Ref<Texture2D> p_texture) {
+ vrs_texture = p_texture;
+
+ // TODO need to add something here in case the RID changes
+ RID tex = p_texture.is_valid() ? p_texture->get_rid() : RID();
+ RS::get_singleton()->viewport_set_vrs_texture(viewport, tex);
+}
+
+Ref<Texture2D> Viewport::get_vrs_texture() const {
+ return vrs_texture;
+}
+
DisplayServer::WindowID Viewport::get_window_id() const {
return DisplayServer::MAIN_WINDOW_ID;
}
@@ -3667,11 +3702,11 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_remove_focus_for_window"), &Viewport::_gui_remove_focus_for_window);
ClassDB::bind_method(D_METHOD("_post_gui_grab_click_focus"), &Viewport::_post_gui_grab_click_focus);
- ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size);
- ClassDB::bind_method(D_METHOD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size);
+ ClassDB::bind_method(D_METHOD("set_positional_shadow_atlas_size", "size"), &Viewport::set_positional_shadow_atlas_size);
+ ClassDB::bind_method(D_METHOD("get_positional_shadow_atlas_size"), &Viewport::get_positional_shadow_atlas_size);
- ClassDB::bind_method(D_METHOD("set_shadow_atlas_16_bits", "enable"), &Viewport::set_shadow_atlas_16_bits);
- ClassDB::bind_method(D_METHOD("get_shadow_atlas_16_bits"), &Viewport::get_shadow_atlas_16_bits);
+ ClassDB::bind_method(D_METHOD("set_positional_shadow_atlas_16_bits", "enable"), &Viewport::set_positional_shadow_atlas_16_bits);
+ ClassDB::bind_method(D_METHOD("get_positional_shadow_atlas_16_bits"), &Viewport::get_positional_shadow_atlas_16_bits);
ClassDB::bind_method(D_METHOD("set_snap_controls_to_pixels", "enabled"), &Viewport::set_snap_controls_to_pixels);
ClassDB::bind_method(D_METHOD("is_snap_controls_to_pixels_enabled"), &Viewport::is_snap_controls_to_pixels_enabled);
@@ -3682,8 +3717,8 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_snap_2d_vertices_to_pixel", "enabled"), &Viewport::set_snap_2d_vertices_to_pixel);
ClassDB::bind_method(D_METHOD("is_snap_2d_vertices_to_pixel_enabled"), &Viewport::is_snap_2d_vertices_to_pixel_enabled);
- ClassDB::bind_method(D_METHOD("set_shadow_atlas_quadrant_subdiv", "quadrant", "subdiv"), &Viewport::set_shadow_atlas_quadrant_subdiv);
- ClassDB::bind_method(D_METHOD("get_shadow_atlas_quadrant_subdiv", "quadrant"), &Viewport::get_shadow_atlas_quadrant_subdiv);
+ ClassDB::bind_method(D_METHOD("set_positional_shadow_atlas_quadrant_subdiv", "quadrant", "subdiv"), &Viewport::set_positional_shadow_atlas_quadrant_subdiv);
+ ClassDB::bind_method(D_METHOD("get_positional_shadow_atlas_quadrant_subdiv", "quadrant"), &Viewport::get_positional_shadow_atlas_quadrant_subdiv);
ClassDB::bind_method(D_METHOD("set_input_as_handled"), &Viewport::set_input_as_handled);
ClassDB::bind_method(D_METHOD("is_input_handled"), &Viewport::is_input_handled);
@@ -3741,6 +3776,12 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_fsr_mipmap_bias", "fsr_mipmap_bias"), &Viewport::set_fsr_mipmap_bias);
ClassDB::bind_method(D_METHOD("get_fsr_mipmap_bias"), &Viewport::get_fsr_mipmap_bias);
+ ClassDB::bind_method(D_METHOD("set_vrs_mode", "mode"), &Viewport::set_vrs_mode);
+ ClassDB::bind_method(D_METHOD("get_vrs_mode"), &Viewport::get_vrs_mode);
+
+ ClassDB::bind_method(D_METHOD("set_vrs_texture", "texture"), &Viewport::set_vrs_texture);
+ ClassDB::bind_method(D_METHOD("get_vrs_texture"), &Viewport::get_vrs_texture);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_xr"), "set_use_xr", "is_using_xr");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d");
@@ -3766,6 +3807,9 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_mipmap_bias", PROPERTY_HINT_RANGE, "-2,2,0.1"), "set_fsr_mipmap_bias", "get_fsr_mipmap_bias");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.1"), "set_fsr_sharpness", "get_fsr_sharpness");
#endif
+ ADD_GROUP("Variable Rate Shading", "vrs_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "vrs_mode", PROPERTY_HINT_ENUM, "Disabled,Texture,Depth buffer,XR"), "set_vrs_mode", "get_vrs_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "vrs_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_vrs_texture", "get_vrs_texture");
ADD_GROUP("Canvas Items", "canvas_item_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Linear Mipmap,Nearest Mipmap"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirror"), "set_default_canvas_item_texture_repeat", "get_default_canvas_item_texture_repeat");
@@ -3783,13 +3827,13 @@ void Viewport::_bind_methods() {
ADD_GROUP("SDF", "sdf_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_oversize", PROPERTY_HINT_ENUM, "100%,120%,150%,200%"), "set_sdf_oversize", "get_sdf_oversize");
ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_scale", PROPERTY_HINT_ENUM, "100%,50%,25%"), "set_sdf_scale", "get_sdf_scale");
- ADD_GROUP("Shadow Atlas", "shadow_atlas_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_atlas_16_bits"), "set_shadow_atlas_16_bits", "get_shadow_atlas_16_bits");
- ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0);
- ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 1);
- ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 2);
- ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_3", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 3);
+ ADD_GROUP("Positional Shadow Atlas", "positional_shadow_atlas_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "positional_shadow_atlas_size"), "set_positional_shadow_atlas_size", "get_positional_shadow_atlas_size");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "positional_shadow_atlas_16_bits"), "set_positional_shadow_atlas_16_bits", "get_positional_shadow_atlas_16_bits");
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "positional_shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_positional_shadow_atlas_quadrant_subdiv", "get_positional_shadow_atlas_quadrant_subdiv", 0);
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "positional_shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_positional_shadow_atlas_quadrant_subdiv", "get_positional_shadow_atlas_quadrant_subdiv", 1);
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "positional_shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_positional_shadow_atlas_quadrant_subdiv", "get_positional_shadow_atlas_quadrant_subdiv", 2);
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "positional_shadow_atlas_quad_3", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_positional_shadow_atlas_quadrant_subdiv", "get_positional_shadow_atlas_quadrant_subdiv", 3);
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "canvas_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_canvas_transform", "get_canvas_transform");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_canvas_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_canvas_transform", "get_global_canvas_transform");
@@ -3876,6 +3920,17 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(SDF_SCALE_50_PERCENT);
BIND_ENUM_CONSTANT(SDF_SCALE_25_PERCENT);
BIND_ENUM_CONSTANT(SDF_SCALE_MAX);
+
+ BIND_ENUM_CONSTANT(VRS_DISABLED);
+ BIND_ENUM_CONSTANT(VRS_TEXTURE);
+ BIND_ENUM_CONSTANT(VRS_XR);
+ BIND_ENUM_CONSTANT(VRS_MAX);
+}
+
+void Viewport::_validate_property(PropertyInfo &property) const {
+ if (vrs_mode != VRS_TEXTURE && (property.name == "vrs_texture")) {
+ property.usage = PROPERTY_USAGE_NO_EDITOR;
+ }
}
Viewport::Viewport() {
@@ -3891,15 +3946,15 @@ Viewport::Viewport() {
canvas_layers.insert(nullptr); // This eases picking code (interpreted as the canvas of the Viewport).
- set_shadow_atlas_size(shadow_atlas_size);
+ set_positional_shadow_atlas_size(positional_shadow_atlas_size);
for (int i = 0; i < 4; i++) {
- shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX;
+ positional_shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX;
}
- set_shadow_atlas_quadrant_subdiv(0, SHADOW_ATLAS_QUADRANT_SUBDIV_4);
- set_shadow_atlas_quadrant_subdiv(1, SHADOW_ATLAS_QUADRANT_SUBDIV_4);
- set_shadow_atlas_quadrant_subdiv(2, SHADOW_ATLAS_QUADRANT_SUBDIV_16);
- set_shadow_atlas_quadrant_subdiv(3, SHADOW_ATLAS_QUADRANT_SUBDIV_64);
+ set_positional_shadow_atlas_quadrant_subdiv(0, SHADOW_ATLAS_QUADRANT_SUBDIV_4);
+ set_positional_shadow_atlas_quadrant_subdiv(1, SHADOW_ATLAS_QUADRANT_SUBDIV_4);
+ set_positional_shadow_atlas_quadrant_subdiv(2, SHADOW_ATLAS_QUADRANT_SUBDIV_16);
+ set_positional_shadow_atlas_quadrant_subdiv(3, SHADOW_ATLAS_QUADRANT_SUBDIV_64);
set_mesh_lod_threshold(mesh_lod_threshold);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index a22a2acf49..a43e3f3ee2 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -95,7 +95,7 @@ public:
SCALING_3D_MODE_MAX
};
- enum ShadowAtlasQuadrantSubdiv {
+ enum PositionalShadowAtlasQuadrantSubdiv {
SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED,
SHADOW_ATLAS_QUADRANT_SUBDIV_1,
SHADOW_ATLAS_QUADRANT_SUBDIV_4,
@@ -197,6 +197,13 @@ public:
SUBWINDOW_CANVAS_LAYER = 1024
};
+ enum VRSMode {
+ VRS_DISABLED,
+ VRS_TEXTURE,
+ VRS_XR,
+ VRS_MAX
+ };
+
private:
friend class ViewportTexture;
@@ -286,9 +293,9 @@ private:
DebugDraw debug_draw = DEBUG_DRAW_DISABLED;
- int shadow_atlas_size = 2048;
- bool shadow_atlas_16_bits = true;
- ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
+ int positional_shadow_atlas_size = 2048;
+ bool positional_shadow_atlas_16_bits = true;
+ PositionalShadowAtlasQuadrantSubdiv positional_shadow_atlas_quadrant_subdiv[4];
MSAA msaa = MSAA_DISABLED;
ScreenSpaceAA screen_space_aa = SCREEN_SPACE_AA_DISABLED;
@@ -333,6 +340,10 @@ private:
RID canvas_item;
};
+ // VRS
+ VRSMode vrs_mode = VRS_DISABLED;
+ Ref<Texture2D> vrs_texture;
+
struct GUI {
// info used when this is a window
@@ -502,14 +513,14 @@ public:
Ref<ViewportTexture> get_texture() const;
- void set_shadow_atlas_size(int p_size);
- int get_shadow_atlas_size() const;
+ void set_positional_shadow_atlas_size(int p_size);
+ int get_positional_shadow_atlas_size() const;
- void set_shadow_atlas_16_bits(bool p_16_bits);
- bool get_shadow_atlas_16_bits() const;
+ void set_positional_shadow_atlas_16_bits(bool p_16_bits);
+ bool get_positional_shadow_atlas_16_bits() const;
- void set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv);
- ShadowAtlasQuadrantSubdiv get_shadow_atlas_quadrant_subdiv(int p_quadrant) const;
+ void set_positional_shadow_atlas_quadrant_subdiv(int p_quadrant, PositionalShadowAtlasQuadrantSubdiv p_subdiv);
+ PositionalShadowAtlasQuadrantSubdiv get_positional_shadow_atlas_quadrant_subdiv(int p_quadrant) const;
void set_msaa(MSAA p_msaa);
MSAA get_msaa() const;
@@ -604,6 +615,14 @@ public:
void set_default_canvas_item_texture_repeat(DefaultCanvasItemTextureRepeat p_repeat);
DefaultCanvasItemTextureRepeat get_default_canvas_item_texture_repeat() const;
+ // VRS
+
+ void set_vrs_mode(VRSMode p_vrs_mode);
+ VRSMode get_vrs_mode() const;
+
+ void set_vrs_texture(Ref<Texture2D> p_texture);
+ Ref<Texture2D> get_vrs_texture() const;
+
virtual DisplayServer::WindowID get_window_id() const = 0;
void set_embedding_subwindows(bool p_embed);
@@ -690,6 +709,7 @@ public:
bool is_using_xr();
#endif // _3D_DISABLED
+ virtual void _validate_property(PropertyInfo &property) const override;
Viewport();
~Viewport();
};
@@ -746,12 +766,13 @@ public:
};
VARIANT_ENUM_CAST(Viewport::Scaling3DMode);
VARIANT_ENUM_CAST(SubViewport::UpdateMode);
-VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
+VARIANT_ENUM_CAST(Viewport::PositionalShadowAtlasQuadrantSubdiv);
VARIANT_ENUM_CAST(Viewport::MSAA);
VARIANT_ENUM_CAST(Viewport::ScreenSpaceAA);
VARIANT_ENUM_CAST(Viewport::DebugDraw);
VARIANT_ENUM_CAST(Viewport::SDFScale);
VARIANT_ENUM_CAST(Viewport::SDFOversize);
+VARIANT_ENUM_CAST(Viewport::VRSMode);
VARIANT_ENUM_CAST(SubViewport::ClearMode);
VARIANT_ENUM_CAST(Viewport::RenderInfo);
VARIANT_ENUM_CAST(Viewport::RenderInfoType);
diff --git a/scene/multiplayer/multiplayer_spawner.cpp b/scene/multiplayer/multiplayer_spawner.cpp
index ddd01d0a43..8363d05e54 100644
--- a/scene/multiplayer/multiplayer_spawner.cpp
+++ b/scene/multiplayer/multiplayer_spawner.cpp
@@ -71,7 +71,7 @@ bool MultiplayerSpawner::_get(const StringName &p_name, Variant &r_ret) const {
}
void MultiplayerSpawner::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::INT, "_spawnable_scene_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, "Scenes,scenes/"));
+ p_list->push_back(PropertyInfo(Variant::INT, "_spawnable_scene_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, "Auto Spawn List,scenes/"));
List<String> exts;
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &exts);
String ext_hint;
@@ -144,10 +144,6 @@ void MultiplayerSpawner::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_spawn_limit", "limit"), &MultiplayerSpawner::set_spawn_limit);
ADD_PROPERTY(PropertyInfo(Variant::INT, "spawn_limit", PROPERTY_HINT_RANGE, "0,1024,1,or_greater"), "set_spawn_limit", "get_spawn_limit");
- ClassDB::bind_method(D_METHOD("set_auto_spawning", "enabled"), &MultiplayerSpawner::set_auto_spawning);
- ClassDB::bind_method(D_METHOD("is_auto_spawning"), &MultiplayerSpawner::is_auto_spawning);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_spawn"), "set_auto_spawning", "is_auto_spawning");
-
GDVIRTUAL_BIND(_spawn_custom, "data");
ADD_SIGNAL(MethodInfo("despawned", PropertyInfo(Variant::INT, "scene_id"), PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
@@ -169,7 +165,7 @@ void MultiplayerSpawner::_update_spawn_node() {
Node *node = spawn_path.is_empty() && is_inside_tree() ? nullptr : get_node_or_null(spawn_path);
if (node) {
spawn_node = node->get_instance_id();
- if (auto_spawn) {
+ if (get_spawnable_scene_count() && !GDVIRTUAL_IS_OVERRIDDEN(_spawn_custom)) {
node->connect("child_entered_tree", callable_mp(this, &MultiplayerSpawner::_node_added));
}
} else {
@@ -221,15 +217,6 @@ void MultiplayerSpawner::_node_added(Node *p_node) {
_track(p_node, Variant(), id);
}
-void MultiplayerSpawner::set_auto_spawning(bool p_enabled) {
- auto_spawn = p_enabled;
- _update_spawn_node();
-}
-
-bool MultiplayerSpawner::is_auto_spawning() const {
- return auto_spawn;
-}
-
NodePath MultiplayerSpawner::get_spawn_path() const {
return spawn_path;
}
diff --git a/scene/multiplayer/multiplayer_spawner.h b/scene/multiplayer/multiplayer_spawner.h
index e8abe702a0..2c0eb9a2f0 100644
--- a/scene/multiplayer/multiplayer_spawner.h
+++ b/scene/multiplayer/multiplayer_spawner.h
@@ -69,7 +69,6 @@ private:
ObjectID spawn_node;
HashMap<ObjectID, SpawnInfo> tracked_nodes;
- bool auto_spawn = false;
uint32_t spawn_limit = 0;
void _update_spawn_node();
@@ -102,8 +101,6 @@ public:
void set_spawn_path(const NodePath &p_path);
uint32_t get_spawn_limit() const { return spawn_limit; }
void set_spawn_limit(uint32_t p_limit) { spawn_limit = p_limit; }
- bool is_auto_spawning() const;
- void set_auto_spawning(bool p_enabled);
const Variant get_spawn_argument(const ObjectID &p_id) const;
int find_spawnable_scene_index_from_object(const ObjectID &p_id) const;
diff --git a/scene/multiplayer/multiplayer_synchronizer.cpp b/scene/multiplayer/multiplayer_synchronizer.cpp
index 68f6e54fa8..e1b7433968 100644
--- a/scene/multiplayer/multiplayer_synchronizer.cpp
+++ b/scene/multiplayer/multiplayer_synchronizer.cpp
@@ -43,6 +43,11 @@ Object *MultiplayerSynchronizer::_get_prop_target(Object *p_obj, const NodePath
}
void MultiplayerSynchronizer::_stop() {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ return;
+ }
+#endif
Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr;
if (node) {
get_multiplayer()->replication_stop(node, this);
@@ -50,9 +55,42 @@ void MultiplayerSynchronizer::_stop() {
}
void MultiplayerSynchronizer::_start() {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ return;
+ }
+#endif
Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr;
if (node) {
get_multiplayer()->replication_start(node, this);
+ _update_process();
+ }
+}
+
+void MultiplayerSynchronizer::_update_process() {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ return;
+ }
+#endif
+ Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr;
+ if (!node) {
+ return;
+ }
+ set_process_internal(false);
+ set_physics_process_internal(false);
+ if (!visibility_filters.size()) {
+ return;
+ }
+ switch (visibility_update_mode) {
+ case VISIBILITY_PROCESS_IDLE:
+ set_process_internal(true);
+ break;
+ case VISIBILITY_PROCESS_PHYSICS:
+ set_physics_process_internal(true);
+ break;
+ case VISIBILITY_PROCESS_NONE:
+ break;
}
}
@@ -85,6 +123,66 @@ Error MultiplayerSynchronizer::set_state(const List<NodePath> &p_properties, Obj
return OK;
}
+bool MultiplayerSynchronizer::is_visibility_public() const {
+ return peer_visibility.has(0);
+}
+
+void MultiplayerSynchronizer::set_visibility_public(bool p_visible) {
+ set_visibility_for(0, p_visible);
+}
+
+bool MultiplayerSynchronizer::is_visible_to(int p_peer) {
+ if (visibility_filters.size()) {
+ Variant arg = p_peer;
+ const Variant *argv[1] = { &arg };
+ for (Callable filter : visibility_filters) {
+ Variant ret;
+ Callable::CallError err;
+ filter.call(argv, 1, ret, err);
+ ERR_FAIL_COND_V(err.error != Callable::CallError::CALL_OK || ret.get_type() != Variant::BOOL, false);
+ if (!ret.operator bool()) {
+ return false;
+ }
+ }
+ }
+ return peer_visibility.has(0) || peer_visibility.has(p_peer);
+}
+
+void MultiplayerSynchronizer::add_visibility_filter(Callable p_callback) {
+ visibility_filters.insert(p_callback);
+ _update_process();
+}
+
+void MultiplayerSynchronizer::remove_visibility_filter(Callable p_callback) {
+ visibility_filters.erase(p_callback);
+ _update_process();
+}
+
+void MultiplayerSynchronizer::set_visibility_for(int p_peer, bool p_visible) {
+ if (peer_visibility.has(p_peer) == p_visible) {
+ return;
+ }
+ if (p_visible) {
+ peer_visibility.insert(p_peer);
+ } else {
+ peer_visibility.erase(p_peer);
+ }
+ update_visibility(p_peer);
+}
+
+bool MultiplayerSynchronizer::get_visibility_for(int p_peer) const {
+ return peer_visibility.has(p_peer);
+}
+
+void MultiplayerSynchronizer::set_visibility_update_mode(VisibilityUpdateMode p_mode) {
+ visibility_update_mode = p_mode;
+ _update_process();
+}
+
+MultiplayerSynchronizer::VisibilityUpdateMode MultiplayerSynchronizer::get_visibility_update_mode() const {
+ return visibility_update_mode;
+}
+
void MultiplayerSynchronizer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_root_path", "path"), &MultiplayerSynchronizer::set_root_path);
ClassDB::bind_method(D_METHOD("get_root_path"), &MultiplayerSynchronizer::get_root_path);
@@ -95,9 +193,29 @@ void MultiplayerSynchronizer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_replication_config", "config"), &MultiplayerSynchronizer::set_replication_config);
ClassDB::bind_method(D_METHOD("get_replication_config"), &MultiplayerSynchronizer::get_replication_config);
+ ClassDB::bind_method(D_METHOD("set_visibility_update_mode", "mode"), &MultiplayerSynchronizer::set_visibility_update_mode);
+ ClassDB::bind_method(D_METHOD("get_visibility_update_mode"), &MultiplayerSynchronizer::get_visibility_update_mode);
+ ClassDB::bind_method(D_METHOD("update_visibility", "for_peer"), &MultiplayerSynchronizer::update_visibility, DEFVAL(0));
+
+ ClassDB::bind_method(D_METHOD("set_visibility_public", "visible"), &MultiplayerSynchronizer::set_visibility_public);
+ ClassDB::bind_method(D_METHOD("is_visibility_public"), &MultiplayerSynchronizer::is_visibility_public);
+
+ ClassDB::bind_method(D_METHOD("add_visibility_filter", "filter"), &MultiplayerSynchronizer::add_visibility_filter);
+ ClassDB::bind_method(D_METHOD("remove_visibility_filter", "filter"), &MultiplayerSynchronizer::remove_visibility_filter);
+ ClassDB::bind_method(D_METHOD("set_visibility_for", "peer", "visible"), &MultiplayerSynchronizer::set_visibility_for);
+ ClassDB::bind_method(D_METHOD("get_visibility_for", "peer"), &MultiplayerSynchronizer::get_visibility_for);
+
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_path"), "set_root_path", "get_root_path");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "replication_interval", PROPERTY_HINT_RANGE, "0,5,0.001,suffix:s"), "set_replication_interval", "get_replication_interval");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "replication_config", PROPERTY_HINT_RESOURCE_TYPE, "SceneReplicationConfig"), "set_replication_config", "get_replication_config");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "replication_config", PROPERTY_HINT_RESOURCE_TYPE, "SceneReplicationConfig", PROPERTY_USAGE_NO_EDITOR), "set_replication_config", "get_replication_config");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_update_mode", PROPERTY_HINT_ENUM, "Idle,Physics,None"), "set_visibility_update_mode", "get_visibility_update_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "public_visibility"), "set_visibility_public", "is_visibility_public");
+
+ BIND_ENUM_CONSTANT(VISIBILITY_PROCESS_IDLE);
+ BIND_ENUM_CONSTANT(VISIBILITY_PROCESS_PHYSICS);
+ BIND_ENUM_CONSTANT(VISIBILITY_PROCESS_NONE);
+
+ ADD_SIGNAL(MethodInfo("visibility_changed", PropertyInfo(Variant::INT, "for_peer")));
}
void MultiplayerSynchronizer::_notification(int p_what) {
@@ -118,6 +236,11 @@ void MultiplayerSynchronizer::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
_stop();
} break;
+
+ case NOTIFICATION_INTERNAL_PROCESS:
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ update_visibility(0);
+ } break;
}
}
@@ -142,6 +265,18 @@ Ref<SceneReplicationConfig> MultiplayerSynchronizer::get_replication_config() {
return replication_config;
}
+void MultiplayerSynchronizer::update_visibility(int p_for_peer) {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ return;
+ }
+#endif
+ Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr;
+ if (node && get_multiplayer()->has_multiplayer_peer() && is_multiplayer_authority()) {
+ emit_signal(SNAME("visibility_changed"), p_for_peer);
+ }
+}
+
void MultiplayerSynchronizer::set_root_path(const NodePath &p_path) {
_stop();
root_path = p_path;
@@ -162,3 +297,8 @@ void MultiplayerSynchronizer::set_multiplayer_authority(int p_peer_id, bool p_re
Node::set_multiplayer_authority(p_peer_id, p_recursive);
get_multiplayer()->replication_start(node, this);
}
+
+MultiplayerSynchronizer::MultiplayerSynchronizer() {
+ // Publicly visible by default.
+ peer_visibility.insert(0);
+}
diff --git a/scene/multiplayer/multiplayer_synchronizer.h b/scene/multiplayer/multiplayer_synchronizer.h
index f61ef459da..59f02b84c1 100644
--- a/scene/multiplayer/multiplayer_synchronizer.h
+++ b/scene/multiplayer/multiplayer_synchronizer.h
@@ -38,14 +38,25 @@
class MultiplayerSynchronizer : public Node {
GDCLASS(MultiplayerSynchronizer, Node);
+public:
+ enum VisibilityUpdateMode {
+ VISIBILITY_PROCESS_IDLE,
+ VISIBILITY_PROCESS_PHYSICS,
+ VISIBILITY_PROCESS_NONE,
+ };
+
private:
Ref<SceneReplicationConfig> replication_config;
NodePath root_path = NodePath(".."); // Start with parent, like with AnimationPlayer.
uint64_t interval_msec = 0;
+ VisibilityUpdateMode visibility_update_mode = VISIBILITY_PROCESS_IDLE;
+ HashSet<Callable> visibility_filters;
+ HashSet<int> peer_visibility;
static Object *_get_prop_target(Object *p_obj, const NodePath &p_prop);
void _start();
void _stop();
+ void _update_process();
protected:
static void _bind_methods();
@@ -66,7 +77,19 @@ public:
NodePath get_root_path() const;
virtual void set_multiplayer_authority(int p_peer_id, bool p_recursive = true) override;
- MultiplayerSynchronizer() {}
+ bool is_visibility_public() const;
+ void set_visibility_public(bool p_public);
+ bool is_visible_to(int p_peer);
+ void set_visibility_for(int p_peer, bool p_visible);
+ bool get_visibility_for(int p_peer) const;
+ void update_visibility(int p_for_peer);
+ void set_visibility_update_mode(VisibilityUpdateMode p_mode);
+ void add_visibility_filter(Callable p_callback);
+ void remove_visibility_filter(Callable p_callback);
+ VisibilityUpdateMode get_visibility_update_mode() const;
+
+ MultiplayerSynchronizer();
};
+VARIANT_ENUM_CAST(MultiplayerSynchronizer::VisibilityUpdateMode);
#endif // MULTIPLAYER_SYNCHRONIZER_H
diff --git a/scene/multiplayer/scene_cache_interface.cpp b/scene/multiplayer/scene_cache_interface.cpp
index 7c271341db..79a7dc2d5a 100644
--- a/scene/multiplayer/scene_cache_interface.cpp
+++ b/scene/multiplayer/scene_cache_interface.cpp
@@ -187,18 +187,29 @@ bool SceneCacheInterface::is_cache_confirmed(NodePath p_path, int p_peer) {
return F->value;
}
-bool SceneCacheInterface::send_object_cache(Object *p_obj, NodePath p_path, int p_peer_id, int &r_id) {
+int SceneCacheInterface::make_object_cache(Object *p_obj) {
Node *node = Object::cast_to<Node>(p_obj);
- ERR_FAIL_COND_V(!node, false);
+ ERR_FAIL_COND_V(!node, -1);
+ NodePath for_path = multiplayer->get_root_path().rel_path_to(node->get_path());
// See if the path is cached.
- PathSentCache *psc = path_send_cache.getptr(p_path);
+ PathSentCache *psc = path_send_cache.getptr(for_path);
if (!psc) {
// Path is not cached, create.
- path_send_cache[p_path] = PathSentCache();
- psc = path_send_cache.getptr(p_path);
+ path_send_cache[for_path] = PathSentCache();
+ psc = path_send_cache.getptr(for_path);
psc->id = last_send_cache_id++;
}
- r_id = psc->id;
+ return psc->id;
+}
+
+bool SceneCacheInterface::send_object_cache(Object *p_obj, int p_peer_id, int &r_id) {
+ Node *node = Object::cast_to<Node>(p_obj);
+ ERR_FAIL_COND_V(!node, false);
+
+ r_id = make_object_cache(p_obj);
+ ERR_FAIL_COND_V(r_id < 0, false);
+ NodePath for_path = multiplayer->get_root_path().rel_path_to(node->get_path());
+ PathSentCache *psc = path_send_cache.getptr(for_path);
bool has_all_peers = true;
List<int> peers_to_add; // If one is missing, take note to add it.
@@ -233,7 +244,7 @@ bool SceneCacheInterface::send_object_cache(Object *p_obj, NodePath p_path, int
}
if (peers_to_add.size()) {
- _send_confirm_path(node, p_path, psc, peers_to_add);
+ _send_confirm_path(node, for_path, psc, peers_to_add);
}
return has_all_peers;
diff --git a/scene/multiplayer/scene_cache_interface.h b/scene/multiplayer/scene_cache_interface.h
index 3116233b5b..6bfd683cf4 100644
--- a/scene/multiplayer/scene_cache_interface.h
+++ b/scene/multiplayer/scene_cache_interface.h
@@ -72,7 +72,8 @@ public:
virtual void process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) override;
// Returns true if all peers have cached path.
- virtual bool send_object_cache(Object *p_obj, NodePath p_path, int p_target, int &p_id) override;
+ virtual bool send_object_cache(Object *p_obj, int p_target, int &p_id) override;
+ virtual int make_object_cache(Object *p_obj) override;
virtual Object *get_cached_object(int p_from, uint32_t p_cache_id) override;
virtual bool is_cache_confirmed(NodePath p_path, int p_peer) override;
diff --git a/scene/multiplayer/scene_replication_interface.cpp b/scene/multiplayer/scene_replication_interface.cpp
index e4715ceb88..c616c5bb85 100644
--- a/scene/multiplayer/scene_replication_interface.cpp
+++ b/scene/multiplayer/scene_replication_interface.cpp
@@ -60,14 +60,13 @@ void SceneReplicationInterface::on_peer_change(int p_id, bool p_connected) {
if (p_connected) {
rep_state->on_peer_change(p_id, p_connected);
for (const ObjectID &oid : rep_state->get_spawned_nodes()) {
- _send_spawn(rep_state->get_node(oid), rep_state->get_spawner(oid), p_id);
+ _update_spawn_visibility(p_id, oid);
}
- for (const ObjectID &oid : rep_state->get_path_only_nodes()) {
- Node *node = rep_state->get_node(oid);
+ for (const ObjectID &oid : rep_state->get_synced_nodes()) {
MultiplayerSynchronizer *sync = rep_state->get_synchronizer(oid);
- ERR_CONTINUE(!node || !sync);
+ ERR_CONTINUE(!sync); // ERR_BUG
if (sync->is_multiplayer_authority()) {
- rep_state->peer_add_node(p_id, oid);
+ _update_sync_visibility(p_id, oid);
}
}
} else {
@@ -97,7 +96,13 @@ Error SceneReplicationInterface::on_spawn(Object *p_obj, Variant p_config) {
ERR_FAIL_COND_V(!spawner, ERR_INVALID_PARAMETER);
Error err = rep_state->config_add_spawn(node, spawner);
ERR_FAIL_COND_V(err != OK, err);
- return _send_spawn(node, spawner, 0);
+ const ObjectID oid = node->get_instance_id();
+ if (multiplayer->has_multiplayer_peer() && spawner->is_multiplayer_authority()) {
+ rep_state->ensure_net_id(oid);
+ _update_spawn_visibility(0, oid);
+ }
+ ERR_FAIL_COND_V(err != OK, err);
+ return OK;
}
Error SceneReplicationInterface::on_despawn(Object *p_obj, Variant p_config) {
@@ -105,9 +110,19 @@ Error SceneReplicationInterface::on_despawn(Object *p_obj, Variant p_config) {
ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER);
MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(p_config.get_validated_object());
ERR_FAIL_COND_V(!p_obj || !spawner, ERR_INVALID_PARAMETER);
- Error err = rep_state->config_del_spawn(node, spawner);
- ERR_FAIL_COND_V(err != OK, err);
- return _send_despawn(node, 0);
+ // Forcibly despawn to all peers that knowns me.
+ int len = 0;
+ Error err = _make_despawn_packet(node, len);
+ ERR_FAIL_COND_V(err != OK, ERR_BUG);
+ const ObjectID oid = p_obj->get_instance_id();
+ for (int pid : rep_state->get_peers()) {
+ if (!rep_state->is_peer_spawn(pid, oid)) {
+ continue;
+ }
+ _send_raw(packet_cache.ptr(), len, pid, true);
+ }
+ // Also remove spawner tracking from the replication state.
+ return rep_state->config_del_spawn(node, spawner);
}
Error SceneReplicationInterface::on_replication_start(Object *p_obj, Variant p_config) {
@@ -115,7 +130,15 @@ Error SceneReplicationInterface::on_replication_start(Object *p_obj, Variant p_c
ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER);
MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object());
ERR_FAIL_COND_V(!sync, ERR_INVALID_PARAMETER);
+
+ // Add to synchronizer list and setup visibility.
rep_state->config_add_sync(node, sync);
+ const ObjectID oid = node->get_instance_id();
+ sync->connect("visibility_changed", callable_mp(this, &SceneReplicationInterface::_visibility_changed), varray(oid));
+ if (multiplayer->has_multiplayer_peer() && sync->is_multiplayer_authority()) {
+ _update_sync_visibility(0, oid);
+ }
+
// Try to apply initial state if spawning (hack to apply if before ready).
if (pending_spawn == p_obj->get_instance_id()) {
pending_spawn = ObjectID(); // Make sure this only happens once.
@@ -127,9 +150,6 @@ Error SceneReplicationInterface::on_replication_start(Object *p_obj, Variant p_c
ERR_FAIL_COND_V(err, err);
err = MultiplayerSynchronizer::set_state(props, node, vars);
ERR_FAIL_COND_V(err, err);
- } else if (multiplayer->has_multiplayer_peer() && sync->is_multiplayer_authority()) {
- // Either it's a spawn or a static sync, in any case add it to the list of known nodes.
- rep_state->peer_add_node(0, p_obj->get_instance_id());
}
return OK;
}
@@ -138,10 +158,103 @@ Error SceneReplicationInterface::on_replication_stop(Object *p_obj, Variant p_co
Node *node = Object::cast_to<Node>(p_obj);
ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER);
MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object());
- ERR_FAIL_COND_V(!p_obj || !sync, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(!sync, ERR_INVALID_PARAMETER);
+ sync->disconnect("visibility_changed", callable_mp(this, &SceneReplicationInterface::_visibility_changed));
return rep_state->config_del_sync(node, sync);
}
+void SceneReplicationInterface::_visibility_changed(int p_peer, ObjectID p_oid) {
+ if (rep_state->is_spawned_node(p_oid)) {
+ _update_spawn_visibility(p_peer, p_oid);
+ }
+ if (rep_state->is_synced_node(p_oid)) {
+ _update_sync_visibility(p_peer, p_oid);
+ }
+}
+
+Error SceneReplicationInterface::_update_sync_visibility(int p_peer, const ObjectID &p_oid) {
+ MultiplayerSynchronizer *sync = rep_state->get_synchronizer(p_oid);
+ ERR_FAIL_COND_V(!sync || !sync->is_multiplayer_authority(), ERR_BUG);
+ bool is_visible = sync->is_visible_to(p_peer);
+ if (p_peer == 0) {
+ for (int pid : rep_state->get_peers()) {
+ // Might be visible to this specific peer.
+ is_visible = is_visible || sync->is_visible_to(pid);
+ if (rep_state->is_peer_sync(pid, p_oid) == is_visible) {
+ continue;
+ }
+ if (is_visible) {
+ rep_state->peer_add_sync(pid, p_oid);
+ } else {
+ rep_state->peer_del_sync(pid, p_oid);
+ }
+ }
+ return OK;
+ } else {
+ if (is_visible == rep_state->is_peer_sync(p_peer, p_oid)) {
+ return OK;
+ }
+ if (is_visible) {
+ return rep_state->peer_add_sync(p_peer, p_oid);
+ } else {
+ return rep_state->peer_del_sync(p_peer, p_oid);
+ }
+ }
+}
+
+Error SceneReplicationInterface::_update_spawn_visibility(int p_peer, const ObjectID &p_oid) {
+ MultiplayerSpawner *spawner = rep_state->get_spawner(p_oid);
+ MultiplayerSynchronizer *sync = rep_state->get_synchronizer(p_oid);
+ Node *node = Object::cast_to<Node>(ObjectDB::get_instance(p_oid));
+ ERR_FAIL_COND_V(!node || !spawner || !spawner->is_multiplayer_authority(), ERR_BUG);
+ bool is_visible = !sync || sync->is_visible_to(p_peer);
+ // Spawn (and despawn) when needed.
+ HashSet<int> to_spawn;
+ HashSet<int> to_despawn;
+ if (p_peer) {
+ if (is_visible == rep_state->is_peer_spawn(p_peer, p_oid)) {
+ return OK;
+ }
+ if (is_visible) {
+ to_spawn.insert(p_peer);
+ } else {
+ to_despawn.insert(p_peer);
+ }
+ } else {
+ // Check visibility for each peers.
+ for (int pid : rep_state->get_peers()) {
+ bool peer_visible = is_visible || sync->is_visible_to(pid);
+ if (peer_visible == rep_state->is_peer_spawn(pid, p_oid)) {
+ continue;
+ }
+ if (peer_visible) {
+ to_spawn.insert(pid);
+ } else {
+ to_despawn.insert(pid);
+ }
+ }
+ }
+ if (to_spawn.size()) {
+ int len = 0;
+ _make_spawn_packet(node, len);
+ for (int pid : to_spawn) {
+ int path_id;
+ multiplayer->send_object_cache(spawner, pid, path_id);
+ _send_raw(packet_cache.ptr(), len, pid, true);
+ rep_state->peer_add_spawn(pid, p_oid);
+ }
+ }
+ if (to_despawn.size()) {
+ int len = 0;
+ _make_despawn_packet(node, len);
+ for (int pid : to_despawn) {
+ rep_state->peer_del_spawn(pid, p_oid);
+ _send_raw(packet_cache.ptr(), len, pid, true);
+ }
+ }
+ return OK;
+}
+
Error SceneReplicationInterface::_send_raw(const uint8_t *p_buffer, int p_size, int p_peer, bool p_reliable) {
ERR_FAIL_COND_V(!p_buffer || p_size < 1, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!multiplayer, ERR_UNCONFIGURED);
@@ -158,18 +271,20 @@ Error SceneReplicationInterface::_send_raw(const uint8_t *p_buffer, int p_size,
return peer->put_packet(p_buffer, p_size);
}
-Error SceneReplicationInterface::_send_spawn(Node *p_node, MultiplayerSpawner *p_spawner, int p_peer) {
- ERR_FAIL_COND_V(p_peer < 0, ERR_BUG);
+Error SceneReplicationInterface::_make_spawn_packet(Node *p_node, int &r_len) {
ERR_FAIL_COND_V(!multiplayer, ERR_BUG);
- ERR_FAIL_COND_V(!p_spawner || !p_node, ERR_BUG);
const ObjectID oid = p_node->get_instance_id();
- uint32_t nid = rep_state->ensure_net_id(oid);
+ MultiplayerSpawner *spawner = rep_state->get_spawner(oid);
+ ERR_FAIL_COND_V(!spawner || !p_node, ERR_BUG);
+
+ uint32_t nid = rep_state->get_net_id(oid);
+ ERR_FAIL_COND_V(!nid, ERR_UNCONFIGURED);
// Prepare custom arg and scene_id
- uint8_t scene_id = p_spawner->find_spawnable_scene_index_from_object(oid);
+ uint8_t scene_id = spawner->find_spawnable_scene_index_from_object(oid);
bool is_custom = scene_id == MultiplayerSpawner::INVALID_ID;
- Variant spawn_arg = p_spawner->get_spawn_argument(oid);
+ Variant spawn_arg = spawner->get_spawn_argument(oid);
int spawn_arg_size = 0;
if (is_custom) {
Error err = MultiplayerAPI::encode_and_compress_variant(spawn_arg, nullptr, spawn_arg_size, false);
@@ -181,7 +296,8 @@ Error SceneReplicationInterface::_send_spawn(Node *p_node, MultiplayerSpawner *p
Vector<Variant> state_vars;
Vector<const Variant *> state_varp;
MultiplayerSynchronizer *synchronizer = rep_state->get_synchronizer(oid);
- if (synchronizer && synchronizer->get_replication_config().is_valid()) {
+ if (synchronizer) {
+ ERR_FAIL_COND_V(synchronizer->get_replication_config().is_null(), ERR_BUG);
const List<NodePath> props = synchronizer->get_replication_config()->get_spawn_properties();
Error err = MultiplayerSynchronizer::get_state(props, p_node, state_vars, state_varp);
ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to retrieve spawn state.");
@@ -189,13 +305,8 @@ Error SceneReplicationInterface::_send_spawn(Node *p_node, MultiplayerSpawner *p
ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to encode spawn state.");
}
- // Prepare simplified path.
- NodePath rel_path = multiplayer->get_root_path().rel_path_to(p_spawner->get_path());
-
- int path_id = 0;
- multiplayer->send_object_cache(p_spawner, rel_path, p_peer, path_id);
-
- // Encode name and parent ID.
+ // Encode scene ID, path ID, net ID, node name.
+ int path_id = multiplayer->make_object_cache(spawner);
CharString cname = p_node->get_name().operator String().utf8();
int nlen = encode_cstring(cname.get_data(), nullptr);
MAKE_ROOM(1 + 1 + 4 + 4 + 4 + nlen + (is_custom ? 4 + spawn_arg_size : 0) + state_size);
@@ -220,12 +331,11 @@ Error SceneReplicationInterface::_send_spawn(Node *p_node, MultiplayerSpawner *p
ERR_FAIL_COND_V(err, err);
ofs += state_size;
}
- Error err = _send_raw(ptr, ofs, p_peer, true);
- ERR_FAIL_COND_V(err, err);
- return rep_state->peer_add_node(p_peer, oid);
+ r_len = ofs;
+ return OK;
}
-Error SceneReplicationInterface::_send_despawn(Node *p_node, int p_peer) {
+Error SceneReplicationInterface::_make_despawn_packet(Node *p_node, int &r_len) {
const ObjectID oid = p_node->get_instance_id();
MAKE_ROOM(5);
uint8_t *ptr = packet_cache.ptrw();
@@ -233,9 +343,8 @@ Error SceneReplicationInterface::_send_despawn(Node *p_node, int p_peer) {
int ofs = 1;
uint32_t nid = rep_state->get_net_id(oid);
ofs += encode_uint32(nid, &ptr[ofs]);
- Error err = _send_raw(ptr, ofs, p_peer, true);
- ERR_FAIL_COND_V(err, err);
- return rep_state->peer_del_node(p_peer, oid);
+ r_len = ofs;
+ return OK;
}
Error SceneReplicationInterface::on_spawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) {
@@ -316,8 +425,8 @@ Error SceneReplicationInterface::on_despawn_receive(int p_from, const uint8_t *p
}
void SceneReplicationInterface::_send_sync(int p_peer, uint64_t p_msec) {
- const HashSet<ObjectID> &known = rep_state->get_known_nodes(p_peer);
- if (known.is_empty()) {
+ const HashSet<ObjectID> &to_sync = rep_state->get_peer_sync_nodes(p_peer);
+ if (to_sync.is_empty()) {
return;
}
MAKE_ROOM(sync_mtu);
@@ -327,14 +436,29 @@ void SceneReplicationInterface::_send_sync(int p_peer, uint64_t p_msec) {
ofs += encode_uint16(rep_state->peer_sync_next(p_peer), &ptr[1]);
// Can only send updates for already notified nodes.
// This is a lazy implementation, we could optimize much more here with by grouping by replication config.
- for (const ObjectID &oid : known) {
+ for (const ObjectID &oid : to_sync) {
if (!rep_state->update_sync_time(oid, p_msec)) {
continue; // nothing to sync.
}
MultiplayerSynchronizer *sync = rep_state->get_synchronizer(oid);
- ERR_CONTINUE(!sync);
+ ERR_CONTINUE(!sync || !sync->get_replication_config().is_valid());
Node *node = rep_state->get_node(oid);
ERR_CONTINUE(!node);
+ uint32_t net_id = rep_state->get_net_id(oid);
+ if (net_id == 0 || (net_id & 0x80000000)) {
+ int path_id = 0;
+ bool verified = multiplayer->send_object_cache(sync, p_peer, path_id);
+ ERR_CONTINUE_MSG(path_id < 0, "This should never happen!");
+ if (net_id == 0) {
+ // First time path based ID.
+ net_id = path_id | 0x80000000;
+ rep_state->set_net_id(oid, net_id | 0x80000000);
+ }
+ if (!verified) {
+ // The path based sync is not yet confirmed, skipping.
+ continue;
+ }
+ }
int size;
Vector<Variant> vars;
Vector<const Variant *> varp;
@@ -351,16 +475,6 @@ void SceneReplicationInterface::_send_sync(int p_peer, uint64_t p_msec) {
ofs = 3;
}
if (size) {
- uint32_t net_id = rep_state->get_net_id(oid);
- if (net_id == 0 || (net_id & 0x80000000)) {
- // First time path based ID.
- NodePath rel_path = multiplayer->get_root_path().rel_path_to(sync->get_path());
- int path_id = 0;
- multiplayer->send_object_cache(sync, rel_path, p_peer, path_id);
- ERR_CONTINUE_MSG(net_id && net_id != (uint32_t(path_id) | 0x80000000), "This should never happen!");
- net_id = path_id;
- rep_state->set_net_id(oid, net_id | 0x80000000);
- }
ofs += encode_uint32(rep_state->get_net_id(oid), &ptr[ofs]);
ofs += encode_uint32(size, &ptr[ofs]);
MultiplayerAPI::encode_and_compress_variants(varp.ptrw(), varp.size(), &ptr[ofs], size);
diff --git a/scene/multiplayer/scene_replication_interface.h b/scene/multiplayer/scene_replication_interface.h
index 60ac95c93c..ad3a3be979 100644
--- a/scene/multiplayer/scene_replication_interface.h
+++ b/scene/multiplayer/scene_replication_interface.h
@@ -40,10 +40,13 @@ class SceneReplicationInterface : public MultiplayerReplicationInterface {
private:
void _send_sync(int p_peer, uint64_t p_msec);
- Error _send_spawn(Node *p_node, MultiplayerSpawner *p_spawner, int p_peer);
- Error _send_despawn(Node *p_node, int p_peer);
+ Error _make_spawn_packet(Node *p_node, int &r_len);
+ Error _make_despawn_packet(Node *p_node, int &r_len);
Error _send_raw(const uint8_t *p_buffer, int p_size, int p_peer, bool p_reliable);
+ void _visibility_changed(int p_peer, ObjectID p_oid);
+ Error _update_sync_visibility(int p_peer, const ObjectID &p_oid);
+ Error _update_spawn_visibility(int p_peer, const ObjectID &p_oid);
void _free_remotes(int p_peer);
Ref<SceneReplicationState> rep_state;
diff --git a/scene/multiplayer/scene_replication_state.cpp b/scene/multiplayer/scene_replication_state.cpp
index 937b30cb36..f6a51ff9c7 100644
--- a/scene/multiplayer/scene_replication_state.cpp
+++ b/scene/multiplayer/scene_replication_state.cpp
@@ -56,7 +56,8 @@ void SceneReplicationState::_untrack(const ObjectID &p_id) {
// If we spawned or synced it, we need to remove it from any peer it was sent to.
if (net_id || peer == 0) {
for (KeyValue<int, PeerInfo> &E : peers_info) {
- E.value.known_nodes.erase(p_id);
+ E.value.sync_nodes.erase(p_id);
+ E.value.spawn_nodes.erase(p_id);
}
}
}
@@ -93,11 +94,6 @@ bool SceneReplicationState::update_sync_time(const ObjectID &p_id, uint64_t p_ms
return false;
}
-const HashSet<ObjectID> SceneReplicationState::get_known_nodes(int p_peer) {
- ERR_FAIL_COND_V(!peers_info.has(p_peer), HashSet<ObjectID>());
- return peers_info[p_peer].known_nodes;
-}
-
uint32_t SceneReplicationState::get_net_id(const ObjectID &p_id) const {
const TrackedNode *tnode = tracked_nodes.getptr(p_id);
ERR_FAIL_COND_V(!tnode, 0);
@@ -147,8 +143,6 @@ Error SceneReplicationState::config_add_spawn(Node *p_node, MultiplayerSpawner *
ERR_FAIL_COND_V(tobj.spawner != ObjectID(), ERR_ALREADY_IN_USE);
tobj.spawner = p_spawner->get_instance_id();
spawned_nodes.insert(oid);
- // The spawner may be notified after the synchronizer.
- path_only_nodes.erase(oid);
return OK;
}
@@ -159,6 +153,9 @@ Error SceneReplicationState::config_del_spawn(Node *p_node, MultiplayerSpawner *
ERR_FAIL_COND_V(tobj.spawner != p_spawner->get_instance_id(), ERR_INVALID_PARAMETER);
tobj.spawner = ObjectID();
spawned_nodes.erase(oid);
+ for (KeyValue<int, PeerInfo> &E : peers_info) {
+ E.value.spawn_nodes.erase(oid);
+ }
return OK;
}
@@ -167,10 +164,7 @@ Error SceneReplicationState::config_add_sync(Node *p_node, MultiplayerSynchroniz
TrackedNode &tobj = _track(oid);
ERR_FAIL_COND_V(tobj.synchronizer != ObjectID(), ERR_ALREADY_IN_USE);
tobj.synchronizer = p_sync->get_instance_id();
- // If it doesn't have a spawner, we might need to assign ID for this node using it's path.
- if (tobj.spawner.is_null()) {
- path_only_nodes.insert(oid);
- }
+ synced_nodes.insert(oid);
return OK;
}
@@ -180,38 +174,57 @@ Error SceneReplicationState::config_del_sync(Node *p_node, MultiplayerSynchroniz
TrackedNode &tobj = _track(oid);
ERR_FAIL_COND_V(tobj.synchronizer != p_sync->get_instance_id(), ERR_INVALID_PARAMETER);
tobj.synchronizer = ObjectID();
- if (path_only_nodes.has(oid)) {
- p_node->disconnect(SceneStringNames::get_singleton()->tree_exited, callable_mp(this, &SceneReplicationState::_untrack));
- _untrack(oid);
- path_only_nodes.erase(oid);
+ synced_nodes.erase(oid);
+ for (KeyValue<int, PeerInfo> &E : peers_info) {
+ E.value.sync_nodes.erase(oid);
}
return OK;
}
-Error SceneReplicationState::peer_add_node(int p_peer, const ObjectID &p_id) {
- if (p_peer) {
- ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER);
- peers_info[p_peer].known_nodes.insert(p_id);
- } else {
- for (KeyValue<int, PeerInfo> &E : peers_info) {
- E.value.known_nodes.insert(p_id);
- }
- }
+Error SceneReplicationState::peer_add_sync(int p_peer, const ObjectID &p_id) {
+ ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER);
+ peers_info[p_peer].sync_nodes.insert(p_id);
return OK;
}
-Error SceneReplicationState::peer_del_node(int p_peer, const ObjectID &p_id) {
- if (p_peer) {
- ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER);
- peers_info[p_peer].known_nodes.erase(p_id);
- } else {
- for (KeyValue<int, PeerInfo> &E : peers_info) {
- E.value.known_nodes.erase(p_id);
- }
- }
+Error SceneReplicationState::peer_del_sync(int p_peer, const ObjectID &p_id) {
+ ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER);
+ peers_info[p_peer].sync_nodes.erase(p_id);
return OK;
}
+const HashSet<ObjectID> SceneReplicationState::get_peer_sync_nodes(int p_peer) {
+ ERR_FAIL_COND_V(!peers_info.has(p_peer), HashSet<ObjectID>());
+ return peers_info[p_peer].sync_nodes;
+}
+
+bool SceneReplicationState::is_peer_sync(int p_peer, const ObjectID &p_id) const {
+ ERR_FAIL_COND_V(!peers_info.has(p_peer), false);
+ return peers_info[p_peer].sync_nodes.has(p_id);
+}
+
+Error SceneReplicationState::peer_add_spawn(int p_peer, const ObjectID &p_id) {
+ ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER);
+ peers_info[p_peer].spawn_nodes.insert(p_id);
+ return OK;
+}
+
+Error SceneReplicationState::peer_del_spawn(int p_peer, const ObjectID &p_id) {
+ ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER);
+ peers_info[p_peer].spawn_nodes.erase(p_id);
+ return OK;
+}
+
+const HashSet<ObjectID> SceneReplicationState::get_peer_spawn_nodes(int p_peer) {
+ ERR_FAIL_COND_V(!peers_info.has(p_peer), HashSet<ObjectID>());
+ return peers_info[p_peer].spawn_nodes;
+}
+
+bool SceneReplicationState::is_peer_spawn(int p_peer, const ObjectID &p_id) const {
+ ERR_FAIL_COND_V(!peers_info.has(p_peer), false);
+ return peers_info[p_peer].spawn_nodes.has(p_id);
+}
+
Node *SceneReplicationState::peer_get_remote(int p_peer, uint32_t p_net_id) {
PeerInfo *info = peers_info.getptr(p_peer);
return info && info->recv_nodes.has(p_net_id) ? Object::cast_to<Node>(ObjectDB::get_instance(info->recv_nodes[p_net_id])) : nullptr;
diff --git a/scene/multiplayer/scene_replication_state.h b/scene/multiplayer/scene_replication_state.h
index 60a6c5d70c..7973b5c904 100644
--- a/scene/multiplayer/scene_replication_state.h
+++ b/scene/multiplayer/scene_replication_state.h
@@ -62,7 +62,8 @@ private:
};
struct PeerInfo {
- HashSet<ObjectID> known_nodes;
+ HashSet<ObjectID> sync_nodes;
+ HashSet<ObjectID> spawn_nodes;
HashMap<uint32_t, ObjectID> recv_nodes;
uint16_t last_sent_sync = 0;
uint16_t last_recv_sync = 0;
@@ -73,7 +74,7 @@ private:
HashMap<ObjectID, TrackedNode> tracked_nodes;
HashMap<int, PeerInfo> peers_info;
HashSet<ObjectID> spawned_nodes;
- HashSet<ObjectID> path_only_nodes;
+ HashSet<ObjectID> synced_nodes;
TrackedNode &_track(const ObjectID &p_id);
void _untrack(const ObjectID &p_id);
@@ -82,7 +83,9 @@ private:
public:
const HashSet<int> get_peers() const { return known_peers; }
const HashSet<ObjectID> &get_spawned_nodes() const { return spawned_nodes; }
- const HashSet<ObjectID> &get_path_only_nodes() const { return path_only_nodes; }
+ bool is_spawned_node(const ObjectID &p_id) const { return spawned_nodes.has(p_id); }
+ const HashSet<ObjectID> &get_synced_nodes() const { return synced_nodes; }
+ bool is_synced_node(const ObjectID &p_id) const { return synced_nodes.has(p_id); }
MultiplayerSynchronizer *get_synchronizer(const ObjectID &p_id) { return tracked_nodes.has(p_id) ? tracked_nodes[p_id].get_synchronizer() : nullptr; }
MultiplayerSpawner *get_spawner(const ObjectID &p_id) { return tracked_nodes.has(p_id) ? tracked_nodes[p_id].get_spawner() : nullptr; }
@@ -90,7 +93,6 @@ public:
bool update_last_node_sync(const ObjectID &p_id, uint16_t p_time);
bool update_sync_time(const ObjectID &p_id, uint64_t p_msec);
- const HashSet<ObjectID> get_known_nodes(int p_peer);
uint32_t get_net_id(const ObjectID &p_id) const;
void set_net_id(const ObjectID &p_id, uint32_t p_net_id);
uint32_t ensure_net_id(const ObjectID &p_id);
@@ -104,8 +106,17 @@ public:
Error config_add_sync(Node *p_node, MultiplayerSynchronizer *p_sync);
Error config_del_sync(Node *p_node, MultiplayerSynchronizer *p_sync);
- Error peer_add_node(int p_peer, const ObjectID &p_id);
- Error peer_del_node(int p_peer, const ObjectID &p_id);
+ Error peer_add_sync(int p_peer, const ObjectID &p_id);
+ Error peer_del_sync(int p_peer, const ObjectID &p_id);
+
+ const HashSet<ObjectID> get_peer_sync_nodes(int p_peer);
+ bool is_peer_sync(int p_peer, const ObjectID &p_id) const;
+
+ Error peer_add_spawn(int p_peer, const ObjectID &p_id);
+ Error peer_del_spawn(int p_peer, const ObjectID &p_id);
+
+ const HashSet<ObjectID> get_peer_spawn_nodes(int p_peer);
+ bool is_peer_spawn(int p_peer, const ObjectID &p_id) const;
const HashMap<uint32_t, ObjectID> peer_get_remotes(int p_peer) const;
Node *peer_get_remote(int p_peer, uint32_t p_net_id);
diff --git a/scene/multiplayer/scene_rpc_interface.cpp b/scene/multiplayer/scene_rpc_interface.cpp
index 84700a82f3..144a10c665 100644
--- a/scene/multiplayer/scene_rpc_interface.cpp
+++ b/scene/multiplayer/scene_rpc_interface.cpp
@@ -302,12 +302,9 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con
ERR_FAIL_MSG("Attempt to call RPC with unknown peer ID: " + itos(p_to) + ".");
}
- NodePath from_path = multiplayer->get_root_path().rel_path_to(p_from->get_path());
- ERR_FAIL_COND_MSG(from_path.is_empty(), "Unable to send RPC. Relative path is empty. THIS IS LIKELY A BUG IN THE ENGINE!");
-
// See if all peers have cached path (if so, call can be fast).
int psc_id;
- const bool has_all_peers = multiplayer->send_object_cache(p_from, from_path, p_to, psc_id);
+ const bool has_all_peers = multiplayer->send_object_cache(p_from, p_to, psc_id);
// Create base packet, lots of hardcode because it must be tight.
@@ -414,6 +411,7 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con
// Not all verified path, so send one by one.
// Append path at the end, since we will need it for some packets.
+ NodePath from_path = multiplayer->get_root_path().rel_path_to(p_from->get_path());
CharString pname = String(from_path).utf8();
int path_len = encode_cstring(pname.get_data(), nullptr);
MAKE_ROOM(ofs + path_len);
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index f70d57291f..b1ef3d0f6f 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -143,6 +143,7 @@
#include "scene/resources/animation_library.h"
#include "scene/resources/audio_stream_sample.h"
#include "scene/resources/bit_map.h"
+#include "scene/resources/bone_map.h"
#include "scene/resources/box_shape_3d.h"
#include "scene/resources/camera_effects.h"
#include "scene/resources/capsule_shape_2d.h"
@@ -158,6 +159,7 @@
#include "scene/resources/gradient.h"
#include "scene/resources/height_map_shape_3d.h"
#include "scene/resources/immediate_mesh.h"
+#include "scene/resources/label_settings.h"
#include "scene/resources/material.h"
#include "scene/resources/mesh.h"
#include "scene/resources/mesh_data_tool.h"
@@ -189,6 +191,7 @@
#include "scene/resources/skeleton_modification_3d_twoboneik.h"
#include "scene/resources/skeleton_modification_stack_2d.h"
#include "scene/resources/skeleton_modification_stack_3d.h"
+#include "scene/resources/skeleton_profile.h"
#include "scene/resources/sky.h"
#include "scene/resources/sky_material.h"
#include "scene/resources/sphere_shape_3d.h"
@@ -437,6 +440,7 @@ void register_scene_types() {
GDREGISTER_CLASS(AnimationNodeStateMachine);
GDREGISTER_CLASS(AnimationNodeStateMachinePlayback);
+ GDREGISTER_CLASS(AnimationNodeSync);
GDREGISTER_CLASS(AnimationNodeStateMachineTransition);
GDREGISTER_CLASS(AnimationNodeOutput);
GDREGISTER_CLASS(AnimationNodeOneShot);
@@ -851,10 +855,15 @@ void register_scene_types() {
GDREGISTER_CLASS(Animation);
GDREGISTER_CLASS(AnimationLibrary);
- GDREGISTER_CLASS(FontData);
- GDREGISTER_CLASS(Font);
+
+ GDREGISTER_ABSTRACT_CLASS(Font);
+ GDREGISTER_CLASS(FontFile);
+ GDREGISTER_CLASS(FontVariation);
+
GDREGISTER_CLASS(Curve);
+ GDREGISTER_CLASS(LabelSettings);
+
GDREGISTER_CLASS(SceneReplicationConfig);
GDREGISTER_CLASS(TextLine);
@@ -871,6 +880,10 @@ void register_scene_types() {
GDREGISTER_CLASS(BitMap);
GDREGISTER_CLASS(Gradient);
+ GDREGISTER_CLASS(SkeletonProfile);
+ GDREGISTER_CLASS(SkeletonProfileHumanoid);
+ GDREGISTER_CLASS(BoneMap);
+
OS::get_singleton()->yield(); // may take time to init
GDREGISTER_CLASS(AudioStreamPlayer);
@@ -915,9 +928,9 @@ void register_scene_types() {
ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree");
ClassDB::add_compatibility_class("BakedLightmap", "LightmapGI");
ClassDB::add_compatibility_class("BakedLightmapData", "LightmapGIData");
- ClassDB::add_compatibility_class("BitmapFont", "Font");
- ClassDB::add_compatibility_class("DynamicFont", "Font");
- ClassDB::add_compatibility_class("DynamicFontData", "FontData");
+ ClassDB::add_compatibility_class("BitmapFont", "FontFile");
+ ClassDB::add_compatibility_class("DynamicFont", "FontFile");
+ ClassDB::add_compatibility_class("DynamicFontData", "FontFile");
ClassDB::add_compatibility_class("Navigation3D", "Node3D");
ClassDB::add_compatibility_class("Navigation2D", "Node2D");
ClassDB::add_compatibility_class("OpenSimplexNoise", "FastNoiseLite");
@@ -1107,7 +1120,7 @@ void initialize_theme() {
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
String font_path = GLOBAL_DEF_RST("gui/theme/custom_font", "");
- ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
bool font_antialiased = (bool)GLOBAL_DEF_RST("gui/theme/default_font_antialiased", true);
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_antialiased", PropertyInfo(Variant::BOOL, "gui/theme/default_font_antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
diff --git a/scene/resources/bone_map.cpp b/scene/resources/bone_map.cpp
new file mode 100644
index 0000000000..aff917b2d4
--- /dev/null
+++ b/scene/resources/bone_map.cpp
@@ -0,0 +1,181 @@
+/*************************************************************************/
+/* bone_map.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "bone_map.h"
+
+bool BoneMap::_set(const StringName &p_path, const Variant &p_value) {
+ String path = p_path;
+ if (path.begins_with("bone_map/")) {
+ String which = path.get_slicec('/', 1);
+ set_skeleton_bone_name(which, p_value);
+ return true;
+ }
+ return true;
+}
+
+bool BoneMap::_get(const StringName &p_path, Variant &r_ret) const {
+ String path = p_path;
+ if (path.begins_with("bone_map/")) {
+ String which = path.get_slicec('/', 1);
+ r_ret = get_skeleton_bone_name(which);
+ return true;
+ }
+ return true;
+}
+
+void BoneMap::_get_property_list(List<PropertyInfo> *p_list) const {
+ HashMap<StringName, StringName>::ConstIterator E = bone_map.begin();
+ while (E) {
+ p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bone_map/" + E->key, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+ ++E;
+ }
+}
+
+Ref<SkeletonProfile> BoneMap::get_profile() const {
+ return profile;
+}
+
+void BoneMap::set_profile(const Ref<SkeletonProfile> &p_profile) {
+ bool is_changed = profile != p_profile;
+ if (is_changed) {
+ if (!profile.is_null() && profile->is_connected("profile_updated", callable_mp(this, &BoneMap::_update_profile))) {
+ profile->disconnect("profile_updated", callable_mp(this, &BoneMap::_update_profile));
+ }
+ profile = p_profile;
+ if (!profile.is_null()) {
+ profile->connect("profile_updated", callable_mp(this, &BoneMap::_update_profile));
+ }
+ _update_profile();
+ }
+ notify_property_list_changed();
+}
+
+StringName BoneMap::get_skeleton_bone_name(StringName p_profile_bone_name) const {
+ ERR_FAIL_COND_V(!bone_map.has(p_profile_bone_name), StringName());
+ return bone_map.get(p_profile_bone_name);
+}
+
+void BoneMap::set_skeleton_bone_name(StringName p_profile_bone_name, const StringName p_skeleton_bone_name) {
+ ERR_FAIL_COND(!bone_map.has(p_profile_bone_name));
+ bone_map.insert(p_profile_bone_name, p_skeleton_bone_name);
+ emit_signal("bone_map_updated");
+}
+
+StringName BoneMap::find_profile_bone_name(StringName p_skeleton_bone_name) const {
+ StringName profile_bone_name = StringName();
+ HashMap<StringName, StringName>::ConstIterator E = bone_map.begin();
+ while (E) {
+ if (E->value == p_skeleton_bone_name) {
+ profile_bone_name = E->key;
+ break;
+ }
+ ++E;
+ }
+ return profile_bone_name;
+}
+
+int BoneMap::get_skeleton_bone_name_count(const StringName p_skeleton_bone_name) const {
+ int count = 0;
+ HashMap<StringName, StringName>::ConstIterator E = bone_map.begin();
+ while (E) {
+ if (E->value == p_skeleton_bone_name) {
+ ++count;
+ }
+ ++E;
+ }
+ return count;
+}
+
+void BoneMap::_update_profile() {
+ _validate_bone_map();
+ emit_signal("profile_updated");
+}
+
+void BoneMap::_validate_bone_map() {
+ Ref<SkeletonProfile> current_profile = get_profile();
+ if (current_profile.is_valid()) {
+ // Insert missing profile bones into bone map.
+ int len = current_profile->get_bone_size();
+ StringName profile_bone_name;
+ for (int i = 0; i < len; i++) {
+ profile_bone_name = current_profile->get_bone_name(i);
+ if (!bone_map.has(profile_bone_name)) {
+ bone_map.insert(profile_bone_name, StringName());
+ }
+ }
+ // Remove bones that do not exist in the profile from the map.
+ Vector<StringName> delete_bones;
+ StringName k;
+ HashMap<StringName, StringName>::ConstIterator E = bone_map.begin();
+ while (E) {
+ k = E->key;
+ if (!current_profile->has_bone(k)) {
+ delete_bones.push_back(k);
+ }
+ ++E;
+ }
+ len = delete_bones.size();
+ for (int i = 0; i < len; i++) {
+ bone_map.erase(delete_bones[i]);
+ }
+ } else {
+ bone_map.clear();
+ }
+ emit_signal("retarget_option_updated");
+}
+
+void BoneMap::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_profile"), &BoneMap::get_profile);
+ ClassDB::bind_method(D_METHOD("set_profile", "profile"), &BoneMap::set_profile);
+
+ ClassDB::bind_method(D_METHOD("get_skeleton_bone_name", "profile_bone_name"), &BoneMap::get_skeleton_bone_name);
+ ClassDB::bind_method(D_METHOD("set_skeleton_bone_name", "profile_bone_name", "skeleton_bone_name"), &BoneMap::set_skeleton_bone_name);
+
+ ClassDB::bind_method(D_METHOD("find_profile_bone_name", "skeleton_bone_name"), &BoneMap::find_profile_bone_name);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "profile", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonProfile"), "set_profile", "get_profile");
+ ADD_ARRAY("bonemap", "bonemap");
+
+ ADD_SIGNAL(MethodInfo("bone_map_updated"));
+ ADD_SIGNAL(MethodInfo("profile_updated"));
+}
+
+void BoneMap::_validate_property(PropertyInfo &property) const {
+ //
+}
+
+BoneMap::BoneMap() {
+ _validate_bone_map();
+}
+
+BoneMap::~BoneMap() {
+}
+
+//////////////////////////////////////
diff --git a/scene/resources/bone_map.h b/scene/resources/bone_map.h
new file mode 100644
index 0000000000..17452dfc73
--- /dev/null
+++ b/scene/resources/bone_map.h
@@ -0,0 +1,70 @@
+/*************************************************************************/
+/* bone_map.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef BONE_MAP_H
+#define BONE_MAP_H
+
+#include "skeleton_profile.h"
+
+class BoneMap : public Resource {
+ GDCLASS(BoneMap, Resource);
+
+ Ref<SkeletonProfile> profile;
+ HashMap<StringName, StringName> bone_map;
+
+ void _update_profile();
+ void _validate_bone_map();
+
+protected:
+ bool _get(const StringName &p_path, Variant &r_ret) const;
+ bool _set(const StringName &p_path, const Variant &p_value);
+ virtual void _validate_property(PropertyInfo &property) const override;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+ static void _bind_methods();
+
+public:
+ int get_profile_type() const;
+ void set_profile_type(const int p_profile_type);
+
+ Ref<SkeletonProfile> get_profile() const;
+ void set_profile(const Ref<SkeletonProfile> &p_profile);
+
+ int get_skeleton_bone_name_count(const StringName p_skeleton_bone_name) const;
+
+ StringName get_skeleton_bone_name(StringName p_profile_bone_name) const;
+ void set_skeleton_bone_name(StringName p_profile_bone_name, const StringName p_skeleton_bone_name);
+
+ StringName find_profile_bone_name(StringName p_skeleton_bone_name) const;
+
+ BoneMap();
+ ~BoneMap();
+};
+
+#endif // BONE_MAP_H
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 401aeb4889..520a0a04ed 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -76,7 +76,6 @@ static Ref<StyleBoxFlat> sb_expand(Ref<StyleBoxFlat> p_sbox, float p_left, float
// See also `editor_generate_icon()` in `editor/editor_themes.cpp`.
static Ref<ImageTexture> generate_icon(int p_index) {
- Ref<ImageTexture> icon = memnew(ImageTexture);
Ref<Image> img = memnew(Image);
#ifdef MODULE_SVG_ENABLED
@@ -87,9 +86,8 @@ static Ref<ImageTexture> generate_icon(int p_index) {
ImageLoaderSVG img_loader;
img_loader.create_image_from_string(img, default_theme_icons_sources[p_index], scale, upsample, false);
#endif
- icon->create_from_image(img);
- return icon;
+ return ImageTexture::create_from_image(img);
}
static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
@@ -467,6 +465,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("completion_selected_color", "CodeEdit", Color(0.26, 0.26, 0.27));
theme->set_color("completion_existing_color", "CodeEdit", Color(0.87, 0.87, 0.87, 0.13));
theme->set_color("completion_scroll_color", "CodeEdit", control_font_pressed_color * Color(1, 1, 1, 0.29));
+ theme->set_color("completion_scroll_hovered_color", "CodeEdit", control_font_pressed_color * Color(1, 1, 1, 0.4));
theme->set_color("completion_font_color", "CodeEdit", Color(0.67, 0.67, 0.67));
theme->set_color("font_color", "CodeEdit", control_font_color);
theme->set_color("font_selected_color", "CodeEdit", Color(0, 0, 0));
@@ -917,8 +916,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("panel", "TooltipPanel",
make_flat_stylebox(Color(0, 0, 0, 0.5), 2 * default_margin, 0.5 * default_margin, 2 * default_margin, 0.5 * default_margin));
- theme->set_font("font", "TooltipLabel", Ref<Font>());
theme->set_font_size("font_size", "TooltipLabel", -1);
+ theme->set_font("font", "TooltipLabel", Ref<Font>());
theme->set_color("font_color", "TooltipLabel", control_font_color);
theme->set_color("font_shadow_color", "TooltipLabel", Color(0, 0, 0, 0));
@@ -938,7 +937,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font("italics_font", "RichTextLabel", italics_font);
theme->set_font("bold_italics_font", "RichTextLabel", bold_italics_font);
theme->set_font("mono_font", "RichTextLabel", Ref<Font>());
-
theme->set_font_size("normal_font_size", "RichTextLabel", -1);
theme->set_font_size("bold_font_size", "RichTextLabel", -1);
theme->set_font_size("italics_font_size", "RichTextLabel", -1);
@@ -1033,9 +1031,9 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos
Ref<StyleBox> default_style;
Ref<Texture2D> default_icon;
Ref<Font> default_font;
- Ref<Font> bold_font;
- Ref<Font> bold_italics_font;
- Ref<Font> italics_font;
+ Ref<FontVariation> bold_font;
+ Ref<FontVariation> bold_italics_font;
+ Ref<FontVariation> italics_font;
float default_scale = CLAMP(p_scale, 0.5, 8.0);
if (p_font.is_valid()) {
@@ -1045,48 +1043,31 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos
// Use the default DynamicFont (separate from the editor font).
// The default DynamicFont is chosen to have a small file size since it's
// embedded in both editor and export template binaries.
- Ref<Font> dynamic_font;
+ Ref<FontFile> dynamic_font;
dynamic_font.instantiate();
-
- Ref<FontData> dynamic_font_data;
- dynamic_font_data.instantiate();
- dynamic_font_data->set_data_ptr(_font_OpenSans_SemiBold, _font_OpenSans_SemiBold_size);
- dynamic_font_data->set_subpixel_positioning(p_font_subpixel);
- dynamic_font_data->set_hinting(p_font_hinting);
- dynamic_font_data->set_antialiased(p_font_antialiased);
- dynamic_font_data->set_multichannel_signed_distance_field(p_font_msdf);
- dynamic_font_data->set_generate_mipmaps(p_font_generate_mipmaps);
-
- dynamic_font->add_data(dynamic_font_data);
+ dynamic_font->set_data_ptr(_font_OpenSans_SemiBold, _font_OpenSans_SemiBold_size);
+ dynamic_font->set_subpixel_positioning(p_font_subpixel);
+ dynamic_font->set_hinting(p_font_hinting);
+ dynamic_font->set_antialiased(p_font_antialiased);
+ dynamic_font->set_multichannel_signed_distance_field(p_font_msdf);
+ dynamic_font->set_generate_mipmaps(p_font_generate_mipmaps);
default_font = dynamic_font;
}
if (default_font.is_valid()) {
bold_font.instantiate();
- for (int i = 0; i < default_font->get_data_count(); i++) {
- Ref<FontData> data = default_font->get_data(i)->duplicate();
- // Try to match OpenSans ExtraBold.
- data->set_embolden(1.2);
- bold_font->add_data(data);
- }
+ bold_font->set_base_font(default_font);
+ bold_font->set_variation_embolden(1.2);
bold_italics_font.instantiate();
- for (int i = 0; i < default_font->get_data_count(); i++) {
- Ref<FontData> data = default_font->get_data(i)->duplicate();
- // Try to match OpenSans ExtraBold Italic.
- data->set_embolden(1.2);
- data->set_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
- bold_italics_font->add_data(data);
- }
+ bold_italics_font->set_base_font(default_font);
+ bold_italics_font->set_variation_embolden(1.2);
+ bold_italics_font->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
italics_font.instantiate();
- for (int i = 0; i < default_font->get_data_count(); i++) {
- Ref<FontData> data = default_font->get_data(i)->duplicate();
- // Try to match OpenSans Italic.
- data->set_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
- italics_font->add_data(data);
- }
+ italics_font->set_base_font(default_font);
+ italics_font->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
}
fill_default_theme(t, default_font, bold_font, bold_italics_font, italics_font, default_icon, default_style, default_scale);
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 46f23424dd..f61ac7fcaa 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -30,6 +30,7 @@
#include "font.h"
+#include "core/core_string_names.h"
#include "core/io/image_loader.h"
#include "core/io/resource_loader.h"
#include "core/string/translation.h"
@@ -37,439 +38,558 @@
#include "core/templates/hashfuncs.h"
#include "scene/resources/text_line.h"
#include "scene/resources/text_paragraph.h"
+#include "scene/resources/theme.h"
-_FORCE_INLINE_ void FontData::_clear_cache() {
- for (int i = 0; i < cache.size(); i++) {
- if (cache[i].is_valid()) {
- TS->free_rid(cache[i]);
- cache.write[i] = RID();
- }
- }
-}
+/*************************************************************************/
+/* Font */
+/*************************************************************************/
-_FORCE_INLINE_ void FontData::_ensure_rid(int p_cache_index) const {
- if (unlikely(p_cache_index >= cache.size())) {
- cache.resize(p_cache_index + 1);
- }
- if (unlikely(!cache[p_cache_index].is_valid())) {
- cache.write[p_cache_index] = TS->create_font();
- TS->font_set_data_ptr(cache[p_cache_index], data_ptr, data_size);
- TS->font_set_face_index(cache[p_cache_index], face_index);
- TS->font_set_antialiased(cache[p_cache_index], antialiased);
- TS->font_set_generate_mipmaps(cache[p_cache_index], mipmaps);
- TS->font_set_multichannel_signed_distance_field(cache[p_cache_index], msdf);
- TS->font_set_msdf_pixel_range(cache[p_cache_index], msdf_pixel_range);
- TS->font_set_msdf_size(cache[p_cache_index], msdf_size);
- TS->font_set_fixed_size(cache[p_cache_index], fixed_size);
- TS->font_set_force_autohinter(cache[p_cache_index], force_autohinter);
- TS->font_set_hinting(cache[p_cache_index], hinting);
- TS->font_set_subpixel_positioning(cache[p_cache_index], subpixel_positioning);
- TS->font_set_embolden(cache[p_cache_index], embolden);
- TS->font_set_transform(cache[p_cache_index], transform);
- TS->font_set_oversampling(cache[p_cache_index], oversampling);
- }
-}
+void Font::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_fallbacks", "fallbacks"), &Font::set_fallbacks);
+ ClassDB::bind_method(D_METHOD("get_fallbacks"), &Font::get_fallbacks);
-void FontData::_bind_methods() {
- ClassDB::bind_method(D_METHOD("load_bitmap_font", "path"), &FontData::load_bitmap_font);
- ClassDB::bind_method(D_METHOD("load_dynamic_font", "path"), &FontData::load_dynamic_font);
+ // Output.
+ ClassDB::bind_method(D_METHOD("find_variation", "variation_coordinates", "face_index", "strength", "transform"), &Font::find_variation, DEFVAL(0), DEFVAL(0.0), DEFVAL(Transform2D()));
+ ClassDB::bind_method(D_METHOD("get_rids"), &Font::get_rids);
- ClassDB::bind_method(D_METHOD("set_data", "data"), &FontData::set_data);
- ClassDB::bind_method(D_METHOD("get_data"), &FontData::get_data);
+ // Font metrics.
+ ClassDB::bind_method(D_METHOD("get_height", "font_size"), &Font::get_height, DEFVAL(DEFAULT_FONT_SIZE));
+ ClassDB::bind_method(D_METHOD("get_ascent", "font_size"), &Font::get_ascent, DEFVAL(DEFAULT_FONT_SIZE));
+ ClassDB::bind_method(D_METHOD("get_descent", "font_size"), &Font::get_descent, DEFVAL(DEFAULT_FONT_SIZE));
+ ClassDB::bind_method(D_METHOD("get_underline_position", "font_size"), &Font::get_underline_position, DEFVAL(DEFAULT_FONT_SIZE));
+ ClassDB::bind_method(D_METHOD("get_underline_thickness", "font_size"), &Font::get_underline_thickness, DEFVAL(DEFAULT_FONT_SIZE));
- ClassDB::bind_method(D_METHOD("set_face_index", "face_index"), &FontData::set_face_index);
- ClassDB::bind_method(D_METHOD("get_face_index"), &FontData::get_face_index);
+ ClassDB::bind_method(D_METHOD("get_font_name"), &Font::get_font_name);
+ ClassDB::bind_method(D_METHOD("get_font_style_name"), &Font::get_font_style_name);
+ ClassDB::bind_method(D_METHOD("get_font_style"), &Font::get_font_style);
- ClassDB::bind_method(D_METHOD("get_face_count"), &FontData::get_face_count);
+ ClassDB::bind_method(D_METHOD("get_spacing", "spacing"), &Font::get_spacing);
+ ClassDB::bind_method(D_METHOD("get_opentype_features"), &Font::get_opentype_features);
- ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &FontData::set_antialiased);
- ClassDB::bind_method(D_METHOD("is_antialiased"), &FontData::is_antialiased);
+ // Drawing string.
+ ClassDB::bind_method(D_METHOD("set_cache_capacity", "single_line", "multi_line"), &Font::set_cache_capacity);
- ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &FontData::set_generate_mipmaps);
- ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &FontData::get_generate_mipmaps);
+ ClassDB::bind_method(D_METHOD("get_string_size", "text", "alignment", "width", "font_size", "jst_flags", "direction", "orientation"), &Font::get_string_size, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
+ ClassDB::bind_method(D_METHOD("get_multiline_string_size", "text", "alignment", "width", "font_size", "max_lines", "brk_flags", "jst_flags", "direction", "orientation"), &Font::get_multiline_string_size, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
- ClassDB::bind_method(D_METHOD("set_font_name", "name"), &FontData::set_font_name);
- ClassDB::bind_method(D_METHOD("get_font_name"), &FontData::get_font_name);
+ ClassDB::bind_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "modulate", "jst_flags", "direction", "orientation"), &Font::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
+ ClassDB::bind_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "brk_flags", "jst_flags", "direction", "orientation"), &Font::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
- ClassDB::bind_method(D_METHOD("set_font_style_name", "name"), &FontData::set_font_style_name);
- ClassDB::bind_method(D_METHOD("get_font_style_name"), &FontData::get_font_style_name);
+ ClassDB::bind_method(D_METHOD("draw_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "jst_flags", "direction", "orientation"), &Font::draw_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
+ ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "jst_flags", "direction", "orientation"), &Font::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
- ClassDB::bind_method(D_METHOD("set_font_style", "style"), &FontData::set_font_style);
- ClassDB::bind_method(D_METHOD("get_font_style"), &FontData::get_font_style);
+ // Drawing char.
+ ClassDB::bind_method(D_METHOD("get_char_size", "char"), &Font::get_char_size);
+ ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "modulate"), &Font::draw_char, DEFVAL(Color(1.0, 1.0, 1.0)));
+ ClassDB::bind_method(D_METHOD("draw_char_outline", "canvas_item", "pos", "char", "size", "modulate"), &Font::draw_char_outline, DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)));
- ClassDB::bind_method(D_METHOD("set_multichannel_signed_distance_field", "msdf"), &FontData::set_multichannel_signed_distance_field);
- ClassDB::bind_method(D_METHOD("is_multichannel_signed_distance_field"), &FontData::is_multichannel_signed_distance_field);
+ // Helper functions.
+ ClassDB::bind_method(D_METHOD("has_char", "char"), &Font::has_char);
+ ClassDB::bind_method(D_METHOD("get_supported_chars"), &Font::get_supported_chars);
- ClassDB::bind_method(D_METHOD("set_msdf_pixel_range", "msdf_pixel_range"), &FontData::set_msdf_pixel_range);
- ClassDB::bind_method(D_METHOD("get_msdf_pixel_range"), &FontData::get_msdf_pixel_range);
+ ClassDB::bind_method(D_METHOD("is_language_supported", "language"), &Font::is_language_supported);
+ ClassDB::bind_method(D_METHOD("is_script_supported", "script"), &Font::is_script_supported);
- ClassDB::bind_method(D_METHOD("set_msdf_size", "msdf_size"), &FontData::set_msdf_size);
- ClassDB::bind_method(D_METHOD("get_msdf_size"), &FontData::get_msdf_size);
+ ClassDB::bind_method(D_METHOD("get_supported_feature_list"), &Font::get_supported_feature_list);
+ ClassDB::bind_method(D_METHOD("get_supported_variation_list"), &Font::get_supported_variation_list);
+ ClassDB::bind_method(D_METHOD("get_face_count"), &Font::get_face_count);
+}
- ClassDB::bind_method(D_METHOD("set_fixed_size", "fixed_size"), &FontData::set_fixed_size);
- ClassDB::bind_method(D_METHOD("get_fixed_size"), &FontData::get_fixed_size);
+void Font::_update_rids_fb(const Ref<Font> &p_f, int p_depth) const {
+ ERR_FAIL_COND(p_depth > MAX_FALLBACK_DEPTH);
+ if (p_f.is_valid()) {
+ RID rid = p_f->_get_rid();
+ if (rid.is_valid()) {
+ rids.push_back(rid);
+ }
+ const TypedArray<Font> &_fallbacks = p_f->get_fallbacks();
+ for (int i = 0; i < _fallbacks.size(); i++) {
+ _update_rids_fb(_fallbacks[i], p_depth + 1);
+ }
+ }
+}
- ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &FontData::set_force_autohinter);
- ClassDB::bind_method(D_METHOD("is_force_autohinter"), &FontData::is_force_autohinter);
+void Font::_update_rids() const {
+ rids.clear();
+ _update_rids_fb(const_cast<Font *>(this), 0);
+ dirty_rids = false;
+}
- ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &FontData::set_hinting);
- ClassDB::bind_method(D_METHOD("get_hinting"), &FontData::get_hinting);
+void Font::_invalidate_rids() {
+ rids.clear();
+ dirty_rids = true;
- ClassDB::bind_method(D_METHOD("set_subpixel_positioning", "subpixel_positioning"), &FontData::set_subpixel_positioning);
- ClassDB::bind_method(D_METHOD("get_subpixel_positioning"), &FontData::get_subpixel_positioning);
+ cache.clear();
+ cache_wrap.clear();
- ClassDB::bind_method(D_METHOD("set_embolden", "strength"), &FontData::set_embolden);
- ClassDB::bind_method(D_METHOD("get_embolden"), &FontData::get_embolden);
+ emit_changed();
+}
- ClassDB::bind_method(D_METHOD("set_transform", "transform"), &FontData::set_transform);
- ClassDB::bind_method(D_METHOD("get_transform"), &FontData::get_transform);
+bool Font::_is_cyclic(const Ref<Font> &p_f, int p_depth) const {
+ ERR_FAIL_COND_V(p_depth > MAX_FALLBACK_DEPTH, false);
+ if (p_f.is_null()) {
+ return false;
+ }
+ for (int i = 0; i < p_f->fallbacks.size(); i++) {
+ const Ref<Font> &f = p_f->fallbacks[i];
+ if (f == this) {
+ return true;
+ }
+ return _is_cyclic(f, p_depth + 1);
+ }
+ return false;
+}
- ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &FontData::set_oversampling);
- ClassDB::bind_method(D_METHOD("get_oversampling"), &FontData::get_oversampling);
+void Font::reset_state() {
+ _invalidate_rids();
+}
- ClassDB::bind_method(D_METHOD("find_cache", "variation_coordinates"), &FontData::find_cache);
+// Fallbacks.
+void Font::set_fallbacks(const TypedArray<Font> &p_fallbacks) {
+ ERR_FAIL_COND(_is_cyclic(this, 0));
+ for (int i = 0; i < fallbacks.size(); i++) {
+ Ref<Font> f = fallbacks[i];
+ if (f.is_valid()) {
+ f->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Font::_invalidate_rids));
+ }
+ }
+ fallbacks = p_fallbacks;
+ for (int i = 0; i < fallbacks.size(); i++) {
+ Ref<Font> f = fallbacks[i];
+ if (f.is_valid()) {
+ f->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED);
+ }
+ }
+ _invalidate_rids();
+}
- ClassDB::bind_method(D_METHOD("get_cache_count"), &FontData::get_cache_count);
- ClassDB::bind_method(D_METHOD("clear_cache"), &FontData::clear_cache);
- ClassDB::bind_method(D_METHOD("remove_cache", "cache_index"), &FontData::remove_cache);
+TypedArray<Font> Font::get_fallbacks() const {
+ return fallbacks;
+}
- ClassDB::bind_method(D_METHOD("get_size_cache_list", "cache_index"), &FontData::get_size_cache_list);
- ClassDB::bind_method(D_METHOD("clear_size_cache", "cache_index"), &FontData::clear_size_cache);
- ClassDB::bind_method(D_METHOD("remove_size_cache", "cache_index", "size"), &FontData::remove_size_cache);
+// Output.
+TypedArray<RID> Font::get_rids() const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ return rids;
+}
- ClassDB::bind_method(D_METHOD("set_variation_coordinates", "cache_index", "variation_coordinates"), &FontData::set_variation_coordinates);
- ClassDB::bind_method(D_METHOD("get_variation_coordinates", "cache_index"), &FontData::get_variation_coordinates);
+// Drawing string.
+real_t Font::get_height(int p_font_size) const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ real_t ret = 0.f;
+ for (int i = 0; i < rids.size(); i++) {
+ ret = MAX(ret, TS->font_get_ascent(rids[i], p_font_size) + TS->font_get_descent(rids[i], p_font_size));
+ }
+ return ret + get_spacing(TextServer::SPACING_BOTTOM) + get_spacing(TextServer::SPACING_TOP);
+}
- ClassDB::bind_method(D_METHOD("set_ascent", "cache_index", "size", "ascent"), &FontData::set_ascent);
- ClassDB::bind_method(D_METHOD("get_ascent", "cache_index", "size"), &FontData::get_ascent);
+real_t Font::get_ascent(int p_font_size) const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ real_t ret = 0.f;
+ for (int i = 0; i < rids.size(); i++) {
+ ret = MAX(ret, TS->font_get_ascent(rids[i], p_font_size));
+ }
+ return ret + get_spacing(TextServer::SPACING_TOP);
+}
- ClassDB::bind_method(D_METHOD("set_descent", "cache_index", "size", "descent"), &FontData::set_descent);
- ClassDB::bind_method(D_METHOD("get_descent", "cache_index", "size"), &FontData::get_descent);
+real_t Font::get_descent(int p_font_size) const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ real_t ret = 0.f;
+ for (int i = 0; i < rids.size(); i++) {
+ ret = MAX(ret, TS->font_get_descent(rids[i], p_font_size));
+ }
+ return ret + get_spacing(TextServer::SPACING_BOTTOM);
+}
- ClassDB::bind_method(D_METHOD("set_underline_position", "cache_index", "size", "underline_position"), &FontData::set_underline_position);
- ClassDB::bind_method(D_METHOD("get_underline_position", "cache_index", "size"), &FontData::get_underline_position);
+real_t Font::get_underline_position(int p_font_size) const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ real_t ret = 0.f;
+ for (int i = 0; i < rids.size(); i++) {
+ ret = MAX(ret, TS->font_get_underline_position(rids[i], p_font_size));
+ }
+ return ret + get_spacing(TextServer::SPACING_TOP);
+}
- ClassDB::bind_method(D_METHOD("set_underline_thickness", "cache_index", "size", "underline_thickness"), &FontData::set_underline_thickness);
- ClassDB::bind_method(D_METHOD("get_underline_thickness", "cache_index", "size"), &FontData::get_underline_thickness);
+real_t Font::get_underline_thickness(int p_font_size) const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ real_t ret = 0.f;
+ for (int i = 0; i < rids.size(); i++) {
+ ret = MAX(ret, TS->font_get_underline_thickness(rids[i], p_font_size));
+ }
+ return ret;
+}
- ClassDB::bind_method(D_METHOD("set_scale", "cache_index", "size", "scale"), &FontData::set_scale);
- ClassDB::bind_method(D_METHOD("get_scale", "cache_index", "size"), &FontData::get_scale);
+String Font::get_font_name() const {
+ return TS->font_get_name(_get_rid());
+}
- ClassDB::bind_method(D_METHOD("set_spacing", "cache_index", "size", "spacing_type", "value"), &FontData::set_spacing);
- ClassDB::bind_method(D_METHOD("get_spacing", "cache_index", "size", "spacing_type"), &FontData::get_spacing);
+String Font::get_font_style_name() const {
+ return TS->font_get_style_name(_get_rid());
+}
- ClassDB::bind_method(D_METHOD("get_texture_count", "cache_index", "size"), &FontData::get_texture_count);
- ClassDB::bind_method(D_METHOD("clear_textures", "cache_index", "size"), &FontData::clear_textures);
- ClassDB::bind_method(D_METHOD("remove_texture", "cache_index", "size", "texture_index"), &FontData::remove_texture);
+BitField<TextServer::FontStyle> Font::get_font_style() const {
+ return TS->font_get_style(_get_rid());
+}
- ClassDB::bind_method(D_METHOD("set_texture_image", "cache_index", "size", "texture_index", "image"), &FontData::set_texture_image);
- ClassDB::bind_method(D_METHOD("get_texture_image", "cache_index", "size", "texture_index"), &FontData::get_texture_image);
+Dictionary Font::get_opentype_features() const {
+ return Dictionary();
+}
- ClassDB::bind_method(D_METHOD("set_texture_offsets", "cache_index", "size", "texture_index", "offset"), &FontData::set_texture_offsets);
- ClassDB::bind_method(D_METHOD("get_texture_offsets", "cache_index", "size", "texture_index"), &FontData::get_texture_offsets);
+// Drawing string.
+void Font::set_cache_capacity(int p_single_line, int p_multi_line) {
+ cache.set_capacity(p_single_line);
+ cache_wrap.set_capacity(p_multi_line);
+}
- ClassDB::bind_method(D_METHOD("get_glyph_list", "cache_index", "size"), &FontData::get_glyph_list);
- ClassDB::bind_method(D_METHOD("clear_glyphs", "cache_index", "size"), &FontData::clear_glyphs);
- ClassDB::bind_method(D_METHOD("remove_glyph", "cache_index", "size", "glyph"), &FontData::remove_glyph);
+Size2 Font::get_string_size(const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
+ uint64_t hash = p_text.hash64();
+ hash = hash_djb2_one_64(p_font_size, hash);
+ if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
+ hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
+ }
+ hash = hash_djb2_one_64(p_direction, hash);
+ hash = hash_djb2_one_64(p_orientation, hash);
- ClassDB::bind_method(D_METHOD("set_glyph_advance", "cache_index", "size", "glyph", "advance"), &FontData::set_glyph_advance);
- ClassDB::bind_method(D_METHOD("get_glyph_advance", "cache_index", "size", "glyph"), &FontData::get_glyph_advance);
+ Ref<TextLine> buffer;
+ if (cache.has(hash)) {
+ buffer = cache.get(hash);
+ } else {
+ buffer.instantiate();
+ buffer->set_direction(p_direction);
+ buffer->set_orientation(p_orientation);
+ buffer->add_string(p_text, Ref<Font>(this), p_font_size);
+ if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ buffer->set_horizontal_alignment(p_alignment);
+ buffer->set_width(p_width);
+ buffer->set_flags(p_jst_flags);
+ }
+ cache.insert(hash, buffer);
+ }
+ return buffer->get_size();
+}
- ClassDB::bind_method(D_METHOD("set_glyph_offset", "cache_index", "size", "glyph", "offset"), &FontData::set_glyph_offset);
- ClassDB::bind_method(D_METHOD("get_glyph_offset", "cache_index", "size", "glyph"), &FontData::get_glyph_offset);
+Size2 Font::get_multiline_string_size(const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
+ uint64_t hash = p_text.hash64();
+ hash = hash_djb2_one_64(p_font_size, hash);
+ hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
+ hash = hash_djb2_one_64(p_brk_flags.operator uint32_t(), hash);
+ hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
+ hash = hash_djb2_one_64(p_direction, hash);
+ hash = hash_djb2_one_64(p_orientation, hash);
- ClassDB::bind_method(D_METHOD("set_glyph_size", "cache_index", "size", "glyph", "gl_size"), &FontData::set_glyph_size);
- ClassDB::bind_method(D_METHOD("get_glyph_size", "cache_index", "size", "glyph"), &FontData::get_glyph_size);
+ Ref<TextParagraph> lines_buffer;
+ if (cache_wrap.has(hash)) {
+ lines_buffer = cache_wrap.get(hash);
+ } else {
+ lines_buffer.instantiate();
+ lines_buffer->set_direction(p_direction);
+ lines_buffer->set_orientation(p_orientation);
+ lines_buffer->add_string(p_text, Ref<Font>(this), p_font_size);
+ lines_buffer->set_width(p_width);
+ lines_buffer->set_break_flags(p_brk_flags);
+ lines_buffer->set_justification_flags(p_jst_flags);
+ cache_wrap.insert(hash, lines_buffer);
+ }
- ClassDB::bind_method(D_METHOD("set_glyph_uv_rect", "cache_index", "size", "glyph", "uv_rect"), &FontData::set_glyph_uv_rect);
- ClassDB::bind_method(D_METHOD("get_glyph_uv_rect", "cache_index", "size", "glyph"), &FontData::get_glyph_uv_rect);
+ lines_buffer->set_alignment(p_alignment);
+ lines_buffer->set_max_lines_visible(p_max_lines);
- ClassDB::bind_method(D_METHOD("set_glyph_texture_idx", "cache_index", "size", "glyph", "texture_idx"), &FontData::set_glyph_texture_idx);
- ClassDB::bind_method(D_METHOD("get_glyph_texture_idx", "cache_index", "size", "glyph"), &FontData::get_glyph_texture_idx);
+ return lines_buffer->get_size();
+}
- ClassDB::bind_method(D_METHOD("get_kerning_list", "cache_index", "size"), &FontData::get_kerning_list);
- ClassDB::bind_method(D_METHOD("clear_kerning_map", "cache_index", "size"), &FontData::clear_kerning_map);
- ClassDB::bind_method(D_METHOD("remove_kerning", "cache_index", "size", "glyph_pair"), &FontData::remove_kerning);
+void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
+ uint64_t hash = p_text.hash64();
+ hash = hash_djb2_one_64(p_font_size, hash);
+ if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
+ hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
+ }
+ hash = hash_djb2_one_64(p_direction, hash);
+ hash = hash_djb2_one_64(p_orientation, hash);
- ClassDB::bind_method(D_METHOD("set_kerning", "cache_index", "size", "glyph_pair", "kerning"), &FontData::set_kerning);
- ClassDB::bind_method(D_METHOD("get_kerning", "cache_index", "size", "glyph_pair"), &FontData::get_kerning);
+ Ref<TextLine> buffer;
+ if (cache.has(hash)) {
+ buffer = cache.get(hash);
+ } else {
+ buffer.instantiate();
+ buffer->set_direction(p_direction);
+ buffer->set_orientation(p_orientation);
+ buffer->add_string(p_text, Ref<Font>(this), p_font_size);
+ cache.insert(hash, buffer);
+ }
- ClassDB::bind_method(D_METHOD("render_range", "cache_index", "size", "start", "end"), &FontData::render_range);
- ClassDB::bind_method(D_METHOD("render_glyph", "cache_index", "size", "index"), &FontData::render_glyph);
+ Vector2 ofs = p_pos;
+ if (p_orientation == TextServer::ORIENTATION_HORIZONTAL) {
+ ofs.y -= buffer->get_line_ascent();
+ } else {
+ ofs.x -= buffer->get_line_ascent();
+ }
- ClassDB::bind_method(D_METHOD("get_cache_rid", "cache_index"), &FontData::get_cache_rid);
+ buffer->set_width(p_width);
+ buffer->set_horizontal_alignment(p_alignment);
+ if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ buffer->set_flags(p_jst_flags);
+ }
- ClassDB::bind_method(D_METHOD("is_language_supported", "language"), &FontData::is_language_supported);
- ClassDB::bind_method(D_METHOD("set_language_support_override", "language", "supported"), &FontData::set_language_support_override);
- ClassDB::bind_method(D_METHOD("get_language_support_override", "language"), &FontData::get_language_support_override);
- ClassDB::bind_method(D_METHOD("remove_language_support_override", "language"), &FontData::remove_language_support_override);
- ClassDB::bind_method(D_METHOD("get_language_support_overrides"), &FontData::get_language_support_overrides);
+ buffer->draw(p_canvas_item, ofs, p_modulate);
+}
- ClassDB::bind_method(D_METHOD("is_script_supported", "script"), &FontData::is_script_supported);
- ClassDB::bind_method(D_METHOD("set_script_support_override", "script", "supported"), &FontData::set_script_support_override);
- ClassDB::bind_method(D_METHOD("get_script_support_override", "script"), &FontData::get_script_support_override);
- ClassDB::bind_method(D_METHOD("remove_script_support_override", "script"), &FontData::remove_script_support_override);
- ClassDB::bind_method(D_METHOD("get_script_support_overrides"), &FontData::get_script_support_overrides);
+void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
+ uint64_t hash = p_text.hash64();
+ hash = hash_djb2_one_64(p_font_size, hash);
+ hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
+ hash = hash_djb2_one_64(p_brk_flags.operator uint32_t(), hash);
+ hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
+ hash = hash_djb2_one_64(p_direction, hash);
+ hash = hash_djb2_one_64(p_orientation, hash);
- ClassDB::bind_method(D_METHOD("set_opentype_feature_overrides", "overrides"), &FontData::set_opentype_feature_overrides);
- ClassDB::bind_method(D_METHOD("get_opentype_feature_overrides"), &FontData::get_opentype_feature_overrides);
+ Ref<TextParagraph> lines_buffer;
+ if (cache_wrap.has(hash)) {
+ lines_buffer = cache_wrap.get(hash);
+ } else {
+ lines_buffer.instantiate();
+ lines_buffer->set_direction(p_direction);
+ lines_buffer->set_orientation(p_orientation);
+ lines_buffer->add_string(p_text, Ref<Font>(this), p_font_size);
+ lines_buffer->set_width(p_width);
+ lines_buffer->set_break_flags(p_brk_flags);
+ lines_buffer->set_justification_flags(p_jst_flags);
+ cache_wrap.insert(hash, lines_buffer);
+ }
- ClassDB::bind_method(D_METHOD("has_char", "char"), &FontData::has_char);
- ClassDB::bind_method(D_METHOD("get_supported_chars"), &FontData::get_supported_chars);
+ Vector2 ofs = p_pos;
+ if (p_orientation == TextServer::ORIENTATION_HORIZONTAL) {
+ ofs.y -= lines_buffer->get_line_ascent(0);
+ } else {
+ ofs.x -= lines_buffer->get_line_ascent(0);
+ }
- ClassDB::bind_method(D_METHOD("get_glyph_index", "size", "char", "variation_selector"), &FontData::get_glyph_index);
+ lines_buffer->set_alignment(p_alignment);
+ lines_buffer->set_max_lines_visible(p_max_lines);
- ClassDB::bind_method(D_METHOD("get_supported_feature_list"), &FontData::get_supported_feature_list);
- ClassDB::bind_method(D_METHOD("get_supported_variation_list"), &FontData::get_supported_variation_list);
+ lines_buffer->draw(p_canvas_item, ofs, p_modulate);
+}
- ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_data", "get_data");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "face_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_face_index", "get_face_index");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_generate_mipmaps", "get_generate_mipmaps");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_antialiased", "is_antialiased");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_name", "get_font_name");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style_name", "get_font_style_name");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style", "get_font_style");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_STORAGE), "set_subpixel_positioning", "get_subpixel_positioning");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_RANGE, "-2,2,0.01", PROPERTY_USAGE_STORAGE), "set_embolden", "get_embolden");
- ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_transform", "get_transform");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_pixel_range", "get_msdf_pixel_range");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_size", "get_msdf_size");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_force_autohinter", "is_force_autohinter");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE), "set_hinting", "get_hinting");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_oversampling", "get_oversampling");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_fixed_size", "get_fixed_size");
- ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_opentype_feature_overrides", "get_opentype_feature_overrides");
+void Font::draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
+ uint64_t hash = p_text.hash64();
+ hash = hash_djb2_one_64(p_font_size, hash);
+ if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
+ hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
+ }
+ hash = hash_djb2_one_64(p_direction, hash);
+ hash = hash_djb2_one_64(p_orientation, hash);
+
+ Ref<TextLine> buffer;
+ if (cache.has(hash)) {
+ buffer = cache.get(hash);
+ } else {
+ buffer.instantiate();
+ buffer->set_direction(p_direction);
+ buffer->set_orientation(p_orientation);
+ buffer->add_string(p_text, Ref<Font>(this), p_font_size);
+ cache.insert(hash, buffer);
+ }
+
+ Vector2 ofs = p_pos;
+ if (p_orientation == TextServer::ORIENTATION_HORIZONTAL) {
+ ofs.y -= buffer->get_line_ascent();
+ } else {
+ ofs.x -= buffer->get_line_ascent();
+ }
+
+ buffer->set_width(p_width);
+ buffer->set_horizontal_alignment(p_alignment);
+ if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ buffer->set_flags(p_jst_flags);
+ }
+
+ buffer->draw_outline(p_canvas_item, ofs, p_size, p_modulate);
}
-bool FontData::_set(const StringName &p_name, const Variant &p_value) {
- Vector<String> tokens = p_name.operator String().split("/");
- if (tokens.size() == 2 && tokens[0] == "language_support_override") {
- String lang = tokens[1];
- set_language_support_override(lang, p_value);
- return true;
- } else if (tokens.size() == 2 && tokens[0] == "script_support_override") {
- String script = tokens[1];
- set_script_support_override(script, p_value);
- return true;
- } else if (tokens.size() >= 3 && tokens[0] == "cache") {
- int cache_index = tokens[1].to_int();
- if (tokens.size() == 3 && tokens[2] == "variation_coordinates") {
- set_variation_coordinates(cache_index, p_value);
- return true;
- }
- if (tokens.size() >= 5) {
- Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int());
- if (tokens[4] == "ascent") {
- set_ascent(cache_index, sz.x, p_value);
- return true;
- } else if (tokens[4] == "descent") {
- set_descent(cache_index, sz.x, p_value);
- return true;
- } else if (tokens[4] == "underline_position") {
- set_underline_position(cache_index, sz.x, p_value);
- return true;
- } else if (tokens[4] == "underline_thickness") {
- set_underline_thickness(cache_index, sz.x, p_value);
- return true;
- } else if (tokens[4] == "scale") {
- set_scale(cache_index, sz.x, p_value);
- return true;
- } else if (tokens[4] == "spacing_glyph") {
- set_spacing(cache_index, sz.x, TextServer::SPACING_GLYPH, p_value);
- return true;
- } else if (tokens[4] == "spacing_space") {
- set_spacing(cache_index, sz.x, TextServer::SPACING_SPACE, p_value);
- return true;
- } else if (tokens.size() == 7 && tokens[4] == "textures") {
- int texture_index = tokens[5].to_int();
- if (tokens[6] == "image") {
- set_texture_image(cache_index, sz, texture_index, p_value);
- return true;
- } else if (tokens[6] == "offsets") {
- set_texture_offsets(cache_index, sz, texture_index, p_value);
- return true;
- }
- } else if (tokens.size() == 7 && tokens[4] == "glyphs") {
- int32_t glyph_index = tokens[5].to_int();
- if (tokens[6] == "advance") {
- set_glyph_advance(cache_index, sz.x, glyph_index, p_value);
- return true;
- } else if (tokens[6] == "offset") {
- set_glyph_offset(cache_index, sz, glyph_index, p_value);
- return true;
- } else if (tokens[6] == "size") {
- set_glyph_size(cache_index, sz, glyph_index, p_value);
- return true;
- } else if (tokens[6] == "uv_rect") {
- set_glyph_uv_rect(cache_index, sz, glyph_index, p_value);
- return true;
- } else if (tokens[6] == "texture_idx") {
- set_glyph_texture_idx(cache_index, sz, glyph_index, p_value);
- return true;
- }
- } else if (tokens.size() == 7 && tokens[4] == "kerning_overrides") {
- Vector2i gp = Vector2i(tokens[5].to_int(), tokens[6].to_int());
- set_kerning(cache_index, sz.x, gp, p_value);
- return true;
- }
+void Font::draw_multiline_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
+ uint64_t hash = p_text.hash64();
+ hash = hash_djb2_one_64(p_font_size, hash);
+ hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
+ hash = hash_djb2_one_64(p_brk_flags.operator uint32_t(), hash);
+ hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
+ hash = hash_djb2_one_64(p_direction, hash);
+ hash = hash_djb2_one_64(p_orientation, hash);
+
+ Ref<TextParagraph> lines_buffer;
+ if (cache_wrap.has(hash)) {
+ lines_buffer = cache_wrap.get(hash);
+ } else {
+ lines_buffer.instantiate();
+ lines_buffer->set_direction(p_direction);
+ lines_buffer->set_orientation(p_orientation);
+ lines_buffer->add_string(p_text, Ref<Font>(this), p_font_size);
+ lines_buffer->set_width(p_width);
+ lines_buffer->set_break_flags(p_brk_flags);
+ lines_buffer->set_justification_flags(p_jst_flags);
+ cache_wrap.insert(hash, lines_buffer);
+ }
+
+ Vector2 ofs = p_pos;
+ if (p_orientation == TextServer::ORIENTATION_HORIZONTAL) {
+ ofs.y -= lines_buffer->get_line_ascent(0);
+ } else {
+ ofs.x -= lines_buffer->get_line_ascent(0);
+ }
+
+ lines_buffer->set_alignment(p_alignment);
+ lines_buffer->set_max_lines_visible(p_max_lines);
+
+ lines_buffer->draw_outline(p_canvas_item, ofs, p_size, p_modulate);
+}
+
+// Drawing char.
+Size2 Font::get_char_size(char32_t p_char, int p_font_size) const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ for (int i = 0; i < rids.size(); i++) {
+ if (TS->font_has_char(rids[i], p_char)) {
+ int32_t glyph = TS->font_get_glyph_index(rids[i], p_font_size, p_char, 0);
+ return Size2(TS->font_get_glyph_advance(rids[i], p_font_size, glyph).x, get_height(p_font_size));
}
}
- return false;
+ return Size2();
}
-bool FontData::_get(const StringName &p_name, Variant &r_ret) const {
- Vector<String> tokens = p_name.operator String().split("/");
- if (tokens.size() == 2 && tokens[0] == "language_support_override") {
- String lang = tokens[1];
- r_ret = get_language_support_override(lang);
- return true;
- } else if (tokens.size() == 2 && tokens[0] == "script_support_override") {
- String script = tokens[1];
- r_ret = get_script_support_override(script);
- return true;
- } else if (tokens.size() >= 3 && tokens[0] == "cache") {
- int cache_index = tokens[1].to_int();
- if (tokens.size() == 3 && tokens[2] == "variation_coordinates") {
- r_ret = get_variation_coordinates(cache_index);
- return true;
+real_t Font::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, const Color &p_modulate) const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ for (int i = 0; i < rids.size(); i++) {
+ if (TS->font_has_char(rids[i], p_char)) {
+ int32_t glyph = TS->font_get_glyph_index(rids[i], p_font_size, p_char, 0);
+ TS->font_draw_glyph(rids[i], p_canvas_item, p_font_size, p_pos, glyph, p_modulate);
+ return TS->font_get_glyph_advance(rids[i], p_font_size, glyph).x;
}
- if (tokens.size() >= 5) {
- Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int());
- if (tokens[4] == "ascent") {
- r_ret = get_ascent(cache_index, sz.x);
- return true;
- } else if (tokens[4] == "descent") {
- r_ret = get_descent(cache_index, sz.x);
- return true;
- } else if (tokens[4] == "underline_position") {
- r_ret = get_underline_position(cache_index, sz.x);
- return true;
- } else if (tokens[4] == "underline_thickness") {
- r_ret = get_underline_thickness(cache_index, sz.x);
- return true;
- } else if (tokens[4] == "scale") {
- r_ret = get_scale(cache_index, sz.x);
- return true;
- } else if (tokens[4] == "spacing_glyph") {
- r_ret = get_spacing(cache_index, sz.x, TextServer::SPACING_GLYPH);
- return true;
- } else if (tokens[4] == "spacing_space") {
- r_ret = get_spacing(cache_index, sz.x, TextServer::SPACING_SPACE);
- return true;
- } else if (tokens.size() == 7 && tokens[4] == "textures") {
- int texture_index = tokens[5].to_int();
- if (tokens[6] == "image") {
- r_ret = get_texture_image(cache_index, sz, texture_index);
- return true;
- } else if (tokens[6] == "offsets") {
- r_ret = get_texture_offsets(cache_index, sz, texture_index);
- return true;
- }
- } else if (tokens.size() == 7 && tokens[4] == "glyphs") {
- int32_t glyph_index = tokens[5].to_int();
- if (tokens[6] == "advance") {
- r_ret = get_glyph_advance(cache_index, sz.x, glyph_index);
- return true;
- } else if (tokens[6] == "offset") {
- r_ret = get_glyph_offset(cache_index, sz, glyph_index);
- return true;
- } else if (tokens[6] == "size") {
- r_ret = get_glyph_size(cache_index, sz, glyph_index);
- return true;
- } else if (tokens[6] == "uv_rect") {
- r_ret = get_glyph_uv_rect(cache_index, sz, glyph_index);
- return true;
- } else if (tokens[6] == "texture_idx") {
- r_ret = get_glyph_texture_idx(cache_index, sz, glyph_index);
- return true;
- }
- } else if (tokens.size() == 7 && tokens[4] == "kerning_overrides") {
- Vector2i gp = Vector2i(tokens[5].to_int(), tokens[6].to_int());
- r_ret = get_kerning(cache_index, sz.x, gp);
- return true;
- }
+ }
+ return 0.f;
+}
+
+real_t Font::draw_char_outline(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, int p_size, const Color &p_modulate) const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ for (int i = 0; i < rids.size(); i++) {
+ if (TS->font_has_char(rids[i], p_char)) {
+ int32_t glyph = TS->font_get_glyph_index(rids[i], p_font_size, p_char, 0);
+ TS->font_draw_glyph_outline(rids[i], p_canvas_item, p_font_size, p_size, p_pos, glyph, p_modulate);
+ return TS->font_get_glyph_advance(rids[i], p_font_size, glyph).x;
}
}
- return false;
+ return 0.f;
}
-void FontData::_get_property_list(List<PropertyInfo> *p_list) const {
- Vector<String> lang_over = get_language_support_overrides();
- for (int i = 0; i < lang_over.size(); i++) {
- p_list->push_back(PropertyInfo(Variant::BOOL, "language_support_override/" + lang_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+// Helper functions.
+bool Font::has_char(char32_t p_char) const {
+ if (dirty_rids) {
+ _update_rids();
}
- Vector<String> scr_over = get_script_support_overrides();
- for (int i = 0; i < scr_over.size(); i++) {
- p_list->push_back(PropertyInfo(Variant::BOOL, "script_support_override/" + scr_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ for (int i = 0; i < rids.size(); i++) {
+ if (TS->font_has_char(rids[i], p_char)) {
+ return true;
+ }
}
- for (int i = 0; i < cache.size(); i++) {
- String prefix = "cache/" + itos(i) + "/";
- Array sizes = get_size_cache_list(i);
- p_list->push_back(PropertyInfo(Variant::DICTIONARY, prefix + "variation_coordinates", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- for (int j = 0; j < sizes.size(); j++) {
- Vector2i sz = sizes[j];
- String prefix_sz = prefix + itos(sz.x) + "/" + itos(sz.y) + "/";
- if (sz.y == 0) {
- p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "ascent", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "descent", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "underline_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "underline_thickness", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::BOOL, prefix_sz + "spacing_glyph", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::BOOL, prefix_sz + "spacing_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- }
+ return false;
+}
- int tx_cnt = get_texture_count(i, sz);
- for (int k = 0; k < tx_cnt; k++) {
- p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, prefix_sz + "textures/" + itos(k) + "/offsets", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::OBJECT, prefix_sz + "textures/" + itos(k) + "/image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
- }
- Array glyphs = get_glyph_list(i, sz);
- for (int k = 0; k < glyphs.size(); k++) {
- const int32_t &gl = glyphs[k];
- if (sz.y == 0) {
- p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "glyphs/" + itos(gl) + "/advance", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- }
- p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "glyphs/" + itos(gl) + "/offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "glyphs/" + itos(gl) + "/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::RECT2, prefix_sz + "glyphs/" + itos(gl) + "/uv_rect", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, prefix_sz + "glyphs/" + itos(gl) + "/texture_idx", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- }
- if (sz.y == 0) {
- Array kerning_map = get_kerning_list(i, sz.x);
- for (int k = 0; k < kerning_map.size(); k++) {
- const Vector2i &gl_pair = kerning_map[k];
- p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "kerning_overrides/" + itos(gl_pair.x) + "/" + itos(gl_pair.y), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- }
+String Font::get_supported_chars() const {
+ if (dirty_rids) {
+ _update_rids();
+ }
+ String chars;
+ for (int i = 0; i < rids.size(); i++) {
+ String data_chars = TS->font_get_supported_chars(rids[i]);
+ for (int j = 0; j < data_chars.length(); j++) {
+ if (chars.find_char(data_chars[j]) == -1) {
+ chars += data_chars[j];
}
}
}
+ return chars;
}
-void FontData::reset_state() {
- _clear_cache();
- data.clear();
- data_ptr = nullptr;
- data_size = 0;
- face_index = 0;
- cache.clear();
+bool Font::is_language_supported(const String &p_language) const {
+ return TS->font_is_language_supported(_get_rid(), p_language);
+}
- antialiased = true;
- mipmaps = false;
- msdf = false;
- force_autohinter = false;
- hinting = TextServer::HINTING_LIGHT;
- subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED;
- msdf_pixel_range = 14;
- msdf_size = 128;
- fixed_size = 0;
- embolden = 0.f;
- transform = Transform2D();
- oversampling = 0.f;
+bool Font::is_script_supported(const String &p_script) const {
+ return TS->font_is_script_supported(_get_rid(), p_script);
+}
+
+Dictionary Font::get_supported_feature_list() const {
+ return TS->font_supported_feature_list(_get_rid());
+}
+
+Dictionary Font::get_supported_variation_list() const {
+ return TS->font_supported_variation_list(_get_rid());
+}
+
+int64_t Font::get_face_count() const {
+ return TS->font_get_face_count(_get_rid());
+}
+
+Font::Font() {
+ cache.set_capacity(64);
+ cache_wrap.set_capacity(16);
+}
+
+Font::~Font() {
+ reset_state();
}
-void FontData::_convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz) {
+/*************************************************************************/
+/* FontFile */
+/*************************************************************************/
+
+_FORCE_INLINE_ void FontFile::_clear_cache() {
+ for (int i = 0; i < cache.size(); i++) {
+ if (cache[i].is_valid()) {
+ TS->free_rid(cache[i]);
+ cache.write[i] = RID();
+ }
+ }
+}
+
+_FORCE_INLINE_ void FontFile::_ensure_rid(int p_cache_index) const {
+ if (unlikely(p_cache_index >= cache.size())) {
+ cache.resize(p_cache_index + 1);
+ }
+ if (unlikely(!cache[p_cache_index].is_valid())) {
+ cache.write[p_cache_index] = TS->create_font();
+ TS->font_set_data_ptr(cache[p_cache_index], data_ptr, data_size);
+ TS->font_set_antialiased(cache[p_cache_index], antialiased);
+ TS->font_set_generate_mipmaps(cache[p_cache_index], mipmaps);
+ TS->font_set_multichannel_signed_distance_field(cache[p_cache_index], msdf);
+ TS->font_set_msdf_pixel_range(cache[p_cache_index], msdf_pixel_range);
+ TS->font_set_msdf_size(cache[p_cache_index], msdf_size);
+ TS->font_set_fixed_size(cache[p_cache_index], fixed_size);
+ TS->font_set_force_autohinter(cache[p_cache_index], force_autohinter);
+ TS->font_set_hinting(cache[p_cache_index], hinting);
+ TS->font_set_subpixel_positioning(cache[p_cache_index], subpixel_positioning);
+ TS->font_set_oversampling(cache[p_cache_index], oversampling);
+ }
+}
+
+void FontFile::_convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz) {
int w = p_source->get_width();
int h = p_source->get_height();
@@ -516,7 +636,7 @@ void FontData::_convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz)
set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
}
-void FontData::_convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
+void FontFile::_convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
int w = p_source->get_width();
int h = p_source->get_height();
@@ -616,7 +736,7 @@ void FontData::_convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz)
set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 3, img_ao);
}
-void FontData::_convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
+void FontFile::_convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
int w = p_source->get_width();
int h = p_source->get_height();
@@ -672,7 +792,7 @@ void FontData::_convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
set_texture_image(0, Vector2i(p_sz, 1), p_page, img_o);
}
-void FontData::_convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
+void FontFile::_convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
int w = p_source->get_width();
int h = p_source->get_height();
@@ -701,7 +821,7 @@ void FontData::_convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, in
set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_g);
}
-void FontData::_convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
+void FontFile::_convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
int w = p_source->get_width();
int h = p_source->get_height();
@@ -744,9 +864,477 @@ void FontData::_convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, in
set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_o);
}
+void FontFile::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load_bitmap_font", "path"), &FontFile::load_bitmap_font);
+ ClassDB::bind_method(D_METHOD("load_dynamic_font", "path"), &FontFile::load_dynamic_font);
+
+ ClassDB::bind_method(D_METHOD("set_data", "data"), &FontFile::set_data);
+ ClassDB::bind_method(D_METHOD("get_data"), &FontFile::get_data);
+
+ ClassDB::bind_method(D_METHOD("set_font_name", "name"), &FontFile::set_font_name);
+ ClassDB::bind_method(D_METHOD("set_font_style_name", "name"), &FontFile::set_font_style_name);
+ ClassDB::bind_method(D_METHOD("set_font_style", "style"), &FontFile::set_font_style);
+
+ ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &FontFile::set_antialiased);
+ ClassDB::bind_method(D_METHOD("is_antialiased"), &FontFile::is_antialiased);
+
+ ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &FontFile::set_generate_mipmaps);
+ ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &FontFile::get_generate_mipmaps);
+
+ ClassDB::bind_method(D_METHOD("set_multichannel_signed_distance_field", "msdf"), &FontFile::set_multichannel_signed_distance_field);
+ ClassDB::bind_method(D_METHOD("is_multichannel_signed_distance_field"), &FontFile::is_multichannel_signed_distance_field);
+
+ ClassDB::bind_method(D_METHOD("set_msdf_pixel_range", "msdf_pixel_range"), &FontFile::set_msdf_pixel_range);
+ ClassDB::bind_method(D_METHOD("get_msdf_pixel_range"), &FontFile::get_msdf_pixel_range);
+
+ ClassDB::bind_method(D_METHOD("set_msdf_size", "msdf_size"), &FontFile::set_msdf_size);
+ ClassDB::bind_method(D_METHOD("get_msdf_size"), &FontFile::get_msdf_size);
+
+ ClassDB::bind_method(D_METHOD("set_fixed_size", "fixed_size"), &FontFile::set_fixed_size);
+ ClassDB::bind_method(D_METHOD("get_fixed_size"), &FontFile::get_fixed_size);
+
+ ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &FontFile::set_force_autohinter);
+ ClassDB::bind_method(D_METHOD("is_force_autohinter"), &FontFile::is_force_autohinter);
+
+ ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &FontFile::set_hinting);
+ ClassDB::bind_method(D_METHOD("get_hinting"), &FontFile::get_hinting);
+
+ ClassDB::bind_method(D_METHOD("set_subpixel_positioning", "subpixel_positioning"), &FontFile::set_subpixel_positioning);
+ ClassDB::bind_method(D_METHOD("get_subpixel_positioning"), &FontFile::get_subpixel_positioning);
+
+ ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &FontFile::set_oversampling);
+ ClassDB::bind_method(D_METHOD("get_oversampling"), &FontFile::get_oversampling);
+
+ ClassDB::bind_method(D_METHOD("get_cache_count"), &FontFile::get_cache_count);
+ ClassDB::bind_method(D_METHOD("clear_cache"), &FontFile::clear_cache);
+ ClassDB::bind_method(D_METHOD("remove_cache", "cache_index"), &FontFile::remove_cache);
+
+ ClassDB::bind_method(D_METHOD("get_size_cache_list", "cache_index"), &FontFile::get_size_cache_list);
+ ClassDB::bind_method(D_METHOD("clear_size_cache", "cache_index"), &FontFile::clear_size_cache);
+ ClassDB::bind_method(D_METHOD("remove_size_cache", "cache_index", "size"), &FontFile::remove_size_cache);
+
+ ClassDB::bind_method(D_METHOD("set_variation_coordinates", "cache_index", "variation_coordinates"), &FontFile::set_variation_coordinates);
+ ClassDB::bind_method(D_METHOD("get_variation_coordinates", "cache_index"), &FontFile::get_variation_coordinates);
+
+ ClassDB::bind_method(D_METHOD("set_embolden", "cache_index", "strength"), &FontFile::set_embolden);
+ ClassDB::bind_method(D_METHOD("get_embolden", "cache_index"), &FontFile::get_embolden);
+
+ ClassDB::bind_method(D_METHOD("set_transform", "cache_index", "transform"), &FontFile::set_transform);
+ ClassDB::bind_method(D_METHOD("get_transform", "cache_index"), &FontFile::get_transform);
+
+ ClassDB::bind_method(D_METHOD("set_face_index", "cache_index", "face_index"), &FontFile::set_face_index);
+ ClassDB::bind_method(D_METHOD("get_face_index", "cache_index"), &FontFile::get_face_index);
+
+ ClassDB::bind_method(D_METHOD("set_cache_ascent", "cache_index", "size", "ascent"), &FontFile::set_cache_ascent);
+ ClassDB::bind_method(D_METHOD("get_cache_ascent", "cache_index", "size"), &FontFile::get_cache_ascent);
+
+ ClassDB::bind_method(D_METHOD("set_cache_descent", "cache_index", "size", "descent"), &FontFile::set_cache_descent);
+ ClassDB::bind_method(D_METHOD("get_cache_descent", "cache_index", "size"), &FontFile::get_cache_descent);
+
+ ClassDB::bind_method(D_METHOD("set_cache_underline_position", "cache_index", "size", "underline_position"), &FontFile::set_cache_underline_position);
+ ClassDB::bind_method(D_METHOD("get_cache_underline_position", "cache_index", "size"), &FontFile::get_cache_underline_position);
+
+ ClassDB::bind_method(D_METHOD("set_cache_underline_thickness", "cache_index", "size", "underline_thickness"), &FontFile::set_cache_underline_thickness);
+ ClassDB::bind_method(D_METHOD("get_cache_underline_thickness", "cache_index", "size"), &FontFile::get_cache_underline_thickness);
+
+ ClassDB::bind_method(D_METHOD("set_cache_scale", "cache_index", "size", "scale"), &FontFile::set_cache_scale);
+ ClassDB::bind_method(D_METHOD("get_cache_scale", "cache_index", "size"), &FontFile::get_cache_scale);
+
+ ClassDB::bind_method(D_METHOD("get_texture_count", "cache_index", "size"), &FontFile::get_texture_count);
+ ClassDB::bind_method(D_METHOD("clear_textures", "cache_index", "size"), &FontFile::clear_textures);
+ ClassDB::bind_method(D_METHOD("remove_texture", "cache_index", "size", "texture_index"), &FontFile::remove_texture);
+
+ ClassDB::bind_method(D_METHOD("set_texture_image", "cache_index", "size", "texture_index", "image"), &FontFile::set_texture_image);
+ ClassDB::bind_method(D_METHOD("get_texture_image", "cache_index", "size", "texture_index"), &FontFile::get_texture_image);
+
+ ClassDB::bind_method(D_METHOD("set_texture_offsets", "cache_index", "size", "texture_index", "offset"), &FontFile::set_texture_offsets);
+ ClassDB::bind_method(D_METHOD("get_texture_offsets", "cache_index", "size", "texture_index"), &FontFile::get_texture_offsets);
+
+ ClassDB::bind_method(D_METHOD("get_glyph_list", "cache_index", "size"), &FontFile::get_glyph_list);
+ ClassDB::bind_method(D_METHOD("clear_glyphs", "cache_index", "size"), &FontFile::clear_glyphs);
+ ClassDB::bind_method(D_METHOD("remove_glyph", "cache_index", "size", "glyph"), &FontFile::remove_glyph);
+
+ ClassDB::bind_method(D_METHOD("set_glyph_advance", "cache_index", "size", "glyph", "advance"), &FontFile::set_glyph_advance);
+ ClassDB::bind_method(D_METHOD("get_glyph_advance", "cache_index", "size", "glyph"), &FontFile::get_glyph_advance);
+
+ ClassDB::bind_method(D_METHOD("set_glyph_offset", "cache_index", "size", "glyph", "offset"), &FontFile::set_glyph_offset);
+ ClassDB::bind_method(D_METHOD("get_glyph_offset", "cache_index", "size", "glyph"), &FontFile::get_glyph_offset);
+
+ ClassDB::bind_method(D_METHOD("set_glyph_size", "cache_index", "size", "glyph", "gl_size"), &FontFile::set_glyph_size);
+ ClassDB::bind_method(D_METHOD("get_glyph_size", "cache_index", "size", "glyph"), &FontFile::get_glyph_size);
+
+ ClassDB::bind_method(D_METHOD("set_glyph_uv_rect", "cache_index", "size", "glyph", "uv_rect"), &FontFile::set_glyph_uv_rect);
+ ClassDB::bind_method(D_METHOD("get_glyph_uv_rect", "cache_index", "size", "glyph"), &FontFile::get_glyph_uv_rect);
+
+ ClassDB::bind_method(D_METHOD("set_glyph_texture_idx", "cache_index", "size", "glyph", "texture_idx"), &FontFile::set_glyph_texture_idx);
+ ClassDB::bind_method(D_METHOD("get_glyph_texture_idx", "cache_index", "size", "glyph"), &FontFile::get_glyph_texture_idx);
+
+ ClassDB::bind_method(D_METHOD("get_kerning_list", "cache_index", "size"), &FontFile::get_kerning_list);
+ ClassDB::bind_method(D_METHOD("clear_kerning_map", "cache_index", "size"), &FontFile::clear_kerning_map);
+ ClassDB::bind_method(D_METHOD("remove_kerning", "cache_index", "size", "glyph_pair"), &FontFile::remove_kerning);
+
+ ClassDB::bind_method(D_METHOD("set_kerning", "cache_index", "size", "glyph_pair", "kerning"), &FontFile::set_kerning);
+ ClassDB::bind_method(D_METHOD("get_kerning", "cache_index", "size", "glyph_pair"), &FontFile::get_kerning);
+
+ ClassDB::bind_method(D_METHOD("render_range", "cache_index", "size", "start", "end"), &FontFile::render_range);
+ ClassDB::bind_method(D_METHOD("render_glyph", "cache_index", "size", "index"), &FontFile::render_glyph);
+
+ ClassDB::bind_method(D_METHOD("set_language_support_override", "language", "supported"), &FontFile::set_language_support_override);
+ ClassDB::bind_method(D_METHOD("get_language_support_override", "language"), &FontFile::get_language_support_override);
+ ClassDB::bind_method(D_METHOD("remove_language_support_override", "language"), &FontFile::remove_language_support_override);
+ ClassDB::bind_method(D_METHOD("get_language_support_overrides"), &FontFile::get_language_support_overrides);
+
+ ClassDB::bind_method(D_METHOD("set_script_support_override", "script", "supported"), &FontFile::set_script_support_override);
+ ClassDB::bind_method(D_METHOD("get_script_support_override", "script"), &FontFile::get_script_support_override);
+ ClassDB::bind_method(D_METHOD("remove_script_support_override", "script"), &FontFile::remove_script_support_override);
+ ClassDB::bind_method(D_METHOD("get_script_support_overrides"), &FontFile::get_script_support_overrides);
+
+ ClassDB::bind_method(D_METHOD("set_opentype_feature_overrides", "overrides"), &FontFile::set_opentype_feature_overrides);
+ ClassDB::bind_method(D_METHOD("get_opentype_feature_overrides"), &FontFile::get_opentype_feature_overrides);
+
+ ClassDB::bind_method(D_METHOD("get_glyph_index", "size", "char", "variation_selector"), &FontFile::get_glyph_index);
+
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_data", "get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_generate_mipmaps", "get_generate_mipmaps");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_antialiased", "is_antialiased");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_name", "get_font_name");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style_name", "get_font_style_name");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_FLAGS, "Bold,Italic,Fixed Size", PROPERTY_USAGE_STORAGE), "set_font_style", "get_font_style");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_STORAGE), "set_subpixel_positioning", "get_subpixel_positioning");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_pixel_range", "get_msdf_pixel_range");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_size", "get_msdf_size");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_force_autohinter", "is_force_autohinter");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE), "set_hinting", "get_hinting");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_oversampling", "get_oversampling");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_fixed_size", "get_fixed_size");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_opentype_feature_overrides", "get_opentype_feature_overrides");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font"), PROPERTY_USAGE_STORAGE), "set_fallbacks", "get_fallbacks");
+}
+
+bool FontFile::_set(const StringName &p_name, const Variant &p_value) {
+ Vector<String> tokens = p_name.operator String().split("/");
+
+#ifndef DISABLE_DEPRECATED
+ if (tokens.size() == 1 && tokens[0] == "font_path") {
+ // Compatibility, DynamicFontData.
+ load_dynamic_font(p_value);
+ } else if (tokens.size() == 1 && tokens[0] == "override_oversampling") {
+ set_oversampling(p_value);
+ }
+ if (tokens.size() == 1 && tokens[0] == "font_data") {
+ // Compatibility, DynamicFont.
+ Ref<Font> f = p_value;
+ if (f.is_valid()) {
+ fallbacks.push_back(f);
+ return true;
+ }
+ return false;
+ } else if (tokens.size() == 2 && tokens[0] == "fallback") {
+ // Compatibility, DynamicFont.
+ Ref<FontFile> f = p_value;
+ if (f.is_valid()) {
+ fallbacks.push_back(f);
+ return true;
+ }
+ return false;
+ } else if (tokens.size() == 1 && tokens[0] == "textures") {
+ // Compatibility, BitmapFont.
+ set_fixed_size(16);
+ Array textures = p_value;
+ for (int i = 0; i < textures.size(); i++) {
+ Ref<ImageTexture> tex = textures[i];
+ ERR_CONTINUE(!tex.is_valid());
+ set_texture_image(0, Vector2i(16, 0), i, tex->get_image());
+ }
+ } else if (tokens.size() == 1 && tokens[0] == "chars") {
+ // Compatibility, BitmapFont.
+ set_fixed_size(16);
+ PackedInt32Array arr = p_value;
+ int len = arr.size();
+ ERR_FAIL_COND_V(len % 9, false);
+ if (!len) {
+ return false;
+ }
+ int chars = len / 9;
+ for (int i = 0; i < chars; i++) {
+ const int32_t *data = &arr[i * 9];
+ char32_t c = data[0];
+ set_glyph_texture_idx(0, Vector2i(16, 0), c, data[1]);
+ set_glyph_uv_rect(0, Vector2i(16, 0), c, Rect2(data[2], data[3], data[4], data[5]));
+ set_glyph_offset(0, Vector2i(16, 0), c, Size2(data[6], data[7]));
+ set_glyph_advance(0, 16, c, Vector2(data[8], 0));
+ }
+ } else if (tokens.size() == 1 && tokens[0] == "kernings") {
+ // Compatibility, BitmapFont.
+ set_fixed_size(16);
+ PackedInt32Array arr = p_value;
+ int len = arr.size();
+ ERR_FAIL_COND_V(len % 3, false);
+ if (!len) {
+ return false;
+ }
+ for (int i = 0; i < len / 3; i++) {
+ const int32_t *data = &arr[i * 3];
+ set_kerning(0, 16, Vector2i(data[0], data[1]), Vector2(data[2], 0));
+ }
+ } else if (tokens.size() == 1 && tokens[0] == "height") {
+ // Compatibility, BitmapFont.
+ bmp_height = p_value;
+ set_fixed_size(16);
+ set_cache_descent(0, 16, bmp_height - bmp_ascent);
+ } else if (tokens.size() == 1 && tokens[0] == "ascent") {
+ // Compatibility, BitmapFont.
+ bmp_ascent = p_value;
+ set_fixed_size(16);
+ set_cache_ascent(0, 16, bmp_ascent);
+ set_cache_descent(0, 16, bmp_height - bmp_ascent);
+ } else if (tokens.size() == 1 && tokens[0] == "fallback") {
+ // Compatibility, BitmapFont.
+ Ref<Font> f = p_value;
+ if (f.is_valid()) {
+ fallbacks.push_back(f);
+ return true;
+ }
+ return false;
+ }
+#endif // DISABLE_DEPRECATED
+
+ if (tokens.size() == 2 && tokens[0] == "language_support_override") {
+ String lang = tokens[1];
+ set_language_support_override(lang, p_value);
+ return true;
+ } else if (tokens.size() == 2 && tokens[0] == "script_support_override") {
+ String script = tokens[1];
+ set_script_support_override(script, p_value);
+ return true;
+ } else if (tokens.size() >= 3 && tokens[0] == "cache") {
+ int cache_index = tokens[1].to_int();
+ if (tokens.size() == 3 && tokens[2] == "variation_coordinates") {
+ set_variation_coordinates(cache_index, p_value);
+ return true;
+ } else if (tokens.size() == 3 && tokens[2] == "embolden") {
+ set_embolden(cache_index, p_value);
+ return true;
+ } else if (tokens.size() == 3 && tokens[2] == "face_index") {
+ set_face_index(cache_index, p_value);
+ return true;
+ } else if (tokens.size() == 3 && tokens[2] == "transform") {
+ set_transform(cache_index, p_value);
+ return true;
+ }
+ if (tokens.size() >= 5) {
+ Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int());
+ if (tokens[4] == "ascent") {
+ set_cache_ascent(cache_index, sz.x, p_value);
+ return true;
+ } else if (tokens[4] == "descent") {
+ set_cache_descent(cache_index, sz.x, p_value);
+ return true;
+ } else if (tokens[4] == "underline_position") {
+ set_cache_underline_position(cache_index, sz.x, p_value);
+ return true;
+ } else if (tokens[4] == "underline_thickness") {
+ set_cache_underline_thickness(cache_index, sz.x, p_value);
+ return true;
+ } else if (tokens[4] == "scale") {
+ set_cache_scale(cache_index, sz.x, p_value);
+ return true;
+ } else if (tokens.size() == 7 && tokens[4] == "textures") {
+ int texture_index = tokens[5].to_int();
+ if (tokens[6] == "image") {
+ set_texture_image(cache_index, sz, texture_index, p_value);
+ return true;
+ } else if (tokens[6] == "offsets") {
+ set_texture_offsets(cache_index, sz, texture_index, p_value);
+ return true;
+ }
+ } else if (tokens.size() == 7 && tokens[4] == "glyphs") {
+ int32_t glyph_index = tokens[5].to_int();
+ if (tokens[6] == "advance") {
+ set_glyph_advance(cache_index, sz.x, glyph_index, p_value);
+ return true;
+ } else if (tokens[6] == "offset") {
+ set_glyph_offset(cache_index, sz, glyph_index, p_value);
+ return true;
+ } else if (tokens[6] == "size") {
+ set_glyph_size(cache_index, sz, glyph_index, p_value);
+ return true;
+ } else if (tokens[6] == "uv_rect") {
+ set_glyph_uv_rect(cache_index, sz, glyph_index, p_value);
+ return true;
+ } else if (tokens[6] == "texture_idx") {
+ set_glyph_texture_idx(cache_index, sz, glyph_index, p_value);
+ return true;
+ }
+ } else if (tokens.size() == 7 && tokens[4] == "kerning_overrides") {
+ Vector2i gp = Vector2i(tokens[5].to_int(), tokens[6].to_int());
+ set_kerning(cache_index, sz.x, gp, p_value);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool FontFile::_get(const StringName &p_name, Variant &r_ret) const {
+ Vector<String> tokens = p_name.operator String().split("/");
+ if (tokens.size() == 2 && tokens[0] == "language_support_override") {
+ String lang = tokens[1];
+ r_ret = get_language_support_override(lang);
+ return true;
+ } else if (tokens.size() == 2 && tokens[0] == "script_support_override") {
+ String script = tokens[1];
+ r_ret = get_script_support_override(script);
+ return true;
+ } else if (tokens.size() >= 3 && tokens[0] == "cache") {
+ int cache_index = tokens[1].to_int();
+ if (tokens.size() == 3 && tokens[2] == "variation_coordinates") {
+ r_ret = get_variation_coordinates(cache_index);
+ return true;
+ } else if (tokens.size() == 3 && tokens[2] == "embolden") {
+ r_ret = get_embolden(cache_index);
+ return true;
+ } else if (tokens.size() == 3 && tokens[2] == "face_index") {
+ r_ret = get_face_index(cache_index);
+ return true;
+ } else if (tokens.size() == 3 && tokens[2] == "transform") {
+ r_ret = get_transform(cache_index);
+ return true;
+ }
+ if (tokens.size() >= 5) {
+ Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int());
+ if (tokens[4] == "ascent") {
+ r_ret = get_cache_ascent(cache_index, sz.x);
+ return true;
+ } else if (tokens[4] == "descent") {
+ r_ret = get_cache_descent(cache_index, sz.x);
+ return true;
+ } else if (tokens[4] == "underline_position") {
+ r_ret = get_cache_underline_position(cache_index, sz.x);
+ return true;
+ } else if (tokens[4] == "underline_thickness") {
+ r_ret = get_cache_underline_thickness(cache_index, sz.x);
+ return true;
+ } else if (tokens[4] == "scale") {
+ r_ret = get_cache_scale(cache_index, sz.x);
+ return true;
+ } else if (tokens.size() == 7 && tokens[4] == "textures") {
+ int texture_index = tokens[5].to_int();
+ if (tokens[6] == "image") {
+ r_ret = get_texture_image(cache_index, sz, texture_index);
+ return true;
+ } else if (tokens[6] == "offsets") {
+ r_ret = get_texture_offsets(cache_index, sz, texture_index);
+ return true;
+ }
+ } else if (tokens.size() == 7 && tokens[4] == "glyphs") {
+ int32_t glyph_index = tokens[5].to_int();
+ if (tokens[6] == "advance") {
+ r_ret = get_glyph_advance(cache_index, sz.x, glyph_index);
+ return true;
+ } else if (tokens[6] == "offset") {
+ r_ret = get_glyph_offset(cache_index, sz, glyph_index);
+ return true;
+ } else if (tokens[6] == "size") {
+ r_ret = get_glyph_size(cache_index, sz, glyph_index);
+ return true;
+ } else if (tokens[6] == "uv_rect") {
+ r_ret = get_glyph_uv_rect(cache_index, sz, glyph_index);
+ return true;
+ } else if (tokens[6] == "texture_idx") {
+ r_ret = get_glyph_texture_idx(cache_index, sz, glyph_index);
+ return true;
+ }
+ } else if (tokens.size() == 7 && tokens[4] == "kerning_overrides") {
+ Vector2i gp = Vector2i(tokens[5].to_int(), tokens[6].to_int());
+ r_ret = get_kerning(cache_index, sz.x, gp);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void FontFile::_get_property_list(List<PropertyInfo> *p_list) const {
+ Vector<String> lang_over = get_language_support_overrides();
+ for (int i = 0; i < lang_over.size(); i++) {
+ p_list->push_back(PropertyInfo(Variant::BOOL, "language_support_override/" + lang_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ }
+ Vector<String> scr_over = get_script_support_overrides();
+ for (int i = 0; i < scr_over.size(); i++) {
+ p_list->push_back(PropertyInfo(Variant::BOOL, "script_support_override/" + scr_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ }
+ for (int i = 0; i < cache.size(); i++) {
+ String prefix = "cache/" + itos(i) + "/";
+ Array sizes = get_size_cache_list(i);
+ p_list->push_back(PropertyInfo(Variant::DICTIONARY, prefix + "variation_coordinates", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::INT, "face_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+
+ for (int j = 0; j < sizes.size(); j++) {
+ Vector2i sz = sizes[j];
+ String prefix_sz = prefix + itos(sz.x) + "/" + itos(sz.y) + "/";
+ if (sz.y == 0) {
+ p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "ascent", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "descent", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "underline_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "underline_thickness", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ }
+
+ int tx_cnt = get_texture_count(i, sz);
+ for (int k = 0; k < tx_cnt; k++) {
+ p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, prefix_sz + "textures/" + itos(k) + "/offsets", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, prefix_sz + "textures/" + itos(k) + "/image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
+ }
+ Array glyphs = get_glyph_list(i, sz);
+ for (int k = 0; k < glyphs.size(); k++) {
+ const int32_t &gl = glyphs[k];
+ if (sz.y == 0) {
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "glyphs/" + itos(gl) + "/advance", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ }
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "glyphs/" + itos(gl) + "/offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "glyphs/" + itos(gl) + "/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::RECT2, prefix_sz + "glyphs/" + itos(gl) + "/uv_rect", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ p_list->push_back(PropertyInfo(Variant::INT, prefix_sz + "glyphs/" + itos(gl) + "/texture_idx", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ }
+ if (sz.y == 0) {
+ Array kerning_map = get_kerning_list(i, sz.x);
+ for (int k = 0; k < kerning_map.size(); k++) {
+ const Vector2i &gl_pair = kerning_map[k];
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "kerning_overrides/" + itos(gl_pair.x) + "/" + itos(gl_pair.y), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
+ }
+ }
+ }
+ }
+}
+
+void FontFile::reset_state() {
+ _clear_cache();
+ data.clear();
+ data_ptr = nullptr;
+ data_size = 0;
+ cache.clear();
+
+ antialiased = true;
+ mipmaps = false;
+ msdf = false;
+ force_autohinter = false;
+ hinting = TextServer::HINTING_LIGHT;
+ subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED;
+ msdf_pixel_range = 14;
+ msdf_size = 128;
+ fixed_size = 0;
+ oversampling = 0.f;
+
+ Font::reset_state();
+}
+
/*************************************************************************/
-Error FontData::load_bitmap_font(const String &p_path) {
+Error FontFile::load_bitmap_font(const String &p_path) {
reset_state();
antialiased = false;
@@ -763,7 +1351,7 @@ Error FontData::load_bitmap_font(const String &p_path) {
int height = 0;
int ascent = 0;
int outline = 0;
- uint32_t st_flags = 0;
+ BitField<TextServer::FontStyle> st_flags = 0;
String font_name;
bool packed = false;
@@ -789,10 +1377,10 @@ Error FontData::load_bitmap_font(const String &p_path) {
uint8_t flags = f->get_8();
ERR_FAIL_COND_V_MSG(flags & 0x02, ERR_CANT_CREATE, RTR("Non-unicode version of BMFont is not supported."));
if (flags & (1 << 3)) {
- st_flags |= TextServer::FONT_BOLD;
+ st_flags.set_flag(TextServer::FONT_BOLD);
}
if (flags & (1 << 2)) {
- st_flags |= TextServer::FONT_ITALIC;
+ st_flags.set_flag(TextServer::FONT_ITALIC);
}
f->get_8(); // non-unicode charset, skip
f->get_16(); // stretch_h, skip
@@ -1019,12 +1607,12 @@ Error FontData::load_bitmap_font(const String &p_path) {
}
if (keys.has("bold")) {
if (keys["bold"].to_int()) {
- st_flags |= TextServer::FONT_BOLD;
+ st_flags.set_flag(TextServer::FONT_BOLD);
}
}
if (keys.has("italic")) {
if (keys["italic"].to_int()) {
- st_flags |= TextServer::FONT_ITALIC;
+ st_flags.set_flag(TextServer::FONT_ITALIC);
}
}
if (keys.has("face")) {
@@ -1209,13 +1797,13 @@ Error FontData::load_bitmap_font(const String &p_path) {
set_font_name(font_name);
set_font_style(st_flags);
- set_ascent(0, base_size, ascent);
- set_descent(0, base_size, height - ascent);
+ set_cache_ascent(0, base_size, ascent);
+ set_cache_descent(0, base_size, height - ascent);
return OK;
}
-Error FontData::load_dynamic_font(const String &p_path) {
+Error FontFile::load_dynamic_font(const String &p_path) {
reset_state();
Vector<uint8_t> data = FileAccess::get_file_as_array(p_path);
@@ -1224,7 +1812,7 @@ Error FontData::load_dynamic_font(const String &p_path) {
return OK;
}
-void FontData::set_data_ptr(const uint8_t *p_data, size_t p_size) {
+void FontFile::set_data_ptr(const uint8_t *p_data, size_t p_size) {
data.clear();
data_ptr = p_data;
data_size = p_size;
@@ -1238,7 +1826,7 @@ void FontData::set_data_ptr(const uint8_t *p_data, size_t p_size) {
}
}
-void FontData::set_data(const PackedByteArray &p_data) {
+void FontFile::set_data(const PackedByteArray &p_data) {
data = p_data;
data_ptr = data.ptr();
data_size = data.size();
@@ -1252,32 +1840,7 @@ void FontData::set_data(const PackedByteArray &p_data) {
}
}
-void FontData::set_face_index(int64_t p_index) {
- ERR_FAIL_COND(p_index < 0);
- ERR_FAIL_COND(p_index >= 0x7FFF);
-
- if (face_index != p_index) {
- face_index = p_index;
- if (data_ptr != nullptr) {
- for (int i = 0; i < cache.size(); i++) {
- if (cache[i].is_valid()) {
- TS->font_set_face_index(cache[i], face_index);
- }
- }
- }
- }
-}
-
-int64_t FontData::get_face_index() const {
- return face_index;
-}
-
-int64_t FontData::get_face_count() const {
- _ensure_rid(0);
- return TS->font_get_face_count(cache[0]);
-}
-
-PackedByteArray FontData::get_data() const {
+PackedByteArray FontFile::get_data() const {
if (unlikely((size_t)data.size() != data_size)) {
PackedByteArray *data_w = const_cast<PackedByteArray *>(&data);
data_w->resize(data_size);
@@ -1286,37 +1849,22 @@ PackedByteArray FontData::get_data() const {
return data;
}
-void FontData::set_font_name(const String &p_name) {
+void FontFile::set_font_name(const String &p_name) {
_ensure_rid(0);
TS->font_set_name(cache[0], p_name);
}
-String FontData::get_font_name() const {
- _ensure_rid(0);
- return TS->font_get_name(cache[0]);
-}
-
-void FontData::set_font_style_name(const String &p_name) {
+void FontFile::set_font_style_name(const String &p_name) {
_ensure_rid(0);
TS->font_set_style_name(cache[0], p_name);
}
-String FontData::get_font_style_name() const {
- _ensure_rid(0);
- return TS->font_get_style_name(cache[0]);
-}
-
-void FontData::set_font_style(uint32_t p_style) {
+void FontFile::set_font_style(BitField<TextServer::FontStyle> p_style) {
_ensure_rid(0);
TS->font_set_style(cache[0], p_style);
}
-uint32_t FontData::get_font_style() const {
- _ensure_rid(0);
- return TS->font_get_style(cache[0]);
-}
-
-void FontData::set_antialiased(bool p_antialiased) {
+void FontFile::set_antialiased(bool p_antialiased) {
if (antialiased != p_antialiased) {
antialiased = p_antialiased;
for (int i = 0; i < cache.size(); i++) {
@@ -1327,11 +1875,11 @@ void FontData::set_antialiased(bool p_antialiased) {
}
}
-bool FontData::is_antialiased() const {
+bool FontFile::is_antialiased() const {
return antialiased;
}
-void FontData::set_generate_mipmaps(bool p_generate_mipmaps) {
+void FontFile::set_generate_mipmaps(bool p_generate_mipmaps) {
if (mipmaps != p_generate_mipmaps) {
mipmaps = p_generate_mipmaps;
for (int i = 0; i < cache.size(); i++) {
@@ -1342,11 +1890,11 @@ void FontData::set_generate_mipmaps(bool p_generate_mipmaps) {
}
}
-bool FontData::get_generate_mipmaps() const {
+bool FontFile::get_generate_mipmaps() const {
return mipmaps;
}
-void FontData::set_multichannel_signed_distance_field(bool p_msdf) {
+void FontFile::set_multichannel_signed_distance_field(bool p_msdf) {
if (msdf != p_msdf) {
msdf = p_msdf;
for (int i = 0; i < cache.size(); i++) {
@@ -1357,11 +1905,11 @@ void FontData::set_multichannel_signed_distance_field(bool p_msdf) {
}
}
-bool FontData::is_multichannel_signed_distance_field() const {
+bool FontFile::is_multichannel_signed_distance_field() const {
return msdf;
}
-void FontData::set_msdf_pixel_range(int p_msdf_pixel_range) {
+void FontFile::set_msdf_pixel_range(int p_msdf_pixel_range) {
if (msdf_pixel_range != p_msdf_pixel_range) {
msdf_pixel_range = p_msdf_pixel_range;
for (int i = 0; i < cache.size(); i++) {
@@ -1372,11 +1920,11 @@ void FontData::set_msdf_pixel_range(int p_msdf_pixel_range) {
}
}
-int FontData::get_msdf_pixel_range() const {
+int FontFile::get_msdf_pixel_range() const {
return msdf_pixel_range;
}
-void FontData::set_msdf_size(int p_msdf_size) {
+void FontFile::set_msdf_size(int p_msdf_size) {
if (msdf_size != p_msdf_size) {
msdf_size = p_msdf_size;
for (int i = 0; i < cache.size(); i++) {
@@ -1387,11 +1935,11 @@ void FontData::set_msdf_size(int p_msdf_size) {
}
}
-int FontData::get_msdf_size() const {
+int FontFile::get_msdf_size() const {
return msdf_size;
}
-void FontData::set_fixed_size(int p_fixed_size) {
+void FontFile::set_fixed_size(int p_fixed_size) {
if (fixed_size != p_fixed_size) {
fixed_size = p_fixed_size;
for (int i = 0; i < cache.size(); i++) {
@@ -1402,11 +1950,11 @@ void FontData::set_fixed_size(int p_fixed_size) {
}
}
-int FontData::get_fixed_size() const {
+int FontFile::get_fixed_size() const {
return fixed_size;
}
-void FontData::set_force_autohinter(bool p_force_autohinter) {
+void FontFile::set_force_autohinter(bool p_force_autohinter) {
if (force_autohinter != p_force_autohinter) {
force_autohinter = p_force_autohinter;
for (int i = 0; i < cache.size(); i++) {
@@ -1417,11 +1965,11 @@ void FontData::set_force_autohinter(bool p_force_autohinter) {
}
}
-bool FontData::is_force_autohinter() const {
+bool FontFile::is_force_autohinter() const {
return force_autohinter;
}
-void FontData::set_hinting(TextServer::Hinting p_hinting) {
+void FontFile::set_hinting(TextServer::Hinting p_hinting) {
if (hinting != p_hinting) {
hinting = p_hinting;
for (int i = 0; i < cache.size(); i++) {
@@ -1432,11 +1980,11 @@ void FontData::set_hinting(TextServer::Hinting p_hinting) {
}
}
-TextServer::Hinting FontData::get_hinting() const {
+TextServer::Hinting FontFile::get_hinting() const {
return hinting;
}
-void FontData::set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel) {
+void FontFile::set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel) {
if (subpixel_positioning != p_subpixel) {
subpixel_positioning = p_subpixel;
for (int i = 0; i < cache.size(); i++) {
@@ -1447,41 +1995,11 @@ void FontData::set_subpixel_positioning(TextServer::SubpixelPositioning p_subpix
}
}
-TextServer::SubpixelPositioning FontData::get_subpixel_positioning() const {
+TextServer::SubpixelPositioning FontFile::get_subpixel_positioning() const {
return subpixel_positioning;
}
-void FontData::set_embolden(float p_strength) {
- if (embolden != p_strength) {
- embolden = p_strength;
- for (int i = 0; i < cache.size(); i++) {
- _ensure_rid(i);
- TS->font_set_embolden(cache[i], embolden);
- }
- emit_changed();
- }
-}
-
-float FontData::get_embolden() const {
- return embolden;
-}
-
-void FontData::set_transform(Transform2D p_transform) {
- if (transform != p_transform) {
- transform = p_transform;
- for (int i = 0; i < cache.size(); i++) {
- _ensure_rid(i);
- TS->font_set_transform(cache[i], transform);
- }
- emit_changed();
- }
-}
-
-Transform2D FontData::get_transform() const {
- return transform;
-}
-
-void FontData::set_oversampling(real_t p_oversampling) {
+void FontFile::set_oversampling(real_t p_oversampling) {
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
for (int i = 0; i < cache.size(); i++) {
@@ -1492,17 +2010,20 @@ void FontData::set_oversampling(real_t p_oversampling) {
}
}
-real_t FontData::get_oversampling() const {
+real_t FontFile::get_oversampling() const {
return oversampling;
}
-RID FontData::find_cache(const Dictionary &p_variation_coordinates) const {
+RID FontFile::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const {
// Find existing variation cache.
const Dictionary &supported_coords = get_supported_variation_list();
for (int i = 0; i < cache.size(); i++) {
if (cache[i].is_valid()) {
const Dictionary &cache_var = TS->font_get_variation_coordinates(cache[i]);
bool match = true;
+ match = match && (TS->font_get_face_index(cache[i]) == p_face_index);
+ match = match && (TS->font_get_embolden(cache[i]) == p_strength);
+ match = match && (TS->font_get_transform(cache[i]) == p_transform);
for (const Variant *V = supported_coords.next(nullptr); V && match; V = supported_coords.next(V)) {
const Vector3 &def = supported_coords[*V];
@@ -1538,19 +2059,28 @@ RID FontData::find_cache(const Dictionary &p_variation_coordinates) const {
int idx = cache.size();
_ensure_rid(idx);
TS->font_set_variation_coordinates(cache[idx], p_variation_coordinates);
+ TS->font_set_face_index(cache[idx], p_face_index);
+ TS->font_set_embolden(cache[idx], p_strength);
+ TS->font_set_transform(cache[idx], p_transform);
return cache[idx];
}
-int FontData::get_cache_count() const {
+RID FontFile::_get_rid() const {
+ _ensure_rid(0);
+ return cache[0];
+}
+
+int FontFile::get_cache_count() const {
return cache.size();
}
-void FontData::clear_cache() {
+void FontFile::clear_cache() {
_clear_cache();
cache.clear();
+ emit_changed();
}
-void FontData::remove_cache(int p_cache_index) {
+void FontFile::remove_cache(int p_cache_index) {
ERR_FAIL_INDEX(p_cache_index, cache.size());
if (cache[p_cache_index].is_valid()) {
TS->free_rid(cache.write[p_cache_index]);
@@ -1559,952 +2089,607 @@ void FontData::remove_cache(int p_cache_index) {
emit_changed();
}
-Array FontData::get_size_cache_list(int p_cache_index) const {
+Array FontFile::get_size_cache_list(int p_cache_index) const {
ERR_FAIL_COND_V(p_cache_index < 0, Array());
_ensure_rid(p_cache_index);
return TS->font_get_size_cache_list(cache[p_cache_index]);
}
-void FontData::clear_size_cache(int p_cache_index) {
+void FontFile::clear_size_cache(int p_cache_index) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_clear_size_cache(cache[p_cache_index]);
}
-void FontData::remove_size_cache(int p_cache_index, const Vector2i &p_size) {
+void FontFile::remove_size_cache(int p_cache_index, const Vector2i &p_size) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_remove_size_cache(cache[p_cache_index], p_size);
}
-void FontData::set_variation_coordinates(int p_cache_index, const Dictionary &p_variation_coordinates) {
+void FontFile::set_variation_coordinates(int p_cache_index, const Dictionary &p_variation_coordinates) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_variation_coordinates(cache[p_cache_index], p_variation_coordinates);
- emit_changed();
}
-Dictionary FontData::get_variation_coordinates(int p_cache_index) const {
+Dictionary FontFile::get_variation_coordinates(int p_cache_index) const {
ERR_FAIL_COND_V(p_cache_index < 0, Dictionary());
_ensure_rid(p_cache_index);
return TS->font_get_variation_coordinates(cache[p_cache_index]);
}
-void FontData::set_ascent(int p_cache_index, int p_size, real_t p_ascent) {
+void FontFile::set_embolden(int p_cache_index, float p_strength) {
+ ERR_FAIL_COND(p_cache_index < 0);
+ _ensure_rid(p_cache_index);
+ TS->font_set_embolden(cache[p_cache_index], p_strength);
+}
+
+float FontFile::get_embolden(int p_cache_index) const {
+ ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
+ _ensure_rid(p_cache_index);
+ return TS->font_get_embolden(cache[p_cache_index]);
+}
+
+void FontFile::set_transform(int p_cache_index, Transform2D p_transform) {
+ ERR_FAIL_COND(p_cache_index < 0);
+ _ensure_rid(p_cache_index);
+ TS->font_set_transform(cache[p_cache_index], p_transform);
+}
+
+Transform2D FontFile::get_transform(int p_cache_index) const {
+ ERR_FAIL_COND_V(p_cache_index < 0, Transform2D());
+ _ensure_rid(p_cache_index);
+ return TS->font_get_transform(cache[p_cache_index]);
+}
+
+void FontFile::set_face_index(int p_cache_index, int64_t p_index) {
+ ERR_FAIL_COND(p_cache_index < 0);
+ ERR_FAIL_COND(p_index < 0);
+ ERR_FAIL_COND(p_index >= 0x7FFF);
+
+ _ensure_rid(p_cache_index);
+ TS->font_set_face_index(cache[p_cache_index], p_index);
+}
+
+int64_t FontFile::get_face_index(int p_cache_index) const {
+ ERR_FAIL_COND_V(p_cache_index < 0, 0);
+ _ensure_rid(p_cache_index);
+ return TS->font_get_face_index(cache[p_cache_index]);
+}
+
+void FontFile::set_cache_ascent(int p_cache_index, int p_size, real_t p_ascent) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_ascent(cache[p_cache_index], p_size, p_ascent);
}
-real_t FontData::get_ascent(int p_cache_index, int p_size) const {
+real_t FontFile::get_cache_ascent(int p_cache_index, int p_size) const {
ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
_ensure_rid(p_cache_index);
return TS->font_get_ascent(cache[p_cache_index], p_size);
}
-void FontData::set_descent(int p_cache_index, int p_size, real_t p_descent) {
+void FontFile::set_cache_descent(int p_cache_index, int p_size, real_t p_descent) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_descent(cache[p_cache_index], p_size, p_descent);
}
-real_t FontData::get_descent(int p_cache_index, int p_size) const {
+real_t FontFile::get_cache_descent(int p_cache_index, int p_size) const {
ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
_ensure_rid(p_cache_index);
return TS->font_get_descent(cache[p_cache_index], p_size);
}
-void FontData::set_underline_position(int p_cache_index, int p_size, real_t p_underline_position) {
+void FontFile::set_cache_underline_position(int p_cache_index, int p_size, real_t p_underline_position) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_underline_position(cache[p_cache_index], p_size, p_underline_position);
}
-real_t FontData::get_underline_position(int p_cache_index, int p_size) const {
+real_t FontFile::get_cache_underline_position(int p_cache_index, int p_size) const {
ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
_ensure_rid(p_cache_index);
return TS->font_get_underline_position(cache[p_cache_index], p_size);
}
-void FontData::set_underline_thickness(int p_cache_index, int p_size, real_t p_underline_thickness) {
+void FontFile::set_cache_underline_thickness(int p_cache_index, int p_size, real_t p_underline_thickness) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_underline_thickness(cache[p_cache_index], p_size, p_underline_thickness);
}
-real_t FontData::get_underline_thickness(int p_cache_index, int p_size) const {
+real_t FontFile::get_cache_underline_thickness(int p_cache_index, int p_size) const {
ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
_ensure_rid(p_cache_index);
return TS->font_get_underline_thickness(cache[p_cache_index], p_size);
}
-void FontData::set_scale(int p_cache_index, int p_size, real_t p_scale) {
+void FontFile::set_cache_scale(int p_cache_index, int p_size, real_t p_scale) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_scale(cache[p_cache_index], p_size, p_scale);
}
-real_t FontData::get_scale(int p_cache_index, int p_size) const {
+real_t FontFile::get_cache_scale(int p_cache_index, int p_size) const {
ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
_ensure_rid(p_cache_index);
return TS->font_get_scale(cache[p_cache_index], p_size);
}
-void FontData::set_spacing(int p_cache_index, int p_size, TextServer::SpacingType p_spacing, int p_value) {
- ERR_FAIL_COND(p_cache_index < 0);
- _ensure_rid(p_cache_index);
- TS->font_set_spacing(cache[p_cache_index], p_size, p_spacing, p_value);
-}
-
-int FontData::get_spacing(int p_cache_index, int p_size, TextServer::SpacingType p_spacing) const {
- ERR_FAIL_COND_V(p_cache_index < 0, 0);
- _ensure_rid(p_cache_index);
- return TS->font_get_spacing(cache[p_cache_index], p_size, p_spacing);
-}
-
-int FontData::get_texture_count(int p_cache_index, const Vector2i &p_size) const {
+int FontFile::get_texture_count(int p_cache_index, const Vector2i &p_size) const {
ERR_FAIL_COND_V(p_cache_index < 0, 0);
_ensure_rid(p_cache_index);
return TS->font_get_texture_count(cache[p_cache_index], p_size);
}
-void FontData::clear_textures(int p_cache_index, const Vector2i &p_size) {
+void FontFile::clear_textures(int p_cache_index, const Vector2i &p_size) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_clear_textures(cache[p_cache_index], p_size);
}
-void FontData::remove_texture(int p_cache_index, const Vector2i &p_size, int p_texture_index) {
+void FontFile::remove_texture(int p_cache_index, const Vector2i &p_size, int p_texture_index) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_remove_texture(cache[p_cache_index], p_size, p_texture_index);
}
-void FontData::set_texture_image(int p_cache_index, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) {
+void FontFile::set_texture_image(int p_cache_index, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_texture_image(cache[p_cache_index], p_size, p_texture_index, p_image);
}
-Ref<Image> FontData::get_texture_image(int p_cache_index, const Vector2i &p_size, int p_texture_index) const {
+Ref<Image> FontFile::get_texture_image(int p_cache_index, const Vector2i &p_size, int p_texture_index) const {
ERR_FAIL_COND_V(p_cache_index < 0, Ref<Image>());
_ensure_rid(p_cache_index);
return TS->font_get_texture_image(cache[p_cache_index], p_size, p_texture_index);
}
-void FontData::set_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) {
+void FontFile::set_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_texture_offsets(cache[p_cache_index], p_size, p_texture_index, p_offset);
}
-PackedInt32Array FontData::get_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index) const {
+PackedInt32Array FontFile::get_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index) const {
ERR_FAIL_COND_V(p_cache_index < 0, PackedInt32Array());
_ensure_rid(p_cache_index);
return TS->font_get_texture_offsets(cache[p_cache_index], p_size, p_texture_index);
}
-Array FontData::get_glyph_list(int p_cache_index, const Vector2i &p_size) const {
+Array FontFile::get_glyph_list(int p_cache_index, const Vector2i &p_size) const {
ERR_FAIL_COND_V(p_cache_index < 0, Array());
_ensure_rid(p_cache_index);
return TS->font_get_glyph_list(cache[p_cache_index], p_size);
}
-void FontData::clear_glyphs(int p_cache_index, const Vector2i &p_size) {
+void FontFile::clear_glyphs(int p_cache_index, const Vector2i &p_size) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_clear_glyphs(cache[p_cache_index], p_size);
}
-void FontData::remove_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) {
+void FontFile::remove_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_remove_glyph(cache[p_cache_index], p_size, p_glyph);
}
-void FontData::set_glyph_advance(int p_cache_index, int p_size, int32_t p_glyph, const Vector2 &p_advance) {
+void FontFile::set_glyph_advance(int p_cache_index, int p_size, int32_t p_glyph, const Vector2 &p_advance) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_glyph_advance(cache[p_cache_index], p_size, p_glyph, p_advance);
}
-Vector2 FontData::get_glyph_advance(int p_cache_index, int p_size, int32_t p_glyph) const {
+Vector2 FontFile::get_glyph_advance(int p_cache_index, int p_size, int32_t p_glyph) const {
ERR_FAIL_COND_V(p_cache_index < 0, Vector2());
_ensure_rid(p_cache_index);
return TS->font_get_glyph_advance(cache[p_cache_index], p_size, p_glyph);
}
-void FontData::set_glyph_offset(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) {
+void FontFile::set_glyph_offset(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_glyph_offset(cache[p_cache_index], p_size, p_glyph, p_offset);
}
-Vector2 FontData::get_glyph_offset(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
+Vector2 FontFile::get_glyph_offset(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
ERR_FAIL_COND_V(p_cache_index < 0, Vector2());
_ensure_rid(p_cache_index);
return TS->font_get_glyph_offset(cache[p_cache_index], p_size, p_glyph);
}
-void FontData::set_glyph_size(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) {
+void FontFile::set_glyph_size(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_glyph_size(cache[p_cache_index], p_size, p_glyph, p_gl_size);
}
-Vector2 FontData::get_glyph_size(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
+Vector2 FontFile::get_glyph_size(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
ERR_FAIL_COND_V(p_cache_index < 0, Vector2());
_ensure_rid(p_cache_index);
return TS->font_get_glyph_size(cache[p_cache_index], p_size, p_glyph);
}
-void FontData::set_glyph_uv_rect(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) {
+void FontFile::set_glyph_uv_rect(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_glyph_uv_rect(cache[p_cache_index], p_size, p_glyph, p_uv_rect);
}
-Rect2 FontData::get_glyph_uv_rect(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
+Rect2 FontFile::get_glyph_uv_rect(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
ERR_FAIL_COND_V(p_cache_index < 0, Rect2());
_ensure_rid(p_cache_index);
return TS->font_get_glyph_uv_rect(cache[p_cache_index], p_size, p_glyph);
}
-void FontData::set_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) {
+void FontFile::set_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_glyph_texture_idx(cache[p_cache_index], p_size, p_glyph, p_texture_idx);
}
-int FontData::get_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
+int FontFile::get_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
ERR_FAIL_COND_V(p_cache_index < 0, 0);
_ensure_rid(p_cache_index);
return TS->font_get_glyph_texture_idx(cache[p_cache_index], p_size, p_glyph);
}
-Array FontData::get_kerning_list(int p_cache_index, int p_size) const {
+Array FontFile::get_kerning_list(int p_cache_index, int p_size) const {
ERR_FAIL_COND_V(p_cache_index < 0, Array());
_ensure_rid(p_cache_index);
return TS->font_get_kerning_list(cache[p_cache_index], p_size);
}
-void FontData::clear_kerning_map(int p_cache_index, int p_size) {
+void FontFile::clear_kerning_map(int p_cache_index, int p_size) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_clear_kerning_map(cache[p_cache_index], p_size);
}
-void FontData::remove_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair) {
+void FontFile::remove_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_remove_kerning(cache[p_cache_index], p_size, p_glyph_pair);
}
-void FontData::set_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
+void FontFile::set_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_set_kerning(cache[p_cache_index], p_size, p_glyph_pair, p_kerning);
}
-Vector2 FontData::get_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair) const {
+Vector2 FontFile::get_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair) const {
ERR_FAIL_COND_V(p_cache_index < 0, Vector2());
_ensure_rid(p_cache_index);
return TS->font_get_kerning(cache[p_cache_index], p_size, p_glyph_pair);
}
-void FontData::render_range(int p_cache_index, const Vector2i &p_size, char32_t p_start, char32_t p_end) {
+void FontFile::render_range(int p_cache_index, const Vector2i &p_size, char32_t p_start, char32_t p_end) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_render_range(cache[p_cache_index], p_size, p_start, p_end);
}
-void FontData::render_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_index) {
+void FontFile::render_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_index) {
ERR_FAIL_COND(p_cache_index < 0);
_ensure_rid(p_cache_index);
TS->font_render_glyph(cache[p_cache_index], p_size, p_index);
}
-RID FontData::get_cache_rid(int p_cache_index) const {
- ERR_FAIL_COND_V(p_cache_index < 0, RID());
- _ensure_rid(p_cache_index);
- return cache[p_cache_index];
-}
-
-bool FontData::is_language_supported(const String &p_language) const {
- _ensure_rid(0);
- return TS->font_is_language_supported(cache[0], p_language);
-}
-
-void FontData::set_language_support_override(const String &p_language, bool p_supported) {
+void FontFile::set_language_support_override(const String &p_language, bool p_supported) {
_ensure_rid(0);
TS->font_set_language_support_override(cache[0], p_language, p_supported);
}
-bool FontData::get_language_support_override(const String &p_language) const {
+bool FontFile::get_language_support_override(const String &p_language) const {
_ensure_rid(0);
return TS->font_get_language_support_override(cache[0], p_language);
}
-void FontData::remove_language_support_override(const String &p_language) {
+void FontFile::remove_language_support_override(const String &p_language) {
_ensure_rid(0);
TS->font_remove_language_support_override(cache[0], p_language);
}
-Vector<String> FontData::get_language_support_overrides() const {
+Vector<String> FontFile::get_language_support_overrides() const {
_ensure_rid(0);
return TS->font_get_language_support_overrides(cache[0]);
}
-bool FontData::is_script_supported(const String &p_script) const {
- _ensure_rid(0);
- return TS->font_is_script_supported(cache[0], p_script);
-}
-
-void FontData::set_script_support_override(const String &p_script, bool p_supported) {
+void FontFile::set_script_support_override(const String &p_script, bool p_supported) {
_ensure_rid(0);
TS->font_set_script_support_override(cache[0], p_script, p_supported);
}
-bool FontData::get_script_support_override(const String &p_script) const {
+bool FontFile::get_script_support_override(const String &p_script) const {
_ensure_rid(0);
return TS->font_get_script_support_override(cache[0], p_script);
}
-void FontData::remove_script_support_override(const String &p_script) {
+void FontFile::remove_script_support_override(const String &p_script) {
_ensure_rid(0);
TS->font_remove_script_support_override(cache[0], p_script);
}
-Vector<String> FontData::get_script_support_overrides() const {
+Vector<String> FontFile::get_script_support_overrides() const {
_ensure_rid(0);
return TS->font_get_script_support_overrides(cache[0]);
}
-void FontData::set_opentype_feature_overrides(const Dictionary &p_overrides) {
+void FontFile::set_opentype_feature_overrides(const Dictionary &p_overrides) {
_ensure_rid(0);
TS->font_set_opentype_feature_overrides(cache[0], p_overrides);
}
-Dictionary FontData::get_opentype_feature_overrides() const {
+Dictionary FontFile::get_opentype_feature_overrides() const {
_ensure_rid(0);
return TS->font_get_opentype_feature_overrides(cache[0]);
}
-bool FontData::has_char(char32_t p_char) const {
- _ensure_rid(0);
- return TS->font_has_char(cache[0], p_char);
-}
-
-String FontData::get_supported_chars() const {
- _ensure_rid(0);
- return TS->font_get_supported_chars(cache[0]);
-}
-
-int32_t FontData::get_glyph_index(int p_size, char32_t p_char, char32_t p_variation_selector) const {
+int32_t FontFile::get_glyph_index(int p_size, char32_t p_char, char32_t p_variation_selector) const {
_ensure_rid(0);
return TS->font_get_glyph_index(cache[0], p_size, p_char, p_variation_selector);
}
-Dictionary FontData::get_supported_feature_list() const {
- _ensure_rid(0);
- return TS->font_supported_feature_list(cache[0]);
-}
-
-Dictionary FontData::get_supported_variation_list() const {
- _ensure_rid(0);
- return TS->font_supported_variation_list(cache[0]);
-}
-
-FontData::FontData() {
+FontFile::FontFile() {
/* NOP */
}
-FontData::~FontData() {
- _clear_cache();
+FontFile::~FontFile() {
+ reset_state();
}
/*************************************************************************/
+/* FontVariation */
+/*************************************************************************/
-void Font::_data_changed() {
- for (int i = 0; i < rids.size(); i++) {
- rids.write[i] = RID();
- }
- emit_changed();
-}
+void FontVariation::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_base_font", "font"), &FontVariation::set_base_font);
+ ClassDB::bind_method(D_METHOD("get_base_font"), &FontVariation::get_base_font);
-void Font::_ensure_rid(int p_index) const {
- // Find or create cache record.
- if (!rids[p_index].is_valid() && data[p_index].is_valid()) {
- rids.write[p_index] = data[p_index]->find_cache(variation_coordinates);
- }
-}
+ ClassDB::bind_method(D_METHOD("set_variation_opentype", "coords"), &FontVariation::set_variation_opentype);
+ ClassDB::bind_method(D_METHOD("get_variation_opentype"), &FontVariation::get_variation_opentype);
-void Font::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_data", "data"), &Font::add_data);
- ClassDB::bind_method(D_METHOD("set_data", "idx", "data"), &Font::set_data);
- ClassDB::bind_method(D_METHOD("get_data_count"), &Font::get_data_count);
- ClassDB::bind_method(D_METHOD("get_data", "idx"), &Font::get_data);
- ClassDB::bind_method(D_METHOD("get_data_rid", "idx"), &Font::get_data_rid);
- ClassDB::bind_method(D_METHOD("clear_data"), &Font::clear_data);
- ClassDB::bind_method(D_METHOD("remove_data", "idx"), &Font::remove_data);
-
- ClassDB::bind_method(D_METHOD("set_variation_coordinates", "variation_coordinates"), &Font::set_variation_coordinates);
- ClassDB::bind_method(D_METHOD("get_variation_coordinates"), &Font::get_variation_coordinates);
- ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "variation_coordinates"), "set_variation_coordinates", "get_variation_coordinates");
-
- ClassDB::bind_method(D_METHOD("set_spacing", "spacing", "value"), &Font::set_spacing);
- ClassDB::bind_method(D_METHOD("get_spacing", "spacing"), &Font::get_spacing);
+ ClassDB::bind_method(D_METHOD("set_variation_embolden", "strength"), &FontVariation::set_variation_embolden);
+ ClassDB::bind_method(D_METHOD("get_variation_embolden"), &FontVariation::get_variation_embolden);
- ADD_GROUP("Extra Spacing", "spacing");
- ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_top", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_bottom", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_BOTTOM);
-
- ClassDB::bind_method(D_METHOD("get_height", "size"), &Font::get_height, DEFVAL(DEFAULT_FONT_SIZE));
- ClassDB::bind_method(D_METHOD("get_ascent", "size"), &Font::get_ascent, DEFVAL(DEFAULT_FONT_SIZE));
- ClassDB::bind_method(D_METHOD("get_descent", "size"), &Font::get_descent, DEFVAL(DEFAULT_FONT_SIZE));
- ClassDB::bind_method(D_METHOD("get_underline_position", "size"), &Font::get_underline_position, DEFVAL(DEFAULT_FONT_SIZE));
- ClassDB::bind_method(D_METHOD("get_underline_thickness", "size"), &Font::get_underline_thickness, DEFVAL(DEFAULT_FONT_SIZE));
+ ClassDB::bind_method(D_METHOD("set_variation_face_index", "face_index"), &FontVariation::set_variation_face_index);
+ ClassDB::bind_method(D_METHOD("get_variation_face_index"), &FontVariation::get_variation_face_index);
- ClassDB::bind_method(D_METHOD("get_string_size", "text", "size", "alignment", "width", "flags"), &Font::get_string_size, DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
- ClassDB::bind_method(D_METHOD("get_multiline_string_size", "text", "width", "size", "flags"), &Font::get_multiline_string_size, DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND));
+ ClassDB::bind_method(D_METHOD("set_variation_transform", "transform"), &FontVariation::set_variation_transform);
+ ClassDB::bind_method(D_METHOD("get_variation_transform"), &FontVariation::get_variation_transform);
- ClassDB::bind_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "alignment", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
- ClassDB::bind_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "alignment", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &Font::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
+ ClassDB::bind_method(D_METHOD("set_opentype_features", "features"), &FontVariation::set_opentype_features);
- ClassDB::bind_method(D_METHOD("get_char_size", "char", "next", "size"), &Font::get_char_size, DEFVAL(0), DEFVAL(DEFAULT_FONT_SIZE));
- ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "next", "size", "modulate", "outline_size", "outline_modulate"), &Font::draw_char, DEFVAL(0), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)));
+ ClassDB::bind_method(D_METHOD("set_spacing", "spacing", "value"), &FontVariation::set_spacing);
- ClassDB::bind_method(D_METHOD("has_char", "char"), &Font::has_char);
- ClassDB::bind_method(D_METHOD("get_supported_chars"), &Font::get_supported_chars);
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_base_font", "get_base_font");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), "set_fallbacks", "get_fallbacks");
- ClassDB::bind_method(D_METHOD("update_changes"), &Font::update_changes);
+ ADD_GROUP("Variation", "variation");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "variation_opentype"), "set_variation_opentype", "get_variation_opentype");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "variation_face_index"), "set_variation_face_index", "get_variation_face_index");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "variation_embolden", PROPERTY_HINT_RANGE, "-2,2,0.01"), "set_variation_embolden", "get_variation_embolden");
+ ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "variation_transform", PROPERTY_HINT_NONE, "suffix:px"), "set_variation_transform", "get_variation_transform");
- ClassDB::bind_method(D_METHOD("get_rids"), &Font::get_rids);
-}
+ ADD_GROUP("OpenType Features", "opentype");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "opentype_features"), "set_opentype_features", "get_opentype_features");
-bool Font::_set(const StringName &p_name, const Variant &p_value) {
- Vector<String> tokens = p_name.operator String().split("/");
-#ifndef DISABLE_DEPRECATED
- if (tokens.size() == 1 && tokens[0] == "font_data") {
- // Compatibility, DynamicFont main data.
- Ref<FontData> fd = p_value;
- if (fd.is_valid()) {
- add_data(fd);
- return true;
- }
- return false;
- } else if (tokens.size() == 2 && tokens[0] == "fallback") {
- // Compatibility, DynamicFont fallback data.
- Ref<FontData> fd = p_value;
- if (fd.is_valid()) {
- add_data(fd);
- return true;
- }
- return false;
- } else if (tokens.size() == 1 && tokens[0] == "fallback") {
- // Compatibility, BitmapFont fallback data.
- Ref<Font> f = p_value;
- if (f.is_valid()) {
- for (int i = 0; i < f->get_data_count(); i++) {
- add_data(f->get_data(i));
- }
- return true;
- }
- return false;
- }
-#endif /* DISABLE_DEPRECATED */
- if (tokens.size() == 2 && tokens[0] == "data") {
- int idx = tokens[1].to_int();
- Ref<FontData> fd = p_value;
- if (fd.is_valid()) {
- if (idx == data.size()) {
- add_data(fd);
- return true;
- } else if (idx >= 0 && idx < data.size()) {
- set_data(idx, fd);
- return true;
- } else {
- return false;
- }
- } else if (idx >= 0 && idx < data.size()) {
- remove_data(idx);
- return true;
- }
- }
- return false;
+ ADD_GROUP("Extra Spacing", "spacing");
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_glyph", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_GLYPH);
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_space", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_SPACE);
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_top", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_bottom", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_BOTTOM);
}
-bool Font::_get(const StringName &p_name, Variant &r_ret) const {
- Vector<String> tokens = p_name.operator String().split("/");
- if (tokens.size() == 2 && tokens[0] == "data") {
- int idx = tokens[1].to_int();
+void FontVariation::_update_rids() const {
+ Ref<Font> f = _get_base_font_or_default();
- if (idx == data.size()) {
- r_ret = Ref<FontData>();
- return true;
- } else if (idx >= 0 && idx < data.size()) {
- r_ret = get_data(idx);
- return true;
+ rids.clear();
+ if (fallbacks.is_empty() && f.is_valid()) {
+ RID rid = _get_rid();
+ if (rid.is_valid()) {
+ rids.push_back(rid);
}
- }
-
- return false;
-}
-void Font::_get_property_list(List<PropertyInfo> *p_list) const {
- for (int i = 0; i < data.size(); i++) {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "data/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "FontData"));
+ const TypedArray<Font> &base_fallbacks = f->get_fallbacks();
+ for (int i = 0; i < base_fallbacks.size(); i++) {
+ _update_rids_fb(base_fallbacks[i], 0);
+ }
+ } else {
+ _update_rids_fb(const_cast<FontVariation *>(this), 0);
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "data/" + itos(data.size()), PROPERTY_HINT_RESOURCE_TYPE, "FontData"));
+ dirty_rids = false;
}
-void Font::reset_state() {
- for (int i = 0; i < data.size(); i++) {
- if (data[i].is_valid()) {
- data.write[i]->connect(SNAME("changed"), callable_mp(this, &Font::_data_changed), varray(), CONNECT_REFERENCE_COUNTED);
- }
+void FontVariation::reset_state() {
+ if (base_font.is_valid()) {
+ base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids));
+ base_font.unref();
}
- cache.clear();
- cache_wrap.clear();
- data.clear();
- rids.clear();
- variation_coordinates.clear();
- spacing_bottom = 0;
- spacing_top = 0;
-}
-
-Dictionary Font::get_feature_list() const {
- Dictionary out;
- for (int i = 0; i < data.size(); i++) {
- Dictionary data_ftrs = data[i]->get_supported_feature_list();
- for (const Variant *ftr = data_ftrs.next(nullptr); ftr != nullptr; ftr = data_ftrs.next(ftr)) {
- out[*ftr] = data_ftrs[*ftr];
- }
+ if (theme_font.is_valid()) {
+ theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids));
+ theme_font.unref();
}
- return out;
-}
-void Font::add_data(const Ref<FontData> &p_data) {
- ERR_FAIL_COND(p_data.is_null());
- data.push_back(p_data);
- rids.push_back(RID());
+ variation = Variation();
+ opentype_features = Dictionary();
- if (data[data.size() - 1].is_valid()) {
- data.write[data.size() - 1]->connect(SNAME("changed"), callable_mp(this, &Font::_data_changed), varray(), CONNECT_REFERENCE_COUNTED);
- Dictionary data_var_list = p_data->get_supported_variation_list();
- for (int j = 0; j < data_var_list.size(); j++) {
- int32_t tag = data_var_list.get_key_at_index(j);
- Vector3i value = data_var_list.get_value_at_index(j);
- if (!variation_coordinates.has(tag) && !variation_coordinates.has(TS->tag_to_name(tag))) {
- variation_coordinates[TS->tag_to_name(tag)] = value.z;
- }
- }
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ extra_spacing[i] = 0;
}
- cache.clear();
- cache_wrap.clear();
-
- emit_changed();
- notify_property_list_changed();
+ Font::reset_state();
}
-void Font::set_data(int p_idx, const Ref<FontData> &p_data) {
- ERR_FAIL_COND(p_data.is_null());
- ERR_FAIL_INDEX(p_idx, data.size());
-
- if (data[p_idx].is_valid()) {
- data.write[p_idx]->disconnect(SNAME("changed"), callable_mp(this, &Font::_data_changed));
- }
-
- data.write[p_idx] = p_data;
- rids.write[p_idx] = RID();
- Dictionary data_var_list = p_data->get_supported_variation_list();
- for (int j = 0; j < data_var_list.size(); j++) {
- int32_t tag = data_var_list.get_key_at_index(j);
- Vector3i value = data_var_list.get_value_at_index(j);
- if (!variation_coordinates.has(tag) && !variation_coordinates.has(TS->tag_to_name(tag))) {
- variation_coordinates[TS->tag_to_name(tag)] = value.z;
+void FontVariation::set_base_font(const Ref<Font> &p_font) {
+ if (base_font != p_font) {
+ if (base_font.is_valid()) {
+ base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids));
}
+ base_font = p_font;
+ if (base_font.is_valid()) {
+ base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED);
+ }
+ _invalidate_rids();
+ notify_property_list_changed();
}
-
- if (data[p_idx].is_valid()) {
- data.write[p_idx]->connect(SNAME("changed"), callable_mp(this, &Font::_data_changed), varray(), CONNECT_REFERENCE_COUNTED);
- }
-
- cache.clear();
- cache_wrap.clear();
-
- emit_changed();
- notify_property_list_changed();
-}
-
-int Font::get_data_count() const {
- return data.size();
}
-Ref<FontData> Font::get_data(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, data.size(), Ref<FontData>());
- return data[p_idx];
+Ref<Font> FontVariation::get_base_font() const {
+ return base_font;
}
-RID Font::get_data_rid(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, data.size(), RID());
- _ensure_rid(p_idx);
- return rids[p_idx];
-}
-
-void Font::clear_data() {
- for (int i = 0; i < data.size(); i++) {
- if (data[i].is_valid()) {
- data.write[i]->connect(SNAME("changed"), callable_mp(this, &Font::_data_changed), varray(), CONNECT_REFERENCE_COUNTED);
- }
+Ref<Font> FontVariation::_get_base_font_or_default() const {
+ if (theme_font.is_valid()) {
+ theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids));
+ theme_font.unref();
}
- data.clear();
- rids.clear();
-}
-void Font::remove_data(int p_idx) {
- ERR_FAIL_INDEX(p_idx, data.size());
-
- if (data[p_idx].is_valid()) {
- data.write[p_idx]->disconnect(SNAME("changed"), callable_mp(this, &Font::_data_changed));
+ if (base_font.is_valid()) {
+ return base_font;
}
- data.remove_at(p_idx);
- rids.remove_at(p_idx);
-
- cache.clear();
- cache_wrap.clear();
+ // Check the project-defined Theme resource.
+ if (Theme::get_project_default().is_valid()) {
+ List<StringName> theme_types;
+ Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
- emit_changed();
- notify_property_list_changed();
-}
+ for (const StringName &E : theme_types) {
+ if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED);
+ }
+ return f;
+ }
+ }
+ }
-void Font::set_variation_coordinates(const Dictionary &p_variation_coordinates) {
- _data_changed();
- variation_coordinates = p_variation_coordinates;
-}
+ // Lastly, fall back on the items defined in the default Theme, if they exist.
+ if (Theme::get_default().is_valid()) {
+ List<StringName> theme_types;
+ Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
-Dictionary Font::get_variation_coordinates() const {
- return variation_coordinates;
-}
+ for (const StringName &E : theme_types) {
+ if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED);
+ }
+ return f;
+ }
+ }
-void Font::set_spacing(TextServer::SpacingType p_spacing, int p_value) {
- _data_changed();
- switch (p_spacing) {
- case TextServer::SPACING_TOP: {
- spacing_top = p_value;
- } break;
- case TextServer::SPACING_BOTTOM: {
- spacing_bottom = p_value;
- } break;
- default: {
- ERR_FAIL_MSG("Invalid spacing type: " + itos(p_spacing));
- } break;
+ // If they don't exist, use any type to return the default/empty value.
+ Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED);
+ }
+ return f;
}
-}
-int Font::get_spacing(TextServer::SpacingType p_spacing) const {
- switch (p_spacing) {
- case TextServer::SPACING_TOP: {
- return spacing_top;
- } break;
- case TextServer::SPACING_BOTTOM: {
- return spacing_bottom;
- } break;
- default: {
- ERR_FAIL_V_MSG(0, "Invalid spacing type: " + itos(p_spacing));
- } break;
- }
+ return Ref<Font>();
}
-real_t Font::get_height(int p_size) const {
- real_t ret = 0.f;
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- ret = MAX(ret, TS->font_get_ascent(rids[i], p_size) + TS->font_get_descent(rids[i], p_size));
+void FontVariation::set_variation_opentype(const Dictionary &p_coords) {
+ if (variation.opentype != p_coords) {
+ variation.opentype = p_coords;
+ _invalidate_rids();
}
- return ret + spacing_bottom + spacing_top;
}
-real_t Font::get_ascent(int p_size) const {
- real_t ret = 0.f;
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- ret = MAX(ret, TS->font_get_ascent(rids[i], p_size));
- }
- return ret + spacing_top;
+Dictionary FontVariation::get_variation_opentype() const {
+ return variation.opentype;
}
-real_t Font::get_descent(int p_size) const {
- real_t ret = 0.f;
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- ret = MAX(ret, TS->font_get_descent(rids[i], p_size));
+void FontVariation::set_variation_embolden(float p_strength) {
+ if (variation.embolden != p_strength) {
+ variation.embolden = p_strength;
+ _invalidate_rids();
}
- return ret + spacing_bottom;
}
-real_t Font::get_underline_position(int p_size) const {
- real_t ret = 0.f;
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- ret = MAX(ret, TS->font_get_underline_position(rids[i], p_size));
- }
- return ret + spacing_top;
+float FontVariation::get_variation_embolden() const {
+ return variation.embolden;
}
-real_t Font::get_underline_thickness(int p_size) const {
- real_t ret = 0.f;
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- ret = MAX(ret, TS->font_get_underline_thickness(rids[i], p_size));
+void FontVariation::set_variation_transform(Transform2D p_transform) {
+ if (variation.transform != p_transform) {
+ variation.transform = p_transform;
+ _invalidate_rids();
}
- return ret;
}
-Size2 Font::get_string_size(const String &p_text, int p_size, HorizontalAlignment p_alignment, float p_width, uint16_t p_flags) const {
- ERR_FAIL_COND_V(data.is_empty(), Size2());
-
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- }
-
- uint64_t hash = p_text.hash64();
- if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
- hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
- hash = hash_djb2_one_64(p_flags, hash);
- }
- hash = hash_djb2_one_64(p_size, hash);
-
- Ref<TextLine> buffer;
- if (cache.has(hash)) {
- buffer = cache.get(hash);
- } else {
- buffer.instantiate();
- buffer->add_string(p_text, Ref<Font>(this), p_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
- cache.insert(hash, buffer);
- }
- return buffer->get_size();
+Transform2D FontVariation::get_variation_transform() const {
+ return variation.transform;
}
-Size2 Font::get_multiline_string_size(const String &p_text, float p_width, int p_size, uint16_t p_flags) const {
- ERR_FAIL_COND_V(data.is_empty(), Size2());
-
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- }
-
- uint64_t hash = p_text.hash64();
- uint64_t wrp_hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
- wrp_hash = hash_djb2_one_64(p_flags, wrp_hash);
- wrp_hash = hash_djb2_one_64(p_size, wrp_hash);
-
- Ref<TextParagraph> lines_buffer;
- if (cache_wrap.has(wrp_hash)) {
- lines_buffer = cache_wrap.get(wrp_hash);
- } else {
- lines_buffer.instantiate();
- lines_buffer->add_string(p_text, Ref<Font>(this), p_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
- lines_buffer->set_width(p_width);
- lines_buffer->set_flags(p_flags);
- cache_wrap.insert(wrp_hash, lines_buffer);
- }
-
- Size2 ret;
- for (int i = 0; i < lines_buffer->get_line_count(); i++) {
- Size2 line_size = lines_buffer->get_line_size(i);
- if (lines_buffer->get_orientation() == TextServer::ORIENTATION_HORIZONTAL) {
- ret.x = MAX(ret.x, line_size.x);
- ret.y += line_size.y;
- } else {
- ret.y = MAX(ret.y, line_size.y);
- ret.x += line_size.x;
- }
+void FontVariation::set_variation_face_index(int p_face_index) {
+ if (variation.face_index != p_face_index) {
+ variation.face_index = p_face_index;
+ _invalidate_rids();
}
- return ret;
}
-void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
- ERR_FAIL_COND(data.is_empty());
-
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- }
-
- uint64_t hash = p_text.hash64();
- if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
- hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
- hash = hash_djb2_one_64(p_flags, hash);
- }
- hash = hash_djb2_one_64(p_size, hash);
-
- Ref<TextLine> buffer;
- if (cache.has(hash)) {
- buffer = cache.get(hash);
- } else {
- buffer.instantiate();
- buffer->add_string(p_text, Ref<Font>(this), p_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
- cache.insert(hash, buffer);
- }
-
- Vector2 ofs = p_pos;
- if (buffer->get_orientation() == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.y -= buffer->get_line_ascent();
- } else {
- ofs.x -= buffer->get_line_ascent();
- }
-
- buffer->set_width(p_width);
- buffer->set_horizontal_alignment(p_alignment);
- buffer->set_flags(p_flags);
-
- if (p_outline_size > 0 && p_outline_modulate.a != 0.0f) {
- buffer->draw_outline(p_canvas_item, ofs, p_outline_size, p_outline_modulate);
- }
- buffer->draw(p_canvas_item, ofs, p_modulate);
+int FontVariation::get_variation_face_index() const {
+ return variation.face_index;
}
-void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
- ERR_FAIL_COND(data.is_empty());
-
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- }
-
- uint64_t hash = p_text.hash64();
- uint64_t wrp_hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
- wrp_hash = hash_djb2_one_64(p_flags, wrp_hash);
- wrp_hash = hash_djb2_one_64(p_size, wrp_hash);
-
- Ref<TextParagraph> lines_buffer;
- if (cache_wrap.has(wrp_hash)) {
- lines_buffer = cache_wrap.get(wrp_hash);
- } else {
- lines_buffer.instantiate();
- lines_buffer->add_string(p_text, Ref<Font>(this), p_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
- lines_buffer->set_width(p_width);
- lines_buffer->set_flags(p_flags);
- cache_wrap.insert(wrp_hash, lines_buffer);
- }
-
- lines_buffer->set_alignment(p_alignment);
-
- Vector2 lofs = p_pos;
- for (int i = 0; i < lines_buffer->get_line_count(); i++) {
- if (lines_buffer->get_orientation() == TextServer::ORIENTATION_HORIZONTAL) {
- if (i == 0) {
- lofs.y -= lines_buffer->get_line_ascent(0);
- }
- } else {
- if (i == 0) {
- lofs.x -= lines_buffer->get_line_ascent(0);
- }
- }
- if (p_width > 0) {
- lines_buffer->set_alignment(p_alignment);
- }
-
- if (p_outline_size > 0 && p_outline_modulate.a != 0.0f) {
- lines_buffer->draw_line_outline(p_canvas_item, lofs, i, p_outline_size, p_outline_modulate);
- }
- lines_buffer->draw_line(p_canvas_item, lofs, i, p_modulate);
-
- Size2 line_size = lines_buffer->get_line_size(i);
- if (lines_buffer->get_orientation() == TextServer::ORIENTATION_HORIZONTAL) {
- lofs.y += line_size.y;
- } else {
- lofs.x += line_size.x;
- }
-
- if ((p_max_lines > 0) && (i >= p_max_lines)) {
- return;
- }
+void FontVariation::set_opentype_features(const Dictionary &p_features) {
+ if (opentype_features != p_features) {
+ opentype_features = p_features;
+ _invalidate_rids();
}
}
-Size2 Font::get_char_size(char32_t p_char, char32_t p_next, int p_size) const {
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- if (data[i]->has_char(p_char)) {
- int32_t glyph_a = TS->font_get_glyph_index(rids[i], p_size, p_char, 0);
- Size2 ret = Size2(TS->font_get_glyph_advance(rids[i], p_size, glyph_a).x, TS->font_get_ascent(rids[i], p_size) + TS->font_get_descent(rids[i], p_size));
- if ((p_next != 0) && data[i]->has_char(p_next)) {
- int32_t glyph_b = TS->font_get_glyph_index(rids[i], p_size, p_next, 0);
- ret.x -= TS->font_get_kerning(rids[i], p_size, Vector2i(glyph_a, glyph_b)).x;
- }
- return ret;
- }
- }
- return Size2();
+Dictionary FontVariation::get_opentype_features() const {
+ return opentype_features;
}
-real_t Font::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate) const {
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- if (data[i]->has_char(p_char)) {
- int32_t glyph_a = TS->font_get_glyph_index(rids[i], p_size, p_char, 0);
- real_t ret = TS->font_get_glyph_advance(rids[i], p_size, glyph_a).x;
- if ((p_next != 0) && data[i]->has_char(p_next)) {
- int32_t glyph_b = TS->font_get_glyph_index(rids[i], p_size, p_next, 0);
- ret -= TS->font_get_kerning(rids[i], p_size, Vector2i(glyph_a, glyph_b)).x;
- }
-
- if (p_outline_size > 0 && p_outline_modulate.a != 0.0f) {
- TS->font_draw_glyph_outline(rids[i], p_canvas_item, p_size, p_outline_size, p_pos, glyph_a, p_outline_modulate);
- }
- TS->font_draw_glyph(rids[i], p_canvas_item, p_size, p_pos, glyph_a, p_modulate);
- return ret;
- }
+void FontVariation::set_spacing(TextServer::SpacingType p_spacing, int p_value) {
+ ERR_FAIL_INDEX((int)p_spacing, TextServer::SPACING_MAX);
+ if (extra_spacing[p_spacing] != p_value) {
+ extra_spacing[p_spacing] = p_value;
+ _invalidate_rids();
}
- return 0;
}
-bool Font::has_char(char32_t p_char) const {
- for (int i = 0; i < data.size(); i++) {
- if (data[i]->has_char(p_char)) {
- return true;
- }
- }
- return false;
+int FontVariation::get_spacing(TextServer::SpacingType p_spacing) const {
+ ERR_FAIL_INDEX_V((int)p_spacing, TextServer::SPACING_MAX, 0);
+ return extra_spacing[p_spacing];
}
-String Font::get_supported_chars() const {
- String chars;
- for (int i = 0; i < data.size(); i++) {
- String data_chars = data[i]->get_supported_chars();
- for (int j = 0; j < data_chars.length(); j++) {
- if (chars.find_char(data_chars[j]) == -1) {
- chars += data_chars[j];
- }
- }
+RID FontVariation::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const {
+ Ref<Font> f = _get_base_font_or_default();
+ if (f.is_valid()) {
+ return f->find_variation(p_variation_coordinates, p_face_index, p_strength, p_transform);
}
- return chars;
+ return RID();
}
-Array Font::get_rids() const {
- Array _rids;
- for (int i = 0; i < data.size(); i++) {
- _ensure_rid(i);
- if (rids[i].is_valid()) {
- _rids.push_back(rids[i]);
- }
+RID FontVariation::_get_rid() const {
+ Ref<Font> f = _get_base_font_or_default();
+ if (f.is_valid()) {
+ return f->find_variation(variation.opentype, variation.face_index, variation.embolden, variation.transform);
}
- return _rids;
-}
-
-void Font::update_changes() {
- emit_changed();
+ return RID();
}
-Font::Font() {
- cache.set_capacity(128);
- cache_wrap.set_capacity(32);
+FontVariation::FontVariation() {
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ extra_spacing[i] = 0;
+ }
}
-Font::~Font() {
- clear_data();
- cache.clear();
- cache_wrap.clear();
+FontVariation::~FontVariation() {
+ reset_state();
}
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 950959e054..7a42a4dfea 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -37,16 +37,108 @@
#include "scene/resources/texture.h"
#include "servers/text_server.h"
+class TextLine;
+class TextParagraph;
+
+/*************************************************************************/
+/* Font */
+/*************************************************************************/
+
+class Font : public Resource {
+ GDCLASS(Font, Resource);
+
+ // Shaped string cache.
+ mutable LRUCache<uint64_t, Ref<TextLine>> cache;
+ mutable LRUCache<uint64_t, Ref<TextParagraph>> cache_wrap;
+
+protected:
+ // Output.
+ mutable TypedArray<RID> rids;
+ mutable bool dirty_rids = true;
+
+ // Fallbacks.
+ static constexpr int MAX_FALLBACK_DEPTH = 64;
+ TypedArray<Font> fallbacks;
+
+ static void _bind_methods();
+
+ virtual void _update_rids_fb(const Ref<Font> &p_f, int p_depth) const;
+ virtual void _update_rids() const;
+ virtual bool _is_cyclic(const Ref<Font> &p_f, int p_depth) const;
+
+ virtual void reset_state() override;
+
+public:
+ virtual void _invalidate_rids();
+
+ static constexpr int DEFAULT_FONT_SIZE = 16;
+
+ // Fallbacks.
+ virtual void set_fallbacks(const TypedArray<Font> &p_fallbacks);
+ virtual TypedArray<Font> get_fallbacks() const;
+
+ // Output.
+ virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const { return RID(); };
+ virtual RID _get_rid() const { return RID(); };
+ virtual TypedArray<RID> get_rids() const;
+
+ // Font metrics.
+ virtual real_t get_height(int p_font_size) const;
+ virtual real_t get_ascent(int p_font_size) const;
+ virtual real_t get_descent(int p_font_size) const;
+ virtual real_t get_underline_position(int p_font_size) const;
+ virtual real_t get_underline_thickness(int p_font_size) const;
+
+ virtual String get_font_name() const;
+ virtual String get_font_style_name() const;
+ virtual BitField<TextServer::FontStyle> get_font_style() const;
+
+ virtual int get_spacing(TextServer::SpacingType p_spacing) const { return 0; };
+ virtual Dictionary get_opentype_features() const;
+
+ // Drawing string.
+ virtual void set_cache_capacity(int p_single_line, int p_multi_line);
+
+ virtual Size2 get_string_size(const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+ virtual Size2 get_multiline_string_size(const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+
+ virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+ virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+
+ virtual void draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+ virtual void draw_multiline_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), BitField<TextServer::LineBreakFlag> p_brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
+
+ // Drawing char.
+ virtual Size2 get_char_size(char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE) const;
+ virtual real_t draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
+ virtual real_t draw_char_outline(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
+
+ // Helper functions.
+ virtual bool has_char(char32_t p_char) const;
+ virtual String get_supported_chars() const;
+
+ virtual bool is_language_supported(const String &p_language) const;
+ virtual bool is_script_supported(const String &p_script) const;
+
+ virtual Dictionary get_supported_feature_list() const;
+ virtual Dictionary get_supported_variation_list() const;
+ virtual int64_t get_face_count() const;
+
+ Font();
+ ~Font();
+};
+
+/*************************************************************************/
+/* FontFile */
/*************************************************************************/
-class FontData : public Resource {
- GDCLASS(FontData, Resource);
+class FontFile : public Font {
+ GDCLASS(FontFile, Font);
RES_BASE_EXTENSION("fontdata");
// Font source data.
const uint8_t *data_ptr = nullptr;
size_t data_size = 0;
- int face_index = 0;
PackedByteArray data;
bool antialiased = true;
@@ -59,8 +151,11 @@ class FontData : public Resource {
TextServer::Hinting hinting = TextServer::HINTING_LIGHT;
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
real_t oversampling = 0.f;
- real_t embolden = 0.f;
- Transform2D transform;
+
+#ifndef DISABLE_DEPRECATED
+ real_t bmp_height = 0.0;
+ real_t bmp_ascent = 0.0;
+#endif
// Cache.
mutable Vector<RID> cache;
@@ -92,20 +187,10 @@ public:
virtual void set_data(const PackedByteArray &p_data);
virtual PackedByteArray get_data() const;
- virtual void set_face_index(int64_t p_index);
- virtual int64_t get_face_index() const;
-
- virtual int64_t get_face_count() const;
-
// Common properties.
virtual void set_font_name(const String &p_name);
- virtual String get_font_name() const;
-
virtual void set_font_style_name(const String &p_name);
- virtual String get_font_style_name() const;
-
- virtual void set_font_style(uint32_t p_style);
- virtual uint32_t get_font_style() const;
+ virtual void set_font_style(BitField<TextServer::FontStyle> p_style);
virtual void set_antialiased(bool p_antialiased);
virtual bool is_antialiased() const;
@@ -134,17 +219,12 @@ public:
virtual void set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel);
virtual TextServer::SubpixelPositioning get_subpixel_positioning() const;
- virtual void set_embolden(float p_strength);
- virtual float get_embolden() const;
-
- virtual void set_transform(Transform2D p_transform);
- virtual Transform2D get_transform() const;
-
virtual void set_oversampling(real_t p_oversampling);
virtual real_t get_oversampling() const;
// Cache.
- virtual RID find_cache(const Dictionary &p_variation_coordinates) const;
+ virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override;
+ virtual RID _get_rid() const override;
virtual int get_cache_count() const;
virtual void clear_cache();
@@ -157,23 +237,29 @@ public:
virtual void set_variation_coordinates(int p_cache_index, const Dictionary &p_variation_coordinates);
virtual Dictionary get_variation_coordinates(int p_cache_index) const;
- virtual void set_ascent(int p_cache_index, int p_size, real_t p_ascent);
- virtual real_t get_ascent(int p_cache_index, int p_size) const;
+ virtual void set_embolden(int p_cache_index, float p_strength);
+ virtual float get_embolden(int p_cache_index) const;
+
+ virtual void set_transform(int p_cache_index, Transform2D p_transform);
+ virtual Transform2D get_transform(int p_cache_index) const;
- virtual void set_descent(int p_cache_index, int p_size, real_t p_descent);
- virtual real_t get_descent(int p_cache_index, int p_size) const;
+ virtual void set_face_index(int p_cache_index, int64_t p_index);
+ virtual int64_t get_face_index(int p_cache_index) const;
- virtual void set_underline_position(int p_cache_index, int p_size, real_t p_underline_position);
- virtual real_t get_underline_position(int p_cache_index, int p_size) const;
+ virtual void set_cache_ascent(int p_cache_index, int p_size, real_t p_ascent);
+ virtual real_t get_cache_ascent(int p_cache_index, int p_size) const;
- virtual void set_underline_thickness(int p_cache_index, int p_size, real_t p_underline_thickness);
- virtual real_t get_underline_thickness(int p_cache_index, int p_size) const;
+ virtual void set_cache_descent(int p_cache_index, int p_size, real_t p_descent);
+ virtual real_t get_cache_descent(int p_cache_index, int p_size) const;
- virtual void set_scale(int p_cache_index, int p_size, real_t p_scale); // Rendering scale for bitmap fonts (e.g. emoji fonts).
- virtual real_t get_scale(int p_cache_index, int p_size) const;
+ virtual void set_cache_underline_position(int p_cache_index, int p_size, real_t p_underline_position);
+ virtual real_t get_cache_underline_position(int p_cache_index, int p_size) const;
- virtual void set_spacing(int p_cache_index, int p_size, TextServer::SpacingType p_spacing, int p_value);
- virtual int get_spacing(int p_cache_index, int p_size, TextServer::SpacingType p_spacing) const;
+ virtual void set_cache_underline_thickness(int p_cache_index, int p_size, real_t p_underline_thickness);
+ virtual real_t get_cache_underline_thickness(int p_cache_index, int p_size) const;
+
+ virtual void set_cache_scale(int p_cache_index, int p_size, real_t p_scale); // Rendering scale for bitmap fonts (e.g. emoji fonts).
+ virtual real_t get_cache_scale(int p_cache_index, int p_size) const;
virtual int get_texture_count(int p_cache_index, const Vector2i &p_size) const;
virtual void clear_textures(int p_cache_index, const Vector2i &p_size);
@@ -214,16 +300,12 @@ public:
virtual void render_range(int p_cache_index, const Vector2i &p_size, char32_t p_start, char32_t p_end);
virtual void render_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_index);
- virtual RID get_cache_rid(int p_cache_index) const;
-
// Language/script support override.
- virtual bool is_language_supported(const String &p_language) const;
virtual void set_language_support_override(const String &p_language, bool p_supported);
virtual bool get_language_support_override(const String &p_language) const;
virtual void remove_language_support_override(const String &p_language);
virtual Vector<String> get_language_support_overrides() const;
- virtual bool is_script_supported(const String &p_script) const;
virtual void set_script_support_override(const String &p_script, bool p_supported);
virtual bool get_script_support_override(const String &p_script) const;
virtual void remove_script_support_override(const String &p_script);
@@ -233,100 +315,70 @@ public:
virtual Dictionary get_opentype_feature_overrides() const;
// Base font properties.
- virtual bool has_char(char32_t p_char) const;
- virtual String get_supported_chars() const;
-
virtual int32_t get_glyph_index(int p_size, char32_t p_char, char32_t p_variation_selector = 0x0000) const;
- virtual Dictionary get_supported_feature_list() const;
- virtual Dictionary get_supported_variation_list() const;
-
- FontData();
- ~FontData();
+ FontFile();
+ ~FontFile();
};
/*************************************************************************/
+/* FontVariation */
+/*************************************************************************/
-class TextLine;
-class TextParagraph;
-
-class Font : public Resource {
- GDCLASS(Font, Resource);
+class FontVariation : public Font {
+ GDCLASS(FontVariation, Font);
- // Shaped string cache.
- mutable LRUCache<uint64_t, Ref<TextLine>> cache;
- mutable LRUCache<uint64_t, Ref<TextParagraph>> cache_wrap;
+ struct Variation {
+ Dictionary opentype;
+ real_t embolden = 0.f;
+ int face_index = 0;
+ Transform2D transform;
+ };
- // Font data cache.
- Vector<Ref<FontData>> data;
- mutable Vector<RID> rids;
+ mutable Ref<Font> theme_font;
- // Font config.
- Dictionary variation_coordinates;
- int spacing_bottom = 0;
- int spacing_top = 0;
+ Ref<Font> base_font;
- _FORCE_INLINE_ void _data_changed();
- _FORCE_INLINE_ void _ensure_rid(int p_index) const; // Find or create cache record.
+ Variation variation;
+ Dictionary opentype_features;
+ int extra_spacing[TextServer::SPACING_MAX];
protected:
static void _bind_methods();
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void _update_rids() const override;
virtual void reset_state() override;
public:
- static const int DEFAULT_FONT_SIZE = 16;
+ virtual void set_base_font(const Ref<Font> &p_font);
+ virtual Ref<Font> get_base_font() const;
+ virtual Ref<Font> _get_base_font_or_default() const;
- Dictionary get_feature_list() const;
+ virtual void set_variation_opentype(const Dictionary &p_coords);
+ virtual Dictionary get_variation_opentype() const;
- // Font data.
- virtual void add_data(const Ref<FontData> &p_data);
- virtual void set_data(int p_idx, const Ref<FontData> &p_data);
- virtual int get_data_count() const;
- virtual Ref<FontData> get_data(int p_idx) const;
- virtual RID get_data_rid(int p_idx) const;
- virtual void clear_data();
- virtual void remove_data(int p_idx);
+ virtual void set_variation_embolden(float p_strength);
+ virtual float get_variation_embolden() const;
- // Font configuration.
- virtual void set_variation_coordinates(const Dictionary &p_variation_coordinates);
- virtual Dictionary get_variation_coordinates() const;
+ virtual void set_variation_transform(Transform2D p_transform);
+ virtual Transform2D get_variation_transform() const;
- virtual void set_spacing(TextServer::SpacingType p_spacing, int p_value);
- virtual int get_spacing(TextServer::SpacingType p_spacing) const;
+ virtual void set_variation_face_index(int p_face_index);
+ virtual int get_variation_face_index() const;
- // Font metrics.
- virtual real_t get_height(int p_size = DEFAULT_FONT_SIZE) const;
- virtual real_t get_ascent(int p_size = DEFAULT_FONT_SIZE) const;
- virtual real_t get_descent(int p_size = DEFAULT_FONT_SIZE) const;
- virtual real_t get_underline_position(int p_size = DEFAULT_FONT_SIZE) const;
- virtual real_t get_underline_thickness(int p_size = DEFAULT_FONT_SIZE) const;
+ virtual void set_opentype_features(const Dictionary &p_features);
+ virtual Dictionary get_opentype_features() const override;
- // Drawing string.
- virtual Size2 get_string_size(const String &p_text, int p_size = DEFAULT_FONT_SIZE, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
- virtual Size2 get_multiline_string_size(const String &p_text, float p_width = -1, int p_size = DEFAULT_FONT_SIZE, uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const;
-
- virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
- virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_max_lines = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
-
- // Helper functions.
- virtual bool has_char(char32_t p_char) const;
- virtual String get_supported_chars() const;
-
- // Drawing char.
- virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0, int p_size = DEFAULT_FONT_SIZE) const;
- virtual real_t draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const;
-
- Array get_rids() const;
+ virtual void set_spacing(TextServer::SpacingType p_spacing, int p_value);
+ virtual int get_spacing(TextServer::SpacingType p_spacing) const override;
- void update_changes();
+ // Output.
+ virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override;
+ virtual RID _get_rid() const override;
- Font();
- ~Font();
+ FontVariation();
+ ~FontVariation();
};
#endif /* FONT_H */
diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h
index 2b04ead0af..e4bac15e4b 100644
--- a/scene/resources/gradient.h
+++ b/scene/resources/gradient.h
@@ -157,10 +157,10 @@ public:
const Point &pointP3 = points[p3];
float x = (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset);
- float r = Math::cubic_interpolate(pointP0.color.r, pointFirst.color.r, pointSecond.color.r, pointP3.color.r, x);
- float g = Math::cubic_interpolate(pointP0.color.g, pointFirst.color.g, pointSecond.color.g, pointP3.color.g, x);
- float b = Math::cubic_interpolate(pointP0.color.b, pointFirst.color.b, pointSecond.color.b, pointP3.color.b, x);
- float a = Math::cubic_interpolate(pointP0.color.a, pointFirst.color.a, pointSecond.color.a, pointP3.color.a, x);
+ float r = Math::cubic_interpolate(pointFirst.color.r, pointSecond.color.r, pointP0.color.r, pointP3.color.r, x);
+ float g = Math::cubic_interpolate(pointFirst.color.g, pointSecond.color.g, pointP0.color.g, pointP3.color.g, x);
+ float b = Math::cubic_interpolate(pointFirst.color.b, pointSecond.color.b, pointP0.color.b, pointP3.color.b, x);
+ float a = Math::cubic_interpolate(pointFirst.color.a, pointSecond.color.a, pointP0.color.a, pointP3.color.a, x);
return Color(r, g, b, a);
} break;
diff --git a/scene/resources/label_settings.cpp b/scene/resources/label_settings.cpp
new file mode 100644
index 0000000000..e8b986b431
--- /dev/null
+++ b/scene/resources/label_settings.cpp
@@ -0,0 +1,187 @@
+/*************************************************************************/
+/* label_settings.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "label_settings.h"
+
+#include "core/core_string_names.h"
+
+void LabelSettings::_font_changed() {
+ emit_changed();
+}
+
+void LabelSettings::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_line_spacing", "spacing"), &LabelSettings::set_line_spacing);
+ ClassDB::bind_method(D_METHOD("get_line_spacing"), &LabelSettings::get_line_spacing);
+
+ ClassDB::bind_method(D_METHOD("set_font", "font"), &LabelSettings::set_font);
+ ClassDB::bind_method(D_METHOD("get_font"), &LabelSettings::get_font);
+
+ ClassDB::bind_method(D_METHOD("set_font_size", "size"), &LabelSettings::set_font_size);
+ ClassDB::bind_method(D_METHOD("get_font_size"), &LabelSettings::get_font_size);
+
+ ClassDB::bind_method(D_METHOD("set_font_color", "color"), &LabelSettings::set_font_color);
+ ClassDB::bind_method(D_METHOD("get_font_color"), &LabelSettings::get_font_color);
+
+ ClassDB::bind_method(D_METHOD("set_outline_size", "size"), &LabelSettings::set_outline_size);
+ ClassDB::bind_method(D_METHOD("get_outline_size"), &LabelSettings::get_outline_size);
+
+ ClassDB::bind_method(D_METHOD("set_outline_color", "color"), &LabelSettings::set_outline_color);
+ ClassDB::bind_method(D_METHOD("get_outline_color"), &LabelSettings::get_outline_color);
+
+ ClassDB::bind_method(D_METHOD("set_shadow_size", "size"), &LabelSettings::set_shadow_size);
+ ClassDB::bind_method(D_METHOD("get_shadow_size"), &LabelSettings::get_shadow_size);
+
+ ClassDB::bind_method(D_METHOD("set_shadow_color", "color"), &LabelSettings::set_shadow_color);
+ ClassDB::bind_method(D_METHOD("get_shadow_color"), &LabelSettings::get_shadow_color);
+
+ ClassDB::bind_method(D_METHOD("set_shadow_offset", "offset"), &LabelSettings::set_shadow_offset);
+ ClassDB::bind_method(D_METHOD("get_shadow_offset"), &LabelSettings::get_shadow_offset);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_spacing", PROPERTY_HINT_NONE, "suffix:px"), "set_line_spacing", "get_line_spacing");
+
+ ADD_GROUP("Font", "font");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,1024,1,or_greater,suffix:px"), "set_font_size", "get_font_size");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "font_color"), "set_font_color", "get_font_color");
+
+ ADD_GROUP("Outline", "outline");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1,or_greater,suffix:px"), "set_outline_size", "get_outline_size");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color");
+
+ ADD_GROUP("Shadow", "shadow");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_size", PROPERTY_HINT_RANGE, "0,127,1,or_greater,suffix:px"), "set_shadow_size", "get_shadow_size");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "shadow_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_shadow_offset", "get_shadow_offset");
+}
+
+void LabelSettings::set_line_spacing(real_t p_spacing) {
+ if (line_spacing != p_spacing) {
+ line_spacing = p_spacing;
+ emit_changed();
+ }
+}
+
+real_t LabelSettings::get_line_spacing() const {
+ return line_spacing;
+}
+
+void LabelSettings::set_font(const Ref<Font> &p_font) {
+ if (font != p_font) {
+ if (font.is_valid()) {
+ font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed));
+ }
+ font = p_font;
+ if (font.is_valid()) {
+ font->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed), varray(), CONNECT_REFERENCE_COUNTED);
+ }
+ emit_changed();
+ }
+}
+
+Ref<Font> LabelSettings::get_font() const {
+ return font;
+}
+
+void LabelSettings::set_font_size(int p_size) {
+ if (font_size != p_size) {
+ font_size = p_size;
+ emit_changed();
+ }
+}
+
+int LabelSettings::get_font_size() const {
+ return font_size;
+}
+
+void LabelSettings::set_font_color(const Color &p_color) {
+ if (font_color != p_color) {
+ font_color = p_color;
+ emit_changed();
+ }
+}
+
+Color LabelSettings::get_font_color() const {
+ return font_color;
+}
+
+void LabelSettings::set_outline_size(int p_size) {
+ if (outline_size != p_size) {
+ outline_size = p_size;
+ emit_changed();
+ }
+}
+
+int LabelSettings::get_outline_size() const {
+ return outline_size;
+}
+
+void LabelSettings::set_outline_color(const Color &p_color) {
+ if (outline_color != p_color) {
+ outline_color = p_color;
+ emit_changed();
+ }
+}
+
+Color LabelSettings::get_outline_color() const {
+ return outline_color;
+}
+
+void LabelSettings::set_shadow_size(int p_size) {
+ if (shadow_size != p_size) {
+ shadow_size = p_size;
+ emit_changed();
+ }
+}
+
+int LabelSettings::get_shadow_size() const {
+ return shadow_size;
+}
+
+void LabelSettings::set_shadow_color(const Color &p_color) {
+ if (shadow_color != p_color) {
+ shadow_color = p_color;
+ emit_changed();
+ }
+}
+
+Color LabelSettings::get_shadow_color() const {
+ return shadow_color;
+}
+
+void LabelSettings::set_shadow_offset(const Vector2 &p_offset) {
+ if (shadow_offset != p_offset) {
+ shadow_offset = p_offset;
+ emit_changed();
+ }
+}
+
+Vector2 LabelSettings::get_shadow_offset() const {
+ return shadow_offset;
+}
diff --git a/editor/plugins/font_editor_plugin.h b/scene/resources/label_settings.h
index 3f0700d880..d2644a7484 100644
--- a/editor/plugins/font_editor_plugin.h
+++ b/scene/resources/label_settings.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* font_editor_plugin.h */
+/* label_settings.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,50 +28,62 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef FONT_EDITOR_PLUGIN_H
-#define FONT_EDITOR_PLUGIN_H
+#ifndef LABEL_SETTINGS_H
+#define LABEL_SETTINGS_H
-#include "editor/editor_plugin.h"
-#include "scene/resources/font.h"
-#include "scene/resources/text_line.h"
+#include "core/io/resource.h"
+#include "font.h"
-class FontDataPreview : public Control {
- GDCLASS(FontDataPreview, Control);
+/*************************************************************************/
-protected:
- void _notification(int p_what);
- static void _bind_methods();
+class LabelSettings : public Resource {
+ GDCLASS(LabelSettings, Resource);
- Ref<TextLine> line;
+ real_t line_spacing = 0;
-public:
- virtual Size2 get_minimum_size() const override;
+ Ref<Font> font;
+ int font_size = Font::DEFAULT_FONT_SIZE;
+ Color font_color = Color(0.875, 0.875, 0.875);
- void set_data(const Ref<FontData> &p_data);
+ int outline_size = 0;
+ Color outline_color = Color(1, 1, 1);
- FontDataPreview();
-};
+ int shadow_size = 0;
+ Color shadow_color = Color(1, 1, 1);
+ Vector2 shadow_offset = Vector2(1, 1);
-/*************************************************************************/
+ void _font_changed();
-class EditorInspectorPluginFont : public EditorInspectorPlugin {
- GDCLASS(EditorInspectorPluginFont, EditorInspectorPlugin);
+protected:
+ static void _bind_methods();
public:
- virtual bool can_handle(Object *p_object) override;
- virtual void parse_begin(Object *p_object) override;
- virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false) override;
-};
+ void set_line_spacing(real_t p_spacing);
+ real_t get_line_spacing() const;
-/*************************************************************************/
+ void set_font(const Ref<Font> &p_font);
+ Ref<Font> get_font() const;
-class FontEditorPlugin : public EditorPlugin {
- GDCLASS(FontEditorPlugin, EditorPlugin);
+ void set_font_size(int p_size);
+ int get_font_size() const;
-public:
- FontEditorPlugin();
+ void set_font_color(const Color &p_color);
+ Color get_font_color() const;
+
+ void set_outline_size(int p_size);
+ int get_outline_size() const;
+
+ void set_outline_color(const Color &p_color);
+ Color get_outline_color() const;
+
+ void set_shadow_size(int p_size);
+ int get_shadow_size() const;
+
+ void set_shadow_color(const Color &p_color);
+ Color get_shadow_color() const;
- virtual String get_name() const override { return "Font"; }
+ void set_shadow_offset(const Vector2 &p_offset);
+ Vector2 get_shadow_offset() const;
};
-#endif // FONT_EDITOR_PLUGIN_H
+#endif // LABEL_SETTINGS_H
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index c8bfb73b2d..2d3f9d9afc 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -107,7 +107,7 @@ void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::ARRAY, name + PNAME("shapes")));
p_list->push_back(PropertyInfo(Variant::OBJECT, name + PNAME("navmesh"), PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"));
p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, name + PNAME("navmesh_transform"), PROPERTY_HINT_NONE, "suffix:m"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, name + PNAME("preview"), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_HELPER));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, name + PNAME("preview"), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT));
}
}
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index f4fd81b25f..68441afb1c 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -2190,12 +2190,12 @@ RibbonTrailMesh::RibbonTrailMesh() {
/* TextMesh */
/*************************************************************************/
-void TextMesh::_generate_glyph_mesh_data(uint32_t p_hash, const Glyph &p_gl) const {
- if (cache.has(p_hash)) {
+void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph &p_gl) const {
+ if (cache.has(p_key)) {
return;
}
- GlyphMeshData &gl_data = cache[p_hash];
+ GlyphMeshData &gl_data = cache[p_key];
Dictionary d = TS->font_get_glyph_contours(p_gl.font_rid, p_gl.font_size, p_gl.index);
Vector2 origin = Vector2(p_gl.x_off, p_gl.y_off) * pixel_size;
@@ -2376,7 +2376,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
TS->shaped_text_set_direction(text_rid, text_direction);
String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
- TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, language);
+ TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, font->get_opentype_features(), language);
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
+ }
Array stt;
if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) {
@@ -2394,7 +2397,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
} else if (dirty_font) {
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_set_span_update_font(text_rid, i, font->get_rids(), font_size, font->get_opentype_features());
+ }
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
}
dirty_font = false;
@@ -2437,11 +2443,9 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
continue;
}
if (glyphs[i].font_rid != RID()) {
- uint32_t hash = hash_one_uint64(glyphs[i].font_rid.get_id());
- hash = hash_murmur3_one_32(glyphs[i].index, hash);
-
- _generate_glyph_mesh_data(hash, glyphs[i]);
- GlyphMeshData &gl_data = cache[hash];
+ GlyphMeshKey key = GlyphMeshKey(glyphs[i].font_rid.get_id(), glyphs[i].index);
+ _generate_glyph_mesh_data(key, glyphs[i]);
+ GlyphMeshData &gl_data = cache[key];
p_size += glyphs[i].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1);
i_size += glyphs[i].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1);
@@ -2496,10 +2500,9 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
continue;
}
if (glyphs[i].font_rid != RID()) {
- uint32_t hash = hash_one_uint64(glyphs[i].font_rid.get_id());
- hash = hash_murmur3_one_32(glyphs[i].index, hash);
-
- const GlyphMeshData &gl_data = cache[hash];
+ GlyphMeshKey key = GlyphMeshKey(glyphs[i].font_rid.get_id(), glyphs[i].index);
+ _generate_glyph_mesh_data(key, glyphs[i]);
+ const GlyphMeshData &gl_data = cache[key];
int64_t ts = gl_data.triangles.size();
const Vector2 *ts_ptr = gl_data.triangles.ptr();
@@ -2682,10 +2685,6 @@ void TextMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &TextMesh::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &TextMesh::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &TextMesh::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &TextMesh::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features"), &TextMesh::clear_opentype_features);
-
ClassDB::bind_method(D_METHOD("set_language", "language"), &TextMesh::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &TextMesh::get_language);
@@ -2704,11 +2703,9 @@ void TextMesh::_bind_methods() {
ADD_GROUP("Text", "");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,127,1,suffix:px"), "set_font_size", "get_font_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px"), "set_font_size", "get_font_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase");
- 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("Mesh", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001,suffix:m"), "set_pixel_size", "get_pixel_size");
@@ -2716,9 +2713,11 @@ void TextMesh::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_RANGE, "0.0,100.0,0.001,or_greater,suffix:m"), "set_depth", "get_depth");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width", PROPERTY_HINT_NONE, "suffix:m"), "set_width", "get_width");
- ADD_GROUP("Locale", "");
+ ADD_GROUP("BiDi", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left"), "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, "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");
}
void TextMesh::_notification(int p_what) {
@@ -2735,56 +2734,6 @@ void TextMesh::_notification(int p_what) {
}
}
-bool TextMesh::_set(const StringName &p_name, const Variant &p_value) {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- int value = p_value;
- if (value == -1) {
- if (opentype_features.has(tag)) {
- opentype_features.erase(tag);
- dirty_font = true;
- _request_update();
- }
- } else {
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
- opentype_features[tag] = value;
- dirty_font = true;
- _request_update();
- }
- }
- notify_property_list_changed();
- return true;
- }
-
- return false;
-}
-
-bool TextMesh::_get(const StringName &p_name, Variant &r_ret) const {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- if (opentype_features.has(tag)) {
- r_ret = opentype_features[tag];
- return true;
- } else {
- r_ret = -1;
- return true;
- }
- }
- return false;
-}
-
-void TextMesh::_get_property_list(List<PropertyInfo> *p_list) const {
- for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
- String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
- }
- p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
-}
-
TextMesh::TextMesh() {
primitive_type = PRIMITIVE_TRIANGLES;
text_rid = TS->create_shaped_text();
@@ -2848,7 +2797,7 @@ Ref<Font> TextMesh::get_font() const {
}
Ref<Font> TextMesh::_get_font_or_default() const {
- if (font_override.is_valid() && font_override->get_data_count() > 0) {
+ if (font_override.is_valid()) {
return font_override;
}
@@ -2955,29 +2904,6 @@ TextServer::Direction TextMesh::get_text_direction() const {
return text_direction;
}
-void TextMesh::clear_opentype_features() {
- opentype_features.clear();
- dirty_font = true;
- _request_update();
-}
-
-void TextMesh::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_font = true;
- _request_update();
- }
-}
-
-int TextMesh::get_opentype_feature(const String &p_name) const {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag)) {
- return -1;
- }
- return opentype_features[tag];
-}
-
void TextMesh::set_language(const String &p_language) {
if (language != p_language) {
language = p_language;
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 38cc7db5fe..cb93211756 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -475,6 +475,7 @@ private:
sharp = p_sharp;
};
};
+
struct ContourInfo {
real_t length = 0.0;
bool ccw = true;
@@ -484,6 +485,27 @@ private:
ccw = p_ccw;
}
};
+
+ struct GlyphMeshKey {
+ uint64_t font_id;
+ uint32_t gl_id;
+
+ bool operator==(const GlyphMeshKey &p_b) const {
+ return (font_id == p_b.font_id) && (gl_id == p_b.gl_id);
+ }
+
+ GlyphMeshKey(uint64_t p_font_id, uint32_t p_gl_id) {
+ font_id = p_font_id;
+ gl_id = p_gl_id;
+ }
+ };
+
+ struct GlyphMeshKeyHasher {
+ _FORCE_INLINE_ static uint32_t hash(const GlyphMeshKey &p_a) {
+ return hash_murmur3_buffer(&p_a, sizeof(GlyphMeshKey));
+ }
+ };
+
struct GlyphMeshData {
Vector<Vector2> triangles;
Vector<Vector<ContourPoint>> contours;
@@ -491,7 +513,7 @@ private:
Vector2 min_p = Vector2(INFINITY, INFINITY);
Vector2 max_p = Vector2(-INFINITY, -INFINITY);
};
- mutable HashMap<uint32_t, GlyphMeshData> cache;
+ mutable HashMap<GlyphMeshKey, GlyphMeshData, GlyphMeshKeyHasher> cache;
RID text_rid;
String text;
@@ -503,7 +525,6 @@ private:
HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER;
bool uppercase = false;
- Dictionary opentype_features;
String language;
TextServer::Direction text_direction = TextServer::DIRECTION_AUTO;
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
@@ -517,7 +538,7 @@ private:
mutable bool dirty_font = true;
mutable bool dirty_cache = true;
- void _generate_glyph_mesh_data(uint32_t p_hash, const Glyph &p_glyph) const;
+ void _generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph &p_glyph) const;
void _font_changed();
protected:
@@ -526,10 +547,6 @@ protected:
virtual void _create_mesh_array(Array &p_arr) const override;
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
-
public:
GDVIRTUAL2RC(Array, _structured_text_parser, Array, String)
@@ -552,10 +569,6 @@ public:
void set_text_direction(TextServer::Direction p_text_direction);
TextServer::Direction get_text_direction() const;
- void set_opentype_feature(const String &p_name, int p_value);
- int get_opentype_feature(const String &p_name) const;
- void clear_opentype_features();
-
void set_language(const String &p_language);
String get_language() const;
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 66afb001fb..100e8ea7c6 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -65,14 +65,18 @@ Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, Varia
return ERR_PARSE_ERROR;
}
- String unique_id = token.value;
+ if (p_data->no_placeholders) {
+ r_res.unref();
+ } else {
+ String unique_id = token.value;
- if (!p_data->resource_map.has(unique_id)) {
- r_err_str = "Found unique_id reference before mapping, sub-resources stored out of order in resource file";
- return ERR_PARSE_ERROR;
- }
+ if (!p_data->resource_map.has(unique_id)) {
+ r_err_str = "Found unique_id reference before mapping, sub-resources stored out of order in resource file";
+ return ERR_PARSE_ERROR;
+ }
- r_res = p_data->resource_map[unique_id];
+ r_res = p_data->resource_map[unique_id];
+ }
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) {
@@ -91,11 +95,15 @@ Error ResourceLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, Varia
return ERR_PARSE_ERROR;
}
- String id = token.value;
+ if (p_data->no_placeholders) {
+ r_res.unref();
+ } else {
+ String id = token.value;
- ERR_FAIL_COND_V(!p_data->rev_external_resources.has(id), ERR_PARSE_ERROR);
+ ERR_FAIL_COND_V(!p_data->rev_external_resources.has(id), ERR_PARSE_ERROR);
- r_res = p_data->rev_external_resources[id];
+ r_res = p_data->rev_external_resources[id];
+ }
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) {
@@ -1066,7 +1074,7 @@ static void bs_save_unicode_string(Ref<FileAccess> p_f, const String &p_string,
p_f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1);
}
-Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_path) {
+Error ResourceLoaderText::save_as_binary(const String &p_path) {
if (error) {
return error;
}
@@ -1271,7 +1279,7 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa
}
if (next_tag.name == "node") {
- //this is a node, must save one more!
+ // This is a node, must save one more!
if (!is_scene) {
error_text += "found the 'node' tag on a resource file!";
@@ -1346,6 +1354,126 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa
return OK;
}
+Error ResourceLoaderText::get_classes_used(HashSet<StringName> *r_classes) {
+ if (error) {
+ return error;
+ }
+
+ ignore_resource_parsing = true;
+
+ DummyReadData dummy_read;
+ dummy_read.no_placeholders = true;
+ VariantParser::ResourceParser rp;
+ rp.ext_func = _parse_ext_resource_dummys;
+ rp.sub_func = _parse_sub_resource_dummys;
+ rp.userdata = &dummy_read;
+
+ while (next_tag.name == "ext_resource") {
+ error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp);
+
+ if (error) {
+ _printerr();
+ return error;
+ }
+ }
+
+ while (next_tag.name == "sub_resource" || next_tag.name == "resource") {
+ if (next_tag.name == "sub_resource") {
+ if (!next_tag.fields.has("type")) {
+ error = ERR_FILE_CORRUPT;
+ error_text = "Missing 'type' in external resource tag";
+ _printerr();
+ return error;
+ }
+
+ r_classes->insert(next_tag.fields["type"]);
+
+ } else {
+ r_classes->insert(next_tag.fields["res_type"]);
+ }
+
+ while (true) {
+ String assign;
+ Variant value;
+
+ error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp);
+
+ if (error) {
+ if (error == ERR_FILE_EOF) {
+ return OK;
+ }
+
+ _printerr();
+ return error;
+ }
+
+ if (!assign.is_empty()) {
+ continue;
+ } else if (!next_tag.name.is_empty()) {
+ error = OK;
+ break;
+ } else {
+ error = ERR_FILE_CORRUPT;
+ error_text = "Premature end of file while parsing [sub_resource]";
+ _printerr();
+ return error;
+ }
+ }
+ }
+
+ while (next_tag.name == "node") {
+ // This is a node, must save one more!
+
+ if (!is_scene) {
+ error_text += "found the 'node' tag on a resource file!";
+ _printerr();
+ error = ERR_FILE_CORRUPT;
+ return error;
+ }
+
+ if (!next_tag.fields.has("type")) {
+ error = ERR_FILE_CORRUPT;
+ error_text = "Missing 'type' in external resource tag";
+ _printerr();
+ return error;
+ }
+
+ r_classes->insert(next_tag.fields["type"]);
+
+ while (true) {
+ String assign;
+ Variant value;
+
+ error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp);
+
+ if (error) {
+ if (error == ERR_FILE_MISSING_DEPENDENCIES) {
+ // Resource loading error, just skip it.
+ } else if (error != ERR_FILE_EOF) {
+ _printerr();
+ return error;
+ } else {
+ return OK;
+ }
+ }
+
+ if (!assign.is_empty()) {
+ continue;
+ } else if (!next_tag.name.is_empty()) {
+ error = OK;
+ break;
+ } else {
+ error = ERR_FILE_CORRUPT;
+ error_text = "Premature end of file while parsing [sub_resource]";
+ _printerr();
+ return error;
+ }
+ }
+ }
+
+ return OK;
+}
+
String ResourceLoaderText::recognize(Ref<FileAccess> p_f) {
error = OK;
@@ -1473,6 +1601,26 @@ bool ResourceFormatLoaderText::handles_type(const String &p_type) const {
return true;
}
+void ResourceFormatLoaderText::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) {
+ String ext = p_path.get_extension().to_lower();
+ if (ext == "tscn") {
+ r_classes->insert("PackedScene");
+ }
+
+ // ...for anything else must test...
+
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ if (f.is_null()) {
+ return; // Could not read.
+ }
+
+ ResourceLoaderText loader;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ loader.res_path = loader.local_path;
+ loader.open(f);
+ loader.get_classes_used(r_classes);
+}
+
String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
String ext = p_path.get_extension().to_lower();
if (ext == "tscn") {
@@ -1561,7 +1709,7 @@ Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path,
loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
loader.res_path = loader.local_path;
loader.open(f);
- return loader.save_as_binary(f, p_dst_path);
+ return loader.save_as_binary(p_dst_path);
}
/*****************************************************************************************************/
diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h
index 5c6a937bf2..69bb40502f 100644
--- a/scene/resources/resource_format_text.h
+++ b/scene/resources/resource_format_text.h
@@ -90,6 +90,7 @@ class ResourceLoaderText {
};
struct DummyReadData {
+ bool no_placeholders = false;
HashMap<Ref<Resource>, int> external_resources;
HashMap<String, Ref<Resource>> rev_external_resources;
HashMap<Ref<Resource>, int> resource_index_map;
@@ -125,8 +126,9 @@ public:
ResourceUID::ID get_uid(Ref<FileAccess> p_f);
void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types);
Error rename_dependencies(Ref<FileAccess> p_f, const String &p_path, const HashMap<String, String> &p_map);
+ Error get_classes_used(HashSet<StringName> *r_classes);
- Error save_as_binary(Ref<FileAccess> p_f, const String &p_path);
+ Error save_as_binary(const String &p_path);
ResourceLoaderText();
};
@@ -137,6 +139,8 @@ public:
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
+ virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
+
virtual String get_resource_type(const String &p_path) const;
virtual ResourceUID::ID get_resource_uid(const String &p_path) const;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
diff --git a/scene/resources/skeleton_profile.cpp b/scene/resources/skeleton_profile.cpp
new file mode 100644
index 0000000000..0714de470c
--- /dev/null
+++ b/scene/resources/skeleton_profile.cpp
@@ -0,0 +1,793 @@
+/*************************************************************************/
+/* skeleton_profile.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "skeleton_profile.h"
+
+bool SkeletonProfile::_set(const StringName &p_path, const Variant &p_value) {
+ ERR_FAIL_COND_V(is_read_only, false);
+ String path = p_path;
+
+ if (path.begins_with("groups/")) {
+ int which = path.get_slicec('/', 1).to_int();
+ String what = path.get_slicec('/', 2);
+ ERR_FAIL_INDEX_V(which, groups.size(), false);
+
+ if (what == "group_name") {
+ set_group_name(which, p_value);
+ } else if (what == "texture") {
+ set_texture(which, p_value);
+ } else {
+ return false;
+ }
+ }
+
+ if (path.begins_with("bones/")) {
+ int which = path.get_slicec('/', 1).to_int();
+ String what = path.get_slicec('/', 2);
+ ERR_FAIL_INDEX_V(which, bones.size(), false);
+
+ if (what == "bone_name") {
+ set_bone_name(which, p_value);
+ } else if (what == "bone_parent") {
+ set_bone_parent(which, p_value);
+ } else if (what == "tail_direction") {
+ set_tail_direction(which, static_cast<TailDirection>((int)p_value));
+ } else if (what == "bone_tail") {
+ set_bone_tail(which, p_value);
+ } else if (what == "reference_pose") {
+ set_reference_pose(which, p_value);
+ } else if (what == "handle_offset") {
+ set_handle_offset(which, p_value);
+ } else if (what == "group") {
+ set_group(which, p_value);
+ } else if (what == "require") {
+ set_require(which, p_value);
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SkeletonProfile::_get(const StringName &p_path, Variant &r_ret) const {
+ String path = p_path;
+
+ if (path.begins_with("groups/")) {
+ int which = path.get_slicec('/', 1).to_int();
+ String what = path.get_slicec('/', 2);
+ ERR_FAIL_INDEX_V(which, groups.size(), false);
+
+ if (what == "group_name") {
+ r_ret = get_group_name(which);
+ } else if (what == "texture") {
+ r_ret = get_texture(which);
+ } else {
+ return false;
+ }
+ }
+
+ if (path.begins_with("bones/")) {
+ int which = path.get_slicec('/', 1).to_int();
+ String what = path.get_slicec('/', 2);
+ ERR_FAIL_INDEX_V(which, bones.size(), false);
+
+ if (what == "bone_name") {
+ r_ret = get_bone_name(which);
+ } else if (what == "bone_parent") {
+ r_ret = get_bone_parent(which);
+ } else if (what == "tail_direction") {
+ r_ret = get_tail_direction(which);
+ } else if (what == "bone_tail") {
+ r_ret = get_bone_tail(which);
+ } else if (what == "reference_pose") {
+ r_ret = get_reference_pose(which);
+ } else if (what == "handle_offset") {
+ r_ret = get_handle_offset(which);
+ } else if (what == "group") {
+ r_ret = get_group(which);
+ } else if (what == "require") {
+ r_ret = is_require(which);
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+void SkeletonProfile::_validate_property(PropertyInfo &property) const {
+ if (is_read_only) {
+ if (property.name == ("group_size") || property.name == ("bone_size")) {
+ property.usage = PROPERTY_USAGE_NO_EDITOR;
+ return;
+ }
+ }
+
+ PackedStringArray split = property.name.split("/");
+ if (split.size() == 3 && split[0] == "bones") {
+ if (split[2] == "bone_tail" && get_tail_direction(split[1].to_int()) != TAIL_DIRECTION_SPECIFIC_CHILD) {
+ property.usage = PROPERTY_USAGE_NONE;
+ }
+ }
+}
+
+void SkeletonProfile::_get_property_list(List<PropertyInfo> *p_list) const {
+ if (is_read_only) {
+ return;
+ }
+ String group_names = "";
+ for (int i = 0; i < groups.size(); i++) {
+ String path = "groups/" + itos(i) + "/";
+ p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "group_name"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, path + "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"));
+ if (i > 0) {
+ group_names = group_names + ",";
+ }
+ group_names = group_names + groups[i].group_name;
+ }
+ for (int i = 0; i < bones.size(); i++) {
+ String path = "bones/" + itos(i) + "/";
+ p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "bone_name"));
+ p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "bone_parent"));
+ p_list->push_back(PropertyInfo(Variant::INT, path + "tail_direction", PROPERTY_HINT_ENUM, "AverageChildren,SpecificChild,End"));
+ p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "bone_tail"));
+ p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, path + "reference_pose"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, path + "handle_offset"));
+ p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "group", PROPERTY_HINT_ENUM, group_names));
+ p_list->push_back(PropertyInfo(Variant::BOOL, path + "require"));
+ }
+
+ for (PropertyInfo &E : *p_list) {
+ _validate_property(E);
+ }
+}
+
+int SkeletonProfile::get_group_size() {
+ return groups.size();
+}
+
+void SkeletonProfile::set_group_size(int p_size) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_COND(p_size < 0);
+ groups.resize(p_size);
+ emit_signal("profile_updated");
+ notify_property_list_changed();
+}
+
+StringName SkeletonProfile::get_group_name(int p_group_idx) const {
+ ERR_FAIL_INDEX_V(p_group_idx, groups.size(), StringName());
+ return groups[p_group_idx].group_name;
+}
+
+void SkeletonProfile::set_group_name(int p_group_idx, const StringName p_group_name) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_group_idx, groups.size());
+ groups.write[p_group_idx].group_name = p_group_name;
+ emit_signal("profile_updated");
+}
+
+Ref<Texture2D> SkeletonProfile::get_texture(int p_group_idx) const {
+ ERR_FAIL_INDEX_V(p_group_idx, groups.size(), Ref<Texture2D>());
+ return groups[p_group_idx].texture;
+}
+
+void SkeletonProfile::set_texture(int p_group_idx, const Ref<Texture2D> &p_texture) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_group_idx, groups.size());
+ groups.write[p_group_idx].texture = p_texture;
+ emit_signal("profile_updated");
+}
+
+int SkeletonProfile::get_bone_size() {
+ return bones.size();
+}
+
+void SkeletonProfile::set_bone_size(int p_size) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_COND(p_size < 0);
+ bones.resize(p_size);
+ emit_signal("profile_updated");
+ notify_property_list_changed();
+}
+
+int SkeletonProfile::find_bone(StringName p_bone_name) const {
+ if (p_bone_name == StringName()) {
+ return -1;
+ }
+ for (int i = 0; i < bones.size(); i++) {
+ if (bones[i].bone_name == p_bone_name) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+StringName SkeletonProfile::get_bone_name(int p_bone_idx) const {
+ ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), StringName());
+ return bones[p_bone_idx].bone_name;
+}
+
+void SkeletonProfile::set_bone_name(int p_bone_idx, const StringName p_bone_name) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_bone_idx, bones.size());
+ bones.write[p_bone_idx].bone_name = p_bone_name;
+ emit_signal("profile_updated");
+}
+
+StringName SkeletonProfile::get_bone_parent(int p_bone_idx) const {
+ ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), StringName());
+ return bones[p_bone_idx].bone_parent;
+}
+
+void SkeletonProfile::set_bone_parent(int p_bone_idx, const StringName p_bone_parent) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_bone_idx, bones.size());
+ bones.write[p_bone_idx].bone_parent = p_bone_parent;
+ emit_signal("profile_updated");
+}
+
+SkeletonProfile::TailDirection SkeletonProfile::get_tail_direction(int p_bone_idx) const {
+ ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), TAIL_DIRECTION_AVERAGE_CHILDREN);
+ return bones[p_bone_idx].tail_direction;
+}
+
+void SkeletonProfile::set_tail_direction(int p_bone_idx, const TailDirection p_tail_direction) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_bone_idx, bones.size());
+ bones.write[p_bone_idx].tail_direction = p_tail_direction;
+ emit_signal("profile_updated");
+ notify_property_list_changed();
+}
+
+StringName SkeletonProfile::get_bone_tail(int p_bone_idx) const {
+ ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), StringName());
+ return bones[p_bone_idx].bone_tail;
+}
+
+void SkeletonProfile::set_bone_tail(int p_bone_idx, const StringName p_bone_tail) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_bone_idx, bones.size());
+ bones.write[p_bone_idx].bone_tail = p_bone_tail;
+ emit_signal("profile_updated");
+}
+
+Transform3D SkeletonProfile::get_reference_pose(int p_bone_idx) const {
+ ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), Transform3D());
+ return bones[p_bone_idx].reference_pose;
+}
+
+void SkeletonProfile::set_reference_pose(int p_bone_idx, const Transform3D p_reference_pose) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_bone_idx, bones.size());
+ bones.write[p_bone_idx].reference_pose = p_reference_pose;
+ emit_signal("profile_updated");
+}
+
+Vector2 SkeletonProfile::get_handle_offset(int p_bone_idx) const {
+ ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), Vector2());
+ return bones[p_bone_idx].handle_offset;
+}
+
+void SkeletonProfile::set_handle_offset(int p_bone_idx, const Vector2 p_handle_offset) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_bone_idx, bones.size());
+ bones.write[p_bone_idx].handle_offset = p_handle_offset;
+ emit_signal("profile_updated");
+}
+
+StringName SkeletonProfile::get_group(int p_bone_idx) const {
+ ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), StringName());
+ return bones[p_bone_idx].group;
+}
+
+void SkeletonProfile::set_group(int p_bone_idx, const StringName p_group) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_bone_idx, bones.size());
+ bones.write[p_bone_idx].group = p_group;
+ emit_signal("profile_updated");
+}
+
+bool SkeletonProfile::is_require(int p_bone_idx) const {
+ ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), false);
+ return bones[p_bone_idx].require;
+}
+
+void SkeletonProfile::set_require(int p_bone_idx, const bool p_require) {
+ if (is_read_only) {
+ return;
+ }
+ ERR_FAIL_INDEX(p_bone_idx, bones.size());
+ bones.write[p_bone_idx].require = p_require;
+ emit_signal("profile_updated");
+}
+
+bool SkeletonProfile::has_bone(StringName p_bone_name) {
+ bool is_found = false;
+ for (int i = 0; i < bones.size(); i++) {
+ if (bones[i].bone_name == p_bone_name) {
+ is_found = true;
+ break;
+ }
+ }
+ return is_found;
+}
+
+void SkeletonProfile::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_group_size", "size"), &SkeletonProfile::set_group_size);
+ ClassDB::bind_method(D_METHOD("get_group_size"), &SkeletonProfile::get_group_size);
+
+ ClassDB::bind_method(D_METHOD("get_group_name", "group_idx"), &SkeletonProfile::get_group_name);
+ ClassDB::bind_method(D_METHOD("set_group_name", "group_idx", "group_name"), &SkeletonProfile::set_group_name);
+
+ ClassDB::bind_method(D_METHOD("get_texture", "group_idx"), &SkeletonProfile::get_texture);
+ ClassDB::bind_method(D_METHOD("set_texture", "group_idx", "texture"), &SkeletonProfile::set_texture);
+
+ ClassDB::bind_method(D_METHOD("set_bone_size", "size"), &SkeletonProfile::set_bone_size);
+ ClassDB::bind_method(D_METHOD("get_bone_size"), &SkeletonProfile::get_bone_size);
+
+ ClassDB::bind_method(D_METHOD("find_bone", "bone_name"), &SkeletonProfile::find_bone);
+
+ ClassDB::bind_method(D_METHOD("get_bone_name", "bone_idx"), &SkeletonProfile::get_bone_name);
+ ClassDB::bind_method(D_METHOD("set_bone_name", "bone_idx", "bone_name"), &SkeletonProfile::set_bone_name);
+
+ ClassDB::bind_method(D_METHOD("get_bone_parent", "bone_idx"), &SkeletonProfile::get_bone_parent);
+ ClassDB::bind_method(D_METHOD("set_bone_parent", "bone_idx", "bone_parent"), &SkeletonProfile::set_bone_parent);
+
+ ClassDB::bind_method(D_METHOD("get_tail_direction", "bone_idx"), &SkeletonProfile::get_tail_direction);
+ ClassDB::bind_method(D_METHOD("set_tail_direction", "bone_idx", "tail_direction"), &SkeletonProfile::set_tail_direction);
+
+ ClassDB::bind_method(D_METHOD("get_bone_tail", "bone_idx"), &SkeletonProfile::get_bone_tail);
+ ClassDB::bind_method(D_METHOD("set_bone_tail", "bone_idx", "bone_tail"), &SkeletonProfile::set_bone_tail);
+
+ ClassDB::bind_method(D_METHOD("get_reference_pose", "bone_idx"), &SkeletonProfile::get_reference_pose);
+ ClassDB::bind_method(D_METHOD("set_reference_pose", "bone_idx", "bone_name"), &SkeletonProfile::set_reference_pose);
+
+ ClassDB::bind_method(D_METHOD("get_handle_offset", "bone_idx"), &SkeletonProfile::get_handle_offset);
+ ClassDB::bind_method(D_METHOD("set_handle_offset", "bone_idx", "handle_offset"), &SkeletonProfile::set_handle_offset);
+
+ ClassDB::bind_method(D_METHOD("get_group", "bone_idx"), &SkeletonProfile::get_group);
+ ClassDB::bind_method(D_METHOD("set_group", "bone_idx", "group"), &SkeletonProfile::set_group);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "group_size", PROPERTY_HINT_RANGE, "0,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Groups,groups/"), "set_group_size", "get_group_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_size", PROPERTY_HINT_RANGE, "0,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Bones,bones/"), "set_bone_size", "get_bone_size");
+
+ ADD_SIGNAL(MethodInfo("profile_updated"));
+
+ BIND_ENUM_CONSTANT(TAIL_DIRECTION_AVERAGE_CHILDREN);
+ BIND_ENUM_CONSTANT(TAIL_DIRECTION_SPECIFIC_CHILD);
+ BIND_ENUM_CONSTANT(TAIL_DIRECTION_END);
+}
+
+SkeletonProfile::SkeletonProfile() {
+}
+
+SkeletonProfile::~SkeletonProfile() {
+}
+
+SkeletonProfileHumanoid::SkeletonProfileHumanoid() {
+ is_read_only = true;
+
+ groups.resize(4);
+
+ groups.write[0].group_name = "Body";
+ groups.write[1].group_name = "Face";
+ groups.write[2].group_name = "LeftHand";
+ groups.write[3].group_name = "RightHand";
+
+ bones.resize(56);
+
+ bones.write[0].bone_name = "Root";
+ bones.write[0].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0);
+ bones.write[0].handle_offset = Vector2(0.5, 0.91);
+ bones.write[0].group = "Body";
+
+ bones.write[1].bone_name = "Hips";
+ bones.write[1].bone_parent = "Root";
+ bones.write[1].tail_direction = TAIL_DIRECTION_SPECIFIC_CHILD;
+ bones.write[1].bone_tail = "Spine";
+ bones.write[1].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0);
+ bones.write[1].handle_offset = Vector2(0.5, 0.5);
+ bones.write[1].group = "Body";
+ bones.write[1].require = true;
+
+ bones.write[2].bone_name = "Spine";
+ bones.write[2].bone_parent = "Hips";
+ bones.write[2].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0);
+ bones.write[2].handle_offset = Vector2(0.5, 0.43);
+ bones.write[2].group = "Body";
+ bones.write[2].require = true;
+
+ bones.write[3].bone_name = "Chest";
+ bones.write[3].bone_parent = "Spine";
+ bones.write[3].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0);
+ bones.write[3].handle_offset = Vector2(0.5, 0.36);
+ bones.write[3].group = "Body";
+
+ bones.write[4].bone_name = "UpperChest";
+ bones.write[4].bone_parent = "Chest";
+ bones.write[4].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0);
+ bones.write[4].handle_offset = Vector2(0.5, 0.29);
+ bones.write[4].group = "Body";
+
+ bones.write[5].bone_name = "Neck";
+ bones.write[5].bone_parent = "UpperChest";
+ bones.write[5].tail_direction = TAIL_DIRECTION_SPECIFIC_CHILD;
+ bones.write[5].bone_tail = "Head";
+ bones.write[5].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0);
+ bones.write[5].handle_offset = Vector2(0.5, 0.23);
+ bones.write[5].group = "Body";
+ bones.write[5].require = true;
+
+ bones.write[6].bone_name = "Head";
+ bones.write[6].bone_parent = "Neck";
+ bones.write[6].tail_direction = TAIL_DIRECTION_END;
+ bones.write[6].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0);
+ bones.write[6].handle_offset = Vector2(0.5, 0.18);
+ bones.write[6].group = "Body";
+ bones.write[6].require = true;
+
+ bones.write[7].bone_name = "LeftEye";
+ bones.write[7].bone_parent = "Head";
+ bones.write[7].reference_pose = Transform3D(1, 0, 0, 0, 0, -1, 0, 1, 0, 0.05, 0.15, 0);
+ bones.write[7].handle_offset = Vector2(0.6, 0.46);
+ bones.write[7].group = "Face";
+
+ bones.write[8].bone_name = "RightEye";
+ bones.write[8].bone_parent = "Head";
+ bones.write[8].reference_pose = Transform3D(1, 0, 0, 0, 0, -1, 0, 1, 0, -0.05, 0.15, 0);
+ bones.write[8].handle_offset = Vector2(0.37, 0.46);
+ bones.write[8].group = "Face";
+
+ bones.write[9].bone_name = "Jaw";
+ bones.write[9].bone_parent = "Head";
+ bones.write[9].reference_pose = Transform3D(-1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0.05, 0.05);
+ bones.write[9].handle_offset = Vector2(0.46, 0.75);
+ bones.write[9].group = "Face";
+
+ bones.write[10].bone_name = "LeftShoulder";
+ bones.write[10].bone_parent = "UpperChest";
+ bones.write[10].reference_pose = Transform3D(0, 1, 0, 0, 0, 1, 1, 0, 0, 0.05, 0.1, 0);
+ bones.write[10].handle_offset = Vector2(0.55, 0.235);
+ bones.write[10].group = "Body";
+ bones.write[10].require = true;
+
+ bones.write[11].bone_name = "LeftUpperArm";
+ bones.write[11].bone_parent = "LeftShoulder";
+ bones.write[11].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.05, 0);
+ bones.write[11].handle_offset = Vector2(0.6, 0.24);
+ bones.write[11].group = "Body";
+ bones.write[11].require = true;
+
+ bones.write[12].bone_name = "LeftLowerArm";
+ bones.write[12].bone_parent = "LeftUpperArm";
+ bones.write[12].reference_pose = Transform3D(0, 0, -1, 0, 1, 0, 1, 0, 0, 0, 0.25, 0);
+ bones.write[12].handle_offset = Vector2(0.7, 0.24);
+ bones.write[12].group = "Body";
+ bones.write[12].require = true;
+
+ bones.write[13].bone_name = "LeftHand";
+ bones.write[13].bone_parent = "LeftLowerArm";
+ bones.write[13].tail_direction = TAIL_DIRECTION_SPECIFIC_CHILD;
+ bones.write[13].bone_tail = "LeftMiddleProximal";
+ bones.write[13].reference_pose = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 0, 0.25, 0);
+ bones.write[13].handle_offset = Vector2(0.82, 0.235);
+ bones.write[13].group = "Body";
+ bones.write[13].require = true;
+
+ bones.write[14].bone_name = "LeftThumbMetacarpal";
+ bones.write[14].bone_parent = "LeftHand";
+ bones.write[14].reference_pose = Transform3D(0, -0.577, 0.816, 0.707, 0.577, 0.408, -0.707, 0.577, 0.408, -0.025, 0, 0);
+ bones.write[14].handle_offset = Vector2(0.4, 0.8);
+ bones.write[14].group = "LeftHand";
+
+ bones.write[15].bone_name = "LeftThumbProximal";
+ bones.write[15].bone_parent = "LeftThumbMetacarpal";
+ bones.write[15].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.043, 0);
+ bones.write[15].handle_offset = Vector2(0.3, 0.69);
+ bones.write[15].group = "LeftHand";
+
+ bones.write[16].bone_name = "LeftThumbDistal";
+ bones.write[16].bone_parent = "LeftThumbProximal";
+ bones.write[16].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.043, 0);
+ bones.write[16].handle_offset = Vector2(0.23, 0.555);
+ bones.write[16].group = "LeftHand";
+
+ bones.write[17].bone_name = "LeftIndexProximal";
+ bones.write[17].bone_parent = "LeftHand";
+ bones.write[17].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.025, 0.075, 0);
+ bones.write[17].handle_offset = Vector2(0.413, 0.52);
+ bones.write[17].group = "LeftHand";
+
+ bones.write[18].bone_name = "LeftIndexIntermediate";
+ bones.write[18].bone_parent = "LeftIndexProximal";
+ bones.write[18].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0);
+ bones.write[18].handle_offset = Vector2(0.403, 0.36);
+ bones.write[18].group = "LeftHand";
+
+ bones.write[19].bone_name = "LeftIndexDistal";
+ bones.write[19].bone_parent = "LeftIndexIntermediate";
+ bones.write[19].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0);
+ bones.write[19].handle_offset = Vector2(0.403, 0.255);
+ bones.write[19].group = "LeftHand";
+
+ bones.write[20].bone_name = "LeftMiddleProximal";
+ bones.write[20].bone_parent = "LeftHand";
+ bones.write[20].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.075, 0);
+ bones.write[20].handle_offset = Vector2(0.5, 0.51);
+ bones.write[20].group = "LeftHand";
+
+ bones.write[21].bone_name = "LeftMiddleIntermediate";
+ bones.write[21].bone_parent = "LeftMiddleProximal";
+ bones.write[21].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.075, 0);
+ bones.write[21].handle_offset = Vector2(0.5, 0.345);
+ bones.write[21].group = "LeftHand";
+
+ bones.write[22].bone_name = "LeftMiddleDistal";
+ bones.write[22].bone_parent = "LeftMiddleIntermediate";
+ bones.write[22].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0);
+ bones.write[22].handle_offset = Vector2(0.5, 0.22);
+ bones.write[22].group = "LeftHand";
+
+ bones.write[23].bone_name = "LeftRingProximal";
+ bones.write[23].bone_parent = "LeftHand";
+ bones.write[23].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.025, 0.075, 0);
+ bones.write[23].handle_offset = Vector2(0.586, 0.52);
+ bones.write[23].group = "LeftHand";
+
+ bones.write[24].bone_name = "LeftRingIntermediate";
+ bones.write[24].bone_parent = "LeftRingProximal";
+ bones.write[24].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0);
+ bones.write[24].handle_offset = Vector2(0.59, 0.36);
+ bones.write[24].group = "LeftHand";
+
+ bones.write[25].bone_name = "LeftRingDistal";
+ bones.write[25].bone_parent = "LeftRingIntermediate";
+ bones.write[25].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0);
+ bones.write[25].handle_offset = Vector2(0.591, 0.25);
+ bones.write[25].group = "LeftHand";
+
+ bones.write[26].bone_name = "LeftLittleProximal";
+ bones.write[26].bone_parent = "LeftHand";
+ bones.write[26].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.05, 0.05, 0);
+ bones.write[26].handle_offset = Vector2(0.663, 0.543);
+ bones.write[26].group = "LeftHand";
+
+ bones.write[27].bone_name = "LeftLittleIntermediate";
+ bones.write[27].bone_parent = "LeftLittleProximal";
+ bones.write[27].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0);
+ bones.write[27].handle_offset = Vector2(0.672, 0.415);
+ bones.write[27].group = "LeftHand";
+
+ bones.write[28].bone_name = "LeftLittleDistal";
+ bones.write[28].bone_parent = "LeftLittleIntermediate";
+ bones.write[28].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0);
+ bones.write[28].handle_offset = Vector2(0.672, 0.32);
+ bones.write[28].group = "LeftHand";
+
+ bones.write[29].bone_name = "RightShoulder";
+ bones.write[29].bone_parent = "UpperChest";
+ bones.write[29].reference_pose = Transform3D(0, -1, 0, 0, 0, 1, -1, 0, 0, -0.05, 0.1, 0);
+ bones.write[29].handle_offset = Vector2(0.45, 0.235);
+ bones.write[29].group = "Body";
+ bones.write[29].require = true;
+
+ bones.write[30].bone_name = "RightUpperArm";
+ bones.write[30].bone_parent = "RightShoulder";
+ bones.write[30].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.05, 0);
+ bones.write[30].handle_offset = Vector2(0.4, 0.24);
+ bones.write[30].group = "Body";
+ bones.write[30].require = true;
+
+ bones.write[31].bone_name = "RightLowerArm";
+ bones.write[31].bone_parent = "RightUpperArm";
+ bones.write[31].reference_pose = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 0, 0.25, 0);
+ bones.write[31].handle_offset = Vector2(0.3, 0.24);
+ bones.write[31].group = "Body";
+ bones.write[31].require = true;
+
+ bones.write[32].bone_name = "RightHand";
+ bones.write[32].bone_parent = "RightLowerArm";
+ bones.write[32].tail_direction = TAIL_DIRECTION_SPECIFIC_CHILD;
+ bones.write[32].bone_tail = "RightMiddleProximal";
+ bones.write[32].reference_pose = Transform3D(0, 0, -1, 0, 1, 0, 1, 0, 0, 0, 0.25, 0);
+ bones.write[32].handle_offset = Vector2(0.18, 0.235);
+ bones.write[32].group = "Body";
+ bones.write[32].require = true;
+
+ bones.write[33].bone_name = "RightThumbMetacarpal";
+ bones.write[33].bone_parent = "RightHand";
+ bones.write[33].reference_pose = Transform3D(0, 0.577, -0.816, -0.707, 0.577, 0.408, 0.707, 0.577, 0.408, 0.025, 0, 0);
+ bones.write[33].handle_offset = Vector2(0.6, 0.8);
+ bones.write[33].group = "RightHand";
+
+ bones.write[34].bone_name = "RightThumbProximal";
+ bones.write[34].bone_parent = "RightThumbMetacarpal";
+ bones.write[34].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.043, 0);
+ bones.write[34].handle_offset = Vector2(0.7, 0.69);
+ bones.write[34].group = "RightHand";
+
+ bones.write[35].bone_name = "RightThumbDistal";
+ bones.write[35].bone_parent = "RightThumbProximal";
+ bones.write[35].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.043, 0);
+ bones.write[35].handle_offset = Vector2(0.77, 0.555);
+ bones.write[35].group = "RightHand";
+
+ bones.write[36].bone_name = "RightIndexProximal";
+ bones.write[36].bone_parent = "RightHand";
+ bones.write[36].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.025, 0.075, 0);
+ bones.write[36].handle_offset = Vector2(0.587, 0.52);
+ bones.write[36].group = "RightHand";
+
+ bones.write[37].bone_name = "RightIndexIntermediate";
+ bones.write[37].bone_parent = "RightIndexProximal";
+ bones.write[37].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0);
+ bones.write[37].handle_offset = Vector2(0.597, 0.36);
+ bones.write[37].group = "RightHand";
+
+ bones.write[38].bone_name = "RightIndexDistal";
+ bones.write[38].bone_parent = "RightIndexIntermediate";
+ bones.write[38].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0);
+ bones.write[38].handle_offset = Vector2(0.597, 0.255);
+ bones.write[38].group = "RightHand";
+
+ bones.write[39].bone_name = "RightMiddleProximal";
+ bones.write[39].bone_parent = "RightHand";
+ bones.write[39].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.075, 0);
+ bones.write[39].handle_offset = Vector2(0.5, 0.51);
+ bones.write[39].group = "RightHand";
+
+ bones.write[40].bone_name = "RightMiddleIntermediate";
+ bones.write[40].bone_parent = "RightMiddleProximal";
+ bones.write[40].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.075, 0);
+ bones.write[40].handle_offset = Vector2(0.5, 0.345);
+ bones.write[40].group = "RightHand";
+
+ bones.write[41].bone_name = "RightMiddleDistal";
+ bones.write[41].bone_parent = "RightMiddleIntermediate";
+ bones.write[41].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0);
+ bones.write[41].handle_offset = Vector2(0.5, 0.22);
+ bones.write[41].group = "RightHand";
+
+ bones.write[42].bone_name = "RightRingProximal";
+ bones.write[42].bone_parent = "RightHand";
+ bones.write[42].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.025, 0.075, 0);
+ bones.write[42].handle_offset = Vector2(0.414, 0.52);
+ bones.write[42].group = "RightHand";
+
+ bones.write[43].bone_name = "RightRingIntermediate";
+ bones.write[43].bone_parent = "RightRingProximal";
+ bones.write[43].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0);
+ bones.write[43].handle_offset = Vector2(0.41, 0.36);
+ bones.write[43].group = "RightHand";
+
+ bones.write[44].bone_name = "RightRingDistal";
+ bones.write[44].bone_parent = "RightRingIntermediate";
+ bones.write[44].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0);
+ bones.write[44].handle_offset = Vector2(0.409, 0.25);
+ bones.write[44].group = "RightHand";
+
+ bones.write[45].bone_name = "RightLittleProximal";
+ bones.write[45].bone_parent = "RightHand";
+ bones.write[45].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.05, 0.05, 0);
+ bones.write[45].handle_offset = Vector2(0.337, 0.543);
+ bones.write[45].group = "RightHand";
+
+ bones.write[46].bone_name = "RightLittleIntermediate";
+ bones.write[46].bone_parent = "RightLittleProximal";
+ bones.write[46].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0);
+ bones.write[46].handle_offset = Vector2(0.328, 0.415);
+ bones.write[46].group = "RightHand";
+
+ bones.write[47].bone_name = "RightLittleDistal";
+ bones.write[47].bone_parent = "RightLittleIntermediate";
+ bones.write[47].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0);
+ bones.write[47].handle_offset = Vector2(0.328, 0.32);
+ bones.write[47].group = "RightHand";
+
+ bones.write[48].bone_name = "LeftUpperLeg";
+ bones.write[48].bone_parent = "Hips";
+ bones.write[48].reference_pose = Transform3D(-1, 0, 0, 0, -1, 0, 0, 0, 1, 0.1, 0, 0);
+ bones.write[48].handle_offset = Vector2(0.549, 0.49);
+ bones.write[48].group = "Body";
+ bones.write[48].require = true;
+
+ bones.write[49].bone_name = "LeftLowerLeg";
+ bones.write[49].bone_parent = "LeftUpperLeg";
+ bones.write[49].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.375, 0);
+ bones.write[49].handle_offset = Vector2(0.548, 0.683);
+ bones.write[49].group = "Body";
+ bones.write[49].require = true;
+
+ bones.write[50].bone_name = "LeftFoot";
+ bones.write[50].bone_parent = "LeftLowerLeg";
+ bones.write[50].reference_pose = Transform3D(-1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0.375, 0);
+ bones.write[50].handle_offset = Vector2(0.545, 0.9);
+ bones.write[50].group = "Body";
+ bones.write[50].require = true;
+
+ bones.write[51].bone_name = "LeftToes";
+ bones.write[51].bone_parent = "LeftFoot";
+ bones.write[51].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.15, 0);
+ bones.write[51].handle_offset = Vector2(0.545, 0.95);
+ bones.write[51].group = "Body";
+
+ bones.write[52].bone_name = "RightUpperLeg";
+ bones.write[52].bone_parent = "Hips";
+ bones.write[52].reference_pose = Transform3D(-1, 0, 0, 0, -1, 0, 0, 0, 1, -0.1, 0, 0);
+ bones.write[52].handle_offset = Vector2(0.451, 0.49);
+ bones.write[52].group = "Body";
+ bones.write[52].require = true;
+
+ bones.write[53].bone_name = "RightLowerLeg";
+ bones.write[53].bone_parent = "RightUpperLeg";
+ bones.write[53].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.375, 0);
+ bones.write[53].handle_offset = Vector2(0.452, 0.683);
+ bones.write[53].group = "Body";
+ bones.write[53].require = true;
+
+ bones.write[54].bone_name = "RightFoot";
+ bones.write[54].bone_parent = "RightLowerLeg";
+ bones.write[54].reference_pose = Transform3D(-1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0.375, 0);
+ bones.write[54].handle_offset = Vector2(0.455, 0.9);
+ bones.write[54].group = "Body";
+ bones.write[54].require = true;
+
+ bones.write[55].bone_name = "RightToes";
+ bones.write[55].bone_parent = "RightFoot";
+ bones.write[55].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.15, 0);
+ bones.write[55].handle_offset = Vector2(0.455, 0.95);
+ bones.write[55].group = "Body";
+}
+
+SkeletonProfileHumanoid::~SkeletonProfileHumanoid() {
+}
+
+//////////////////////////////////////
diff --git a/scene/resources/skeleton_profile.h b/scene/resources/skeleton_profile.h
new file mode 100644
index 0000000000..d305311538
--- /dev/null
+++ b/scene/resources/skeleton_profile.h
@@ -0,0 +1,131 @@
+/*************************************************************************/
+/* skeleton_profile.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SKELETON_PROFILE_H
+#define SKELETON_PROFILE_H
+
+#include "texture.h"
+
+class SkeletonProfile : public Resource {
+ GDCLASS(SkeletonProfile, Resource);
+
+public:
+ enum TailDirection {
+ TAIL_DIRECTION_AVERAGE_CHILDREN,
+ TAIL_DIRECTION_SPECIFIC_CHILD,
+ TAIL_DIRECTION_END
+ };
+
+protected:
+ // Note: SkeletonProfileHumanoid which extends SkeletonProfile exists to unify standard bone names.
+ // That is what is_read_only is for, so don't make it public.
+ bool is_read_only = false;
+
+ struct SkeletonProfileGroup {
+ StringName group_name;
+ Ref<Texture2D> texture;
+ };
+
+ struct SkeletonProfileBone {
+ StringName bone_name;
+ StringName bone_parent;
+ TailDirection tail_direction = TAIL_DIRECTION_AVERAGE_CHILDREN;
+ StringName bone_tail;
+ Transform3D reference_pose;
+ Vector2 handle_offset;
+ StringName group;
+ bool require = false;
+ };
+
+ Vector<SkeletonProfileGroup> groups;
+ Vector<SkeletonProfileBone> bones;
+
+ bool _get(const StringName &p_path, Variant &r_ret) const;
+ bool _set(const StringName &p_path, const Variant &p_value);
+ virtual void _validate_property(PropertyInfo &property) const override;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+ static void _bind_methods();
+
+public:
+ int get_group_size();
+ void set_group_size(int p_size);
+
+ StringName get_group_name(int p_group_idx) const;
+ void set_group_name(int p_group_idx, const StringName p_group_name);
+
+ Ref<Texture2D> get_texture(int p_group_idx) const;
+ void set_texture(int p_group_idx, const Ref<Texture2D> &p_texture);
+
+ int get_bone_size();
+ void set_bone_size(int p_size);
+
+ int find_bone(const StringName p_bone_name) const;
+
+ StringName get_bone_name(int p_bone_idx) const;
+ void set_bone_name(int p_bone_idx, const StringName p_bone_name);
+
+ StringName get_bone_parent(int p_bone_idx) const;
+ void set_bone_parent(int p_bone_idx, const StringName p_bone_parent);
+
+ TailDirection get_tail_direction(int p_bone_idx) const;
+ void set_tail_direction(int p_bone_idx, const TailDirection p_tail_direction);
+
+ StringName get_bone_tail(int p_bone_idx) const;
+ void set_bone_tail(int p_bone_idx, const StringName p_bone_tail);
+
+ Transform3D get_reference_pose(int p_bone_idx) const;
+ void set_reference_pose(int p_bone_idx, const Transform3D p_reference_pose);
+
+ Vector2 get_handle_offset(int p_bone_idx) const;
+ void set_handle_offset(int p_bone_idx, const Vector2 p_handle_offset);
+
+ StringName get_group(int p_bone_idx) const;
+ void set_group(int p_bone_idx, const StringName p_group);
+
+ bool is_require(int p_bone_idx) const;
+ void set_require(int p_bone_idx, const bool p_require);
+
+ bool has_bone(StringName p_bone_name);
+
+ SkeletonProfile();
+ ~SkeletonProfile();
+};
+
+class SkeletonProfileHumanoid : public SkeletonProfile {
+ GDCLASS(SkeletonProfileHumanoid, SkeletonProfile);
+
+public:
+ SkeletonProfileHumanoid();
+ ~SkeletonProfileHumanoid();
+};
+
+VARIANT_ENUM_CAST(SkeletonProfile::TailDirection);
+
+#endif // SKELETON_PROFILE_H
diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp
index ba21b9fd17..55c9d7397d 100644
--- a/scene/resources/sprite_frames.cpp
+++ b/scene/resources/sprite_frames.cpp
@@ -96,17 +96,6 @@ void SpriteFrames::rename_animation(const StringName &p_prev, const StringName &
animations[p_next] = anim;
}
-Vector<String> SpriteFrames::_get_animation_list() const {
- Vector<String> ret;
- List<StringName> al;
- get_animation_list(&al);
- for (const StringName &E : al) {
- ret.push_back(E);
- }
-
- return ret;
-}
-
void SpriteFrames::get_animation_list(List<StringName> *r_animations) const {
for (const KeyValue<StringName, Anim> &E : animations) {
r_animations->push_back(E.key);
@@ -147,31 +136,22 @@ bool SpriteFrames::get_animation_loop(const StringName &p_anim) const {
return E->value.loop;
}
-void SpriteFrames::_set_frames(const Array &p_frames) {
- clear_all();
- HashMap<StringName, Anim>::Iterator E = animations.find(SceneStringNames::get_singleton()->_default);
- ERR_FAIL_COND(!E);
-
- E->value.frames.resize(p_frames.size());
- for (int i = 0; i < E->value.frames.size(); i++) {
- E->value.frames.write[i] = p_frames[i];
- }
-}
-
-Array SpriteFrames::_get_frames() const {
- return Array();
-}
-
Array SpriteFrames::_get_animations() const {
Array anims;
- for (const KeyValue<StringName, Anim> &E : animations) {
+
+ List<StringName> sorted_names;
+ get_animation_list(&sorted_names);
+ sorted_names.sort_custom<StringName::AlphCompare>();
+
+ for (const StringName &name : sorted_names) {
+ const Anim &anim = animations[name];
Dictionary d;
- d["name"] = E.key;
- d["speed"] = E.value.speed;
- d["loop"] = E.value.loop;
+ d["name"] = name;
+ d["speed"] = anim.speed;
+ d["loop"] = anim.loop;
Array frames;
- for (int i = 0; i < E.value.frames.size(); i++) {
- frames.push_back(E.value.frames[i]);
+ for (int i = 0; i < anim.frames.size(); i++) {
+ frames.push_back(anim.frames[i]);
}
d["frames"] = frames;
anims.push_back(d);
@@ -225,15 +205,12 @@ void SpriteFrames::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear", "anim"), &SpriteFrames::clear);
ClassDB::bind_method(D_METHOD("clear_all"), &SpriteFrames::clear_all);
- ClassDB::bind_method(D_METHOD("_set_frames"), &SpriteFrames::_set_frames);
- ClassDB::bind_method(D_METHOD("_get_frames"), &SpriteFrames::_get_frames);
-
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "frames", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "_set_frames", "_get_frames"); //compatibility
+ // `animations` property is for serialization.
ClassDB::bind_method(D_METHOD("_set_animations"), &SpriteFrames::_set_animations);
ClassDB::bind_method(D_METHOD("_get_animations"), &SpriteFrames::_get_animations);
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_animations", "_get_animations"); //compatibility
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_animations", "_get_animations");
}
SpriteFrames::SpriteFrames() {
diff --git a/scene/resources/sprite_frames.h b/scene/resources/sprite_frames.h
index e32ccc1336..87d84b70c0 100644
--- a/scene/resources/sprite_frames.h
+++ b/scene/resources/sprite_frames.h
@@ -44,14 +44,9 @@ class SpriteFrames : public Resource {
HashMap<StringName, Anim> animations;
- Array _get_frames() const;
- void _set_frames(const Array &p_frames);
-
Array _get_animations() const;
void _set_animations(const Array &p_animations);
- Vector<String> _get_animation_list() const;
-
protected:
static void _bind_methods();
diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp
index 96a47c37c4..0404e1f79b 100644
--- a/scene/resources/text_file.cpp
+++ b/scene/resources/text_file.cpp
@@ -64,7 +64,7 @@ Error TextFile::load_text(const String &p_path) {
w[len] = 0;
String s;
- ERR_FAIL_COND_V_MSG(s.parse_utf8((const char *)w), ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
+ ERR_FAIL_COND_V_MSG(s.parse_utf8((const char *)w) != OK, ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
text = s;
path = p_path;
return OK;
diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp
index d6e7ca3478..823d742d72 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", "meta"), &TextLine::add_string, DEFVAL(Dictionary()), DEFVAL(""), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("add_string", "text", "font", "font_size", "language", "meta"), &TextLine::add_string, 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));
@@ -74,7 +74,7 @@ void TextLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextLine::set_flags);
ClassDB::bind_method(D_METHOD("get_flags"), &TextLine::get_flags);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justify,Word Justify,Trim Edge Spaces After Justify,Justify Only After Last Tab"), "set_flags", "get_flags");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justification,Trim Edge Spaces After Justification,Justify Only After Last Tab,Constrain Ellipsis"), "set_flags", "get_flags");
ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &TextLine::set_text_overrun_behavior);
ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &TextLine::get_text_overrun_behavior);
@@ -106,24 +106,24 @@ void TextLine::_shape() {
TS->shaped_text_tab_align(rid, tab_stops);
}
- uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIM;
+ BitField<TextServer::TextOverrunFlag> overrun_flags = TextServer::OVERRUN_NO_TRIM;
if (overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) {
switch (overrun_behavior) {
case TextServer::OVERRUN_TRIM_WORD_ELLIPSIS:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
- overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY);
+ overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS);
break;
case TextServer::OVERRUN_TRIM_ELLIPSIS:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS);
break;
case TextServer::OVERRUN_TRIM_WORD:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY);
break;
case TextServer::OVERRUN_TRIM_CHAR:
- overrun_flags |= TextServer::OVERRUN_TRIM;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
break;
case TextServer::OVERRUN_NO_TRIMMING:
break;
@@ -131,7 +131,7 @@ void TextLine::_shape() {
if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
TS->shaped_text_fit_to_width(rid, width, flags);
- overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE;
+ overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE);
TS->shaped_text_overrun_trim_to_width(rid, width, overrun_flags);
} else {
TS->shaped_text_overrun_trim_to_width(rid, width, overrun_flags);
@@ -149,8 +149,6 @@ RID TextLine::get_rid() const {
void TextLine::clear() {
TS->shaped_text_clear(rid);
- spacing_top = 0;
- spacing_bottom = 0;
}
void TextLine::set_preserve_invalid(bool p_enabled) {
@@ -194,11 +192,12 @@ 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, 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, p_meta);
- spacing_top = p_fonts->get_spacing(TextServer::SPACING_TOP);
- spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
+bool TextLine::add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language, const Variant &p_meta) {
+ ERR_FAIL_COND_V(p_font.is_null(), false);
+ bool res = TS->shaped_text_add_string(rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language, p_meta);
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
+ }
dirty = true;
return res;
}
@@ -242,14 +241,14 @@ void TextLine::tab_align(const Vector<float> &p_tab_stops) {
dirty = true;
}
-void TextLine::set_flags(uint16_t p_flags) {
+void TextLine::set_flags(BitField<TextServer::JustificationFlag> p_flags) {
if (flags != p_flags) {
flags = p_flags;
dirty = true;
}
}
-uint16_t TextLine::get_flags() const {
+BitField<TextServer::JustificationFlag> TextLine::get_flags() const {
return flags;
}
@@ -278,20 +277,20 @@ float TextLine::get_width() const {
Size2 TextLine::get_size() const {
const_cast<TextLine *>(this)->_shape();
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
- return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom);
+ return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y);
} else {
- return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y);
+ return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y);
}
}
float TextLine::get_line_ascent() const {
const_cast<TextLine *>(this)->_shape();
- return TS->shaped_text_get_ascent(rid) + spacing_top;
+ return TS->shaped_text_get_ascent(rid);
}
float TextLine::get_line_descent() const {
const_cast<TextLine *>(this)->_shape();
- return TS->shaped_text_get_descent(rid) + spacing_bottom;
+ return TS->shaped_text_get_descent(rid);
}
float TextLine::get_line_width() const {
@@ -347,10 +346,10 @@ void TextLine::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color) co
float clip_l;
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.y += TS->shaped_text_get_ascent(rid) + spacing_top;
+ ofs.y += TS->shaped_text_get_ascent(rid);
clip_l = MAX(0, p_pos.x - ofs.x);
} else {
- ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top;
+ ofs.x += TS->shaped_text_get_ascent(rid);
clip_l = MAX(0, p_pos.y - ofs.y);
}
return TS->shaped_text_draw(rid, p_canvas, ofs, clip_l, clip_l + width, p_color);
@@ -394,10 +393,10 @@ void TextLine::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_si
float clip_l;
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.y += TS->shaped_text_get_ascent(rid) + spacing_top;
+ ofs.y += TS->shaped_text_get_ascent(rid);
clip_l = MAX(0, p_pos.x - ofs.x);
} else {
- ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top;
+ ofs.x += TS->shaped_text_get_ascent(rid);
clip_l = MAX(0, p_pos.y - ofs.y);
}
return TS->shaped_text_draw_outline(rid, p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color);
@@ -409,11 +408,14 @@ int TextLine::hit_test(float p_coords) const {
return TS->shaped_text_hit_test_position(rid, p_coords);
}
-TextLine::TextLine(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
+TextLine::TextLine(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language, TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
rid = TS->create_shaped_text(p_direction, p_orientation);
- spacing_top = p_fonts->get_spacing(TextServer::SPACING_TOP);
- spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
- TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
+ if (p_font.is_valid()) {
+ TS->shaped_text_add_string(rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language);
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
+ }
+ }
}
TextLine::TextLine() {
diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h
index 784ee8ef26..e70e82cf2b 100644
--- a/scene/resources/text_line.h
+++ b/scene/resources/text_line.h
@@ -41,13 +41,11 @@ class TextLine : public RefCounted {
private:
RID rid;
- int spacing_top = 0;
- int spacing_bottom = 0;
bool dirty = true;
float width = -1.0;
- uint16_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
+ BitField<TextServer::JustificationFlag> flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT;
TextServer::OverrunBehavior overrun_behavior = TextServer::OVERRUN_TRIM_ELLIPSIS;
@@ -77,7 +75,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 = "", const Variant &p_meta = Variant());
+ bool add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, 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);
@@ -86,8 +84,8 @@ public:
void tab_align(const Vector<float> &p_tab_stops);
- void set_flags(uint16_t p_flags);
- uint16_t get_flags() const;
+ void set_flags(BitField<TextServer::JustificationFlag> p_flags);
+ BitField<TextServer::JustificationFlag> get_flags() const;
void set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior);
TextServer::OverrunBehavior get_text_overrun_behavior() const;
@@ -111,7 +109,7 @@ public:
int hit_test(float p_coords) const;
- TextLine(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
+ TextLine(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
TextLine();
~TextLine();
};
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index 874992ea3d..43d3f329fa 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -60,10 +60,10 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextParagraph::set_bidi_override);
- 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("set_dropcap", "text", "font", "font_size", "dropcap_margins", "language"), &TextParagraph::set_dropcap, DEFVAL(Rect2()), DEFVAL(""));
ClassDB::bind_method(D_METHOD("clear_dropcap"), &TextParagraph::clear_dropcap);
- 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_string", "text", "font", "font_size", "language", "meta"), &TextParagraph::add_string, 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));
@@ -74,10 +74,15 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("tab_align", "tab_stops"), &TextParagraph::tab_align);
- ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextParagraph::set_flags);
- ClassDB::bind_method(D_METHOD("get_flags"), &TextParagraph::get_flags);
+ ClassDB::bind_method(D_METHOD("set_break_flags", "flags"), &TextParagraph::set_break_flags);
+ ClassDB::bind_method(D_METHOD("get_break_flags"), &TextParagraph::get_break_flags);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justify,Word Justify,Trim Edge Spaces After Justify,Justify Only After Last Tab,Break Mandatory,Break Words,Break Graphemes"), "set_flags", "get_flags");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "break_flags", PROPERTY_HINT_FLAGS, "Mandatory,Word Bound,Grapheme Bound,Adaptive"), "set_break_flags", "get_break_flags");
+
+ ClassDB::bind_method(D_METHOD("set_justification_flags", "flags"), &TextParagraph::set_justification_flags);
+ ClassDB::bind_method(D_METHOD("get_justification_flags"), &TextParagraph::get_justification_flags);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "justification_flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justification,Trim Edge Spaces After Justification,Justify Only After Last Tab,Constrain Ellipsis"), "set_justification_flags", "get_justification_flags");
ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &TextParagraph::set_text_overrun_behavior);
ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &TextParagraph::get_text_overrun_behavior);
@@ -113,9 +118,6 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line_underline_position", "line"), &TextParagraph::get_line_underline_position);
ClassDB::bind_method(D_METHOD("get_line_underline_thickness", "line"), &TextParagraph::get_line_underline_thickness);
- ClassDB::bind_method(D_METHOD("get_spacing_top"), &TextParagraph::get_spacing_top);
- ClassDB::bind_method(D_METHOD("get_spacing_bottom"), &TextParagraph::get_spacing_bottom);
-
ClassDB::bind_method(D_METHOD("get_dropcap_size"), &TextParagraph::get_dropcap_size);
ClassDB::bind_method(D_METHOD("get_dropcap_lines"), &TextParagraph::get_dropcap_lines);
@@ -157,7 +159,7 @@ void TextParagraph::_shape_lines() {
if (h_offset > 0) {
// Dropcap, flow around.
- PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(rid, width - h_offset, 0, flags);
+ PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(rid, width - h_offset, 0, brk_flags);
for (int i = 0; i < line_breaks.size(); i = i + 2) {
RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]);
float h = (TS->shaped_text_get_orientation(line) == TextServer::ORIENTATION_HORIZONTAL) ? TS->shaped_text_get_size(line).y : TS->shaped_text_get_size(line).x;
@@ -175,7 +177,7 @@ void TextParagraph::_shape_lines() {
}
}
// Use fixed for the rest of lines.
- PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(rid, width, start, flags);
+ PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(rid, width, start, brk_flags);
for (int i = 0; i < line_breaks.size(); i = i + 2) {
RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]);
if (!tab_stops.is_empty()) {
@@ -184,43 +186,43 @@ void TextParagraph::_shape_lines() {
lines_rid.push_back(line);
}
- uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIM;
+ BitField<TextServer::TextOverrunFlag> overrun_flags = TextServer::OVERRUN_NO_TRIM;
if (overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) {
switch (overrun_behavior) {
case TextServer::OVERRUN_TRIM_WORD_ELLIPSIS:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
- overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY);
+ overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS);
break;
case TextServer::OVERRUN_TRIM_ELLIPSIS:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS);
break;
case TextServer::OVERRUN_TRIM_WORD:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY);
break;
case TextServer::OVERRUN_TRIM_CHAR:
- overrun_flags |= TextServer::OVERRUN_TRIM;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
break;
case TextServer::OVERRUN_NO_TRIMMING:
break;
}
}
- bool autowrap_enabled = ((flags & TextServer::BREAK_WORD_BOUND) == TextServer::BREAK_WORD_BOUND) || ((flags & TextServer::BREAK_GRAPHEME_BOUND) == TextServer::BREAK_GRAPHEME_BOUND);
+ bool autowrap_enabled = brk_flags.has_flag(TextServer::BREAK_WORD_BOUND) || brk_flags.has_flag(TextServer::BREAK_GRAPHEME_BOUND);
// Fill after min_size calculation.
if (autowrap_enabled) {
int visible_lines = (max_lines_visible >= 0) ? MIN(max_lines_visible, (int)lines_rid.size()) : (int)lines_rid.size();
bool lines_hidden = visible_lines > 0 && visible_lines < (int)lines_rid.size();
if (lines_hidden) {
- overrun_flags |= TextServer::OVERRUN_ENFORCE_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_ENFORCE_ELLIPSIS);
}
if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
for (int i = 0; i < (int)lines_rid.size(); i++) {
if (i < visible_lines - 1 || (int)lines_rid.size() == 1) {
- TS->shaped_text_fit_to_width(lines_rid[i], width, flags);
+ TS->shaped_text_fit_to_width(lines_rid[i], width, jst_flags);
} else if (i == (visible_lines - 1)) {
TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags);
}
@@ -234,10 +236,10 @@ void TextParagraph::_shape_lines() {
// Autowrap disabled.
for (int i = 0; i < (int)lines_rid.size(); i++) {
if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
- TS->shaped_text_fit_to_width(lines_rid[i], width, flags);
- overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE;
+ TS->shaped_text_fit_to_width(lines_rid[i], width, jst_flags);
+ overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE);
TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags);
- TS->shaped_text_fit_to_width(lines_rid[i], width, flags | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS);
+ TS->shaped_text_fit_to_width(lines_rid[i], width, jst_flags | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS);
} else {
TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags);
}
@@ -266,8 +268,6 @@ RID TextParagraph::get_dropcap_rid() const {
void TextParagraph::clear() {
_THREAD_SAFE_METHOD_
- spacing_top = 0;
- spacing_bottom = 0;
for (int i = 0; i < (int)lines_rid.size(); i++) {
TS->free_rid(lines_rid[i]);
}
@@ -347,44 +347,37 @@ TextServer::Orientation TextParagraph::get_orientation() const {
return TS->shaped_text_get_orientation(rid);
}
-bool TextParagraph::set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins, const Dictionary &p_opentype_features, const String &p_language) {
+bool TextParagraph::set_dropcap(const String &p_text, const Ref<Font> &p_font, int p_font_size, const Rect2 &p_dropcap_margins, const String &p_language) {
_THREAD_SAFE_METHOD_
-
- ERR_FAIL_COND_V(p_fonts.is_null(), false);
+ ERR_FAIL_COND_V(p_font.is_null(), false);
TS->shaped_text_clear(dropcap_rid);
dropcap_margins = p_dropcap_margins;
- bool res = TS->shaped_text_add_string(dropcap_rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
+ bool res = TS->shaped_text_add_string(dropcap_rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language);
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(dropcap_rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
+ }
lines_dirty = true;
return res;
}
void TextParagraph::clear_dropcap() {
_THREAD_SAFE_METHOD_
-
dropcap_margins = Rect2();
TS->shaped_text_clear(dropcap_rid);
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, const Variant &p_meta) {
+bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language, const Variant &p_meta) {
_THREAD_SAFE_METHOD_
-
- 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, p_meta);
- spacing_top = p_fonts->get_spacing(TextServer::SPACING_TOP);
- spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
+ ERR_FAIL_COND_V(p_font.is_null(), false);
+ bool res = TS->shaped_text_add_string(rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language, p_meta);
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
+ }
lines_dirty = true;
return res;
}
-int TextParagraph::get_spacing_top() const {
- return spacing_top;
-}
-
-int TextParagraph::get_spacing_bottom() const {
- return spacing_bottom;
-}
-
void TextParagraph::set_bidi_override(const Array &p_override) {
_THREAD_SAFE_METHOD_
@@ -432,17 +425,30 @@ void TextParagraph::tab_align(const Vector<float> &p_tab_stops) {
lines_dirty = true;
}
-void TextParagraph::set_flags(uint16_t p_flags) {
+void TextParagraph::set_justification_flags(BitField<TextServer::JustificationFlag> p_flags) {
_THREAD_SAFE_METHOD_
- if (flags != p_flags) {
- flags = p_flags;
+ if (jst_flags != p_flags) {
+ jst_flags = p_flags;
lines_dirty = true;
}
}
-uint16_t TextParagraph::get_flags() const {
- return flags;
+BitField<TextServer::JustificationFlag> TextParagraph::get_justification_flags() const {
+ return jst_flags;
+}
+
+void TextParagraph::set_break_flags(BitField<TextServer::LineBreakFlag> p_flags) {
+ _THREAD_SAFE_METHOD_
+
+ if (brk_flags != p_flags) {
+ brk_flags = p_flags;
+ lines_dirty = true;
+ }
+}
+
+BitField<TextServer::LineBreakFlag> TextParagraph::get_break_flags() const {
+ return brk_flags;
}
void TextParagraph::set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior) {
@@ -476,9 +482,9 @@ Size2 TextParagraph::get_non_wrapped_size() const {
const_cast<TextParagraph *>(this)->_shape_lines();
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
- return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom);
+ return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y);
} else {
- return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y);
+ return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y);
}
}
@@ -492,9 +498,9 @@ Size2 TextParagraph::get_size() const {
Size2 lsize = TS->shaped_text_get_size(lines_rid[i]);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
size.x = MAX(size.x, lsize.x);
- size.y += lsize.y + spacing_top + spacing_bottom;
+ size.y += lsize.y;
} else {
- size.x += lsize.x + spacing_top + spacing_bottom;
+ size.x += lsize.x;
size.y = MAX(size.y, lsize.y);
}
}
@@ -538,9 +544,9 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const {
for (int i = 0; i < p_line; i++) {
Size2 lsize = TS->shaped_text_get_size(lines_rid[i]);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
- xrect.position.y += lsize.y + spacing_top + spacing_bottom;
+ xrect.position.y += lsize.y;
} else {
- xrect.position.x += lsize.x + spacing_top + spacing_bottom;
+ xrect.position.x += lsize.x;
}
}
return xrect;
@@ -552,9 +558,9 @@ Size2 TextParagraph::get_line_size(int p_line) const {
const_cast<TextParagraph *>(this)->_shape_lines();
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), Size2());
if (TS->shaped_text_get_orientation(lines_rid[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
- return Size2(TS->shaped_text_get_size(lines_rid[p_line]).x, TS->shaped_text_get_size(lines_rid[p_line]).y + spacing_top + spacing_bottom);
+ return Size2(TS->shaped_text_get_size(lines_rid[p_line]).x, TS->shaped_text_get_size(lines_rid[p_line]).y);
} else {
- return Size2(TS->shaped_text_get_size(lines_rid[p_line]).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(lines_rid[p_line]).y);
+ return Size2(TS->shaped_text_get_size(lines_rid[p_line]).x, TS->shaped_text_get_size(lines_rid[p_line]).y);
}
}
@@ -571,7 +577,7 @@ float TextParagraph::get_line_ascent(int p_line) const {
const_cast<TextParagraph *>(this)->_shape_lines();
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), 0.f);
- return TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
+ return TS->shaped_text_get_ascent(lines_rid[p_line]);
}
float TextParagraph::get_line_descent(int p_line) const {
@@ -579,7 +585,7 @@ float TextParagraph::get_line_descent(int p_line) const {
const_cast<TextParagraph *>(this)->_shape_lines();
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), 0.f);
- return TS->shaped_text_get_descent(lines_rid[p_line]) + spacing_bottom;
+ return TS->shaped_text_get_descent(lines_rid[p_line]);
}
float TextParagraph::get_line_width(int p_line) const {
@@ -647,7 +653,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
float l_width = width;
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
- ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
+ ofs.y += TS->shaped_text_get_ascent(lines_rid[i]);
if (i <= dropcap_lines) {
if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
ofs.x -= h_offset;
@@ -656,7 +662,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
}
} else {
ofs.y = p_pos.y;
- ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
+ ofs.x += TS->shaped_text_get_ascent(lines_rid[i]);
if (i <= dropcap_lines) {
if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
ofs.x -= h_offset;
@@ -711,10 +717,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
TS->shaped_text_draw(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_color);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
- ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + spacing_bottom;
+ ofs.y += TS->shaped_text_get_descent(lines_rid[i]);
} else {
ofs.y = p_pos.y;
- ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + spacing_bottom;
+ ofs.x += TS->shaped_text_get_descent(lines_rid[i]);
}
}
}
@@ -749,7 +755,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
float l_width = width;
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
- ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
+ ofs.y += TS->shaped_text_get_ascent(lines_rid[i]);
if (i <= dropcap_lines) {
if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
ofs.x -= h_offset;
@@ -758,7 +764,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
}
} else {
ofs.y = p_pos.y;
- ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
+ ofs.x += TS->shaped_text_get_ascent(lines_rid[i]);
if (i <= dropcap_lines) {
if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
ofs.x -= h_offset;
@@ -813,10 +819,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
TS->shaped_text_draw_outline(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_outline_size, p_color);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
- ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + spacing_bottom;
+ ofs.y += TS->shaped_text_get_descent(lines_rid[i]);
} else {
ofs.y = p_pos.y;
- ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + spacing_bottom;
+ ofs.x += TS->shaped_text_get_descent(lines_rid[i]);
}
}
}
@@ -840,12 +846,12 @@ int TextParagraph::hit_test(const Point2 &p_coords) const {
if ((p_coords.y >= ofs.y) && (p_coords.y <= ofs.y + TS->shaped_text_get_size(lines_rid[i]).y)) {
return TS->shaped_text_hit_test_position(lines_rid[i], p_coords.x);
}
- ofs.y += TS->shaped_text_get_size(lines_rid[i]).y + spacing_bottom + spacing_top;
+ ofs.y += TS->shaped_text_get_size(lines_rid[i]).y;
} else {
if ((p_coords.x >= ofs.x) && (p_coords.x <= ofs.x + TS->shaped_text_get_size(lines_rid[i]).x)) {
return TS->shaped_text_hit_test_position(lines_rid[i], p_coords.y);
}
- ofs.y += TS->shaped_text_get_size(lines_rid[i]).x + spacing_bottom + spacing_top;
+ ofs.y += TS->shaped_text_get_size(lines_rid[i]).x;
}
}
return TS->shaped_text_get_range(rid).y;
@@ -908,9 +914,9 @@ void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, co
Vector2 ofs = p_pos;
if (TS->shaped_text_get_orientation(lines_rid[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.y += TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
+ ofs.y += TS->shaped_text_get_ascent(lines_rid[p_line]);
} else {
- ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
+ ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]);
}
return TS->shaped_text_draw(lines_rid[p_line], p_canvas, ofs, -1, -1, p_color);
}
@@ -923,18 +929,21 @@ void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_
Vector2 ofs = p_pos;
if (TS->shaped_text_get_orientation(lines_rid[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.y += TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
+ ofs.y += TS->shaped_text_get_ascent(lines_rid[p_line]);
} else {
- ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
+ ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]);
}
return TS->shaped_text_draw_outline(lines_rid[p_line], p_canvas, ofs, -1, -1, p_outline_size, p_color);
}
-TextParagraph::TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, float p_width, TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
+TextParagraph::TextParagraph(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language, float p_width, TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
rid = TS->create_shaped_text(p_direction, p_orientation);
- TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
- spacing_top = p_fonts->get_spacing(TextServer::SPACING_TOP);
- spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
+ if (p_font.is_valid()) {
+ TS->shaped_text_add_string(rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language);
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
+ }
+ }
width = p_width;
}
diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h
index bdcc2b5701..0fe82b4364 100644
--- a/scene/resources/text_paragraph.h
+++ b/scene/resources/text_paragraph.h
@@ -48,15 +48,14 @@ private:
RID rid;
LocalVector<RID> lines_rid;
- int spacing_top = 0;
- int spacing_bottom = 0;
bool lines_dirty = true;
float width = -1.0;
int max_lines_visible = -1;
- uint16_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
+ BitField<TextServer::LineBreakFlag> brk_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND;
+ BitField<TextServer::JustificationFlag> jst_flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
TextServer::OverrunBehavior overrun_behavior = TextServer::OVERRUN_NO_TRIMMING;
HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT;
@@ -92,10 +91,10 @@ public:
void set_custom_punctuation(const String &p_punct);
String get_custom_punctuation() const;
- 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 = "");
+ bool set_dropcap(const String &p_text, const Ref<Font> &p_font, int p_font_size, const Rect2 &p_dropcap_margins = Rect2(), 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 = "", const Variant &p_meta = Variant());
+ bool add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, 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);
@@ -104,8 +103,11 @@ public:
void tab_align(const Vector<float> &p_tab_stops);
- void set_flags(uint16_t p_flags);
- uint16_t get_flags() const;
+ void set_justification_flags(BitField<TextServer::JustificationFlag> p_flags);
+ BitField<TextServer::JustificationFlag> get_justification_flags() const;
+
+ void set_break_flags(BitField<TextServer::LineBreakFlag> p_flags);
+ BitField<TextServer::LineBreakFlag> get_break_flags() const;
void set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior);
TextServer::OverrunBehavior get_text_overrun_behavior() const;
@@ -151,7 +153,7 @@ public:
Mutex &get_mutex() const { return _thread_safe_; };
- TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", float p_width = -1.f, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
+ TextParagraph(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", float p_width = -1.f, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
TextParagraph();
~TextParagraph();
};
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index f31a71eada..0aefe34f7d 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -139,7 +139,7 @@ void ImageTexture::reload_from_file() {
img.instantiate();
if (ImageLoader::load_image(path, img) == OK) {
- create_from_image(img);
+ set_image(img);
} else {
Resource::reload_from_file();
notify_property_list_changed();
@@ -149,7 +149,7 @@ void ImageTexture::reload_from_file() {
bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
if (p_name == "image") {
- create_from_image(p_value);
+ set_image(p_value);
return true;
}
return false;
@@ -167,7 +167,16 @@ void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("image"), PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
}
-void ImageTexture::create_from_image(const Ref<Image> &p_image) {
+Ref<ImageTexture> ImageTexture::create_from_image(const Ref<Image> &p_image) {
+ ERR_FAIL_COND_V_MSG(p_image.is_null() || p_image->is_empty(), Ref<ImageTexture>(), "Invalid image");
+
+ Ref<ImageTexture> image_texture;
+ image_texture.instantiate();
+ image_texture->set_image(p_image);
+ return image_texture;
+}
+
+void ImageTexture::set_image(const Ref<Image> &p_image) {
ERR_FAIL_COND_MSG(p_image.is_null() || p_image->is_empty(), "Invalid image");
w = p_image->get_width();
h = p_image->get_height();
@@ -291,8 +300,8 @@ bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
return true;
}
-void ImageTexture::set_size_override(const Size2 &p_size) {
- Size2 s = p_size;
+void ImageTexture::set_size_override(const Size2i &p_size) {
+ Size2i s = p_size;
if (s.x != 0) {
w = s.x;
}
@@ -311,9 +320,10 @@ void ImageTexture::set_path(const String &p_path, bool p_take_over) {
}
void ImageTexture::_bind_methods() {
- ClassDB::bind_method(D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
+ ClassDB::bind_static_method("ImageTexture", D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
+ ClassDB::bind_method(D_METHOD("set_image", "image"), &ImageTexture::set_image);
ClassDB::bind_method(D_METHOD("update", "image"), &ImageTexture::update);
ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
}
@@ -2148,7 +2158,7 @@ void GradientTexture1D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update"), &GradientTexture1D::_update);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
+ 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,16384,suffix:px"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr");
}
@@ -3016,12 +3026,12 @@ Error ImageTextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
}
void ImageTextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) {
- ERR_FAIL_COND(texture.is_valid());
- ERR_FAIL_COND(p_image.is_null());
- ERR_FAIL_COND(p_image->get_format() != format);
- ERR_FAIL_COND(p_image->get_width() != width || p_image->get_height() != height);
- ERR_FAIL_INDEX(p_layer, layers);
- ERR_FAIL_COND(p_image->has_mipmaps() != mipmaps);
+ ERR_FAIL_COND_MSG(texture.is_null(), "Texture is not initialized.");
+ ERR_FAIL_COND_MSG(p_image.is_null(), "Invalid image.");
+ ERR_FAIL_COND_MSG(p_image->get_format() != format, "Image format must match texture's image format.");
+ ERR_FAIL_COND_MSG(p_image->get_width() != width || p_image->get_height() != height, "Image size must match texture's image size.");
+ ERR_FAIL_COND_MSG(p_image->has_mipmaps() != mipmaps, "Image mipmap configuration must match texture's image mipmap configuration.");
+ ERR_FAIL_INDEX_MSG(p_layer, layers, "Layer index is out of bounds.");
RS::get_singleton()->texture_2d_update(texture, p_image, p_layer);
}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 317756e313..b107a2a70d 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -110,7 +110,8 @@ protected:
static void _bind_methods();
public:
- void create_from_image(const Ref<Image> &p_image);
+ void set_image(const Ref<Image> &p_image);
+ static Ref<ImageTexture> create_from_image(const Ref<Image> &p_image);
Image::Format get_format() const;
@@ -129,7 +130,7 @@ public:
bool is_pixel_opaque(int p_x, int p_y) const override;
- void set_size_override(const Size2 &p_size);
+ void set_size_override(const Size2i &p_size);
virtual void set_path(const String &p_path, bool p_take_over = false) override;
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 13b671e562..22b5ef0108 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -1801,19 +1801,16 @@ Vector<Vector<Ref<Texture2D>>> TileSet::generate_terrains_icons(Size2i p_size) {
if (counts[terrain_set][terrain].count > 0) {
// Get the best tile.
Ref<Texture2D> texture = counts[terrain_set][terrain].texture;
- Rect2 region = counts[terrain_set][terrain].region;
+ Rect2i region = counts[terrain_set][terrain].region;
image->create(region.size.x, region.size.y, false, Image::FORMAT_RGBA8);
- image->blit_rect(texture->get_image(), region, Point2());
+ image->blit_rect(texture->get_image(), region, Point2i());
image->resize(p_size.x, p_size.y, Image::INTERPOLATE_NEAREST);
} else {
image->create(1, 1, false, Image::FORMAT_RGBA8);
image->set_pixel(0, 0, get_terrain_color(terrain_set, terrain));
}
- Ref<ImageTexture> icon;
- icon.instantiate();
- icon->create_from_image(image);
+ Ref<ImageTexture> icon = ImageTexture::create_from_image(image);
icon->set_size_override(p_size);
-
output.write[terrain_set].write[terrain] = icon;
}
}
@@ -3930,7 +3927,7 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const {
tile_property_list.push_back(property_info);
// animation_frames_count.
- tile_property_list.push_back(PropertyInfo(Variant::INT, "animation_frames_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NETWORK));
+ tile_property_list.push_back(PropertyInfo(Variant::INT, "animation_frames_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE));
// animation_frame_*.
bool store_durations = tiles[E_tile.key].animation_frames_durations.size() >= 2;
@@ -4594,7 +4591,7 @@ void TileSetAtlasSource::_update_padded_texture() {
if (!padded_texture.is_valid()) {
padded_texture.instantiate();
}
- padded_texture->create_from_image(image);
+ padded_texture->set_image(image);
emit_changed();
}
@@ -4924,6 +4921,10 @@ void TileData::move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) {
void TileData::remove_terrain(int p_terrain_set, int p_index) {
if (terrain_set == p_terrain_set) {
+ if (terrain == p_index) {
+ terrain = -1;
+ }
+
for (int i = 0; i < 16; i++) {
if (terrain_peering_bits[i] == p_index) {
terrain_peering_bits[i] = -1;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index b8eac6de00..b68cce9dda 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -30,6 +30,7 @@
#include "visual_shader.h"
+#include "core/templates/rb_map.h"
#include "core/templates/vmap.h"
#include "servers/rendering/shader_types.h"
#include "visual_shader_nodes.h"
@@ -3189,18 +3190,18 @@ VisualShaderNodeInput::VisualShaderNodeInput() {
////////////// UniformRef
-List<VisualShaderNodeUniformRef::Uniform> uniforms;
+RBMap<RID, List<VisualShaderNodeUniformRef::Uniform>> uniforms;
-void VisualShaderNodeUniformRef::add_uniform(const String &p_name, UniformType p_type) {
- uniforms.push_back({ p_name, p_type });
+void VisualShaderNodeUniformRef::add_uniform(RID p_shader_rid, const String &p_name, UniformType p_type) {
+ uniforms[p_shader_rid].push_back({ p_name, p_type });
}
-void VisualShaderNodeUniformRef::clear_uniforms() {
- uniforms.clear();
+void VisualShaderNodeUniformRef::clear_uniforms(RID p_shader_rid) {
+ uniforms[p_shader_rid].clear();
}
-bool VisualShaderNodeUniformRef::has_uniform(const String &p_name) {
- for (const VisualShaderNodeUniformRef::Uniform &E : uniforms) {
+bool VisualShaderNodeUniformRef::has_uniform(RID p_shader_rid, const String &p_name) {
+ for (const VisualShaderNodeUniformRef::Uniform &E : uniforms[p_shader_rid]) {
if (E.name == p_name) {
return true;
}
@@ -3313,14 +3314,24 @@ String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const {
return "";
}
+void VisualShaderNodeUniformRef::set_shader_rid(const RID &p_shader_rid) {
+ shader_rid = p_shader_rid;
+}
+
void VisualShaderNodeUniformRef::set_uniform_name(const String &p_name) {
uniform_name = p_name;
+ if (shader_rid.is_valid()) {
+ update_uniform_type();
+ }
+ emit_changed();
+}
+
+void VisualShaderNodeUniformRef::update_uniform_type() {
if (uniform_name != "[None]") {
uniform_type = get_uniform_type_by_name(uniform_name);
} else {
uniform_type = UniformType::UNIFORM_TYPE_FLOAT;
}
- emit_changed();
}
String VisualShaderNodeUniformRef::get_uniform_name() const {
@@ -3328,35 +3339,45 @@ String VisualShaderNodeUniformRef::get_uniform_name() const {
}
int VisualShaderNodeUniformRef::get_uniforms_count() const {
- return uniforms.size();
+ ERR_FAIL_COND_V(!shader_rid.is_valid(), 0);
+
+ return uniforms[shader_rid].size();
}
String VisualShaderNodeUniformRef::get_uniform_name_by_index(int p_idx) const {
- if (p_idx >= 0 && p_idx < uniforms.size()) {
- return uniforms[p_idx].name;
+ ERR_FAIL_COND_V(!shader_rid.is_valid(), String());
+
+ if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) {
+ return uniforms[shader_rid][p_idx].name;
}
return "";
}
VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_name(const String &p_name) const {
- for (int i = 0; i < uniforms.size(); i++) {
- if (uniforms[i].name == p_name) {
- return uniforms[i].type;
+ ERR_FAIL_COND_V(!shader_rid.is_valid(), UNIFORM_TYPE_FLOAT);
+
+ for (int i = 0; i < uniforms[shader_rid].size(); i++) {
+ if (uniforms[shader_rid][i].name == p_name) {
+ return uniforms[shader_rid][i].type;
}
}
return UniformType::UNIFORM_TYPE_FLOAT;
}
VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_index(int p_idx) const {
- if (p_idx >= 0 && p_idx < uniforms.size()) {
- return uniforms[p_idx].type;
+ ERR_FAIL_COND_V(!shader_rid.is_valid(), UNIFORM_TYPE_FLOAT);
+
+ if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) {
+ return uniforms[shader_rid][p_idx].type;
}
return UniformType::UNIFORM_TYPE_FLOAT;
}
VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_port_type_by_index(int p_idx) const {
- if (p_idx >= 0 && p_idx < uniforms.size()) {
- switch (uniforms[p_idx].type) {
+ ERR_FAIL_COND_V(!shader_rid.is_valid(), PORT_TYPE_SCALAR);
+
+ if (p_idx >= 0 && p_idx < uniforms[shader_rid].size()) {
+ switch (uniforms[shader_rid][p_idx].type) {
case UniformType::UNIFORM_TYPE_FLOAT:
return PORT_TYPE_SCALAR;
case UniformType::UNIFORM_TYPE_INT:
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index afd84e49cc..7ca4e5fc4a 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -561,6 +561,7 @@ public:
};
private:
+ RID shader_rid;
String uniform_name = "[None]";
UniformType uniform_type = UniformType::UNIFORM_TYPE_FLOAT;
@@ -568,9 +569,9 @@ protected:
static void _bind_methods();
public:
- static void add_uniform(const String &p_name, UniformType p_type);
- static void clear_uniforms();
- static bool has_uniform(const String &p_name);
+ static void add_uniform(RID p_shader_rid, const String &p_name, UniformType p_type);
+ static void clear_uniforms(RID p_shader_rid);
+ static bool has_uniform(RID p_shader_rid, const String &p_name);
public:
virtual String get_caption() const override;
@@ -583,9 +584,13 @@ public:
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
+ void set_shader_rid(const RID &p_shader);
+
void set_uniform_name(const String &p_name);
String get_uniform_name() const;
+ void update_uniform_type();
+
void _set_uniform_type(int p_uniform_type);
int _get_uniform_type() const;
diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp
index 54df935168..bdfbb59fa6 100644
--- a/scene/resources/visual_shader_particle_nodes.cpp
+++ b/scene/resources/visual_shader_particle_nodes.cpp
@@ -470,7 +470,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Vector2>
image->set_pixel(i, 0, Color(v.x, v.y, 0));
}
if (r_texture->get_width() != p_array.size() || p_array.size() == 0) {
- r_texture->create_from_image(image);
+ r_texture->set_image(image);
} else {
r_texture->update(image);
}
@@ -491,7 +491,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Vector3>
image->set_pixel(i, 0, Color(v.x, v.y, v.z));
}
if (r_texture->get_width() != p_array.size() || p_array.size() == 0) {
- r_texture->create_from_image(image);
+ r_texture->set_image(image);
} else {
r_texture->update(image);
}
@@ -511,7 +511,7 @@ void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Color> &p
image->set_pixel(i, 0, p_array[i]);
}
if (r_texture->get_width() != p_array.size() || p_array.size() == 0) {
- r_texture->create_from_image(image);
+ r_texture->set_image(image);
} else {
r_texture->update(image);
}
diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp
index a84ee773b4..fb6dcd3d57 100644
--- a/scene/resources/world_3d.cpp
+++ b/scene/resources/world_3d.cpp
@@ -31,7 +31,6 @@
#include "world_3d.h"
#include "core/config/project_settings.h"
-#include "core/math/octree.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/visible_on_screen_notifier_3d.h"
#include "scene/scene_string_names.h"
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 5d9a9e61dc..0408db2539 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -696,7 +696,7 @@ void AudioStreamRandomizer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "streams_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_streams_count", "get_streams_count");
ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_mode", PROPERTY_HINT_ENUM, "Random (Avoid Repeats),Random,Sequential"), "set_playback_mode", "get_playback_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "random_pitch", PROPERTY_HINT_RANGE, "1,16,0.01"), "set_random_pitch", "get_random_pitch");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "random_volume_offset_db", PROPERTY_HINT_RANGE, "0,40,0,suffix:dB"), "set_random_volume_offset_db", "get_random_volume_offset_db");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "random_volume_offset_db", PROPERTY_HINT_RANGE, "0,40,0.01,suffix:dB"), "set_random_volume_offset_db", "get_random_volume_offset_db");
BIND_ENUM_CONSTANT(PLAYBACK_RANDOM_NO_REPEATS);
BIND_ENUM_CONSTANT(PLAYBACK_RANDOM);
diff --git a/servers/movie_writer/movie_writer.cpp b/servers/movie_writer/movie_writer.cpp
index 8560d92aa2..9f96b8cfda 100644
--- a/servers/movie_writer/movie_writer.cpp
+++ b/servers/movie_writer/movie_writer.cpp
@@ -30,7 +30,6 @@
#include "movie_writer.h"
#include "core/config/project_settings.h"
-#include "core/io/dir_access.h"
MovieWriter *MovieWriter::writers[MovieWriter::MAX_WRITERS];
uint32_t MovieWriter::writer_count = 0;
@@ -170,139 +169,3 @@ void MovieWriter::add_frame(const Ref<Image> &p_image) {
void MovieWriter::end() {
write_end();
}
-/////////////////////////////////////////
-
-uint32_t MovieWriterPNGWAV::get_audio_mix_rate() const {
- return mix_rate;
-}
-AudioServer::SpeakerMode MovieWriterPNGWAV::get_audio_speaker_mode() const {
- return speaker_mode;
-}
-
-void MovieWriterPNGWAV::get_supported_extensions(List<String> *r_extensions) const {
- r_extensions->push_back("png");
-}
-
-bool MovieWriterPNGWAV::handles_file(const String &p_path) const {
- return p_path.get_extension().to_lower() == "png";
-}
-
-String MovieWriterPNGWAV::zeros_str(uint32_t p_index) {
- char zeros[MAX_TRAILING_ZEROS + 1];
- for (uint32_t i = 0; i < MAX_TRAILING_ZEROS; i++) {
- uint32_t idx = MAX_TRAILING_ZEROS - i - 1;
- uint32_t digit = (p_index / uint32_t(Math::pow(double(10), double(idx)))) % 10;
- zeros[i] = '0' + digit;
- }
- zeros[MAX_TRAILING_ZEROS] = 0;
- return zeros;
-}
-
-Error MovieWriterPNGWAV::write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) {
- // Quick & Dirty PNGWAV Code based on - https://docs.microsoft.com/en-us/windows/win32/directshow/avi-riff-file-reference
-
- base_path = p_base_path.get_basename();
- if (base_path.is_relative_path()) {
- base_path = "res://" + base_path;
- }
-
- {
- //Remove existing files before writing anew
- uint32_t idx = 0;
- Ref<DirAccess> d = DirAccess::open(base_path.get_base_dir());
- String file = base_path.get_file();
- while (true) {
- String path = file + zeros_str(idx) + ".png";
- if (d->remove(path) != OK) {
- break;
- }
- }
- }
-
- f_wav = FileAccess::open(base_path + ".wav", FileAccess::WRITE_READ);
- ERR_FAIL_COND_V(f_wav.is_null(), ERR_CANT_OPEN);
-
- fps = p_fps;
-
- f_wav->store_buffer((const uint8_t *)"RIFF", 4);
- int total_size = 4 /* WAVE */ + 8 /* fmt+size */ + 16 /* format */ + 8 /* data+size */;
- f_wav->store_32(total_size); //will store final later
- f_wav->store_buffer((const uint8_t *)"WAVE", 4);
-
- /* FORMAT CHUNK */
-
- f_wav->store_buffer((const uint8_t *)"fmt ", 4);
-
- uint32_t channels = 2;
- switch (speaker_mode) {
- case AudioServer::SPEAKER_MODE_STEREO:
- channels = 2;
- break;
- case AudioServer::SPEAKER_SURROUND_31:
- channels = 4;
- break;
- case AudioServer::SPEAKER_SURROUND_51:
- channels = 6;
- break;
- case AudioServer::SPEAKER_SURROUND_71:
- channels = 8;
- break;
- }
-
- f_wav->store_32(16); //standard format, no extra fields
- f_wav->store_16(1); // compression code, standard PCM
- f_wav->store_16(channels); //CHANNELS: 2
-
- f_wav->store_32(mix_rate);
-
- /* useless stuff the format asks for */
-
- int bits_per_sample = 32;
- int blockalign = bits_per_sample / 8 * channels;
- int bytes_per_sec = mix_rate * blockalign;
-
- audio_block_size = (mix_rate / fps) * blockalign;
-
- f_wav->store_32(bytes_per_sec);
- f_wav->store_16(blockalign); // block align (unused)
- f_wav->store_16(bits_per_sample);
-
- /* DATA CHUNK */
-
- f_wav->store_buffer((const uint8_t *)"data", 4);
-
- f_wav->store_32(0); //data size... wooh
- wav_data_size_pos = f_wav->get_position();
-
- return OK;
-}
-
-Error MovieWriterPNGWAV::write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) {
- ERR_FAIL_COND_V(!f_wav.is_valid(), ERR_UNCONFIGURED);
-
- Vector<uint8_t> png_buffer = p_image->save_png_to_buffer();
-
- Ref<FileAccess> fi = FileAccess::open(base_path + zeros_str(frame_count) + ".png", FileAccess::WRITE);
- fi->store_buffer(png_buffer.ptr(), png_buffer.size());
- f_wav->store_buffer((const uint8_t *)p_audio_data, audio_block_size);
-
- frame_count++;
-
- return OK;
-}
-
-void MovieWriterPNGWAV::write_end() {
- if (f_wav.is_valid()) {
- uint32_t total_size = 4 /* WAVE */ + 8 /* fmt+size */ + 16 /* format */ + 8 /* data+size */;
- uint32_t datasize = f_wav->get_position() - wav_data_size_pos;
- f_wav->seek(4);
- f_wav->store_32(total_size + datasize);
- f_wav->seek(0x28);
- f_wav->store_32(datasize);
- }
-}
-
-MovieWriterPNGWAV::MovieWriterPNGWAV() {
- mix_rate = GLOBAL_GET("editor/movie_writer/mix_rate");
- speaker_mode = AudioServer::SpeakerMode(int(GLOBAL_GET("editor/movie_writer/speaker_mode")));
-}
diff --git a/servers/movie_writer/movie_writer.h b/servers/movie_writer/movie_writer.h
index 11e739df39..1ec6e93052 100644
--- a/servers/movie_writer/movie_writer.h
+++ b/servers/movie_writer/movie_writer.h
@@ -85,39 +85,4 @@ public:
void end();
};
-class MovieWriterPNGWAV : public MovieWriter {
- GDCLASS(MovieWriterPNGWAV, MovieWriter)
-
- enum {
- MAX_TRAILING_ZEROS = 8 // more than 10 days at 60fps, no hard drive can put up with this anyway :)
- };
-
- uint32_t mix_rate = 48000;
- AudioServer::SpeakerMode speaker_mode = AudioServer::SPEAKER_MODE_STEREO;
- String base_path;
- uint32_t frame_count = 0;
- uint32_t fps = 0;
-
- uint32_t audio_block_size = 0;
-
- Ref<FileAccess> f_wav;
- uint32_t wav_data_size_pos = 0;
-
- String zeros_str(uint32_t p_index);
-
-protected:
- virtual uint32_t get_audio_mix_rate() const override;
- virtual AudioServer::SpeakerMode get_audio_speaker_mode() const override;
- virtual void get_supported_extensions(List<String> *r_extensions) const override;
-
- virtual Error write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) override;
- virtual Error write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) override;
- virtual void write_end() override;
-
- virtual bool handles_file(const String &p_path) const override;
-
-public:
- MovieWriterPNGWAV();
-};
-
-#endif // VIDEO_WRITER_H
+#endif // MOVIE_WRITER_H
diff --git a/servers/movie_writer/movie_writer_mjpeg.h b/servers/movie_writer/movie_writer_mjpeg.h
index 822bedfedf..233267df30 100644
--- a/servers/movie_writer/movie_writer_mjpeg.h
+++ b/servers/movie_writer/movie_writer_mjpeg.h
@@ -70,4 +70,4 @@ public:
MovieWriterMJPEG();
};
-#endif // MOVIE_WRITER_AVIJPEG_H
+#endif // MOVIE_WRITER_MJPEG_H
diff --git a/servers/movie_writer/movie_writer_pngwav.cpp b/servers/movie_writer/movie_writer_pngwav.cpp
new file mode 100644
index 0000000000..bd79b0bd98
--- /dev/null
+++ b/servers/movie_writer/movie_writer_pngwav.cpp
@@ -0,0 +1,168 @@
+/*************************************************************************/
+/* movie_writer_pngwav.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "movie_writer_pngwav.h"
+#include "core/config/project_settings.h"
+#include "core/io/dir_access.h"
+
+uint32_t MovieWriterPNGWAV::get_audio_mix_rate() const {
+ return mix_rate;
+}
+AudioServer::SpeakerMode MovieWriterPNGWAV::get_audio_speaker_mode() const {
+ return speaker_mode;
+}
+
+void MovieWriterPNGWAV::get_supported_extensions(List<String> *r_extensions) const {
+ r_extensions->push_back("png");
+}
+
+bool MovieWriterPNGWAV::handles_file(const String &p_path) const {
+ return p_path.get_extension().to_lower() == "png";
+}
+
+String MovieWriterPNGWAV::zeros_str(uint32_t p_index) {
+ char zeros[MAX_TRAILING_ZEROS + 1];
+ for (uint32_t i = 0; i < MAX_TRAILING_ZEROS; i++) {
+ uint32_t idx = MAX_TRAILING_ZEROS - i - 1;
+ uint32_t digit = (p_index / uint32_t(Math::pow(double(10), double(idx)))) % 10;
+ zeros[i] = '0' + digit;
+ }
+ zeros[MAX_TRAILING_ZEROS] = 0;
+ return zeros;
+}
+
+Error MovieWriterPNGWAV::write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) {
+ // Quick & Dirty PNGWAV Code based on - https://docs.microsoft.com/en-us/windows/win32/directshow/avi-riff-file-reference
+
+ base_path = p_base_path.get_basename();
+ if (base_path.is_relative_path()) {
+ base_path = "res://" + base_path;
+ }
+
+ {
+ //Remove existing files before writing anew
+ uint32_t idx = 0;
+ Ref<DirAccess> d = DirAccess::open(base_path.get_base_dir());
+ String file = base_path.get_file();
+ while (true) {
+ String path = file + zeros_str(idx) + ".png";
+ if (d->remove(path) != OK) {
+ break;
+ }
+ }
+ }
+
+ f_wav = FileAccess::open(base_path + ".wav", FileAccess::WRITE_READ);
+ ERR_FAIL_COND_V(f_wav.is_null(), ERR_CANT_OPEN);
+
+ fps = p_fps;
+
+ f_wav->store_buffer((const uint8_t *)"RIFF", 4);
+ int total_size = 4 /* WAVE */ + 8 /* fmt+size */ + 16 /* format */ + 8 /* data+size */;
+ f_wav->store_32(total_size); //will store final later
+ f_wav->store_buffer((const uint8_t *)"WAVE", 4);
+
+ /* FORMAT CHUNK */
+
+ f_wav->store_buffer((const uint8_t *)"fmt ", 4);
+
+ uint32_t channels = 2;
+ switch (speaker_mode) {
+ case AudioServer::SPEAKER_MODE_STEREO:
+ channels = 2;
+ break;
+ case AudioServer::SPEAKER_SURROUND_31:
+ channels = 4;
+ break;
+ case AudioServer::SPEAKER_SURROUND_51:
+ channels = 6;
+ break;
+ case AudioServer::SPEAKER_SURROUND_71:
+ channels = 8;
+ break;
+ }
+
+ f_wav->store_32(16); //standard format, no extra fields
+ f_wav->store_16(1); // compression code, standard PCM
+ f_wav->store_16(channels); //CHANNELS: 2
+
+ f_wav->store_32(mix_rate);
+
+ /* useless stuff the format asks for */
+
+ int bits_per_sample = 32;
+ int blockalign = bits_per_sample / 8 * channels;
+ int bytes_per_sec = mix_rate * blockalign;
+
+ audio_block_size = (mix_rate / fps) * blockalign;
+
+ f_wav->store_32(bytes_per_sec);
+ f_wav->store_16(blockalign); // block align (unused)
+ f_wav->store_16(bits_per_sample);
+
+ /* DATA CHUNK */
+
+ f_wav->store_buffer((const uint8_t *)"data", 4);
+
+ f_wav->store_32(0); //data size... wooh
+ wav_data_size_pos = f_wav->get_position();
+
+ return OK;
+}
+
+Error MovieWriterPNGWAV::write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) {
+ ERR_FAIL_COND_V(!f_wav.is_valid(), ERR_UNCONFIGURED);
+
+ Vector<uint8_t> png_buffer = p_image->save_png_to_buffer();
+
+ Ref<FileAccess> fi = FileAccess::open(base_path + zeros_str(frame_count) + ".png", FileAccess::WRITE);
+ fi->store_buffer(png_buffer.ptr(), png_buffer.size());
+ f_wav->store_buffer((const uint8_t *)p_audio_data, audio_block_size);
+
+ frame_count++;
+
+ return OK;
+}
+
+void MovieWriterPNGWAV::write_end() {
+ if (f_wav.is_valid()) {
+ uint32_t total_size = 4 /* WAVE */ + 8 /* fmt+size */ + 16 /* format */ + 8 /* data+size */;
+ uint32_t datasize = f_wav->get_position() - wav_data_size_pos;
+ f_wav->seek(4);
+ f_wav->store_32(total_size + datasize);
+ f_wav->seek(0x28);
+ f_wav->store_32(datasize);
+ }
+}
+
+MovieWriterPNGWAV::MovieWriterPNGWAV() {
+ mix_rate = GLOBAL_GET("editor/movie_writer/mix_rate");
+ speaker_mode = AudioServer::SpeakerMode(int(GLOBAL_GET("editor/movie_writer/speaker_mode")));
+}
diff --git a/servers/movie_writer/movie_writer_pngwav.h b/servers/movie_writer/movie_writer_pngwav.h
new file mode 100644
index 0000000000..64608ce387
--- /dev/null
+++ b/servers/movie_writer/movie_writer_pngwav.h
@@ -0,0 +1,71 @@
+/*************************************************************************/
+/* movie_writer_pngwav.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef MOVIE_WRITER_PNGWAV_H
+#define MOVIE_WRITER_PNGWAV_H
+
+#include "servers/movie_writer/movie_writer.h"
+
+class MovieWriterPNGWAV : public MovieWriter {
+ GDCLASS(MovieWriterPNGWAV, MovieWriter)
+
+ enum {
+ MAX_TRAILING_ZEROS = 8 // more than 10 days at 60fps, no hard drive can put up with this anyway :)
+ };
+
+ uint32_t mix_rate = 48000;
+ AudioServer::SpeakerMode speaker_mode = AudioServer::SPEAKER_MODE_STEREO;
+ String base_path;
+ uint32_t frame_count = 0;
+ uint32_t fps = 0;
+
+ uint32_t audio_block_size = 0;
+
+ Ref<FileAccess> f_wav;
+ uint32_t wav_data_size_pos = 0;
+
+ String zeros_str(uint32_t p_index);
+
+protected:
+ virtual uint32_t get_audio_mix_rate() const override;
+ virtual AudioServer::SpeakerMode get_audio_speaker_mode() const override;
+ virtual void get_supported_extensions(List<String> *r_extensions) const override;
+
+ virtual Error write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) override;
+ virtual Error write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) override;
+ virtual void write_end() override;
+
+ virtual bool handles_file(const String &p_path) const override;
+
+public:
+ MovieWriterPNGWAV();
+};
+
+#endif // MOVIE_WRITER_PNGWAV_H
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index d7d2340119..db473f6296 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -59,6 +59,7 @@
#include "display_server.h"
#include "movie_writer/movie_writer.h"
#include "movie_writer/movie_writer_mjpeg.h"
+#include "movie_writer/movie_writer_pngwav.h"
#include "navigation_server_2d.h"
#include "navigation_server_3d.h"
#include "physics_2d/godot_physics_server_2d.h"
diff --git a/servers/rendering/SCsub b/servers/rendering/SCsub
index 06d1d28b08..cf26ca029d 100644
--- a/servers/rendering/SCsub
+++ b/servers/rendering/SCsub
@@ -4,5 +4,6 @@ Import("env")
env.add_source_files(env.servers_sources, "*.cpp")
+SConscript("dummy/SCsub")
SConscript("renderer_rd/SCsub")
SConscript("storage/SCsub")
diff --git a/servers/rendering/dummy/SCsub b/servers/rendering/dummy/SCsub
new file mode 100644
index 0000000000..aa688af6cd
--- /dev/null
+++ b/servers/rendering/dummy/SCsub
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.servers_sources, "*.cpp")
+
+SConscript("storage/SCsub")
diff --git a/servers/rendering/dummy/environment/fog.h b/servers/rendering/dummy/environment/fog.h
new file mode 100644
index 0000000000..8a2be90507
--- /dev/null
+++ b/servers/rendering/dummy/environment/fog.h
@@ -0,0 +1,55 @@
+/*************************************************************************/
+/* fog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef FOG_DUMMY_H
+#define FOG_DUMMY_H
+
+#include "servers/rendering/environment/renderer_fog.h"
+
+namespace RendererDummy {
+
+class Fog : public RendererFog {
+public:
+ /* FOG VOLUMES */
+
+ virtual RID fog_volume_allocate() override { return RID(); }
+ virtual void fog_volume_initialize(RID p_rid) override {}
+ virtual void fog_free(RID p_rid) override {}
+
+ virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override {}
+ virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override {}
+ virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override {}
+ virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override { return AABB(); }
+ virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override { return RS::FOG_VOLUME_SHAPE_BOX; }
+};
+
+} // namespace RendererDummy
+
+#endif // !FOG_DUMMY_H
diff --git a/servers/rendering/dummy/environment/gi.h b/servers/rendering/dummy/environment/gi.h
index 374f0c8923..9c7647c2de 100644
--- a/servers/rendering/dummy/environment/gi.h
+++ b/servers/rendering/dummy/environment/gi.h
@@ -74,9 +74,6 @@ public:
virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override {}
virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override { return false; }
- virtual void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) override {}
- virtual float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const override { return 0; }
-
virtual uint32_t voxel_gi_get_version(RID p_voxel_gi) const override { return 0; }
};
diff --git a/servers/rendering/dummy/rasterizer_dummy.h b/servers/rendering/dummy/rasterizer_dummy.h
index 9c2bd45cce..d867114384 100644
--- a/servers/rendering/dummy/rasterizer_dummy.h
+++ b/servers/rendering/dummy/rasterizer_dummy.h
@@ -34,15 +34,16 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "scene/resources/mesh.h"
+#include "servers/rendering/dummy/environment/fog.h"
#include "servers/rendering/dummy/environment/gi.h"
#include "servers/rendering/dummy/rasterizer_canvas_dummy.h"
#include "servers/rendering/dummy/rasterizer_scene_dummy.h"
-#include "servers/rendering/dummy/rasterizer_storage_dummy.h"
#include "servers/rendering/dummy/storage/light_storage.h"
#include "servers/rendering/dummy/storage/material_storage.h"
#include "servers/rendering/dummy/storage/mesh_storage.h"
#include "servers/rendering/dummy/storage/particles_storage.h"
#include "servers/rendering/dummy/storage/texture_storage.h"
+#include "servers/rendering/dummy/storage/utilities.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
@@ -53,23 +54,25 @@ private:
protected:
RasterizerCanvasDummy canvas;
+ RendererDummy::Utilities utilities;
RendererDummy::LightStorage light_storage;
RendererDummy::MaterialStorage material_storage;
RendererDummy::MeshStorage mesh_storage;
RendererDummy::ParticlesStorage particles_storage;
RendererDummy::TextureStorage texture_storage;
RendererDummy::GI gi;
- RasterizerStorageDummy storage;
+ RendererDummy::Fog fog;
RasterizerSceneDummy scene;
public:
+ RendererUtilities *get_utilities() override { return &utilities; };
RendererLightStorage *get_light_storage() override { return &light_storage; };
RendererMaterialStorage *get_material_storage() override { return &material_storage; };
RendererMeshStorage *get_mesh_storage() override { return &mesh_storage; };
RendererParticlesStorage *get_particles_storage() override { return &particles_storage; };
RendererTextureStorage *get_texture_storage() override { return &texture_storage; };
RendererGI *get_gi() override { return &gi; };
- RendererStorage *get_storage() override { return &storage; }
+ RendererFog *get_fog() override { return &fog; };
RendererCanvasRender *get_canvas() override { return &canvas; }
RendererSceneRender *get_scene() override { return &scene; }
diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h
index e6d2b93f99..b49d6cff69 100644
--- a/servers/rendering/dummy/rasterizer_scene_dummy.h
+++ b/servers/rendering/dummy/rasterizer_scene_dummy.h
@@ -143,8 +143,8 @@ public:
void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) override {}
void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override {}
- void shadows_quality_set(RS::ShadowQuality p_quality) override {}
- void directional_shadow_quality_set(RS::ShadowQuality p_quality) override {}
+ void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override {}
+ void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override {}
RID light_instance_create(RID p_light) override { return RID(); }
void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override {}
diff --git a/servers/rendering/dummy/storage/SCsub b/servers/rendering/dummy/storage/SCsub
new file mode 100644
index 0000000000..86681f9c74
--- /dev/null
+++ b/servers/rendering/dummy/storage/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.servers_sources, "*.cpp")
diff --git a/servers/rendering/dummy/storage/material_storage.h b/servers/rendering/dummy/storage/material_storage.h
index 8890be8ea9..d4809f81e3 100644
--- a/servers/rendering/dummy/storage/material_storage.h
+++ b/servers/rendering/dummy/storage/material_storage.h
@@ -32,6 +32,7 @@
#define MATERIAL_STORAGE_DUMMY_H
#include "servers/rendering/storage/material_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererDummy {
@@ -87,7 +88,7 @@ public:
virtual bool material_is_animated(RID p_material) override { return false; }
virtual bool material_casts_shadows(RID p_material) override { return false; }
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
- virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override {}
+ virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {}
};
} // namespace RendererDummy
diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h
index dfbd265bba..78b19d721d 100644
--- a/servers/rendering/dummy/storage/mesh_storage.h
+++ b/servers/rendering/dummy/storage/mesh_storage.h
@@ -32,6 +32,7 @@
#define MESH_STORAGE_DUMMY_H
#include "servers/rendering/storage/mesh_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererDummy {
@@ -121,7 +122,11 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override {}
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override { return Transform2D(); }
- virtual void skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) override {}
+ virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
+
+ /* OCCLUDER */
+
+ void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {}
};
} // namespace RendererDummy
diff --git a/servers/rendering/dummy/storage/texture_storage.cpp b/servers/rendering/dummy/storage/texture_storage.cpp
new file mode 100644
index 0000000000..62e2a306a2
--- /dev/null
+++ b/servers/rendering/dummy/storage/texture_storage.cpp
@@ -0,0 +1,43 @@
+/*************************************************************************/
+/* texture_storage.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "texture_storage.h"
+
+using namespace RendererDummy;
+
+TextureStorage *TextureStorage::singleton = nullptr;
+
+TextureStorage::TextureStorage() {
+ singleton = this;
+}
+
+TextureStorage::~TextureStorage() {
+ singleton = nullptr;
+}
diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h
index 11d827a6e3..195d378a41 100644
--- a/servers/rendering/dummy/storage/texture_storage.h
+++ b/servers/rendering/dummy/storage/texture_storage.h
@@ -38,6 +38,8 @@ namespace RendererDummy {
class TextureStorage : public RendererTextureStorage {
private:
+ static TextureStorage *singleton;
+
struct DummyTexture {
Ref<Image> image;
};
@@ -45,11 +47,12 @@ private:
public:
static TextureStorage *get_singleton() {
- // Here we cheat until we can retire RasterizerStorageDummy::free()
-
- return (TextureStorage *)RSG::texture_storage;
+ return singleton;
};
+ TextureStorage();
+ ~TextureStorage();
+
virtual bool can_create_resources_async() const override { return false; }
/* Canvas Texture API */
@@ -166,6 +169,9 @@ public:
virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override {}
virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); }
virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override {}
+
+ virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) override{};
+ virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override{};
};
} // namespace RendererDummy
diff --git a/servers/rendering/dummy/rasterizer_storage_dummy.h b/servers/rendering/dummy/storage/utilities.h
index 7f637d2c42..f090309e88 100644
--- a/servers/rendering/dummy/rasterizer_storage_dummy.h
+++ b/servers/rendering/dummy/storage/utilities.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* rasterizer_storage_dummy.h */
+/* utilities.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,79 +28,71 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_STORAGE_DUMMY_H
-#define RASTERIZER_STORAGE_DUMMY_H
+#ifndef UTILITIES_DUMMY_H
+#define UTILITIES_DUMMY_H
-#include "servers/rendering/renderer_storage.h"
-#include "storage/texture_storage.h"
+#include "servers/rendering/storage/utilities.h"
+#include "texture_storage.h"
-class RasterizerStorageDummy : public RendererStorage {
-public:
- void base_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
-
- /* OCCLUDER */
+namespace RendererDummy {
- void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {}
+class Utilities : public RendererUtilities {
+public:
+ /* INSTANCES */
- /* FOG VOLUMES */
+ virtual RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; }
+ virtual bool free(RID p_rid) override {
+ if (RendererDummy::TextureStorage::get_singleton()->owns_texture(p_rid)) {
+ RendererDummy::TextureStorage::get_singleton()->texture_free(p_rid);
+ return true;
+ }
+ return false;
+ }
- RID fog_volume_allocate() override { return RID(); }
- void fog_volume_initialize(RID p_rid) override {}
+ /* DEPENDENCIES */
- void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override {}
- void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override {}
- void fog_volume_set_material(RID p_fog_volume, RID p_material) override {}
- AABB fog_volume_get_aabb(RID p_fog_volume) const override { return AABB(); }
- RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override { return RS::FOG_VOLUME_SHAPE_BOX; }
+ virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
/* VISIBILITY NOTIFIER */
+
virtual RID visibility_notifier_allocate() override { return RID(); }
virtual void visibility_notifier_initialize(RID p_notifier) override {}
+ virtual void visibility_notifier_free(RID p_notifier) override {}
+
virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override {}
virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override {}
virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override { return AABB(); }
virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override {}
- /* STORAGE */
+ /* TIMING */
- RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; }
- bool free(RID p_rid) override {
- if (RendererDummy::TextureStorage::get_singleton()->owns_texture(p_rid)) {
- RendererDummy::TextureStorage::get_singleton()->texture_free(p_rid);
- return true;
- }
- return false;
- }
+ virtual void capture_timestamps_begin() override {}
+ virtual void capture_timestamp(const String &p_name) override {}
+ virtual uint32_t get_captured_timestamps_count() const override { return 0; }
+ virtual uint64_t get_captured_timestamps_frame() const override { return 0; }
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override { return 0; }
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override { return 0; }
+ virtual String get_captured_timestamp_name(uint32_t p_index) const override { return String(); }
- virtual void update_memory_info() override {}
- virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override { return 0; }
+ /* MISC */
+
+ virtual void update_dirty_resources() override {}
+ virtual void set_debug_generate_wireframes(bool p_generate) override {}
- bool has_os_feature(const String &p_feature) const override {
+ virtual bool has_os_feature(const String &p_feature) const override {
return p_feature == "rgtc" || p_feature == "bptc" || p_feature == "s3tc" || p_feature == "etc" || p_feature == "etc2";
}
- void update_dirty_resources() override {}
-
- void set_debug_generate_wireframes(bool p_generate) override {}
-
- String get_video_adapter_name() const override { return String(); }
- String get_video_adapter_vendor() const override { return String(); }
- RenderingDevice::DeviceType get_video_adapter_type() const override { return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER; }
- String get_video_adapter_api_version() const override { return String(); }
-
- static RendererStorage *base_singleton;
-
- void capture_timestamps_begin() override {}
- void capture_timestamp(const String &p_name) override {}
- uint32_t get_captured_timestamps_count() const override { return 0; }
- uint64_t get_captured_timestamps_frame() const override { return 0; }
- uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override { return 0; }
- uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override { return 0; }
- String get_captured_timestamp_name(uint32_t p_index) const override { return String(); }
+ virtual void update_memory_info() override {}
- RasterizerStorageDummy() {}
- ~RasterizerStorageDummy() {}
+ virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override { return 0; }
+ virtual String get_video_adapter_name() const override { return String(); }
+ virtual String get_video_adapter_vendor() const override { return String(); }
+ virtual RenderingDevice::DeviceType get_video_adapter_type() const override { return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER; }
+ virtual String get_video_adapter_api_version() const override { return String(); }
};
-#endif // !RASTERIZER_STORAGE_DUMMY_H
+} // namespace RendererDummy
+
+#endif // !UTILITIES_DUMMY_H
diff --git a/servers/rendering/environment/renderer_fog.h b/servers/rendering/environment/renderer_fog.h
new file mode 100644
index 0000000000..ac50da0fc0
--- /dev/null
+++ b/servers/rendering/environment/renderer_fog.h
@@ -0,0 +1,53 @@
+/*************************************************************************/
+/* renderer_fog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RENDERER_FOG_H
+#define RENDERER_FOG_H
+
+#include "servers/rendering_server.h"
+
+class RendererFog {
+public:
+ virtual ~RendererFog() {}
+
+ /* FOG VOLUMES */
+
+ virtual RID fog_volume_allocate() = 0;
+ virtual void fog_volume_initialize(RID p_rid) = 0;
+ virtual void fog_free(RID p_rid) = 0;
+
+ virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) = 0;
+ virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) = 0;
+ virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) = 0;
+ virtual AABB fog_volume_get_aabb(RID p_fog_volume) const = 0;
+ virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const = 0;
+};
+
+#endif // !RENDERER_FOG_H
diff --git a/servers/rendering/environment/renderer_gi.h b/servers/rendering/environment/renderer_gi.h
index c4f63b7b6b..4f93bb8675 100644
--- a/servers/rendering/environment/renderer_gi.h
+++ b/servers/rendering/environment/renderer_gi.h
@@ -31,7 +31,6 @@
#ifndef RENDERER_GI_H
#define RENDERER_GI_H
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
class RendererGI {
@@ -76,9 +75,6 @@ public:
virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) = 0;
virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const = 0;
- virtual void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) = 0;
- virtual float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const = 0;
-
virtual uint32_t voxel_gi_get_version(RID p_probe) const = 0;
};
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index bc1e8eb348..dea68ac61c 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -76,10 +76,11 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas
}
}
-void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, RendererCanvasCull::Item **r_items, int &r_index) {
+void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, RendererCanvasCull::Item **r_items, int &r_index, int p_z) {
int child_item_count = p_canvas_item->child_items.size();
RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw();
for (int i = 0; i < child_item_count; i++) {
+ int abs_z = 0;
if (child_items[i]->visible) {
if (r_items) {
r_items[r_index] = child_items[i];
@@ -87,12 +88,20 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2
child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.columns[2]);
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr;
child_items[i]->ysort_index = r_index;
+ child_items[i]->ysort_parent_abs_z_index = p_z;
+
+ // Y sorted canvas items are flattened into r_items. Calculate their absolute z index to use when rendering r_items.
+ if (child_items[i]->z_relative) {
+ abs_z = CLAMP(p_z + child_items[i]->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
+ } else {
+ abs_z = child_items[i]->z_index;
+ }
}
r_index++;
if (child_items[i]->sort_y) {
- _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index);
+ _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index, abs_z);
}
}
}
@@ -277,6 +286,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
ci->final_clip_owner = p_canvas_clip;
}
+ int parent_z = p_z;
if (ci->z_relative) {
p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
} else {
@@ -287,22 +297,23 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (allow_y_sort) {
if (ci->ysort_children_count == -1) {
ci->ysort_children_count = 0;
- _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count);
+ _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count, p_z);
}
child_item_count = ci->ysort_children_count + 1;
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
+ ci->ysort_parent_abs_z_index = parent_z;
child_items[0] = ci;
int i = 1;
- _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i);
+ _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i, p_z);
ci->ysort_xform = ci->xform.affine_inverse();
SortArray<Item *, ItemPtrSort> sorter;
sorter.sort(child_items, child_item_count);
for (i = 0; i < child_item_count; i++) {
- _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false);
+ _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, child_items[i]->ysort_parent_abs_z_index, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false);
}
} else {
RendererCanvasRender::Item *canvas_group_from = nullptr;
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index 963cca7630..48d0598c9f 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -53,6 +53,7 @@ public:
Transform2D ysort_xform;
Vector2 ysort_pos;
int ysort_index;
+ int ysort_parent_abs_z_index; // Absolute Z index of parent. Only populated and used when y-sorting.
Vector<Item *> child_items;
@@ -84,6 +85,7 @@ public:
ysort_xform = Transform2D();
ysort_pos = Vector2();
ysort_index = 0;
+ ysort_parent_abs_z_index = 0;
}
};
diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp
index 163a24247e..623f0c647b 100644
--- a/servers/rendering/renderer_canvas_render.cpp
+++ b/servers/rendering/renderer_canvas_render.cpp
@@ -128,3 +128,9 @@ const Rect2 &RendererCanvasRender::Item::get_rect() const {
rect_dirty = false;
return rect;
}
+
+RendererCanvasRender::Item::CommandMesh::~CommandMesh() {
+ if (mesh_instance.is_valid()) {
+ RSG::mesh_storage->mesh_instance_free(mesh_instance);
+ }
+}
diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h
index 1724a99b20..52b2f82089 100644
--- a/servers/rendering/renderer_canvas_render.h
+++ b/servers/rendering/renderer_canvas_render.h
@@ -31,7 +31,7 @@
#ifndef RENDERINGSERVERCANVASRENDER_H
#define RENDERINGSERVERCANVASRENDER_H
-#include "servers/rendering/renderer_storage.h"
+#include "servers/rendering_server.h"
class RendererCanvasRender {
public:
@@ -257,11 +257,7 @@ public:
RID texture;
CommandMesh() { type = TYPE_MESH; }
- ~CommandMesh() {
- if (mesh_instance.is_valid()) {
- RendererStorage::base_singleton->free(mesh_instance);
- }
- }
+ ~CommandMesh();
};
struct CommandMultiMesh : public Command {
diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h
index f58bc851ef..a67eb25736 100644
--- a/servers/rendering/renderer_compositor.h
+++ b/servers/rendering/renderer_compositor.h
@@ -31,15 +31,16 @@
#ifndef RENDERING_SERVER_COMPOSITOR_H
#define RENDERING_SERVER_COMPOSITOR_H
+#include "servers/rendering/environment/renderer_fog.h"
#include "servers/rendering/environment/renderer_gi.h"
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_scene.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/light_storage.h"
#include "servers/rendering/storage/material_storage.h"
#include "servers/rendering/storage/mesh_storage.h"
#include "servers/rendering/storage/particles_storage.h"
#include "servers/rendering/storage/texture_storage.h"
+#include "servers/rendering/storage/utilities.h"
#include "servers/rendering_server.h"
class RendererSceneRender;
@@ -77,13 +78,14 @@ protected:
public:
static RendererCompositor *create();
+ virtual RendererUtilities *get_utilities() = 0;
virtual RendererLightStorage *get_light_storage() = 0;
virtual RendererMaterialStorage *get_material_storage() = 0;
virtual RendererMeshStorage *get_mesh_storage() = 0;
virtual RendererParticlesStorage *get_particles_storage() = 0;
virtual RendererTextureStorage *get_texture_storage() = 0;
virtual RendererGI *get_gi() = 0;
- virtual RendererStorage *get_storage() = 0;
+ virtual RendererFog *get_fog() = 0;
virtual RendererCanvasRender *get_canvas() = 0;
virtual RendererSceneRender *get_scene() = 0;
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
index 0b36fe3964..228933d618 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -413,7 +413,7 @@ void ClusterBuilderRD::bake_cluster() {
StateUniform state;
- RendererStorageRD::store_camera(adjusted_projection, state.projection);
+ RendererRD::MaterialStorage::store_camera(adjusted_projection, state.projection);
state.inv_z_far = 1.0 / z_far;
state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size);
state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h
index e82193ea6a..74ca530ff6 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.h
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.h
@@ -31,10 +31,10 @@
#ifndef CLUSTER_BUILDER_RD_H
#define CLUSTER_BUILDER_RD_H
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/cluster_debug.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/cluster_render.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/cluster_store.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
class ClusterBuilderSharedDataRD {
friend class ClusterBuilderRD;
@@ -261,7 +261,7 @@ public:
e.type = ELEMENT_TYPE_OMNI_LIGHT;
e.original_index = cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT];
- RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv);
+ RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv);
cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT]++;
@@ -309,7 +309,7 @@ public:
e.type = ELEMENT_TYPE_SPOT_LIGHT;
e.original_index = cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]; //use omni since they share index
- RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv);
+ RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv);
cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]++;
}
@@ -356,7 +356,7 @@ public:
e.type = (p_box_type == BOX_TYPE_DECAL) ? ELEMENT_TYPE_DECAL : ELEMENT_TYPE_REFLECTION_PROBE;
e.original_index = cluster_count_by_type[e.type];
- RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv);
+ RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv);
cluster_count_by_type[e.type]++;
render_element_count++;
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp
index c30e8ed58f..5507483cee 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp
@@ -100,11 +100,11 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) {
{
Vector<String> copy_modes;
- copy_modes.push_back("\n");
- copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n");
- copy_modes.push_back("\n#define MODE_TWO_SOURCES\n");
- copy_modes.push_back("\n#define MULTIVIEW\n");
- copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n");
+ copy_modes.push_back("\n"); // COPY_TO_FB_COPY
+ copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n"); // COPY_TO_FB_COPY_PANORAMA_TO_DP
+ copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_COPY2
+ copy_modes.push_back("\n#define MULTIVIEW\n"); // COPY_TO_FB_MULTIVIEW
+ copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_MULTIVIEW_WITH_DEPTH
copy_to_fb.shader.initialize(copy_modes);
@@ -249,6 +249,56 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) {
roughness.raster_pipeline.clear();
}
}
+
+ {
+ Vector<String> specular_modes;
+ specular_modes.push_back("\n#define MODE_MERGE\n"); // SPECULAR_MERGE_ADD
+ specular_modes.push_back("\n#define MODE_MERGE\n#define MODE_SSR\n"); // SPECULAR_MERGE_SSR
+ specular_modes.push_back("\n"); // SPECULAR_MERGE_ADDITIVE_ADD
+ specular_modes.push_back("\n#define MODE_SSR\n"); // SPECULAR_MERGE_ADDITIVE_SSR
+
+ specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_MERGE\n"); // SPECULAR_MERGE_ADD_MULTIVIEW
+ specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_MERGE\n#define MODE_SSR\n"); // SPECULAR_MERGE_SSR_MULTIVIEW
+ specular_modes.push_back("\n#define USE_MULTIVIEW\n"); // SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW
+ specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_SSR\n"); // SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW
+
+ specular_merge.shader.initialize(specular_modes);
+
+ if (!RendererCompositorRD::singleton->is_xr_enabled()) {
+ specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADD_MULTIVIEW, false);
+ specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_SSR_MULTIVIEW, false);
+ specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW, false);
+ specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW, false);
+ }
+
+ specular_merge.shader_version = specular_merge.shader.version_create();
+
+ //use additive
+
+ RD::PipelineColorBlendState::Attachment ba;
+ ba.enable_blend = true;
+ ba.src_color_blend_factor = RD::BLEND_FACTOR_ONE;
+ ba.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
+ ba.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
+ ba.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
+ ba.color_blend_op = RD::BLEND_OP_ADD;
+ ba.alpha_blend_op = RD::BLEND_OP_ADD;
+
+ RD::PipelineColorBlendState blend_additive;
+ blend_additive.attachments.push_back(ba);
+
+ for (int i = 0; i < SPECULAR_MERGE_MAX; i++) {
+ if (specular_merge.shader.is_variant_enabled(i)) {
+ RD::PipelineColorBlendState blend_state;
+ if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR || i == SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW || i == SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW) {
+ blend_state = blend_additive;
+ } else {
+ blend_state = RD::PipelineColorBlendState::create_disabled();
+ }
+ specular_merge.pipelines[i].setup(specular_merge.shader.version_get_shader(specular_merge.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
+ }
+ }
+ }
}
CopyEffects::~CopyEffects() {
@@ -264,6 +314,8 @@ CopyEffects::~CopyEffects() {
roughness.compute_shader.version_free(roughness.shader_version);
}
+ specular_merge.shader.version_free(specular_merge.shader_version);
+
RD::get_singleton()->free(filter.coefficient_buffer);
if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {
@@ -1083,3 +1135,57 @@ void CopyEffects::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_f
RD::get_singleton()->draw_list_draw(draw_list, true);
RD::get_singleton()->draw_list_end();
}
+
+void CopyEffects::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection, uint32_t p_view_count) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::get_singleton()->draw_command_begin_label("Merge specular");
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, Vector<Color>());
+
+ int mode;
+ if (p_reflection.is_valid()) {
+ if (p_base.is_valid()) {
+ mode = SPECULAR_MERGE_SSR;
+ } else {
+ mode = SPECULAR_MERGE_ADDITIVE_SSR;
+ }
+ } else {
+ if (p_base.is_valid()) {
+ mode = SPECULAR_MERGE_ADD;
+ } else {
+ mode = SPECULAR_MERGE_ADDITIVE_ADD;
+ }
+ }
+
+ if (p_view_count > 1) {
+ mode += SPECULAR_MERGE_ADD_MULTIVIEW;
+ }
+
+ RID shader = specular_merge.shader.version_get_shader(specular_merge.shader_version, mode);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
+
+ if (p_base.is_valid()) {
+ RD::Uniform u_base(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_base }));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 2, u_base), 2);
+ }
+
+ RD::Uniform u_specular(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_specular }));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_specular), 0);
+
+ if (p_reflection.is_valid()) {
+ RD::Uniform u_reflection(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_reflection }));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_reflection), 1);
+ }
+
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+
+ RD::get_singleton()->draw_command_end_label();
+}
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h
index 882b446964..0066f2be31 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.h
+++ b/servers/rendering/renderer_rd/effects/copy_effects.h
@@ -42,6 +42,7 @@
#include "servers/rendering/renderer_rd/shaders/effects/cubemap_filter_raster.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/cubemap_roughness.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_raster.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering_server.h"
@@ -274,6 +275,33 @@ private:
PipelineCacheRD raster_pipeline;
} roughness;
+ // Merge specular
+
+ enum SpecularMergeMode {
+ SPECULAR_MERGE_ADD,
+ SPECULAR_MERGE_SSR,
+ SPECULAR_MERGE_ADDITIVE_ADD,
+ SPECULAR_MERGE_ADDITIVE_SSR,
+
+ SPECULAR_MERGE_ADD_MULTIVIEW,
+ SPECULAR_MERGE_SSR_MULTIVIEW,
+ SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW,
+ SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW,
+
+ SPECULAR_MERGE_MAX
+ };
+
+ /* Specular merge must be done using raster, rather than compute
+ * because it must continue the existing color buffer
+ */
+
+ struct SpecularMerge {
+ SpecularMergeShaderRD shader;
+ RID shader_version;
+ PipelineCacheRD pipelines[SPECULAR_MERGE_MAX];
+
+ } specular_merge;
+
static CopyEffects *singleton;
public:
@@ -309,6 +337,8 @@ public:
void cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
+
+ void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection, uint32_t p_view_count);
};
} // namespace RendererRD
diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp
new file mode 100644
index 0000000000..49d66023d8
--- /dev/null
+++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp
@@ -0,0 +1,1715 @@
+/*************************************************************************/
+/* ss_effects.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "ss_effects.h"
+
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
+#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
+
+using namespace RendererRD;
+
+SSEffects *SSEffects::singleton = nullptr;
+
+static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ p_array[i * 4 + j] = p_mtx.matrix[i][j];
+ }
+ }
+}
+
+SSEffects::SSEffects() {
+ singleton = this;
+
+ {
+ // Initialize depth buffer for screen space effects
+ Vector<String> downsampler_modes;
+ downsampler_modes.push_back("\n");
+ downsampler_modes.push_back("\n#define USE_HALF_SIZE\n");
+ downsampler_modes.push_back("\n#define GENERATE_MIPS\n");
+ downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define USE_HALF_SIZE\n");
+ downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n");
+ downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n#define USE_HALF_SIZE\n");
+ downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define GENERATE_FULL_MIPS");
+
+ ss_effects.downsample_shader.initialize(downsampler_modes);
+
+ ss_effects.downsample_shader_version = ss_effects.downsample_shader.version_create();
+
+ for (int i = 0; i < SS_EFFECTS_MAX; i++) {
+ ss_effects.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, i));
+ }
+
+ ss_effects.gather_constants_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSEffectsGatherConstants));
+ SSEffectsGatherConstants gather_constants;
+
+ const int sub_pass_count = 5;
+ for (int pass = 0; pass < 4; pass++) {
+ for (int subPass = 0; subPass < sub_pass_count; subPass++) {
+ int a = pass;
+ int b = subPass;
+
+ int spmap[5]{ 0, 1, 4, 3, 2 };
+ b = spmap[subPass];
+
+ float ca, sa;
+ float angle0 = (float(a) + float(b) / float(sub_pass_count)) * Math_PI * 0.5f;
+
+ ca = Math::cos(angle0);
+ sa = Math::sin(angle0);
+
+ float scale = 1.0f + (a - 1.5f + (b - (sub_pass_count - 1.0f) * 0.5f) / float(sub_pass_count)) * 0.07f;
+
+ gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 0] = scale * ca;
+ gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 1] = scale * -sa;
+ gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 2] = -scale * sa;
+ gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 3] = -scale * ca;
+ }
+ }
+
+ RD::get_singleton()->buffer_update(ss_effects.gather_constants_buffer, 0, sizeof(SSEffectsGatherConstants), &gather_constants);
+ }
+
+ // Initialize Screen Space Indirect Lighting (SSIL)
+
+ {
+ Vector<String> ssil_modes;
+ ssil_modes.push_back("\n");
+ ssil_modes.push_back("\n#define SSIL_BASE\n");
+ ssil_modes.push_back("\n#define ADAPTIVE\n");
+
+ ssil.gather_shader.initialize(ssil_modes);
+
+ ssil.gather_shader_version = ssil.gather_shader.version_create();
+
+ for (int i = SSIL_GATHER; i <= SSIL_GATHER_ADAPTIVE; i++) {
+ ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.gather_shader.version_get_shader(ssil.gather_shader_version, i));
+ }
+ ssil.projection_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSILProjectionUniforms));
+ }
+
+ {
+ Vector<String> ssil_modes;
+ ssil_modes.push_back("\n#define GENERATE_MAP\n");
+ ssil_modes.push_back("\n#define PROCESS_MAPA\n");
+ ssil_modes.push_back("\n#define PROCESS_MAPB\n");
+
+ ssil.importance_map_shader.initialize(ssil_modes);
+
+ ssil.importance_map_shader_version = ssil.importance_map_shader.version_create();
+
+ for (int i = SSIL_GENERATE_IMPORTANCE_MAP; i <= SSIL_PROCESS_IMPORTANCE_MAPB; i++) {
+ ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, i - SSIL_GENERATE_IMPORTANCE_MAP));
+ }
+ ssil.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t));
+ int zero[1] = { 0 };
+ RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero);
+ RD::get_singleton()->set_resource_name(ssil.importance_map_load_counter, "Importance Map Load Counter");
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.append_id(ssil.importance_map_load_counter);
+ uniforms.push_back(u);
+ }
+ ssil.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, 2), 2);
+ RD::get_singleton()->set_resource_name(ssil.counter_uniform_set, "Load Counter Uniform Set");
+ }
+
+ {
+ Vector<String> ssil_modes;
+ ssil_modes.push_back("\n#define MODE_NON_SMART\n");
+ ssil_modes.push_back("\n#define MODE_SMART\n");
+ ssil_modes.push_back("\n#define MODE_WIDE\n");
+
+ ssil.blur_shader.initialize(ssil_modes);
+
+ ssil.blur_shader_version = ssil.blur_shader.version_create();
+ for (int i = SSIL_BLUR_PASS; i <= SSIL_BLUR_PASS_WIDE; i++) {
+ ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.blur_shader.version_get_shader(ssil.blur_shader_version, i - SSIL_BLUR_PASS));
+ }
+ }
+
+ {
+ Vector<String> ssil_modes;
+ ssil_modes.push_back("\n#define MODE_NON_SMART\n");
+ ssil_modes.push_back("\n#define MODE_SMART\n");
+ ssil_modes.push_back("\n#define MODE_HALF\n");
+
+ ssil.interleave_shader.initialize(ssil_modes);
+
+ ssil.interleave_shader_version = ssil.interleave_shader.version_create();
+ for (int i = SSIL_INTERLEAVE; i <= SSIL_INTERLEAVE_HALF; i++) {
+ ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.interleave_shader.version_get_shader(ssil.interleave_shader_version, i - SSIL_INTERLEAVE));
+ }
+ }
+
+ {
+ // Initialize Screen Space Ambient Occlusion (SSAO)
+
+ RD::SamplerState sampler;
+ sampler.mag_filter = RD::SAMPLER_FILTER_NEAREST;
+ sampler.min_filter = RD::SAMPLER_FILTER_NEAREST;
+ sampler.mip_filter = RD::SAMPLER_FILTER_NEAREST;
+ sampler.repeat_u = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
+ sampler.repeat_v = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
+ sampler.repeat_w = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
+ sampler.max_lod = 4;
+
+ uint32_t pipeline = 0;
+ {
+ Vector<String> ssao_modes;
+
+ ssao_modes.push_back("\n");
+ ssao_modes.push_back("\n#define SSAO_BASE\n");
+ ssao_modes.push_back("\n#define ADAPTIVE\n");
+
+ ssao.gather_shader.initialize(ssao_modes);
+
+ ssao.gather_shader_version = ssao.gather_shader.version_create();
+
+ for (int i = 0; i <= SSAO_GATHER_ADAPTIVE; i++) {
+ ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.gather_shader.version_get_shader(ssao.gather_shader_version, i));
+ pipeline++;
+ }
+ }
+
+ {
+ Vector<String> ssao_modes;
+ ssao_modes.push_back("\n#define GENERATE_MAP\n");
+ ssao_modes.push_back("\n#define PROCESS_MAPA\n");
+ ssao_modes.push_back("\n#define PROCESS_MAPB\n");
+
+ ssao.importance_map_shader.initialize(ssao_modes);
+
+ ssao.importance_map_shader_version = ssao.importance_map_shader.version_create();
+
+ for (int i = SSAO_GENERATE_IMPORTANCE_MAP; i <= SSAO_PROCESS_IMPORTANCE_MAPB; i++) {
+ ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, i - SSAO_GENERATE_IMPORTANCE_MAP));
+
+ pipeline++;
+ }
+
+ ssao.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t));
+ int zero[1] = { 0 };
+ RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero);
+ RD::get_singleton()->set_resource_name(ssao.importance_map_load_counter, "Importance Map Load Counter");
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.append_id(ssao.importance_map_load_counter);
+ uniforms.push_back(u);
+ }
+ ssao.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 2), 2);
+ RD::get_singleton()->set_resource_name(ssao.counter_uniform_set, "Load Counter Uniform Set");
+ }
+
+ {
+ Vector<String> ssao_modes;
+ ssao_modes.push_back("\n#define MODE_NON_SMART\n");
+ ssao_modes.push_back("\n#define MODE_SMART\n");
+ ssao_modes.push_back("\n#define MODE_WIDE\n");
+
+ ssao.blur_shader.initialize(ssao_modes);
+
+ ssao.blur_shader_version = ssao.blur_shader.version_create();
+
+ for (int i = SSAO_BLUR_PASS; i <= SSAO_BLUR_PASS_WIDE; i++) {
+ ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.blur_shader.version_get_shader(ssao.blur_shader_version, i - SSAO_BLUR_PASS));
+
+ pipeline++;
+ }
+ }
+
+ {
+ Vector<String> ssao_modes;
+ ssao_modes.push_back("\n#define MODE_NON_SMART\n");
+ ssao_modes.push_back("\n#define MODE_SMART\n");
+ ssao_modes.push_back("\n#define MODE_HALF\n");
+
+ ssao.interleave_shader.initialize(ssao_modes);
+
+ ssao.interleave_shader_version = ssao.interleave_shader.version_create();
+ for (int i = SSAO_INTERLEAVE; i <= SSAO_INTERLEAVE_HALF; i++) {
+ ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, i - SSAO_INTERLEAVE));
+ RD::get_singleton()->set_resource_name(ssao.pipelines[pipeline], "Interleave Pipeline " + itos(i));
+ pipeline++;
+ }
+ }
+
+ ERR_FAIL_COND(pipeline != SSAO_MAX);
+
+ ss_effects.mirror_sampler = RD::get_singleton()->sampler_create(sampler);
+ }
+
+ {
+ // Screen Space Reflections
+
+ Vector<RD::PipelineSpecializationConstant> specialization_constants;
+
+ {
+ RD::PipelineSpecializationConstant sc;
+ sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
+ sc.constant_id = 0; // SSR_USE_FULL_PROJECTION_MATRIX
+ sc.bool_value = false;
+ specialization_constants.push_back(sc);
+ }
+
+ {
+ Vector<String> ssr_scale_modes;
+ ssr_scale_modes.push_back("\n");
+
+ ssr_scale.shader.initialize(ssr_scale_modes);
+ ssr_scale.shader_version = ssr_scale.shader.version_create();
+
+ for (int v = 0; v < SSR_VARIATIONS; v++) {
+ specialization_constants.ptrw()[0].bool_value = (v & SSR_MULTIVIEW) ? true : false;
+ ssr_scale.pipelines[v] = RD::get_singleton()->compute_pipeline_create(ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), specialization_constants);
+ }
+ }
+
+ {
+ Vector<String> ssr_modes;
+ ssr_modes.push_back("\n"); // SCREEN_SPACE_REFLECTION_NORMAL
+ ssr_modes.push_back("\n#define MODE_ROUGH\n"); // SCREEN_SPACE_REFLECTION_ROUGH
+
+ ssr.shader.initialize(ssr_modes);
+ ssr.shader_version = ssr.shader.version_create();
+
+ for (int v = 0; v < SSR_VARIATIONS; v++) {
+ specialization_constants.ptrw()[0].bool_value = (v & SSR_MULTIVIEW) ? true : false;
+ for (int i = 0; i < SCREEN_SPACE_REFLECTION_MAX; i++) {
+ ssr.pipelines[v][i] = RD::get_singleton()->compute_pipeline_create(ssr.shader.version_get_shader(ssr.shader_version, i), specialization_constants);
+ }
+ }
+ }
+
+ {
+ Vector<String> ssr_filter_modes;
+ ssr_filter_modes.push_back("\n"); // SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL
+ ssr_filter_modes.push_back("\n#define VERTICAL_PASS\n"); // SCREEN_SPACE_REFLECTION_FILTER_VERTICAL
+
+ ssr_filter.shader.initialize(ssr_filter_modes);
+ ssr_filter.shader_version = ssr_filter.shader.version_create();
+
+ for (int v = 0; v < SSR_VARIATIONS; v++) {
+ specialization_constants.ptrw()[0].bool_value = (v & SSR_MULTIVIEW) ? true : false;
+ for (int i = 0; i < SCREEN_SPACE_REFLECTION_FILTER_MAX; i++) {
+ ssr_filter.pipelines[v][i] = RD::get_singleton()->compute_pipeline_create(ssr_filter.shader.version_get_shader(ssr_filter.shader_version, i), specialization_constants);
+ }
+ }
+ }
+ }
+}
+
+SSEffects::~SSEffects() {
+ {
+ // Cleanup SS Reflections
+ ssr.shader.version_free(ssr.shader_version);
+ ssr_filter.shader.version_free(ssr_filter.shader_version);
+ ssr_scale.shader.version_free(ssr_scale.shader_version);
+
+ if (ssr.ubo.is_valid()) {
+ RD::get_singleton()->free(ssr.ubo);
+ }
+ }
+
+ {
+ // Cleanup SS downsampler
+ ss_effects.downsample_shader.version_free(ss_effects.downsample_shader_version);
+
+ RD::get_singleton()->free(ss_effects.mirror_sampler);
+ RD::get_singleton()->free(ss_effects.gather_constants_buffer);
+ }
+
+ {
+ // Cleanup SSIL
+ ssil.blur_shader.version_free(ssil.blur_shader_version);
+ ssil.gather_shader.version_free(ssil.gather_shader_version);
+ ssil.interleave_shader.version_free(ssil.interleave_shader_version);
+ ssil.importance_map_shader.version_free(ssil.importance_map_shader_version);
+
+ RD::get_singleton()->free(ssil.importance_map_load_counter);
+ RD::get_singleton()->free(ssil.projection_uniform_buffer);
+ }
+
+ {
+ // Cleanup SSAO
+ ssao.blur_shader.version_free(ssao.blur_shader_version);
+ ssao.gather_shader.version_free(ssao.gather_shader_version);
+ ssao.interleave_shader.version_free(ssao.interleave_shader_version);
+ ssao.importance_map_shader.version_free(ssao.importance_map_shader_version);
+
+ RD::get_singleton()->free(ssao.importance_map_load_counter);
+ }
+
+ singleton = nullptr;
+}
+
+/* SS Downsampler */
+
+void SSEffects::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ // Downsample and deinterleave the depth buffer for SSAO and SSIL
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ int downsample_mode = SS_EFFECTS_DOWNSAMPLE;
+ bool use_mips = p_ssao_quality > RS::ENV_SSAO_QUALITY_MEDIUM || p_ssil_quality > RS::ENV_SSIL_QUALITY_MEDIUM;
+
+ if (p_ssao_quality == RS::ENV_SSAO_QUALITY_VERY_LOW && p_ssil_quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ downsample_mode = SS_EFFECTS_DOWNSAMPLE_HALF;
+ } else if (use_mips) {
+ downsample_mode = SS_EFFECTS_DOWNSAMPLE_MIPMAP;
+ }
+
+ bool use_half_size = false;
+ bool use_full_mips = false;
+
+ if (p_ssao_half_size && p_ssil_half_size) {
+ downsample_mode++;
+ use_half_size = true;
+ } else if (p_ssao_half_size != p_ssil_half_size) {
+ if (use_mips) {
+ downsample_mode = SS_EFFECTS_DOWNSAMPLE_FULL_MIPS;
+ use_full_mips = true;
+ } else {
+ // Only need the first two mipmaps, but the cost to generate the next two is trivial
+ // TODO investigate the benefit of a shader version to generate only 2 mips
+ downsample_mode = SS_EFFECTS_DOWNSAMPLE_MIPMAP;
+ use_mips = true;
+ }
+ }
+
+ int depth_index = use_half_size ? 1 : 0;
+
+ RD::get_singleton()->draw_command_begin_label("Downsample Depth");
+ if (p_invalidate_uniform_set || use_full_mips != ss_effects.used_full_mips_last_frame || use_half_size != ss_effects.used_half_size_last_frame || use_mips != ss_effects.used_mips_last_frame) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.append_id(p_depth_mipmaps[depth_index + 1]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.append_id(p_depth_mipmaps[depth_index + 2]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.append_id(p_depth_mipmaps[depth_index + 3]);
+ uniforms.push_back(u);
+ }
+ if (use_full_mips) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 3;
+ u.append_id(p_depth_mipmaps[4]);
+ uniforms.push_back(u);
+ }
+ ss_effects.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, use_full_mips ? 6 : 2), 2);
+ }
+
+ float depth_linearize_mul = -p_projection.matrix[3][2];
+ float depth_linearize_add = p_projection.matrix[2][2];
+ if (depth_linearize_mul * depth_linearize_add < 0) {
+ depth_linearize_add = -depth_linearize_add;
+ }
+
+ ss_effects.downsample_push_constant.orthogonal = p_projection.is_orthogonal();
+ ss_effects.downsample_push_constant.z_near = depth_linearize_mul;
+ ss_effects.downsample_push_constant.z_far = depth_linearize_add;
+ if (ss_effects.downsample_push_constant.orthogonal) {
+ ss_effects.downsample_push_constant.z_near = p_projection.get_z_near();
+ ss_effects.downsample_push_constant.z_far = p_projection.get_z_far();
+ }
+ ss_effects.downsample_push_constant.pixel_size[0] = 1.0 / p_full_screen_size.x;
+ ss_effects.downsample_push_constant.pixel_size[1] = 1.0 / p_full_screen_size.y;
+ ss_effects.downsample_push_constant.radius_sq = 1.0;
+
+ RID shader = ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, downsample_mode);
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_depth_buffer(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_depth_buffer }));
+ RD::Uniform u_depth_mipmaps(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_depth_mipmaps[depth_index + 0] }));
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ss_effects.pipelines[downsample_mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_depth_buffer), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_depth_mipmaps), 1);
+ if (use_mips) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ss_effects.downsample_uniform_set, 2);
+ }
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ss_effects.downsample_push_constant, sizeof(SSEffectsDownsamplePushConstant));
+
+ Size2i size(MAX(1, p_full_screen_size.x >> (use_half_size ? 2 : 1)), MAX(1, p_full_screen_size.y >> (use_half_size ? 2 : 1)));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->draw_command_end_label();
+
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE);
+
+ ss_effects.used_full_mips_last_frame = use_full_mips;
+ ss_effects.used_half_size_last_frame = use_half_size;
+}
+
+/* SSIL */
+
+void SSEffects::gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0);
+ if ((p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) && !p_adaptive_base_pass) {
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 1);
+ }
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_projection_uniform_set, 3);
+
+ RID shader = ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0);
+
+ for (int i = 0; i < 4; i++) {
+ if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
+ continue;
+ }
+
+ RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_slices[i] }));
+ RD::Uniform u_edges_slice(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_edges_slices[i] }));
+
+ ssil.gather_push_constant.pass_coord_offset[0] = i % 2;
+ ssil.gather_push_constant.pass_coord_offset[1] = i / 2;
+ ssil.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x;
+ ssil.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y;
+ ssil.gather_push_constant.pass = i;
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, uniform_set_cache->get_cache(shader, 2, u_ssil_slice, u_edges_slice), 2);
+ RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssil.gather_push_constant, sizeof(SSILGatherPushConstant));
+
+ Size2i size = Size2i(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
+
+ RD::get_singleton()->compute_list_dispatch_threads(p_compute_list, size.x, size.y, 1);
+ }
+ RD::get_singleton()->compute_list_add_barrier(p_compute_list);
+}
+
+void SSEffects::ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings, RID p_linear_depth) {
+ if (p_ssil_buffers.half_size != p_settings.half_size) {
+ ssil_free(p_ssil_buffers);
+ }
+
+ if (p_settings.half_size) {
+ p_ssil_buffers.buffer_width = (p_settings.full_screen_size.x + 3) / 4;
+ p_ssil_buffers.buffer_height = (p_settings.full_screen_size.y + 3) / 4;
+ p_ssil_buffers.half_buffer_width = (p_settings.full_screen_size.x + 7) / 8;
+ p_ssil_buffers.half_buffer_height = (p_settings.full_screen_size.y + 7) / 8;
+ } else {
+ p_ssil_buffers.buffer_width = (p_settings.full_screen_size.x + 1) / 2;
+ p_ssil_buffers.buffer_height = (p_settings.full_screen_size.y + 1) / 2;
+ p_ssil_buffers.half_buffer_width = (p_settings.full_screen_size.x + 3) / 4;
+ p_ssil_buffers.half_buffer_height = (p_settings.full_screen_size.y + 3) / 4;
+ }
+
+ if (p_ssil_buffers.ssil_final.is_null()) {
+ {
+ p_ssil_buffers.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_linear_depth, 0, p_settings.half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY);
+ }
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.width = p_settings.full_screen_size.x;
+ tf.height = p_settings.full_screen_size.y;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ p_ssil_buffers.ssil_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssil_buffers.ssil_final, "SSIL texture");
+ RD::get_singleton()->texture_clear(p_ssil_buffers.ssil_final, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ if (p_ssil_buffers.last_frame.is_null()) {
+ tf.mipmaps = 6;
+ p_ssil_buffers.last_frame = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssil_buffers.last_frame, "Last Frame Radiance");
+ RD::get_singleton()->texture_clear(p_ssil_buffers.last_frame, Color(0, 0, 0, 0), 0, tf.mipmaps, 0, 1);
+ for (uint32_t i = 0; i < 6; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.last_frame, 0, i);
+ p_ssil_buffers.last_frame_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "Last Frame Radiance Mip " + itos(i) + " ");
+ }
+ }
+ }
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = p_ssil_buffers.buffer_width;
+ tf.height = p_ssil_buffers.buffer_height;
+ tf.array_layers = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ p_ssil_buffers.deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssil_buffers.deinterleaved, "SSIL deinterleaved buffer");
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.deinterleaved, i, 0);
+ p_ssil_buffers.deinterleaved_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer array " + itos(i) + " ");
+ }
+ }
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = p_ssil_buffers.buffer_width;
+ tf.height = p_ssil_buffers.buffer_height;
+ tf.array_layers = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ p_ssil_buffers.pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssil_buffers.pong, "SSIL deinterleaved pong buffer");
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.pong, i, 0);
+ p_ssil_buffers.pong_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer pong array " + itos(i) + " ");
+ }
+ }
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = p_ssil_buffers.buffer_width;
+ tf.height = p_ssil_buffers.buffer_height;
+ tf.array_layers = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ p_ssil_buffers.edges = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssil_buffers.edges, "SSIL edges buffer");
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.edges, i, 0);
+ p_ssil_buffers.edges_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSIL edges buffer slice " + itos(i) + " ");
+ }
+ }
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.width = p_ssil_buffers.half_buffer_width;
+ tf.height = p_ssil_buffers.half_buffer_height;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ p_ssil_buffers.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssil_buffers.importance_map[0], "SSIL Importance Map");
+ p_ssil_buffers.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssil_buffers.importance_map[1], "SSIL Importance Map Pong");
+ }
+ p_ssil_buffers.half_size = p_settings.half_size;
+ }
+}
+
+void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ RD::get_singleton()->draw_command_begin_label("Process Screen Space Indirect Lighting");
+ //Store projection info before starting the compute list
+ SSILProjectionUniforms projection_uniforms;
+ store_camera(p_last_projection, projection_uniforms.inv_last_frame_projection_matrix);
+
+ RD::get_singleton()->buffer_update(ssil.projection_uniform_buffer, 0, sizeof(SSILProjectionUniforms), &projection_uniforms);
+
+ memset(&ssil.gather_push_constant, 0, sizeof(SSILGatherPushConstant));
+
+ RID shader = ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0);
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ {
+ RD::get_singleton()->draw_command_begin_label("Gather Samples");
+ ssil.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x;
+ ssil.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y;
+
+ ssil.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width;
+ ssil.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height;
+ float tan_half_fov_x = 1.0 / p_projection.matrix[0][0];
+ float tan_half_fov_y = 1.0 / p_projection.matrix[1][1];
+ ssil.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
+ ssil.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0;
+ ssil.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0;
+ ssil.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y;
+ ssil.gather_push_constant.z_near = p_projection.get_z_near();
+ ssil.gather_push_constant.z_far = p_projection.get_z_far();
+ ssil.gather_push_constant.is_orthogonal = p_projection.is_orthogonal();
+
+ ssil.gather_push_constant.half_screen_pixel_size_x025[0] = ssil.gather_push_constant.half_screen_pixel_size[0] * 0.25;
+ ssil.gather_push_constant.half_screen_pixel_size_x025[1] = ssil.gather_push_constant.half_screen_pixel_size[1] * 0.25;
+
+ ssil.gather_push_constant.radius = p_settings.radius;
+ float radius_near_limit = (p_settings.radius * 1.2f);
+ if (p_settings.quality <= RS::ENV_SSIL_QUALITY_LOW) {
+ radius_near_limit *= 1.50f;
+
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ ssil.gather_push_constant.radius *= 0.8f;
+ }
+ }
+ radius_near_limit /= tan_half_fov_y;
+ ssil.gather_push_constant.intensity = p_settings.intensity * Math_PI;
+ ssil.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from);
+ ssil.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0;
+ ssil.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit;
+ ssil.gather_push_constant.neg_inv_radius = -1.0 / ssil.gather_push_constant.radius;
+ ssil.gather_push_constant.normal_rejection_amount = p_settings.normal_rejection;
+
+ ssil.gather_push_constant.load_counter_avg_div = 9.0 / float((p_ssil_buffers.half_buffer_width) * (p_ssil_buffers.half_buffer_height) * 255);
+ ssil.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target;
+
+ ssil.gather_push_constant.quality = MAX(0, p_settings.quality - 1);
+ ssil.gather_push_constant.size_multiplier = p_settings.half_size ? 2 : 1;
+
+ if (p_ssil_buffers.projection_uniform_set.is_null()) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 0;
+ u.append_id(default_mipmap_sampler);
+ u.append_id(p_ssil_buffers.last_frame);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 1;
+ u.append_id(ssil.projection_uniform_buffer);
+ uniforms.push_back(u);
+ }
+ p_ssil_buffers.projection_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 3);
+ }
+
+ if (p_ssil_buffers.gather_uniform_set.is_null()) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 0;
+ u.append_id(default_sampler);
+ u.append_id(p_ssil_buffers.depth_texture_view);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.append_id(p_normal_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 2;
+ u.append_id(ss_effects.gather_constants_buffer);
+ uniforms.push_back(u);
+ }
+ p_ssil_buffers.gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 0);
+ }
+
+ if (p_ssil_buffers.importance_map_uniform_set.is_null()) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.append_id(p_ssil_buffers.pong);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 1;
+ u.append_id(default_sampler);
+ u.append_id(p_ssil_buffers.importance_map[0]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.append_id(ssil.importance_map_load_counter);
+ uniforms.push_back(u);
+ }
+ p_ssil_buffers.importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 2), 1);
+ }
+
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) {
+ RD::get_singleton()->draw_command_begin_label("Generate Importance Map");
+ ssil.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width;
+ ssil.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height;
+ ssil.importance_map_push_constant.intensity = p_settings.intensity * Math_PI;
+ //base pass
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_BASE]);
+ gather_ssil(compute_list, p_ssil_buffers.pong_slices, p_ssil_buffers.edges_slices, p_settings, true, p_ssil_buffers.gather_uniform_set, p_ssil_buffers.importance_map_uniform_set, p_ssil_buffers.projection_uniform_set);
+
+ //generate importance map
+ RD::Uniform u_ssil_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.pong }));
+ RD::Uniform u_importance_map(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.importance_map[0] }));
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GENERATE_IMPORTANCE_MAP]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_pong_with_sampler), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ // process Importance Map A
+ RD::Uniform u_importance_map_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.importance_map[0] }));
+ RD::Uniform u_importance_map_pong(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.importance_map[1] }));
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPA]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_with_sampler), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map_pong), 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ // process Importance Map B
+ RD::Uniform u_importance_map_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.importance_map[1] }));
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPB]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_pong_with_sampler), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssil.counter_uniform_set, 2);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ RD::get_singleton()->draw_command_end_label(); // Importance Map
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_ADAPTIVE]);
+ } else {
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER]);
+ }
+
+ gather_ssil(compute_list, p_ssil_buffers.deinterleaved_slices, p_ssil_buffers.edges_slices, p_settings, false, p_ssil_buffers.gather_uniform_set, p_ssil_buffers.importance_map_uniform_set, p_ssil_buffers.projection_uniform_set);
+ RD::get_singleton()->draw_command_end_label(); //Gather
+ }
+
+ {
+ RD::get_singleton()->draw_command_begin_label("Edge Aware Blur");
+ ssil.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness;
+ ssil.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width;
+ ssil.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height;
+
+ int blur_passes = p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW ? p_settings.blur_passes : 1;
+
+ shader = ssil.blur_shader.version_get_shader(ssil.blur_shader_version, 0);
+
+ for (int pass = 0; pass < blur_passes; pass++) {
+ int blur_pipeline = SSIL_BLUR_PASS;
+ if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ blur_pipeline = SSIL_BLUR_PASS_SMART;
+ if (pass < blur_passes - 2) {
+ blur_pipeline = SSIL_BLUR_PASS_WIDE;
+ }
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
+ continue;
+ }
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[blur_pipeline]);
+ if (pass % 2 == 0) {
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_slice), 0);
+ } else {
+ RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssil_buffers.deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_slice), 0);
+ }
+
+ RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil_pong_slice), 1);
+ } else {
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_pong_slice), 0);
+ } else {
+ RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssil_buffers.pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_pong_slice), 0);
+ }
+
+ RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil_slice), 1);
+ }
+
+ RD::Uniform u_edges_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.edges_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_edges_slice), 2);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.blur_push_constant, sizeof(SSILBlurPushConstant));
+
+ int x_groups = (p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1));
+ int y_groups = (p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, x_groups, y_groups, 1);
+ if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ }
+ }
+ }
+
+ RD::get_singleton()->draw_command_end_label(); // Blur
+ }
+
+ {
+ RD::get_singleton()->draw_command_begin_label("Interleave Buffers");
+ ssil.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness;
+ ssil.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x;
+ ssil.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y;
+ ssil.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2);
+
+ int interleave_pipeline = SSIL_INTERLEAVE_HALF;
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_LOW) {
+ interleave_pipeline = SSIL_INTERLEAVE;
+ } else if (p_settings.quality >= RS::ENV_SSIL_QUALITY_MEDIUM) {
+ interleave_pipeline = SSIL_INTERLEAVE_SMART;
+ }
+
+ shader = ssil.interleave_shader.version_get_shader(ssil.interleave_shader_version, 0);
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[interleave_pipeline]);
+
+ RD::Uniform u_destination(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.ssil_final }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_destination), 0);
+
+ if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW && p_settings.blur_passes % 2 == 0) {
+ RD::Uniform u_ssil(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.deinterleaved }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil), 1);
+ } else {
+ RD::Uniform u_ssil_pong(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.pong }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil_pong), 1);
+ }
+
+ RD::Uniform u_edges(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.edges }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_edges), 2);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.interleave_push_constant, sizeof(SSILInterleavePushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.full_screen_size.x, p_settings.full_screen_size.y, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->draw_command_end_label(); // Interleave
+ }
+
+ RD::get_singleton()->draw_command_end_label(); // SSIL
+
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER);
+
+ int zero[1] = { 0 };
+ RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
+}
+
+void SSEffects::ssil_free(SSILRenderBuffers &p_ssil_buffers) {
+ if (p_ssil_buffers.ssil_final.is_valid()) {
+ RD::get_singleton()->free(p_ssil_buffers.ssil_final);
+ RD::get_singleton()->free(p_ssil_buffers.deinterleaved);
+ RD::get_singleton()->free(p_ssil_buffers.pong);
+ RD::get_singleton()->free(p_ssil_buffers.edges);
+ RD::get_singleton()->free(p_ssil_buffers.importance_map[0]);
+ RD::get_singleton()->free(p_ssil_buffers.importance_map[1]);
+ RD::get_singleton()->free(p_ssil_buffers.last_frame);
+
+ p_ssil_buffers.ssil_final = RID();
+ p_ssil_buffers.deinterleaved = RID();
+ p_ssil_buffers.pong = RID();
+ p_ssil_buffers.edges = RID();
+ p_ssil_buffers.deinterleaved_slices.clear();
+ p_ssil_buffers.pong_slices.clear();
+ p_ssil_buffers.edges_slices.clear();
+ p_ssil_buffers.importance_map[0] = RID();
+ p_ssil_buffers.importance_map[1] = RID();
+ p_ssil_buffers.last_frame = RID();
+ p_ssil_buffers.last_frame_slices.clear();
+
+ p_ssil_buffers.gather_uniform_set = RID();
+ p_ssil_buffers.importance_map_uniform_set = RID();
+ p_ssil_buffers.projection_uniform_set = RID();
+ }
+}
+
+/* SSAO */
+
+void SSEffects::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0);
+ if ((p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) && !p_adaptive_base_pass) {
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 0);
+ }
+
+ RID shader = ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 1); //
+
+ for (int i = 0; i < 4; i++) {
+ if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
+ continue;
+ }
+
+ RD::Uniform u_ao_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ao_slices[i] }));
+
+ ssao.gather_push_constant.pass_coord_offset[0] = i % 2;
+ ssao.gather_push_constant.pass_coord_offset[1] = i / 2;
+ ssao.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x;
+ ssao.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y;
+ ssao.gather_push_constant.pass = i;
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, uniform_set_cache->get_cache(shader, 2, u_ao_slice), 2);
+ RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssao.gather_push_constant, sizeof(SSAOGatherPushConstant));
+
+ Size2i size = Size2i(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
+
+ RD::get_singleton()->compute_list_dispatch_threads(p_compute_list, size.x, size.y, 1);
+ }
+ RD::get_singleton()->compute_list_add_barrier(p_compute_list);
+}
+
+void SSEffects::ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings, RID p_linear_depth) {
+ if (p_ssao_buffers.half_size != p_settings.half_size) {
+ ssao_free(p_ssao_buffers);
+ }
+
+ if (p_settings.half_size) {
+ p_ssao_buffers.buffer_width = (p_settings.full_screen_size.x + 3) / 4;
+ p_ssao_buffers.buffer_height = (p_settings.full_screen_size.y + 3) / 4;
+ p_ssao_buffers.half_buffer_width = (p_settings.full_screen_size.x + 7) / 8;
+ p_ssao_buffers.half_buffer_height = (p_settings.full_screen_size.y + 7) / 8;
+ } else {
+ p_ssao_buffers.buffer_width = (p_settings.full_screen_size.x + 1) / 2;
+ p_ssao_buffers.buffer_height = (p_settings.full_screen_size.y + 1) / 2;
+ p_ssao_buffers.half_buffer_width = (p_settings.full_screen_size.x + 3) / 4;
+ p_ssao_buffers.half_buffer_height = (p_settings.full_screen_size.y + 3) / 4;
+ }
+
+ if (p_ssao_buffers.ao_deinterleaved.is_null()) {
+ {
+ p_ssao_buffers.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_linear_depth, 0, p_settings.half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY);
+ }
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8G8_UNORM;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = p_ssao_buffers.buffer_width;
+ tf.height = p_ssao_buffers.buffer_height;
+ tf.array_layers = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ p_ssao_buffers.ao_deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssao_buffers.ao_deinterleaved, "SSAO De-interleaved Array");
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssao_buffers.ao_deinterleaved, i, 0);
+ p_ssao_buffers.ao_deinterleaved_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " ");
+ }
+ }
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8G8_UNORM;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = p_ssao_buffers.buffer_width;
+ tf.height = p_ssao_buffers.buffer_height;
+ tf.array_layers = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ p_ssao_buffers.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssao_buffers.ao_pong, "SSAO De-interleaved Array Pong");
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssao_buffers.ao_pong, i, 0);
+ p_ssao_buffers.ao_pong_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " Pong");
+ }
+ }
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.width = p_ssao_buffers.buffer_width;
+ tf.height = p_ssao_buffers.buffer_height;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ p_ssao_buffers.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssao_buffers.importance_map[0], "SSAO Importance Map");
+ p_ssao_buffers.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssao_buffers.importance_map[1], "SSAO Importance Map Pong");
+ }
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.width = p_settings.full_screen_size.x;
+ tf.height = p_settings.full_screen_size.y;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ p_ssao_buffers.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssao_buffers.ao_final, "SSAO Final");
+ }
+ p_ssao_buffers.half_size = p_settings.half_size;
+ }
+}
+
+void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const CameraMatrix &p_projection, const SSAOSettings &p_settings) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ memset(&ssao.gather_push_constant, 0, sizeof(SSAOGatherPushConstant));
+ /* FIRST PASS */
+
+ RID shader = ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0);
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::get_singleton()->draw_command_begin_label("Process Screen Space Ambient Occlusion");
+ /* SECOND PASS */
+ // Sample SSAO
+ {
+ RD::get_singleton()->draw_command_begin_label("Gather Samples");
+ ssao.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x;
+ ssao.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y;
+
+ ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssao_buffers.buffer_width;
+ ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssao_buffers.buffer_height;
+ float tan_half_fov_x = 1.0 / p_projection.matrix[0][0];
+ float tan_half_fov_y = 1.0 / p_projection.matrix[1][1];
+ ssao.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
+ ssao.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0;
+ ssao.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0;
+ ssao.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y;
+ ssao.gather_push_constant.is_orthogonal = p_projection.is_orthogonal();
+
+ ssao.gather_push_constant.half_screen_pixel_size_x025[0] = ssao.gather_push_constant.half_screen_pixel_size[0] * 0.25;
+ ssao.gather_push_constant.half_screen_pixel_size_x025[1] = ssao.gather_push_constant.half_screen_pixel_size[1] * 0.25;
+
+ ssao.gather_push_constant.radius = p_settings.radius;
+ float radius_near_limit = (p_settings.radius * 1.2f);
+ if (p_settings.quality <= RS::ENV_SSAO_QUALITY_LOW) {
+ radius_near_limit *= 1.50f;
+
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ ssao.gather_push_constant.radius *= 0.8f;
+ }
+ }
+ radius_near_limit /= tan_half_fov_y;
+ ssao.gather_push_constant.intensity = p_settings.intensity;
+ ssao.gather_push_constant.shadow_power = p_settings.power;
+ ssao.gather_push_constant.shadow_clamp = 0.98;
+ ssao.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from);
+ ssao.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0;
+ ssao.gather_push_constant.horizon_angle_threshold = p_settings.horizon;
+ ssao.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit;
+ ssao.gather_push_constant.neg_inv_radius = -1.0 / ssao.gather_push_constant.radius;
+
+ ssao.gather_push_constant.load_counter_avg_div = 9.0 / float((p_ssao_buffers.half_buffer_width) * (p_ssao_buffers.half_buffer_height) * 255);
+ ssao.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target;
+
+ ssao.gather_push_constant.detail_intensity = p_settings.detail;
+ ssao.gather_push_constant.quality = MAX(0, p_settings.quality - 1);
+ ssao.gather_push_constant.size_multiplier = p_settings.half_size ? 2 : 1;
+
+ if (p_ssao_buffers.gather_uniform_set.is_null()) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 0;
+ u.append_id(default_sampler);
+ u.append_id(p_ssao_buffers.depth_texture_view);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.append_id(p_normal_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 2;
+ u.append_id(ss_effects.gather_constants_buffer);
+ uniforms.push_back(u);
+ }
+ p_ssao_buffers.gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader, 0);
+ RD::get_singleton()->set_resource_name(p_ssao_buffers.gather_uniform_set, "SSAO Gather Uniform Set");
+ }
+
+ if (p_ssao_buffers.importance_map_uniform_set.is_null()) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.append_id(p_ssao_buffers.ao_pong);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 1;
+ u.append_id(default_sampler);
+ u.append_id(p_ssao_buffers.importance_map[0]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.append_id(ssao.importance_map_load_counter);
+ uniforms.push_back(u);
+ }
+ p_ssao_buffers.importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 2), 1);
+ RD::get_singleton()->set_resource_name(p_ssao_buffers.importance_map_uniform_set, "SSAO Importance Map Uniform Set");
+ }
+
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) {
+ RD::get_singleton()->draw_command_begin_label("Generate Importance Map");
+ ssao.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssao_buffers.buffer_width;
+ ssao.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssao_buffers.buffer_height;
+ ssao.importance_map_push_constant.intensity = p_settings.intensity;
+ ssao.importance_map_push_constant.power = p_settings.power;
+
+ //base pass
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_BASE]);
+ gather_ssao(compute_list, p_ssao_buffers.ao_pong_slices, p_settings, true, p_ssao_buffers.gather_uniform_set, RID());
+
+ //generate importance map
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GENERATE_IMPORTANCE_MAP]);
+
+ RD::Uniform u_ao_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_pong }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_pong_with_sampler), 0);
+
+ RD::Uniform u_importance_map(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.importance_map[0] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ //process importance map A
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPA]);
+
+ RD::Uniform u_importance_map_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.importance_map[0] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_with_sampler), 0);
+
+ RD::Uniform u_importance_map_pong(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.importance_map[1] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map_pong), 1);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ //process Importance Map B
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPB]);
+
+ RD::Uniform u_importance_map_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.importance_map[1] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_pong_with_sampler), 0);
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.counter_uniform_set, 2);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_ADAPTIVE]);
+ RD::get_singleton()->draw_command_end_label(); // Importance Map
+ } else {
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER]);
+ }
+
+ gather_ssao(compute_list, p_ssao_buffers.ao_deinterleaved_slices, p_settings, false, p_ssao_buffers.gather_uniform_set, p_ssao_buffers.importance_map_uniform_set);
+ RD::get_singleton()->draw_command_end_label(); // Gather SSAO
+ }
+
+ // /* THIRD PASS */
+ // // Blur
+ //
+ {
+ RD::get_singleton()->draw_command_begin_label("Edge Aware Blur");
+ ssao.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness;
+ ssao.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssao_buffers.buffer_width;
+ ssao.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssao_buffers.buffer_height;
+
+ int blur_passes = p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW ? p_settings.blur_passes : 1;
+
+ shader = ssao.blur_shader.version_get_shader(ssao.blur_shader_version, 0);
+
+ for (int pass = 0; pass < blur_passes; pass++) {
+ int blur_pipeline = SSAO_BLUR_PASS;
+ if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ blur_pipeline = SSAO_BLUR_PASS_SMART;
+ if (pass < blur_passes - 2) {
+ blur_pipeline = SSAO_BLUR_PASS_WIDE;
+ } else {
+ blur_pipeline = SSAO_BLUR_PASS_SMART;
+ }
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
+ continue;
+ }
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[blur_pipeline]);
+ if (pass % 2 == 0) {
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ RD::Uniform u_ao_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_slices_with_sampler), 0);
+ } else {
+ RD::Uniform u_ao_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssao_buffers.ao_deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_slices_with_sampler), 0);
+ }
+
+ RD::Uniform u_ao_pong_slices(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.ao_pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao_pong_slices), 1);
+ } else {
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ RD::Uniform u_ao_pong_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_pong_slices_with_sampler), 0);
+ } else {
+ RD::Uniform u_ao_pong_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssao_buffers.ao_pong_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_pong_slices_with_sampler), 0);
+ }
+
+ RD::Uniform u_ao_slices(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.ao_deinterleaved_slices[i] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao_slices), 1);
+ }
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant));
+
+ Size2i size(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
+ }
+
+ if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ }
+ }
+ RD::get_singleton()->draw_command_end_label(); // Blur
+ }
+
+ /* FOURTH PASS */
+ // Interleave buffers
+ // back to full size
+ {
+ RD::get_singleton()->draw_command_begin_label("Interleave Buffers");
+ ssao.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness;
+ ssao.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x;
+ ssao.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y;
+ ssao.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2);
+
+ shader = ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, 0);
+
+ int interleave_pipeline = SSAO_INTERLEAVE_HALF;
+ if (p_settings.quality == RS::ENV_SSAO_QUALITY_LOW) {
+ interleave_pipeline = SSAO_INTERLEAVE;
+ } else if (p_settings.quality >= RS::ENV_SSAO_QUALITY_MEDIUM) {
+ interleave_pipeline = SSAO_INTERLEAVE_SMART;
+ }
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[interleave_pipeline]);
+
+ RD::Uniform u_upscale_buffer(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.ao_final }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_upscale_buffer), 0);
+
+ if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW && p_settings.blur_passes % 2 == 0) {
+ RD::Uniform u_ao(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_deinterleaved }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao), 1);
+ } else {
+ RD::Uniform u_ao(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_pong }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao), 1);
+ }
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.interleave_push_constant, sizeof(SSAOInterleavePushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.full_screen_size.x, p_settings.full_screen_size.y, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->draw_command_end_label(); // Interleave
+ }
+ RD::get_singleton()->draw_command_end_label(); //SSAO
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //wait for upcoming transfer
+
+ int zero[1] = { 0 };
+ RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
+}
+
+void SSEffects::ssao_free(SSAORenderBuffers &p_ssao_buffers) {
+ if (p_ssao_buffers.ao_final.is_valid()) {
+ RD::get_singleton()->free(p_ssao_buffers.ao_deinterleaved);
+ RD::get_singleton()->free(p_ssao_buffers.ao_pong);
+ RD::get_singleton()->free(p_ssao_buffers.ao_final);
+
+ RD::get_singleton()->free(p_ssao_buffers.importance_map[0]);
+ RD::get_singleton()->free(p_ssao_buffers.importance_map[1]);
+
+ p_ssao_buffers.ao_deinterleaved = RID();
+ p_ssao_buffers.ao_pong = RID();
+ p_ssao_buffers.ao_final = RID();
+ p_ssao_buffers.importance_map[0] = RID();
+ p_ssao_buffers.importance_map[1] = RID();
+ p_ssao_buffers.ao_deinterleaved_slices.clear();
+ p_ssao_buffers.ao_pong_slices.clear();
+
+ p_ssao_buffers.gather_uniform_set = RID();
+ p_ssao_buffers.importance_map_uniform_set = RID();
+ }
+}
+
+/* Screen Space Reflection */
+
+void SSEffects::ssr_allocate_buffers(SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, const Size2i &p_screen_size, const uint32_t p_view_count) {
+ // As we are processing one view at a time, we can reuse buffers, only our output needs to have layers for each view.
+
+ if (p_ssr_buffers.depth_scaled.is_null()) {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R32_SFLOAT;
+ tf.width = p_screen_size.x;
+ tf.height = p_screen_size.y;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = 1;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
+
+ p_ssr_buffers.depth_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssr_buffers.depth_scaled, "SSR Depth Scaled");
+
+ tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+
+ p_ssr_buffers.normal_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssr_buffers.normal_scaled, "SSR Normal Scaled");
+ }
+
+ if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED && !p_ssr_buffers.blur_radius[0].is_valid()) {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.width = p_screen_size.x;
+ tf.height = p_screen_size.y;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = 1;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
+
+ p_ssr_buffers.blur_radius[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssr_buffers.blur_radius[0], "SSR Blur Radius 0");
+ p_ssr_buffers.blur_radius[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssr_buffers.blur_radius[1], "SSR Blur Radius 1");
+ }
+
+ if (p_ssr_buffers.intermediate.is_null()) {
+ RD::TextureFormat tf;
+ tf.format = p_color_format;
+ tf.width = p_screen_size.x;
+ tf.height = p_screen_size.y;
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = 1;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+
+ p_ssr_buffers.intermediate = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssr_buffers.intermediate, "SSR Intermediate");
+
+ if (p_view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.array_layers = p_view_count;
+ } else {
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = 1;
+ }
+
+ p_ssr_buffers.output = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(p_ssr_buffers.output, "SSR Output");
+
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ p_ssr_buffers.output_slices[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssr_buffers.output, v, 0);
+ }
+ }
+}
+
+void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, const RID *p_metallic_slices, const Color &p_metallic_mask, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ {
+ // Store some scene data in a UBO, in the near future we will use a UBO shared with other shaders
+ ScreenSpaceReflectionSceneData scene_data;
+
+ if (ssr.ubo.is_null()) {
+ ssr.ubo = RD::get_singleton()->uniform_buffer_create(sizeof(ScreenSpaceReflectionSceneData));
+ }
+
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ store_camera(p_projections[v], scene_data.projection[v]);
+ store_camera(p_projections[v].inverse(), scene_data.inv_projection[v]);
+ scene_data.eye_offset[v][0] = p_eye_offsets[v].x;
+ scene_data.eye_offset[v][1] = p_eye_offsets[v].y;
+ scene_data.eye_offset[v][2] = p_eye_offsets[v].z;
+ scene_data.eye_offset[v][3] = 0.0;
+ }
+
+ RD::get_singleton()->buffer_update(ssr.ubo, 0, sizeof(ScreenSpaceReflectionSceneData), &scene_data, RD::BARRIER_MASK_COMPUTE);
+ }
+
+ uint32_t pipeline_specialization = 0;
+ if (p_view_count > 1) {
+ pipeline_specialization |= SSR_MULTIVIEW;
+ }
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ RD::get_singleton()->draw_command_begin_label(String("SSR View ") + itos(v));
+
+ { //scale color and depth to half
+ RD::get_singleton()->draw_command_begin_label("SSR Scale");
+
+ ScreenSpaceReflectionScalePushConstant push_constant;
+ push_constant.view_index = v;
+ push_constant.camera_z_far = p_projections[v].get_z_far();
+ push_constant.camera_z_near = p_projections[v].get_z_near();
+ push_constant.orthogonal = p_projections[v].is_orthogonal();
+ push_constant.filter = false; //enabling causes arctifacts
+ push_constant.screen_size[0] = p_screen_size.x;
+ push_constant.screen_size[1] = p_screen_size.y;
+
+ RID shader = ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0);
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_scale.pipelines[pipeline_specialization]);
+
+ RD::Uniform u_diffuse(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_diffuse_slices[v] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_diffuse), 0);
+
+ RD::Uniform u_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_depth_slices[v] }));
+ RD::Uniform u_normal_roughness(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 1, Vector<RID>({ default_sampler, p_normal_roughness_slices[v] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_depth, u_normal_roughness), 1);
+
+ RD::Uniform u_output_blur(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_output_blur), 2);
+
+ RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.depth_scaled }));
+ RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.normal_scaled }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_scale_depth, u_scale_normal), 3);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionScalePushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
+
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ RD::get_singleton()->draw_command_end_label();
+ }
+
+ {
+ RD::get_singleton()->draw_command_begin_label("SSR main");
+
+ ScreenSpaceReflectionPushConstant push_constant;
+ push_constant.view_index = v;
+ push_constant.camera_z_far = p_projections[v].get_z_far();
+ push_constant.camera_z_near = p_projections[v].get_z_near();
+ push_constant.orthogonal = p_projections[v].is_orthogonal();
+ push_constant.screen_size[0] = p_screen_size.x;
+ push_constant.screen_size[1] = p_screen_size.y;
+ push_constant.curve_fade_in = p_fade_in;
+ push_constant.distance_fade = p_fade_out;
+ push_constant.num_steps = p_max_steps;
+ push_constant.depth_tolerance = p_tolerance;
+ push_constant.use_half_res = true;
+ push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].matrix[0][0]);
+ push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].matrix[1][1]);
+ push_constant.proj_info[2] = (1.0f - p_projections[v].matrix[0][2]) / p_projections[v].matrix[0][0];
+ push_constant.proj_info[3] = (1.0f + p_projections[v].matrix[1][2]) / p_projections[v].matrix[1][1];
+ push_constant.metallic_mask[0] = CLAMP(p_metallic_mask.r * 255.0, 0, 255);
+ push_constant.metallic_mask[1] = CLAMP(p_metallic_mask.g * 255.0, 0, 255);
+ push_constant.metallic_mask[2] = CLAMP(p_metallic_mask.b * 255.0, 0, 255);
+ push_constant.metallic_mask[3] = CLAMP(p_metallic_mask.a * 255.0, 0, 255);
+
+ ScreenSpaceReflectionMode mode = (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL;
+ RID shader = ssr.shader.version_get_shader(ssr.shader_version, mode);
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[pipeline_specialization][mode]);
+
+ RD::Uniform u_scene_data(RD::UNIFORM_TYPE_UNIFORM_BUFFER, 0, ssr.ubo);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4);
+
+ RD::Uniform u_output_blur(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] }));
+ RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.depth_scaled }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_output_blur, u_scale_depth), 0);
+
+ if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) {
+ RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate }));
+ RD::Uniform u_blur_radius(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.blur_radius[0] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_intermediate, u_blur_radius), 1);
+ } else {
+ RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_intermediate), 1);
+ }
+
+ RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.normal_scaled }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_scale_normal), 2);
+
+ RD::Uniform u_metallic(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_metallic_slices[v] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_metallic), 3);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
+
+ RD::get_singleton()->draw_command_end_label();
+ }
+
+ if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) {
+ RD::get_singleton()->draw_command_begin_label("SSR filter");
+ //blur
+
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ ScreenSpaceReflectionFilterPushConstant push_constant;
+ push_constant.view_index = v;
+ push_constant.orthogonal = p_projections[v].is_orthogonal();
+ push_constant.edge_tolerance = Math::sin(Math::deg2rad(15.0));
+ push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].matrix[0][0]);
+ push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].matrix[1][1]);
+ push_constant.proj_info[2] = (1.0f - p_projections[v].matrix[0][2]) / p_projections[v].matrix[0][0];
+ push_constant.proj_info[3] = (1.0f + p_projections[v].matrix[1][2]) / p_projections[v].matrix[1][1];
+ push_constant.vertical = 0;
+ if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_LOW) {
+ push_constant.steps = p_max_steps / 3;
+ push_constant.increment = 3;
+ } else if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_MEDIUM) {
+ push_constant.steps = p_max_steps / 2;
+ push_constant.increment = 2;
+ } else {
+ push_constant.steps = p_max_steps;
+ push_constant.increment = 1;
+ }
+
+ push_constant.screen_size[0] = p_screen_size.width;
+ push_constant.screen_size[1] = p_screen_size.height;
+
+ // Horizontal pass
+
+ SSRReflectionMode mode = SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL;
+
+ RID shader = ssr_filter.shader.version_get_shader(ssr_filter.shader_version, mode);
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[pipeline_specialization][mode]);
+
+ RD::Uniform u_scene_data(RD::UNIFORM_TYPE_UNIFORM_BUFFER, 0, ssr.ubo);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4);
+
+ RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate }));
+ RD::Uniform u_blur_radius(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.blur_radius[0] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_intermediate, u_blur_radius), 0);
+
+ RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.normal_scaled }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_scale_normal), 1);
+
+ RD::Uniform u_output_blur(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] }));
+ RD::Uniform u_blur_radius2(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.blur_radius[1] }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_output_blur, u_blur_radius2), 2);
+
+ RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.depth_scaled }));
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_scale_depth), 3);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ // Vertical pass
+
+ mode = SCREEN_SPACE_REFLECTION_FILTER_VERTICAL;
+ shader = ssr_filter.shader.version_get_shader(ssr_filter.shader_version, mode);
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[pipeline_specialization][mode]);
+
+ push_constant.vertical = 1;
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_output_blur, u_blur_radius2), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_scale_normal), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_intermediate), 2);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_scale_depth), 3);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
+
+ if (v != p_view_count - 1) {
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ }
+
+ RD::get_singleton()->draw_command_end_label();
+ }
+
+ RD::get_singleton()->draw_command_end_label();
+ }
+
+ RD::get_singleton()->compute_list_end();
+}
+
+void SSEffects::ssr_free(SSRRenderBuffers &p_ssr_buffers) {
+ for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {
+ p_ssr_buffers.output_slices[v] = RID();
+ }
+
+ if (p_ssr_buffers.output.is_valid()) {
+ RD::get_singleton()->free(p_ssr_buffers.output);
+ p_ssr_buffers.output = RID();
+ }
+
+ if (p_ssr_buffers.intermediate.is_valid()) {
+ RD::get_singleton()->free(p_ssr_buffers.intermediate);
+ p_ssr_buffers.intermediate = RID();
+ }
+
+ if (p_ssr_buffers.blur_radius[0].is_valid()) {
+ RD::get_singleton()->free(p_ssr_buffers.blur_radius[0]);
+ RD::get_singleton()->free(p_ssr_buffers.blur_radius[1]);
+ p_ssr_buffers.blur_radius[0] = RID();
+ p_ssr_buffers.blur_radius[1] = RID();
+ }
+
+ if (p_ssr_buffers.depth_scaled.is_valid()) {
+ RD::get_singleton()->free(p_ssr_buffers.depth_scaled);
+ p_ssr_buffers.depth_scaled = RID();
+ RD::get_singleton()->free(p_ssr_buffers.normal_scaled);
+ p_ssr_buffers.normal_scaled = RID();
+ }
+}
diff --git a/servers/rendering/renderer_rd/effects/ss_effects.h b/servers/rendering/renderer_rd/effects/ss_effects.h
new file mode 100644
index 0000000000..38b127aba6
--- /dev/null
+++ b/servers/rendering/renderer_rd/effects/ss_effects.h
@@ -0,0 +1,508 @@
+/*************************************************************************/
+/* ss_effects.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SS_EFFECTS_RD_H
+#define SS_EFFECTS_RD_H
+
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
+#include "servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/ssao.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/ssil.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl.gen.h"
+#include "servers/rendering/renderer_scene_render.h"
+#include "servers/rendering_server.h"
+
+namespace RendererRD {
+
+class SSEffects {
+private:
+ static SSEffects *singleton;
+
+public:
+ static SSEffects *get_singleton() { return singleton; }
+
+ SSEffects();
+ ~SSEffects();
+
+ /* SS Downsampler */
+
+ void downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection);
+
+ /* SSIL */
+
+ struct SSILRenderBuffers {
+ bool half_size = false;
+ int buffer_width;
+ int buffer_height;
+ int half_buffer_width;
+ int half_buffer_height;
+
+ RID ssil_final;
+ RID deinterleaved;
+ Vector<RID> deinterleaved_slices;
+ RID pong;
+ Vector<RID> pong_slices;
+ RID edges;
+ Vector<RID> edges_slices;
+ RID importance_map[2];
+ RID depth_texture_view;
+
+ RID last_frame;
+ Vector<RID> last_frame_slices;
+
+ RID gather_uniform_set;
+ RID importance_map_uniform_set;
+ RID projection_uniform_set;
+ };
+
+ struct SSILSettings {
+ float radius = 1.0;
+ float intensity = 2.0;
+ float sharpness = 0.98;
+ float normal_rejection = 1.0;
+
+ RS::EnvironmentSSILQuality quality = RS::ENV_SSIL_QUALITY_MEDIUM;
+ bool half_size = true;
+ float adaptive_target = 0.5;
+ int blur_passes = 4;
+ float fadeout_from = 50.0;
+ float fadeout_to = 300.0;
+
+ Size2i full_screen_size = Size2i();
+ };
+
+ void ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings, RID p_linear_depth);
+ void screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings);
+ void ssil_free(SSILRenderBuffers &p_ssil_buffers);
+
+ /* SSAO */
+
+ struct SSAORenderBuffers {
+ bool half_size = false;
+ int buffer_width;
+ int buffer_height;
+ int half_buffer_width;
+ int half_buffer_height;
+
+ RID ao_deinterleaved;
+ Vector<RID> ao_deinterleaved_slices;
+ RID ao_pong;
+ Vector<RID> ao_pong_slices;
+ RID ao_final;
+ RID importance_map[2];
+ RID depth_texture_view;
+
+ RID gather_uniform_set;
+ RID importance_map_uniform_set;
+ };
+
+ struct SSAOSettings {
+ float radius = 1.0;
+ float intensity = 2.0;
+ float power = 1.5;
+ float detail = 0.5;
+ float horizon = 0.06;
+ float sharpness = 0.98;
+
+ RS::EnvironmentSSAOQuality quality = RS::ENV_SSAO_QUALITY_MEDIUM;
+ bool half_size = false;
+ float adaptive_target = 0.5;
+ int blur_passes = 2;
+ float fadeout_from = 50.0;
+ float fadeout_to = 300.0;
+
+ Size2i full_screen_size = Size2i();
+ };
+
+ void ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings, RID p_linear_depth);
+ void generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const CameraMatrix &p_projection, const SSAOSettings &p_settings);
+ void ssao_free(SSAORenderBuffers &p_ssao_buffers);
+
+ /* Screen Space Reflection */
+
+ struct SSRRenderBuffers {
+ RID normal_scaled;
+ RID depth_scaled;
+ RID blur_radius[2];
+ RID intermediate;
+ RID output;
+ RID output_slices[RendererSceneRender::MAX_RENDER_VIEWS];
+ };
+
+ void ssr_allocate_buffers(SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, const Size2i &p_screen_size, const uint32_t p_view_count);
+ void screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, const RID *p_metallic_slices, const Color &p_metallic_mask, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets);
+ void ssr_free(SSRRenderBuffers &p_ssr_buffers);
+
+private:
+ /* SS Downsampler */
+
+ struct SSEffectsDownsamplePushConstant {
+ float pixel_size[2];
+ float z_far;
+ float z_near;
+ uint32_t orthogonal;
+ float radius_sq;
+ uint32_t pad[2];
+ };
+
+ enum SSEffectsMode {
+ SS_EFFECTS_DOWNSAMPLE,
+ SS_EFFECTS_DOWNSAMPLE_HALF_RES,
+ SS_EFFECTS_DOWNSAMPLE_MIPMAP,
+ SS_EFFECTS_DOWNSAMPLE_MIPMAP_HALF_RES,
+ SS_EFFECTS_DOWNSAMPLE_HALF,
+ SS_EFFECTS_DOWNSAMPLE_HALF_RES_HALF,
+ SS_EFFECTS_DOWNSAMPLE_FULL_MIPS,
+ SS_EFFECTS_MAX
+ };
+
+ struct SSEffectsGatherConstants {
+ float rotation_matrices[80]; //5 vec4s * 4
+ };
+
+ struct SSEffectsShader {
+ SSEffectsDownsamplePushConstant downsample_push_constant;
+ SsEffectsDownsampleShaderRD downsample_shader;
+ RID downsample_shader_version;
+ RID downsample_uniform_set;
+ bool used_half_size_last_frame = false;
+ bool used_mips_last_frame = false;
+ bool used_full_mips_last_frame = false;
+
+ RID gather_constants_buffer;
+
+ RID mirror_sampler;
+
+ RID pipelines[SS_EFFECTS_MAX];
+ } ss_effects;
+
+ /* SSIL */
+
+ enum SSILMode {
+ SSIL_GATHER,
+ SSIL_GATHER_BASE,
+ SSIL_GATHER_ADAPTIVE,
+ SSIL_GENERATE_IMPORTANCE_MAP,
+ SSIL_PROCESS_IMPORTANCE_MAPA,
+ SSIL_PROCESS_IMPORTANCE_MAPB,
+ SSIL_BLUR_PASS,
+ SSIL_BLUR_PASS_SMART,
+ SSIL_BLUR_PASS_WIDE,
+ SSIL_INTERLEAVE,
+ SSIL_INTERLEAVE_SMART,
+ SSIL_INTERLEAVE_HALF,
+ SSIL_MAX
+ };
+
+ struct SSILGatherPushConstant {
+ int32_t screen_size[2];
+ int pass;
+ int quality;
+
+ float half_screen_pixel_size[2];
+ float half_screen_pixel_size_x025[2];
+
+ float NDC_to_view_mul[2];
+ float NDC_to_view_add[2];
+
+ float pad2[2];
+ float z_near;
+ float z_far;
+
+ float radius;
+ float intensity;
+ int size_multiplier;
+ int pad;
+
+ float fade_out_mul;
+ float fade_out_add;
+ float normal_rejection_amount;
+ float inv_radius_near_limit;
+
+ uint32_t is_orthogonal;
+ float neg_inv_radius;
+ float load_counter_avg_div;
+ float adaptive_sample_limit;
+
+ int32_t pass_coord_offset[2];
+ float pass_uv_offset[2];
+ };
+
+ struct SSILImportanceMapPushConstant {
+ float half_screen_pixel_size[2];
+ float intensity;
+ float pad;
+ };
+
+ struct SSILBlurPushConstant {
+ float edge_sharpness;
+ float pad;
+ float half_screen_pixel_size[2];
+ };
+
+ struct SSILInterleavePushConstant {
+ float inv_sharpness;
+ uint32_t size_modifier;
+ float pixel_size[2];
+ };
+
+ struct SSILProjectionUniforms {
+ float inv_last_frame_projection_matrix[16];
+ };
+
+ struct SSIL {
+ SSILGatherPushConstant gather_push_constant;
+ SsilShaderRD gather_shader;
+ RID gather_shader_version;
+ RID projection_uniform_buffer;
+
+ SSILImportanceMapPushConstant importance_map_push_constant;
+ SsilImportanceMapShaderRD importance_map_shader;
+ RID importance_map_shader_version;
+ RID importance_map_load_counter;
+ RID counter_uniform_set;
+
+ SSILBlurPushConstant blur_push_constant;
+ SsilBlurShaderRD blur_shader;
+ RID blur_shader_version;
+
+ SSILInterleavePushConstant interleave_push_constant;
+ SsilInterleaveShaderRD interleave_shader;
+ RID interleave_shader_version;
+
+ RID pipelines[SSIL_MAX];
+ } ssil;
+
+ void gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set);
+
+ /* SSAO */
+
+ enum SSAOMode {
+ SSAO_GATHER,
+ SSAO_GATHER_BASE,
+ SSAO_GATHER_ADAPTIVE,
+ SSAO_GENERATE_IMPORTANCE_MAP,
+ SSAO_PROCESS_IMPORTANCE_MAPA,
+ SSAO_PROCESS_IMPORTANCE_MAPB,
+ SSAO_BLUR_PASS,
+ SSAO_BLUR_PASS_SMART,
+ SSAO_BLUR_PASS_WIDE,
+ SSAO_INTERLEAVE,
+ SSAO_INTERLEAVE_SMART,
+ SSAO_INTERLEAVE_HALF,
+ SSAO_MAX
+ };
+
+ struct SSAOGatherPushConstant {
+ int32_t screen_size[2];
+ int pass;
+ int quality;
+
+ float half_screen_pixel_size[2];
+ int size_multiplier;
+ float detail_intensity;
+
+ float NDC_to_view_mul[2];
+ float NDC_to_view_add[2];
+
+ float pad[2];
+ float half_screen_pixel_size_x025[2];
+
+ float radius;
+ float intensity;
+ float shadow_power;
+ float shadow_clamp;
+
+ float fade_out_mul;
+ float fade_out_add;
+ float horizon_angle_threshold;
+ float inv_radius_near_limit;
+
+ uint32_t is_orthogonal;
+ float neg_inv_radius;
+ float load_counter_avg_div;
+ float adaptive_sample_limit;
+
+ int32_t pass_coord_offset[2];
+ float pass_uv_offset[2];
+ };
+
+ struct SSAOImportanceMapPushConstant {
+ float half_screen_pixel_size[2];
+ float intensity;
+ float power;
+ };
+
+ struct SSAOBlurPushConstant {
+ float edge_sharpness;
+ float pad;
+ float half_screen_pixel_size[2];
+ };
+
+ struct SSAOInterleavePushConstant {
+ float inv_sharpness;
+ uint32_t size_modifier;
+ float pixel_size[2];
+ };
+
+ struct SSAO {
+ SSAOGatherPushConstant gather_push_constant;
+ SsaoShaderRD gather_shader;
+ RID gather_shader_version;
+
+ SSAOImportanceMapPushConstant importance_map_push_constant;
+ SsaoImportanceMapShaderRD importance_map_shader;
+ RID importance_map_shader_version;
+ RID importance_map_load_counter;
+ RID counter_uniform_set;
+
+ SSAOBlurPushConstant blur_push_constant;
+ SsaoBlurShaderRD blur_shader;
+ RID blur_shader_version;
+
+ SSAOInterleavePushConstant interleave_push_constant;
+ SsaoInterleaveShaderRD interleave_shader;
+ RID interleave_shader_version;
+
+ RID pipelines[SSAO_MAX];
+ } ssao;
+
+ void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set);
+
+ /* Screen Space Reflection */
+
+ enum SSRShaderSpecializations {
+ SSR_MULTIVIEW = 1 << 0,
+ SSR_VARIATIONS = 2,
+ };
+
+ struct ScreenSpaceReflectionSceneData {
+ float projection[2][16];
+ float inv_projection[2][16];
+ float eye_offset[2][4];
+ };
+
+ // SSR Scale
+
+ struct ScreenSpaceReflectionScalePushConstant {
+ int32_t screen_size[2];
+ float camera_z_near;
+ float camera_z_far;
+
+ uint32_t orthogonal;
+ uint32_t filter;
+ uint32_t view_index;
+ uint32_t pad1;
+ };
+
+ struct ScreenSpaceReflectionScale {
+ ScreenSpaceReflectionScaleShaderRD shader;
+ RID shader_version;
+ RID pipelines[SSR_VARIATIONS];
+ } ssr_scale;
+
+ // SSR main
+
+ enum ScreenSpaceReflectionMode {
+ SCREEN_SPACE_REFLECTION_NORMAL,
+ SCREEN_SPACE_REFLECTION_ROUGH,
+ SCREEN_SPACE_REFLECTION_MAX,
+ };
+
+ struct ScreenSpaceReflectionPushConstant {
+ float proj_info[4]; // 16 - 16
+
+ int32_t screen_size[2]; // 8 - 24
+ float camera_z_near; // 4 - 28
+ float camera_z_far; // 4 - 32
+
+ int32_t num_steps; // 4 - 36
+ float depth_tolerance; // 4 - 40
+ float distance_fade; // 4 - 44
+ float curve_fade_in; // 4 - 48
+
+ uint32_t orthogonal; // 4 - 52
+ float filter_mipmap_levels; // 4 - 56
+ uint32_t use_half_res; // 4 - 60
+ uint8_t metallic_mask[4]; // 4 - 64
+
+ uint32_t view_index; // 4 - 68
+ uint32_t pad[3]; // 12 - 80
+
+ // float projection[16]; // this is in our ScreenSpaceReflectionSceneData now
+ };
+
+ struct ScreenSpaceReflection {
+ ScreenSpaceReflectionShaderRD shader;
+ RID shader_version;
+ RID pipelines[SSR_VARIATIONS][SCREEN_SPACE_REFLECTION_MAX];
+
+ RID ubo;
+ } ssr;
+
+ // SSR Filter
+
+ struct ScreenSpaceReflectionFilterPushConstant {
+ float proj_info[4]; // 16 - 16
+
+ uint32_t orthogonal; // 4 - 20
+ float edge_tolerance; // 4 - 24
+ int32_t increment; // 4 - 28
+ uint32_t view_index; // 4 - 32
+
+ int32_t screen_size[2]; // 8 - 40
+ uint32_t vertical; // 4 - 44
+ uint32_t steps; // 4 - 48
+ };
+
+ enum SSRReflectionMode {
+ SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL,
+ SCREEN_SPACE_REFLECTION_FILTER_VERTICAL,
+ SCREEN_SPACE_REFLECTION_FILTER_MAX,
+ };
+
+ struct ScreenSpaceReflectionFilter {
+ ScreenSpaceReflectionFilterShaderRD shader;
+ RID shader_version;
+ RID pipelines[SSR_VARIATIONS][SCREEN_SPACE_REFLECTION_FILTER_MAX];
+ } ssr_filter;
+};
+
+} // namespace RendererRD
+
+#endif // !SS_EFFECTS_RD_H
diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp
new file mode 100644
index 0000000000..fa0b99fef9
--- /dev/null
+++ b/servers/rendering/renderer_rd/effects/vrs.cpp
@@ -0,0 +1,171 @@
+/*************************************************************************/
+/* vrs.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "vrs.h"
+#include "../renderer_compositor_rd.h"
+#include "../storage_rd/texture_storage.h"
+#include "../uniform_set_cache_rd.h"
+#include "servers/xr_server.h"
+
+using namespace RendererRD;
+
+VRS::VRS() {
+ {
+ Vector<String> vrs_modes;
+ vrs_modes.push_back("\n"); // VRS_DEFAULT
+ vrs_modes.push_back("\n#define MULTIVIEW\n"); // VRS_MULTIVIEW
+
+ vrs_shader.shader.initialize(vrs_modes);
+
+ if (!RendererCompositorRD::singleton->is_xr_enabled()) {
+ vrs_shader.shader.set_variant_enabled(VRS_MULTIVIEW, false);
+ }
+
+ vrs_shader.shader_version = vrs_shader.shader.version_create();
+
+ //use additive
+
+ for (int i = 0; i < VRS_MAX; i++) {
+ if (vrs_shader.shader.is_variant_enabled(i)) {
+ vrs_shader.pipelines[i].setup(vrs_shader.shader.version_get_shader(vrs_shader.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ } else {
+ vrs_shader.pipelines[i].clear();
+ }
+ }
+ }
+}
+
+VRS::~VRS() {
+ vrs_shader.shader.version_free(vrs_shader.shader_version);
+}
+
+void VRS::copy_vrs(RID p_source_rd_texture, RID p_dest_framebuffer, bool p_multiview) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ // setup our uniforms
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
+
+ VRSMode mode = p_multiview ? VRS_MULTIVIEW : VRS_DEFAULT;
+
+ RID shader = vrs_shader.shader.version_get_shader(vrs_shader.shader_version, mode);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>());
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, vrs_shader.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
+ // RD::get_singleton()->draw_list_set_push_constant(draw_list, &vrs_shader.push_constant, sizeof(VRSPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+}
+
+void VRS::create_vrs_texture(const int p_base_width, const int p_base_height, const uint32_t p_view_count, RID &p_vrs_texture, RID &p_vrs_fb) {
+ // TODO find a way to skip this if VRS is not supported, but we don't have access to VulkanContext here, even though we're in vulkan.. hmmm
+
+ // TODO we should find some way to store this properly, we're assuming 16x16 as this seems to be the standard but in our vrs_capacities we
+ // obtain a minimum and maximum size, and we should choose something within this range and then make sure that is consistently set when creating
+ // our frame buffer. Also it is important that we make the resulting size we calculate down below available to the end user so they know the size
+ // of the VRS buffer to supply.
+ Size2i texel_size = Size2i(16, 16);
+
+ RD::TextureFormat tf;
+ if (p_view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ } else {
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ }
+ tf.format = RD::DATA_FORMAT_R8_UINT;
+ tf.width = p_base_width / texel_size.x;
+ if (p_base_width % texel_size.x != 0) {
+ tf.width++;
+ }
+ tf.height = p_base_height / texel_size.y;
+ if (p_base_height % texel_size.y != 0) {
+ tf.height++;
+ }
+ tf.array_layers = p_view_count; // create a layer for every view
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ tf.samples = RD::TEXTURE_SAMPLES_1;
+
+ p_vrs_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ // by default VRS is assumed to be our VRS attachment, but if we need to write into it, we need a bit more control
+ Vector<RID> fb;
+ fb.push_back(p_vrs_texture);
+
+ RD::FramebufferPass pass;
+ pass.color_attachments.push_back(0);
+
+ Vector<RD::FramebufferPass> passes;
+ passes.push_back(pass);
+
+ p_vrs_fb = RD::get_singleton()->framebuffer_create_multipass(fb, passes, RenderingDevice::INVALID_ID, p_view_count);
+}
+
+void VRS::update_vrs_texture(RID p_vrs_fb, RID p_render_target) {
+ TextureStorage *texture_storage = TextureStorage::get_singleton();
+ RS::ViewportVRSMode vrs_mode = texture_storage->render_target_get_vrs_mode(p_render_target);
+
+ if (vrs_mode != RS::VIEWPORT_VRS_DISABLED) {
+ RD::get_singleton()->draw_command_begin_label("VRS Setup");
+
+ // TODO figure out if image has changed since it was last copied so we can save some resources..
+
+ if (vrs_mode == RS::VIEWPORT_VRS_TEXTURE) {
+ RID vrs_texture = texture_storage->render_target_get_vrs_texture(p_render_target);
+ if (vrs_texture.is_valid()) {
+ Texture *texture = texture_storage->get_texture(vrs_texture);
+ if (texture) {
+ // Copy into our density buffer
+ copy_vrs(texture->rd_texture, p_vrs_fb, texture->layers > 1);
+ }
+ }
+ } else if (vrs_mode == RS::VIEWPORT_VRS_XR) {
+ Ref<XRInterface> interface = XRServer::get_singleton()->get_primary_interface();
+ if (interface.is_valid()) {
+ RID vrs_texture = interface->get_vrs_texture();
+ if (vrs_texture.is_valid()) {
+ Texture *texture = texture_storage->get_texture(vrs_texture);
+ if (texture) {
+ // Copy into our density buffer
+ copy_vrs(texture->rd_texture, p_vrs_fb, texture->layers > 1);
+ }
+ }
+ }
+ }
+
+ RD::get_singleton()->draw_command_end_label();
+ }
+}
diff --git a/servers/rendering/renderer_rd/effects/vrs.h b/servers/rendering/renderer_rd/effects/vrs.h
new file mode 100644
index 0000000000..0f2bdd31b6
--- /dev/null
+++ b/servers/rendering/renderer_rd/effects/vrs.h
@@ -0,0 +1,75 @@
+/*************************************************************************/
+/* vrs.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef VRS_RD_H
+#define VRS_RD_H
+
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
+#include "servers/rendering/renderer_rd/shaders/effects/vrs.glsl.gen.h"
+#include "servers/rendering/renderer_scene_render.h"
+
+#include "servers/rendering_server.h"
+
+namespace RendererRD {
+
+class VRS {
+private:
+ enum VRSMode {
+ VRS_DEFAULT,
+ VRS_MULTIVIEW,
+ VRS_MAX,
+ };
+
+ /* we have no push constant here (yet)
+ struct VRSPushConstant {
+
+ };
+ */
+
+ struct VRSShader {
+ // VRSPushConstant push_constant;
+ VrsShaderRD shader;
+ RID shader_version;
+ PipelineCacheRD pipelines[VRS_MAX];
+ } vrs_shader;
+
+public:
+ VRS();
+ ~VRS();
+
+ void copy_vrs(RID p_source_rd_texture, RID p_dest_framebuffer, bool p_multiview = false);
+
+ void create_vrs_texture(const int p_base_width, const int p_base_height, const uint32_t p_view_count, RID &p_vrs_texture, RID &p_vrs_fb);
+ void update_vrs_texture(RID p_vrs_fb, RID p_render_target);
+};
+
+} // namespace RendererRD
+
+#endif // !VRS_RD_H
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index d45ddbc392..e9cfee5d64 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -41,14 +41,6 @@ bool EffectsRD::get_prefer_raster_effects() {
return prefer_raster_effects;
}
-static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- p_array[i * 4 + j] = p_mtx.matrix[i][j];
- }
- }
-}
-
RID EffectsRD::_get_uniform_set_from_image(RID p_image) {
if (image_to_uniform_set_cache.has(p_image)) {
RID uniform_set = image_to_uniform_set_cache[p_image];
@@ -86,7 +78,7 @@ RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps)
u.append_id(p_texture);
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, specular_merge.shader.version_get_shader(specular_merge.shader_version, 0), 0);
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce_raster.shader.version_get_shader(luminance_reduce_raster.shader_version, 0), 0);
texture_to_uniform_set_cache[p_texture] = uniform_set;
@@ -116,105 +108,6 @@ RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_m
return uniform_set;
}
-RID EffectsRD::_get_compute_uniform_set_from_texture_and_sampler(RID p_texture, RID p_sampler) {
- TextureSamplerPair tsp;
- tsp.texture = p_texture;
- tsp.sampler = p_sampler;
-
- if (texture_sampler_to_compute_uniform_set_cache.has(tsp)) {
- RID uniform_set = texture_sampler_to_compute_uniform_set_cache[tsp];
- 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.append_id(p_sampler);
- u.append_id(p_texture);
- uniforms.push_back(u);
- //any thing with the same configuration (one texture in binding 0 for set 0), is good
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.blur_shader.version_get_shader(ssao.blur_shader_version, 0), 0);
-
- texture_sampler_to_compute_uniform_set_cache[tsp] = uniform_set;
-
- return uniform_set;
-}
-
-RID EffectsRD::_get_compute_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_compute_uniform_set_cache.has(tp)) {
- RID uniform_set = texture_pair_to_compute_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.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
- u.append_id(p_texture1);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 1;
- u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
- u.append_id(p_texture2);
- uniforms.push_back(u);
- }
- //any thing with the same configuration (one texture in binding 0 for set 0), is good
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), 1);
-
- texture_pair_to_compute_uniform_set_cache[tp] = uniform_set;
-
- return uniform_set;
-}
-
-RID EffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) {
- TexturePair tp;
- tp.texture1 = p_texture1;
- tp.texture2 = p_texture2;
-
- if (image_pair_to_compute_uniform_set_cache.has(tp)) {
- RID uniform_set = image_pair_to_compute_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_IMAGE;
- u.binding = 0;
- u.append_id(p_texture1);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.append_id(p_texture2);
- uniforms.push_back(u);
- }
- //any thing with the same configuration (one texture in binding 0 for set 0), is good
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), 3);
-
- image_pair_to_compute_uniform_set_cache[tp] = uniform_set;
-
- return uniform_set;
-}
-
void EffectsRD::fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness) {
memset(&FSR_upscale.push_constant, 0, sizeof(FSRUpscalePushConstant));
@@ -281,125 +174,6 @@ void EffectsRD::taa_resolve(RID p_frame, RID p_temp, RID p_depth, RID p_velocity
RD::get_singleton()->compute_list_end();
}
-void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) {
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
- { //scale color and depth to half
- ssr_scale.push_constant.camera_z_far = p_camera.get_z_far();
- ssr_scale.push_constant.camera_z_near = p_camera.get_z_near();
- ssr_scale.push_constant.orthogonal = p_camera.is_orthogonal();
- ssr_scale.push_constant.filter = false; //enabling causes arctifacts
- ssr_scale.push_constant.screen_size[0] = p_screen_size.x;
- ssr_scale.push_constant.screen_size[1] = p_screen_size.y;
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_scale.pipeline);
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_diffuse), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_depth, p_normal_roughness), 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output_blur), 2);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_scale_depth, p_scale_normal), 3);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_scale.push_constant, sizeof(ScreenSpaceReflectionScalePushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
-
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- }
-
- {
- ssr.push_constant.camera_z_far = p_camera.get_z_far();
- ssr.push_constant.camera_z_near = p_camera.get_z_near();
- ssr.push_constant.orthogonal = p_camera.is_orthogonal();
- ssr.push_constant.screen_size[0] = p_screen_size.x;
- ssr.push_constant.screen_size[1] = p_screen_size.y;
- ssr.push_constant.curve_fade_in = p_fade_in;
- ssr.push_constant.distance_fade = p_fade_out;
- ssr.push_constant.num_steps = p_max_steps;
- ssr.push_constant.depth_tolerance = p_tolerance;
- ssr.push_constant.use_half_res = true;
- ssr.push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_camera.matrix[0][0]);
- ssr.push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_camera.matrix[1][1]);
- ssr.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0];
- ssr.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1];
- ssr.push_constant.metallic_mask[0] = CLAMP(p_metallic_mask.r * 255.0, 0, 255);
- ssr.push_constant.metallic_mask[1] = CLAMP(p_metallic_mask.g * 255.0, 0, 255);
- ssr.push_constant.metallic_mask[2] = CLAMP(p_metallic_mask.b * 255.0, 0, 255);
- ssr.push_constant.metallic_mask[3] = CLAMP(p_metallic_mask.a * 255.0, 0, 255);
- store_camera(p_camera, ssr.push_constant.projection);
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[(p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL]);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr.push_constant, sizeof(ScreenSpaceReflectionPushConstant));
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_scale_depth), 0);
-
- if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 1);
- } else {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 1);
- }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_metallic), 3);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 2);
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
- }
-
- if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) {
- //blur
-
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- ssr_filter.push_constant.orthogonal = p_camera.is_orthogonal();
- ssr_filter.push_constant.edge_tolerance = Math::sin(Math::deg2rad(15.0));
- ssr_filter.push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_camera.matrix[0][0]);
- ssr_filter.push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_camera.matrix[1][1]);
- ssr_filter.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0];
- ssr_filter.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1];
- ssr_filter.push_constant.vertical = 0;
- if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_LOW) {
- ssr_filter.push_constant.steps = p_max_steps / 3;
- ssr_filter.push_constant.increment = 3;
- } else if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_MEDIUM) {
- ssr_filter.push_constant.steps = p_max_steps / 2;
- ssr_filter.push_constant.increment = 2;
- } else {
- ssr_filter.push_constant.steps = p_max_steps;
- ssr_filter.push_constant.increment = 1;
- }
-
- ssr_filter.push_constant.screen_size[0] = p_screen_size.width;
- ssr_filter.push_constant.screen_size[1] = p_screen_size.height;
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL]);
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_blur_radius2), 2);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_depth), 3);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
-
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[SCREEN_SPACE_REFLECTION_FILTER_VERTICAL]);
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_blur_radius2), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 2);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_depth), 3);
-
- ssr_filter.push_constant.vertical = 1;
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
- }
-
- RD::get_singleton()->compute_list_end();
-}
-
void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -443,36 +217,6 @@ void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_dept
}
}
-void EffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) {
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, Vector<Color>());
-
- if (p_reflection.is_valid()) {
- if (p_base.is_valid()) {
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2);
- } else {
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADDITIVE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- }
-
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_specular), 0);
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_reflection), 1);
-
- } else {
- if (p_base.is_valid()) {
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2);
- } else {
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADDITIVE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- }
-
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_specular), 0);
- }
-
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
-}
-
void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) {
ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of luminance reduction with the mobile renderer.");
@@ -546,674 +290,6 @@ void EffectsRD::luminance_reduction_raster(RID p_source_texture, const Size2i p_
}
}
-void EffectsRD::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection) {
- // Downsample and deinterleave the depth buffer for SSAO and SSIL
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
- int downsample_pipeline = SS_EFFECTS_DOWNSAMPLE;
- bool use_mips = p_ssao_quality > RS::ENV_SSAO_QUALITY_MEDIUM || p_ssil_quality > RS::ENV_SSIL_QUALITY_MEDIUM;
-
- if (p_ssao_quality == RS::ENV_SSAO_QUALITY_VERY_LOW && p_ssil_quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
- downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_HALF;
- } else if (use_mips) {
- downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_MIPMAP;
- }
-
- bool use_half_size = false;
- bool use_full_mips = false;
-
- if (p_ssao_half_size && p_ssil_half_size) {
- downsample_pipeline++;
- use_half_size = true;
- } else if (p_ssao_half_size != p_ssil_half_size) {
- if (use_mips) {
- downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_FULL_MIPS;
- use_full_mips = true;
- } else {
- // Only need the first two mipmaps, but the cost to generate the next two is trivial
- // TODO investigate the benefit of a shader version to generate only 2 mips
- downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_MIPMAP;
- use_mips = true;
- }
- }
-
- int depth_index = use_half_size ? 1 : 0;
-
- RD::get_singleton()->draw_command_begin_label("Downsample Depth");
- if (p_invalidate_uniform_set || use_full_mips != ss_effects.used_full_mips_last_frame || use_half_size != ss_effects.used_half_size_last_frame || use_mips != ss_effects.used_mips_last_frame) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 0;
- u.append_id(p_depth_mipmaps[depth_index + 1]);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.append_id(p_depth_mipmaps[depth_index + 2]);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.append_id(p_depth_mipmaps[depth_index + 3]);
- uniforms.push_back(u);
- }
- if (use_full_mips) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 3;
- u.append_id(p_depth_mipmaps[4]);
- uniforms.push_back(u);
- }
- ss_effects.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, use_full_mips ? 6 : 2), 2);
- }
-
- float depth_linearize_mul = -p_projection.matrix[3][2];
- float depth_linearize_add = p_projection.matrix[2][2];
- if (depth_linearize_mul * depth_linearize_add < 0) {
- depth_linearize_add = -depth_linearize_add;
- }
-
- ss_effects.downsample_push_constant.orthogonal = p_projection.is_orthogonal();
- ss_effects.downsample_push_constant.z_near = depth_linearize_mul;
- ss_effects.downsample_push_constant.z_far = depth_linearize_add;
- if (ss_effects.downsample_push_constant.orthogonal) {
- ss_effects.downsample_push_constant.z_near = p_projection.get_z_near();
- ss_effects.downsample_push_constant.z_far = p_projection.get_z_far();
- }
- ss_effects.downsample_push_constant.pixel_size[0] = 1.0 / p_full_screen_size.x;
- ss_effects.downsample_push_constant.pixel_size[1] = 1.0 / p_full_screen_size.y;
- ss_effects.downsample_push_constant.radius_sq = 1.0;
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ss_effects.pipelines[downsample_pipeline]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_depth_mipmaps[depth_index + 0]), 1);
- if (use_mips) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ss_effects.downsample_uniform_set, 2);
- }
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ss_effects.downsample_push_constant, sizeof(SSEffectsDownsamplePushConstant));
-
- Size2i size(MAX(1, p_full_screen_size.x >> (use_half_size ? 2 : 1)), MAX(1, p_full_screen_size.y >> (use_half_size ? 2 : 1)));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- RD::get_singleton()->draw_command_end_label();
-
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE);
-
- ss_effects.used_full_mips_last_frame = use_full_mips;
- ss_effects.used_half_size_last_frame = use_half_size;
-}
-
-void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set) {
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0);
- if ((p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) && !p_adaptive_base_pass) {
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 1);
- }
-
- for (int i = 0; i < 4; i++) {
- if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
- continue;
- }
-
- ssao.gather_push_constant.pass_coord_offset[0] = i % 2;
- ssao.gather_push_constant.pass_coord_offset[1] = i / 2;
- ssao.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x;
- ssao.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y;
- ssao.gather_push_constant.pass = i;
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, _get_uniform_set_from_image(p_ao_slices[i]), 2);
- RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssao.gather_push_constant, sizeof(SSAOGatherPushConstant));
-
- Size2i size = Size2i(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
-
- RD::get_singleton()->compute_list_dispatch_threads(p_compute_list, size.x, size.y, 1);
- }
- RD::get_singleton()->compute_list_add_barrier(p_compute_list);
-}
-
-void EffectsRD::generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set) {
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- memset(&ssao.gather_push_constant, 0, sizeof(SSAOGatherPushConstant));
- /* FIRST PASS */
-
- RD::get_singleton()->draw_command_begin_label("Process Screen Space Ambient Occlusion");
- /* SECOND PASS */
- // Sample SSAO
- {
- RD::get_singleton()->draw_command_begin_label("Gather Samples");
- ssao.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x;
- ssao.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y;
-
- ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
- ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
- float tan_half_fov_x = 1.0 / p_projection.matrix[0][0];
- float tan_half_fov_y = 1.0 / p_projection.matrix[1][1];
- ssao.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
- ssao.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0;
- ssao.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0;
- ssao.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y;
- ssao.gather_push_constant.is_orthogonal = p_projection.is_orthogonal();
-
- ssao.gather_push_constant.half_screen_pixel_size_x025[0] = ssao.gather_push_constant.half_screen_pixel_size[0] * 0.25;
- ssao.gather_push_constant.half_screen_pixel_size_x025[1] = ssao.gather_push_constant.half_screen_pixel_size[1] * 0.25;
-
- ssao.gather_push_constant.radius = p_settings.radius;
- float radius_near_limit = (p_settings.radius * 1.2f);
- if (p_settings.quality <= RS::ENV_SSAO_QUALITY_LOW) {
- radius_near_limit *= 1.50f;
-
- if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
- ssao.gather_push_constant.radius *= 0.8f;
- }
- }
- radius_near_limit /= tan_half_fov_y;
- ssao.gather_push_constant.intensity = p_settings.intensity;
- ssao.gather_push_constant.shadow_power = p_settings.power;
- ssao.gather_push_constant.shadow_clamp = 0.98;
- ssao.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from);
- ssao.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0;
- ssao.gather_push_constant.horizon_angle_threshold = p_settings.horizon;
- ssao.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit;
- ssao.gather_push_constant.neg_inv_radius = -1.0 / ssao.gather_push_constant.radius;
-
- ssao.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_screen_size.x) * (p_settings.quarter_screen_size.y) * 255);
- ssao.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target;
-
- ssao.gather_push_constant.detail_intensity = p_settings.detail;
- ssao.gather_push_constant.quality = MAX(0, p_settings.quality - 1);
- ssao.gather_push_constant.size_multiplier = p_settings.half_size ? 2 : 1;
-
- if (p_invalidate_uniform_sets) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 0;
- u.append_id(default_sampler);
- u.append_id(p_depth_mipmaps_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.append_id(p_normal_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 2;
- u.append_id(ss_effects.gather_constants_buffer);
- uniforms.push_back(u);
- }
- r_gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0), 0);
- }
-
- if (p_invalidate_uniform_sets) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 0;
- u.append_id(p_ao_pong);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 1;
- u.append_id(default_sampler);
- u.append_id(p_importance_map);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 2;
- u.append_id(ssao.importance_map_load_counter);
- uniforms.push_back(u);
- }
- r_importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 2), 1);
- }
-
- if (p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) {
- RD::get_singleton()->draw_command_begin_label("Generate Importance Map");
- ssao.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
- ssao.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
- ssao.importance_map_push_constant.intensity = p_settings.intensity;
- ssao.importance_map_push_constant.power = p_settings.power;
- //base pass
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_BASE]);
- gather_ssao(compute_list, p_ao_pong_slices, p_settings, true, r_gather_uniform_set, RID());
- //generate importance map
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GENERATE_IMPORTANCE_MAP]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- //process importance map A
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPA]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map_pong), 1);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- //process Importance Map B
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPB]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map_pong), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.counter_uniform_set, 2);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_ADAPTIVE]);
- RD::get_singleton()->draw_command_end_label(); // Importance Map
- } else {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER]);
- }
-
- gather_ssao(compute_list, p_ao_slices, p_settings, false, r_gather_uniform_set, r_importance_map_uniform_set);
- RD::get_singleton()->draw_command_end_label(); // Gather SSAO
- }
-
- // /* THIRD PASS */
- // // Blur
- //
- {
- RD::get_singleton()->draw_command_begin_label("Edge Aware Blur");
- ssao.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness;
- ssao.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
- ssao.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
-
- int blur_passes = p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW ? p_settings.blur_passes : 1;
-
- for (int pass = 0; pass < blur_passes; pass++) {
- int blur_pipeline = SSAO_BLUR_PASS;
- if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) {
- blur_pipeline = SSAO_BLUR_PASS_SMART;
- if (pass < blur_passes - 2) {
- blur_pipeline = SSAO_BLUR_PASS_WIDE;
- } else {
- blur_pipeline = SSAO_BLUR_PASS_SMART;
- }
- }
-
- for (int i = 0; i < 4; i++) {
- if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
- continue;
- }
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[blur_pipeline]);
- if (pass % 2 == 0) {
- if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_slices[i]), 0);
- } else {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ao_slices[i], ss_effects.mirror_sampler), 0);
- }
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao_pong_slices[i]), 1);
- } else {
- if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong_slices[i]), 0);
- } else {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ao_pong_slices[i], ss_effects.mirror_sampler), 0);
- }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao_slices[i]), 1);
- }
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant));
-
- Size2i size(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
- }
-
- if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) {
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- }
- }
- RD::get_singleton()->draw_command_end_label(); // Blur
- }
-
- /* FOURTH PASS */
- // Interleave buffers
- // back to full size
- {
- RD::get_singleton()->draw_command_begin_label("Interleave Buffers");
- ssao.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness;
- ssao.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x;
- ssao.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y;
- ssao.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2);
-
- int interleave_pipeline = SSAO_INTERLEAVE_HALF;
- if (p_settings.quality == RS::ENV_SSAO_QUALITY_LOW) {
- interleave_pipeline = SSAO_INTERLEAVE;
- } else if (p_settings.quality >= RS::ENV_SSAO_QUALITY_MEDIUM) {
- interleave_pipeline = SSAO_INTERLEAVE_SMART;
- }
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[interleave_pipeline]);
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_upscale_buffer), 0);
- if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW && p_settings.blur_passes % 2 == 0) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao), 1);
- } else {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong), 1);
- }
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.interleave_push_constant, sizeof(SSAOInterleavePushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.full_screen_size.x, p_settings.full_screen_size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- RD::get_singleton()->draw_command_end_label(); // Interleave
- }
- RD::get_singleton()->draw_command_end_label(); //SSAO
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //wait for upcoming transfer
-
- int zero[1] = { 0 };
- RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
-}
-
-void EffectsRD::gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set) {
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0);
- if ((p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) && !p_adaptive_base_pass) {
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 1);
- }
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_projection_uniform_set, 3);
-
- for (int i = 0; i < 4; i++) {
- if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
- continue;
- }
-
- ssil.gather_push_constant.pass_coord_offset[0] = i % 2;
- ssil.gather_push_constant.pass_coord_offset[1] = i / 2;
- ssil.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x;
- ssil.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y;
- ssil.gather_push_constant.pass = i;
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, _get_compute_uniform_set_from_image_pair(p_ssil_slices[i], p_edges_slices[i]), 2);
- RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssil.gather_push_constant, sizeof(SSILGatherPushConstant));
-
- Size2i size = Size2i(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
-
- RD::get_singleton()->compute_list_dispatch_threads(p_compute_list, size.x, size.y, 1);
- }
- RD::get_singleton()->compute_list_add_barrier(p_compute_list);
-}
-
-void EffectsRD::screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ssil, const Vector<RID> p_ssil_slices, RID p_ssil_pong, const Vector<RID> p_ssil_pong_slices, RID p_importance_map, RID p_importance_map_pong, RID p_edges, const Vector<RID> p_edges_slices, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set, RID &r_projection_uniform_set) {
- RD::get_singleton()->draw_command_begin_label("Process Screen Space Indirect Lighting");
- //Store projection info before starting the compute list
- SSILProjectionUniforms projection_uniforms;
- store_camera(p_last_projection, projection_uniforms.inv_last_frame_projection_matrix);
-
- RD::get_singleton()->buffer_update(ssil.projection_uniform_buffer, 0, sizeof(SSILProjectionUniforms), &projection_uniforms);
-
- memset(&ssil.gather_push_constant, 0, sizeof(SSILGatherPushConstant));
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- {
- RD::get_singleton()->draw_command_begin_label("Gather Samples");
- ssil.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x;
- ssil.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y;
-
- ssil.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
- ssil.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
- float tan_half_fov_x = 1.0 / p_projection.matrix[0][0];
- float tan_half_fov_y = 1.0 / p_projection.matrix[1][1];
- ssil.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
- ssil.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0;
- ssil.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0;
- ssil.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y;
- ssil.gather_push_constant.z_near = p_projection.get_z_near();
- ssil.gather_push_constant.z_far = p_projection.get_z_far();
- ssil.gather_push_constant.is_orthogonal = p_projection.is_orthogonal();
-
- ssil.gather_push_constant.half_screen_pixel_size_x025[0] = ssil.gather_push_constant.half_screen_pixel_size[0] * 0.25;
- ssil.gather_push_constant.half_screen_pixel_size_x025[1] = ssil.gather_push_constant.half_screen_pixel_size[1] * 0.25;
-
- ssil.gather_push_constant.radius = p_settings.radius;
- float radius_near_limit = (p_settings.radius * 1.2f);
- if (p_settings.quality <= RS::ENV_SSIL_QUALITY_LOW) {
- radius_near_limit *= 1.50f;
-
- if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
- ssil.gather_push_constant.radius *= 0.8f;
- }
- }
- radius_near_limit /= tan_half_fov_y;
- ssil.gather_push_constant.intensity = p_settings.intensity * Math_PI;
- ssil.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from);
- ssil.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0;
- ssil.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit;
- ssil.gather_push_constant.neg_inv_radius = -1.0 / ssil.gather_push_constant.radius;
- ssil.gather_push_constant.normal_rejection_amount = p_settings.normal_rejection;
-
- ssil.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_screen_size.x) * (p_settings.quarter_screen_size.y) * 255);
- ssil.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target;
-
- ssil.gather_push_constant.quality = MAX(0, p_settings.quality - 1);
- ssil.gather_push_constant.size_multiplier = p_settings.half_size ? 2 : 1;
-
- if (p_invalidate_uniform_sets) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 0;
- u.append_id(default_mipmap_sampler);
- u.append_id(p_diffuse);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 1;
- u.append_id(ssil.projection_uniform_buffer);
- uniforms.push_back(u);
- }
- r_projection_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 3);
- }
-
- if (p_invalidate_uniform_sets) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 0;
- u.append_id(default_sampler);
- u.append_id(p_depth_mipmaps_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.append_id(p_normal_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 2;
- u.append_id(ss_effects.gather_constants_buffer);
- uniforms.push_back(u);
- }
- r_gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 0);
- }
-
- if (p_invalidate_uniform_sets) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 0;
- u.append_id(p_ssil_pong);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
- u.binding = 1;
- u.append_id(default_sampler);
- u.append_id(p_importance_map);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 2;
- u.append_id(ssil.importance_map_load_counter);
- uniforms.push_back(u);
- }
- r_importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 2), 1);
- }
-
- if (p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) {
- RD::get_singleton()->draw_command_begin_label("Generate Importance Map");
- ssil.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
- ssil.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
- ssil.importance_map_push_constant.intensity = p_settings.intensity * Math_PI;
- //base pass
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_BASE]);
- gather_ssil(compute_list, p_ssil_pong_slices, p_edges_slices, p_settings, true, r_gather_uniform_set, r_importance_map_uniform_set, r_projection_uniform_set);
- //generate importance map
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GENERATE_IMPORTANCE_MAP]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_pong), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- // process Importance Map A
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPA]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map_pong), 1);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- // process Importance Map B
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPB]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map_pong), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssil.counter_uniform_set, 2);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- RD::get_singleton()->draw_command_end_label(); // Importance Map
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_ADAPTIVE]);
- } else {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER]);
- }
-
- gather_ssil(compute_list, p_ssil_slices, p_edges_slices, p_settings, false, r_gather_uniform_set, r_importance_map_uniform_set, r_projection_uniform_set);
- RD::get_singleton()->draw_command_end_label(); //Gather
- }
-
- {
- RD::get_singleton()->draw_command_begin_label("Edge Aware Blur");
- ssil.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness;
- ssil.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
- ssil.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
-
- int blur_passes = p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW ? p_settings.blur_passes : 1;
-
- for (int pass = 0; pass < blur_passes; pass++) {
- int blur_pipeline = SSIL_BLUR_PASS;
- if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) {
- blur_pipeline = SSIL_BLUR_PASS_SMART;
- if (pass < blur_passes - 2) {
- blur_pipeline = SSIL_BLUR_PASS_WIDE;
- }
- }
-
- for (int i = 0; i < 4; i++) {
- if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
- continue;
- }
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[blur_pipeline]);
- if (pass % 2 == 0) {
- if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_slices[i]), 0);
- } else {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ssil_slices[i], ss_effects.mirror_sampler), 0);
- }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ssil_pong_slices[i]), 1);
- } else {
- if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_pong_slices[i]), 0);
- } else {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ssil_pong_slices[i], ss_effects.mirror_sampler), 0);
- }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ssil_slices[i]), 1);
- }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_edges_slices[i]), 2);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.blur_push_constant, sizeof(SSILBlurPushConstant));
-
- int x_groups = (p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1));
- int y_groups = (p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, x_groups, y_groups, 1);
- if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) {
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- }
- }
- }
-
- RD::get_singleton()->draw_command_end_label(); // Blur
- }
-
- {
- RD::get_singleton()->draw_command_begin_label("Interleave Buffers");
- ssil.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness;
- ssil.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x;
- ssil.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y;
- ssil.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2);
-
- int interleave_pipeline = SSIL_INTERLEAVE_HALF;
- if (p_settings.quality == RS::ENV_SSIL_QUALITY_LOW) {
- interleave_pipeline = SSIL_INTERLEAVE;
- } else if (p_settings.quality >= RS::ENV_SSIL_QUALITY_MEDIUM) {
- interleave_pipeline = SSIL_INTERLEAVE_SMART;
- }
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[interleave_pipeline]);
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_destination), 0);
-
- if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW && p_settings.blur_passes % 2 == 0) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil), 1);
- } else {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_pong), 1);
- }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_edges), 2);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.interleave_push_constant, sizeof(SSILInterleavePushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.full_screen_size.x, p_settings.full_screen_size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- RD::get_singleton()->draw_command_end_label(); // Interleave
- }
-
- RD::get_singleton()->draw_command_end_label(); // SSIL
-
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER);
-
- int zero[1] = { 0 };
- RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
-}
-
void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) {
roughness_limiter.push_constant.screen_size[0] = p_size.x;
roughness_limiter.push_constant.screen_size[1] = p_size.y;
@@ -1304,12 +380,12 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
{
Vector<String> FSR_upscale_modes;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
// MoltenVK does not support some of the operations used by the normal mode of FSR. Fallback works just fine though.
FSR_upscale_modes.push_back("\n#define MODE_FSR_UPSCALE_FALLBACK\n");
#else
// Everyone else can use normal mode when available.
- if (RD::get_singleton()->get_device_capabilities()->supports_fsr_half_float) {
+ if (RD::get_singleton()->has_feature(RD::SUPPORTS_FSR_HALF_FLOAT)) {
FSR_upscale_modes.push_back("\n#define MODE_FSR_UPSCALE_NORMAL\n");
} else {
FSR_upscale_modes.push_back("\n#define MODE_FSR_UPSCALE_FALLBACK\n");
@@ -1358,154 +434,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
}
if (!prefer_raster_effects) {
- {
- // Initialize depth buffer for screen space effects
- Vector<String> downsampler_modes;
- downsampler_modes.push_back("\n");
- downsampler_modes.push_back("\n#define USE_HALF_SIZE\n");
- downsampler_modes.push_back("\n#define GENERATE_MIPS\n");
- downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define USE_HALF_SIZE\n");
- downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n");
- downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n#define USE_HALF_SIZE\n");
- downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define GENERATE_FULL_MIPS");
-
- ss_effects.downsample_shader.initialize(downsampler_modes);
-
- ss_effects.downsample_shader_version = ss_effects.downsample_shader.version_create();
-
- for (int i = 0; i < SS_EFFECTS_MAX; i++) {
- ss_effects.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, i));
- }
-
- ss_effects.gather_constants_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSEffectsGatherConstants));
- SSEffectsGatherConstants gather_constants;
-
- const int sub_pass_count = 5;
- for (int pass = 0; pass < 4; pass++) {
- for (int subPass = 0; subPass < sub_pass_count; subPass++) {
- int a = pass;
- int b = subPass;
-
- int spmap[5]{ 0, 1, 4, 3, 2 };
- b = spmap[subPass];
-
- float ca, sa;
- float angle0 = (float(a) + float(b) / float(sub_pass_count)) * Math_PI * 0.5f;
-
- ca = Math::cos(angle0);
- sa = Math::sin(angle0);
-
- float scale = 1.0f + (a - 1.5f + (b - (sub_pass_count - 1.0f) * 0.5f) / float(sub_pass_count)) * 0.07f;
-
- gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 0] = scale * ca;
- gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 1] = scale * -sa;
- gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 2] = -scale * sa;
- gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 3] = -scale * ca;
- }
- }
-
- RD::get_singleton()->buffer_update(ss_effects.gather_constants_buffer, 0, sizeof(SSEffectsGatherConstants), &gather_constants);
- }
-
- {
- // Initialize ssao
-
- RD::SamplerState sampler;
- sampler.mag_filter = RD::SAMPLER_FILTER_NEAREST;
- sampler.min_filter = RD::SAMPLER_FILTER_NEAREST;
- sampler.mip_filter = RD::SAMPLER_FILTER_NEAREST;
- sampler.repeat_u = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
- sampler.repeat_v = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
- sampler.repeat_w = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
- sampler.max_lod = 4;
-
- ss_effects.mirror_sampler = RD::get_singleton()->sampler_create(sampler);
-
- uint32_t pipeline = 0;
- {
- Vector<String> ssao_modes;
-
- ssao_modes.push_back("\n");
- ssao_modes.push_back("\n#define SSAO_BASE\n");
- ssao_modes.push_back("\n#define ADAPTIVE\n");
-
- ssao.gather_shader.initialize(ssao_modes);
-
- ssao.gather_shader_version = ssao.gather_shader.version_create();
-
- for (int i = 0; i <= SSAO_GATHER_ADAPTIVE; i++) {
- ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.gather_shader.version_get_shader(ssao.gather_shader_version, i));
- pipeline++;
- }
- }
- {
- Vector<String> ssao_modes;
- ssao_modes.push_back("\n#define GENERATE_MAP\n");
- ssao_modes.push_back("\n#define PROCESS_MAPA\n");
- ssao_modes.push_back("\n#define PROCESS_MAPB\n");
-
- ssao.importance_map_shader.initialize(ssao_modes);
-
- ssao.importance_map_shader_version = ssao.importance_map_shader.version_create();
-
- for (int i = SSAO_GENERATE_IMPORTANCE_MAP; i <= SSAO_PROCESS_IMPORTANCE_MAPB; i++) {
- ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, i - SSAO_GENERATE_IMPORTANCE_MAP));
-
- pipeline++;
- }
- ssao.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t));
- int zero[1] = { 0 };
- RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero);
- RD::get_singleton()->set_resource_name(ssao.importance_map_load_counter, "Importance Map Load Counter");
-
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 0;
- u.append_id(ssao.importance_map_load_counter);
- uniforms.push_back(u);
- }
- ssao.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 2), 2);
- RD::get_singleton()->set_resource_name(ssao.counter_uniform_set, "Load Counter Uniform Set");
- }
- {
- Vector<String> ssao_modes;
- ssao_modes.push_back("\n#define MODE_NON_SMART\n");
- ssao_modes.push_back("\n#define MODE_SMART\n");
- ssao_modes.push_back("\n#define MODE_WIDE\n");
-
- ssao.blur_shader.initialize(ssao_modes);
-
- ssao.blur_shader_version = ssao.blur_shader.version_create();
-
- for (int i = SSAO_BLUR_PASS; i <= SSAO_BLUR_PASS_WIDE; i++) {
- ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.blur_shader.version_get_shader(ssao.blur_shader_version, i - SSAO_BLUR_PASS));
-
- pipeline++;
- }
- }
- {
- Vector<String> ssao_modes;
- ssao_modes.push_back("\n#define MODE_NON_SMART\n");
- ssao_modes.push_back("\n#define MODE_SMART\n");
- ssao_modes.push_back("\n#define MODE_HALF\n");
-
- ssao.interleave_shader.initialize(ssao_modes);
-
- ssao.interleave_shader_version = ssao.interleave_shader.version_create();
- for (int i = SSAO_INTERLEAVE; i <= SSAO_INTERLEAVE_HALF; i++) {
- ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, i - SSAO_INTERLEAVE));
- RD::get_singleton()->set_resource_name(ssao.pipelines[pipeline], "Interleave Pipeline " + itos(i));
- pipeline++;
- }
- }
-
- ERR_FAIL_COND(pipeline != SSAO_MAX);
- }
- }
-
- if (!prefer_raster_effects) {
// Initialize roughness limiter
Vector<String> shader_modes;
shader_modes.push_back("");
@@ -1518,81 +446,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
}
if (!prefer_raster_effects) {
- Vector<String> specular_modes;
- specular_modes.push_back("\n#define MODE_MERGE\n");
- specular_modes.push_back("\n#define MODE_MERGE\n#define MODE_SSR\n");
- specular_modes.push_back("\n");
- specular_modes.push_back("\n#define MODE_SSR\n");
-
- specular_merge.shader.initialize(specular_modes);
-
- specular_merge.shader_version = specular_merge.shader.version_create();
-
- //use additive
-
- RD::PipelineColorBlendState::Attachment ba;
- ba.enable_blend = true;
- ba.src_color_blend_factor = RD::BLEND_FACTOR_ONE;
- ba.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
- ba.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
- ba.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
- ba.color_blend_op = RD::BLEND_OP_ADD;
- ba.alpha_blend_op = RD::BLEND_OP_ADD;
-
- RD::PipelineColorBlendState blend_additive;
- blend_additive.attachments.push_back(ba);
-
- for (int i = 0; i < SPECULAR_MERGE_MAX; i++) {
- RD::PipelineColorBlendState blend_state;
- if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR) {
- blend_state = blend_additive;
- } else {
- blend_state = RD::PipelineColorBlendState::create_disabled();
- }
- specular_merge.pipelines[i].setup(specular_merge.shader.version_get_shader(specular_merge.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
- }
- }
-
- if (!prefer_raster_effects) {
- {
- Vector<String> ssr_modes;
- ssr_modes.push_back("\n");
- ssr_modes.push_back("\n#define MODE_ROUGH\n");
-
- ssr.shader.initialize(ssr_modes);
-
- ssr.shader_version = ssr.shader.version_create();
-
- for (int i = 0; i < SCREEN_SPACE_REFLECTION_MAX; i++) {
- ssr.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssr.shader.version_get_shader(ssr.shader_version, i));
- }
- }
-
- {
- Vector<String> ssr_filter_modes;
- ssr_filter_modes.push_back("\n");
- ssr_filter_modes.push_back("\n#define VERTICAL_PASS\n");
-
- ssr_filter.shader.initialize(ssr_filter_modes);
-
- ssr_filter.shader_version = ssr_filter.shader.version_create();
-
- for (int i = 0; i < SCREEN_SPACE_REFLECTION_FILTER_MAX; i++) {
- ssr_filter.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssr_filter.shader.version_get_shader(ssr_filter.shader_version, i));
- }
- }
-
- {
- Vector<String> ssr_scale_modes;
- ssr_scale_modes.push_back("\n");
-
- ssr_scale.shader.initialize(ssr_scale_modes);
-
- ssr_scale.shader_version = ssr_scale.shader.version_create();
-
- ssr_scale.pipeline = RD::get_singleton()->compute_pipeline_create(ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0));
- }
-
{
Vector<String> sss_modes;
sss_modes.push_back("\n#define USE_11_SAMPLES\n");
@@ -1607,79 +460,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
sss.pipelines[i] = RD::get_singleton()->compute_pipeline_create(sss.shader.version_get_shader(sss.shader_version, i));
}
}
-
- {
- Vector<String> ssil_modes;
- ssil_modes.push_back("\n");
- ssil_modes.push_back("\n#define SSIL_BASE\n");
- ssil_modes.push_back("\n#define ADAPTIVE\n");
-
- ssil.gather_shader.initialize(ssil_modes);
-
- ssil.gather_shader_version = ssil.gather_shader.version_create();
-
- for (int i = SSIL_GATHER; i <= SSIL_GATHER_ADAPTIVE; i++) {
- ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.gather_shader.version_get_shader(ssil.gather_shader_version, i));
- }
- ssil.projection_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSILProjectionUniforms));
- }
-
- {
- Vector<String> ssil_modes;
- ssil_modes.push_back("\n#define GENERATE_MAP\n");
- ssil_modes.push_back("\n#define PROCESS_MAPA\n");
- ssil_modes.push_back("\n#define PROCESS_MAPB\n");
-
- ssil.importance_map_shader.initialize(ssil_modes);
-
- ssil.importance_map_shader_version = ssil.importance_map_shader.version_create();
-
- for (int i = SSIL_GENERATE_IMPORTANCE_MAP; i <= SSIL_PROCESS_IMPORTANCE_MAPB; i++) {
- ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, i - SSIL_GENERATE_IMPORTANCE_MAP));
- }
- ssil.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t));
- int zero[1] = { 0 };
- RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero);
- RD::get_singleton()->set_resource_name(ssil.importance_map_load_counter, "Importance Map Load Counter");
-
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 0;
- u.append_id(ssil.importance_map_load_counter);
- uniforms.push_back(u);
- }
- ssil.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, 2), 2);
- RD::get_singleton()->set_resource_name(ssil.counter_uniform_set, "Load Counter Uniform Set");
- }
- {
- Vector<String> ssil_modes;
- ssil_modes.push_back("\n#define MODE_NON_SMART\n");
- ssil_modes.push_back("\n#define MODE_SMART\n");
- ssil_modes.push_back("\n#define MODE_WIDE\n");
-
- ssil.blur_shader.initialize(ssil_modes);
-
- ssil.blur_shader_version = ssil.blur_shader.version_create();
- for (int i = SSIL_BLUR_PASS; i <= SSIL_BLUR_PASS_WIDE; i++) {
- ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.blur_shader.version_get_shader(ssil.blur_shader_version, i - SSIL_BLUR_PASS));
- }
- }
-
- {
- Vector<String> ssil_modes;
- ssil_modes.push_back("\n#define MODE_NON_SMART\n");
- ssil_modes.push_back("\n#define MODE_SMART\n");
- ssil_modes.push_back("\n#define MODE_HALF\n");
-
- ssil.interleave_shader.initialize(ssil_modes);
-
- ssil.interleave_shader_version = ssil.interleave_shader.version_create();
- for (int i = SSIL_INTERLEAVE; i <= SSIL_INTERLEAVE_HALF; i++) {
- ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.interleave_shader.version_get_shader(ssil.interleave_shader_version, i - SSIL_INTERLEAVE));
- }
- }
}
{
@@ -1751,27 +531,8 @@ EffectsRD::~EffectsRD() {
luminance_reduce.shader.version_free(luminance_reduce.shader_version);
}
if (!prefer_raster_effects) {
- specular_merge.shader.version_free(specular_merge.shader_version);
- ss_effects.downsample_shader.version_free(ss_effects.downsample_shader_version);
- ssao.blur_shader.version_free(ssao.blur_shader_version);
- ssao.gather_shader.version_free(ssao.gather_shader_version);
- ssao.interleave_shader.version_free(ssao.interleave_shader_version);
- ssao.importance_map_shader.version_free(ssao.importance_map_shader_version);
- ssil.blur_shader.version_free(ssil.blur_shader_version);
- ssil.gather_shader.version_free(ssil.gather_shader_version);
- ssil.interleave_shader.version_free(ssil.interleave_shader_version);
- ssil.importance_map_shader.version_free(ssil.importance_map_shader_version);
roughness_limiter.shader.version_free(roughness_limiter.shader_version);
- ssr.shader.version_free(ssr.shader_version);
- ssr_filter.shader.version_free(ssr_filter.shader_version);
- ssr_scale.shader.version_free(ssr_scale.shader_version);
sss.shader.version_free(sss.shader_version);
-
- RD::get_singleton()->free(ss_effects.mirror_sampler);
- RD::get_singleton()->free(ss_effects.gather_constants_buffer);
- RD::get_singleton()->free(ssao.importance_map_load_counter);
- RD::get_singleton()->free(ssil.importance_map_load_counter);
- RD::get_singleton()->free(ssil.projection_uniform_buffer);
}
sort.shader.version_free(sort.shader_version);
}
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index 76627a8d7d..f8b5ecb920 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -37,20 +37,7 @@
#include "servers/rendering/renderer_rd/shaders/luminance_reduce.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/roughness_limiter.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/ssao_blur.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/ssao_interleave.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/ssil.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/ssil_blur.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/ssil_interleave.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/taa_resolve.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
@@ -142,231 +129,6 @@ private:
PipelineCacheRD pipelines[LUMINANCE_REDUCE_FRAGMENT_MAX];
} luminance_reduce_raster;
- struct SSEffectsDownsamplePushConstant {
- float pixel_size[2];
- float z_far;
- float z_near;
- uint32_t orthogonal;
- float radius_sq;
- uint32_t pad[2];
- };
-
- enum SSEffectsMode {
- SS_EFFECTS_DOWNSAMPLE,
- SS_EFFECTS_DOWNSAMPLE_HALF_RES,
- SS_EFFECTS_DOWNSAMPLE_MIPMAP,
- SS_EFFECTS_DOWNSAMPLE_MIPMAP_HALF_RES,
- SS_EFFECTS_DOWNSAMPLE_HALF,
- SS_EFFECTS_DOWNSAMPLE_HALF_RES_HALF,
- SS_EFFECTS_DOWNSAMPLE_FULL_MIPS,
- SS_EFFECTS_MAX
- };
-
- struct SSEffectsGatherConstants {
- float rotation_matrices[80]; //5 vec4s * 4
- };
-
- struct SSEffects {
- SSEffectsDownsamplePushConstant downsample_push_constant;
- SsEffectsDownsampleShaderRD downsample_shader;
- RID downsample_shader_version;
- RID downsample_uniform_set;
- bool used_half_size_last_frame = false;
- bool used_mips_last_frame = false;
- bool used_full_mips_last_frame = false;
-
- RID gather_constants_buffer;
-
- RID mirror_sampler;
-
- RID pipelines[SS_EFFECTS_MAX];
- } ss_effects;
-
- enum SSAOMode {
- SSAO_GATHER,
- SSAO_GATHER_BASE,
- SSAO_GATHER_ADAPTIVE,
- SSAO_GENERATE_IMPORTANCE_MAP,
- SSAO_PROCESS_IMPORTANCE_MAPA,
- SSAO_PROCESS_IMPORTANCE_MAPB,
- SSAO_BLUR_PASS,
- SSAO_BLUR_PASS_SMART,
- SSAO_BLUR_PASS_WIDE,
- SSAO_INTERLEAVE,
- SSAO_INTERLEAVE_SMART,
- SSAO_INTERLEAVE_HALF,
- SSAO_MAX
- };
-
- struct SSAOGatherPushConstant {
- int32_t screen_size[2];
- int pass;
- int quality;
-
- float half_screen_pixel_size[2];
- int size_multiplier;
- float detail_intensity;
-
- float NDC_to_view_mul[2];
- float NDC_to_view_add[2];
-
- float pad[2];
- float half_screen_pixel_size_x025[2];
-
- float radius;
- float intensity;
- float shadow_power;
- float shadow_clamp;
-
- float fade_out_mul;
- float fade_out_add;
- float horizon_angle_threshold;
- float inv_radius_near_limit;
-
- uint32_t is_orthogonal;
- float neg_inv_radius;
- float load_counter_avg_div;
- float adaptive_sample_limit;
-
- int32_t pass_coord_offset[2];
- float pass_uv_offset[2];
- };
-
- struct SSAOImportanceMapPushConstant {
- float half_screen_pixel_size[2];
- float intensity;
- float power;
- };
-
- struct SSAOBlurPushConstant {
- float edge_sharpness;
- float pad;
- float half_screen_pixel_size[2];
- };
-
- struct SSAOInterleavePushConstant {
- float inv_sharpness;
- uint32_t size_modifier;
- float pixel_size[2];
- };
-
- struct SSAO {
- SSAOGatherPushConstant gather_push_constant;
- SsaoShaderRD gather_shader;
- RID gather_shader_version;
-
- SSAOImportanceMapPushConstant importance_map_push_constant;
- SsaoImportanceMapShaderRD importance_map_shader;
- RID importance_map_shader_version;
- RID importance_map_load_counter;
- RID counter_uniform_set;
-
- SSAOBlurPushConstant blur_push_constant;
- SsaoBlurShaderRD blur_shader;
- RID blur_shader_version;
-
- SSAOInterleavePushConstant interleave_push_constant;
- SsaoInterleaveShaderRD interleave_shader;
- RID interleave_shader_version;
-
- RID pipelines[SSAO_MAX];
- } ssao;
-
- enum SSILMode {
- SSIL_GATHER,
- SSIL_GATHER_BASE,
- SSIL_GATHER_ADAPTIVE,
- SSIL_GENERATE_IMPORTANCE_MAP,
- SSIL_PROCESS_IMPORTANCE_MAPA,
- SSIL_PROCESS_IMPORTANCE_MAPB,
- SSIL_BLUR_PASS,
- SSIL_BLUR_PASS_SMART,
- SSIL_BLUR_PASS_WIDE,
- SSIL_INTERLEAVE,
- SSIL_INTERLEAVE_SMART,
- SSIL_INTERLEAVE_HALF,
- SSIL_MAX
- };
-
- struct SSILGatherPushConstant {
- int32_t screen_size[2];
- int pass;
- int quality;
-
- float half_screen_pixel_size[2];
- float half_screen_pixel_size_x025[2];
-
- float NDC_to_view_mul[2];
- float NDC_to_view_add[2];
-
- float pad2[2];
- float z_near;
- float z_far;
-
- float radius;
- float intensity;
- int size_multiplier;
- int pad;
-
- float fade_out_mul;
- float fade_out_add;
- float normal_rejection_amount;
- float inv_radius_near_limit;
-
- uint32_t is_orthogonal;
- float neg_inv_radius;
- float load_counter_avg_div;
- float adaptive_sample_limit;
-
- int32_t pass_coord_offset[2];
- float pass_uv_offset[2];
- };
-
- struct SSILImportanceMapPushConstant {
- float half_screen_pixel_size[2];
- float intensity;
- float pad;
- };
-
- struct SSILBlurPushConstant {
- float edge_sharpness;
- float pad;
- float half_screen_pixel_size[2];
- };
-
- struct SSILInterleavePushConstant {
- float inv_sharpness;
- uint32_t size_modifier;
- float pixel_size[2];
- };
-
- struct SSILProjectionUniforms {
- float inv_last_frame_projection_matrix[16];
- };
-
- struct SSIL {
- SSILGatherPushConstant gather_push_constant;
- SsilShaderRD gather_shader;
- RID gather_shader_version;
- RID projection_uniform_buffer;
-
- SSILImportanceMapPushConstant importance_map_push_constant;
- SsilImportanceMapShaderRD importance_map_shader;
- RID importance_map_shader_version;
- RID importance_map_load_counter;
- RID counter_uniform_set;
-
- SSILBlurPushConstant blur_push_constant;
- SsilBlurShaderRD blur_shader;
- RID blur_shader_version;
-
- SSILInterleavePushConstant interleave_push_constant;
- SsilInterleaveShaderRD interleave_shader;
- RID interleave_shader_version;
-
- RID pipelines[SSIL_MAX];
- } ssil;
-
struct RoughnessLimiterPushConstant {
int32_t screen_size[2];
float curve;
@@ -381,101 +143,6 @@ private:
} roughness_limiter;
- enum SpecularMergeMode {
- SPECULAR_MERGE_ADD,
- SPECULAR_MERGE_SSR,
- SPECULAR_MERGE_ADDITIVE_ADD,
- SPECULAR_MERGE_ADDITIVE_SSR,
- SPECULAR_MERGE_MAX
- };
-
- /* Specular merge must be done using raster, rather than compute
- * because it must continue the existing color buffer
- */
-
- struct SpecularMerge {
- SpecularMergeShaderRD shader;
- RID shader_version;
- PipelineCacheRD pipelines[SPECULAR_MERGE_MAX];
-
- } specular_merge;
-
- enum ScreenSpaceReflectionMode {
- SCREEN_SPACE_REFLECTION_NORMAL,
- SCREEN_SPACE_REFLECTION_ROUGH,
- SCREEN_SPACE_REFLECTION_MAX,
- };
-
- struct ScreenSpaceReflectionPushConstant {
- float proj_info[4];
-
- int32_t screen_size[2];
- float camera_z_near;
- float camera_z_far;
-
- int32_t num_steps;
- float depth_tolerance;
- float distance_fade;
- float curve_fade_in;
-
- uint32_t orthogonal;
- float filter_mipmap_levels;
- uint32_t use_half_res;
- uint8_t metallic_mask[4];
-
- float projection[16];
- };
-
- struct ScreenSpaceReflection {
- ScreenSpaceReflectionPushConstant push_constant;
- ScreenSpaceReflectionShaderRD shader;
- RID shader_version;
- RID pipelines[SCREEN_SPACE_REFLECTION_MAX];
-
- } ssr;
-
- struct ScreenSpaceReflectionFilterPushConstant {
- float proj_info[4];
-
- uint32_t orthogonal;
- float edge_tolerance;
- int32_t increment;
- uint32_t pad;
-
- int32_t screen_size[2];
- uint32_t vertical;
- uint32_t steps;
- };
- enum {
- SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL,
- SCREEN_SPACE_REFLECTION_FILTER_VERTICAL,
- SCREEN_SPACE_REFLECTION_FILTER_MAX,
- };
-
- struct ScreenSpaceReflectionFilter {
- ScreenSpaceReflectionFilterPushConstant push_constant;
- ScreenSpaceReflectionFilterShaderRD shader;
- RID shader_version;
- RID pipelines[SCREEN_SPACE_REFLECTION_FILTER_MAX];
- } ssr_filter;
-
- struct ScreenSpaceReflectionScalePushConstant {
- int32_t screen_size[2];
- float camera_z_near;
- float camera_z_far;
-
- uint32_t orthogonal;
- uint32_t filter;
- uint32_t pad[2];
- };
-
- struct ScreenSpaceReflectionScale {
- ScreenSpaceReflectionScalePushConstant push_constant;
- ScreenSpaceReflectionScaleShaderRD shader;
- RID shader_version;
- RID pipeline;
- } ssr_scale;
-
struct SubSurfaceScatteringPushConstant {
int32_t screen_size[2];
float camera_z_far;
@@ -559,9 +226,6 @@ private:
RID _get_uniform_set_from_image(RID p_texture);
RID _get_uniform_set_from_texture(RID p_texture, 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);
- RID _get_compute_uniform_set_from_image_pair(RID p_texture, RID p_texture2);
public:
bool get_prefer_raster_effects();
@@ -572,56 +236,8 @@ public:
void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
void luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
- struct SSAOSettings {
- float radius = 1.0;
- float intensity = 2.0;
- float power = 1.5;
- float detail = 0.5;
- float horizon = 0.06;
- float sharpness = 0.98;
-
- RS::EnvironmentSSAOQuality quality = RS::ENV_SSAO_QUALITY_MEDIUM;
- bool half_size = false;
- float adaptive_target = 0.5;
- int blur_passes = 2;
- float fadeout_from = 50.0;
- float fadeout_to = 300.0;
-
- Size2i full_screen_size = Size2i();
- Size2i half_screen_size = Size2i();
- Size2i quarter_screen_size = Size2i();
- };
-
- struct SSILSettings {
- float radius = 1.0;
- float intensity = 2.0;
- float sharpness = 0.98;
- float normal_rejection = 1.0;
-
- RS::EnvironmentSSILQuality quality = RS::ENV_SSIL_QUALITY_MEDIUM;
- bool half_size = true;
- float adaptive_target = 0.5;
- int blur_passes = 4;
- float fadeout_from = 50.0;
- float fadeout_to = 300.0;
-
- Size2i full_screen_size = Size2i();
- Size2i half_screen_size = Size2i();
- Size2i quarter_screen_size = Size2i();
- };
-
- void downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection);
-
- void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set);
- void generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set);
-
- void gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set);
- void screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_importance_map, RID p_importance_map_pong, RID p_edges, const Vector<RID> p_edges_slices, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set, RID &r_projection_uniform_set);
-
void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve);
- void screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera);
- void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection);
void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality);
void sort_buffer(RID p_uniform_set, int p_size);
diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp
new file mode 100644
index 0000000000..2a6c96480e
--- /dev/null
+++ b/servers/rendering/renderer_rd/environment/fog.cpp
@@ -0,0 +1,128 @@
+/*************************************************************************/
+/* fog.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "fog.h"
+
+using namespace RendererRD;
+
+Fog *Fog::singleton = nullptr;
+
+Fog::Fog() {
+ singleton = this;
+}
+
+Fog::~Fog() {
+ singleton = nullptr;
+}
+
+/* FOG VOLUMES */
+
+RID Fog::fog_volume_allocate() {
+ return fog_volume_owner.allocate_rid();
+}
+
+void Fog::fog_volume_initialize(RID p_rid) {
+ fog_volume_owner.initialize_rid(p_rid, FogVolume());
+}
+
+void Fog::fog_free(RID p_rid) {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid);
+ fog_volume->dependency.deleted_notify(p_rid);
+ fog_volume_owner.free(p_rid);
+}
+
+void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND(!fog_volume);
+
+ if (p_shape == fog_volume->shape) {
+ return;
+ }
+
+ fog_volume->shape = p_shape;
+ fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
+}
+
+void Fog::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND(!fog_volume);
+
+ fog_volume->extents = p_extents;
+ fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
+}
+
+void Fog::fog_volume_set_material(RID p_fog_volume, RID p_material) {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND(!fog_volume);
+ fog_volume->material = p_material;
+}
+
+RID Fog::fog_volume_get_material(RID p_fog_volume) const {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND_V(!fog_volume, RID());
+
+ return fog_volume->material;
+}
+
+RS::FogVolumeShape Fog::fog_volume_get_shape(RID p_fog_volume) const {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND_V(!fog_volume, RS::FOG_VOLUME_SHAPE_BOX);
+
+ return fog_volume->shape;
+}
+
+AABB Fog::fog_volume_get_aabb(RID p_fog_volume) const {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND_V(!fog_volume, AABB());
+
+ switch (fog_volume->shape) {
+ case RS::FOG_VOLUME_SHAPE_ELLIPSOID:
+ case RS::FOG_VOLUME_SHAPE_CONE:
+ case RS::FOG_VOLUME_SHAPE_CYLINDER:
+ case RS::FOG_VOLUME_SHAPE_BOX: {
+ AABB aabb;
+ aabb.position = -fog_volume->extents;
+ aabb.size = fog_volume->extents * 2;
+ return aabb;
+ }
+ default: {
+ // Need some size otherwise will get culled
+ return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
+ }
+ }
+
+ return AABB();
+}
+
+Vector3 Fog::fog_volume_get_extents(RID p_fog_volume) const {
+ const FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND_V(!fog_volume, Vector3());
+ return fog_volume->extents;
+}
diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h
new file mode 100644
index 0000000000..55a01c3616
--- /dev/null
+++ b/servers/rendering/renderer_rd/environment/fog.h
@@ -0,0 +1,83 @@
+/*************************************************************************/
+/* fog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef FOG_RD_H
+#define FOG_RD_H
+
+#include "core/templates/local_vector.h"
+#include "core/templates/rid_owner.h"
+#include "servers/rendering/environment/renderer_fog.h"
+#include "servers/rendering/storage/utilities.h"
+
+namespace RendererRD {
+
+class Fog : public RendererFog {
+public:
+ struct FogVolume {
+ RID material;
+ Vector3 extents = Vector3(1, 1, 1);
+
+ RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX;
+
+ Dependency dependency;
+ };
+
+private:
+ static Fog *singleton;
+
+ mutable RID_Owner<FogVolume, true> fog_volume_owner;
+
+public:
+ static Fog *get_singleton() { return singleton; }
+
+ Fog();
+ ~Fog();
+
+ /* FOG VOLUMES */
+
+ FogVolume *get_fog_volume(RID p_rid) { return fog_volume_owner.get_or_null(p_rid); };
+ bool owns_fog_volume(RID p_rid) { return fog_volume_owner.owns(p_rid); };
+
+ virtual RID fog_volume_allocate() override;
+ virtual void fog_volume_initialize(RID p_rid) override;
+ virtual void fog_free(RID p_rid) override;
+
+ virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override;
+ virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override;
+ virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override;
+ virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override;
+ RID fog_volume_get_material(RID p_fog_volume) const;
+ virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override;
+ Vector3 fog_volume_get_extents(RID p_fog_volume) const;
+};
+
+} // namespace RendererRD
+
+#endif // !FOG_RD_H
diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp
index f3be4a7085..6361b9b18f 100644
--- a/servers/rendering/renderer_rd/environment/gi.cpp
+++ b/servers/rendering/renderer_rd/environment/gi.cpp
@@ -33,7 +33,6 @@
#include "core/config/project_settings.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
@@ -110,6 +109,7 @@ void GI::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xfo
Vector<Vector<uint8_t>> s;
s.push_back(p_distance_field);
voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s);
+ RD::get_singleton()->set_resource_name(voxel_gi->sdf_texture, "VoxelGI SDF Texture");
}
#if 0
{
@@ -123,6 +123,7 @@ void GI::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xfo
tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM);
tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT);
voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(voxel_gi->sdf_texture, "VoxelGI SDF Texture");
}
RID shared_tex;
{
@@ -184,7 +185,7 @@ void GI::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xfo
voxel_gi->version++;
voxel_gi->data_version++;
- voxel_gi->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ voxel_gi->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
AABB GI::voxel_gi_get_bounds(RID p_voxel_gi) const {
@@ -312,19 +313,6 @@ float GI::voxel_gi_get_normal_bias(RID p_voxel_gi) const {
return voxel_gi->normal_bias;
}
-void GI::voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- voxel_gi->anisotropy_strength = p_strength;
-}
-
-float GI::voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
- return voxel_gi->anisotropy_strength;
-}
-
void GI::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) {
VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
ERR_FAIL_COND(!voxel_gi);
@@ -390,7 +378,6 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_gi->storage;
gi = p_gi;
num_cascades = p_env->sdfgi_cascades;
min_cell_size = p_env->sdfgi_min_cell_size;
@@ -417,29 +404,38 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world
RD::TextureFormat tf_render = tf_sdf;
tf_render.format = RD::DATA_FORMAT_R16_UINT;
render_albedo = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ RD::get_singleton()->set_resource_name(render_albedo, "VoxelGI Render Albedo");
tf_render.format = RD::DATA_FORMAT_R32_UINT;
render_emission = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ RD::get_singleton()->set_resource_name(render_emission, "VoxelGI Render Emission");
render_emission_aniso = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ RD::get_singleton()->set_resource_name(render_emission_aniso, "VoxelGI Render Emission Aniso");
tf_render.format = RD::DATA_FORMAT_R8_UNORM; //at least its easy to visualize
for (int i = 0; i < 8; i++) {
render_occlusion[i] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ RD::get_singleton()->set_resource_name(render_occlusion[i], String("VoxelGI Render Occlusion ") + itos(i));
}
tf_render.format = RD::DATA_FORMAT_R32_UINT;
render_geom_facing = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ RD::get_singleton()->set_resource_name(render_geom_facing, "VoxelGI Render Geometry Facing");
tf_render.format = RD::DATA_FORMAT_R8G8B8A8_UINT;
render_sdf[0] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ RD::get_singleton()->set_resource_name(render_sdf[0], "VoxelGI Render SDF 0");
render_sdf[1] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ RD::get_singleton()->set_resource_name(render_sdf[1], "VoxelGI Render SDF 1");
tf_render.width /= 2;
tf_render.height /= 2;
tf_render.depth /= 2;
render_sdf_half[0] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ RD::get_singleton()->set_resource_name(render_sdf_half[0], "VoxelGI Render SDF Half 0");
render_sdf_half[1] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ RD::get_singleton()->set_resource_name(render_sdf_half[1], "VoxelGI Render SDF Half 1");
}
RD::TextureFormat tf_occlusion = tf_sdf;
@@ -480,7 +476,9 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world
tf_probe_average.texture_type = RD::TEXTURE_TYPE_2D;
lightprobe_history_scroll = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView());
+ RD::get_singleton()->set_resource_name(lightprobe_history_scroll, "VoxelGI LightProbe History Scroll");
lightprobe_average_scroll = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView());
+ RD::get_singleton()->set_resource_name(lightprobe_average_scroll, "VoxelGI LightProbe Average Scroll");
{
//octahedral lightprobes
@@ -494,6 +492,7 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world
//lightprobe texture is an octahedral texture
lightprobe_data = RD::get_singleton()->texture_create(tf_octprobes, RD::TextureView());
+ RD::get_singleton()->set_resource_name(lightprobe_data, "VoxelGI LightProbe Data");
RD::TextureView tv;
tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
lightprobe_texture = RD::get_singleton()->texture_create_shared(tv, lightprobe_data);
@@ -507,11 +506,13 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world
tf_ambient.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
//lightprobe texture is an octahedral texture
ambient_texture = RD::get_singleton()->texture_create(tf_ambient, RD::TextureView());
+ RD::get_singleton()->set_resource_name(ambient_texture, "VoxelGI Ambient Texture");
}
cascades_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES);
occlusion_data = RD::get_singleton()->texture_create(tf_occlusion, RD::TextureView());
+ RD::get_singleton()->set_resource_name(occlusion_data, "VoxelGI Occlusion Data");
{
RD::TextureView tv;
tv.format_override = RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16;
@@ -524,11 +525,15 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world
/* 3D Textures */
cascade.sdf_tex = RD::get_singleton()->texture_create(tf_sdf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(cascade.sdf_tex, "VoxelGI Cascade SDF Texture");
cascade.light_data = RD::get_singleton()->texture_create(tf_light, RD::TextureView());
+ RD::get_singleton()->set_resource_name(cascade.light_data, "VoxelGI Cascade Light Data");
cascade.light_aniso_0_tex = RD::get_singleton()->texture_create(tf_aniso0, RD::TextureView());
+ RD::get_singleton()->set_resource_name(cascade.light_aniso_0_tex, "VoxelGI Cascade Light Aniso 0 Texture");
cascade.light_aniso_1_tex = RD::get_singleton()->texture_create(tf_aniso1, RD::TextureView());
+ RD::get_singleton()->set_resource_name(cascade.light_aniso_1_tex, "VoxelGI Cascade Light Aniso 1 Texture");
{
RD::TextureView tv;
@@ -555,9 +560,11 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world
/* Probe History */
cascade.lightprobe_history_tex = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView());
+ RD::get_singleton()->set_resource_name(cascade.lightprobe_history_tex, "VoxelGI Cascade LightProbe History Texture");
RD::get_singleton()->texture_clear(cascade.lightprobe_history_tex, Color(0, 0, 0, 0), 0, 1, 0, tf_probe_history.array_layers); //needs to be cleared for average to work
cascade.lightprobe_average_tex = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView());
+ RD::get_singleton()->set_resource_name(cascade.lightprobe_average_tex, "VoxelGI Cascade LightProbe Average Texture");
RD::get_singleton()->texture_clear(cascade.lightprobe_average_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); //needs to be cleared for average to work
/* Buffers */
@@ -803,7 +810,8 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world
uniforms.push_back(u);
}
- cascade.sdf_direct_light_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.direct_light.version_get_shader(gi->sdfgi_shader.direct_light_shader, 0), 0);
+ cascade.sdf_direct_light_static_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.direct_light.version_get_shader(gi->sdfgi_shader.direct_light_shader, SDFGIShader::DIRECT_LIGHT_MODE_STATIC), 0);
+ cascade.sdf_direct_light_dynamic_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.direct_light.version_get_shader(gi->sdfgi_shader.direct_light_shader, SDFGIShader::DIRECT_LIGHT_MODE_DYNAMIC), 0);
}
//preprocess initialize uniform set
@@ -1252,7 +1260,7 @@ void GI::SDFGI::update_light() {
}
cascades[i].all_dynamic_lights_dirty = false;
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_dynamic_uniform_set, 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DirectLightPushConstant));
RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0);
}
@@ -1287,7 +1295,7 @@ void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSk
if (p_env->background == RS::ENV_BG_CLEAR_COLOR) {
push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR;
- Color c = storage->get_default_clear_color().srgb_to_linear();
+ Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear();
push_constant.sky_color[0] = c.r;
push_constant.sky_color[1] = c.g;
push_constant.sky_color[2] = c.b;
@@ -1636,7 +1644,7 @@ void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, con
}
for (uint32_t v = 0; v < p_view_count; v++) {
- RendererStorageRD::store_camera(p_camera_with_transforms[v], scene_data.projection[v]);
+ RendererRD::MaterialStorage::store_camera(p_camera_with_transforms[v], scene_data.projection[v]);
}
RD::get_singleton()->buffer_update(debug_probes_scene_data_ubo, 0, sizeof(SDFGIShader::DebugProbesSceneData), &scene_data, RD::BARRIER_MASK_RASTER);
@@ -2406,7 +2414,7 @@ void GI::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_co
dl_push_constant.cascade = p_cascade_indices[i];
if (dl_push_constant.light_count > 0) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cc.sdf_direct_light_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cc.sdf_direct_light_static_uniform_set, 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &dl_push_constant, sizeof(SDFGIShader::DirectLightPushConstant));
RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cc.solid_cell_dispatch_buffer, 0);
}
@@ -2459,6 +2467,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(texture, "VoxelGI Instance Texture");
RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, levels.size(), 0, 1);
@@ -2588,6 +2597,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
dtf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
dmap.texture = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(dmap.texture, "VoxelGI Instance DMap Texture");
if (dynamic_maps.size() == 0) {
// Render depth for first one.
@@ -2595,6 +2605,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
dtf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D16_UNORM, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
dtf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
dmap.fb_depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(dmap.fb_depth, "VoxelGI Instance DMap FB Depth");
}
//just use depth as-is
@@ -2602,13 +2613,17 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
dmap.depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(dmap.depth, "VoxelGI Instance DMap Depth");
if (dynamic_maps.size() == 0) {
dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(dmap.albedo, "VoxelGI Instance DMap Albedo");
dmap.normal = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(dmap.normal, "VoxelGI Instance DMap Normal");
dmap.orm = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(dmap.orm, "VoxelGI Instance DMap ORM");
Vector<RID> fb;
fb.push_back(dmap.albedo);
@@ -3218,12 +3233,10 @@ GI::~GI() {
singleton = nullptr;
}
-void GI::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky) {
+void GI::init(RendererSceneSkyRD *p_sky) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_storage;
-
/* GI */
{
@@ -3339,7 +3352,11 @@ void GI::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky) {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 0;
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE));
+ if (p_sky->sky_use_cubemap_array) {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE));
+ } else {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE));
+ }
uniforms.push_back(u);
}
{
@@ -3359,37 +3376,40 @@ void GI::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky) {
//calculate tables
String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> gi_modes;
+
gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_VOXEL_GI
gi_modes.push_back("\n#define USE_SDFGI\n"); // MODE_SDFGI
gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_COMBINED
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_HALF_RES_VOXEL_GI
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n"); // MODE_HALF_RES_SDFGI
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_HALF_RES_COMBINED
-
- gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_VOXEL_GI_MULTIVIEW
- gi_modes.push_back("\n#define USE_SDFGI\n#define USE_MULTIVIEW\n"); // MODE_SDFGI_MULTIVIEW
- gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_COMBINED_MULTIVIEW
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_HALF_RES_VOXEL_GI_MULTIVIEW
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n#define USE_MULTIVIEW\n"); // MODE_HALF_RES_SDFGI_MULTIVIEW
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_HALF_RES_COMBINED_MULTIVIEW
shader.initialize(gi_modes, defines);
+ shader_version = shader.version_create();
- if (!RendererCompositorRD::singleton->is_xr_enabled()) {
- shader.set_variant_enabled(MODE_VOXEL_GI_MULTIVIEW, false);
- shader.set_variant_enabled(MODE_SDFGI_MULTIVIEW, false);
- shader.set_variant_enabled(MODE_COMBINED_MULTIVIEW, false);
- shader.set_variant_enabled(MODE_HALF_RES_VOXEL_GI_MULTIVIEW, false);
- shader.set_variant_enabled(MODE_HALF_RES_SDFGI_MULTIVIEW, false);
- shader.set_variant_enabled(MODE_HALF_RES_COMBINED_MULTIVIEW, false);
+ Vector<RD::PipelineSpecializationConstant> specialization_constants;
+
+ {
+ RD::PipelineSpecializationConstant sc;
+ sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
+ sc.constant_id = 0; // SHADER_SPECIALIZATION_HALF_RES
+ sc.bool_value = false;
+ specialization_constants.push_back(sc);
+
+ sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
+ sc.constant_id = 1; // SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX
+ sc.bool_value = false;
+ specialization_constants.push_back(sc);
+
+ sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
+ sc.constant_id = 2; // SHADER_SPECIALIZATION_USE_VRS
+ sc.bool_value = false;
+ specialization_constants.push_back(sc);
}
- shader_version = shader.version_create();
- for (int i = 0; i < MODE_MAX; i++) {
- if (shader.is_variant_enabled(i)) {
- pipelines[i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, i));
- } else {
- pipelines[i] = RID();
+ for (int v = 0; v < SHADER_SPECIALIZATION_VARIATIONS; v++) {
+ specialization_constants.ptrw()[0].bool_value = (v & SHADER_SPECIALIZATION_HALF_RES) ? true : false;
+ specialization_constants.ptrw()[1].bool_value = (v & SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX) ? true : false;
+ specialization_constants.ptrw()[2].bool_value = (v & SHADER_SPECIALIZATION_USE_VRS) ? true : false;
+ for (int i = 0; i < MODE_MAX; i++) {
+ pipelines[v][i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, i), specialization_constants);
}
}
@@ -3581,25 +3601,17 @@ void GI::RenderBuffersGI::free() {
}
if (ambient_buffer.is_valid()) {
- if (view_count == 1) {
- // Only one view? then these are copies of our main buffers.
- ambient_view[0] = RID();
- reflection_view[0] = RID();
- } else {
- // Multiple views? free our slices.
- for (uint32_t v = 0; v < view_count; v++) {
- RD::get_singleton()->free(ambient_view[v]);
- RD::get_singleton()->free(reflection_view[v]);
- ambient_view[v] = RID();
- reflection_view[v] = RID();
- }
- }
-
- // Now we can free our buffers.
RD::get_singleton()->free(ambient_buffer);
RD::get_singleton()->free(reflection_buffer);
ambient_buffer = RID();
reflection_buffer = RID();
+
+ // these are automatically freed when we free the textures, so just reset..
+ for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {
+ ambient_slice[v] = RID();
+ reflection_slice[v] = RID();
+ }
+
view_count = 0;
}
@@ -3609,7 +3621,7 @@ void GI::RenderBuffersGI::free() {
}
}
-void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) {
+void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
@@ -3623,17 +3635,14 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
if (rb->rbgi.ambient_buffer.is_null() || rb->rbgi.using_half_size_gi != half_resolution || rb->rbgi.view_count != p_view_count) {
// Free our old buffer if applicable
if (rb->rbgi.ambient_buffer.is_valid()) {
- if (rb->rbgi.view_count > 1) {
- for (uint32_t v = 0; v < rb->rbgi.view_count; v++) {
- RD::get_singleton()->free(rb->rbgi.ambient_view[v]);
- RD::get_singleton()->free(rb->rbgi.reflection_view[v]);
- }
- }
RD::get_singleton()->free(rb->rbgi.ambient_buffer);
RD::get_singleton()->free(rb->rbgi.reflection_buffer);
- }
- print_line("Allocating GI buffers"); // TESTING REMOVE BEFORE MERGING
+ for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {
+ rb->rbgi.ambient_slice[v] = RID();
+ rb->rbgi.reflection_slice[v] = RID();
+ }
+ }
// Remember the view count we're using
rb->rbgi.view_count = p_view_count;
@@ -3656,18 +3665,19 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
}
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
rb->rbgi.ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->rbgi.ambient_buffer, "GI Ambient Buffer");
rb->rbgi.reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->rbgi.reflection_buffer, "GI Reflection Buffer");
rb->rbgi.using_half_size_gi = half_resolution;
if (p_view_count == 1) {
- // Just one view? Copy our buffers
- rb->rbgi.ambient_view[0] = rb->rbgi.ambient_buffer;
- rb->rbgi.reflection_view[0] = rb->rbgi.reflection_buffer;
+ // Just copy, we don't need to create slices
+ rb->rbgi.ambient_slice[0] = rb->rbgi.ambient_buffer;
+ rb->rbgi.reflection_slice[0] = rb->rbgi.reflection_buffer;
} else {
- // More then one view? Create slices for each view
for (uint32_t v = 0; v < p_view_count; v++) {
- rb->rbgi.ambient_view[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->rbgi.ambient_buffer, v, 0);
- rb->rbgi.reflection_view[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->rbgi.reflection_buffer, v, 0);
+ rb->rbgi.ambient_slice[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->rbgi.ambient_buffer, v, 0);
+ rb->rbgi.reflection_slice[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->rbgi.reflection_buffer, v, 0);
}
}
}
@@ -3681,7 +3691,7 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
}
for (uint32_t v = 0; v < p_view_count; v++) {
- RendererStorageRD::store_camera(p_projections[v].inverse(), scene_data.inv_projection[v]);
+ RendererRD::MaterialStorage::store_camera(p_projections[v].inverse(), scene_data.inv_projection[v]);
scene_data.eye_offset[v][0] = p_eye_offsets[v].x;
scene_data.eye_offset[v][1] = p_eye_offsets[v].y;
scene_data.eye_offset[v][2] = p_eye_offsets[v].z;
@@ -3689,7 +3699,7 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
}
// Note that we will be ignoring the origin of this transform.
- RendererStorageRD::store_transform(p_cam_transform, scene_data.cam_transform);
+ RendererRD::MaterialStorage::store_transform(p_cam_transform, scene_data.cam_transform);
scene_data.screen_size[0] = rb->internal_width;
scene_data.screen_size[1] = rb->internal_height;
@@ -3700,29 +3710,45 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
// Now compute the contents of our buffers.
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true);
- for (uint32_t v = 0; v < p_view_count; v++) {
- // Render each eye seperately.
- // We need to look into whether we can make our compute shader use Multiview but not sure that works or makes a difference..
+ // Render each eye separately.
+ // We need to look into whether we can make our compute shader use Multiview but not sure that works or makes a difference..
- // setup our push constant
+ // setup our push constant
- PushConstant push_constant;
+ PushConstant push_constant;
- push_constant.view_index = v;
- push_constant.orthogonal = p_projections[v].is_orthogonal();
- push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size());
- push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH;
+ push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size());
+ push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH;
- push_constant.z_near = p_projections[v].get_z_near();
- push_constant.z_far = p_projections[v].get_z_far();
+ // these should be the same for all views
+ push_constant.orthogonal = p_projections[0].is_orthogonal();
+ push_constant.z_near = p_projections[0].get_z_near();
+ push_constant.z_far = p_projections[0].get_z_far();
- push_constant.proj_info[0] = -2.0f / (rb->internal_width * p_projections[v].matrix[0][0]);
- push_constant.proj_info[1] = -2.0f / (rb->internal_height * p_projections[v].matrix[1][1]);
- push_constant.proj_info[2] = (1.0f - p_projections[v].matrix[0][2]) / p_projections[v].matrix[0][0];
- push_constant.proj_info[3] = (1.0f + p_projections[v].matrix[1][2]) / p_projections[v].matrix[1][1];
+ // these are only used if we have 1 view, else we use the projections in our scene data
+ push_constant.proj_info[0] = -2.0f / (rb->internal_width * p_projections[0].matrix[0][0]);
+ push_constant.proj_info[1] = -2.0f / (rb->internal_height * p_projections[0].matrix[1][1]);
+ push_constant.proj_info[2] = (1.0f - p_projections[0].matrix[0][2]) / p_projections[0].matrix[0][0];
+ push_constant.proj_info[3] = (1.0f + p_projections[0].matrix[1][2]) / p_projections[0].matrix[1][1];
- bool use_sdfgi = rb->sdfgi != nullptr;
- bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0;
+ bool use_sdfgi = rb->sdfgi != nullptr;
+ bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0;
+
+ uint32_t pipeline_specialization = 0;
+ if (rb->rbgi.using_half_size_gi) {
+ pipeline_specialization |= SHADER_SPECIALIZATION_HALF_RES;
+ }
+ if (p_view_count > 1) {
+ pipeline_specialization |= SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX;
+ }
+ if (p_vrs_slices[0].is_valid()) {
+ pipeline_specialization |= SHADER_SPECIALIZATION_USE_VRS;
+ }
+
+ Mode mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_VOXEL_GI);
+
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ push_constant.view_index = v;
// setup our uniform set
if (rb->rbgi.uniform_set[v].is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->rbgi.uniform_set[v])) {
@@ -3809,7 +3835,7 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 9;
- u.append_id(rb->rbgi.ambient_view[v]);
+ u.append_id(rb->rbgi.ambient_slice[v]);
uniforms.push_back(u);
}
@@ -3817,7 +3843,7 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 10;
- u.append_id(rb->rbgi.reflection_view[v]);
+ u.append_id(rb->rbgi.reflection_slice[v]);
uniforms.push_back(u);
}
@@ -3843,7 +3869,7 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 13;
- u.append_id(p_normal_roughness_views[v]);
+ u.append_id(p_normal_roughness_slices[v]);
uniforms.push_back(u);
}
{
@@ -3884,27 +3910,19 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
u.append_id(rb->rbgi.scene_data_ubo);
uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 19;
+ RID buffer = p_vrs_slices[v].is_valid() ? p_vrs_slices[v] : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_VRS);
+ u.append_id(buffer);
+ uniforms.push_back(u);
+ }
rb->rbgi.uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, 0), 0);
}
- Mode mode;
-
- if (p_view_count > 1) {
- if (rb->rbgi.using_half_size_gi) {
- mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED_MULTIVIEW : (use_sdfgi ? MODE_HALF_RES_SDFGI_MULTIVIEW : MODE_HALF_RES_VOXEL_GI_MULTIVIEW);
- } else {
- mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED_MULTIVIEW : (use_sdfgi ? MODE_SDFGI_MULTIVIEW : MODE_VOXEL_GI_MULTIVIEW);
- }
- } else {
- if (rb->rbgi.using_half_size_gi) {
- mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_VOXEL_GI);
- } else {
- mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_VOXEL_GI);
- }
- }
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[mode]);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[pipeline_specialization][mode]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->rbgi.uniform_set[v], 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
@@ -3923,7 +3941,6 @@ void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_v
RID GI::voxel_gi_instance_create(RID p_base) {
VoxelGIInstance voxel_gi;
voxel_gi.gi = this;
- voxel_gi.storage = storage;
voxel_gi.probe = p_base;
RID rid = voxel_gi_instance_owner.make_rid(voxel_gi);
return rid;
diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h
index b6ecfe42ea..e90e01196d 100644
--- a/servers/rendering/renderer_rd/environment/gi.h
+++ b/servers/rendering/renderer_rd/environment/gi.h
@@ -37,7 +37,6 @@
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/environment/gi.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl.gen.h"
@@ -47,8 +46,8 @@
#include "servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/storage/utilities.h"
// Forward declare RenderDataRD and RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
struct RenderDataRD;
@@ -84,16 +83,13 @@ public:
bool interior = false;
bool use_two_bounces = false;
- float anisotropy_strength = 0.5;
-
uint32_t version = 1;
uint32_t data_version = 1;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
private:
- RendererStorageRD *storage = nullptr;
static GI *singleton;
/* VOXEL GI STORAGE */
@@ -418,9 +414,6 @@ public:
virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override;
virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override;
- virtual void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) override;
- virtual float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const override;
-
virtual uint32_t voxel_gi_get_version(RID p_probe) const override;
uint32_t voxel_gi_get_data_version(RID p_probe);
@@ -435,7 +428,6 @@ public:
struct VoxelGIInstance {
// access to our containers
- RendererStorageRD *storage = nullptr;
GI *gi = nullptr;
RID probe;
@@ -549,7 +541,8 @@ public:
Vector3i dirty_regions; //(0,0,0 is not dirty, negative is refresh from the end, DIRTY_ALL is refresh all.
RID sdf_store_uniform_set;
- RID sdf_direct_light_uniform_set;
+ RID sdf_direct_light_static_uniform_set;
+ RID sdf_direct_light_dynamic_uniform_set;
RID scroll_uniform_set;
RID scroll_occlusion_uniform_set;
RID integrate_uniform_set;
@@ -559,7 +552,6 @@ public:
};
// access to our containers
- RendererStorageRD *storage = nullptr;
GI *gi = nullptr;
// used for rendering (voxelization)
@@ -669,13 +661,13 @@ public:
/* GI buffers */
RID ambient_buffer;
+ RID ambient_slice[RendererSceneRender::MAX_RENDER_VIEWS];
RID reflection_buffer;
- RID ambient_view[RendererSceneRender::MAX_RENDER_VIEWS];
- RID reflection_view[RendererSceneRender::MAX_RENDER_VIEWS];
- RID uniform_set[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID reflection_slice[RendererSceneRender::MAX_RENDER_VIEWS];
bool using_half_size_gi = false;
uint32_t view_count = 1;
+ RID uniform_set[RendererSceneRender::MAX_RENDER_VIEWS];
RID scene_data_ubo;
void free();
@@ -738,55 +730,52 @@ public:
};
struct PushConstant {
- uint32_t view_index;
uint32_t max_voxel_gi_instances;
uint32_t high_quality_vct;
uint32_t orthogonal;
+ uint32_t view_index;
float proj_info[4];
float z_near;
float z_far;
- float pad1;
float pad2;
+ float pad3;
};
RID sdfgi_ubo;
+
enum Mode {
MODE_VOXEL_GI,
MODE_SDFGI,
MODE_COMBINED,
- MODE_HALF_RES_VOXEL_GI,
- MODE_HALF_RES_SDFGI,
- MODE_HALF_RES_COMBINED,
-
- MODE_VOXEL_GI_MULTIVIEW,
- MODE_SDFGI_MULTIVIEW,
- MODE_COMBINED_MULTIVIEW,
- MODE_HALF_RES_VOXEL_GI_MULTIVIEW,
- MODE_HALF_RES_SDFGI_MULTIVIEW,
- MODE_HALF_RES_COMBINED_MULTIVIEW,
-
MODE_MAX
};
+ enum ShaderSpecializations {
+ SHADER_SPECIALIZATION_HALF_RES = 1 << 0,
+ SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX = 1 << 1,
+ SHADER_SPECIALIZATION_USE_VRS = 1 << 2,
+ SHADER_SPECIALIZATION_VARIATIONS = 8,
+ };
+
RID default_voxel_gi_buffer;
bool half_resolution = false;
GiShaderRD shader;
RID shader_version;
- RID pipelines[MODE_MAX];
+ RID pipelines[SHADER_SPECIALIZATION_VARIATIONS][MODE_MAX];
GI();
~GI();
- void init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky);
+ void init(RendererSceneSkyRD *p_sky);
void free();
SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size);
void setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render);
- void process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render);
+ void process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render);
RID voxel_gi_instance_create(RID p_base);
void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform);
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 c7048289c8..d6613a60cc 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -30,6 +30,7 @@
#include "render_forward_clustered.h"
#include "core/config/project_settings.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
@@ -65,6 +66,13 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
}
specular = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ if (view_count == 1) {
+ specular_views[0] = specular;
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ specular_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), specular, v, 0);
+ }
+ }
if (msaa == RS::VIEWPORT_MSAA_DISABLED) {
{
@@ -79,6 +87,14 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
specular_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ if (view_count == 1) {
+ specular_msaa_views[0] = specular_msaa;
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ specular_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), specular_msaa, v, 0);
+ }
+ }
+
{
Vector<RID> fb;
fb.push_back(specular_msaa);
@@ -170,29 +186,26 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi()
}
void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
+ // note, slices are freed automatically when the parent texture is freed so we just clear them.
+ for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {
+ color_views[v] = RID();
+ depth_views[v] = RID();
+ specular_views[v] = RID();
+ specular_msaa_views[v] = RID();
+ color_msaa_views[v] = RID();
+ depth_msaa_views[v] = RID();
+ normal_roughness_views[v] = RID();
+ normal_roughness_msaa_views[v] = RID();
+ voxelgi_views[v] = RID();
+ voxelgi_msaa_views[v] = RID();
+ vrs_views[v] = RID();
+ }
+
if (voxelgi_buffer != RID()) {
RD::get_singleton()->free(voxelgi_buffer);
voxelgi_buffer = RID();
- if (view_count == 1) {
- voxelgi_views[0] = RID();
- } else {
- for (uint32_t v = 0; v < view_count; v++) {
- RD::get_singleton()->free(voxelgi_views[v]);
- voxelgi_views[v] = RID();
- }
- }
-
if (voxelgi_buffer_msaa.is_valid()) {
- if (view_count == 1) {
- voxelgi_msaa_views[0] = RID();
- } else {
- for (uint32_t v = 0; v < view_count; v++) {
- RD::get_singleton()->free(voxelgi_msaa_views[v]);
- voxelgi_msaa_views[v] = RID();
- }
- }
-
RD::get_singleton()->free(voxelgi_buffer_msaa);
voxelgi_buffer_msaa = RID();
}
@@ -201,35 +214,11 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
}
if (color_msaa.is_valid()) {
- if (view_count == 1) {
- color_views[0] = RID();
- color_msaa_views[0] = RID();
- } else {
- for (uint32_t v = 0; v < view_count; v++) {
- RD::get_singleton()->free(color_views[v]);
- RD::get_singleton()->free(color_msaa_views[v]);
- color_views[v] = RID();
- color_msaa_views[v] = RID();
- }
- }
-
RD::get_singleton()->free(color_msaa);
color_msaa = RID();
}
if (depth_msaa.is_valid()) {
- if (view_count == 1) {
- depth_views[0] = RID();
- depth_msaa_views[0] = RID();
- } else {
- for (uint32_t v = 0; v < view_count; v++) {
- RD::get_singleton()->free(depth_views[v]);
- RD::get_singleton()->free(depth_msaa_views[v]);
- depth_views[v] = RID();
- depth_msaa_views[v] = RID();
- }
- }
-
RD::get_singleton()->free(depth_msaa);
depth_msaa = RID();
}
@@ -244,33 +233,17 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
}
color = RID();
+ color_only_fb = RID();
depth = RID();
depth_fb = RID();
color_framebuffers.clear(); // Color pass framebuffers are freed automatically by their dependency relations
if (normal_roughness_buffer.is_valid()) {
- if (view_count == 1) {
- normal_roughness_views[0] = RID();
- } else {
- for (uint32_t v = 0; v < view_count; v++) {
- RD::get_singleton()->free(normal_roughness_views[v]);
- normal_roughness_views[v] = RID();
- }
- }
-
RD::get_singleton()->free(normal_roughness_buffer);
normal_roughness_buffer = RID();
if (normal_roughness_buffer_msaa.is_valid()) {
- if (view_count == 1) {
- normal_roughness_msaa_views[0] = RID();
- } else {
- for (uint32_t v = 0; v < view_count; v++) {
- RD::get_singleton()->free(normal_roughness_msaa_views[v]);
- normal_roughness_msaa_views[v] = RID();
- }
- }
RD::get_singleton()->free(normal_roughness_buffer_msaa);
normal_roughness_buffer_msaa = RID();
}
@@ -293,11 +266,12 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
}
}
-void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count) {
+void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count, RID p_vrs_texture) {
clear();
msaa = p_msaa;
use_taa = p_use_taa;
+ vrs = p_vrs_texture;
width = p_width;
height = p_height;
@@ -306,11 +280,26 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
color = p_color_buffer;
depth = p_depth_buffer;
+ if (vrs.is_valid()) {
+ if (view_count == 1) {
+ // just reuse
+ vrs_views[0] = vrs;
+ } else {
+ // create slices
+ for (uint32_t v = 0; v < view_count; v++) {
+ vrs_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), vrs, v, 0);
+ }
+ }
+ }
+
if (p_msaa == RS::VIEWPORT_MSAA_DISABLED) {
{
Vector<RID> fb;
fb.push_back(p_color_buffer);
fb.push_back(depth);
+ if (vrs.is_valid()) {
+ fb.push_back(vrs);
+ }
color_only_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
}
@@ -345,7 +334,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
color_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
- tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
+ tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
depth_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -370,6 +359,9 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
Vector<RID> fb;
fb.push_back(color_msaa);
fb.push_back(depth_msaa);
+ if (vrs.is_valid()) {
+ fb.push_back(vrs);
+ }
color_only_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
}
@@ -408,6 +400,10 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_color_pass_fb(
fb.push_back(use_msaa ? depth_msaa : depth);
+ if (vrs.is_valid()) {
+ fb.push_back(vrs);
+ }
+
int v_count = (p_color_pass_flags & COLOR_PASS_FLAG_MULTIVIEW) ? view_count : 1;
RID framebuffer = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, v_count);
color_framebuffers[p_color_pass_flags] = framebuffer;
@@ -435,7 +431,7 @@ void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferData
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
} else {
tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
@@ -448,7 +444,7 @@ void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferData
fb.push_back(rb->normal_roughness_buffer);
rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, rb->view_count);
} else {
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
tf.samples = rb->texture_samples;
rb->normal_roughness_buffer_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -812,15 +808,15 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
CameraMatrix projection = correction * p_render_data->cam_projection;
//store camera into ubo
- RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix);
- RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
- RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
- RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
+ RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix);
+ RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
for (uint32_t v = 0; v < p_render_data->view_count; v++) {
projection = correction * p_render_data->view_projection[v];
- RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
- RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x;
scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y;
@@ -836,10 +832,10 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
scene_state.ubo.pancake_shadows = p_pancake_shadows;
- RendererStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);
scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;
@@ -934,7 +930,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);
sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
- RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
@@ -1005,15 +1001,15 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
CameraMatrix prev_projection = prev_correction * p_render_data->prev_cam_projection;
//store camera into ubo
- RendererStorageRD::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix);
- RendererStorageRD::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix);
- RendererStorageRD::store_transform(p_render_data->prev_cam_transform, scene_state.prev_ubo.inv_view_matrix);
- RendererStorageRD::store_transform(p_render_data->prev_cam_transform.affine_inverse(), scene_state.prev_ubo.view_matrix);
+ RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix);
+ RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->prev_cam_transform, scene_state.prev_ubo.inv_view_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->prev_cam_transform.affine_inverse(), scene_state.prev_ubo.view_matrix);
for (uint32_t v = 0; v < p_render_data->view_count; v++) {
prev_projection = prev_correction * p_render_data->view_projection[v];
- RendererStorageRD::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix_view[v]);
- RendererStorageRD::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix_view[v]);
}
scene_state.prev_ubo.taa_jitter[0] = p_render_data->prev_taa_jitter.x;
scene_state.prev_ubo.taa_jitter[1] = p_render_data->prev_taa_jitter.y;
@@ -1069,11 +1065,11 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i
}
if (inst->store_transform_cache) {
- RendererStorageRD::store_transform(inst->transform, instance_data.transform);
- RendererStorageRD::store_transform(inst->prev_transform, instance_data.prev_transform);
+ RendererRD::MaterialStorage::store_transform(inst->transform, instance_data.transform);
+ RendererRD::MaterialStorage::store_transform(inst->prev_transform, instance_data.prev_transform);
} else {
- RendererStorageRD::store_transform(Transform3D(), instance_data.transform);
- RendererStorageRD::store_transform(Transform3D(), instance_data.prev_transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), instance_data.transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), instance_data.prev_transform);
}
instance_data.flags = inst->flags_cache;
@@ -1397,7 +1393,7 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps
Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
to_lm = to_lm.inverse().transposed(); //will transform normals
- RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
scene_state.lightmap_ids[i] = p_lightmaps[i];
scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap);
@@ -1672,8 +1668,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
continue_depth = !finish_depth;
}
- RID null_rids[2];
- _pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_views : null_rids, render_buffer ? render_buffer->voxelgi_buffer : RID());
+ RID nullrids[RendererSceneRender::MAX_RENDER_VIEWS];
+ _pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_views : nullrids, render_buffer ? render_buffer->voxelgi_buffer : RID(), render_buffer ? render_buffer->vrs_views : nullrids);
RD::get_singleton()->draw_command_begin_label("Render Opaque Pass");
@@ -1770,9 +1766,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
for (uint32_t v = 0; v < render_buffer->view_count; v++) {
RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa_views[v], render_buffer->color_views[v]);
}
- // TODO mame this do multiview
if (using_separate_specular) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular);
+ for (uint32_t v = 0; v < render_buffer->view_count; v++) {
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa_views[v], render_buffer->specular_views[v]);
+ }
}
}
@@ -1793,12 +1790,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (using_ssr) {
RENDER_TIMESTAMP("Screen-Space Reflections");
RD::get_singleton()->draw_command_begin_label("Process Screen-Space Reflections");
- _process_ssr(p_render_data->render_buffers, color_only_framebuffer, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED);
+ _process_ssr(p_render_data->render_buffers, color_only_framebuffer, render_buffer->normal_roughness_views, render_buffer->specular, render_buffer->specular_views, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->view_projection, p_render_data->view_eye_offset, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED);
RD::get_singleton()->draw_command_end_label();
} else {
//just mix specular back
RENDER_TIMESTAMP("Merge Specular");
- storage->get_effects()->merge_specular(color_only_framebuffer, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID());
+ copy_effects->merge_specular(color_only_framebuffer, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID(), p_render_data->view_count);
}
}
@@ -2189,7 +2186,7 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i
to_bounds.origin = p_bounds.position;
to_bounds.basis.scale(p_bounds.size);
- RendererStorageRD::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds);
+ RendererRD::MaterialStorage::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds);
_setup_environment(&render_data, true, Vector2(1, 1), false, Color());
@@ -2888,7 +2885,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
sdcache->surface_index = p_surface;
if (ginstance->data->dirty_dependencies) {
- storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
+ RSG::utilities->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
}
//shadow
@@ -3131,16 +3128,16 @@ void RenderForwardClustered::_update_dirty_geometry_instances() {
}
}
-void RenderForwardClustered::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) {
+void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) {
switch (p_notification) {
- case RendererStorage::DEPENDENCY_CHANGED_MATERIAL:
- case RendererStorage::DEPENDENCY_CHANGED_MESH:
- case RendererStorage::DEPENDENCY_CHANGED_PARTICLES:
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
- case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: {
+ case Dependency::DEPENDENCY_CHANGED_MATERIAL:
+ case Dependency::DEPENDENCY_CHANGED_MESH:
+ case Dependency::DEPENDENCY_CHANGED_PARTICLES:
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {
static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata);
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
ginstance->instance_count = RendererRD::MeshStorage::get_singleton()->multimesh_get_instances_to_draw(ginstance->data->base);
@@ -3151,12 +3148,12 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(RendererStora
} break;
}
}
-void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) {
+void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
}
RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) {
- RS::InstanceType type = storage->get_base_type(p_base);
+ RS::InstanceType type = RSG::utilities->get_base_type(p_base);
ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
GeometryInstanceForwardClustered *ginstance = geometry_instance_alloc.alloc();
@@ -3420,8 +3417,7 @@ void RenderForwardClustered::_update_shader_quality_settings() {
_base_uniforms_changed(); //also need this
}
-RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) :
- RendererSceneRenderRD(p_storage) {
+RenderForwardClustered::RenderForwardClustered() {
singleton = this;
/* SCENE SHADER */
@@ -3453,7 +3449,7 @@ RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) :
defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n";
}
- scene_shader.init(p_storage, defines);
+ scene_shader.init(defines);
}
render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances");
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
index dd3d14f0a8..6429def4f9 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -36,8 +36,8 @@
#include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/utilities.h"
namespace RendererSceneRenderImplementation {
@@ -107,26 +107,32 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID depth_normal_roughness_voxelgi_fb;
RID color_only_fb;
RID specular_only_fb;
+
+ RID vrs;
+
int width, height;
HashMap<uint32_t, RID> color_framebuffers;
// for multiview
- uint32_t view_count;
+ uint32_t view_count = 1;
RID color_views[RendererSceneRender::MAX_RENDER_VIEWS]; // we should rewrite this so we get access to the existing views in our renderer, something we can address when we reorg this
RID depth_views[RendererSceneRender::MAX_RENDER_VIEWS]; // we should rewrite this so we get access to the existing views in our renderer, something we can address when we reorg this
+ RID specular_views[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID specular_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS];
RID color_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS];
RID depth_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS];
RID normal_roughness_views[RendererSceneRender::MAX_RENDER_VIEWS];
RID normal_roughness_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS];
RID voxelgi_views[RendererSceneRender::MAX_RENDER_VIEWS];
RID voxelgi_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID vrs_views[RendererSceneRender::MAX_RENDER_VIEWS];
RID render_sdfgi_uniform_set;
void ensure_specular();
void ensure_voxelgi();
void ensure_velocity();
void clear();
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count);
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count, RID p_vrs_texture);
RID get_color_pass_fb(uint32_t p_color_pass_flags);
~RenderBufferDataForwardClustered();
@@ -536,12 +542,12 @@ class RenderForwardClustered : public RendererSceneRenderRD {
AABB aabb;
bool use_dynamic_gi = false;
- bool use_baked_light = false;
+ bool use_baked_light = true;
bool cast_double_sided_shadows = false;
bool mirror = false;
bool dirty_dependencies = false;
- RendererStorage::DependencyTracker dependency_tracker;
+ DependencyTracker dependency_tracker;
};
Data *data = nullptr;
@@ -550,8 +556,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
dirty_list_element(this) {}
};
- static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
- static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker);
SelfList<GeometryInstanceForwardClustered>::List geometry_instance_dirty_list;
@@ -683,7 +689,7 @@ public:
virtual bool free(RID p_rid) override;
- RenderForwardClustered(RendererStorageRD *p_storage);
+ RenderForwardClustered();
~RenderForwardClustered();
};
} // namespace RendererSceneRenderImplementation
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index aada989bcb..1951bfe915 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -520,9 +520,8 @@ SceneShaderForwardClustered::~SceneShaderForwardClustered() {
material_storage->material_free(default_material);
}
-void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const String p_defines) {
+void SceneShaderForwardClustered::init(const String p_defines) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_storage;
{
Vector<String> shader_versions;
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
index ffa3893b6a..1cfe723174 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -32,7 +32,6 @@
#define RSSR_SCENE_SHADER_FC_H
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h"
namespace RendererSceneRenderImplementation {
@@ -42,8 +41,6 @@ private:
static SceneShaderForwardClustered *singleton;
public:
- RendererStorageRD *storage = nullptr;
-
enum ShaderVersion {
SHADER_VERSION_DEPTH_PASS,
SHADER_VERSION_DEPTH_PASS_DP,
@@ -249,7 +246,7 @@ public:
SceneShaderForwardClustered();
~SceneShaderForwardClustered();
- void init(RendererStorageRD *p_storage, const String p_defines);
+ void init(const String p_defines);
void set_default_specialization_constants(const Vector<RD::PipelineSpecializationConstant> &p_constants);
};
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 25acd2e25f..966621c93e 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -87,10 +87,11 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::clear() {
}
}
-void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count) {
+void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count, RID p_vrs_texture) {
clear();
msaa = p_msaa;
+ vrs = p_vrs_texture;
Size2i target_size = RD::get_singleton()->texture_size(p_target_buffer);
@@ -108,6 +109,9 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
Vector<RID> fb;
fb.push_back(p_color_buffer); // 0 - color buffer
fb.push_back(depth); // 1 - depth buffer
+ if (vrs.is_valid()) {
+ fb.push_back(vrs); // 2 - vrs texture
+ }
// Now define our subpasses
Vector<RD::FramebufferPass> passes;
@@ -116,6 +120,9 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
// re-using the same attachments
pass.color_attachments.push_back(0);
pass.depth_attachment = 1;
+ if (vrs.is_valid()) {
+ pass.vrs_attachment = 2;
+ }
// - opaque pass
passes.push_back(pass);
@@ -131,12 +138,13 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
if (!is_scaled) {
// - add blit to 2D pass
- fb.push_back(p_target_buffer); // 2 - target buffer
+ int target_buffer_id = fb.size();
+ fb.push_back(p_target_buffer); // 2/3 - target buffer
RD::FramebufferPass blit_pass;
- blit_pass.color_attachments.push_back(2);
+ blit_pass.color_attachments.push_back(target_buffer_id);
blit_pass.input_attachments.push_back(0);
- passes.push_back(blit_pass);
+ passes.push_back(blit_pass); // this doesn't need VRS
color_fbs[FB_CONFIG_FOUR_SUBPASSES] = RD::get_singleton()->framebuffer_create_multipass(fb, passes, RenderingDevice::INVALID_ID, view_count);
} else {
@@ -179,6 +187,9 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
Vector<RID> fb;
fb.push_back(color_msaa); // 0 - msaa color buffer
fb.push_back(depth_msaa); // 1 - msaa depth buffer
+ if (vrs.is_valid()) {
+ fb.push_back(vrs); // 2 - vrs texture
+ }
// Now define our subpasses
Vector<RD::FramebufferPass> passes;
@@ -187,18 +198,22 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
// re-using the same attachments
pass.color_attachments.push_back(0);
pass.depth_attachment = 1;
+ if (vrs.is_valid()) {
+ pass.vrs_attachment = 2;
+ }
// - opaque pass
passes.push_back(pass);
// - add sky pass
- fb.push_back(color); // 2 - color buffer
+ int color_buffer_id = fb.size();
+ fb.push_back(color); // color buffer
passes.push_back(pass); // without resolve for our 3 + 4 subpass config
{
// but with resolve for our 2 subpass config
Vector<RD::FramebufferPass> two_passes;
two_passes.push_back(pass); // opaque subpass without resolve
- pass.resolve_attachments.push_back(2);
+ pass.resolve_attachments.push_back(color_buffer_id);
two_passes.push_back(pass); // sky subpass with resolve
color_fbs[FB_CONFIG_TWO_SUBPASSES] = RD::get_singleton()->framebuffer_create_multipass(fb, two_passes, RenderingDevice::INVALID_ID, view_count);
@@ -217,10 +232,11 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
if (!is_scaled) {
// - add blit to 2D pass
- fb.push_back(p_target_buffer); // 3 - target buffer
+ int target_buffer_id = fb.size();
+ fb.push_back(p_target_buffer); // target buffer
RD::FramebufferPass blit_pass;
- blit_pass.color_attachments.push_back(3);
- blit_pass.input_attachments.push_back(2);
+ blit_pass.color_attachments.push_back(target_buffer_id);
+ blit_pass.input_attachments.push_back(color_buffer_id);
passes.push_back(blit_pass);
color_fbs[FB_CONFIG_FOUR_SUBPASSES] = RD::get_singleton()->framebuffer_create_multipass(fb, passes, RenderingDevice::INVALID_ID, view_count);
@@ -465,7 +481,7 @@ void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, c
Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
to_lm = to_lm.inverse().transposed(); //will transform normals
- RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
scene_state.lightmap_ids[i] = p_lightmaps[i];
scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap);
@@ -675,8 +691,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
}
- RID null_rids[2];
- _pre_opaque_render(p_render_data, false, false, false, null_rids, RID());
+ RID nullrids[RendererSceneRender::MAX_RENDER_VIEWS];
+ _pre_opaque_render(p_render_data, false, false, false, nullrids, RID(), nullrids);
uint32_t spec_constant_base_flags = 0;
@@ -1534,15 +1550,15 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
CameraMatrix projection = correction * p_render_data->cam_projection;
//store camera into ubo
- RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix);
- RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
- RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
- RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
+ RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix);
+ RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
for (uint32_t v = 0; v < p_render_data->view_count; v++) {
projection = correction * p_render_data->view_projection[v];
- RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
- RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x;
scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y;
@@ -1555,10 +1571,10 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
scene_state.ubo.pancake_shadows = p_pancake_shadows;
- RendererStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);
scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;
@@ -1648,7 +1664,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);
sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
- RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
@@ -1866,9 +1882,9 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
GeometryInstanceForwardMobile::PushConstant push_constant;
if (inst->store_transform_cache) {
- RendererStorageRD::store_transform(inst->transform, push_constant.transform);
+ RendererRD::MaterialStorage::store_transform(inst->transform, push_constant.transform);
} else {
- RendererStorageRD::store_transform(Transform3D(), push_constant.transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), push_constant.transform);
}
push_constant.flags = inst->flags_cache;
@@ -2032,7 +2048,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
/* Geometry instance */
RendererSceneRender::GeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base) {
- RS::InstanceType type = storage->get_base_type(p_base);
+ RS::InstanceType type = RSG::utilities->get_base_type(p_base);
ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
GeometryInstanceForwardMobile *ginstance = geometry_instance_alloc.alloc();
@@ -2373,7 +2389,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
sdcache->surface_index = p_surface;
if (ginstance->data->dirty_dependencies) {
- storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
+ RSG::utilities->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
}
//shadow
@@ -2609,16 +2625,16 @@ void RenderForwardMobile::_update_dirty_geometry_instances() {
}
}
-void RenderForwardMobile::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) {
+void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) {
switch (p_notification) {
- case RendererStorage::DEPENDENCY_CHANGED_MATERIAL:
- case RendererStorage::DEPENDENCY_CHANGED_MESH:
- case RendererStorage::DEPENDENCY_CHANGED_PARTICLES:
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
- case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: {
+ case Dependency::DEPENDENCY_CHANGED_MATERIAL:
+ case Dependency::DEPENDENCY_CHANGED_MESH:
+ case Dependency::DEPENDENCY_CHANGED_PARTICLES:
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {
static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata);
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
ginstance->instance_count = RendererRD::MeshStorage::get_singleton()->multimesh_get_instances_to_draw(ginstance->data->base);
@@ -2629,7 +2645,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(RendererStorage:
} break;
}
}
-void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) {
+void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
}
@@ -2695,8 +2711,7 @@ void RenderForwardMobile::_update_shader_quality_settings() {
_base_uniforms_changed(); //also need this
}
-RenderForwardMobile::RenderForwardMobile(RendererStorageRD *p_storage) :
- RendererSceneRenderRD(p_storage) {
+RenderForwardMobile::RenderForwardMobile() {
singleton = this;
sky.set_texture_format(_render_buffers_get_color_format());
@@ -2728,7 +2743,7 @@ RenderForwardMobile::RenderForwardMobile(RendererStorageRD *p_storage) :
defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n";
}
- scene_shader.init(p_storage, defines);
+ scene_shader.init(defines);
// !BAS! maybe we need a mobile version of this setting?
render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances");
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
index 1b2df0ab9f..bf4a52d466 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -35,7 +35,7 @@
#include "servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/utilities.h"
namespace RendererSceneRenderImplementation {
@@ -131,12 +131,14 @@ protected:
RID depth_msaa;
// RID normal_roughness_buffer_msaa;
+ RID vrs;
+
RID color_fbs[FB_CONFIG_MAX];
int width, height;
uint32_t view_count;
void clear();
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count);
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count, RID p_vrs_texture);
~RenderBufferDataForwardMobile();
};
@@ -591,13 +593,13 @@ protected:
RID material_overlay;
AABB aabb;
- bool use_baked_light = false;
+ bool use_baked_light = true;
bool cast_double_sided_shadows = false;
// bool mirror = false; // !BAS! Does not seem used, we already have this in the main struct
bool dirty_dependencies = false;
- RendererStorage::DependencyTracker dependency_tracker;
+ DependencyTracker dependency_tracker;
};
Data *data = nullptr;
@@ -613,8 +615,8 @@ protected:
public:
virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth) override;
- static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
- static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker);
SelfList<GeometryInstanceForwardMobile>::List geometry_instance_dirty_list;
@@ -668,7 +670,7 @@ public:
virtual bool is_volumetric_supported() const override;
virtual uint32_t get_max_elements() const override;
- RenderForwardMobile(RendererStorageRD *p_storage);
+ RenderForwardMobile();
~RenderForwardMobile();
};
} // namespace RendererSceneRenderImplementation
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index f66ad529de..dd00dc2bf9 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -466,8 +466,7 @@ SceneShaderForwardMobile::SceneShaderForwardMobile() {
singleton = this;
}
-void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p_defines) {
- storage = p_storage;
+void SceneShaderForwardMobile::init(const String p_defines) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
/* SCENE SHADER */
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
index f325d5c0a5..88c2143b09 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
@@ -32,7 +32,6 @@
#define RSSR_SCENE_SHADER_FM_H
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl.gen.h"
namespace RendererSceneRenderImplementation {
@@ -40,7 +39,6 @@ namespace RendererSceneRenderImplementation {
class SceneShaderForwardMobile {
private:
static SceneShaderForwardMobile *singleton;
- RendererStorageRD *storage = nullptr;
public:
enum ShaderVersion {
@@ -207,7 +205,7 @@ public:
Vector<RD::PipelineSpecializationConstant> default_specialization_constants;
- void init(RendererStorageRD *p_storage, const String p_defines);
+ void init(const String p_defines);
void set_default_specialization_constants(const Vector<RD::PipelineSpecializationConstant> &p_constants);
};
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 3c2f3f8a42..7d55be1216 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1581,7 +1581,8 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index,
//light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1));
Rect2i rect((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2);
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
+ RD::InitialAction initial_action = i == 0 ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE;
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, initial_action, i != 3 ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, initial_action, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
CameraMatrix projection;
{
@@ -1670,7 +1671,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh
cc.push_back(Color(1, 1, 1, 1));
Rect2i rect(0, p_shadow_index * 2, state.shadow_texture_size, 2);
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR_REGION, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR_REGION, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
CameraMatrix projection;
projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance);
@@ -2270,10 +2271,9 @@ void RendererCanvasRenderRD::set_time(double p_time) {
void RendererCanvasRenderRD::update() {
}
-RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
+RendererCanvasRenderRD::RendererCanvasRenderRD() {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_storage;
{ //create default samplers
@@ -2432,6 +2432,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
actions.usage_defines["LIGHT"] = "#define LIGHT_SHADER_CODE_USED\n";
+ actions.usage_defines["SPECULAR_SHININESS"] = "#define SPECULAR_SHININESS_USED\n";
actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 04881ce7e6..2ab5a7c831 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -34,15 +34,13 @@
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/shader_compiler.h"
class RendererCanvasRenderRD : public RendererCanvasRender {
- RendererStorageRD *storage = nullptr;
-
enum {
BASE_UNIFORM_SET = 0,
MATERIAL_UNIFORM_SET = 1,
@@ -462,7 +460,7 @@ public:
void set_time(double p_time);
void update();
bool free(RID p_rid);
- RendererCanvasRenderRD(RendererStorageRD *p_storage);
+ RendererCanvasRenderRD();
~RendererCanvasRenderRD();
};
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 759b8690eb..a61172c8f5 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -154,12 +154,14 @@ uint64_t RendererCompositorRD::frame = 1;
void RendererCompositorRD::finalize() {
memdelete(scene);
memdelete(canvas);
- memdelete(storage);
+ memdelete(effects);
+ memdelete(fog);
memdelete(particles_storage);
memdelete(light_storage);
memdelete(mesh_storage);
memdelete(material_storage);
memdelete(texture_storage);
+ memdelete(utilities);
//only need to erase these, the rest are erased by cascade
blit.shader.version_free(blit.shader_version);
@@ -287,28 +289,29 @@ RendererCompositorRD::RendererCompositorRD() {
singleton = this;
+ utilities = memnew(RendererRD::Utilities);
texture_storage = memnew(RendererRD::TextureStorage);
material_storage = memnew(RendererRD::MaterialStorage);
mesh_storage = memnew(RendererRD::MeshStorage);
light_storage = memnew(RendererRD::LightStorage);
particles_storage = memnew(RendererRD::ParticlesStorage);
- storage = memnew(RendererStorageRD);
- canvas = memnew(RendererCanvasRenderRD(storage));
+ fog = memnew(RendererRD::Fog);
+ canvas = memnew(RendererCanvasRenderRD());
back_end = (bool)(int)GLOBAL_GET("rendering/vulkan/rendering/back_end");
uint64_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
if (back_end || textures_per_stage < 48) {
- scene = memnew(RendererSceneRenderImplementation::RenderForwardMobile(storage));
+ scene = memnew(RendererSceneRenderImplementation::RenderForwardMobile());
} else { // back_end == false
// default to our high end renderer
- scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered(storage));
+ scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered());
}
scene->init();
// now we're ready to create our effects,
- storage->init_effects(!scene->_render_buffers_can_be_storage());
+ effects = memnew(EffectsRD(!scene->_render_buffers_can_be_storage()));
}
RendererCompositorRD::~RendererCompositorRD() {
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h
index 12bcfc4684..2be55743fb 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.h
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h
@@ -34,28 +34,32 @@
#include "core/os/os.h"
#include "core/templates/thread_work_pool.h"
#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/effects_rd.h"
+#include "servers/rendering/renderer_rd/environment/fog.h"
#include "servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h"
#include "servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h"
#include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
+#include "servers/rendering/renderer_rd/storage_rd/utilities.h"
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
class RendererCompositorRD : public RendererCompositor {
protected:
UniformSetCacheRD *uniform_set_cache = nullptr;
RendererCanvasRenderRD *canvas = nullptr;
+ RendererRD::Utilities *utilities = nullptr;
RendererRD::LightStorage *light_storage = nullptr;
RendererRD::MaterialStorage *material_storage = nullptr;
RendererRD::MeshStorage *mesh_storage = nullptr;
RendererRD::ParticlesStorage *particles_storage = nullptr;
RendererRD::TextureStorage *texture_storage = nullptr;
- RendererStorageRD *storage = nullptr;
+ RendererRD::Fog *fog = nullptr;
+ EffectsRD *effects = nullptr;
RendererSceneRenderRD *scene = nullptr;
enum BlitMode {
@@ -98,6 +102,7 @@ protected:
static uint64_t frame;
public:
+ RendererUtilities *get_utilities() { return utilities; };
RendererLightStorage *get_light_storage() { return light_storage; }
RendererMaterialStorage *get_material_storage() { return material_storage; }
RendererMeshStorage *get_mesh_storage() { return mesh_storage; }
@@ -107,7 +112,8 @@ public:
ERR_FAIL_NULL_V(scene, nullptr);
return scene->get_gi();
}
- RendererStorage *get_storage() { return storage; }
+ RendererFog *get_fog() { return fog; }
+ EffectsRD *get_effects() { return effects; }
RendererCanvasRender *get_canvas() { return canvas; }
RendererSceneRender *get_scene() { return scene; }
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 90a7394344..73028f38bf 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
#include "renderer_compositor_rd.h"
+#include "servers/rendering/renderer_rd/environment/fog.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
@@ -534,7 +535,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba
return panorama;
} else {
const float bg_energy = env->bg_energy;
- Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? storage->get_default_clear_color() : env->bg_color);
+ Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : env->bg_color);
panorama_color = panorama_color.srgb_to_linear();
panorama_color.r *= bg_energy;
panorama_color.g *= bg_energy;
@@ -759,7 +760,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc
}
atlas->reflections.resize(atlas->count);
for (int i = 0; i < atlas->count; i++) {
- atlas->reflections.write[i].data.update_reflection_data(storage, atlas->size, mipmaps, false, atlas->reflection, i * 6, RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, sky.roughness_layers, _render_buffers_get_color_format());
+ atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, sky.roughness_layers, _render_buffers_get_color_format());
for (int j = 0; j < 6; j++) {
atlas->reflections.write[i].fbs[j] = reflection_probe_create_framebuffer(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j], atlas->depth_buffer);
}
@@ -829,7 +830,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
if (RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {
// Using real time reflections, all roughness is done in one step
- atlas->reflections.write[rpi->atlas_index].data.create_reflection_fast_filter(storage, false);
+ atlas->reflections.write[rpi->atlas_index].data.create_reflection_fast_filter(false);
rpi->rendering = false;
rpi->processing_side = 0;
rpi->processing_layer = 1;
@@ -837,7 +838,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
}
if (rpi->processing_layer > 1) {
- atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(storage, false, 10, rpi->processing_layer, sky.sky_ggx_samples_quality);
+ atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(false, 10, rpi->processing_layer, sky.sky_ggx_samples_quality);
rpi->processing_layer++;
if (rpi->processing_layer == atlas->reflections[rpi->atlas_index].data.layers[0].mipmaps.size()) {
rpi->rendering = false;
@@ -848,7 +849,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
return false;
} else {
- atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(storage, false, rpi->processing_side, rpi->processing_layer, sky.sky_ggx_samples_quality);
+ atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(false, rpi->processing_side, rpi->processing_layer, sky.sky_ggx_samples_quality);
}
rpi->processing_side++;
@@ -1826,6 +1827,16 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
rb->sss_texture = RID();
}
+ if (rb->vrs_fb.is_valid()) {
+ RD::get_singleton()->free(rb->vrs_fb);
+ rb->vrs_fb = RID();
+ }
+
+ if (rb->vrs_texture.is_valid()) {
+ RD::get_singleton()->free(rb->vrs_texture);
+ rb->vrs_texture = RID();
+ }
+
for (int i = 0; i < 2; i++) {
for (int l = 0; l < rb->blur[i].layers.size(); l++) {
for (int m = 0; m < rb->blur[i].layers[l].mipmaps.size(); m++) {
@@ -1880,60 +1891,9 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
rb->ss_effects.linear_depth_slices.clear();
}
- if (rb->ss_effects.ssao.ao_final.is_valid()) {
- RD::get_singleton()->free(rb->ss_effects.ssao.ao_deinterleaved);
- RD::get_singleton()->free(rb->ss_effects.ssao.ao_pong);
- RD::get_singleton()->free(rb->ss_effects.ssao.ao_final);
-
- RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[0]);
- RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[1]);
-
- rb->ss_effects.ssao.ao_deinterleaved = RID();
- rb->ss_effects.ssao.ao_pong = RID();
- rb->ss_effects.ssao.ao_final = RID();
- rb->ss_effects.ssao.importance_map[0] = RID();
- rb->ss_effects.ssao.importance_map[1] = RID();
-
- rb->ss_effects.ssao.ao_deinterleaved_slices.clear();
- rb->ss_effects.ssao.ao_pong_slices.clear();
- }
-
- if (rb->ss_effects.ssil.ssil_final.is_valid()) {
- RD::get_singleton()->free(rb->ss_effects.ssil.ssil_final);
- RD::get_singleton()->free(rb->ss_effects.ssil.deinterleaved);
- RD::get_singleton()->free(rb->ss_effects.ssil.pong);
- RD::get_singleton()->free(rb->ss_effects.ssil.edges);
- RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[0]);
- RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[1]);
-
- rb->ss_effects.ssil.ssil_final = RID();
- rb->ss_effects.ssil.deinterleaved = RID();
- rb->ss_effects.ssil.pong = RID();
- rb->ss_effects.ssil.edges = RID();
- rb->ss_effects.ssil.deinterleaved_slices.clear();
- rb->ss_effects.ssil.pong_slices.clear();
- rb->ss_effects.ssil.edges_slices.clear();
- rb->ss_effects.ssil.importance_map[0] = RID();
- rb->ss_effects.ssil.importance_map[1] = RID();
-
- RD::get_singleton()->free(rb->ss_effects.last_frame);
- rb->ss_effects.last_frame = RID();
- rb->ss_effects.last_frame_slices.clear();
- }
-
- if (rb->ssr.blur_radius[0].is_valid()) {
- RD::get_singleton()->free(rb->ssr.blur_radius[0]);
- RD::get_singleton()->free(rb->ssr.blur_radius[1]);
- rb->ssr.blur_radius[0] = RID();
- rb->ssr.blur_radius[1] = RID();
- }
-
- if (rb->ssr.depth_scaled.is_valid()) {
- RD::get_singleton()->free(rb->ssr.depth_scaled);
- rb->ssr.depth_scaled = RID();
- RD::get_singleton()->free(rb->ssr.normal_scaled);
- rb->ssr.normal_scaled = RID();
- }
+ ss_effects->ssao_free(rb->ss_effects.ssao);
+ ss_effects->ssil_free(rb->ss_effects.ssil);
+ ss_effects->ssr_free(rb->ssr);
if (rb->taa.history.is_valid()) {
RD::get_singleton()->free(rb->taa.history);
@@ -1968,10 +1928,12 @@ void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatri
_allocate_blur_textures(rb);
}
- storage->get_effects()->sub_surface_scattering(rb->internal_texture, rb->sss_texture, rb->depth_texture, p_camera, Size2i(rb->internal_width, rb->internal_height), sss_scale, sss_depth_scale, sss_quality);
+ RendererCompositorRD::singleton->get_effects()->sub_surface_scattering(rb->internal_texture, rb->sss_texture, rb->depth_texture, p_camera, Size2i(rb->internal_width, rb->internal_height), sss_scale, sss_depth_scale, sss_quality);
}
-void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) {
+void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_slices, RID p_specular_buffer, const RID *p_metallic_slices, const Color &p_metallic_mask, RID p_environment, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive) {
+ ERR_FAIL_NULL(ss_effects);
+
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -1979,7 +1941,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb
if (!can_use_effects) {
//just copy
- storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, RID());
+ copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, RID(), rb->view_count);
return;
}
@@ -1988,42 +1950,23 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb
ERR_FAIL_COND(!env->ssr_enabled);
- if (rb->ssr.depth_scaled.is_null()) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R32_SFLOAT;
- tf.width = rb->internal_width / 2;
- tf.height = rb->internal_height / 2;
- tf.texture_type = RD::TEXTURE_TYPE_2D;
- tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
-
- rb->ssr.depth_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
-
- rb->ssr.normal_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView());
- }
-
- if (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED && !rb->ssr.blur_radius[0].is_valid()) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = rb->internal_width / 2;
- tf.height = rb->internal_height / 2;
- tf.texture_type = RD::TEXTURE_TYPE_2D;
- tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
-
- rb->ssr.blur_radius[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- rb->ssr.blur_radius[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ Size2i half_size = Size2i(rb->internal_width / 2, rb->internal_height / 2);
+ if (rb->ssr.output.is_null()) {
+ ss_effects->ssr_allocate_buffers(rb->ssr, _render_buffers_get_color_format(), ssr_roughness_quality, half_size, rb->view_count);
}
-
- if (rb->blur[0].texture.is_null()) {
- _allocate_blur_textures(rb);
+ RID texture_slices[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID depth_slices[RendererSceneRender::MAX_RENDER_VIEWS];
+ for (uint32_t v = 0; v < rb->view_count; v++) {
+ texture_slices[v] = rb->views[v].view_texture;
+ depth_slices[v] = rb->views[v].view_depth;
}
-
- storage->get_effects()->screen_space_reflection(rb->internal_texture, p_normal_buffer, ssr_roughness_quality, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].layers[0].mipmaps[1].texture, rb->blur[1].layers[0].mipmaps[0].texture, Size2i(rb->internal_width / 2, rb->internal_height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection);
- storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->blur[0].layers[0].mipmaps[1].texture);
+ ss_effects->screen_space_reflection(rb->ssr, texture_slices, p_normal_slices, ssr_roughness_quality, p_metallic_slices, p_metallic_mask, depth_slices, half_size, env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, rb->view_count, p_projections, p_eye_offsets);
+ copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->ssr.output, rb->view_count);
}
void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) {
+ ERR_FAIL_NULL(ss_effects);
+
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -2032,102 +1975,7 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
RENDER_TIMESTAMP("Process SSAO");
- if (rb->ss_effects.ssao.ao_final.is_valid() && ssao_using_half_size != ssao_half_size) {
- RD::get_singleton()->free(rb->ss_effects.ssao.ao_deinterleaved);
- RD::get_singleton()->free(rb->ss_effects.ssao.ao_pong);
- RD::get_singleton()->free(rb->ss_effects.ssao.ao_final);
-
- RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[0]);
- RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[1]);
-
- rb->ss_effects.ssao.ao_deinterleaved = RID();
- rb->ss_effects.ssao.ao_pong = RID();
- rb->ss_effects.ssao.ao_final = RID();
- rb->ss_effects.ssao.importance_map[0] = RID();
- rb->ss_effects.ssao.importance_map[1] = RID();
- rb->ss_effects.ssao.ao_deinterleaved_slices.clear();
- rb->ss_effects.ssao.ao_pong_slices.clear();
- }
-
- int buffer_width;
- int buffer_height;
- int half_width;
- int half_height;
- if (ssao_half_size) {
- buffer_width = (rb->internal_width + 3) / 4;
- buffer_height = (rb->internal_height + 3) / 4;
- half_width = (rb->internal_width + 7) / 8;
- half_height = (rb->internal_height + 7) / 8;
- } else {
- buffer_width = (rb->internal_width + 1) / 2;
- buffer_height = (rb->internal_height + 1) / 2;
- half_width = (rb->internal_width + 3) / 4;
- half_height = (rb->internal_height + 3) / 4;
- }
- bool uniform_sets_are_invalid = false;
- if (rb->ss_effects.ssao.ao_deinterleaved.is_null()) {
- {
- rb->ss_effects.ssao.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.linear_depth, 0, ssao_half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY);
- }
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8G8_UNORM;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = buffer_width;
- tf.height = buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ss_effects.ssao.ao_deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.ao_deinterleaved, "SSAO De-interleaved Array");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssao.ao_deinterleaved, i, 0);
- rb->ss_effects.ssao.ao_deinterleaved_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " ");
- }
- }
-
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8G8_UNORM;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = buffer_width;
- tf.height = buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ss_effects.ssao.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.ao_pong, "SSAO De-interleaved Array Pong");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssao.ao_pong, i, 0);
- rb->ss_effects.ssao.ao_pong_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " Pong");
- }
- }
-
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = half_width;
- tf.height = half_height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ss_effects.ssao.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.importance_map[0], "SSAO Importance Map");
- rb->ss_effects.ssao.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.importance_map[1], "SSAO Importance Map Pong");
- }
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = rb->internal_width;
- tf.height = rb->internal_height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ss_effects.ssao.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.ao_final, "SSAO Final");
- }
- ssao_using_half_size = ssao_half_size;
- uniform_sets_are_invalid = true;
- }
-
- EffectsRD::SSAOSettings settings;
+ RendererRD::SSEffects::SSAOSettings settings;
settings.radius = env->ssao_radius;
settings.intensity = env->ssao_intensity;
settings.power = env->ssao_power;
@@ -2142,13 +1990,14 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
settings.fadeout_from = ssao_fadeout_from;
settings.fadeout_to = ssao_fadeout_to;
settings.full_screen_size = Size2i(rb->internal_width, rb->internal_height);
- settings.half_screen_size = Size2i(buffer_width, buffer_height);
- settings.quarter_screen_size = Size2i(half_width, half_height);
- storage->get_effects()->generate_ssao(p_normal_buffer, rb->ss_effects.ssao.depth_texture_view, rb->ss_effects.ssao.ao_deinterleaved, rb->ss_effects.ssao.ao_deinterleaved_slices, rb->ss_effects.ssao.ao_pong, rb->ss_effects.ssao.ao_pong_slices, rb->ss_effects.ssao.ao_final, rb->ss_effects.ssao.importance_map[0], rb->ss_effects.ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssao.gather_uniform_set, rb->ss_effects.ssao.importance_map_uniform_set);
+ ss_effects->ssao_allocate_buffers(rb->ss_effects.ssao, settings, rb->ss_effects.linear_depth);
+ ss_effects->generate_ssao(rb->ss_effects.ssao, p_normal_buffer, p_projection, settings);
}
void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform) {
+ ERR_FAIL_NULL(ss_effects);
+
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -2157,133 +2006,7 @@ void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environmen
RENDER_TIMESTAMP("Process SSIL");
- if (rb->ss_effects.ssil.ssil_final.is_valid() && ssil_using_half_size != ssil_half_size) {
- RD::get_singleton()->free(rb->ss_effects.ssil.ssil_final);
- RD::get_singleton()->free(rb->ss_effects.ssil.deinterleaved);
- RD::get_singleton()->free(rb->ss_effects.ssil.pong);
- RD::get_singleton()->free(rb->ss_effects.ssil.edges);
- RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[0]);
- RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[1]);
-
- rb->ss_effects.ssil.ssil_final = RID();
- rb->ss_effects.ssil.deinterleaved = RID();
- rb->ss_effects.ssil.pong = RID();
- rb->ss_effects.ssil.edges = RID();
- rb->ss_effects.ssil.deinterleaved_slices.clear();
- rb->ss_effects.ssil.pong_slices.clear();
- rb->ss_effects.ssil.edges_slices.clear();
- rb->ss_effects.ssil.importance_map[0] = RID();
- rb->ss_effects.ssil.importance_map[1] = RID();
- }
-
- int buffer_width;
- int buffer_height;
- int half_width;
- int half_height;
- if (ssil_half_size) {
- buffer_width = (rb->width + 3) / 4;
- buffer_height = (rb->height + 3) / 4;
- half_width = (rb->width + 7) / 8;
- half_height = (rb->height + 7) / 8;
- } else {
- buffer_width = (rb->width + 1) / 2;
- buffer_height = (rb->height + 1) / 2;
- half_width = (rb->width + 3) / 4;
- half_height = (rb->height + 3) / 4;
- }
- bool uniform_sets_are_invalid = false;
- if (rb->ss_effects.ssil.ssil_final.is_null()) {
- {
- rb->ss_effects.ssil.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.linear_depth, 0, ssil_half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY);
- }
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.width = rb->width;
- tf.height = rb->height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
- rb->ss_effects.ssil.ssil_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.ssil_final, "SSIL texture");
- RD::get_singleton()->texture_clear(rb->ss_effects.ssil.ssil_final, Color(0, 0, 0, 0), 0, 1, 0, 1);
- if (rb->ss_effects.last_frame.is_null()) {
- tf.mipmaps = 6;
- rb->ss_effects.last_frame = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.last_frame, "Last Frame Radiance");
- RD::get_singleton()->texture_clear(rb->ss_effects.last_frame, Color(0, 0, 0, 0), 0, tf.mipmaps, 0, 1);
- for (uint32_t i = 0; i < 6; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.last_frame, 0, i);
- rb->ss_effects.last_frame_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "Last Frame Radiance Mip " + itos(i) + " ");
- }
- }
- }
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = buffer_width;
- tf.height = buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ss_effects.ssil.deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.deinterleaved, "SSIL deinterleaved buffer");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssil.deinterleaved, i, 0);
- rb->ss_effects.ssil.deinterleaved_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer array " + itos(i) + " ");
- }
- }
-
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = buffer_width;
- tf.height = buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ss_effects.ssil.pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.pong, "SSIL deinterleaved pong buffer");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssil.pong, i, 0);
- rb->ss_effects.ssil.pong_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer pong array " + itos(i) + " ");
- }
- }
-
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- tf.width = buffer_width;
- tf.height = buffer_height;
- tf.array_layers = 4;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ss_effects.ssil.edges = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.edges, "SSIL edges buffer");
- for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssil.edges, i, 0);
- rb->ss_effects.ssil.edges_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(slice, "SSIL edges buffer slice " + itos(i) + " ");
- }
- }
-
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = half_width;
- tf.height = half_height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ss_effects.ssil.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.importance_map[0], "SSIL Importance Map");
- rb->ss_effects.ssil.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.importance_map[1], "SSIL Importance Map Pong");
- }
- uniform_sets_are_invalid = true;
- ssil_using_half_size = ssil_half_size;
- }
-
- EffectsRD::SSILSettings settings;
+ RendererRD::SSEffects::SSILSettings settings;
settings.radius = env->ssil_radius;
settings.intensity = env->ssil_intensity;
settings.sharpness = env->ssil_sharpness;
@@ -2296,8 +2019,6 @@ void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environmen
settings.fadeout_from = ssil_fadeout_from;
settings.fadeout_to = ssil_fadeout_to;
settings.full_screen_size = Size2i(rb->width, rb->height);
- settings.half_screen_size = Size2i(buffer_width, buffer_height);
- settings.quarter_screen_size = Size2i(half_width, half_height);
CameraMatrix correction;
correction.set_depth_correction(true);
@@ -2306,7 +2027,8 @@ void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environmen
transform.set_origin(Vector3(0.0, 0.0, 0.0));
CameraMatrix last_frame_projection = rb->ss_effects.last_frame_projection * CameraMatrix(rb->ss_effects.last_frame_transform.affine_inverse()) * CameraMatrix(transform) * projection.inverse();
- storage->get_effects()->screen_space_indirect_lighting(rb->ss_effects.last_frame, rb->ss_effects.ssil.ssil_final, p_normal_buffer, rb->ss_effects.ssil.depth_texture_view, rb->ss_effects.ssil.deinterleaved, rb->ss_effects.ssil.deinterleaved_slices, rb->ss_effects.ssil.pong, rb->ss_effects.ssil.pong_slices, rb->ss_effects.ssil.importance_map[0], rb->ss_effects.ssil.importance_map[1], rb->ss_effects.ssil.edges, rb->ss_effects.ssil.edges_slices, p_projection, last_frame_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssil.gather_uniform_set, rb->ss_effects.ssil.importance_map_uniform_set, rb->ss_effects.ssil.projection_uniform_set);
+ ss_effects->ssil_allocate_buffers(rb->ss_effects.ssil, settings, rb->ss_effects.linear_depth);
+ ss_effects->screen_space_indirect_lighting(rb->ss_effects.ssil, p_normal_buffer, p_projection, last_frame_projection, settings);
rb->ss_effects.last_frame_projection = projection;
rb->ss_effects.last_frame_transform = transform;
}
@@ -2315,15 +2037,15 @@ void RendererSceneRenderRD::_copy_framebuffer_to_ssil(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND(!rb);
- if (rb->ss_effects.last_frame.is_valid()) {
- copy_effects->copy_to_rect(rb->texture, rb->ss_effects.last_frame, Rect2i(0, 0, rb->width, rb->height));
+ if (rb->ss_effects.ssil.last_frame.is_valid()) {
+ copy_effects->copy_to_rect(rb->texture, rb->ss_effects.ssil.last_frame, Rect2i(0, 0, rb->width, rb->height));
int width = rb->width;
int height = rb->height;
- for (int i = 0; i < rb->ss_effects.last_frame_slices.size() - 1; i++) {
+ for (int i = 0; i < rb->ss_effects.ssil.last_frame_slices.size() - 1; i++) {
width = MAX(1, width >> 1);
height = MAX(1, height >> 1);
- copy_effects->make_mipmap(rb->ss_effects.last_frame_slices[i], rb->ss_effects.last_frame_slices[i + 1], Size2i(width, height));
+ copy_effects->make_mipmap(rb->ss_effects.ssil.last_frame_slices[i], rb->ss_effects.ssil.last_frame_slices[i + 1], Size2i(width, height));
}
}
}
@@ -2354,7 +2076,7 @@ void RendererSceneRenderRD::_process_taa(RID p_render_buffers, RID p_velocity_bu
RD::get_singleton()->draw_command_begin_label("TAA");
if (!just_allocated) {
- storage->get_effects()->taa_resolve(rb->internal_texture, rb->taa.temp, rb->depth_texture, p_velocity_buffer, rb->taa.prev_velocity, rb->taa.history, Size2(rb->internal_width, rb->internal_height), p_z_near, p_z_far);
+ RendererCompositorRD::singleton->get_effects()->taa_resolve(rb->internal_texture, rb->taa.temp, rb->depth_texture, p_velocity_buffer, rb->taa.prev_velocity, rb->taa.history, Size2(rb->internal_width, rb->internal_height), p_z_near, p_z_far);
copy_effects->copy_to_rect(rb->taa.temp, rb->internal_texture, Rect2(0, 0, rb->internal_width, rb->internal_height));
}
@@ -2492,9 +2214,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
double step = env->auto_exp_speed * time_step;
if (can_use_storage) {
- storage->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate);
+ RendererCompositorRD::singleton->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate);
} else {
- storage->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate);
+ RendererCompositorRD::singleton->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate);
}
// Swap final reduce with prev luminance.
SWAP(rb->luminance.current, rb->luminance.reduce.write[rb->luminance.reduce.size() - 1]);
@@ -2639,7 +2361,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
if (can_use_effects && can_use_storage && (rb->internal_width != rb->width || rb->internal_height != rb->height)) {
RD::get_singleton()->draw_command_begin_label("FSR 1.0 Upscale");
- storage->get_effects()->fsr_upscale(rb->internal_texture, rb->upscale_texture, rb->texture, Size2i(rb->internal_width, rb->internal_height), Size2i(rb->width, rb->height), rb->fsr_sharpness);
+ RendererCompositorRD::singleton->get_effects()->fsr_upscale(rb->internal_texture, rb->upscale_texture, rb->texture, Size2i(rb->internal_width, rb->internal_height), Size2i(rb->width, rb->height), rb->fsr_sharpness);
RD::get_singleton()->draw_command_end_label();
}
@@ -3097,7 +2819,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
}
if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) {
- tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
+ tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, (RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT)) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
} else {
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
}
@@ -3129,14 +2851,14 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
if (rb->view_count == 1) {
// copy as a convenience
RenderBuffers::View view;
- view.view_texture = rb->internal_texture;
+ view.view_texture = rb->texture;
view.view_depth = rb->depth_texture;
view.view_fb = rb->texture_fb;
rb->views.push_back(view);
} else {
for (uint32_t i = 0; i < rb->view_count; i++) {
RenderBuffers::View view;
- view.view_texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->internal_texture, i, 0);
+ view.view_texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->texture, i, 0);
view.view_depth = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->depth_texture, i, 0);
if (!_render_buffers_can_be_storage()) {
@@ -3150,8 +2872,13 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
}
}
+ RS::ViewportVRSMode vrs_mode = texture_storage->render_target_get_vrs_mode(rb->render_target);
+ if (is_vrs_supported() && vrs_mode != RS::VIEWPORT_VRS_DISABLED) {
+ vrs->create_vrs_texture(p_internal_width, p_internal_height, p_view_count, rb->vrs_texture, rb->vrs_fb);
+ }
+
RID target_texture = texture_storage->render_target_get_rd_texture(rb->render_target);
- rb->data->configure(rb->internal_texture, rb->depth_texture, target_texture, p_internal_width, p_internal_height, p_msaa, p_use_taa, p_view_count);
+ rb->data->configure(rb->internal_texture, rb->depth_texture, target_texture, p_internal_width, p_internal_height, p_msaa, p_use_taa, p_view_count, rb->vrs_texture);
if (is_clustered_enabled()) {
rb->cluster_builder->setup(Size2i(p_internal_width, p_internal_height), max_cluster_elements, rb->depth_texture, RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->internal_texture);
@@ -3175,7 +2902,7 @@ void RendererSceneRenderRD::sub_surface_scattering_set_scale(float p_scale, floa
sss_depth_scale = p_depth_scale;
}
-void RendererSceneRenderRD::shadows_quality_set(RS::ShadowQuality p_quality) {
+void RendererSceneRenderRD::positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {
ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum");
if (shadows_quality != p_quality) {
@@ -3222,7 +2949,7 @@ void RendererSceneRenderRD::shadows_quality_set(RS::ShadowQuality p_quality) {
_update_shader_quality_settings();
}
-void RendererSceneRenderRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) {
+void RendererSceneRenderRD::directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {
ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum");
if (directional_shadow_quality != p_quality) {
@@ -3364,7 +3091,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
Transform3D transform = rpi->transform;
Transform3D proj = (p_camera_inverse_transform * transform).inverse();
- RendererStorageRD::store_transform(proj, reflection_ubo.local_matrix);
+ RendererRD::MaterialStorage::store_transform(proj, reflection_ubo.local_matrix);
if (current_cluster_builder != nullptr) {
current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_REFLECTION_PROBE, transform, extents);
@@ -3482,7 +3209,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
light_data.shadow_transmittance_bias[j] = light_storage->light_get_transmittance_bias(base) * bias_scale;
light_data.shadow_z_range[j] = li->shadow_transform[j].farplane;
light_data.shadow_range_begin[j] = li->shadow_transform[j].range_begin;
- RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
+ RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
Vector2 uv_scale = li->shadow_transform[j].uv_scale;
uv_scale *= atlas_rect.size; //adapt to atlas size
@@ -3727,7 +3454,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
if (type == RS::LIGHT_OMNI) {
Transform3D proj = (inverse_transform * light_transform).inverse();
- RendererStorageRD::store_transform(proj, light_data.shadow_matrix);
+ RendererRD::MaterialStorage::store_transform(proj, light_data.shadow_matrix);
if (size > 0.0 && light_data.soft_shadow_scale > 0.0) {
// Only enable PCSS-like soft shadows if blurring is enabled.
@@ -3746,7 +3473,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
bias.set_light_bias();
CameraMatrix shadow_mtx = bias * li->shadow_transform[0].camera * modelview;
- RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix);
+ RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrix);
if (size > 0.0 && light_data.soft_shadow_scale > 0.0) {
// Only enable PCSS-like soft shadows if blurring is enabled.
@@ -3865,7 +3592,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
Transform3D scale_xform;
scale_xform.basis.scale(decal_extents);
Transform3D to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse();
- RendererStorageRD::store_transform(to_decal_xform, dd.xform);
+ RendererRD::MaterialStorage::store_transform(to_decal_xform, dd.xform);
Vector3 normal = xform.basis.get_column(Vector3::AXIS_Y).normalized();
normal = p_camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine
@@ -3903,7 +3630,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
dd.normal_rect[3] = rect.size.y;
Basis normal_xform = p_camera_inverse_xform.basis * xform.basis.orthonormalized();
- RendererStorageRD::store_basis_3x4(normal_xform, dd.normal_xform);
+ RendererRD::MaterialStorage::store_basis_3x4(normal_xform, dd.normal_xform);
} else {
dd.normal_rect[0] = 0;
dd.normal_rect[1] = 0;
@@ -4150,6 +3877,9 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
if (rb->volumetric_fog->fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) {
RD::get_singleton()->free(rb->volumetric_fog->fog_uniform_set);
}
+ if (rb->volumetric_fog->process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) {
+ RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set_density);
+ }
if (rb->volumetric_fog->process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) {
RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set);
}
@@ -4244,7 +3974,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
rb->volumetric_fog->fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
RD::get_singleton()->set_resource_name(rb->volumetric_fog->fog_map, "Fog map");
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
Vector<uint8_t> dm;
dm.resize(target_width * target_height * volumetric_fog_depth * 4);
dm.fill(0);
@@ -4323,8 +4053,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount;
Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;
- storage->store_transform(to_prev_cam_view, params.to_prev_view);
- storage->store_transform(p_cam_transform, params.transform);
+ RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);
+ RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform);
RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), &params, RD::BARRIER_MASK_COMPUTE);
@@ -4333,7 +4063,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -4353,7 +4083,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -4365,7 +4095,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -4386,7 +4116,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
ERR_FAIL_COND(!fog_volume_instance);
RID fog_volume = fog_volume_instance->volume;
- RID fog_material = storage->fog_volume_get_material(fog_volume);
+ RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume);
FogMaterialData *material = nullptr;
@@ -4415,8 +4145,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
Vector3i kernel_size = Vector3i();
Vector3 position = fog_volume_instance->transform.get_origin();
- RS::FogVolumeShape volume_type = storage->fog_volume_get_shape(fog_volume);
- Vector3 extents = storage->fog_volume_get_extents(fog_volume);
+ RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume);
+ Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_extents(fog_volume);
if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) {
// Local fog volume.
@@ -4459,8 +4189,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
volumetric_fog.push_constant.corner[0] = min.x;
volumetric_fog.push_constant.corner[1] = min.y;
volumetric_fog.push_constant.corner[2] = min.z;
- volumetric_fog.push_constant.shape = uint32_t(storage->fog_volume_get_shape(fog_volume));
- storage->store_transform(fog_volume_instance->transform.affine_inverse(), volumetric_fog.push_constant.transform);
+ volumetric_fog.push_constant.shape = uint32_t(RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume));
+ RendererRD::MaterialStorage::store_transform(fog_volume_instance->transform.affine_inverse(), volumetric_fog.push_constant.transform);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline);
@@ -4482,7 +4212,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::get_singleton()->compute_list_end();
}
- if (rb->volumetric_fog->process_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) {
+ if (rb->volumetric_fog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) {
//re create uniform set if needed
Vector<RD::Uniform> uniforms;
Vector<RD::Uniform> copy_uniforms;
@@ -4637,7 +4367,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
}
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -4648,7 +4378,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
}
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -4660,7 +4390,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
{
RD::Uniform u;
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
#else
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
@@ -4682,7 +4412,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
rb->volumetric_fog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0);
- rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0);
+ rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
RID aux7 = uniforms.write[7].get_id(0);
RID aux8 = uniforms.write[8].get_id(0);
@@ -4690,7 +4420,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
uniforms.write[7].set_id(0, aux8);
uniforms.write[8].set_id(0, aux7);
- rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, 0), 0);
+ rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
+
+ uniforms.remove_at(8);
+ uniforms.write[7].set_id(0, aux7);
+ rb->volumetric_fog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0);
}
bool using_sdfgi = env->volumetric_fog_gi_inject > 0.0001 && env->sdfgi_enabled && (rb->sdfgi != nullptr);
@@ -4801,7 +4535,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;
Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;
- storage->store_transform(to_prev_cam_view, params.to_prev_view);
+ RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);
params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection;
params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount;
@@ -4822,7 +4556,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
Basis sky_transform = env->sky_orientation;
sky_transform = sky_transform.inverse() * p_cam_transform.basis;
- RendererStorageRD::store_transform_3x3(sky_transform, params.radiance_inverse_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform);
RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog");
@@ -4833,7 +4567,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[using_sdfgi ? VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set_density, 0);
if (using_sdfgi) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1);
@@ -4921,7 +4655,7 @@ void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, boo
}
}
-void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID *p_normal_roughness_views, RID p_voxel_gi_buffer) {
+void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices) {
// Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
@@ -4996,7 +4730,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
//start GI
if (render_gi) {
- gi.process_gi(p_render_data->render_buffers, p_normal_roughness_views, p_voxel_gi_buffer, p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->view_eye_offset, p_render_data->cam_transform, *p_render_data->voxel_gi_instances, this);
+ gi.process_gi(p_render_data->render_buffers, p_normal_roughness_slices, p_voxel_gi_buffer, p_vrs_slices, p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->view_eye_offset, p_render_data->cam_transform, *p_render_data->voxel_gi_instances, this);
}
//Do shadow rendering (in parallel with GI)
@@ -5008,7 +4742,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //use a later barrier
}
- if (p_render_data->render_buffers.is_valid()) {
+ if (p_render_data->render_buffers.is_valid() && ss_effects) {
if (p_use_ssao || p_use_ssil) {
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers);
ERR_FAIL_COND(!rb);
@@ -5033,17 +4767,17 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
invalidate_uniform_set = true;
}
- storage->get_effects()->downsample_depth(rb->depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, Size2i(rb->width, rb->height), p_render_data->cam_projection);
+ ss_effects->downsample_depth(rb->depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, Size2i(rb->width, rb->height), p_render_data->cam_projection);
}
if (p_use_ssao) {
- // TODO make these proper stereo and thus use p_normal_roughness_views correctly
- _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_views[0], p_render_data->cam_projection);
+ // TODO make these proper stereo
+ _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->cam_projection);
}
if (p_use_ssil) {
- // TODO make these proper stereo and thus use p_normal_roughness_views correctly
- _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_views[0], p_render_data->cam_projection, p_render_data->cam_transform);
+ // TODO make these proper stereo
+ _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->cam_projection, p_render_data->cam_transform);
}
}
@@ -5182,7 +4916,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData
if (p_render_buffers.is_valid()) {
clear_color = texture_storage->render_target_get_clear_request_color(rb->render_target);
} else {
- clear_color = storage->get_default_clear_color();
+ clear_color = RSG::texture_storage->get_default_clear_color();
}
//assign render indices to voxel_gi_instances
@@ -5232,6 +4966,11 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData
render_data.cluster_max_elements = current_cluster_builder->get_max_cluster_elements();
}
+ if (rb != nullptr && rb->vrs_fb.is_valid()) {
+ // vrs_fb will only be valid if vrs is enabled
+ vrs->update_vrs_texture(rb->vrs_fb, rb->render_target);
+ }
+
_render_scene(&render_data, clear_color);
if (p_render_buffers.is_valid()) {
@@ -5728,6 +5467,10 @@ int RendererSceneRenderRD::get_max_directional_lights() const {
return cluster.max_directional_lights;
}
+bool RendererSceneRenderRD::is_vrs_supported() const {
+ return RD::get_singleton()->has_feature(RD::SUPPORTS_ATTACHMENT_VRS);
+}
+
bool RendererSceneRenderRD::is_dynamic_gi_supported() const {
// usable by default (unless low end = true)
return true;
@@ -5747,8 +5490,7 @@ uint32_t RendererSceneRenderRD::get_max_elements() const {
return GLOBAL_GET("rendering/limits/cluster_builder/max_clustered_elements");
}
-RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
- storage = p_storage;
+RendererSceneRenderRD::RendererSceneRenderRD() {
singleton = this;
}
@@ -5762,12 +5504,12 @@ void RendererSceneRenderRD::init() {
/* SKY SHADER */
- sky.init(storage);
+ sky.init();
/* GI */
if (is_dynamic_gi_supported()) {
- gi.init(storage, &sky);
+ gi.init(&sky);
}
{ //decals
@@ -5953,8 +5695,8 @@ void fog() {
directional_soft_shadow_kernel = memnew_arr(float, 128);
penumbra_shadow_kernel = memnew_arr(float, 128);
soft_shadow_kernel = memnew_arr(float, 128);
- shadows_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/shadows/soft_shadow_quality"))));
- directional_shadow_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/directional_shadow/soft_shadow_quality"))));
+ positional_soft_shadow_filter_set_quality(RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/positional_shadow/soft_shadow_filter_quality"))));
+ directional_soft_shadow_filter_set_quality(RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/directional_shadow/soft_shadow_filter_quality"))));
environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/environment/volumetric_fog/volume_size"), GLOBAL_GET("rendering/environment/volumetric_fog/volume_depth"));
environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter"));
@@ -5968,6 +5710,10 @@ void fog() {
bokeh_dof = memnew(RendererRD::BokehDOF(!can_use_storage));
copy_effects = memnew(RendererRD::CopyEffects(!can_use_storage));
tone_mapper = memnew(RendererRD::ToneMapper);
+ vrs = memnew(RendererRD::VRS);
+ if (can_use_storage) {
+ ss_effects = memnew(RendererRD::SSEffects);
+ }
}
RendererSceneRenderRD::~RendererSceneRenderRD() {
@@ -5982,6 +5728,12 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
if (tone_mapper) {
memdelete(tone_mapper);
}
+ if (vrs) {
+ memdelete(vrs);
+ }
+ if (ss_effects) {
+ memdelete(ss_effects);
+ }
for (const KeyValue<int, ShadowCubemap> &E : shadow_cubemaps) {
RD::get_singleton()->free(E.value.cubemap);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index c87fd6703f..16cf99314a 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -37,11 +37,12 @@
#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
#include "servers/rendering/renderer_rd/effects/bokeh_dof.h"
#include "servers/rendering/renderer_rd/effects/copy_effects.h"
+#include "servers/rendering/renderer_rd/effects/ss_effects.h"
#include "servers/rendering/renderer_rd/effects/tone_mapper.h"
+#include "servers/rendering/renderer_rd/effects/vrs.h"
#include "servers/rendering/renderer_rd/environment/gi.h"
#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl.gen.h"
#include "servers/rendering/renderer_scene.h"
@@ -102,15 +103,15 @@ class RendererSceneRenderRD : public RendererSceneRender {
friend RendererRD::GI;
protected:
- RendererStorageRD *storage = nullptr;
RendererRD::BokehDOF *bokeh_dof = nullptr;
RendererRD::CopyEffects *copy_effects = nullptr;
RendererRD::ToneMapper *tone_mapper = nullptr;
+ RendererRD::VRS *vrs = nullptr;
double time = 0.0;
double time_step = 0.0;
struct RenderBufferData {
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count) = 0;
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count, RID p_vrs_texture) = 0;
virtual ~RenderBufferData() {}
};
virtual RenderBufferData *_create_render_buffer_data() = 0;
@@ -141,7 +142,7 @@ protected:
virtual RID _render_buffers_get_velocity_texture(RID p_render_buffers) = 0;
void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection);
- void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive);
+ void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, const Color &p_metallic_mask, RID p_environment, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive);
void _process_sss(RID p_render_buffers, const CameraMatrix &p_camera);
void _process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform);
void _copy_framebuffer_to_ssil(RID p_render_buffers);
@@ -151,7 +152,7 @@ protected:
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi);
- void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID *p_normal_roughness_views, RID p_voxel_gi_buffer);
+ void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices);
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
@@ -163,6 +164,7 @@ protected:
PagedArrayPool<GeometryInstance *> cull_argument_pool;
PagedArray<GeometryInstance *> cull_argument; //need this to exist
+ RendererRD::SSEffects *ss_effects = nullptr;
RendererRD::GI gi;
RendererSceneSkyRD sky;
@@ -418,7 +420,6 @@ private:
RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM;
bool ssao_half_size = false;
- bool ssao_using_half_size = false;
float ssao_adaptive_target = 0.5;
int ssao_blur_passes = 2;
float ssao_fadeout_from = 50.0;
@@ -494,6 +495,8 @@ private:
RID depth_texture; //main depth texture
RID texture_fb; // framebuffer for the main texture, ONLY USED FOR MOBILE RENDERER POST EFFECTS, DO NOT USE FOR RENDERING 3D!!!
RID upscale_texture; //used when upscaling internal_texture (This uses the same resource as internal_texture if there is no upscaling)
+ RID vrs_texture; // texture for vrs.
+ RID vrs_fb; // framebuffer to write to our vrs texture
// Access to the layers for each of our views (specifically needed for applying post effects on stereoscopic images)
struct View {
@@ -559,47 +562,14 @@ private:
RID downsample_uniform_set;
- RID last_frame;
- Vector<RID> last_frame_slices;
-
CameraMatrix last_frame_projection;
Transform3D last_frame_transform;
- struct SSAO {
- RID ao_deinterleaved;
- Vector<RID> ao_deinterleaved_slices;
- RID ao_pong;
- Vector<RID> ao_pong_slices;
- RID ao_final;
- RID importance_map[2];
- RID depth_texture_view;
-
- RID gather_uniform_set;
- RID importance_map_uniform_set;
- } ssao;
-
- struct SSIL {
- RID ssil_final;
- RID deinterleaved;
- Vector<RID> deinterleaved_slices;
- RID pong;
- Vector<RID> pong_slices;
- RID edges;
- Vector<RID> edges_slices;
- RID importance_map[2];
- RID depth_texture_view;
-
- RID gather_uniform_set;
- RID importance_map_uniform_set;
- RID projection_uniform_set;
- } ssil;
+ RendererRD::SSEffects::SSAORenderBuffers ssao;
+ RendererRD::SSEffects::SSILRenderBuffers ssil;
} ss_effects;
- struct SSR {
- RID normal_scaled;
- RID depth_scaled;
- RID blur_radius[2];
- } ssr;
+ RendererRD::SSEffects::SSRRenderBuffers ssr;
struct TAA {
RID history;
@@ -799,6 +769,7 @@ private:
RID fog_uniform_set;
RID copy_uniform_set;
+ RID process_uniform_set_density;
RID process_uniform_set;
RID process_uniform_set2;
RID sdfgi_uniform_set;
@@ -1455,8 +1426,8 @@ public:
RS::SubSurfaceScatteringQuality sub_surface_scattering_get_quality() const;
virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override;
- virtual void shadows_quality_set(RS::ShadowQuality p_quality) override;
- virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) override;
+ virtual void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override;
+ virtual void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override;
virtual void decals_set_filter(RS::DecalFilter p_filter) override;
virtual void light_projectors_set_filter(RS::LightProjectorFilter p_filter) override;
@@ -1504,6 +1475,7 @@ public:
virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override;
+ virtual bool is_vrs_supported() const;
virtual bool is_dynamic_gi_supported() const;
virtual bool is_clustered_enabled() const;
virtual bool is_volumetric_supported() const;
@@ -1511,7 +1483,7 @@ public:
void init();
- RendererSceneRenderRD(RendererStorageRD *p_storage);
+ RendererSceneRenderRD();
~RendererSceneRenderRD();
};
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index b3b9b86aa8..73175d3cf3 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -37,6 +37,7 @@
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
+#include "servers/rendering/rendering_server_globals.h"
////////////////////////////////////////////////////////////////////////////////
// SKY SHADER
@@ -329,13 +330,13 @@ void RendererSceneSkyRD::ReflectionData::clear_reflection_data() {
coefficient_buffer = RID();
}
-void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageRD *p_storage, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) {
+void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) {
//recreate radiance and all data
int mipmaps = p_mipmaps;
uint32_t w = p_size, h = p_size;
- EffectsRD *effects = p_storage->get_effects();
+ EffectsRD *effects = RendererCompositorRD::singleton->get_effects();
ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised");
bool prefer_raster_effects = effects->get_prefer_raster_effects();
@@ -437,7 +438,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR
}
}
-void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererStorageRD *p_storage, bool p_use_arrays) {
+void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) {
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
@@ -495,7 +496,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererS
}
}
-void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(RendererStorageRD *p_storage, bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) {
+void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) {
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
@@ -564,7 +565,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren
RD::get_singleton()->draw_command_end_label(); // Filter radiance
}
-void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end) {
+void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) {
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
@@ -591,7 +592,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStora
////////////////////////////////////////////////////////////////////////////////
// RendererSceneSkyRD::Sky
-void RendererSceneSkyRD::Sky::free(RendererStorageRD *p_storage) {
+void RendererSceneSkyRD::Sky::free() {
if (radiance.is_valid()) {
RD::get_singleton()->free(radiance);
radiance = RID();
@@ -614,12 +615,12 @@ void RendererSceneSkyRD::Sky::free(RendererStorageRD *p_storage) {
}
if (material.is_valid()) {
- p_storage->free(material);
+ RSG::material_storage->material_free(material);
material = RID();
}
}
-RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextureSetVersion p_version, RID p_default_shader_rd) {
+RID RendererSceneSkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) {
@@ -795,10 +796,9 @@ RendererSceneSkyRD::RendererSceneSkyRD() {
sky_use_cubemap_array = GLOBAL_GET("rendering/reflections/sky_reflections/texture_array_reflections");
}
-void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
+void RendererSceneSkyRD::init() {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_storage;
{
// Start with the directional lights for the sky
@@ -1387,7 +1387,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
for (int i = 0; i < 6; i++) {
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
@@ -1406,7 +1406,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
for (int i = 0; i < 6; i++) {
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
@@ -1421,7 +1421,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
RD::get_singleton()->draw_command_begin_label("Render Sky Cubemap");
for (int i = 0; i < 6; i++) {
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
@@ -1430,22 +1430,22 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
RD::get_singleton()->draw_command_end_label();
if (sky_mode == RS::SKY_MODE_REALTIME) {
- sky->reflection.create_reflection_fast_filter(storage, sky_use_cubemap_array);
+ sky->reflection.create_reflection_fast_filter(sky_use_cubemap_array);
if (sky_use_cubemap_array) {
- sky->reflection.update_reflection_mipmaps(storage, 0, sky->reflection.layers.size());
+ sky->reflection.update_reflection_mipmaps(0, sky->reflection.layers.size());
}
} else {
if (update_single_frame) {
for (int i = 1; i < max_processing_layer; i++) {
- sky->reflection.create_reflection_importance_sample(storage, sky_use_cubemap_array, 10, i, sky_ggx_samples_quality);
+ sky->reflection.create_reflection_importance_sample(sky_use_cubemap_array, 10, i, sky_ggx_samples_quality);
}
if (sky_use_cubemap_array) {
- sky->reflection.update_reflection_mipmaps(storage, 0, sky->reflection.layers.size());
+ sky->reflection.update_reflection_mipmaps(0, sky->reflection.layers.size());
}
} else {
if (sky_use_cubemap_array) {
// Multi-Frame so just update the first array level
- sky->reflection.update_reflection_mipmaps(storage, 0, 1);
+ sky->reflection.update_reflection_mipmaps(0, 1);
}
}
sky->processing_layer = 1;
@@ -1455,10 +1455,10 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
} else {
if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {
- sky->reflection.create_reflection_importance_sample(storage, sky_use_cubemap_array, 10, sky->processing_layer, sky_ggx_samples_quality);
+ sky->reflection.create_reflection_importance_sample(sky_use_cubemap_array, 10, sky->processing_layer, sky_ggx_samples_quality);
if (sky_use_cubemap_array) {
- sky->reflection.update_reflection_mipmaps(storage, sky->processing_layer, sky->processing_layer + 1);
+ sky->reflection.update_reflection_mipmaps(sky->processing_layer, sky->processing_layer + 1);
}
sky->processing_layer++;
@@ -1536,7 +1536,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
if (shader_data->uses_quarter_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -1549,7 +1549,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
if (shader_data->uses_half_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -1563,7 +1563,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
RID texture_uniform_set;
if (sky) {
- texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
+ texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
} else {
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
}
@@ -1634,7 +1634,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
if (shader_data->uses_quarter_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -1647,7 +1647,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
if (shader_data->uses_half_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -1729,7 +1729,7 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme
RID texture_uniform_set;
if (sky) {
- texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
+ texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
} else {
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
}
@@ -1777,7 +1777,7 @@ void RendererSceneSkyRD::update_dirty_skys() {
sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
- sky->reflection.update_reflection_data(storage, sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
+ sky->reflection.update_reflection_data(sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
} else {
//regular cubemap, lower quality (aliasing, less memory)
@@ -1792,7 +1792,7 @@ void RendererSceneSkyRD::update_dirty_skys() {
sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
- sky->reflection.update_reflection_data(storage, sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
+ sky->reflection.update_reflection_data(sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
}
texture_set_dirty = true;
}
@@ -1872,7 +1872,7 @@ void RendererSceneSkyRD::free_sky(RID p_sky) {
Sky *sky = get_sky(p_sky);
ERR_FAIL_COND(!sky);
- sky->free(storage);
+ sky->free();
sky_owner.free(p_sky);
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
index 83a8fe6e77..a8ee406abc 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
@@ -33,11 +33,13 @@
#include "core/templates/rid_owner.h"
#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/shader_compiler.h"
// Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
class RendererSceneRenderRD;
@@ -63,7 +65,6 @@ public:
};
private:
- RendererStorageRD *storage = nullptr;
RD::DataFormat texture_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
RID index_buffer;
@@ -211,10 +212,10 @@ public:
Vector<Layer> layers;
void clear_reflection_data();
- void update_reflection_data(RendererStorageRD *p_storage, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format);
- void create_reflection_fast_filter(RendererStorageRD *p_storage, bool p_use_arrays);
- void create_reflection_importance_sample(RendererStorageRD *p_storage, bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality);
- void update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end);
+ void update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format);
+ void create_reflection_fast_filter(bool p_use_arrays);
+ void create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality);
+ void update_reflection_mipmaps(int p_start, int p_end);
};
/* Sky shader */
@@ -267,9 +268,9 @@ public:
Vector3 prev_position;
float prev_time;
- void free(RendererStorageRD *p_storage);
+ void free();
- RID get_textures(RendererStorageRD *p_storage, SkyTextureSetVersion p_version, RID p_default_shader_rd);
+ RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd);
bool set_radiance_size(int p_radiance_size);
bool set_mode(RS::SkyMode p_mode);
bool set_material(RID p_material);
@@ -289,7 +290,7 @@ public:
static RendererRD::MaterialData *_create_sky_material_funcs(RendererRD::ShaderData *p_shader);
RendererSceneSkyRD();
- void init(RendererStorageRD *p_storage);
+ void init();
void set_texture_format(RD::DataFormat p_texture_format);
~RendererSceneSkyRD();
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
deleted file mode 100644
index d41129d678..0000000000
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*************************************************************************/
-/* renderer_storage_rd.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef RENDERING_SERVER_STORAGE_RD_H
-#define RENDERING_SERVER_STORAGE_RD_H
-
-#include "core/templates/list.h"
-#include "core/templates/local_vector.h"
-#include "core/templates/rid_owner.h"
-#include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering/renderer_rd/effects_rd.h"
-#include "servers/rendering/renderer_rd/shaders/environment/voxel_gi_sdf.glsl.gen.h"
-#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
-#include "servers/rendering/renderer_scene_render.h"
-#include "servers/rendering/rendering_device.h"
-#include "servers/rendering/shader_compiler.h"
-
-class RendererStorageRD : public RendererStorage {
-public:
- static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
- p_array[0] = p_mtx.basis.rows[0][0];
- p_array[1] = p_mtx.basis.rows[1][0];
- p_array[2] = p_mtx.basis.rows[2][0];
- p_array[3] = 0;
- p_array[4] = p_mtx.basis.rows[0][1];
- p_array[5] = p_mtx.basis.rows[1][1];
- p_array[6] = p_mtx.basis.rows[2][1];
- p_array[7] = 0;
- p_array[8] = p_mtx.basis.rows[0][2];
- p_array[9] = p_mtx.basis.rows[1][2];
- p_array[10] = p_mtx.basis.rows[2][2];
- p_array[11] = 0;
- p_array[12] = p_mtx.origin.x;
- p_array[13] = p_mtx.origin.y;
- p_array[14] = p_mtx.origin.z;
- p_array[15] = 1;
- }
-
- static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) {
- p_array[0] = p_mtx.rows[0][0];
- p_array[1] = p_mtx.rows[1][0];
- p_array[2] = p_mtx.rows[2][0];
- p_array[3] = 0;
- p_array[4] = p_mtx.rows[0][1];
- p_array[5] = p_mtx.rows[1][1];
- p_array[6] = p_mtx.rows[2][1];
- p_array[7] = 0;
- p_array[8] = p_mtx.rows[0][2];
- p_array[9] = p_mtx.rows[1][2];
- p_array[10] = p_mtx.rows[2][2];
- p_array[11] = 0;
- }
-
- static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
- p_array[0] = p_mtx.rows[0][0];
- p_array[1] = p_mtx.rows[1][0];
- p_array[2] = p_mtx.rows[2][0];
- p_array[3] = 0;
- p_array[4] = p_mtx.rows[0][1];
- p_array[5] = p_mtx.rows[1][1];
- p_array[6] = p_mtx.rows[2][1];
- p_array[7] = 0;
- p_array[8] = p_mtx.rows[0][2];
- p_array[9] = p_mtx.rows[1][2];
- p_array[10] = p_mtx.rows[2][2];
- p_array[11] = 0;
- }
-
- static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform3D &p_mtx, float *p_array) {
- p_array[0] = p_mtx.basis.rows[0][0];
- p_array[1] = p_mtx.basis.rows[0][1];
- p_array[2] = p_mtx.basis.rows[0][2];
- p_array[3] = p_mtx.origin.x;
- p_array[4] = p_mtx.basis.rows[1][0];
- p_array[5] = p_mtx.basis.rows[1][1];
- p_array[6] = p_mtx.basis.rows[1][2];
- p_array[7] = p_mtx.origin.y;
- p_array[8] = p_mtx.basis.rows[2][0];
- p_array[9] = p_mtx.basis.rows[2][1];
- p_array[10] = p_mtx.basis.rows[2][2];
- p_array[11] = p_mtx.origin.z;
- }
-
- static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- p_array[i * 4 + j] = p_mtx.matrix[i][j];
- }
- }
- }
-
- static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) {
- for (int i = 0; i < 128; i++) {
- p_array[i] = p_kernel[i];
- }
- }
-
-private:
- /* FOG VOLUMES */
-
- struct FogVolume {
- RID material;
- Vector3 extents = Vector3(1, 1, 1);
-
- RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX;
-
- Dependency dependency;
- };
-
- mutable RID_Owner<FogVolume, true> fog_volume_owner;
-
- /* visibility_notifier */
-
- struct VisibilityNotifier {
- AABB aabb;
- Callable enter_callback;
- Callable exit_callback;
- Dependency dependency;
- };
-
- mutable RID_Owner<VisibilityNotifier> visibility_notifier_owner;
-
- /* EFFECTS */
-
- EffectsRD *effects = nullptr;
-
-public:
- //internal usage
-
- void base_update_dependency(RID p_base, DependencyTracker *p_instance);
-
- /* FOG VOLUMES */
-
- virtual RID fog_volume_allocate();
- virtual void fog_volume_initialize(RID p_rid);
-
- virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape);
- virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents);
- virtual void fog_volume_set_material(RID p_fog_volume, RID p_material);
- virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const;
- virtual RID fog_volume_get_material(RID p_fog_volume) const;
- virtual AABB fog_volume_get_aabb(RID p_fog_volume) const;
- virtual Vector3 fog_volume_get_extents(RID p_fog_volume) const;
-
- /* VISIBILITY NOTIFIER */
-
- virtual RID visibility_notifier_allocate();
- virtual void visibility_notifier_initialize(RID p_notifier);
- virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb);
- virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable);
-
- virtual AABB visibility_notifier_get_aabb(RID p_notifier) const;
- virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred);
-
- RS::InstanceType get_base_type(RID p_rid) const;
-
- bool free(RID p_rid);
-
- bool has_os_feature(const String &p_feature) const;
-
- void update_dirty_resources();
-
- void set_debug_generate_wireframes(bool p_generate) {}
-
- //keep cached since it can be called form any thread
- uint64_t texture_mem_cache = 0;
- uint64_t buffer_mem_cache = 0;
- uint64_t total_mem_cache = 0;
-
- virtual void update_memory_info();
- virtual uint64_t get_rendering_info(RS::RenderingInfo p_info);
-
- String get_video_adapter_name() const;
- String get_video_adapter_vendor() const;
- RenderingDevice::DeviceType get_video_adapter_type() const;
- String get_video_adapter_api_version() const;
-
- virtual void capture_timestamps_begin();
- virtual void capture_timestamp(const String &p_name);
- virtual uint32_t get_captured_timestamps_count() const;
- virtual uint64_t get_captured_timestamps_frame() const;
- virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const;
- virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const;
- virtual String get_captured_timestamp_name(uint32_t p_index) const;
-
- static RendererStorageRD *base_singleton;
-
- void init_effects(bool p_prefer_raster_effects);
- EffectsRD *get_effects();
-
- RendererStorageRD();
- ~RendererStorageRD();
-};
-
-#endif // RASTERIZER_STORAGE_RD_H
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 04e05380f1..176465234e 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -177,7 +177,7 @@ void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, c
for (const KeyValue<StringName, CharString> &E : p_version->code_sections) {
builder.append(String("#define ") + String(E.key) + "_CODE_USED\n");
}
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
builder.append("#define MOLTENVK_USED\n");
#endif
} break;
diff --git a/servers/rendering/renderer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub
index 05663226c0..d352743908 100644
--- a/servers/rendering/renderer_rd/shaders/SCsub
+++ b/servers/rendering/renderer_rd/shaders/SCsub
@@ -10,7 +10,7 @@ if "RD_GLSL" in env["BUILDERS"]:
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
# make sure we recompile shaders if include files change
- env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files)
+ env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
# compile shaders
for glsl_file in glsl_files:
diff --git a/servers/rendering/renderer_rd/shaders/effects/SCsub b/servers/rendering/renderer_rd/shaders/effects/SCsub
index fc513d3fb9..741da8fe69 100644
--- a/servers/rendering/renderer_rd/shaders/effects/SCsub
+++ b/servers/rendering/renderer_rd/shaders/effects/SCsub
@@ -10,7 +10,7 @@ if "RD_GLSL" in env["BUILDERS"]:
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
# make sure we recompile shaders if include files change
- env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files)
+ env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
# compile shaders
for glsl_file in glsl_files:
diff --git a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
index 9787c9879d..1c17eabb56 100644
--- a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
@@ -88,7 +88,7 @@ layout(set = 0, binding = 0) uniform sampler2DArray source_color;
layout(set = 1, binding = 0) uniform sampler2DArray source_depth;
layout(location = 1) out float depth;
#endif /* MODE_TWO_SOURCES */
-#else
+#else /* MULTIVIEW */
layout(set = 0, binding = 0) uniform sampler2D source_color;
#ifdef MODE_TWO_SOURCES
layout(set = 1, binding = 0) uniform sampler2D source_color2;
@@ -139,7 +139,7 @@ void main() {
//uv.y = 1.0 - uv.y;
uv = 1.0 - uv;
}
-#endif
+#endif /* MODE_PANORAMA_TO_DP */
#ifdef MULTIVIEW
vec4 color = textureLod(source_color, uv, 0.0);
@@ -148,12 +148,13 @@ void main() {
depth = textureLod(source_depth, uv, 0.0).r;
#endif /* MODE_TWO_SOURCES */
-#else
+#else /* MULTIVIEW */
vec4 color = textureLod(source_color, uv, 0.0);
#ifdef MODE_TWO_SOURCES
color += textureLod(source_color2, uv, 0.0);
#endif /* MODE_TWO_SOURCES */
#endif /* MULTIVIEW */
+
if (params.force_luminance) {
color.rgb = vec3(max(max(color.r, color.g), color.b));
}
@@ -163,5 +164,6 @@ void main() {
if (params.srgb) {
color.rgb = linear_to_srgb(color.rgb);
}
+
frag_color = color;
}
diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
index a416891ff2..d85ab3af2e 100644
--- a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
@@ -32,12 +32,17 @@ layout(push_constant, std430) uniform Params {
bool use_half_res;
uint metallic_mask;
- mat4 projection;
+ uint view_index;
+ uint pad1;
+ uint pad2;
+ uint pad3;
}
params;
+#include "screen_space_reflection_inc.glsl"
+
vec2 view_to_screen(vec3 view_pos, out float w) {
- vec4 projected = params.projection * vec4(view_pos, 1.0);
+ vec4 projected = scene_data.projection[params.view_index] * vec4(view_pos, 1.0);
projected.xyz /= projected.w;
projected.xy = projected.xy * 0.5 + 0.5;
w = projected.w;
@@ -46,24 +51,16 @@ vec2 view_to_screen(vec3 view_pos, out float w) {
#define M_PI 3.14159265359
-vec3 reconstructCSPosition(vec2 S, float z) {
- if (params.orthogonal) {
- return vec3((S.xy * params.proj_info.xy + params.proj_info.zw), z);
- } else {
- return vec3((S.xy * params.proj_info.xy + params.proj_info.zw) * z, z);
- }
-}
-
void main() {
// Pixel being shaded
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(ssC.xy, params.screen_size))) { //too large, do nothing
return;
}
vec2 pixel_size = 1.0 / vec2(params.screen_size);
- vec2 uv = vec2(ssC) * pixel_size;
+ vec2 uv = vec2(ssC.xy) * pixel_size;
uv += pixel_size * 0.5;
@@ -77,7 +74,12 @@ void main() {
normal = normalize(normal);
normal.y = -normal.y; //because this code reads flipped
- vec3 view_dir = normalize(vertex);
+ vec3 view_dir;
+ if (sc_multiview) {
+ view_dir = normalize(vertex + scene_data.eye_offset[params.view_index].xyz);
+ } else {
+ view_dir = normalize(vertex);
+ }
vec3 ray_dir = normalize(reflect(view_dir, normal));
if (dot(ray_dir, normal) < 0.001) {
@@ -154,6 +156,11 @@ void main() {
// convert to linear depth
depth = imageLoad(source_depth, ivec2(pos - 0.5)).r;
+ if (sc_multiview) {
+ depth = depth * 2.0 - 1.0;
+ depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near));
+ depth = -depth;
+ }
z_from = z_to;
z_to = z / w;
@@ -222,13 +229,16 @@ void main() {
blur_radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h);
}
}
+
+ // Isn't this going to be overwritten after our endif?
final_color = imageLoad(source_diffuse, ivec2((final_pos - 0.5) * pixel_size));
imageStore(blur_radius_image, ssC, vec4(blur_radius / 255.0)); //stored in r8
-#endif
+#endif // MODE_ROUGH
final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend);
+
//change blend by metallic
vec4 metallic_mask = unpackUnorm4x8(params.metallic_mask);
final_color.a *= dot(metallic_mask, texelFetch(source_metallic, ssC << 1, 0));
diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl
index 20e1712496..a63d60e0b2 100644
--- a/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl
@@ -22,7 +22,7 @@ layout(push_constant, std430) uniform Params {
bool orthogonal;
float edge_tolerance;
int increment;
- uint pad;
+ uint view_index;
ivec2 screen_size;
bool vertical;
@@ -30,6 +30,8 @@ layout(push_constant, std430) uniform Params {
}
params;
+#include "screen_space_reflection_inc.glsl"
+
#define GAUSS_TABLE_SIZE 15
const float gauss_table[GAUSS_TABLE_SIZE + 1] = float[](
@@ -64,14 +66,6 @@ float gauss_weight(float p_val) {
#define M_PI 3.14159265359
-vec3 reconstructCSPosition(vec2 S, float z) {
- if (params.orthogonal) {
- return vec3((S.xy * params.proj_info.xy + params.proj_info.zw), z);
- } else {
- return vec3((S.xy * params.proj_info.xy + params.proj_info.zw) * z, z);
- }
-}
-
void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, ivec2 texcoord, ivec2 increment, vec3 p_pos, vec3 normal, float p_limit_radius) {
for (int i = 1; i < params.steps; i++) {
float d = float(i * params.increment);
@@ -110,7 +104,7 @@ void main() {
// Pixel being shaded
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(ssC.xy, params.screen_size))) { //too large, do nothing
return;
}
@@ -130,13 +124,13 @@ void main() {
ivec2 direction = ivec2(params.increment, 0);
#endif
float depth = imageLoad(source_depth, ssC).r;
- vec3 pos = reconstructCSPosition(vec2(ssC) + 0.5, depth);
+ vec3 pos = reconstructCSPosition(vec2(ssC.xy) + 0.5, depth);
vec3 normal = imageLoad(source_normal, ssC).xyz * 2.0 - 1.0;
normal = normalize(normal);
normal.y = -normal.y;
- do_filter(accum, accum_radius, divisor, ssC, direction, pos, normal, radius);
- do_filter(accum, accum_radius, divisor, ssC, -direction, pos, normal, radius);
+ do_filter(accum, accum_radius, divisor, ssC.xy, direction, pos, normal, radius);
+ do_filter(accum, accum_radius, divisor, ssC.xy, -direction, pos, normal, radius);
if (divisor > 0.0) {
accum /= divisor;
diff --git a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_inc.glsl
new file mode 100644
index 0000000000..26405ab040
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_inc.glsl
@@ -0,0 +1,28 @@
+layout(constant_id = 0) const bool sc_multiview = false;
+
+layout(set = 4, binding = 0, std140) uniform SceneData {
+ mat4x4 projection[2];
+ mat4x4 inv_projection[2];
+ vec4 eye_offset[2];
+}
+scene_data;
+
+vec3 reconstructCSPosition(vec2 screen_pos, float z) {
+ if (sc_multiview) {
+ vec4 pos;
+ pos.xy = (2.0 * vec2(screen_pos) / vec2(params.screen_size)) - 1.0;
+ pos.z = z * 2.0 - 1.0;
+ pos.w = 1.0;
+
+ pos = scene_data.inv_projection[params.view_index] * pos;
+ pos.xyz /= pos.w;
+
+ return pos.xyz;
+ } else {
+ if (params.orthogonal) {
+ return vec3((screen_pos.xy * params.proj_info.xy + params.proj_info.zw), z);
+ } else {
+ return vec3((screen_pos.xy * params.proj_info.xy + params.proj_info.zw) * z, z);
+ }
+ }
+}
diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl
index 3f537e273a..a7da0812df 100644
--- a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl
@@ -6,6 +6,11 @@
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+/* Specialization Constants (Toggles) */
+
+layout(constant_id = 0) const bool sc_multiview = false;
+
+/* inputs */
layout(set = 0, binding = 0) uniform sampler2D source_ssr;
layout(set = 1, binding = 0) uniform sampler2D source_depth;
layout(set = 1, binding = 1) uniform sampler2D source_normal;
@@ -28,7 +33,7 @@ void main() {
// Pixel being shaded
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(ssC.xy, params.screen_size))) { //too large, do nothing
return;
}
//do not filter, SSR will generate arctifacts if this is done
@@ -57,13 +62,19 @@ void main() {
normal.xyz += nr.xyz * 2.0 - 1.0;
normal.w += nr.w;
- d = d * 2.0 - 1.0;
- if (params.orthogonal) {
- d = ((d + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0;
+ if (sc_multiview) {
+ // we're doing a full unproject so we need the value as is.
+ depth += d;
} else {
- d = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - d * (params.camera_z_far - params.camera_z_near));
+ // unproject our Z value so we can use it directly.
+ d = d * 2.0 - 1.0;
+ if (params.orthogonal) {
+ d = ((d + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0;
+ } else {
+ d = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - d * (params.camera_z_far - params.camera_z_near));
+ }
+ depth += -d;
}
- depth += -d;
}
color /= 4.0;
@@ -71,17 +82,22 @@ void main() {
normal.xyz = normalize(normal.xyz / 4.0) * 0.5 + 0.5;
normal.w /= 4.0;
} else {
- color = texelFetch(source_ssr, ssC << 1, 0);
- depth = texelFetch(source_depth, ssC << 1, 0).r;
- normal = texelFetch(source_normal, ssC << 1, 0);
-
- depth = depth * 2.0 - 1.0;
- if (params.orthogonal) {
- depth = ((depth + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0;
- } else {
- depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near));
+ ivec2 ofs = ssC << 1;
+
+ color = texelFetch(source_ssr, ofs, 0);
+ depth = texelFetch(source_depth, ofs, 0).r;
+ normal = texelFetch(source_normal, ofs, 0);
+
+ if (!sc_multiview) {
+ // unproject our Z value so we can use it directly.
+ depth = depth * 2.0 - 1.0;
+ if (params.orthogonal) {
+ depth = ((depth + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0;
+ } else {
+ depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near));
+ }
+ depth = -depth;
}
- depth = -depth;
}
imageStore(dest_ssr, ssC, color);
diff --git a/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl b/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl
new file mode 100644
index 0000000000..c62144fdaf
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl
@@ -0,0 +1,112 @@
+#[vertex]
+
+#version 450
+
+#VERSION_DEFINES
+
+#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview)
+#extension GL_EXT_multiview : enable
+#endif
+
+#ifdef USE_MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+// !BAS! This needs to become an input once we implement our fallback!
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#else // USE_MULTIVIEW
+// Set to zero, not supported in non stereo
+#define ViewIndex 0
+#endif //USE_MULTIVIEW
+
+#ifdef USE_MULTIVIEW
+layout(location = 0) out vec3 uv_interp;
+#else // USE_MULTIVIEW
+layout(location = 0) out vec2 uv_interp;
+#endif //USE_MULTIVIEW
+
+void main() {
+ vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
+
+#ifdef USE_MULTIVIEW
+ uv_interp = vec3(base_arr[gl_VertexIndex], ViewIndex);
+
+ gl_Position = vec4(uv_interp.xy * 2.0 - 1.0, 0.0, 1.0);
+#else
+ uv_interp = base_arr[gl_VertexIndex];
+
+ gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
+#endif
+}
+
+#[fragment]
+
+#version 450
+
+#VERSION_DEFINES
+
+#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview)
+#extension GL_EXT_multiview : enable
+#endif
+
+#ifdef USE_MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+// !BAS! This needs to become an input once we implement our fallback!
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#else // USE_MULTIVIEW
+// Set to zero, not supported in non stereo
+#define ViewIndex 0
+#endif //USE_MULTIVIEW
+
+#ifdef USE_MULTIVIEW
+layout(location = 0) in vec3 uv_interp;
+#else // USE_MULTIVIEW
+layout(location = 0) in vec2 uv_interp;
+#endif //USE_MULTIVIEW
+
+#ifdef USE_MULTIVIEW
+layout(set = 0, binding = 0) uniform sampler2DArray specular;
+#else // USE_MULTIVIEW
+layout(set = 0, binding = 0) uniform sampler2D specular;
+#endif //USE_MULTIVIEW
+
+#ifdef MODE_SSR
+
+#ifdef USE_MULTIVIEW
+layout(set = 1, binding = 0) uniform sampler2DArray ssr;
+#else // USE_MULTIVIEW
+layout(set = 1, binding = 0) uniform sampler2D ssr;
+#endif //USE_MULTIVIEW
+
+#endif
+
+#ifdef MODE_MERGE
+
+#ifdef USE_MULTIVIEW
+layout(set = 2, binding = 0) uniform sampler2DArray diffuse;
+#else // USE_MULTIVIEW
+layout(set = 2, binding = 0) uniform sampler2D diffuse;
+#endif //USE_MULTIVIEW
+
+#endif
+
+layout(location = 0) out vec4 frag_color;
+
+void main() {
+ frag_color.rgb = texture(specular, uv_interp).rgb;
+ frag_color.a = 0.0;
+#ifdef MODE_SSR
+
+ vec4 ssr_color = texture(ssr, uv_interp);
+ frag_color.rgb = mix(frag_color.rgb, ssr_color.rgb, ssr_color.a);
+#endif
+
+#ifdef MODE_MERGE
+ frag_color += texture(diffuse, uv_interp);
+#endif
+ //added using additive blend
+}
diff --git a/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl
index 134aae5ce7..134aae5ce7 100644
--- a/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl
diff --git a/servers/rendering/renderer_rd/shaders/ssao.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao.glsl
index 2a87e273bc..2a87e273bc 100644
--- a/servers/rendering/renderer_rd/shaders/ssao.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssao.glsl
diff --git a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl
index f42734c46d..f42734c46d 100644
--- a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl
diff --git a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl
index 04f98964e8..04f98964e8 100644
--- a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl
diff --git a/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl
index f6a9a92fac..f6a9a92fac 100644
--- a/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl
diff --git a/servers/rendering/renderer_rd/shaders/ssil.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil.glsl
index 513791dfbf..513791dfbf 100644
--- a/servers/rendering/renderer_rd/shaders/ssil.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssil.glsl
diff --git a/servers/rendering/renderer_rd/shaders/ssil_blur.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl
index 47c56571f6..47c56571f6 100644
--- a/servers/rendering/renderer_rd/shaders/ssil_blur.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl
diff --git a/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl
index 6b6b02739d..6b6b02739d 100644
--- a/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl
diff --git a/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl
index 9e86ac0cf0..9e86ac0cf0 100644
--- a/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl
diff --git a/servers/rendering/renderer_rd/shaders/effects/vrs.glsl b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl
new file mode 100644
index 0000000000..5ef83c0b44
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl
@@ -0,0 +1,72 @@
+#[vertex]
+
+#version 450
+
+#VERSION_DEFINES
+
+#ifdef MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#extension GL_EXT_multiview : enable
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#endif //MULTIVIEW
+
+#ifdef MULTIVIEW
+layout(location = 0) out vec3 uv_interp;
+#else
+layout(location = 0) out vec2 uv_interp;
+#endif
+
+void main() {
+ vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
+ uv_interp.xy = base_arr[gl_VertexIndex];
+#ifdef MULTIVIEW
+ uv_interp.z = ViewIndex;
+#endif
+
+ gl_Position = vec4(uv_interp.xy * 2.0 - 1.0, 0.0, 1.0);
+}
+
+#[fragment]
+
+#version 450
+
+#VERSION_DEFINES
+
+#ifdef MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#extension GL_EXT_multiview : enable
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#endif //MULTIVIEW
+
+#ifdef MULTIVIEW
+layout(location = 0) in vec3 uv_interp;
+layout(set = 0, binding = 0) uniform sampler2DArray source_color;
+#else /* MULTIVIEW */
+layout(location = 0) in vec2 uv_interp;
+layout(set = 0, binding = 0) uniform sampler2D source_color;
+#endif /* MULTIVIEW */
+
+layout(location = 0) out uint frag_color;
+
+void main() {
+#ifdef MULTIVIEW
+ vec3 uv = uv_interp;
+#else
+ vec2 uv = uv_interp;
+#endif
+
+#ifdef MULTIVIEW
+ vec4 color = textureLod(source_color, uv, 0.0);
+#else /* MULTIVIEW */
+ vec4 color = textureLod(source_color, uv, 0.0);
+#endif /* MULTIVIEW */
+
+ // See if we can change the sampler to one that returns int...
+ frag_color = uint(color.r * 256.0);
+}
diff --git a/servers/rendering/renderer_rd/shaders/environment/SCsub b/servers/rendering/renderer_rd/shaders/environment/SCsub
index fc513d3fb9..741da8fe69 100644
--- a/servers/rendering/renderer_rd/shaders/environment/SCsub
+++ b/servers/rendering/renderer_rd/shaders/environment/SCsub
@@ -10,7 +10,7 @@ if "RD_GLSL" in env["BUILDERS"]:
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
# make sure we recompile shaders if include files change
- env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files)
+ env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
# compile shaders
for glsl_file in glsl_files:
diff --git a/servers/rendering/renderer_rd/shaders/environment/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl
index f687d50a2d..6ea8cb1377 100644
--- a/servers/rendering/renderer_rd/shaders/environment/gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl
@@ -8,6 +8,12 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#define M_PI 3.141592
+/* Specialization Constants (Toggles) */
+
+layout(constant_id = 0) const bool sc_half_res = false;
+layout(constant_id = 1) const bool sc_use_full_projection_matrix = false;
+layout(constant_id = 2) const bool sc_use_vrs = false;
+
#define SDFGI_MAX_CASCADES 8
//set 0 for SDFGI and render buffers
@@ -97,18 +103,20 @@ layout(set = 0, binding = 18, std140) uniform SceneData {
}
scene_data;
+layout(r8ui, set = 0, binding = 19) uniform restrict readonly uimage2D vrs_buffer;
+
layout(push_constant, std430) uniform Params {
- uint view_index;
uint max_voxel_gi_instances;
bool high_quality_vct;
bool orthogonal;
+ uint view_index;
vec4 proj_info;
float z_near;
float z_far;
- float pad1;
float pad2;
+ float pad3;
}
params;
@@ -140,34 +148,34 @@ vec4 blend_color(vec4 src, vec4 dst) {
}
vec3 reconstruct_position(ivec2 screen_pos) {
-#ifdef USE_MULTIVIEW
- vec4 pos;
- pos.xy = (2.0 * vec2(screen_pos) / vec2(scene_data.screen_size)) - 1.0;
- pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r * 2.0 - 1.0;
- pos.w = 1.0;
+ if (sc_use_full_projection_matrix) {
+ vec4 pos;
+ pos.xy = (2.0 * vec2(screen_pos) / vec2(scene_data.screen_size)) - 1.0;
+ pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r * 2.0 - 1.0;
+ pos.w = 1.0;
- pos = scene_data.inv_projection[params.view_index] * pos;
+ pos = scene_data.inv_projection[params.view_index] * pos;
- return pos.xyz / pos.w;
-#else
- vec3 pos;
- pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r;
-
- pos.z = pos.z * 2.0 - 1.0;
- if (params.orthogonal) {
- pos.z = ((pos.z + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
+ return pos.xyz / pos.w;
} else {
- pos.z = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - pos.z * (params.z_far - params.z_near));
- }
- pos.z = -pos.z;
+ vec3 pos;
+ pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r;
+
+ pos.z = pos.z * 2.0 - 1.0;
+ if (params.orthogonal) {
+ pos.z = ((pos.z + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
+ } else {
+ pos.z = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - pos.z * (params.z_far - params.z_near));
+ }
+ pos.z = -pos.z;
- pos.xy = vec2(screen_pos) * params.proj_info.xy + params.proj_info.zw;
- if (!params.orthogonal) {
- pos.xy *= pos.z;
- }
+ pos.xy = vec2(screen_pos) * params.proj_info.xy + params.proj_info.zw;
+ if (!params.orthogonal) {
+ pos.xy *= pos.z;
+ }
- return pos;
-#endif
+ return pos;
+ }
}
void sdfvoxel_gi_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal, vec3 cam_specular_normal, float roughness, out vec3 diffuse_light, out vec3 specular_light) {
@@ -587,7 +595,6 @@ void voxel_gi_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
vec4 fetch_normal_and_roughness(ivec2 pos) {
vec4 normal_roughness = texelFetch(sampler2D(normal_roughness_buffer, linear_sampler), pos, 0);
-
normal_roughness.xyz = normalize(normal_roughness.xyz * 2.0 - 1.0);
return normal_roughness;
}
@@ -600,7 +607,7 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref
if (normal.length() > 0.5) {
//valid normal, can do GI
float roughness = normal_roughness.w;
- vec3 view = -normalize(mat3(scene_data.cam_transform) * (vertex - scene_data.eye_offset[params.view_index].xyz));
+ vec3 view = -normalize(mat3(scene_data.cam_transform) * (vertex - scene_data.eye_offset[gl_GlobalInvocationID.z].xyz));
vertex = mat3(scene_data.cam_transform) * vertex;
normal = normalize(mat3(scene_data.cam_transform) * normal);
vec3 reflection = normalize(reflect(-view, normal));
@@ -648,9 +655,35 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref
void main() {
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
-#ifdef MODE_HALF_RES
- pos <<= 1;
-#endif
+ uint vrs_x, vrs_y;
+ if (sc_use_vrs) {
+ ivec2 vrs_pos;
+
+ // Currently we use a 16x16 texel, possibly some day make this configurable.
+ if (sc_half_res) {
+ vrs_pos = pos >> 3;
+ } else {
+ vrs_pos = pos >> 4;
+ }
+
+ uint vrs_texel = imageLoad(vrs_buffer, vrs_pos).r;
+ // note, valid values for vrs_x and vrs_y are 1, 2 and 4.
+ vrs_x = 1 << ((vrs_texel >> 2) & 3);
+ vrs_y = 1 << (vrs_texel & 3);
+
+ if (mod(pos.x, vrs_x) != 0) {
+ return;
+ }
+
+ if (mod(pos.y, vrs_y) != 0) {
+ return;
+ }
+ }
+
+ if (sc_half_res) {
+ pos <<= 1;
+ }
+
if (any(greaterThanEqual(pos, scene_data.screen_size))) { //too large, do nothing
return;
}
@@ -663,10 +696,69 @@ void main() {
process_gi(pos, vertex, ambient_light, reflection_light);
-#ifdef MODE_HALF_RES
- pos >>= 1;
-#endif
+ if (sc_half_res) {
+ pos >>= 1;
+ }
imageStore(ambient_buffer, pos, ambient_light);
imageStore(reflection_buffer, pos, reflection_light);
+
+ if (sc_use_vrs) {
+ if (vrs_x > 1) {
+ imageStore(ambient_buffer, pos + ivec2(1, 0), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(1, 0), reflection_light);
+ }
+
+ if (vrs_x > 2) {
+ imageStore(ambient_buffer, pos + ivec2(2, 0), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(2, 0), reflection_light);
+
+ imageStore(ambient_buffer, pos + ivec2(3, 0), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(3, 0), reflection_light);
+ }
+
+ if (vrs_y > 1) {
+ imageStore(ambient_buffer, pos + ivec2(0, 1), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(0, 1), reflection_light);
+ }
+
+ if (vrs_y > 1 && vrs_x > 1) {
+ imageStore(ambient_buffer, pos + ivec2(1, 1), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(1, 1), reflection_light);
+ }
+
+ if (vrs_y > 1 && vrs_x > 2) {
+ imageStore(ambient_buffer, pos + ivec2(2, 1), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(2, 1), reflection_light);
+
+ imageStore(ambient_buffer, pos + ivec2(3, 1), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(3, 1), reflection_light);
+ }
+
+ if (vrs_y > 2) {
+ imageStore(ambient_buffer, pos + ivec2(0, 2), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(0, 2), reflection_light);
+ imageStore(ambient_buffer, pos + ivec2(0, 3), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(0, 3), reflection_light);
+ }
+
+ if (vrs_y > 2 && vrs_x > 1) {
+ imageStore(ambient_buffer, pos + ivec2(1, 2), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(1, 2), reflection_light);
+ imageStore(ambient_buffer, pos + ivec2(1, 3), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(1, 3), reflection_light);
+ }
+
+ if (vrs_y > 2 && vrs_x > 2) {
+ imageStore(ambient_buffer, pos + ivec2(2, 2), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(2, 2), reflection_light);
+ imageStore(ambient_buffer, pos + ivec2(2, 3), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(2, 3), reflection_light);
+
+ imageStore(ambient_buffer, pos + ivec2(3, 2), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(3, 2), reflection_light);
+ imageStore(ambient_buffer, pos + ivec2(3, 3), ambient_light);
+ imageStore(reflection_buffer, pos + ivec2(3, 3), reflection_light);
+ }
+ }
}
diff --git a/servers/rendering/renderer_rd/shaders/specular_merge.glsl b/servers/rendering/renderer_rd/shaders/specular_merge.glsl
deleted file mode 100644
index 3579c35cce..0000000000
--- a/servers/rendering/renderer_rd/shaders/specular_merge.glsl
+++ /dev/null
@@ -1,53 +0,0 @@
-#[vertex]
-
-#version 450
-
-#VERSION_DEFINES
-
-layout(location = 0) out vec2 uv_interp;
-
-void main() {
- vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
- uv_interp = base_arr[gl_VertexIndex];
-
- gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
-}
-
-#[fragment]
-
-#version 450
-
-#VERSION_DEFINES
-
-layout(location = 0) in vec2 uv_interp;
-
-layout(set = 0, binding = 0) uniform sampler2D specular;
-
-#ifdef MODE_SSR
-
-layout(set = 1, binding = 0) uniform sampler2D ssr;
-
-#endif
-
-#ifdef MODE_MERGE
-
-layout(set = 2, binding = 0) uniform sampler2D diffuse;
-
-#endif
-
-layout(location = 0) out vec4 frag_color;
-
-void main() {
- frag_color.rgb = texture(specular, uv_interp).rgb;
- frag_color.a = 0.0;
-#ifdef MODE_SSR
-
- vec4 ssr_color = texture(ssr, uv_interp);
- frag_color.rgb = mix(frag_color.rgb, ssr_color.rgb, ssr_color.a);
-#endif
-
-#ifdef MODE_MERGE
- frag_color += texture(diffuse, uv_interp);
-#endif
- //added using additive blend
-}
diff --git a/servers/rendering/renderer_rd/shaders/taa_resolve.glsl b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl
index a1a77b95aa..b0a0839836 100644
--- a/servers/rendering/renderer_rd/shaders/taa_resolve.glsl
+++ b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl
@@ -29,7 +29,8 @@
#VERSION_DEFINES
-// Based on Spartan Engine's TAA implementation https://github.com/PanosK92/SpartanEngine/blob/master/Data/shaders/temporal_antialiasing.hlsl
+// Based on Spartan Engine's TAA implementation (without TAA upscale).
+// <https://github.com/PanosK92/SpartanEngine/blob/a8338d0609b85dc32f3732a5c27fb4463816a3b9/Data/shaders/temporal_antialiasing.hlsl>
#define USE_SUBGROUPS
@@ -188,7 +189,7 @@ vec3 sample_catmull_rom_9(sampler2D stex, vec2 uv, vec2 resolution) {
// Source: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1
// License: https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae
- // We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
+ // We're going to sample a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
// down the sample location to get the exact center of our "starting" texel. The starting texel will be at
// location [1, 1] in the grid, where [0, 0] is the top left corner.
vec2 sample_pos = uv * resolution;
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
index 347fd13b28..fdbd7d3e35 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
@@ -53,7 +53,6 @@ layout(set = 0, binding = 7) uniform sampler linear_sampler;
#ifdef MODE_DENSITY
layout(rgba16f, set = 0, binding = 8) uniform restrict writeonly image3D density_map;
-layout(rgba16f, set = 0, binding = 9) uniform restrict readonly image3D fog_map; //unused
#endif
#ifdef MODE_FOG
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
index 56a4525b8e..e65f676785 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
@@ -156,12 +156,12 @@ void LightStorage::light_set_param(RID p_light, RS::LightParam p_param, float p_
case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
case RS::LIGHT_PARAM_SHADOW_BIAS: {
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
} break;
case RS::LIGHT_PARAM_SIZE: {
if ((light->param[p_param] > CMP_EPSILON) != (p_value > CMP_EPSILON)) {
//changing from no size to size and the opposite
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
}
} break;
default: {
@@ -177,7 +177,7 @@ void LightStorage::light_set_shadow(RID p_light, bool p_enabled) {
light->shadow = p_enabled;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_projector(RID p_light, RID p_texture) {
@@ -199,7 +199,7 @@ void LightStorage::light_set_projector(RID p_light, RID p_texture) {
if (light->projector.is_valid()) {
texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
}
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
}
}
@@ -217,7 +217,7 @@ void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
light->cull_mask = p_mask;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
@@ -237,7 +237,7 @@ void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled)
light->reverse_cull = p_enabled;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
@@ -247,7 +247,7 @@ void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mod
light->bake_mode = p_bake_mode;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
@@ -257,7 +257,7 @@ void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade)
light->max_sdfgi_cascade = p_cascade;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
@@ -267,7 +267,7 @@ void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMo
light->omni_shadow_mode = p_mode;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
RS::LightOmniShadowMode LightStorage::light_omni_get_shadow_mode(RID p_light) {
@@ -283,7 +283,7 @@ void LightStorage::light_directional_set_shadow_mode(RID p_light, RS::LightDirec
light->directional_shadow_mode = p_mode;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable) {
@@ -292,7 +292,7 @@ void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable
light->directional_blend_splits = p_enable;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
bool LightStorage::light_directional_get_blend_splits(RID p_light) const {
@@ -387,7 +387,7 @@ void LightStorage::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionP
ERR_FAIL_COND(!reflection_probe);
reflection_probe->update_mode = p_mode;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
@@ -424,7 +424,7 @@ void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distan
reflection_probe->max_distance = p_distance;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
@@ -435,7 +435,7 @@ void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_ex
return;
}
reflection_probe->extents = p_extents;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
@@ -443,7 +443,7 @@ void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3
ERR_FAIL_COND(!reflection_probe);
reflection_probe->origin_offset = p_offset;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
@@ -451,7 +451,7 @@ void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable)
ERR_FAIL_COND(!reflection_probe);
reflection_probe->interior = p_enable;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
@@ -466,7 +466,7 @@ void LightStorage::reflection_probe_set_enable_shadows(RID p_probe, bool p_enabl
ERR_FAIL_COND(!reflection_probe);
reflection_probe->enable_shadows = p_enable;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
@@ -474,7 +474,7 @@ void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers
ERR_FAIL_COND(!reflection_probe);
reflection_probe->cull_mask = p_layers;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
@@ -491,7 +491,7 @@ void LightStorage::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_
reflection_probe->mesh_lod_threshold = p_ratio;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const {
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h
index 3cc455692d..fb25e4da7e 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h
@@ -35,6 +35,7 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/storage/light_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -61,7 +62,7 @@ struct Light {
RS::LightDirectionalSkyMode directional_sky_mode = RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY;
uint64_t version = 0;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* REFLECTION PROBE */
@@ -82,7 +83,7 @@ struct ReflectionProbe {
uint32_t cull_mask = (1 << 20) - 1;
float mesh_lod_threshold = 0.01;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* LIGHTMAP */
@@ -104,7 +105,7 @@ struct Lightmap {
int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
};
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
class LightStorage : public RendererLightStorage {
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index 096d371b8d..fcd25852eb 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -2346,7 +2346,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
for (Material *E : shader->owners) {
Material *material = E;
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
}
@@ -2436,7 +2436,7 @@ void MaterialStorage::_material_uniform_set_erased(void *p_material) {
// if a texture is deleted, so re-create it.
MaterialStorage::get_singleton()->_material_queue_update(material, false, true);
}
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
}
@@ -2466,7 +2466,7 @@ void MaterialStorage::_update_queued_materials() {
if (uniforms_changed) {
//some implementations such as 3D renderer cache the matreial uniform set, so update is required
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
}
}
@@ -2507,7 +2507,7 @@ void MaterialStorage::material_set_shader(RID p_material, RID p_shader) {
}
if (p_shader.is_null()) {
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
material->shader_id = 0;
return;
}
@@ -2530,7 +2530,7 @@ void MaterialStorage::material_set_shader(RID p_material, RID p_shader) {
material->data->set_next_pass(material->next_pass);
material->data->set_render_priority(material->priority);
//updating happens later
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
@@ -2576,7 +2576,7 @@ void MaterialStorage::material_set_next_pass(RID p_material, RID p_next_material
material->data->set_next_pass(p_next_material);
}
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
void MaterialStorage::material_set_render_priority(RID p_material, int priority) {
@@ -2626,7 +2626,7 @@ void MaterialStorage::material_get_instance_shader_parameters(RID p_material, Li
}
}
-void MaterialStorage::material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) {
+void MaterialStorage::material_update_dependency(RID p_material, DependencyTracker *p_instance) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
p_instance->update_dependency(&material->dependency);
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h
index f83df05355..e35d5e7669 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h
@@ -31,12 +31,14 @@
#ifndef MATERIAL_STORAGE_RD_H
#define MATERIAL_STORAGE_RD_H
+#include "core/math/camera_matrix.h"
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/shader_compiler.h"
#include "servers/rendering/shader_language.h"
#include "servers/rendering/storage/material_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -125,7 +127,7 @@ struct Material {
RID next_pass;
SelfList<Material> update_element;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
Material() :
update_element(this) {}
@@ -232,6 +234,86 @@ public:
MaterialStorage();
virtual ~MaterialStorage();
+ /* Helpers */
+
+ static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.basis.rows[0][0];
+ p_array[1] = p_mtx.basis.rows[1][0];
+ p_array[2] = p_mtx.basis.rows[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_mtx.basis.rows[0][1];
+ p_array[5] = p_mtx.basis.rows[1][1];
+ p_array[6] = p_mtx.basis.rows[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_mtx.basis.rows[0][2];
+ p_array[9] = p_mtx.basis.rows[1][2];
+ p_array[10] = p_mtx.basis.rows[2][2];
+ p_array[11] = 0;
+ p_array[12] = p_mtx.origin.x;
+ p_array[13] = p_mtx.origin.y;
+ p_array[14] = p_mtx.origin.z;
+ p_array[15] = 1;
+ }
+
+ static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.rows[0][0];
+ p_array[1] = p_mtx.rows[1][0];
+ p_array[2] = p_mtx.rows[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_mtx.rows[0][1];
+ p_array[5] = p_mtx.rows[1][1];
+ p_array[6] = p_mtx.rows[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_mtx.rows[0][2];
+ p_array[9] = p_mtx.rows[1][2];
+ p_array[10] = p_mtx.rows[2][2];
+ p_array[11] = 0;
+ }
+
+ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.rows[0][0];
+ p_array[1] = p_mtx.rows[1][0];
+ p_array[2] = p_mtx.rows[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_mtx.rows[0][1];
+ p_array[5] = p_mtx.rows[1][1];
+ p_array[6] = p_mtx.rows[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_mtx.rows[0][2];
+ p_array[9] = p_mtx.rows[1][2];
+ p_array[10] = p_mtx.rows[2][2];
+ p_array[11] = 0;
+ }
+
+ static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform3D &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.basis.rows[0][0];
+ p_array[1] = p_mtx.basis.rows[0][1];
+ p_array[2] = p_mtx.basis.rows[0][2];
+ p_array[3] = p_mtx.origin.x;
+ p_array[4] = p_mtx.basis.rows[1][0];
+ p_array[5] = p_mtx.basis.rows[1][1];
+ p_array[6] = p_mtx.basis.rows[1][2];
+ p_array[7] = p_mtx.origin.y;
+ p_array[8] = p_mtx.basis.rows[2][0];
+ p_array[9] = p_mtx.basis.rows[2][1];
+ p_array[10] = p_mtx.basis.rows[2][2];
+ p_array[11] = p_mtx.origin.z;
+ }
+
+ static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ p_array[i * 4 + j] = p_mtx.matrix[i][j];
+ }
+ }
+ }
+
+ static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) {
+ for (int i = 0; i < 128; i++) {
+ p_array[i] = p_kernel[i];
+ }
+ }
+
/* Samplers */
_FORCE_INLINE_ RID sampler_rd_get_default(RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat) {
@@ -317,7 +399,7 @@ public:
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override;
- virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override;
+ virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override;
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);
MaterialDataRequestFunction material_get_data_request_function(ShaderType p_shader_type);
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
index 1e0d67f269..3875eb6615 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
@@ -210,6 +210,8 @@ void MeshStorage::mesh_free(RID p_rid) {
mesh_clear(p_rid);
mesh_set_shadow_mesh(p_rid, RID());
Mesh *mesh = mesh_owner.get_or_null(p_rid);
+ ERR_FAIL_COND(!mesh);
+
mesh->dependency.deleted_notify(p_rid);
if (mesh->instances.size()) {
ERR_PRINT("deleting mesh with active instances");
@@ -218,7 +220,7 @@ void MeshStorage::mesh_free(RID p_rid) {
for (Mesh *E : mesh->shadow_owners) {
Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
- shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
}
mesh_owner.free(p_rid);
@@ -429,12 +431,12 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
_mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1);
}
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
for (Mesh *E : mesh->shadow_owners) {
Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
- shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
mesh->material_cache.clear();
@@ -501,7 +503,7 @@ void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_mat
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
mesh->surfaces[p_surface]->material = p_material;
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
mesh->material_cache.clear();
}
@@ -692,7 +694,7 @@ void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) {
shadow_mesh->shadow_owners.insert(mesh);
}
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
void MeshStorage::mesh_clear(RID p_mesh) {
@@ -740,12 +742,12 @@ void MeshStorage::mesh_clear(RID p_mesh) {
_mesh_instance_clear(mi);
}
mesh->has_bone_weights = false;
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
for (Mesh *E : mesh->shadow_owners) {
Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
- shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
}
@@ -1209,7 +1211,7 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4);
}
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MULTIMESH);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH);
}
int MeshStorage::multimesh_get_instance_count(RID p_multimesh) const {
@@ -1243,7 +1245,7 @@ void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
}
}
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
#define MULTIMESH_DIRTY_REGION_SIZE 512
@@ -1602,7 +1604,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
const float *data = p_buffer.ptr();
_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
}
@@ -1644,7 +1646,7 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible
multimesh->visible_instances = p_visible;
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
}
int MeshStorage::multimesh_get_visible_instances(RID p_multimesh) const {
@@ -1703,7 +1705,7 @@ void MeshStorage::_update_dirty_multimeshes() {
//aabb is dirty..
_multimesh_re_create_aabb(multimesh, data, visible_instances);
multimesh->aabb_dirty = false;
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
}
@@ -1781,7 +1783,7 @@ void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_
}
}
- skeleton->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA);
+ skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_DATA);
}
int MeshStorage::skeleton_get_bone_count(RID p_skeleton) const {
@@ -1902,7 +1904,7 @@ void MeshStorage::_update_dirty_skeletons() {
skeleton_dirty_list = skeleton->dirty_list;
- skeleton->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES);
+ skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_BONES);
skeleton->version++;
@@ -1913,7 +1915,7 @@ void MeshStorage::_update_dirty_skeletons() {
skeleton_dirty_list = nullptr;
}
-void MeshStorage::skeleton_update_dependency(RID p_skeleton, RendererStorage::DependencyTracker *p_instance) {
+void MeshStorage::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) {
Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
ERR_FAIL_COND(!skeleton);
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
index 7ce019cf98..9cdda6bfca 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
@@ -35,8 +35,8 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/renderer_rd/shaders/skeleton.glsl.gen.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/mesh_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -143,7 +143,7 @@ struct Mesh {
RID shadow_mesh;
HashSet<Mesh *> shadow_owners;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* Mesh Instance */
@@ -199,7 +199,7 @@ struct MultiMesh {
bool dirty = false;
MultiMesh *dirty_list = nullptr;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* Skeleton */
@@ -256,7 +256,7 @@ struct Skeleton {
uint64_t version = 1;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
class MeshStorage : public RendererMeshStorage {
@@ -672,7 +672,7 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override;
- virtual void skeleton_update_dependency(RID p_skeleton, RendererStorage::DependencyTracker *p_instance) override;
+ virtual void skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) override;
void _update_dirty_skeletons();
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
index 58a96ed1f9..5200e0d318 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
@@ -30,7 +30,6 @@
#include "particles_storage.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/rendering_server_globals.h"
#include "texture_storage.h"
@@ -321,7 +320,7 @@ void ParticlesStorage::particles_set_amount(RID p_particles, int p_amount) {
particles->prev_phase = 0;
particles->clear = true;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_lifetime(RID p_particles, double p_lifetime) {
@@ -356,7 +355,7 @@ void ParticlesStorage::particles_set_custom_aabb(RID p_particles, const AABB &p_
Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_COND(!particles);
particles->custom_aabb = p_aabb;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_set_speed_scale(RID p_particles, double p_scale) {
@@ -370,7 +369,7 @@ void ParticlesStorage::particles_set_use_local_coordinates(RID p_particles, bool
ERR_FAIL_COND(!particles);
particles->use_local_coords = p_enable;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_fixed_fps(RID p_particles, int p_fps) {
@@ -386,7 +385,7 @@ void ParticlesStorage::particles_set_fixed_fps(RID p_particles, int p_fps) {
particles->prev_phase = 0;
particles->clear = true;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_interpolate(RID p_particles, bool p_enable) {
@@ -419,7 +418,7 @@ void ParticlesStorage::particles_set_trails(RID p_particles, bool p_enable, doub
particles->prev_phase = 0;
particles->clear = true;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) {
@@ -436,7 +435,7 @@ void ParticlesStorage::particles_set_trail_bind_poses(RID p_particles, const Vec
particles->trail_bind_poses = p_bind_poses;
particles->trail_bind_poses_dirty = true;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_collision_base_size(RID p_particles, real_t p_size) {
@@ -458,7 +457,7 @@ void ParticlesStorage::particles_set_process_material(RID p_particles, RID p_mat
ERR_FAIL_COND(!particles);
particles->process_material = p_material;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES); //the instance buffer may have changed
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); //the instance buffer may have changed
}
RID ParticlesStorage::particles_get_process_material(RID p_particles) const {
@@ -545,7 +544,7 @@ void ParticlesStorage::particles_emit(RID p_particles, const Transform3D &p_tran
int32_t idx = particles->emission_buffer->particle_count;
if (idx < particles->emission_buffer->particle_max) {
- RendererStorageRD::store_transform(p_transform, particles->emission_buffer->data[idx].xform);
+ RendererRD::MaterialStorage::store_transform(p_transform, particles->emission_buffer->data[idx].xform);
particles->emission_buffer->data[idx].velocity[0] = p_velocity.x;
particles->emission_buffer->data[idx].velocity[1] = p_velocity.y;
@@ -766,9 +765,9 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
frame_params.randomness = p_particles->randomness;
if (p_particles->use_local_coords) {
- RendererStorageRD::store_transform(Transform3D(), frame_params.emission_transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), frame_params.emission_transform);
} else {
- RendererStorageRD::store_transform(p_particles->emission_transform, frame_params.emission_transform);
+ RendererRD::MaterialStorage::store_transform(p_particles->emission_transform, frame_params.emission_transform);
}
frame_params.cycle = p_particles->cycle_number;
@@ -858,7 +857,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
ParticlesFrameParams::Attractor &attr = frame_params.attractors[frame_params.attractor_count];
- RendererStorageRD::store_transform(to_collider, attr.transform);
+ RendererRD::MaterialStorage::store_transform(to_collider, attr.transform);
attr.strength = pc->attractor_strength;
attr.attenuation = pc->attractor_attenuation;
attr.directionality = pc->attractor_directionality;
@@ -906,7 +905,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
ParticlesFrameParams::Collider &col = frame_params.colliders[frame_params.collider_count];
- RendererStorageRD::store_transform(to_collider, col.transform);
+ RendererRD::MaterialStorage::store_transform(to_collider, col.transform);
switch (pc->type) {
case RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE: {
col.type = ParticlesFrameParams::COLLISION_TYPE_SPHERE;
@@ -1203,7 +1202,7 @@ void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p
RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1);
RD::get_singleton()->compute_list_end();
- RendererStorageRD::base_singleton->get_effects()->sort_buffer(particles->particles_sort_uniform_set, particles->amount);
+ RendererCompositorRD::singleton->get_effects()->sort_buffer(particles->particles_sort_uniform_set, particles->amount);
}
copy_push_constant.total_particles *= copy_push_constant.total_particles;
@@ -1383,7 +1382,7 @@ void ParticlesStorage::update_particles() {
}
for (int i = 0; i < particles->trail_bind_poses.size(); i++) {
- RendererStorageRD::store_transform(particles->trail_bind_poses[i], &particles_shader.pose_update_buffer[i * 16]);
+ RendererRD::MaterialStorage::store_transform(particles->trail_bind_poses[i], &particles_shader.pose_update_buffer[i * 16]);
}
RD::get_singleton()->buffer_update(particles->trail_bind_pose_buffer, 0, particles->trail_bind_poses.size() * 16 * sizeof(float), particles_shader.pose_update_buffer.ptr());
@@ -1457,14 +1456,14 @@ void ParticlesStorage::update_particles() {
// In local mode, particle positions are calculated locally (relative to the node position)
// and they're also drawn locally.
// It works as expected, so we just pass an identity transform.
- RendererStorageRD::store_transform(Transform3D(), copy_push_constant.inv_emission_transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), copy_push_constant.inv_emission_transform);
} else {
// In global mode, particle positions are calculated globally (relative to the canvas origin)
// but they're drawn locally.
// So, we need to pass the inverse of the emission transform to bring the
// particles to local coordinates before drawing.
Transform3D inv = particles->emission_transform.affine_inverse();
- RendererStorageRD::store_transform(inv, copy_push_constant.inv_emission_transform);
+ RendererRD::MaterialStorage::store_transform(inv, copy_push_constant.inv_emission_transform);
}
copy_push_constant.total_particles = total_amount;
@@ -1500,7 +1499,7 @@ void ParticlesStorage::update_particles() {
RD::get_singleton()->compute_list_end();
}
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
}
@@ -1756,7 +1755,7 @@ void ParticlesStorage::particles_collision_set_collision_type(RID p_particles_co
particles_collision->heightfield_texture = RID();
}
particles_collision->type = p_type;
- particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) {
@@ -1770,7 +1769,7 @@ void ParticlesStorage::particles_collision_set_sphere_radius(RID p_particles_col
ERR_FAIL_COND(!particles_collision);
particles_collision->radius = p_radius;
- particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) {
@@ -1778,7 +1777,7 @@ void ParticlesStorage::particles_collision_set_box_extents(RID p_particles_colli
ERR_FAIL_COND(!particles_collision);
particles_collision->extents = p_extents;
- particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) {
@@ -1812,7 +1811,7 @@ void ParticlesStorage::particles_collision_set_field_texture(RID p_particles_col
void ParticlesStorage::particles_collision_height_field_update(RID p_particles_collision) {
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
- particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) {
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
index 115633d17a..70ac6f0349 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
@@ -37,9 +37,9 @@
#include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/shader_compiler.h"
#include "servers/rendering/storage/particles_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -226,7 +226,7 @@ struct Particles {
HashSet<RID> collisions;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
double trail_length = 1.0;
bool trails_enabled = false;
@@ -254,7 +254,7 @@ struct ParticlesCollision {
RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
struct ParticlesCollisionInstance {
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index 329c23bad0..abf364b8b4 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -191,7 +191,7 @@ TextureStorage::TextureStorage() {
}
}
- { //create default cubemap
+ { //create default black cubemap array
RD::TextureFormat tformat;
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
@@ -219,7 +219,35 @@ TextureStorage::TextureStorage() {
}
}
- { //create default cubemap array
+ { //create default white cubemap array
+
+ RD::TextureFormat tformat;
+ tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ tformat.width = 4;
+ tformat.height = 4;
+ tformat.array_layers = 6;
+ tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ tformat.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+
+ Vector<uint8_t> pv;
+ pv.resize(16 * 4);
+ for (int i = 0; i < 16; i++) {
+ pv.set(i * 4 + 0, 255);
+ pv.set(i * 4 + 1, 255);
+ pv.set(i * 4 + 2, 255);
+ pv.set(i * 4 + 3, 255);
+ }
+
+ {
+ Vector<Vector<uint8_t>> vpv;
+ for (int i = 0; i < 6; i++) {
+ vpv.push_back(pv);
+ }
+ default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+ }
+ }
+
+ { //create default black cubemap
RD::TextureFormat tformat;
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
@@ -247,7 +275,7 @@ TextureStorage::TextureStorage() {
}
}
- { //create default cubemap white array
+ { //create default white cubemap
RD::TextureFormat tformat;
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
@@ -349,7 +377,6 @@ TextureStorage::TextureStorage() {
Vector<uint8_t> pv;
pv.resize(16 * 4);
-
for (int i = 0; i < 16; i++) {
pv.set(i * 4 + 0, 0);
pv.set(i * 4 + 1, 0);
@@ -358,7 +385,6 @@ TextureStorage::TextureStorage() {
}
{
- //take the chance and initialize decal atlas to something
Vector<Vector<uint8_t>> vpv;
vpv.push_back(pv);
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
@@ -366,6 +392,29 @@ TextureStorage::TextureStorage() {
}
}
+ { //create default VRS
+
+ RD::TextureFormat tformat;
+ tformat.format = RD::DATA_FORMAT_R8_UINT;
+ tformat.width = 4;
+ tformat.height = 4;
+ tformat.array_layers = 1;
+ tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+
+ Vector<uint8_t> pv;
+ pv.resize(4 * 4);
+ for (int i = 0; i < 4 * 4; i++) {
+ pv.set(i, 0);
+ }
+
+ {
+ Vector<Vector<uint8_t>> vpv;
+ vpv.push_back(pv);
+ default_rd_textures[DEFAULT_RD_TEXTURE_VRS] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+ }
+ }
+
{
Vector<String> sdf_modes;
sdf_modes.push_back("\n#define MODE_LOAD\n");
@@ -1712,7 +1761,7 @@ void TextureStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->extents = p_extents;
- decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
@@ -1736,7 +1785,7 @@ void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID
texture_add_to_decal_atlas(decal->textures[p_type]);
}
- decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_DECAL);
+ decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_DECAL);
}
void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
@@ -1761,7 +1810,7 @@ void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->cull_mask = p_layers;
- decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
@@ -2751,3 +2800,31 @@ void TextureStorage::render_target_set_backbuffer_uniform_set(RID p_render_targe
ERR_FAIL_COND(!rt);
rt->backbuffer_uniform_set = p_uniform_set;
}
+
+void TextureStorage::render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->vrs_mode = p_mode;
+}
+
+void TextureStorage::render_target_set_vrs_texture(RID p_render_target, RID p_texture) {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->vrs_texture = p_texture;
+}
+
+RS::ViewportVRSMode TextureStorage::render_target_get_vrs_mode(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, RS::VIEWPORT_VRS_DISABLED);
+
+ return rt->vrs_mode;
+}
+
+RID TextureStorage::render_target_get_vrs_texture(RID p_render_target) const {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+
+ return rt->vrs_texture;
+}
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index 901f764085..8807f78f6e 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -33,8 +33,8 @@
#include "core/templates/rid_owner.h"
#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/texture_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -48,10 +48,12 @@ enum DefaultRDTexture {
DEFAULT_RD_TEXTURE_CUBEMAP_BLACK,
DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK,
DEFAULT_RD_TEXTURE_CUBEMAP_WHITE,
+ DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE,
DEFAULT_RD_TEXTURE_3D_WHITE,
DEFAULT_RD_TEXTURE_3D_BLACK,
DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE,
DEFAULT_RD_TEXTURE_2D_UINT,
+ DEFAULT_RD_TEXTURE_VRS,
DEFAULT_RD_TEXTURE_MAX
};
@@ -193,7 +195,7 @@ struct Decal {
float distance_fade_length = 1;
float normal_fade = 0.0;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
struct RenderTarget {
@@ -229,6 +231,10 @@ struct RenderTarget {
RS::ViewportSDFScale sdf_scale = RS::VIEWPORT_SDF_SCALE_50_PERCENT;
Size2i process_size;
+ // VRS
+ RS::ViewportVRSMode vrs_mode = RS::VIEWPORT_VRS_DISABLED;
+ RID vrs_texture;
+
//texture generated for this owner (nor RD).
RID texture;
bool was_used;
@@ -549,6 +555,12 @@ public:
virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override;
bool render_target_is_sdf_enabled(RID p_render_target) const;
+ virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) override;
+ virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override;
+
+ RS::ViewportVRSMode render_target_get_vrs_mode(RID p_render_target) const;
+ RID render_target_get_vrs_texture(RID p_render_target) const;
+
Size2 render_target_get_size(RID p_render_target);
RID render_target_get_rd_framebuffer(RID p_render_target);
RID render_target_get_rd_texture(RID p_render_target);
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
index 8c55ff1d0a..a1f62c16c7 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* renderer_storage_rd.cpp */
+/* utilities.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,195 +28,29 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "renderer_storage_rd.h"
-
-#include "core/config/engine.h"
-#include "core/config/project_settings.h"
-#include "core/io/resource_loader.h"
-#include "core/math/math_defs.h"
-#include "renderer_compositor_rd.h"
-#include "servers/rendering/renderer_rd/environment/gi.h"
-#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
-#include "servers/rendering/rendering_server_globals.h"
-#include "servers/rendering/shader_language.h"
-
-/* FOG VOLUMES */
-
-RID RendererStorageRD::fog_volume_allocate() {
- return fog_volume_owner.allocate_rid();
-}
-void RendererStorageRD::fog_volume_initialize(RID p_rid) {
- fog_volume_owner.initialize_rid(p_rid, FogVolume());
-}
-
-void RendererStorageRD::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND(!fog_volume);
-
- if (p_shape == fog_volume->shape) {
- return;
- }
-
- fog_volume->shape = p_shape;
- fog_volume->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
-}
+#include "utilities.h"
+#include "../environment/fog.h"
+#include "../environment/gi.h"
+#include "light_storage.h"
+#include "mesh_storage.h"
+#include "particles_storage.h"
+#include "texture_storage.h"
-void RendererStorageRD::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND(!fog_volume);
+using namespace RendererRD;
- fog_volume->extents = p_extents;
- fog_volume->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
-}
+Utilities *Utilities::singleton = nullptr;
-void RendererStorageRD::fog_volume_set_material(RID p_fog_volume, RID p_material) {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND(!fog_volume);
- fog_volume->material = p_material;
+Utilities::Utilities() {
+ singleton = this;
}
-RID RendererStorageRD::fog_volume_get_material(RID p_fog_volume) const {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND_V(!fog_volume, RID());
-
- return fog_volume->material;
+Utilities::~Utilities() {
+ singleton = nullptr;
}
-RS::FogVolumeShape RendererStorageRD::fog_volume_get_shape(RID p_fog_volume) const {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND_V(!fog_volume, RS::FOG_VOLUME_SHAPE_BOX);
-
- return fog_volume->shape;
-}
+/* INSTANCES */
-AABB RendererStorageRD::fog_volume_get_aabb(RID p_fog_volume) const {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND_V(!fog_volume, AABB());
-
- switch (fog_volume->shape) {
- case RS::FOG_VOLUME_SHAPE_ELLIPSOID:
- case RS::FOG_VOLUME_SHAPE_CONE:
- case RS::FOG_VOLUME_SHAPE_CYLINDER:
- case RS::FOG_VOLUME_SHAPE_BOX: {
- AABB aabb;
- aabb.position = -fog_volume->extents;
- aabb.size = fog_volume->extents * 2;
- return aabb;
- }
- default: {
- // Need some size otherwise will get culled
- return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
- }
- }
-
- return AABB();
-}
-
-Vector3 RendererStorageRD::fog_volume_get_extents(RID p_fog_volume) const {
- const FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND_V(!fog_volume, Vector3());
- return fog_volume->extents;
-}
-
-/* VISIBILITY NOTIFIER */
-
-RID RendererStorageRD::visibility_notifier_allocate() {
- return visibility_notifier_owner.allocate_rid();
-}
-void RendererStorageRD::visibility_notifier_initialize(RID p_notifier) {
- visibility_notifier_owner.initialize_rid(p_notifier, VisibilityNotifier());
-}
-void RendererStorageRD::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
- ERR_FAIL_COND(!vn);
- vn->aabb = p_aabb;
- vn->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
-}
-void RendererStorageRD::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
- ERR_FAIL_COND(!vn);
- vn->enter_callback = p_enter_callbable;
- vn->exit_callback = p_exit_callable;
-}
-
-AABB RendererStorageRD::visibility_notifier_get_aabb(RID p_notifier) const {
- const VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
- ERR_FAIL_COND_V(!vn, AABB());
- return vn->aabb;
-}
-void RendererStorageRD::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
- ERR_FAIL_COND(!vn);
-
- if (p_enter) {
- if (!vn->enter_callback.is_null()) {
- if (p_deferred) {
- vn->enter_callback.call_deferred(nullptr, 0);
- } else {
- Variant r;
- Callable::CallError ce;
- vn->enter_callback.call(nullptr, 0, r, ce);
- }
- }
- } else {
- if (!vn->exit_callback.is_null()) {
- if (p_deferred) {
- vn->exit_callback.call_deferred(nullptr, 0);
- } else {
- Variant r;
- Callable::CallError ce;
- vn->exit_callback.call(nullptr, 0, r, ce);
- }
- }
- }
-}
-
-/* misc */
-
-void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
- if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_base)) {
- RendererRD::Mesh *mesh = RendererRD::MeshStorage::get_singleton()->get_mesh(p_base);
- p_instance->update_dependency(&mesh->dependency);
- } else if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_base)) {
- RendererRD::MultiMesh *multimesh = RendererRD::MeshStorage::get_singleton()->get_multimesh(p_base);
- p_instance->update_dependency(&multimesh->dependency);
- if (multimesh->mesh.is_valid()) {
- base_update_dependency(multimesh->mesh, p_instance);
- }
- } else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_base)) {
- RendererRD::ReflectionProbe *rp = RendererRD::LightStorage::get_singleton()->get_reflection_probe(p_base);
- p_instance->update_dependency(&rp->dependency);
- } else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_base)) {
- RendererRD::Decal *decal = RendererRD::TextureStorage::get_singleton()->get_decal(p_base);
- p_instance->update_dependency(&decal->dependency);
- } else if (RendererRD::GI::get_singleton()->owns_voxel_gi(p_base)) {
- RendererRD::GI::VoxelGI *gip = RendererRD::GI::get_singleton()->get_voxel_gi(p_base);
- p_instance->update_dependency(&gip->dependency);
- } else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_base)) {
- RendererRD::Lightmap *lm = RendererRD::LightStorage::get_singleton()->get_lightmap(p_base);
- p_instance->update_dependency(&lm->dependency);
- } else if (RendererRD::LightStorage::get_singleton()->owns_light(p_base)) {
- RendererRD::Light *l = RendererRD::LightStorage::get_singleton()->get_light(p_base);
- p_instance->update_dependency(&l->dependency);
- } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_base)) {
- RendererRD::Particles *p = RendererRD::ParticlesStorage::get_singleton()->get_particles(p_base);
- p_instance->update_dependency(&p->dependency);
- } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_base)) {
- RendererRD::ParticlesCollision *pc = RendererRD::ParticlesStorage::get_singleton()->get_particles_collision(p_base);
- p_instance->update_dependency(&pc->dependency);
- } else if (fog_volume_owner.owns(p_base)) {
- FogVolume *fv = fog_volume_owner.get_or_null(p_base);
- p_instance->update_dependency(&fv->dependency);
- } else if (visibility_notifier_owner.owns(p_base)) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_base);
- p_instance->update_dependency(&vn->dependency);
- }
-}
-
-RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
+RS::InstanceType Utilities::get_base_type(RID p_rid) const {
if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
return RS::INSTANCE_MESH;
}
@@ -244,49 +78,17 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) {
return RS::INSTANCE_PARTICLES_COLLISION;
}
- if (fog_volume_owner.owns(p_rid)) {
+ if (RendererRD::Fog::get_singleton()->owns_fog_volume(p_rid)) {
return RS::INSTANCE_FOG_VOLUME;
}
- if (visibility_notifier_owner.owns(p_rid)) {
+ if (owns_visibility_notifier(p_rid)) {
return RS::INSTANCE_VISIBLITY_NOTIFIER;
}
return RS::INSTANCE_NONE;
}
-void RendererStorageRD::update_dirty_resources() {
- RendererRD::MaterialStorage::get_singleton()->_update_global_variables(); //must do before materials, so it can queue them for update
- RendererRD::MaterialStorage::get_singleton()->_update_queued_materials();
- RendererRD::MeshStorage::get_singleton()->_update_dirty_multimeshes();
- RendererRD::MeshStorage::get_singleton()->_update_dirty_skeletons();
- RendererRD::TextureStorage::get_singleton()->update_decal_atlas();
-}
-
-bool RendererStorageRD::has_os_feature(const String &p_feature) const {
- if (!RD::get_singleton()) {
- return false;
- }
-
- if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
- return true;
- }
-
- if (p_feature == "s3tc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
- return true;
- }
-
- if (p_feature == "bptc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
- return true;
- }
-
- if ((p_feature == "etc" || p_feature == "etc2") && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
- return true;
- }
-
- return false;
-}
-
-bool RendererStorageRD::free(RID p_rid) {
+bool Utilities::free(RID p_rid) {
if (RendererRD::TextureStorage::get_singleton()->owns_texture(p_rid)) {
RendererRD::TextureStorage::get_singleton()->texture_free(p_rid);
} else if (RendererRD::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
@@ -317,16 +119,12 @@ bool RendererStorageRD::free(RID p_rid) {
RendererRD::ParticlesStorage::get_singleton()->particles_free(p_rid);
} else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) {
RendererRD::ParticlesStorage::get_singleton()->particles_collision_free(p_rid);
- } else if (visibility_notifier_owner.owns(p_rid)) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_rid);
- vn->dependency.deleted_notify(p_rid);
- visibility_notifier_owner.free(p_rid);
+ } else if (owns_visibility_notifier(p_rid)) {
+ visibility_notifier_free(p_rid);
} else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision_instance(p_rid)) {
RendererRD::ParticlesStorage::get_singleton()->particles_collision_instance_free(p_rid);
- } else if (fog_volume_owner.owns(p_rid)) {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid);
- fog_volume->dependency.deleted_notify(p_rid);
- fog_volume_owner.free(p_rid);
+ } else if (RendererRD::Fog::get_singleton()->owns_fog_volume(p_rid)) {
+ RendererRD::Fog::get_singleton()->fog_free(p_rid);
} else if (RendererRD::TextureStorage::get_singleton()->owns_render_target(p_rid)) {
RendererRD::TextureStorage::get_singleton()->render_target_free(p_rid);
} else {
@@ -336,49 +134,182 @@ bool RendererStorageRD::free(RID p_rid) {
return true;
}
-void RendererStorageRD::init_effects(bool p_prefer_raster_effects) {
- effects = memnew(EffectsRD(p_prefer_raster_effects));
+/* DEPENDENCIES */
+
+void Utilities::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
+ if (MeshStorage::get_singleton()->owns_mesh(p_base)) {
+ Mesh *mesh = MeshStorage::get_singleton()->get_mesh(p_base);
+ p_instance->update_dependency(&mesh->dependency);
+ } else if (MeshStorage::get_singleton()->owns_multimesh(p_base)) {
+ MultiMesh *multimesh = MeshStorage::get_singleton()->get_multimesh(p_base);
+ p_instance->update_dependency(&multimesh->dependency);
+ if (multimesh->mesh.is_valid()) {
+ base_update_dependency(multimesh->mesh, p_instance);
+ }
+ } else if (LightStorage::get_singleton()->owns_reflection_probe(p_base)) {
+ ReflectionProbe *rp = LightStorage::get_singleton()->get_reflection_probe(p_base);
+ p_instance->update_dependency(&rp->dependency);
+ } else if (TextureStorage::get_singleton()->owns_decal(p_base)) {
+ Decal *decal = TextureStorage::get_singleton()->get_decal(p_base);
+ p_instance->update_dependency(&decal->dependency);
+ } else if (GI::get_singleton()->owns_voxel_gi(p_base)) {
+ GI::VoxelGI *gip = GI::get_singleton()->get_voxel_gi(p_base);
+ p_instance->update_dependency(&gip->dependency);
+ } else if (LightStorage::get_singleton()->owns_lightmap(p_base)) {
+ Lightmap *lm = LightStorage::get_singleton()->get_lightmap(p_base);
+ p_instance->update_dependency(&lm->dependency);
+ } else if (LightStorage::get_singleton()->owns_light(p_base)) {
+ Light *l = LightStorage::get_singleton()->get_light(p_base);
+ p_instance->update_dependency(&l->dependency);
+ } else if (ParticlesStorage::get_singleton()->owns_particles(p_base)) {
+ Particles *p = ParticlesStorage::get_singleton()->get_particles(p_base);
+ p_instance->update_dependency(&p->dependency);
+ } else if (ParticlesStorage::get_singleton()->owns_particles_collision(p_base)) {
+ ParticlesCollision *pc = ParticlesStorage::get_singleton()->get_particles_collision(p_base);
+ p_instance->update_dependency(&pc->dependency);
+ } else if (Fog::get_singleton()->owns_fog_volume(p_base)) {
+ Fog::FogVolume *fv = Fog::get_singleton()->get_fog_volume(p_base);
+ p_instance->update_dependency(&fv->dependency);
+ } else if (owns_visibility_notifier(p_base)) {
+ VisibilityNotifier *vn = get_visibility_notifier(p_base);
+ p_instance->update_dependency(&vn->dependency);
+ }
+}
+
+/* VISIBILITY NOTIFIER */
+
+RID Utilities::visibility_notifier_allocate() {
+ return visibility_notifier_owner.allocate_rid();
+}
+
+void Utilities::visibility_notifier_initialize(RID p_notifier) {
+ visibility_notifier_owner.initialize_rid(p_notifier, VisibilityNotifier());
+}
+
+void Utilities::visibility_notifier_free(RID p_notifier) {
+ VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ vn->dependency.deleted_notify(p_notifier);
+ visibility_notifier_owner.free(p_notifier);
+}
+
+void Utilities::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) {
+ VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ ERR_FAIL_COND(!vn);
+ vn->aabb = p_aabb;
+ vn->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
+}
+
+void Utilities::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) {
+ VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ ERR_FAIL_COND(!vn);
+ vn->enter_callback = p_enter_callbable;
+ vn->exit_callback = p_exit_callable;
+}
+
+AABB Utilities::visibility_notifier_get_aabb(RID p_notifier) const {
+ const VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ ERR_FAIL_COND_V(!vn, AABB());
+ return vn->aabb;
}
-EffectsRD *RendererStorageRD::get_effects() {
- ERR_FAIL_NULL_V_MSG(effects, nullptr, "Effects haven't been initialised yet.");
- return effects;
+void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
+ VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ ERR_FAIL_COND(!vn);
+
+ if (p_enter) {
+ if (!vn->enter_callback.is_null()) {
+ if (p_deferred) {
+ vn->enter_callback.call_deferred(nullptr, 0);
+ } else {
+ Variant r;
+ Callable::CallError ce;
+ vn->enter_callback.call(nullptr, 0, r, ce);
+ }
+ }
+ } else {
+ if (!vn->exit_callback.is_null()) {
+ if (p_deferred) {
+ vn->exit_callback.call_deferred(nullptr, 0);
+ } else {
+ Variant r;
+ Callable::CallError ce;
+ vn->exit_callback.call(nullptr, 0, r, ce);
+ }
+ }
+ }
}
-void RendererStorageRD::capture_timestamps_begin() {
+/* TIMING */
+
+void Utilities::capture_timestamps_begin() {
RD::get_singleton()->capture_timestamp("Frame Begin");
}
-void RendererStorageRD::capture_timestamp(const String &p_name) {
+void Utilities::capture_timestamp(const String &p_name) {
RD::get_singleton()->capture_timestamp(p_name);
}
-uint32_t RendererStorageRD::get_captured_timestamps_count() const {
+uint32_t Utilities::get_captured_timestamps_count() const {
return RD::get_singleton()->get_captured_timestamps_count();
}
-uint64_t RendererStorageRD::get_captured_timestamps_frame() const {
+uint64_t Utilities::get_captured_timestamps_frame() const {
return RD::get_singleton()->get_captured_timestamps_frame();
}
-uint64_t RendererStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const {
+uint64_t Utilities::get_captured_timestamp_gpu_time(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index);
}
-uint64_t RendererStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const {
+uint64_t Utilities::get_captured_timestamp_cpu_time(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index);
}
-String RendererStorageRD::get_captured_timestamp_name(uint32_t p_index) const {
+String Utilities::get_captured_timestamp_name(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_name(p_index);
}
-void RendererStorageRD::update_memory_info() {
+/* MISC */
+
+void Utilities::update_dirty_resources() {
+ MaterialStorage::get_singleton()->_update_global_variables(); //must do before materials, so it can queue them for update
+ MaterialStorage::get_singleton()->_update_queued_materials();
+ MeshStorage::get_singleton()->_update_dirty_multimeshes();
+ MeshStorage::get_singleton()->_update_dirty_skeletons();
+ TextureStorage::get_singleton()->update_decal_atlas();
+}
+
+bool Utilities::has_os_feature(const String &p_feature) const {
+ if (!RD::get_singleton()) {
+ return false;
+ }
+
+ if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ if (p_feature == "s3tc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ if (p_feature == "bptc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ if ((p_feature == "etc" || p_feature == "etc2") && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ return false;
+}
+
+void Utilities::update_memory_info() {
texture_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TEXTURES);
buffer_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_BUFFERS);
total_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TOTAL);
}
-uint64_t RendererStorageRD::get_rendering_info(RS::RenderingInfo p_info) {
+
+uint64_t Utilities::get_rendering_info(RS::RenderingInfo p_info) {
if (p_info == RS::RENDERING_INFO_TEXTURE_MEM_USED) {
return texture_mem_cache;
} else if (p_info == RS::RENDERING_INFO_BUFFER_MEM_USED) {
@@ -389,31 +320,18 @@ uint64_t RendererStorageRD::get_rendering_info(RS::RenderingInfo p_info) {
return 0;
}
-String RendererStorageRD::get_video_adapter_name() const {
+String Utilities::get_video_adapter_name() const {
return RenderingDevice::get_singleton()->get_device_name();
}
-String RendererStorageRD::get_video_adapter_vendor() const {
+String Utilities::get_video_adapter_vendor() const {
return RenderingDevice::get_singleton()->get_device_vendor_name();
}
-RenderingDevice::DeviceType RendererStorageRD::get_video_adapter_type() const {
+RenderingDevice::DeviceType Utilities::get_video_adapter_type() const {
return RenderingDevice::get_singleton()->get_device_type();
}
-String RendererStorageRD::get_video_adapter_api_version() const {
+String Utilities::get_video_adapter_api_version() const {
return RenderingDevice::get_singleton()->get_device_api_version();
}
-
-RendererStorageRD *RendererStorageRD::base_singleton = nullptr;
-
-RendererStorageRD::RendererStorageRD() {
- base_singleton = this;
-}
-
-RendererStorageRD::~RendererStorageRD() {
- if (effects) {
- memdelete(effects);
- effects = nullptr;
- }
-}
diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.h b/servers/rendering/renderer_rd/storage_rd/utilities.h
new file mode 100644
index 0000000000..979e984546
--- /dev/null
+++ b/servers/rendering/renderer_rd/storage_rd/utilities.h
@@ -0,0 +1,122 @@
+/*************************************************************************/
+/* utilities.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef UTILITIES_RD_H
+#define UTILITIES_RD_H
+
+#include "core/templates/rid_owner.h"
+#include "servers/rendering/storage/utilities.h"
+
+namespace RendererRD {
+
+/* VISIBILITY NOTIFIER */
+
+struct VisibilityNotifier {
+ AABB aabb;
+ Callable enter_callback;
+ Callable exit_callback;
+ Dependency dependency;
+};
+
+class Utilities : public RendererUtilities {
+private:
+ static Utilities *singleton;
+
+ /* VISIBILITY NOTIFIER */
+
+ mutable RID_Owner<VisibilityNotifier> visibility_notifier_owner;
+
+ /* MISC */
+
+ //keep cached since it can be called form any thread
+ uint64_t texture_mem_cache = 0;
+ uint64_t buffer_mem_cache = 0;
+ uint64_t total_mem_cache = 0;
+
+public:
+ static Utilities *get_singleton() { return singleton; }
+
+ Utilities();
+ virtual ~Utilities() override;
+
+ /* INSTANCES */
+
+ virtual RS::InstanceType get_base_type(RID p_rid) const override;
+ virtual bool free(RID p_rid) override;
+
+ /* DEPENDENCIES */
+
+ virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override;
+
+ /* VISIBILITY NOTIFIER */
+
+ VisibilityNotifier *get_visibility_notifier(RID p_rid) { return visibility_notifier_owner.get_or_null(p_rid); };
+ bool owns_visibility_notifier(RID p_rid) const { return visibility_notifier_owner.owns(p_rid); };
+
+ virtual RID visibility_notifier_allocate() override;
+ virtual void visibility_notifier_initialize(RID p_notifier) override;
+ virtual void visibility_notifier_free(RID p_notifier) override;
+
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override;
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override;
+
+ virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override;
+ virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override;
+
+ /* TIMING */
+
+ virtual void capture_timestamps_begin() override;
+ virtual void capture_timestamp(const String &p_name) override;
+ virtual uint32_t get_captured_timestamps_count() const override;
+ virtual uint64_t get_captured_timestamps_frame() const override;
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override;
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override;
+ virtual String get_captured_timestamp_name(uint32_t p_index) const override;
+
+ /* MISC */
+
+ virtual void update_dirty_resources() override;
+ virtual void set_debug_generate_wireframes(bool p_generate) override {}
+
+ virtual bool has_os_feature(const String &p_feature) const override;
+
+ virtual void update_memory_info() override;
+
+ virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override;
+
+ virtual String get_video_adapter_name() const override;
+ virtual String get_video_adapter_vendor() const override;
+ virtual RenderingDevice::DeviceType get_video_adapter_type() const override;
+ virtual String get_video_adapter_api_version() const override;
+};
+
+} // namespace RendererRD
+
+#endif // !UTILITIES_RD_H
diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h
index b773ed61f4..d635c7065d 100644
--- a/servers/rendering/renderer_scene.h
+++ b/servers/rendering/renderer_scene.h
@@ -183,8 +183,8 @@ public:
virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0;
virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0;
- virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0;
- virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
+ virtual void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) = 0;
+ virtual void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) = 0;
virtual RID shadow_atlas_create() = 0;
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = true) = 0;
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index c97ca3de5e..ebb5849f85 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -470,7 +470,7 @@ void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) {
p_instance->mesh_instance = RSG::mesh_storage->mesh_instance_create(p_instance->base);
} else {
- RSG::storage->free(p_instance->mesh_instance);
+ RSG::mesh_storage->mesh_instance_free(p_instance->mesh_instance);
p_instance->mesh_instance = RID();
}
@@ -506,7 +506,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
}
if (instance->mesh_instance.is_valid()) {
- RSG::storage->free(instance->mesh_instance);
+ RSG::mesh_storage->mesh_free(instance->mesh_instance);
instance->mesh_instance = RID();
// no need to set instance data flag here, as it was freed above
}
@@ -538,7 +538,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
} break;
case RS::INSTANCE_PARTICLES_COLLISION: {
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
- RSG::storage->free(collision->instance);
+ RSG::utilities->free(collision->instance);
} break;
case RS::INSTANCE_FOG_VOLUME: {
InstanceFogVolumeData *volume = static_cast<InstanceFogVolumeData *>(instance->base_data);
@@ -607,7 +607,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
instance->base = RID();
if (p_base.is_valid()) {
- instance->base_type = RSG::storage->get_base_type(p_base);
+ instance->base_type = RSG::utilities->get_base_type(p_base);
// fix up a specific malfunctioning case before the switch, so it can be handled
if (instance->base_type == RS::INSTANCE_NONE && RendererSceneOcclusionCull::get_singleton()->is_occluder(p_base)) {
@@ -724,7 +724,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
}
//forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it
- RSG::storage->base_update_dependency(p_base, &instance->dependency_tracker);
+ RSG::utilities->base_update_dependency(p_base, &instance->dependency_tracker);
}
_instance_queue_update(instance, true, true);
@@ -1876,10 +1876,10 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
} break;
case RenderingServer::INSTANCE_FOG_VOLUME: {
- new_aabb = RSG::storage->fog_volume_get_aabb(p_instance->base);
+ new_aabb = RSG::fog->fog_volume_get_aabb(p_instance->base);
} break;
case RenderingServer::INSTANCE_VISIBLITY_NOTIFIER: {
- new_aabb = RSG::storage->visibility_notifier_get_aabb(p_instance->base);
+ new_aabb = RSG::utilities->visibility_notifier_get_aabb(p_instance->base);
} break;
case RenderingServer::INSTANCE_LIGHT: {
new_aabb = RSG::light_storage->light_get_aabb(p_instance->base);
@@ -3282,7 +3282,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario,
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(Transform3D(), CameraMatrix(), true, false);
- scene_render->render_scene(p_render_buffers, &camera_data, nullptr, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
+ scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
#endif
}
@@ -3677,7 +3677,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
p_instance->dependency_tracker.update_begin();
if (p_instance->base.is_valid()) {
- RSG::storage->base_update_dependency(p_instance->base, &p_instance->dependency_tracker);
+ RSG::utilities->base_update_dependency(p_instance->base, &p_instance->dependency_tracker);
}
if (p_instance->material_override.is_valid()) {
@@ -3785,7 +3785,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
can_cast_shadows = false;
}
- RSG::storage->base_update_dependency(mesh, &p_instance->dependency_tracker);
+ RSG::utilities->base_update_dependency(mesh, &p_instance->dependency_tracker);
}
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
bool cast_shadows = false;
@@ -3885,7 +3885,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
}
void RendererSceneCull::update_dirty_instances() {
- RSG::storage->update_dirty_resources();
+ RSG::utilities->update_dirty_resources();
while (_instance_update_list.first()) {
_update_dirty_instance(_instance_update_list.first()->self());
@@ -3978,12 +3978,12 @@ void RendererSceneCull::update_visibility_notifiers() {
if (visibility_notifier->just_visible) {
visibility_notifier->just_visible = false;
- RSG::storage->visibility_notifier_call(visibility_notifier->base, true, RSG::threaded);
+ RSG::utilities->visibility_notifier_call(visibility_notifier->base, true, RSG::threaded);
} else {
if (visibility_notifier->visible_in_frame != RSG::rasterizer->get_frame_number()) {
visible_notifier_list.remove(E);
- RSG::storage->visibility_notifier_call(visibility_notifier->base, false, RSG::threaded);
+ RSG::utilities->visibility_notifier_call(visibility_notifier->base, false, RSG::threaded);
}
}
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index d1d3484871..8c722360ae 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -42,7 +42,7 @@
#include "servers/rendering/renderer_scene.h"
#include "servers/rendering/renderer_scene_occlusion_cull.h"
#include "servers/rendering/renderer_scene_render.h"
-#include "servers/rendering/renderer_storage.h"
+#include "servers/rendering/storage/utilities.h"
#include "servers/xr/xr_interface.h"
class RendererSceneCull : public RendererScene {
@@ -470,32 +470,32 @@ public:
SelfList<InstancePair>::List pairs;
uint64_t pair_check;
- RendererStorage::DependencyTracker dependency_tracker;
+ DependencyTracker dependency_tracker;
- static void dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *tracker) {
+ static void dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *tracker) {
Instance *instance = (Instance *)tracker->userdata;
switch (p_notification) {
- case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA:
- case RendererStorage::DEPENDENCY_CHANGED_AABB: {
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA:
+ case Dependency::DEPENDENCY_CHANGED_AABB: {
singleton->_instance_queue_update(instance, true, false);
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MATERIAL: {
+ case Dependency::DEPENDENCY_CHANGED_MATERIAL: {
singleton->_instance_queue_update(instance, false, true);
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MESH:
- case RendererStorage::DEPENDENCY_CHANGED_PARTICLES:
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
- case RendererStorage::DEPENDENCY_CHANGED_DECAL:
- case RendererStorage::DEPENDENCY_CHANGED_LIGHT:
- case RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
+ case Dependency::DEPENDENCY_CHANGED_MESH:
+ case Dependency::DEPENDENCY_CHANGED_PARTICLES:
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
+ case Dependency::DEPENDENCY_CHANGED_DECAL:
+ case Dependency::DEPENDENCY_CHANGED_LIGHT:
+ case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
singleton->_instance_queue_update(instance, true, true);
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
- case RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES: {
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_BONES: {
//ignored
} break;
- case RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: {
+ case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: {
//requires repairing
if (instance->indexer_id.is_valid()) {
singleton->_unpair_instance(instance);
@@ -506,7 +506,7 @@ public:
}
}
- static void dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *tracker) {
+ static void dependency_deleted(const RID &p_dependency, DependencyTracker *tracker) {
Instance *instance = (Instance *)tracker->userdata;
if (p_dependency == instance->base) {
@@ -526,7 +526,7 @@ public:
receive_shadows = true;
visible = true;
layer_mask = 1;
- baked_light = false;
+ baked_light = true;
dynamic_gi = false;
redraw_if_visible = false;
lightmap_slice_index = 0;
@@ -1150,8 +1150,8 @@ public:
PASS8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float)
PASS3(camera_effects_set_custom_exposure, RID, bool, float)
- PASS1(shadows_quality_set, RS::ShadowQuality)
- PASS1(directional_shadow_quality_set, RS::ShadowQuality)
+ PASS1(positional_soft_shadow_filter_set_quality, RS::ShadowQuality)
+ PASS1(directional_soft_shadow_filter_set_quality, RS::ShadowQuality)
PASS2(sdfgi_set_debug_probe_select, const Vector3 &, const Vector3 &)
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index 280277c6d8..74c7d55a57 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -166,8 +166,8 @@ public:
virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0;
virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0;
- virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0;
- virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
+ virtual void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) = 0;
+ virtual void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) = 0;
virtual RID light_instance_create(RID p_light) = 0;
virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) = 0;
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index ab9ee2067f..7c9b2567d6 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -175,7 +175,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) {
void RendererViewport::_draw_viewport(Viewport *p_viewport) {
if (p_viewport->measure_render_time) {
String rt_id = "vp_begin_" + itos(p_viewport->self.get_id());
- RSG::storage->capture_timestamp(rt_id);
+ RSG::utilities->capture_timestamp(rt_id);
timestamp_vp_map[rt_id] = p_viewport->self;
}
@@ -212,7 +212,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
_configure_3d_render_buffers(p_viewport);
}
- Color bgcolor = p_viewport->transparent_bg ? Color(0, 0, 0, 0) : RSG::storage->get_default_clear_color();
+ Color bgcolor = p_viewport->transparent_bg ? Color(0, 0, 0, 0) : RSG::texture_storage->get_default_clear_color();
if (p_viewport->clear_mode != RS::VIEWPORT_CLEAR_NEVER) {
RSG::texture_storage->render_target_request_clear(p_viewport->render_target, bgcolor);
@@ -521,7 +521,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
if (p_viewport->measure_render_time) {
String rt_id = "vp_end_" + itos(p_viewport->self.get_id());
- RSG::storage->capture_timestamp(rt_id);
+ RSG::utilities->capture_timestamp(rt_id);
timestamp_vp_map[rt_id] = p_viewport->self;
}
}
@@ -1016,7 +1016,7 @@ void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas
viewport->canvas_map[p_canvas].sublayer = p_sublayer;
}
-void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits) {
+void RendererViewport::viewport_set_positional_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -1026,7 +1026,7 @@ void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size
RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size, viewport->shadow_atlas_16_bits);
}
-void RendererViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
+void RendererViewport::viewport_set_positional_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -1207,6 +1207,22 @@ RID RendererViewport::viewport_find_from_screen_attachment(DisplayServer::Window
return RID();
}
+void RendererViewport::viewport_set_vrs_mode(RID p_viewport, RS::ViewportVRSMode p_mode) {
+ Viewport *viewport = viewport_owner.get_or_null(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ RSG::texture_storage->render_target_set_vrs_mode(viewport->render_target, p_mode);
+ _configure_3d_render_buffers(viewport);
+}
+
+void RendererViewport::viewport_set_vrs_texture(RID p_viewport, RID p_texture) {
+ Viewport *viewport = viewport_owner.get_or_null(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ RSG::texture_storage->render_target_set_vrs_texture(viewport->render_target, p_texture);
+ _configure_3d_render_buffers(viewport);
+}
+
bool RendererViewport::free(RID p_rid) {
if (viewport_owner.owns(p_rid)) {
Viewport *viewport = viewport_owner.get_or_null(p_rid);
@@ -1259,7 +1275,7 @@ void RendererViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time,
}
void RendererViewport::set_default_clear_color(const Color &p_color) {
- RSG::storage->set_default_clear_color(p_color);
+ RSG::texture_storage->set_default_clear_color(p_color);
}
// Workaround for setting this on thread.
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index acab8063d1..027f2dfad6 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -255,8 +255,8 @@ public:
void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform);
void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer);
- void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = true);
- void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
+ void viewport_set_positional_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = true);
+ void viewport_set_positional_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa);
void viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode);
@@ -284,6 +284,9 @@ public:
virtual RID viewport_find_from_screen_attachment(DisplayServer::WindowID p_id = DisplayServer::MAIN_WINDOW_ID) const;
+ void viewport_set_vrs_mode(RID p_viewport, RS::ViewportVRSMode p_mode);
+ void viewport_set_vrs_texture(RID p_viewport, RID p_texture);
+
void handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time);
void set_default_clear_color(const Color &p_color);
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index 6fc5d0b3e8..0b76bb3051 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -64,12 +64,12 @@ Vector<uint8_t> RenderingDevice::shader_compile_spirv_from_source(ShaderStage p_
ERR_FAIL_COND_V(!compile_to_spirv_function, Vector<uint8_t>());
- return compile_to_spirv_function(p_stage, p_source_code, p_language, r_error, &device_capabilities);
+ return compile_to_spirv_function(p_stage, p_source_code, p_language, r_error, this);
}
String RenderingDevice::shader_get_spirv_cache_key() const {
if (get_spirv_cache_key_function) {
- return get_spirv_cache_key_function(&device_capabilities);
+ return get_spirv_cache_key_function(this);
}
return String();
}
@@ -279,6 +279,7 @@ static Vector<RenderingDevice::PipelineSpecializationConstant> _get_spec_constan
}
return ret;
}
+
RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants) {
PipelineRasterizationState rasterization_state;
if (p_rasterization_state.is_valid()) {
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index 0973e29974..03aa6f7644 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -123,19 +123,10 @@ public:
DeviceFamily device_family = DEVICE_UNKNOWN;
uint32_t version_major = 1.0;
uint32_t version_minor = 0.0;
-
- // subgroup capabilities
- uint32_t subgroup_size = 0;
- uint32_t subgroup_in_shaders = 0; // Set flags using SHADER_STAGE_VERTEX_BIT, SHADER_STAGE_FRAGMENT_BIT, etc.
- uint32_t subgroup_operations = 0; // Set flags, using SubgroupOperations
-
- // features
- bool supports_multiview = false; // If true this device supports multiview options
- bool supports_fsr_half_float = false; // If true this device supports FSR scaling 3D in half float mode, otherwise use the fallback mode
};
- typedef String (*ShaderSPIRVGetCacheKeyFunction)(const Capabilities *p_capabilities);
- typedef Vector<uint8_t> (*ShaderCompileToSPIRVFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, const Capabilities *p_capabilities);
+ typedef String (*ShaderSPIRVGetCacheKeyFunction)(const RenderingDevice *p_render_device);
+ typedef Vector<uint8_t> (*ShaderCompileToSPIRVFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, const RenderingDevice *p_render_device);
typedef Vector<uint8_t> (*ShaderCacheFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language);
private:
@@ -444,6 +435,7 @@ public:
TEXTURE_USAGE_CAN_COPY_FROM_BIT = (1 << 7),
TEXTURE_USAGE_CAN_COPY_TO_BIT = (1 << 8),
TEXTURE_USAGE_INPUT_ATTACHMENT_BIT = (1 << 9),
+ TEXTURE_USAGE_VRS_ATTACHMENT_BIT = (1 << 10),
};
enum TextureSwizzle {
@@ -552,6 +544,7 @@ public:
Vector<int32_t> resolve_attachments;
Vector<int32_t> preserve_attachments;
int32_t depth_attachment = ATTACHMENT_UNUSED;
+ int32_t vrs_attachment = ATTACHMENT_UNUSED; // density map for VRS, only used if supported
};
virtual FramebufferFormatID framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, Vector<FramebufferPass> &p_passes, uint32_t p_view_count = 1) = 0;
@@ -675,6 +668,13 @@ public:
const Capabilities *get_device_capabilities() const { return &device_capabilities; };
+ enum Features {
+ SUPPORTS_MULTIVIEW,
+ SUPPORTS_FSR_HALF_FLOAT,
+ SUPPORTS_ATTACHMENT_VRS,
+ };
+ virtual bool has_feature(const Features p_feature) const = 0;
+
virtual Vector<uint8_t> shader_compile_spirv_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language = SHADER_LANGUAGE_GLSL, String *r_error = nullptr, bool p_allow_cache = true);
virtual String shader_get_spirv_cache_key() const;
@@ -1221,9 +1221,12 @@ public:
LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X,
LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y,
LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z,
+ LIMIT_SUBGROUP_SIZE,
+ LIMIT_SUBGROUP_IN_SHADERS, // Set flags using SHADER_STAGE_VERTEX_BIT, SHADER_STAGE_FRAGMENT_BIT, etc.
+ LIMIT_SUBGROUP_OPERATIONS,
};
- virtual uint64_t limit_get(Limit p_limit) = 0;
+ virtual uint64_t limit_get(Limit p_limit) const = 0;
//methods below not exposed, used by RenderingDeviceRD
virtual void prepare_screen_for_drawing() = 0;
@@ -1324,6 +1327,7 @@ VARIANT_ENUM_CAST(RenderingDevice::InitialAction)
VARIANT_ENUM_CAST(RenderingDevice::FinalAction)
VARIANT_ENUM_CAST(RenderingDevice::Limit)
VARIANT_ENUM_CAST(RenderingDevice::MemoryType)
+VARIANT_ENUM_CAST(RenderingDevice::Features)
typedef RenderingDevice RD;
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index 7e035bae80..bcd7e6a1dd 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -48,7 +48,7 @@ void RenderingServerDefault::_free(RID p_rid) {
if (unlikely(p_rid.is_null())) {
return;
}
- if (RSG::storage->free(p_rid)) {
+ if (RSG::utilities->free(p_rid)) {
return;
}
if (RSG::canvas->free(p_rid)) {
@@ -116,35 +116,35 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
}
RS::get_singleton()->emit_signal(SNAME("frame_post_draw"));
- if (RSG::storage->get_captured_timestamps_count()) {
+ if (RSG::utilities->get_captured_timestamps_count()) {
Vector<FrameProfileArea> new_profile;
- if (RSG::storage->capturing_timestamps) {
- new_profile.resize(RSG::storage->get_captured_timestamps_count());
+ if (RSG::utilities->capturing_timestamps) {
+ new_profile.resize(RSG::utilities->get_captured_timestamps_count());
}
- uint64_t base_cpu = RSG::storage->get_captured_timestamp_cpu_time(0);
- uint64_t base_gpu = RSG::storage->get_captured_timestamp_gpu_time(0);
- for (uint32_t i = 0; i < RSG::storage->get_captured_timestamps_count(); i++) {
- uint64_t time_cpu = RSG::storage->get_captured_timestamp_cpu_time(i);
- uint64_t time_gpu = RSG::storage->get_captured_timestamp_gpu_time(i);
+ uint64_t base_cpu = RSG::utilities->get_captured_timestamp_cpu_time(0);
+ uint64_t base_gpu = RSG::utilities->get_captured_timestamp_gpu_time(0);
+ for (uint32_t i = 0; i < RSG::utilities->get_captured_timestamps_count(); i++) {
+ uint64_t time_cpu = RSG::utilities->get_captured_timestamp_cpu_time(i);
+ uint64_t time_gpu = RSG::utilities->get_captured_timestamp_gpu_time(i);
- String name = RSG::storage->get_captured_timestamp_name(i);
+ String name = RSG::utilities->get_captured_timestamp_name(i);
if (name.begins_with("vp_")) {
RSG::viewport->handle_timestamp(name, time_cpu, time_gpu);
}
- if (RSG::storage->capturing_timestamps) {
+ if (RSG::utilities->capturing_timestamps) {
new_profile.write[i].gpu_msec = double((time_gpu - base_gpu) / 1000) / 1000.0;
new_profile.write[i].cpu_msec = double(time_cpu - base_cpu) / 1000.0;
- new_profile.write[i].name = RSG::storage->get_captured_timestamp_name(i);
+ new_profile.write[i].name = RSG::utilities->get_captured_timestamp_name(i);
}
}
frame_profile = new_profile;
}
- frame_profile_frame = RSG::storage->get_captured_timestamps_frame();
+ frame_profile_frame = RSG::utilities->get_captured_timestamps_frame();
if (print_gpu_profile) {
if (print_frame_profile_ticks_from == 0) {
@@ -191,7 +191,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
}
}
- RSG::storage->update_memory_info();
+ RSG::utilities->update_memory_info();
}
double RenderingServerDefault::get_frame_setup_time_cpu() const {
@@ -250,27 +250,27 @@ uint64_t RenderingServerDefault::get_rendering_info(RenderingInfo p_info) {
} else if (p_info == RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME) {
return RSG::viewport->get_total_draw_calls_used();
}
- return RSG::storage->get_rendering_info(p_info);
+ return RSG::utilities->get_rendering_info(p_info);
}
String RenderingServerDefault::get_video_adapter_name() const {
- return RSG::storage->get_video_adapter_name();
+ return RSG::utilities->get_video_adapter_name();
}
String RenderingServerDefault::get_video_adapter_vendor() const {
- return RSG::storage->get_video_adapter_vendor();
+ return RSG::utilities->get_video_adapter_vendor();
}
RenderingDevice::DeviceType RenderingServerDefault::get_video_adapter_type() const {
- return RSG::storage->get_video_adapter_type();
+ return RSG::utilities->get_video_adapter_type();
}
String RenderingServerDefault::get_video_adapter_api_version() const {
- return RSG::storage->get_video_adapter_api_version();
+ return RSG::utilities->get_video_adapter_api_version();
}
void RenderingServerDefault::set_frame_profiling_enabled(bool p_enable) {
- RSG::storage->capturing_timestamps = p_enable;
+ RSG::utilities->capturing_timestamps = p_enable;
}
uint64_t RenderingServerDefault::get_frame_profile_frame() {
@@ -301,7 +301,7 @@ void RenderingServerDefault::sdfgi_set_debug_probe_select(const Vector3 &p_posit
}
void RenderingServerDefault::set_print_gpu_profile(bool p_enable) {
- RSG::storage->capturing_timestamps = p_enable;
+ RSG::utilities->capturing_timestamps = p_enable;
print_gpu_profile = p_enable;
}
@@ -313,15 +313,15 @@ RID RenderingServerDefault::get_test_cube() {
}
bool RenderingServerDefault::has_os_feature(const String &p_feature) const {
- if (RSG::storage) {
- return RSG::storage->has_os_feature(p_feature);
+ if (RSG::utilities) {
+ return RSG::utilities->has_os_feature(p_feature);
} else {
return false;
}
}
void RenderingServerDefault::set_debug_generate_wireframes(bool p_generate) {
- RSG::storage->set_debug_generate_wireframes(p_generate);
+ RSG::utilities->set_debug_generate_wireframes(p_generate);
}
bool RenderingServerDefault::is_low_end() const {
@@ -399,13 +399,14 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
RendererSceneCull *sr = memnew(RendererSceneCull);
RSG::scene = sr;
RSG::rasterizer = RendererCompositor::create();
+ RSG::utilities = RSG::rasterizer->get_utilities();
RSG::light_storage = RSG::rasterizer->get_light_storage();
RSG::material_storage = RSG::rasterizer->get_material_storage();
RSG::mesh_storage = RSG::rasterizer->get_mesh_storage();
RSG::particles_storage = RSG::rasterizer->get_particles_storage();
RSG::texture_storage = RSG::rasterizer->get_texture_storage();
RSG::gi = RSG::rasterizer->get_gi();
- RSG::storage = RSG::rasterizer->get_storage();
+ RSG::fog = RSG::rasterizer->get_fog();
RSG::canvas_render = RSG::rasterizer->get_canvas();
sr->set_scene_render(RSG::rasterizer->get_scene());
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index aef89619db..429b8a06e2 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -31,7 +31,6 @@
#ifndef RENDERING_SERVER_DEFAULT_H
#define RENDERING_SERVER_DEFAULT_H
-#include "core/math/octree.h"
#include "core/templates/command_queue_mt.h"
#include "core/templates/hash_map.h"
#include "renderer_canvas_cull.h"
@@ -524,8 +523,8 @@ public:
#undef ServerName
#undef server_name
-#define ServerName RendererStorage
-#define server_name RSG::storage
+#define ServerName RendererFog
+#define server_name RSG::fog
FUNCRIDSPLIT(fog_volume)
@@ -535,6 +534,12 @@ public:
/* VISIBILITY_NOTIFIER */
+#undef ServerName
+#undef server_name
+
+#define ServerName RendererUtilities
+#define server_name RSG::utilities
+
FUNCRIDSPLIT(visibility_notifier)
FUNC2(visibility_notifier_set_aabb, RID, const AABB &)
FUNC3(visibility_notifier_set_callbacks, RID, const Callable &, const Callable &)
@@ -610,9 +615,9 @@ public:
FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
FUNC4(viewport_set_canvas_stacking, RID, RID, int, int)
- FUNC3(viewport_set_shadow_atlas_size, RID, int, bool)
+ FUNC3(viewport_set_positional_shadow_atlas_size, RID, int, bool)
FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale)
- FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
+ FUNC3(viewport_set_positional_shadow_atlas_quadrant_subdivision, RID, int, int)
FUNC2(viewport_set_msaa, RID, ViewportMSAA)
FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)
FUNC2(viewport_set_use_taa, RID, bool)
@@ -632,6 +637,9 @@ public:
FUNC2(call_set_vsync_mode, DisplayServer::VSyncMode, DisplayServer::WindowID)
+ FUNC2(viewport_set_vrs_mode, RID, ViewportVRSMode)
+ FUNC2(viewport_set_vrs_texture, RID, RID)
+
/* ENVIRONMENT API */
#undef server_name
@@ -710,8 +718,8 @@ public:
FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float)
FUNC3(camera_effects_set_custom_exposure, RID, bool, float)
- FUNC1(shadows_quality_set, ShadowQuality);
- FUNC1(directional_shadow_quality_set, ShadowQuality);
+ FUNC1(positional_soft_shadow_filter_set_quality, ShadowQuality);
+ FUNC1(directional_soft_shadow_filter_set_quality, ShadowQuality);
FUNC1(decals_set_filter, RS::DecalFilter);
FUNC1(light_projectors_set_filter, RS::LightProjectorFilter);
diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp
index 1c2a275265..46fa49e683 100644
--- a/servers/rendering/rendering_server_globals.cpp
+++ b/servers/rendering/rendering_server_globals.cpp
@@ -32,13 +32,14 @@
bool RenderingServerGlobals::threaded = false;
+RendererUtilities *RenderingServerGlobals::utilities = nullptr;
RendererLightStorage *RenderingServerGlobals::light_storage = nullptr;
RendererMaterialStorage *RenderingServerGlobals::material_storage = nullptr;
RendererMeshStorage *RenderingServerGlobals::mesh_storage = nullptr;
RendererParticlesStorage *RenderingServerGlobals::particles_storage = nullptr;
RendererTextureStorage *RenderingServerGlobals::texture_storage = nullptr;
RendererGI *RenderingServerGlobals::gi = nullptr;
-RendererStorage *RenderingServerGlobals::storage = nullptr;
+RendererFog *RenderingServerGlobals::fog = nullptr;
RendererCanvasRender *RenderingServerGlobals::canvas_render = nullptr;
RendererCompositor *RenderingServerGlobals::rasterizer = nullptr;
diff --git a/servers/rendering/rendering_server_globals.h b/servers/rendering/rendering_server_globals.h
index 91712f2a51..87d69984f8 100644
--- a/servers/rendering/rendering_server_globals.h
+++ b/servers/rendering/rendering_server_globals.h
@@ -31,6 +31,7 @@
#ifndef RENDERING_SERVER_GLOBALS_H
#define RENDERING_SERVER_GLOBALS_H
+#include "servers/rendering/environment/renderer_fog.h"
#include "servers/rendering/environment/renderer_gi.h"
#include "servers/rendering/renderer_canvas_cull.h"
#include "servers/rendering/renderer_canvas_render.h"
@@ -40,6 +41,7 @@
#include "servers/rendering/storage/mesh_storage.h"
#include "servers/rendering/storage/particles_storage.h"
#include "servers/rendering/storage/texture_storage.h"
+#include "servers/rendering/storage/utilities.h"
class RendererCanvasCull;
class RendererViewport;
@@ -49,13 +51,14 @@ class RenderingServerGlobals {
public:
static bool threaded;
+ static RendererUtilities *utilities;
static RendererLightStorage *light_storage;
static RendererMaterialStorage *material_storage;
static RendererMeshStorage *mesh_storage;
static RendererParticlesStorage *particles_storage;
static RendererTextureStorage *texture_storage;
static RendererGI *gi;
- static RendererStorage *storage;
+ static RendererFog *fog;
static RendererCanvasRender *canvas_render;
static RendererCompositor *rasterizer;
diff --git a/servers/rendering/storage/light_storage.h b/servers/rendering/storage/light_storage.h
index 0cb0f35570..f627e46e52 100644
--- a/servers/rendering/storage/light_storage.h
+++ b/servers/rendering/storage/light_storage.h
@@ -31,7 +31,6 @@
#ifndef LIGHT_STORAGE_H
#define LIGHT_STORAGE_H
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
class RendererLightStorage {
diff --git a/servers/rendering/storage/material_storage.h b/servers/rendering/storage/material_storage.h
index f0363f129a..00790106af 100644
--- a/servers/rendering/storage/material_storage.h
+++ b/servers/rendering/storage/material_storage.h
@@ -31,8 +31,8 @@
#ifndef MATERIAL_STORAGE_H
#define MATERIAL_STORAGE_H
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
+#include "utilities.h"
class RendererMaterialStorage {
public:
@@ -95,7 +95,7 @@ public:
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0;
- virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) = 0;
+ virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0;
};
#endif // !MATERIAL_STORAGE_H
diff --git a/servers/rendering/storage/mesh_storage.h b/servers/rendering/storage/mesh_storage.h
index 1dac51319c..146f6fde40 100644
--- a/servers/rendering/storage/mesh_storage.h
+++ b/servers/rendering/storage/mesh_storage.h
@@ -31,8 +31,8 @@
#ifndef MESH_STORAGE_H
#define MESH_STORAGE_H
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
+#include "utilities.h"
class RendererMeshStorage {
public:
@@ -130,7 +130,7 @@ public:
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
- virtual void skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) = 0;
+ virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
};
#endif // !MESH_STORAGE_H
diff --git a/servers/rendering/storage/particles_storage.h b/servers/rendering/storage/particles_storage.h
index 268b5473e2..eba68210a5 100644
--- a/servers/rendering/storage/particles_storage.h
+++ b/servers/rendering/storage/particles_storage.h
@@ -31,7 +31,6 @@
#ifndef PARTICLES_STORAGE_H
#define PARTICLES_STORAGE_H
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
class RendererParticlesStorage {
diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h
index e3a969d032..92238c19ee 100644
--- a/servers/rendering/storage/texture_storage.h
+++ b/servers/rendering/storage/texture_storage.h
@@ -34,7 +34,18 @@
#include "servers/rendering_server.h"
class RendererTextureStorage {
+private:
+ Color default_clear_color;
+
public:
+ void set_default_clear_color(const Color &p_color) {
+ default_clear_color = p_color;
+ }
+
+ Color get_default_clear_color() const {
+ return default_clear_color;
+ }
+
/* Canvas Texture API */
virtual RID canvas_texture_allocate() = 0;
@@ -132,6 +143,9 @@ public:
virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0;
virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0;
virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) = 0;
+
+ virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) = 0;
+ virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) = 0;
};
#endif // !TEXTURE_STORAGE_H
diff --git a/servers/rendering/renderer_storage.cpp b/servers/rendering/storage/utilities.cpp
index 56409ae187..7cc6417a25 100644
--- a/servers/rendering/renderer_storage.cpp
+++ b/servers/rendering/storage/utilities.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* renderer_storage.cpp */
+/* utilities.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "renderer_storage.h"
+#include "utilities.h"
-RendererStorage *RendererStorage::base_singleton = nullptr;
-
-void RendererStorage::Dependency::changed_notify(DependencyChangedNotification p_notification) {
+void Dependency::changed_notify(DependencyChangedNotification p_notification) {
for (const KeyValue<DependencyTracker *, uint32_t> &E : instances) {
if (E.key->changed_callback) {
E.key->changed_callback(p_notification, E.key);
@@ -40,7 +38,7 @@ void RendererStorage::Dependency::changed_notify(DependencyChangedNotification p
}
}
-void RendererStorage::Dependency::deleted_notify(const RID &p_rid) {
+void Dependency::deleted_notify(const RID &p_rid) {
for (const KeyValue<DependencyTracker *, uint32_t> &E : instances) {
if (E.key->deleted_callback) {
E.key->deleted_callback(p_rid, E.key);
@@ -52,7 +50,7 @@ void RendererStorage::Dependency::deleted_notify(const RID &p_rid) {
instances.clear();
}
-RendererStorage::Dependency::~Dependency() {
+Dependency::~Dependency() {
#ifdef DEBUG_ENABLED
if (instances.size()) {
WARN_PRINT("Leaked instance dependency: Bug - did not call instance_notify_deleted when freeing.");
@@ -62,7 +60,3 @@ RendererStorage::Dependency::~Dependency() {
}
#endif
}
-
-RendererStorage::RendererStorage() {
- base_singleton = this;
-}
diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/storage/utilities.h
index 859950673e..4d7c34383c 100644
--- a/servers/rendering/renderer_storage.h
+++ b/servers/rendering/storage/utilities.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* renderer_storage.h */
+/* utilities.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,14 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RENDERINGSERVERSTORAGE_H
-#define RENDERINGSERVERSTORAGE_H
+#ifndef RENDERER_UTILITIES_H
+#define RENDERER_UTILITIES_H
#include "servers/rendering_server.h"
-class RendererStorage {
- Color default_clear_color;
+class DependencyTracker;
+class Dependency {
public:
enum DependencyChangedNotification {
DEPENDENCY_CHANGED_AABB,
@@ -52,137 +52,113 @@ public:
DEPENDENCY_CHANGED_REFLECTION_PROBE,
};
- struct DependencyTracker;
+ void changed_notify(DependencyChangedNotification p_notification);
+ void deleted_notify(const RID &p_rid);
- struct Dependency {
- void changed_notify(DependencyChangedNotification p_notification);
- void deleted_notify(const RID &p_rid);
+ ~Dependency();
- ~Dependency();
-
- private:
- friend struct DependencyTracker;
- HashMap<DependencyTracker *, uint32_t> instances;
- };
+private:
+ friend class DependencyTracker;
+ HashMap<DependencyTracker *, uint32_t> instances;
+};
- struct DependencyTracker {
- void *userdata = nullptr;
- typedef void (*ChangedCallback)(DependencyChangedNotification, DependencyTracker *);
- typedef void (*DeletedCallback)(const RID &, DependencyTracker *);
+class DependencyTracker {
+public:
+ void *userdata = nullptr;
+ typedef void (*ChangedCallback)(Dependency::DependencyChangedNotification, DependencyTracker *);
+ typedef void (*DeletedCallback)(const RID &, DependencyTracker *);
- ChangedCallback changed_callback = nullptr;
- DeletedCallback deleted_callback = nullptr;
+ ChangedCallback changed_callback = nullptr;
+ DeletedCallback deleted_callback = nullptr;
- void update_begin() { // call before updating dependencies
- instance_version++;
- }
+ void update_begin() { // call before updating dependencies
+ instance_version++;
+ }
- void update_dependency(Dependency *p_dependency) { //called internally, can't be used directly, use update functions in Storage
- dependencies.insert(p_dependency);
- p_dependency->instances[this] = instance_version;
- }
+ void update_dependency(Dependency *p_dependency) { //called internally, can't be used directly, use update functions in Storage
+ dependencies.insert(p_dependency);
+ p_dependency->instances[this] = instance_version;
+ }
- void update_end() { //call after updating dependencies
- List<Pair<Dependency *, DependencyTracker *>> to_clean_up;
-
- for (Dependency *E : dependencies) {
- Dependency *dep = E;
- HashMap<DependencyTracker *, uint32_t>::Iterator F = dep->instances.find(this);
- ERR_CONTINUE(!F);
- if (F->value != instance_version) {
- Pair<Dependency *, DependencyTracker *> p;
- p.first = dep;
- p.second = F->key;
- to_clean_up.push_back(p);
- }
+ void update_end() { //call after updating dependencies
+ List<Pair<Dependency *, DependencyTracker *>> to_clean_up;
+
+ for (Dependency *E : dependencies) {
+ Dependency *dep = E;
+ HashMap<DependencyTracker *, uint32_t>::Iterator F = dep->instances.find(this);
+ ERR_CONTINUE(!F);
+ if (F->value != instance_version) {
+ Pair<Dependency *, DependencyTracker *> p;
+ p.first = dep;
+ p.second = F->key;
+ to_clean_up.push_back(p);
}
+ }
- while (to_clean_up.size()) {
- to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second);
- dependencies.erase(to_clean_up.front()->get().first);
- to_clean_up.pop_front();
- }
+ while (to_clean_up.size()) {
+ to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second);
+ dependencies.erase(to_clean_up.front()->get().first);
+ to_clean_up.pop_front();
}
+ }
- void clear() { // clear all dependencies
- for (Dependency *E : dependencies) {
- Dependency *dep = E;
- dep->instances.erase(this);
- }
- dependencies.clear();
+ void clear() { // clear all dependencies
+ for (Dependency *E : dependencies) {
+ Dependency *dep = E;
+ dep->instances.erase(this);
}
+ dependencies.clear();
+ }
- ~DependencyTracker() { clear(); }
+ ~DependencyTracker() { clear(); }
- private:
- friend struct Dependency;
- uint32_t instance_version = 0;
- HashSet<Dependency *> dependencies;
- };
+private:
+ friend class Dependency;
+ uint32_t instance_version = 0;
+ HashSet<Dependency *> dependencies;
+};
- virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
+class RendererUtilities {
+public:
+ virtual ~RendererUtilities() {}
- /* FOG VOLUMES */
+ /* INSTANCES */
- virtual RID fog_volume_allocate() = 0;
- virtual void fog_volume_initialize(RID p_rid) = 0;
+ virtual RS::InstanceType get_base_type(RID p_rid) const = 0;
+ virtual bool free(RID p_rid) = 0;
- virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) = 0;
- virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) = 0;
- virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) = 0;
- virtual AABB fog_volume_get_aabb(RID p_fog_volume) const = 0;
- virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const = 0;
+ /* DEPENDENCIES */
+
+ virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
/* VISIBILITY NOTIFIER */
virtual RID visibility_notifier_allocate() = 0;
virtual void visibility_notifier_initialize(RID p_notifier) = 0;
+ virtual void visibility_notifier_free(RID p_notifier) = 0;
+
virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) = 0;
virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) = 0;
virtual AABB visibility_notifier_get_aabb(RID p_notifier) const = 0;
virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) = 0;
- virtual RS::InstanceType get_base_type(RID p_rid) const = 0;
- virtual bool free(RID p_rid) = 0;
-
- virtual bool has_os_feature(const String &p_feature) const = 0;
+ /* TIMING */
- virtual void update_dirty_resources() = 0;
-
- virtual void set_debug_generate_wireframes(bool p_generate) = 0;
-
- virtual void update_memory_info() = 0;
-
- virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) = 0;
- virtual String get_video_adapter_name() const = 0;
- virtual String get_video_adapter_vendor() const = 0;
- virtual RenderingDevice::DeviceType get_video_adapter_type() const = 0;
- virtual String get_video_adapter_api_version() const = 0;
-
- static RendererStorage *base_singleton;
-
- void set_default_clear_color(const Color &p_color) {
- default_clear_color = p_color;
- }
+ bool capturing_timestamps = false;
- Color get_default_clear_color() const {
- return default_clear_color;
- }
-#define TIMESTAMP_BEGIN() \
- { \
- if (RSG::storage->capturing_timestamps) \
- RSG::storage->capture_timestamps_begin(); \
+#define TIMESTAMP_BEGIN() \
+ { \
+ if (RSG::utilities->capturing_timestamps) \
+ RSG::utilities->capture_timestamps_begin(); \
}
-#define RENDER_TIMESTAMP(m_text) \
- { \
- if (RSG::storage->capturing_timestamps) \
- RSG::storage->capture_timestamp(m_text); \
+#define RENDER_TIMESTAMP(m_text) \
+ { \
+ if (RSG::utilities->capturing_timestamps) \
+ RSG::utilities->capture_timestamp(m_text); \
}
- bool capturing_timestamps = false;
-
virtual void capture_timestamps_begin() = 0;
virtual void capture_timestamp(const String &p_name) = 0;
virtual uint32_t get_captured_timestamps_count() const = 0;
@@ -191,8 +167,20 @@ public:
virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const = 0;
virtual String get_captured_timestamp_name(uint32_t p_index) const = 0;
- RendererStorage();
- virtual ~RendererStorage() {}
+ /* MISC */
+
+ virtual void update_dirty_resources() = 0;
+ virtual void set_debug_generate_wireframes(bool p_generate) = 0;
+
+ virtual bool has_os_feature(const String &p_feature) const = 0;
+
+ virtual void update_memory_info() = 0;
+
+ virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) = 0;
+ virtual String get_video_adapter_name() const = 0;
+ virtual String get_video_adapter_vendor() const = 0;
+ virtual RenderingDevice::DeviceType get_video_adapter_type() const = 0;
+ virtual String get_video_adapter_api_version() const = 0;
};
-#endif // RENDERINGSERVERSTORAGE_H
+#endif // !RENDERER_UTILITIES_H
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 9b407043fc..5ee12d04d9 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -1939,8 +1939,8 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY);
BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY);
- ClassDB::bind_method(D_METHOD("shadows_quality_set", "quality"), &RenderingServer::shadows_quality_set);
- ClassDB::bind_method(D_METHOD("directional_shadow_quality_set", "quality"), &RenderingServer::directional_shadow_quality_set);
+ ClassDB::bind_method(D_METHOD("positional_soft_shadow_filter_set_quality", "quality"), &RenderingServer::positional_soft_shadow_filter_set_quality);
+ ClassDB::bind_method(D_METHOD("directional_soft_shadow_filter_set_quality", "quality"), &RenderingServer::directional_soft_shadow_filter_set_quality);
ClassDB::bind_method(D_METHOD("directional_shadow_atlas_set_size", "size", "is_16bits"), &RenderingServer::directional_shadow_atlas_set_size);
BIND_ENUM_CONSTANT(SHADOW_QUALITY_HARD);
@@ -2207,8 +2207,8 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("viewport_set_sdf_oversize_and_scale", "viewport", "oversize", "scale"), &RenderingServer::viewport_set_sdf_oversize_and_scale);
- ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size", "use_16_bits"), &RenderingServer::viewport_set_shadow_atlas_size, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_shadow_atlas_quadrant_subdivision);
+ ClassDB::bind_method(D_METHOD("viewport_set_positional_shadow_atlas_size", "viewport", "size", "use_16_bits"), &RenderingServer::viewport_set_positional_shadow_atlas_size, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("viewport_set_positional_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_positional_shadow_atlas_quadrant_subdivision);
ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &RenderingServer::viewport_set_msaa);
ClassDB::bind_method(D_METHOD("viewport_set_screen_space_aa", "viewport", "mode"), &RenderingServer::viewport_set_screen_space_aa);
ClassDB::bind_method(D_METHOD("viewport_set_use_taa", "viewport", "enable"), &RenderingServer::viewport_set_use_taa);
@@ -2225,6 +2225,9 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("viewport_get_measured_render_time_gpu", "viewport"), &RenderingServer::viewport_get_measured_render_time_gpu);
+ ClassDB::bind_method(D_METHOD("viewport_set_vrs_mode", "viewport", "mode"), &RenderingServer::viewport_set_vrs_mode);
+ ClassDB::bind_method(D_METHOD("viewport_set_vrs_texture", "viewport", "texture"), &RenderingServer::viewport_set_vrs_texture);
+
BIND_ENUM_CONSTANT(VIEWPORT_SCALING_3D_MODE_BILINEAR);
BIND_ENUM_CONSTANT(VIEWPORT_SCALING_3D_MODE_FSR);
BIND_ENUM_CONSTANT(VIEWPORT_SCALING_3D_MODE_MAX);
@@ -2300,6 +2303,11 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_OCCLUDERS);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_MOTION_VECTORS);
+ BIND_ENUM_CONSTANT(VIEWPORT_VRS_DISABLED);
+ BIND_ENUM_CONSTANT(VIEWPORT_VRS_TEXTURE);
+ BIND_ENUM_CONSTANT(VIEWPORT_VRS_XR);
+ BIND_ENUM_CONSTANT(VIEWPORT_VRS_MAX);
+
/* SKY API */
ClassDB::bind_method(D_METHOD("sky_create"), &RenderingServer::sky_create);
@@ -2841,14 +2849,14 @@ void RenderingServer::init() {
GLOBAL_DEF("rendering/shadows/directional_shadow/size", 4096);
GLOBAL_DEF("rendering/shadows/directional_shadow/size.mobile", 2048);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384"));
- GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality", 2);
- GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality.mobile", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Very Low (Faster),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
+ GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_filter_quality", 2);
+ GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_filter_quality.mobile", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/soft_shadow_filter_quality", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/soft_shadow_filter_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Very Low (Faster),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
GLOBAL_DEF("rendering/shadows/directional_shadow/16_bits", true);
- GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality", 2);
- GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality.mobile", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Very Low (Faster),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
+ GLOBAL_DEF("rendering/shadows/positional_shadow/soft_shadow_filter_quality", 2);
+ GLOBAL_DEF("rendering/shadows/positional_shadow/soft_shadow_filter_quality.mobile", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/positional_shadow/soft_shadow_filter_quality", PropertyInfo(Variant::INT, "rendering/shadows/positional_shadow/soft_shadow_filter_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Very Low (Faster),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
GLOBAL_DEF("rendering/2d/shadow_atlas/size", 2048);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index ccef95f5f2..8d224f2832 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -491,8 +491,8 @@ public:
SHADOW_QUALITY_MAX
};
- virtual void shadows_quality_set(ShadowQuality p_quality) = 0;
- virtual void directional_shadow_quality_set(ShadowQuality p_quality) = 0;
+ virtual void positional_soft_shadow_filter_set_quality(ShadowQuality p_quality) = 0;
+ virtual void directional_soft_shadow_filter_set_quality(ShadowQuality p_quality) = 0;
enum LightProjectorFilter {
LIGHT_PROJECTOR_FILTER_NEAREST,
@@ -856,8 +856,8 @@ public:
virtual void viewport_set_sdf_oversize_and_scale(RID p_viewport, ViewportSDFOversize p_oversize, ViewportSDFScale p_scale) = 0;
- virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = true) = 0;
- virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0;
+ virtual void viewport_set_positional_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = true) = 0;
+ virtual void viewport_set_positional_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0;
enum ViewportMSAA {
VIEWPORT_MSAA_DISABLED,
@@ -946,6 +946,16 @@ public:
virtual RID viewport_find_from_screen_attachment(DisplayServer::WindowID p_id = DisplayServer::MAIN_WINDOW_ID) const = 0;
+ enum ViewportVRSMode {
+ VIEWPORT_VRS_DISABLED,
+ VIEWPORT_VRS_TEXTURE,
+ VIEWPORT_VRS_XR,
+ VIEWPORT_VRS_MAX,
+ };
+
+ virtual void viewport_set_vrs_mode(RID p_viewport, ViewportVRSMode p_mode) = 0;
+ virtual void viewport_set_vrs_texture(RID p_viewport, RID p_texture) = 0;
+
/* SKY API */
enum SkyMode {
@@ -1609,6 +1619,7 @@ VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw);
VARIANT_ENUM_CAST(RenderingServer::ViewportOcclusionCullingBuildQuality);
VARIANT_ENUM_CAST(RenderingServer::ViewportSDFOversize);
VARIANT_ENUM_CAST(RenderingServer::ViewportSDFScale);
+VARIANT_ENUM_CAST(RenderingServer::ViewportVRSMode);
VARIANT_ENUM_CAST(RenderingServer::SkyMode);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentBG);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentAmbientSource);
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
index e9a558ac5f..47598abce7 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -127,9 +127,6 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(font_set_scale, "font_rid", "size", "scale");
GDVIRTUAL_BIND(font_get_scale, "font_rid", "size");
- GDVIRTUAL_BIND(font_set_spacing, "font_rid", "size", "spacing", "value");
- GDVIRTUAL_BIND(font_get_spacing, "font_rid", "size", "spacing");
-
GDVIRTUAL_BIND(font_get_texture_count, "font_rid", "size");
GDVIRTUAL_BIND(font_clear_textures, "font_rid", "size");
GDVIRTUAL_BIND(font_remove_texture, "font_rid", "size", "texture_index");
@@ -230,6 +227,9 @@ 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_set_spacing, "shaped", "spacing", "value");
+ GDVIRTUAL_BIND(shaped_text_get_spacing, "shaped", "spacing");
+
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");
@@ -438,12 +438,12 @@ int64_t TextServerExtension::font_get_face_count(const RID &p_font_rid) const {
return 0;
}
-void TextServerExtension::font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) {
+void TextServerExtension::font_set_style(const RID &p_font_rid, BitField<TextServer::FontStyle> p_style) {
GDVIRTUAL_CALL(font_set_style, p_font_rid, p_style);
}
-int64_t /*FontStyle*/ TextServerExtension::font_get_style(const RID &p_font_rid) const {
- int64_t ret;
+BitField<TextServer::FontStyle> TextServerExtension::font_get_style(const RID &p_font_rid) const {
+ BitField<TextServer::FontStyle> ret = 0;
if (GDVIRTUAL_CALL(font_get_style, p_font_rid, ret)) {
return ret;
}
@@ -706,18 +706,6 @@ double TextServerExtension::font_get_scale(const RID &p_font_rid, int64_t p_size
return 0.0;
}
-void TextServerExtension::font_set_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing, int64_t p_value) {
- GDVIRTUAL_CALL(font_set_spacing, p_font_rid, p_size, p_spacing, p_value);
-}
-
-int64_t TextServerExtension::font_get_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing) const {
- int64_t ret;
- if (GDVIRTUAL_CALL(font_get_spacing, p_font_rid, p_size, p_spacing, ret)) {
- return ret;
- }
- return 0;
-}
-
int64_t TextServerExtension::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
int64_t ret;
if (GDVIRTUAL_CALL(font_get_texture_count, p_font_rid, p_size, ret)) {
@@ -1132,6 +1120,18 @@ bool TextServerExtension::shaped_text_get_preserve_control(const RID &p_shaped)
return false;
}
+void TextServerExtension::shaped_text_set_spacing(const RID &p_shaped, TextServer::SpacingType p_spacing, int64_t p_value) {
+ GDVIRTUAL_CALL(shaped_text_set_spacing, p_shaped, p_spacing, p_value);
+}
+
+int64_t TextServerExtension::shaped_text_get_spacing(const RID &p_shaped, TextServer::SpacingType p_spacing) const {
+ int64_t ret;
+ if (GDVIRTUAL_CALL(shaped_text_get_spacing, p_shaped, p_spacing, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
bool TextServerExtension::shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
bool ret;
if (GDVIRTUAL_CALL(shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret)) {
@@ -1192,7 +1192,7 @@ RID TextServerExtension::shaped_text_get_parent(const RID &p_shaped) const {
return RID();
}
-double TextServerExtension::shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t p_jst_flags) {
+double TextServerExtension::shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags) {
double ret;
if (GDVIRTUAL_CALL(shaped_text_fit_to_width, p_shaped, p_width, p_jst_flags, ret)) {
return ret;
@@ -1272,7 +1272,7 @@ Vector2i TextServerExtension::shaped_text_get_range(const RID &p_shaped) const {
return Vector2i();
}
-PackedInt32Array TextServerExtension::shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start, bool p_once, int64_t p_break_flags) const {
+PackedInt32Array TextServerExtension::shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start, bool p_once, BitField<TextServer::LineBreakFlag> p_break_flags) const {
PackedInt32Array ret;
if (GDVIRTUAL_CALL(shaped_text_get_line_breaks_adv, p_shaped, p_width, p_start, p_once, p_break_flags, ret)) {
return ret;
@@ -1280,7 +1280,7 @@ PackedInt32Array TextServerExtension::shaped_text_get_line_breaks_adv(const RID
return TextServer::shaped_text_get_line_breaks_adv(p_shaped, p_width, p_start, p_once, p_break_flags);
}
-PackedInt32Array TextServerExtension::shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start, int64_t p_break_flags) const {
+PackedInt32Array TextServerExtension::shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start, BitField<TextServer::LineBreakFlag> p_break_flags) const {
PackedInt32Array ret;
if (GDVIRTUAL_CALL(shaped_text_get_line_breaks, p_shaped, p_width, p_start, p_break_flags, ret)) {
return ret;
@@ -1288,7 +1288,7 @@ PackedInt32Array TextServerExtension::shaped_text_get_line_breaks(const RID &p_s
return TextServer::shaped_text_get_line_breaks(p_shaped, p_width, p_start, p_break_flags);
}
-PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags) const {
+PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(const RID &p_shaped, BitField<TextServer::GraphemeFlag> p_grapheme_flags) const {
PackedInt32Array ret;
if (GDVIRTUAL_CALL(shaped_text_get_word_breaks, p_shaped, p_grapheme_flags, ret)) {
return ret;
@@ -1328,7 +1328,7 @@ int64_t TextServerExtension::shaped_text_get_ellipsis_glyph_count(const RID &p_s
return -1;
}
-void TextServerExtension::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, int64_t p_trim_flags) {
+void TextServerExtension::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) {
GDVIRTUAL_CALL(shaped_text_overrun_trim_to_width, p_shaped_line, p_width, p_trim_flags);
}
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index 9ca0939247..571753ea67 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -92,10 +92,10 @@ public:
virtual int64_t font_get_face_count(const RID &p_font_rid) const override;
GDVIRTUAL1RC(int64_t, font_get_face_count, RID);
- virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) override;
- virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const override;
- GDVIRTUAL2(font_set_style, RID, int64_t);
- GDVIRTUAL1RC(int64_t, font_get_style, RID);
+ virtual void font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) override;
+ virtual BitField<FontStyle> font_get_style(const RID &p_font_rid) const override;
+ GDVIRTUAL2(font_set_style, RID, BitField<FontStyle>);
+ GDVIRTUAL1RC(BitField<FontStyle>, font_get_style, RID);
virtual void font_set_name(const RID &p_font_rid, const String &p_name) override;
virtual String font_get_name(const RID &p_font_rid) const override;
@@ -204,11 +204,6 @@ public:
GDVIRTUAL3(font_set_scale, RID, int64_t, double);
GDVIRTUAL2RC(double, font_get_scale, RID, int64_t);
- virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) override;
- virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const override;
- GDVIRTUAL4(font_set_spacing, RID, int64_t, SpacingType, int64_t);
- GDVIRTUAL3RC(int64_t, font_get_spacing, RID, int64_t, SpacingType);
-
virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override;
@@ -377,6 +372,11 @@ public:
GDVIRTUAL2(shaped_text_set_preserve_control, RID, bool);
GDVIRTUAL1RC(bool, shaped_text_get_preserve_control, RID);
+ virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) override;
+ virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const override;
+ GDVIRTUAL3(shaped_text_set_spacing, RID, SpacingType, int64_t);
+ GDVIRTUAL2RC(int64_t, shaped_text_get_spacing, RID, SpacingType);
+
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override;
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
@@ -396,9 +396,9 @@ public:
GDVIRTUAL3RC(RID, shaped_text_substr, RID, int64_t, int64_t);
GDVIRTUAL1RC(RID, shaped_text_get_parent, RID);
- virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
+ virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override;
- GDVIRTUAL3R(double, shaped_text_fit_to_width, RID, double, int64_t);
+ GDVIRTUAL3R(double, shaped_text_fit_to_width, RID, double, BitField<TextServer::JustificationFlag>);
GDVIRTUAL2R(double, shaped_text_tab_align, RID, const PackedFloat32Array &);
virtual bool shaped_text_shape(const RID &p_shaped) override;
@@ -421,12 +421,12 @@ public:
virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override;
GDVIRTUAL1RC(Vector2i, shaped_text_get_range, RID);
- virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, int64_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
- virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, int64_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
- virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override;
- GDVIRTUAL5RC(PackedInt32Array, shaped_text_get_line_breaks_adv, RID, const PackedFloat32Array &, int64_t, bool, int64_t);
- GDVIRTUAL4RC(PackedInt32Array, shaped_text_get_line_breaks, RID, double, int64_t, int64_t);
- GDVIRTUAL2RC(PackedInt32Array, shaped_text_get_word_breaks, RID, int64_t);
+ virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, BitField<TextServer::LineBreakFlag> p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
+ virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, BitField<TextServer::LineBreakFlag> p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
+ virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, BitField<TextServer::GraphemeFlag> p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override;
+ GDVIRTUAL5RC(PackedInt32Array, shaped_text_get_line_breaks_adv, RID, const PackedFloat32Array &, int64_t, bool, BitField<TextServer::LineBreakFlag>);
+ GDVIRTUAL4RC(PackedInt32Array, shaped_text_get_line_breaks, RID, double, int64_t, BitField<TextServer::LineBreakFlag>);
+ GDVIRTUAL2RC(PackedInt32Array, shaped_text_get_word_breaks, RID, BitField<TextServer::GraphemeFlag>);
virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const override;
virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const override;
@@ -437,8 +437,8 @@ public:
GDVIRTUAL1RC(GDNativeConstPtr<const Glyph>, shaped_text_get_ellipsis_glyphs, RID);
GDVIRTUAL1RC(int64_t, shaped_text_get_ellipsis_glyph_count, RID);
- virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_t p_trim_flags) override;
- GDVIRTUAL3(shaped_text_overrun_trim_to_width, RID, double, int64_t);
+ virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) override;
+ GDVIRTUAL3(shaped_text_overrun_trim_to_width, RID, double, BitField<TextServer::TextOverrunFlag>);
virtual Array shaped_text_get_objects(const RID &p_shaped) const override;
virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const override;
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index fe5ade88a1..4a6b03d943 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -280,9 +280,6 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_set_scale", "font_rid", "size", "scale"), &TextServer::font_set_scale);
ClassDB::bind_method(D_METHOD("font_get_scale", "font_rid", "size"), &TextServer::font_get_scale);
- ClassDB::bind_method(D_METHOD("font_set_spacing", "font_rid", "size", "spacing", "value"), &TextServer::font_set_spacing);
- ClassDB::bind_method(D_METHOD("font_get_spacing", "font_rid", "size", "spacing"), &TextServer::font_get_spacing);
-
ClassDB::bind_method(D_METHOD("font_get_texture_count", "font_rid", "size"), &TextServer::font_get_texture_count);
ClassDB::bind_method(D_METHOD("font_clear_textures", "font_rid", "size"), &TextServer::font_clear_textures);
ClassDB::bind_method(D_METHOD("font_remove_texture", "font_rid", "size", "texture_index"), &TextServer::font_remove_texture);
@@ -383,6 +380,9 @@ 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_set_spacing", "shaped", "spacing", "value"), &TextServer::shaped_text_set_spacing);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_spacing", "shaped", "spacing"), &TextServer::shaped_text_get_spacing);
+
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));
@@ -463,12 +463,12 @@ void TextServer::_bind_methods() {
BIND_ENUM_CONSTANT(ORIENTATION_VERTICAL);
/* JustificationFlag */
- BIND_ENUM_CONSTANT(JUSTIFICATION_NONE);
- BIND_ENUM_CONSTANT(JUSTIFICATION_KASHIDA);
- BIND_ENUM_CONSTANT(JUSTIFICATION_WORD_BOUND);
- BIND_ENUM_CONSTANT(JUSTIFICATION_TRIM_EDGE_SPACES);
- BIND_ENUM_CONSTANT(JUSTIFICATION_AFTER_LAST_TAB);
- BIND_ENUM_CONSTANT(JUSTIFICATION_CONSTRAIN_ELLIPSIS);
+ BIND_BITFIELD_FLAG(JUSTIFICATION_NONE);
+ BIND_BITFIELD_FLAG(JUSTIFICATION_KASHIDA);
+ BIND_BITFIELD_FLAG(JUSTIFICATION_WORD_BOUND);
+ BIND_BITFIELD_FLAG(JUSTIFICATION_TRIM_EDGE_SPACES);
+ BIND_BITFIELD_FLAG(JUSTIFICATION_AFTER_LAST_TAB);
+ BIND_BITFIELD_FLAG(JUSTIFICATION_CONSTRAIN_ELLIPSIS);
/* AutowrapMode */
BIND_ENUM_CONSTANT(AUTOWRAP_OFF);
@@ -477,11 +477,11 @@ void TextServer::_bind_methods() {
BIND_ENUM_CONSTANT(AUTOWRAP_WORD_SMART);
/* LineBreakFlag */
- BIND_ENUM_CONSTANT(BREAK_NONE);
- BIND_ENUM_CONSTANT(BREAK_MANDATORY);
- BIND_ENUM_CONSTANT(BREAK_WORD_BOUND);
- BIND_ENUM_CONSTANT(BREAK_GRAPHEME_BOUND);
- BIND_ENUM_CONSTANT(BREAK_WORD_BOUND_ADAPTIVE);
+ BIND_BITFIELD_FLAG(BREAK_NONE);
+ BIND_BITFIELD_FLAG(BREAK_MANDATORY);
+ BIND_BITFIELD_FLAG(BREAK_WORD_BOUND);
+ BIND_BITFIELD_FLAG(BREAK_GRAPHEME_BOUND);
+ BIND_BITFIELD_FLAG(BREAK_ADAPTIVE);
/* VisibleCharactersBehavior */
BIND_ENUM_CONSTANT(VC_CHARS_BEFORE_SHAPING);
@@ -498,25 +498,25 @@ void TextServer::_bind_methods() {
BIND_ENUM_CONSTANT(OVERRUN_TRIM_WORD_ELLIPSIS);
/* TextOverrunFlag */
- BIND_ENUM_CONSTANT(OVERRUN_NO_TRIM);
- BIND_ENUM_CONSTANT(OVERRUN_TRIM);
- BIND_ENUM_CONSTANT(OVERRUN_TRIM_WORD_ONLY);
- BIND_ENUM_CONSTANT(OVERRUN_ADD_ELLIPSIS);
- BIND_ENUM_CONSTANT(OVERRUN_ENFORCE_ELLIPSIS);
- BIND_ENUM_CONSTANT(OVERRUN_JUSTIFICATION_AWARE);
+ BIND_BITFIELD_FLAG(OVERRUN_NO_TRIM);
+ BIND_BITFIELD_FLAG(OVERRUN_TRIM);
+ BIND_BITFIELD_FLAG(OVERRUN_TRIM_WORD_ONLY);
+ BIND_BITFIELD_FLAG(OVERRUN_ADD_ELLIPSIS);
+ BIND_BITFIELD_FLAG(OVERRUN_ENFORCE_ELLIPSIS);
+ BIND_BITFIELD_FLAG(OVERRUN_JUSTIFICATION_AWARE);
/* GraphemeFlag */
- BIND_ENUM_CONSTANT(GRAPHEME_IS_VALID);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_RTL);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_VIRTUAL);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_SPACE);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_BREAK_HARD);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_BREAK_SOFT);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_TAB);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_ELONGATION);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_PUNCTUATION);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_UNDERSCORE);
- BIND_ENUM_CONSTANT(GRAPHEME_IS_CONNECTED);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_VALID);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_RTL);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_VIRTUAL);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_SPACE);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_BREAK_HARD);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_BREAK_SOFT);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_TAB);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_ELONGATION);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_PUNCTUATION);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_UNDERSCORE);
+ BIND_BITFIELD_FLAG(GRAPHEME_IS_CONNECTED);
/* Hinting */
BIND_ENUM_CONSTANT(HINTING_NONE);
@@ -556,11 +556,12 @@ void TextServer::_bind_methods() {
BIND_ENUM_CONSTANT(SPACING_SPACE);
BIND_ENUM_CONSTANT(SPACING_TOP);
BIND_ENUM_CONSTANT(SPACING_BOTTOM);
+ BIND_ENUM_CONSTANT(SPACING_MAX);
/* Font Style */
- BIND_ENUM_CONSTANT(FONT_BOLD);
- BIND_ENUM_CONSTANT(FONT_ITALIC);
- BIND_ENUM_CONSTANT(FONT_FIXED_WIDTH);
+ BIND_BITFIELD_FLAG(FONT_BOLD);
+ BIND_BITFIELD_FLAG(FONT_ITALIC);
+ BIND_BITFIELD_FLAG(FONT_FIXED_WIDTH);
/* Structured text parser */
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_DEFAULT);
@@ -650,7 +651,7 @@ void TextServer::draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Ve
}
}
-PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start, bool p_once, int64_t /*TextBreakFlag*/ p_break_flags) const {
+PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start, bool p_once, BitField<TextServer::LineBreakFlag> p_break_flags) const {
PackedInt32Array lines;
ERR_FAIL_COND_V(p_width.is_empty(), lines);
@@ -687,7 +688,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
}
continue;
}
- if ((p_break_flags & BREAK_MANDATORY) == BREAK_MANDATORY) {
+ if (p_break_flags.has_flag(BREAK_MANDATORY)) {
if ((l_gl[i].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD) {
lines.push_back(line_start);
lines.push_back(l_gl[i].end);
@@ -701,12 +702,12 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
continue;
}
}
- if ((p_break_flags & BREAK_WORD_BOUND) == BREAK_WORD_BOUND) {
+ if (p_break_flags.has_flag(BREAK_WORD_BOUND)) {
if ((l_gl[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) {
last_safe_break = i;
}
}
- if ((p_break_flags & BREAK_GRAPHEME_BOUND) == BREAK_GRAPHEME_BOUND) {
+ if (p_break_flags.has_flag(BREAK_GRAPHEME_BOUND)) {
last_safe_break = i;
}
}
@@ -726,7 +727,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
return lines;
}
-PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start, int64_t /*TextBreakFlag*/ p_break_flags) const {
+PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start, BitField<TextServer::LineBreakFlag> p_break_flags) const {
PackedInt32Array lines;
const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped);
@@ -755,7 +756,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
word_count = 0;
continue;
}
- if ((p_break_flags & BREAK_MANDATORY) == BREAK_MANDATORY) {
+ if (p_break_flags.has_flag(BREAK_MANDATORY)) {
if ((l_gl[i].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD) {
lines.push_back(line_start);
lines.push_back(l_gl[i].end);
@@ -765,16 +766,16 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
continue;
}
}
- if ((p_break_flags & BREAK_WORD_BOUND) == BREAK_WORD_BOUND) {
+ if (p_break_flags.has_flag(BREAK_WORD_BOUND)) {
if ((l_gl[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) {
last_safe_break = i;
word_count++;
}
+ if (p_break_flags.has_flag(BREAK_ADAPTIVE) && word_count == 0) {
+ last_safe_break = i;
+ }
}
- if (((p_break_flags & BREAK_WORD_BOUND_ADAPTIVE) == BREAK_WORD_BOUND_ADAPTIVE) && word_count == 0) {
- last_safe_break = i;
- }
- if ((p_break_flags & BREAK_GRAPHEME_BOUND) == BREAK_GRAPHEME_BOUND) {
+ if (p_break_flags.has_flag(BREAK_GRAPHEME_BOUND)) {
last_safe_break = i;
}
}
@@ -794,7 +795,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
return lines;
}
-PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags) const {
+PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, BitField<TextServer::GraphemeFlag> p_grapheme_flags) const {
PackedInt32Array words;
const_cast<TextServer *>(this)->shaped_text_update_justification_ops(p_shaped);
diff --git a/servers/text_server.h b/servers/text_server.h
index 6339dde0ea..f6ab165bfc 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -79,12 +79,12 @@ public:
AUTOWRAP_WORD_SMART
};
- enum LineBreakFlag { // LineBreakFlag can be passed in the same value as the JustificationFlag, do not use the same values.
+ enum LineBreakFlag {
BREAK_NONE = 0,
- BREAK_MANDATORY = 1 << 5,
- BREAK_WORD_BOUND = 1 << 6,
- BREAK_GRAPHEME_BOUND = 1 << 7,
- BREAK_WORD_BOUND_ADAPTIVE = 1 << 6 | 1 << 8,
+ BREAK_MANDATORY = 1 << 0,
+ BREAK_WORD_BOUND = 1 << 1,
+ BREAK_GRAPHEME_BOUND = 1 << 2,
+ BREAK_ADAPTIVE = 1 << 3,
};
enum OverrunBehavior {
@@ -161,6 +161,7 @@ public:
SPACING_SPACE,
SPACING_TOP,
SPACING_BOTTOM,
+ SPACING_MAX,
};
enum FontStyle {
@@ -217,8 +218,8 @@ public:
virtual int64_t font_get_face_count(const RID &p_font_rid) const = 0;
- virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) = 0;
- virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const = 0;
+ virtual void font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) = 0;
+ virtual BitField<FontStyle> font_get_style(const RID &p_font_rid) const = 0;
virtual void font_set_name(const RID &p_font_rid, const String &p_name) = 0;
virtual String font_get_name(const RID &p_font_rid) const = 0;
@@ -284,9 +285,6 @@ public:
virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) = 0;
virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const = 0;
- virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) = 0;
- virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const = 0;
-
virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const = 0;
virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) = 0;
virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) = 0;
@@ -386,6 +384,9 @@ public:
virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) = 0;
virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const = 0;
+ virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) = 0;
+ virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const = 0;
+
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0;
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) = 0;
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0;
@@ -397,7 +398,7 @@ public:
virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range.
virtual RID shaped_text_get_parent(const RID &p_shaped) const = 0;
- virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0;
+ virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0;
virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) = 0;
virtual bool shaped_text_shape(const RID &p_shaped) = 0;
@@ -414,9 +415,9 @@ public:
virtual Vector2i shaped_text_get_range(const RID &p_shaped) const = 0;
- virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, int64_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
- virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, int64_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
- virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const;
+ virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, BitField<TextServer::LineBreakFlag> p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
+ virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, BitField<TextServer::LineBreakFlag> p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
+ virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, BitField<TextServer::GraphemeFlag> p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const;
virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const = 0;
virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const = 0;
@@ -424,7 +425,7 @@ public:
Array _shaped_text_get_ellipsis_glyphs_wrapper(const RID &p_shaped) const;
virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const = 0;
- virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_t p_trim_flags) = 0;
+ virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) = 0;
virtual Array shaped_text_get_objects(const RID &p_shaped) const = 0;
virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const = 0;
@@ -550,16 +551,16 @@ VARIANT_ENUM_CAST(TextServer::AutowrapMode);
VARIANT_ENUM_CAST(TextServer::OverrunBehavior);
VARIANT_ENUM_CAST(TextServer::Direction);
VARIANT_ENUM_CAST(TextServer::Orientation);
-VARIANT_ENUM_CAST(TextServer::JustificationFlag);
-VARIANT_ENUM_CAST(TextServer::LineBreakFlag);
-VARIANT_ENUM_CAST(TextServer::TextOverrunFlag);
-VARIANT_ENUM_CAST(TextServer::GraphemeFlag);
+VARIANT_BITFIELD_CAST(TextServer::JustificationFlag);
+VARIANT_BITFIELD_CAST(TextServer::LineBreakFlag);
+VARIANT_BITFIELD_CAST(TextServer::TextOverrunFlag);
+VARIANT_BITFIELD_CAST(TextServer::GraphemeFlag);
VARIANT_ENUM_CAST(TextServer::Hinting);
VARIANT_ENUM_CAST(TextServer::SubpixelPositioning);
VARIANT_ENUM_CAST(TextServer::Feature);
VARIANT_ENUM_CAST(TextServer::ContourPointTag);
VARIANT_ENUM_CAST(TextServer::SpacingType);
-VARIANT_ENUM_CAST(TextServer::FontStyle);
+VARIANT_BITFIELD_CAST(TextServer::FontStyle);
VARIANT_ENUM_CAST(TextServer::StructuredTextParser);
GDVIRTUAL_NATIVE_PTR(Glyph);
diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp
index 7ae111b5e7..0808b1fd7b 100644
--- a/servers/xr/xr_interface.cpp
+++ b/servers/xr/xr_interface.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "xr_interface.h"
-// #include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_compositor.h"
void XRInterface::_bind_methods() {
ADD_SIGNAL(MethodInfo("play_area_changed", PropertyInfo(Variant::INT, "mode")));
@@ -114,7 +114,12 @@ void XRInterface::set_primary(bool p_primary) {
XRInterface::XRInterface() {}
-XRInterface::~XRInterface() {}
+XRInterface::~XRInterface() {
+ if (vrs.vrs_texture.is_valid()) {
+ RS::get_singleton()->free(vrs.vrs_texture);
+ vrs.vrs_texture = RID();
+ }
+}
// query if this interface supports this play area mode
bool XRInterface::supports_play_area_mode(XRInterface::PlayAreaMode p_mode) {
@@ -151,6 +156,85 @@ int XRInterface::get_camera_feed_id() {
return 0;
}
+RID XRInterface::get_vrs_texture() {
+ // Default logic will return a standard VRS image based on our target size and default projections.
+ // Note that this only gets called if VRS is supported on the hardware.
+
+ Size2 texel_size = Size2(16.0, 16.0); // For now we assume we always use 16x16 texels, seems to be the standard.
+ int view_count = get_view_count();
+ Size2 target_size = get_render_target_size();
+ real_t aspect = target_size.x / target_size.y; // is this y/x ?
+ Size2 vrs_size = Size2(round(0.5 + target_size.x / texel_size.x), round(0.5 + target_size.y / texel_size.y));
+ real_t radius = vrs_size.length() * 0.5;
+ Size2 vrs_sizei = vrs_size;
+
+ if (vrs.size != vrs_sizei) {
+ const uint8_t densities[] = {
+ 0, // 1x1
+ 1, // 1x2
+ // 4, // 2x1
+ 5, // 2x2
+ 6, // 2x4
+ // 9, // 4x2
+ 10, // 4x4
+ };
+
+ // out with the old
+ if (vrs.vrs_texture.is_valid()) {
+ RS::get_singleton()->free(vrs.vrs_texture);
+ vrs.vrs_texture = RID();
+ }
+
+ // in with the new
+ Vector<Ref<Image>> images;
+ vrs.size = vrs_sizei;
+
+ for (int i = 0; i < view_count && i < 2; i++) {
+ PackedByteArray data;
+ data.resize(vrs_sizei.x * vrs_sizei.y);
+ uint8_t *data_ptr = data.ptrw();
+
+ // Our near and far don't matter much for what we're doing here, but there are some interfaces that will remember this as the near and far and may fail as a result...
+ CameraMatrix cm = get_projection_for_view(i, aspect, 0.1, 1000.0);
+ Vector3 center = cm.xform(Vector3(0.0, 0.0, 999.0));
+
+ Vector2i view_center;
+ view_center.x = int(vrs_size.x * (center.x + 1.0) * 0.5);
+ view_center.y = int(vrs_size.y * (center.y + 1.0) * 0.5);
+
+ int d = 0;
+ for (int y = 0; y < vrs_sizei.y; y++) {
+ for (int x = 0; x < vrs_sizei.x; x++) {
+ Vector2 offset = Vector2(x - view_center.x, y - view_center.y);
+ offset.y *= aspect;
+ real_t distance = offset.length();
+ int idx = round(5.0 * distance / radius);
+ if (idx > 4) {
+ idx = 4;
+ }
+ uint8_t density = densities[idx];
+
+ data_ptr[d++] = density;
+ }
+ }
+
+ Ref<Image> image;
+ image.instantiate();
+ image->create_from_data(vrs_sizei.x, vrs_sizei.y, false, Image::FORMAT_R8, data);
+
+ images.push_back(image);
+ }
+
+ if (images.size() == 1) {
+ vrs.vrs_texture = RS::get_singleton()->texture_2d_create(images[0]);
+ } else {
+ vrs.vrs_texture = RS::get_singleton()->texture_2d_layered_create(images, RS::TEXTURE_LAYERED_2D_ARRAY);
+ }
+ }
+
+ return vrs.vrs_texture;
+}
+
/** these are optional, so we want dummies **/
PackedStringArray XRInterface::get_suggested_tracker_names() const {
PackedStringArray arr;
diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h
index 62eba2f00b..b4eb4694f6 100644
--- a/servers/xr/xr_interface.h
+++ b/servers/xr/xr_interface.h
@@ -120,6 +120,7 @@ public:
virtual Transform3D get_camera_transform() = 0; /* returns the position of our camera for updating our camera node. For monoscopic this is equal to the views transform, for stereoscopic this should be an average */
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) = 0; /* get each views transform */
virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) = 0; /* get each view projection matrix */
+ virtual RID get_vrs_texture(); /* obtain VRS texture */
// note, external color/depth/vrs texture support will be added here soon.
@@ -133,6 +134,12 @@ public:
XRInterface();
~XRInterface();
+
+private:
+ struct VRSData {
+ RID vrs_texture;
+ Size2i size;
+ } vrs;
};
VARIANT_ENUM_CAST(XRInterface::Capabilities);
diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp
index a0bec0f95b..94953c69a9 100644
--- a/servers/xr/xr_interface_extension.cpp
+++ b/servers/xr/xr_interface_extension.cpp
@@ -29,9 +29,7 @@
/*************************************************************************/
#include "xr_interface_extension.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/rendering_server_globals.h"
void XRInterfaceExtension::_bind_methods() {
@@ -52,6 +50,7 @@ void XRInterfaceExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_camera_transform);
GDVIRTUAL_BIND(_get_transform_for_view, "view", "cam_transform");
GDVIRTUAL_BIND(_get_projection_for_view, "view", "aspect", "z_near", "z_far");
+ GDVIRTUAL_BIND(_get_vrs_texture);
GDVIRTUAL_BIND(_process);
GDVIRTUAL_BIND(_pre_render);
@@ -275,6 +274,15 @@ CameraMatrix XRInterfaceExtension::get_projection_for_view(uint32_t p_view, doub
return CameraMatrix();
}
+RID XRInterfaceExtension::get_vrs_texture() {
+ RID vrs_texture;
+ if (GDVIRTUAL_CALL(_get_vrs_texture, vrs_texture)) {
+ return vrs_texture;
+ } else {
+ return XRInterface::get_vrs_texture();
+ }
+}
+
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;
diff --git a/servers/xr/xr_interface_extension.h b/servers/xr/xr_interface_extension.h
index 5a436b9fd0..7174b412c5 100644
--- a/servers/xr/xr_interface_extension.h
+++ b/servers/xr/xr_interface_extension.h
@@ -101,12 +101,14 @@ 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 RID get_vrs_texture() override;
GDVIRTUAL0R(Size2, _get_render_target_size);
GDVIRTUAL0R(uint32_t, _get_view_count);
GDVIRTUAL0R(Transform3D, _get_camera_transform);
GDVIRTUAL2R(Transform3D, _get_transform_for_view, uint32_t, const Transform3D &);
GDVIRTUAL4R(PackedFloat64Array, _get_projection_for_view, uint32_t, double, double, double);
+ GDVIRTUAL0R(RID, _get_vrs_texture);
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);
diff --git a/tests/core/io/test_image.h b/tests/core/io/test_image.h
index 1c778c3228..e6e23912d3 100644
--- a/tests/core/io/test_image.h
+++ b/tests/core/io/test_image.h
@@ -161,8 +161,8 @@ TEST_CASE("[Image] Basic getters") {
CHECK(image->get_height() == 4);
CHECK(image->get_size() == Vector2(8, 4));
CHECK(image->get_format() == Image::FORMAT_LA8);
- CHECK(image->get_used_rect() == Rect2(0, 0, 0, 0));
- Ref<Image> image_get_rect = image->get_rect(Rect2(0, 0, 2, 1));
+ CHECK(image->get_used_rect() == Rect2i(0, 0, 0, 0));
+ Ref<Image> image_get_rect = image->get_rect(Rect2i(0, 0, 2, 1));
CHECK(image_get_rect->get_size() == Vector2(2, 1));
}
@@ -213,8 +213,8 @@ TEST_CASE("[Image] Modifying pixels of an image") {
image->get_pixelv(Vector2(0, 0)).is_equal_approx(Color(1, 1, 1, 1)),
"Image's get_pixel() should return the same color value as the one being set with set_pixel() in the same position.");
CHECK_MESSAGE(
- image->get_used_rect() == Rect2(0, 0, 1, 1),
- "Image's get_used_rect should return the expected value, larger than Rect2(0, 0, 0, 0) if it's visible.");
+ image->get_used_rect() == Rect2i(0, 0, 1, 1),
+ "Image's get_used_rect should return the expected value, larger than Rect2i(0, 0, 0, 0) if it's visible.");
image->set_pixelv(Vector2(0, 0), Color(0.5, 0.5, 0.5, 0.5));
Ref<Image> image2 = memnew(Image(3, 3, false, Image::FORMAT_RGBA8));
@@ -233,19 +233,19 @@ TEST_CASE("[Image] Modifying pixels of an image") {
{
const int img_width = 3;
const int img_height = 3;
- Vector<Rect2> rects;
- rects.push_back(Rect2());
- rects.push_back(Rect2(-5, -5, 3, 3));
- rects.push_back(Rect2(img_width, 0, 12, 12));
- rects.push_back(Rect2(0, img_height, 12, 12));
- rects.push_back(Rect2(img_width + 1, img_height + 2, 12, 12));
- rects.push_back(Rect2(1, 1, 1, 1));
- rects.push_back(Rect2(0, 1, 2, 3));
- rects.push_back(Rect2(-5, 0, img_width + 10, 2));
- rects.push_back(Rect2(0, -5, 2, img_height + 10));
- rects.push_back(Rect2(-1, -1, img_width + 1, img_height + 1));
-
- for (const Rect2 &rect : rects) {
+ Vector<Rect2i> rects;
+ rects.push_back(Rect2i());
+ rects.push_back(Rect2i(-5, -5, 3, 3));
+ rects.push_back(Rect2i(img_width, 0, 12, 12));
+ rects.push_back(Rect2i(0, img_height, 12, 12));
+ rects.push_back(Rect2i(img_width + 1, img_height + 2, 12, 12));
+ rects.push_back(Rect2i(1, 1, 1, 1));
+ rects.push_back(Rect2i(0, 1, 2, 3));
+ rects.push_back(Rect2i(-5, 0, img_width + 10, 2));
+ rects.push_back(Rect2i(0, -5, 2, img_height + 10));
+ rects.push_back(Rect2i(-1, -1, img_width + 1, img_height + 1));
+
+ for (const Rect2i &rect : rects) {
Ref<Image> img = memnew(Image(img_width, img_height, false, Image::FORMAT_RGBA8));
CHECK_NOTHROW_MESSAGE(
img->fill_rect(rect, Color(1, 1, 1, 1)),
@@ -267,7 +267,7 @@ TEST_CASE("[Image] Modifying pixels of an image") {
}
// Blend two images together
- image->blend_rect(image2, Rect2(Vector2(0, 0), image2->get_size()), Vector2(0, 0));
+ image->blend_rect(image2, Rect2i(Vector2i(0, 0), image2->get_size()), Vector2i(0, 0));
CHECK_MESSAGE(
image->get_pixel(0, 0).a > 0.7,
"blend_rect() should blend the alpha values of the two images.");
@@ -279,7 +279,7 @@ TEST_CASE("[Image] Modifying pixels of an image") {
image3->set_pixel(0, 0, Color(0, 1, 0, 1));
//blit_rect() two images together
- image->blit_rect(image3, Rect2(Vector2(0, 0), image3->get_size()), Vector2(0, 0));
+ image->blit_rect(image3, Rect2i(Vector2i(0, 0), image3->get_size()), Vector2i(0, 0));
CHECK_MESSAGE(
image->get_pixel(0, 0).is_equal_approx(Color(0, 1, 0, 1)),
"blit_rect() should replace old colors and not blend them.");
diff --git a/tests/core/math/test_plane.h b/tests/core/math/test_plane.h
new file mode 100644
index 0000000000..d81a5af1ce
--- /dev/null
+++ b/tests/core/math/test_plane.h
@@ -0,0 +1,172 @@
+/*************************************************************************/
+/* test_plane.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_PLANE_H
+#define TEST_PLANE_H
+
+#include "core/math/plane.h"
+
+#include "thirdparty/doctest/doctest.h"
+
+namespace TestPlane {
+
+// Plane
+
+TEST_CASE("[Plane] Constructor methods") {
+ const Plane plane = Plane(32, 22, 16, 3);
+ const Plane plane_vector = Plane(Vector3(32, 22, 16), 3);
+ const Plane plane_copy_plane = Plane(plane);
+
+ CHECK_MESSAGE(
+ plane == plane_vector,
+ "Planes created with same values but different methods should be equal.");
+
+ CHECK_MESSAGE(
+ plane == plane_copy_plane,
+ "Planes created with same values but different methods should be equal.");
+}
+
+TEST_CASE("[Plane] Basic getters") {
+ const Plane plane = Plane(32, 22, 16, 3);
+ const Plane plane_normalized = Plane(32.0 / 42, 22.0 / 42, 16.0 / 42, 3.0 / 42);
+
+ CHECK_MESSAGE(
+ plane.get_normal().is_equal_approx(Vector3(32, 22, 16)),
+ "get_normal() should return the expected value.");
+
+ CHECK_MESSAGE(
+ plane.normalized().is_equal_approx(plane_normalized),
+ "normalized() should return a copy of the normalized value.");
+}
+
+TEST_CASE("[Plane] Basic setters") {
+ Plane plane = Plane(32, 22, 16, 3);
+ plane.set_normal(Vector3(4, 2, 3));
+
+ CHECK_MESSAGE(
+ plane.is_equal_approx(Plane(4, 2, 3, 3)),
+ "set_normal() should result in the expected plane.");
+
+ plane = Plane(32, 22, 16, 3);
+ plane.normalize();
+
+ CHECK_MESSAGE(
+ plane.is_equal_approx(Plane(32.0 / 42, 22.0 / 42, 16.0 / 42, 3.0 / 42)),
+ "normalize() should result in the expected plane.");
+}
+
+TEST_CASE("[Plane] Plane-point operations") {
+ const Plane plane = Plane(32, 22, 16, 3);
+ const Plane y_facing_plane = Plane(0, 1, 0, 4);
+
+ CHECK_MESSAGE(
+ plane.center().is_equal_approx(Vector3(32 * 3, 22 * 3, 16 * 3)),
+ "center() should return a vector pointing to the center of the plane.");
+
+ CHECK_MESSAGE(
+ y_facing_plane.is_point_over(Vector3(0, 5, 0)),
+ "is_point_over() should return the expected result.");
+
+ CHECK_MESSAGE(
+ y_facing_plane.get_any_perpendicular_normal().is_equal_approx(Vector3(1, 0, 0)),
+ "get_any_perpindicular_normal() should return the expected result.");
+
+ // TODO distance_to()
+}
+
+TEST_CASE("[Plane] Has point") {
+ const Plane x_facing_plane = Plane(1, 0, 0, 0);
+ const Plane y_facing_plane = Plane(0, 1, 0, 0);
+ const Plane z_facing_plane = Plane(0, 0, 1, 0);
+
+ const Vector3 x_axis_point = Vector3(10, 0, 0);
+ const Vector3 y_axis_point = Vector3(0, 10, 0);
+ const Vector3 z_axis_point = Vector3(0, 0, 10);
+
+ const Plane x_facing_plane_with_d_offset = Plane(1, 0, 0, 1);
+ const Vector3 y_axis_point_with_d_offset = Vector3(1, 10, 0);
+
+ CHECK_MESSAGE(
+ x_facing_plane.has_point(y_axis_point),
+ "has_point() with contained Vector3 should return the expected result.");
+ CHECK_MESSAGE(
+ x_facing_plane.has_point(z_axis_point),
+ "has_point() with contained Vector3 should return the expected result.");
+
+ CHECK_MESSAGE(
+ y_facing_plane.has_point(x_axis_point),
+ "has_point() with contained Vector3 should return the expected result.");
+ CHECK_MESSAGE(
+ y_facing_plane.has_point(z_axis_point),
+ "has_point() with contained Vector3 should return the expected result.");
+
+ CHECK_MESSAGE(
+ z_facing_plane.has_point(y_axis_point),
+ "has_point() with contained Vector3 should return the expected result.");
+ CHECK_MESSAGE(
+ z_facing_plane.has_point(x_axis_point),
+ "has_point() with contained Vector3 should return the expected result.");
+
+ CHECK_MESSAGE(
+ x_facing_plane_with_d_offset.has_point(y_axis_point_with_d_offset),
+ "has_point() with passed Vector3 should return the expected result.");
+}
+
+TEST_CASE("[Plane] Intersection") {
+ const Plane x_facing_plane = Plane(1, 0, 0, 1);
+ const Plane y_facing_plane = Plane(0, 1, 0, 2);
+ const Plane z_facing_plane = Plane(0, 0, 1, 3);
+
+ Vector3 vec_out;
+
+ CHECK_MESSAGE(
+ x_facing_plane.intersect_3(y_facing_plane, z_facing_plane, &vec_out),
+ "intersect_3() should return the expected result.");
+ CHECK_MESSAGE(
+ vec_out.is_equal_approx(Vector3(1, 2, 3)),
+ "intersect_3() should modify vec_out to the expected result.");
+
+ CHECK_MESSAGE(
+ x_facing_plane.intersects_ray(Vector3(0, 1, 1), Vector3(2, 0, 0), &vec_out),
+ "intersects_ray() should return the expected result.");
+ CHECK_MESSAGE(
+ vec_out.is_equal_approx(Vector3(1, 1, 1)),
+ "intersects_ray() should modify vec_out to the expected result.");
+
+ CHECK_MESSAGE(
+ x_facing_plane.intersects_segment(Vector3(0, 1, 1), Vector3(2, 1, 1), &vec_out),
+ "intersects_segment() should return the expected result.");
+ CHECK_MESSAGE(
+ vec_out.is_equal_approx(Vector3(1, 1, 1)),
+ "intersects_segment() should modify vec_out to the expected result.");
+}
+} // namespace TestPlane
+
+#endif // TEST_PLANE_H
diff --git a/tests/core/object/test_class_db.h b/tests/core/object/test_class_db.h
index 7ea9e16ff1..c7535426df 100644
--- a/tests/core/object/test_class_db.h
+++ b/tests/core/object/test_class_db.h
@@ -597,7 +597,7 @@ void add_exposed_classes(Context &r_context) {
(exposed_class.name != r_context.names_cache.object_class || String(method.name) != "free"),
warn_msg.utf8().get_data());
- } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ } else if (return_info.type == Variant::INT && return_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
method.return_type.name = return_info.class_name;
method.return_type.is_enum = true;
} else if (return_info.class_name != StringName()) {
@@ -626,7 +626,7 @@ void add_exposed_classes(Context &r_context) {
ArgumentData arg;
arg.name = orig_arg_name;
- if (arg_info.type == Variant::INT && arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (arg_info.type == Variant::INT && arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
arg.type.name = arg_info.class_name;
arg.type.is_enum = true;
} else if (arg_info.class_name != StringName()) {
@@ -694,7 +694,7 @@ void add_exposed_classes(Context &r_context) {
ArgumentData arg;
arg.name = orig_arg_name;
- if (arg_info.type == Variant::INT && arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (arg_info.type == Variant::INT && arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
arg.type.name = arg_info.class_name;
arg.type.is_enum = true;
} else if (arg_info.class_name != StringName()) {
@@ -732,13 +732,13 @@ void add_exposed_classes(Context &r_context) {
List<String> constants;
ClassDB::get_integer_constant_list(class_name, &constants, true);
- const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map;
+ const HashMap<StringName, ClassDB::ClassInfo::EnumInfo> &enum_map = class_info->enum_map;
- for (const KeyValue<StringName, List<StringName>> &K : enum_map) {
+ for (const KeyValue<StringName, ClassDB::ClassInfo::EnumInfo> &K : enum_map) {
EnumData enum_;
enum_.name = K.key;
- for (const StringName &E : K.value) {
+ for (const StringName &E : K.value.constants) {
const StringName &constant_name = E;
TEST_FAIL_COND(String(constant_name).find("::") != -1,
"Enum constant contains '::', check bindings to remove the scope: '",
diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h
index 0b191d2d94..0c5704d6c9 100644
--- a/tests/core/string/test_string.h
+++ b/tests/core/string/test_string.h
@@ -89,12 +89,12 @@ TEST_CASE("[String] UTF8") {
static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
static const uint8_t u8str[] = { 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
String s = u32str;
- bool err = s.parse_utf8(s.utf8().get_data());
- CHECK(!err);
+ Error err = s.parse_utf8(s.utf8().get_data());
+ CHECK(err == OK);
CHECK(s == u32str);
err = s.parse_utf8((const char *)u8str);
- CHECK(!err);
+ CHECK(err == OK);
CHECK(s == u32str);
CharString cs = (const char *)u8str;
@@ -106,12 +106,12 @@ TEST_CASE("[String] UTF16") {
static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
static const char16_t u16str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
String s = u32str;
- bool err = s.parse_utf16(s.utf16().get_data());
- CHECK(!err);
+ Error err = s.parse_utf16(s.utf16().get_data());
+ CHECK(err == OK);
CHECK(s == u32str);
err = s.parse_utf16(u16str);
- CHECK(!err);
+ CHECK(err == OK);
CHECK(s == u32str);
Char16String cs = u16str;
@@ -123,8 +123,8 @@ TEST_CASE("[String] UTF8 with BOM") {
static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
static const uint8_t u8str[] = { 0xEF, 0xBB, 0xBF, 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
String s;
- bool err = s.parse_utf8((const char *)u8str);
- CHECK(!err);
+ Error err = s.parse_utf8((const char *)u8str);
+ CHECK(err == OK);
CHECK(s == u32str);
CharString cs = (const char *)u8str;
@@ -137,12 +137,12 @@ TEST_CASE("[String] UTF16 with BOM") {
static const char16_t u16str[] = { 0xFEFF, 0x0020, 0x0045, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
static const char16_t u16str_swap[] = { 0xFFFE, 0x2000, 0x4500, 0x4A30, 0x0F36, 0x8830, 0x4630, 0x3CD8, 0xA4DF, 0 };
String s;
- bool err = s.parse_utf16(u16str);
- CHECK(!err);
+ Error err = s.parse_utf16(u16str);
+ CHECK(err == OK);
CHECK(s == u32str);
err = s.parse_utf16(u16str_swap);
- CHECK(!err);
+ CHECK(err == OK);
CHECK(s == u32str);
Char16String cs = u16str;
@@ -152,29 +152,48 @@ TEST_CASE("[String] UTF16 with BOM") {
CHECK(String::utf16(cs) == s);
}
-TEST_CASE("[String] Invalid UTF8") {
+TEST_CASE("[String] Invalid UTF8 (non-standard)") {
ERR_PRINT_OFF
- static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
+ static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0xF0, 0x82, 0x82, 0xAC, 0xED, 0xA0, 0x81, 0 };
+ // + +2 +2 +2 +3 overlong +3 unpaired +2
+ static const char32_t u32str[] = { 0x45, 0x304A, 0x3088, 0x3046, 0x1F3A4, 0x20AC, 0xD801, 0 };
String s;
- bool err = s.parse_utf8((const char *)u8str);
- CHECK(err);
- CHECK(s.is_empty());
+ Error err = s.parse_utf8((const char *)u8str);
+ CHECK(err == ERR_PARSE_ERROR);
+ CHECK(s == u32str);
CharString cs = (const char *)u8str;
- CHECK(String::utf8(cs).is_empty());
+ CHECK(String::utf8(cs) == s);
ERR_PRINT_ON
}
-TEST_CASE("[String] Invalid UTF16") {
+TEST_CASE("[String] Invalid UTF8 (unrecoverable)") {
+ ERR_PRINT_OFF
+ static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xC0, 0x80, 0xF0, 0x9F, 0x8E, 0xA4, 0xF0, 0x82, 0x82, 0xAC, 0xED, 0xA0, 0x81, 0 };
+ // + +2 inv +2 inv inv inv +2 +2 ovl NUL +1 +3 overlong +3 unpaired +2
+ static const char32_t u32str[] = { 0x45, 0x304A, 0x20, 0x20, 0x20, 0x20, 0x3088, 0x3046, 0x20, 0x1F3A4, 0x20AC, 0xD801, 0 };
+ String s;
+ Error err = s.parse_utf8((const char *)u8str);
+ CHECK(err == ERR_INVALID_DATA);
+ CHECK(s == u32str);
+
+ CharString cs = (const char *)u8str;
+ CHECK(String::utf8(cs) == s);
+ ERR_PRINT_ON
+}
+
+TEST_CASE("[String] Invalid UTF16 (non-standard)") {
ERR_PRINT_OFF
static const char16_t u16str[] = { 0x0045, 0x304A, 0x3088, 0x3046, 0xDFA4, 0 };
+ // + + + + unpaired
+ static const char32_t u32str[] = { 0x0045, 0x304A, 0x3088, 0x3046, 0xDFA4, 0 };
String s;
- bool err = s.parse_utf16(u16str);
- CHECK(err);
- CHECK(s.is_empty());
+ Error err = s.parse_utf16(u16str);
+ CHECK(err == ERR_PARSE_ERROR);
+ CHECK(s == u32str);
Char16String cs = u16str;
- CHECK(String::utf16(cs).is_empty());
+ CHECK(String::utf16(cs) == s);
ERR_PRINT_ON
}
@@ -262,8 +281,8 @@ TEST_CASE("[String] Test chr") {
CHECK(String::chr('H') == "H");
CHECK(String::chr(0x3012)[0] == 0x3012);
ERR_PRINT_OFF
- CHECK(String::chr(0xd812)[0] == 0xfffd); // Unpaired UTF-16 surrogate
- CHECK(String::chr(0x20d812)[0] == 0xfffd); // Outside UTF-32 range
+ CHECK(String::chr(0xd812)[0] == 0xd812); // Unpaired UTF-16 surrogate
+ CHECK(String::chr(0x20d812)[0] == 0x20d812); // Outside UTF-32 range
ERR_PRINT_ON
}
@@ -1125,9 +1144,9 @@ TEST_CASE("[String] lstrip and rstrip") {
#undef STRIP_TEST
}
-TEST_CASE("[String] ensuring empty string into parse_utf8 passes empty string") {
+TEST_CASE("[String] Ensuring empty string into parse_utf8 passes empty string") {
String empty;
- CHECK(empty.parse_utf8(nullptr, -1));
+ CHECK(empty.parse_utf8(nullptr, -1) == ERR_INVALID_DATA);
}
TEST_CASE("[String] Cyrillic to_lower()") {
@@ -1440,8 +1459,8 @@ TEST_CASE("[String] validate_node_name") {
String name_with_spaces = "Name with spaces";
CHECK(name_with_spaces.validate_node_name() == "Name with spaces");
- String name_with_kana = "Name with kana ゴドツ";
- CHECK(name_with_kana.validate_node_name() == "Name with kana ゴドツ");
+ String name_with_kana = U"Name with kana ゴドツ";
+ CHECK(name_with_kana.validate_node_name() == U"Name with kana ゴドツ");
String name_with_invalid_chars = "Name with invalid characters :.@removed!";
CHECK(name_with_invalid_chars.validate_node_name() == "Name with invalid characters removed!");
diff --git a/tests/core/threads/test_worker_thread_pool.h b/tests/core/threads/test_worker_thread_pool.h
new file mode 100644
index 0000000000..641b293c8a
--- /dev/null
+++ b/tests/core/threads/test_worker_thread_pool.h
@@ -0,0 +1,158 @@
+/*************************************************************************/
+/* test_worker_thread_pool.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_WORKER_THREAD_POOL_H
+#define TEST_WORKER_THREAD_POOL_H
+
+#include "core/object/worker_thread_pool.h"
+
+#include "tests/test_macros.h"
+
+namespace TestWorkerThreadPool {
+
+int u32scmp(const char32_t *l, const char32_t *r) {
+ for (; *l == *r && *l && *r; l++, r++) {
+ // Continue.
+ }
+ return *l - *r;
+}
+
+static void static_test(void *p_arg) {
+ SafeNumeric<uint32_t> *counter = (SafeNumeric<uint32_t> *)p_arg;
+ counter->increment();
+}
+
+static SafeNumeric<uint32_t> callable_counter;
+
+static void static_callable_test() {
+ callable_counter.increment();
+}
+
+TEST_CASE("[WorkerThreadPool] Process 256 threads using native task") {
+ const int count = 256;
+ SafeNumeric<uint32_t> counter;
+ WorkerThreadPool::TaskID tasks[count];
+ for (int i = 0; i < count; i++) {
+ tasks[i] = WorkerThreadPool::get_singleton()->add_native_task(static_test, &counter, true);
+ }
+ for (int i = 0; i < count; i++) {
+ WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]);
+ }
+
+ CHECK(counter.get() == count);
+}
+
+TEST_CASE("[WorkerThreadPool] Process 256 threads using native low priority") {
+ const int count = 256;
+ SafeNumeric<uint32_t> counter = SafeNumeric<uint32_t>(0);
+ WorkerThreadPool::TaskID tasks[count];
+ for (int i = 0; i < count; i++) {
+ tasks[i] = WorkerThreadPool::get_singleton()->add_native_task(static_test, &counter, false);
+ }
+ for (int i = 0; i < count; i++) {
+ WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]);
+ }
+
+ CHECK(counter.get() == count);
+}
+
+TEST_CASE("[WorkerThreadPool] Process 256 threads using callable") {
+ const int count = 256;
+ WorkerThreadPool::TaskID tasks[count];
+ callable_counter.set(0);
+ for (int i = 0; i < count; i++) {
+ tasks[i] = WorkerThreadPool::get_singleton()->add_task(callable_mp_static(static_callable_test), true);
+ }
+ for (int i = 0; i < count; i++) {
+ WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]);
+ }
+
+ CHECK(callable_counter.get() == count);
+}
+
+TEST_CASE("[WorkerThreadPool] Process 256 threads using callable low priority") {
+ const int count = 256;
+ WorkerThreadPool::TaskID tasks[count];
+ callable_counter.set(0);
+ for (int i = 0; i < count; i++) {
+ tasks[i] = WorkerThreadPool::get_singleton()->add_task(callable_mp_static(static_callable_test), false);
+ }
+ for (int i = 0; i < count; i++) {
+ WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]);
+ }
+
+ CHECK(callable_counter.get() == count);
+}
+
+static void static_group_test(void *p_arg, uint32_t p_index) {
+ SafeNumeric<uint32_t> *counter = (SafeNumeric<uint32_t> *)p_arg;
+ counter->exchange_if_greater(p_index);
+}
+
+TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group") {
+ const int count = 256;
+ SafeNumeric<uint32_t> counter;
+ WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_native_group_task(static_group_test, &counter, count, -1, true);
+ WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group);
+ CHECK(counter.get() == count - 1);
+}
+
+TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group low priority") {
+ const int count = 256;
+ SafeNumeric<uint32_t> counter;
+ WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_native_group_task(static_group_test, &counter, count, -1, false);
+ WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group);
+ CHECK(counter.get() == count - 1);
+}
+
+static SafeNumeric<uint32_t> callable_group_counter;
+
+static void static_callable_group_test(uint32_t p_index) {
+ callable_group_counter.exchange_if_greater(p_index);
+}
+
+TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group") {
+ const int count = 256;
+ WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_group_task(callable_mp_static(static_callable_group_test), count, -1, true);
+ WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group);
+ CHECK(callable_group_counter.get() == count - 1);
+}
+
+TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group low priority") {
+ const int count = 256;
+ callable_group_counter.set(0);
+ WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_group_task(callable_mp_static(static_callable_group_test), count, -1, false);
+ WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group);
+ CHECK(callable_group_counter.get() == count - 1);
+}
+
+} // namespace TestWorkerThreadPool
+
+#endif // TEST_WORKER_THREAD_POOL_H
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index d28380d056..7605f24cf8 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -3251,7 +3251,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
SIGNAL_WATCH(code_edit, "symbol_validate");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
SEND_GUI_KEY_EVENT(code_edit, Key::META);
#else
SEND_GUI_KEY_EVENT(code_edit, Key::CTRL);
diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h
index 4098dd7ace..0fce359c5a 100644
--- a/tests/scene/test_text_edit.h
+++ b/tests/scene/test_text_edit.h
@@ -724,7 +724,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->has_selection());
CHECK(text_edit->get_selected_text() == "t");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::SHIFT | KeyModifierMask::ALT)
#else
SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::SHIFT | KeyModifierMask::CMD)
@@ -736,7 +736,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->has_selection());
CHECK(text_edit->get_selected_text() == "tes");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::SHIFT | KeyModifierMask::ALT)
#else
SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::SHIFT | KeyModifierMask::CMD)
@@ -1902,7 +1902,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_DISCARD("lines_edited_from");
SIGNAL_DISCARD("caret_changed");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::ALT | KeyModifierMask::SHIFT);
#else
SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::CMD | KeyModifierMask::SHIFT);
@@ -2013,7 +2013,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_DISCARD("lines_edited_from");
SIGNAL_DISCARD("caret_changed");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::ALT | KeyModifierMask::SHIFT);
#else
SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::CMD | KeyModifierMask::SHIFT);
@@ -2244,7 +2244,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_DISCARD("lines_edited_from");
SIGNAL_DISCARD("caret_changed");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
SEND_GUI_KEY_EVENT(text_edit, Key::UP | KeyModifierMask::CMD | KeyModifierMask::SHIFT);
#else
SEND_GUI_KEY_EVENT(text_edit, Key::HOME | KeyModifierMask::CMD | KeyModifierMask::SHIFT);
@@ -2285,7 +2285,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_DISCARD("lines_edited_from");
SIGNAL_DISCARD("caret_changed");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
SEND_GUI_KEY_EVENT(text_edit, Key::DOWN | KeyModifierMask::CMD | KeyModifierMask::SHIFT);
#else
SEND_GUI_KEY_EVENT(text_edit, Key::END | KeyModifierMask::CMD | KeyModifierMask::SHIFT);
@@ -2326,7 +2326,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_DISCARD("lines_edited_from");
SIGNAL_DISCARD("caret_changed");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::CMD | KeyModifierMask::SHIFT);
#else
SEND_GUI_KEY_EVENT(text_edit, Key::HOME | KeyModifierMask::SHIFT);
@@ -2383,7 +2383,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_DISCARD("lines_edited_from");
SIGNAL_DISCARD("caret_changed");
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::CMD | KeyModifierMask::SHIFT);
#else
SEND_GUI_KEY_EVENT(text_edit, Key::END | KeyModifierMask::SHIFT);
@@ -3139,7 +3139,7 @@ TEST_CASE("[SceneTree][TextEdit] viewport") {
v_scroll = text_edit->get_v_scroll();
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButton::WHEEL_DOWN, Key::NONE);
text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
- CHECK(text_edit->get_v_scroll() > v_scroll);
+ CHECK(text_edit->get_v_scroll() >= v_scroll);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, MouseButton::WHEEL_UP, Key::NONE);
text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
CHECK(text_edit->get_v_scroll() == v_scroll);
@@ -3148,7 +3148,7 @@ TEST_CASE("[SceneTree][TextEdit] viewport") {
text_edit->set_v_scroll_speed(10000);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButton::WHEEL_DOWN, Key::NONE);
text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
- CHECK(text_edit->get_v_scroll() > v_scroll);
+ CHECK(text_edit->get_v_scroll() >= v_scroll);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, MouseButton::WHEEL_UP, Key::NONE);
text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
CHECK(text_edit->get_v_scroll() == v_scroll);
diff --git a/tests/scene/test_theme.h b/tests/scene/test_theme.h
index fedffc8449..f7cfa0fd5b 100644
--- a/tests/scene/test_theme.h
+++ b/tests/scene/test_theme.h
@@ -46,7 +46,7 @@ public:
} const valid_data[Theme::DATA_TYPE_MAX] = {
{ Theme::DATA_TYPE_COLOR, Color() },
{ Theme::DATA_TYPE_CONSTANT, 42 },
- { Theme::DATA_TYPE_FONT, Ref<Font>(memnew(Font)) },
+ { Theme::DATA_TYPE_FONT, Ref<FontFile>(memnew(FontFile)) },
{ Theme::DATA_TYPE_FONT_SIZE, 42 },
{ Theme::DATA_TYPE_ICON, Ref<Texture>(memnew(ImageTexture)) },
{ Theme::DATA_TYPE_STYLEBOX, Ref<StyleBox>(memnew(StyleBoxFlat)) },
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index ac0cdf0cc1..e71f2edba3 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -45,6 +45,7 @@
#include "tests/core/math/test_expression.h"
#include "tests/core/math/test_geometry_2d.h"
#include "tests/core/math/test_geometry_3d.h"
+#include "tests/core/math/test_plane.h"
#include "tests/core/math/test_random_number_generator.h"
#include "tests/core/math/test_rect2.h"
#include "tests/core/math/test_rect2i.h"
@@ -69,6 +70,7 @@
#include "tests/core/test_crypto.h"
#include "tests/core/test_hashing_context.h"
#include "tests/core/test_time.h"
+#include "tests/core/threads/test_worker_thread_pool.h"
#include "tests/core/variant/test_array.h"
#include "tests/core/variant/test_dictionary.h"
#include "tests/core/variant/test_variant.h"
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 1cc272b1bf..818f2f5892 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -118,7 +118,7 @@ will limit its functionality to IPv4 only.
## etcpak
- Upstream: https://github.com/wolfpld/etcpak
-- Version: 1.0 (a77d5a37ddf48034cee8aeb9e8792a623c265b4c, 2022)
+- Version: 1.0 (153f0e04a18b93c277684b577365210adcf8e11c, 2022)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -213,7 +213,7 @@ Files extracted from upstream source:
## harfbuzz
- Upstream: https://github.com/harfbuzz/harfbuzz
-- Version: 4.3.0 (aee123fc83388b8f5acfb301d87bd92eccc5b843, 2022)
+- Version: 4.4.1 (096aaa62a6e0d07c02a4894fc036efc927e5aaf9, 2022)
- License: MIT
Files extracted from upstream source:
@@ -328,15 +328,15 @@ Files extracted from upstream source:
## mbedtls
-- Upstream: https://tls.mbed.org/
-- Version: 2.16.12 (cf4667126010c665341f9e50ef691b7ef8294188, 2021)
+- Upstream: https://github.com/Mbed-TLS/mbedtls
+- Version: 2.18.1 (dd79db10014d85b26d11fe57218431f2e5ede6f2, 2022)
- License: Apache 2.0
File extracted from upstream release tarball:
- All `*.h` from `include/mbedtls/` to `thirdparty/mbedtls/include/mbedtls/` except `config_psa.h` and `psa_util.h`.
- All `*.c` and `*.h` from `library/` to `thirdparty/mbedtls/library/` except those starting with `psa_*`.
-- `LICENSE` and `apache-2.0.txt` files.
+- The `LICENSE` file.
- Applied the patch in `patches/1453.diff` (upstream PR:
https://github.com/ARMmbed/mbedtls/pull/1453).
- Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h`
@@ -759,7 +759,7 @@ Files extracted from upstream source:
## zstd
- Upstream: https://github.com/facebook/zstd
-- Version: 1.5.0 (a488ba114ec17ea1054b9057c26a046fc122b3b6, 2021)
+- Version: 1.5.2 (e47e674cd09583ff0503f0f6defd6d23d8b718d3, 2022)
- License: BSD-3-Clause
Files extracted from upstream source:
diff --git a/thirdparty/etcpak/ProcessRGB.cpp b/thirdparty/etcpak/ProcessRGB.cpp
index fdb0967ce7..4dc3bf23af 100644
--- a/thirdparty/etcpak/ProcessRGB.cpp
+++ b/thirdparty/etcpak/ProcessRGB.cpp
@@ -3216,9 +3216,9 @@ etcpak_force_inline static uint16x8_t ErrorProbe_EAC_NEON( uint8x8_t recVal, uin
uint8x8_t srcValWide;
#ifndef __aarch64__
if( Index < 8 )
- srcValWide = vdup_lane_u8( vget_low_u8( alphaBlock ), ClampConstant( Index, 0, 8 ) );
+ srcValWide = vdup_lane_u8( vget_low_u8( alphaBlock ), ClampConstant( Index, 0, 7 ) );
else
- srcValWide = vdup_lane_u8( vget_high_u8( alphaBlock ), ClampConstant( Index - 8, 0, 8 ) );
+ srcValWide = vdup_lane_u8( vget_high_u8( alphaBlock ), ClampConstant( Index - 8, 0, 7 ) );
#else
srcValWide = vdup_laneq_u8( alphaBlock, Index );
#endif
@@ -3256,9 +3256,9 @@ etcpak_force_inline static int16x8_t WidenMultiplier_EAC_NEON( int16x8_t multipl
constexpr int Lane = GetMulSel( Index );
#ifndef __aarch64__
if( Lane < 4 )
- return vdupq_lane_s16( vget_low_s16( multipliers ), ClampConstant( Lane, 0, 4 ) );
+ return vdupq_lane_s16( vget_low_s16( multipliers ), ClampConstant( Lane, 0, 3 ) );
else
- return vdupq_lane_s16( vget_high_s16( multipliers ), ClampConstant( Lane - 4, 0, 4 ) );
+ return vdupq_lane_s16( vget_high_s16( multipliers ), ClampConstant( Lane - 4, 0, 3 ) );
#else
return vdupq_laneq_s16( multipliers, Lane );
#endif
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS.hh
new file mode 100644
index 0000000000..224d6b746b
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS.hh
@@ -0,0 +1,165 @@
+#ifndef OT_LAYOUT_GPOS_HH
+#define OT_LAYOUT_GPOS_HH
+
+#include "../../hb-ot-layout-common.hh"
+#include "../../hb-ot-layout-gsubgpos.hh"
+#include "GPOS/Common.hh"
+#include "GPOS/PosLookup.hh"
+
+namespace OT {
+namespace Layout {
+
+static void
+propagate_attachment_offsets (hb_glyph_position_t *pos,
+ unsigned int len,
+ unsigned int i,
+ hb_direction_t direction,
+ unsigned nesting_level = HB_MAX_NESTING_LEVEL);
+
+/*
+ * GPOS -- Glyph Positioning
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos
+ */
+
+struct GPOS : GSUBGPOS
+{
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS;
+
+ using Lookup = GPOS_impl::PosLookup;
+
+ const GPOS_impl::PosLookup& get_lookup (unsigned int i) const
+ { return static_cast<const GPOS_impl::PosLookup &> (GSUBGPOS::get_lookup (i)); }
+
+ static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
+ static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer);
+ static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer);
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features);
+ return GSUBGPOS::subset<GPOS_impl::PosLookup> (&l);
+ }
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ { return GSUBGPOS::sanitize<GPOS_impl::PosLookup> (c); }
+
+ HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
+ hb_face_t *face) const;
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++)
+ {
+ if (!c->gpos_lookups->has (i)) continue;
+ const GPOS_impl::PosLookup &l = get_lookup (i);
+ l.dispatch (c);
+ }
+ }
+
+ void closure_lookups (hb_face_t *face,
+ const hb_set_t *glyphs,
+ hb_set_t *lookup_indexes /* IN/OUT */) const
+ { GSUBGPOS::closure_lookups<GPOS_impl::PosLookup> (face, glyphs, lookup_indexes); }
+
+ typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t;
+};
+
+
+static void
+propagate_attachment_offsets (hb_glyph_position_t *pos,
+ unsigned int len,
+ unsigned int i,
+ hb_direction_t direction,
+ unsigned nesting_level)
+{
+ /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate
+ * offset of glyph they are attached to. */
+ int chain = pos[i].attach_chain(), type = pos[i].attach_type();
+ if (likely (!chain))
+ return;
+
+ pos[i].attach_chain() = 0;
+
+ unsigned int j = (int) i + chain;
+
+ if (unlikely (j >= len))
+ return;
+
+ if (unlikely (!nesting_level))
+ return;
+
+ propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1);
+
+ assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE));
+
+ if (type & GPOS_impl::ATTACH_TYPE_CURSIVE)
+ {
+ if (HB_DIRECTION_IS_HORIZONTAL (direction))
+ pos[i].y_offset += pos[j].y_offset;
+ else
+ pos[i].x_offset += pos[j].x_offset;
+ }
+ else /*if (type & GPOS_impl::ATTACH_TYPE_MARK)*/
+ {
+ pos[i].x_offset += pos[j].x_offset;
+ pos[i].y_offset += pos[j].y_offset;
+
+ assert (j < i);
+ if (HB_DIRECTION_IS_FORWARD (direction))
+ for (unsigned int k = j; k < i; k++) {
+ pos[i].x_offset -= pos[k].x_advance;
+ pos[i].y_offset -= pos[k].y_advance;
+ }
+ else
+ for (unsigned int k = j + 1; k < i + 1; k++) {
+ pos[i].x_offset += pos[k].x_advance;
+ pos[i].y_offset += pos[k].y_advance;
+ }
+ }
+}
+
+void
+GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0;
+}
+
+void
+GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
+{
+ //_hb_buffer_assert_gsubgpos_vars (buffer);
+}
+
+void
+GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
+{
+ _hb_buffer_assert_gsubgpos_vars (buffer);
+
+ unsigned int len;
+ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
+ hb_direction_t direction = buffer->props.direction;
+
+ /* Handle attachments */
+ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
+ 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 : Layout::GPOS::accelerator_t {
+ GPOS_accelerator_t (hb_face_t *face) : Layout::GPOS::accelerator_t (face) {}
+};
+
+}
+
+#endif /* OT_LAYOUT_GPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/Anchor.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/Anchor.hh
new file mode 100644
index 0000000000..bfe6b36afd
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/Anchor.hh
@@ -0,0 +1,84 @@
+#ifndef OT_LAYOUT_GPOS_ANCHOR_HH
+#define OT_LAYOUT_GPOS_ANCHOR_HH
+
+#include "AnchorFormat1.hh"
+#include "AnchorFormat2.hh"
+#include "AnchorFormat3.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct Anchor
+{
+ protected:
+ union {
+ HBUINT16 format; /* Format identifier */
+ AnchorFormat1 format1;
+ AnchorFormat2 format2;
+ AnchorFormat3 format3;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return_trace (false);
+ switch (u.format) {
+ case 1: return_trace (u.format1.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+ case 3: return_trace (u.format3.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
+ float *x, float *y) const
+ {
+ *x = *y = 0;
+ switch (u.format) {
+ case 1: u.format1.get_anchor (c, glyph_id, x, y); return;
+ case 2: u.format2.get_anchor (c, glyph_id, x, y); return;
+ case 3: u.format3.get_anchor (c, glyph_id, x, y); return;
+ default: return;
+ }
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ switch (u.format) {
+ case 1: return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
+ case 2:
+ if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+ {
+ // AnchorFormat 2 just containins extra hinting information, so
+ // if hints are being dropped convert to format 1.
+ return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
+ }
+ return_trace (bool (reinterpret_cast<Anchor *> (u.format2.copy (c->serializer))));
+ case 3: return_trace (bool (reinterpret_cast<Anchor *> (u.format3.copy (c->serializer,
+ c->plan->layout_variation_idx_map))));
+ default:return_trace (false);
+ }
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ switch (u.format) {
+ case 1: case 2:
+ return;
+ case 3:
+ u.format3.collect_variation_indices (c);
+ return;
+ default: return;
+ }
+ }
+};
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_ANCHOR_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat1.hh
new file mode 100644
index 0000000000..738cc31bbf
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat1.hh
@@ -0,0 +1,46 @@
+#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
+#define OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct AnchorFormat1
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 1 */
+ FWORD xCoordinate; /* Horizontal value--in design units */
+ FWORD yCoordinate; /* Vertical value--in design units */
+ public:
+ DEFINE_SIZE_STATIC (6);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
+ float *x, float *y) const
+ {
+ hb_font_t *font = c->font;
+ *x = font->em_fscale_x (xCoordinate);
+ *y = font->em_fscale_y (yCoordinate);
+ }
+
+ AnchorFormat1* copy (hb_serialize_context_t *c) const
+ {
+ TRACE_SERIALIZE (this);
+ AnchorFormat1* out = c->embed<AnchorFormat1> (this);
+ if (!out) return_trace (out);
+ out->format = 1;
+ return_trace (out);
+ }
+};
+
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat2.hh
new file mode 100644
index 0000000000..70b4d19f53
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat2.hh
@@ -0,0 +1,58 @@
+#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
+#define OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct AnchorFormat2
+{
+
+ protected:
+ HBUINT16 format; /* Format identifier--format = 2 */
+ FWORD xCoordinate; /* Horizontal value--in design units */
+ FWORD yCoordinate; /* Vertical value--in design units */
+ HBUINT16 anchorPoint; /* Index to glyph contour point */
+ public:
+ DEFINE_SIZE_STATIC (8);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
+ float *x, float *y) const
+ {
+ hb_font_t *font = c->font;
+
+#ifdef HB_NO_HINTING
+ *x = font->em_fscale_x (xCoordinate);
+ *y = font->em_fscale_y (yCoordinate);
+ return;
+#endif
+
+ unsigned int x_ppem = font->x_ppem;
+ unsigned int y_ppem = font->y_ppem;
+ hb_position_t cx = 0, cy = 0;
+ bool ret;
+
+ ret = (x_ppem || y_ppem) &&
+ font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
+ *x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate);
+ *y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate);
+ }
+
+ AnchorFormat2* copy (hb_serialize_context_t *c) const
+ {
+ TRACE_SERIALIZE (this);
+ return_trace (c->embed<AnchorFormat2> (this));
+ }
+};
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh
new file mode 100644
index 0000000000..d77b4699be
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh
@@ -0,0 +1,70 @@
+#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
+#define OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct AnchorFormat3
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 3 */
+ FWORD xCoordinate; /* Horizontal value--in design units */
+ FWORD yCoordinate; /* Vertical value--in design units */
+ Offset16To<Device>
+ xDeviceTable; /* Offset to Device table for X
+ * coordinate-- from beginning of
+ * Anchor table (may be NULL) */
+ Offset16To<Device>
+ yDeviceTable; /* Offset to Device table for Y
+ * coordinate-- from beginning of
+ * Anchor table (may be NULL) */
+ public:
+ DEFINE_SIZE_STATIC (10);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
+ }
+
+ void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
+ float *x, float *y) const
+ {
+ hb_font_t *font = c->font;
+ *x = font->em_fscale_x (xCoordinate);
+ *y = font->em_fscale_y (yCoordinate);
+
+ if (font->x_ppem || font->num_coords)
+ *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache);
+ if (font->y_ppem || font->num_coords)
+ *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache);
+ }
+
+ AnchorFormat3* copy (hb_serialize_context_t *c,
+ const hb_map_t *layout_variation_idx_map) const
+ {
+ TRACE_SERIALIZE (this);
+ if (!layout_variation_idx_map) return_trace (nullptr);
+
+ auto *out = c->embed<AnchorFormat3> (this);
+ if (unlikely (!out)) return_trace (nullptr);
+
+ out->xDeviceTable.serialize_copy (c, xDeviceTable, this, 0, hb_serialize_context_t::Head, layout_variation_idx_map);
+ out->yDeviceTable.serialize_copy (c, yDeviceTable, this, 0, hb_serialize_context_t::Head, layout_variation_idx_map);
+ return_trace (out);
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ (this+xDeviceTable).collect_variation_indices (c->layout_variation_indices);
+ (this+yDeviceTable).collect_variation_indices (c->layout_variation_indices);
+ }
+};
+
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh
new file mode 100644
index 0000000000..c442efa1ea
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh
@@ -0,0 +1,77 @@
+#ifndef OT_LAYOUT_GPOS_ANCHORMATRIX_HH
+#define OT_LAYOUT_GPOS_ANCHORMATRIX_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct AnchorMatrix
+{
+ HBUINT16 rows; /* Number of rows */
+ UnsizedArrayOf<Offset16To<Anchor>>
+ matrixZ; /* Matrix of offsets to Anchor tables--
+ * from beginning of AnchorMatrix table */
+ public:
+ DEFINE_SIZE_ARRAY (2, matrixZ);
+
+ bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
+ {
+ TRACE_SANITIZE (this);
+ if (!c->check_struct (this)) return_trace (false);
+ if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
+ unsigned int count = rows * cols;
+ if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
+ for (unsigned int i = 0; i < count; i++)
+ if (!matrixZ[i].sanitize (c, this)) return_trace (false);
+ return_trace (true);
+ }
+
+ const Anchor& get_anchor (unsigned int row, unsigned int col,
+ unsigned int cols, bool *found) const
+ {
+ *found = false;
+ if (unlikely (row >= rows || col >= cols)) return Null (Anchor);
+ *found = !matrixZ[row * cols + col].is_null ();
+ return this+matrixZ[row * cols + col];
+ }
+
+ template <typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ Iterator index_iter) const
+ {
+ for (unsigned i : index_iter)
+ (this+matrixZ[i]).collect_variation_indices (c);
+ }
+
+ template <typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ bool subset (hb_subset_context_t *c,
+ unsigned num_rows,
+ Iterator index_iter) const
+ {
+ TRACE_SUBSET (this);
+
+ auto *out = c->serializer->start_embed (this);
+
+ if (!index_iter) return_trace (false);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ out->rows = num_rows;
+ for (const unsigned i : index_iter)
+ {
+ auto *offset = c->serializer->embed (matrixZ[i]);
+ if (!offset) return_trace (false);
+ offset->serialize_subset (c, matrixZ[i], this);
+ }
+
+ return_trace (true);
+ }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_ANCHORMATRIX_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ChainContextPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ChainContextPos.hh
new file mode 100644
index 0000000000..d551ac2a2b
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ChainContextPos.hh
@@ -0,0 +1,14 @@
+#ifndef OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH
+#define OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct ChainContextPos : ChainContext {};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/Common.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/Common.hh
new file mode 100644
index 0000000000..e16c06729d
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/Common.hh
@@ -0,0 +1,32 @@
+#ifndef OT_LAYOUT_GPOS_COMMON_HH
+#define OT_LAYOUT_GPOS_COMMON_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+enum attach_type_t {
+ ATTACH_TYPE_NONE = 0X00,
+
+ /* Each attachment should be either a mark or a cursive; can't be both. */
+ ATTACH_TYPE_MARK = 0X01,
+ ATTACH_TYPE_CURSIVE = 0X02,
+};
+
+/* buffer **position** var allocations */
+#define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */
+#define attach_type() var.u8[2] /* attachment type */
+/* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */
+
+template<typename Iterator, typename SrcLookup>
+static void SinglePos_serialize (hb_serialize_context_t *c,
+ const SrcLookup *src,
+ Iterator it,
+ const hb_map_t *layout_variation_idx_map);
+
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_COMMON_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ContextPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ContextPos.hh
new file mode 100644
index 0000000000..2a01eaa3a6
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ContextPos.hh
@@ -0,0 +1,14 @@
+#ifndef OT_LAYOUT_GPOS_CONTEXTPOS_HH
+#define OT_LAYOUT_GPOS_CONTEXTPOS_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct ContextPos : Context {};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_CONTEXTPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePos.hh
new file mode 100644
index 0000000000..c105cfb091
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePos.hh
@@ -0,0 +1,35 @@
+#ifndef OT_LAYOUT_GPOS_CURSIVEPOS_HH
+#define OT_LAYOUT_GPOS_CURSIVEPOS_HH
+
+#include "CursivePosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct CursivePos
+{
+ protected:
+ union {
+ HBUINT16 format; /* Format identifier */
+ CursivePosFormat1 format1;
+ } u;
+
+ public:
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_CURSIVEPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
new file mode 100644
index 0000000000..e212fab976
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
@@ -0,0 +1,281 @@
+#ifndef OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH
+
+#include "Anchor.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct EntryExitRecord
+{
+ friend struct CursivePosFormat1;
+
+ bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ const void *src_base) const
+ {
+ (src_base+entryAnchor).collect_variation_indices (c);
+ (src_base+exitAnchor).collect_variation_indices (c);
+ }
+
+ EntryExitRecord* subset (hb_subset_context_t *c,
+ const void *src_base) const
+ {
+ TRACE_SERIALIZE (this);
+ auto *out = c->serializer->embed (this);
+ if (unlikely (!out)) return_trace (nullptr);
+
+ out->entryAnchor.serialize_subset (c, entryAnchor, src_base);
+ out->exitAnchor.serialize_subset (c, exitAnchor, src_base);
+ return_trace (out);
+ }
+
+ protected:
+ Offset16To<Anchor>
+ entryAnchor; /* Offset to EntryAnchor table--from
+ * beginning of CursivePos
+ * subtable--may be NULL */
+ Offset16To<Anchor>
+ exitAnchor; /* Offset to ExitAnchor table--from
+ * beginning of CursivePos
+ * subtable--may be NULL */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+static void
+reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) {
+ int chain = pos[i].attach_chain(), type = pos[i].attach_type();
+ if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE)))
+ return;
+
+ pos[i].attach_chain() = 0;
+
+ unsigned int j = (int) i + chain;
+
+ /* Stop if we see new parent in the chain. */
+ if (j == new_parent)
+ return;
+
+ reverse_cursive_minor_offset (pos, j, direction, new_parent);
+
+ if (HB_DIRECTION_IS_HORIZONTAL (direction))
+ pos[j].y_offset = -pos[i].y_offset;
+ else
+ pos[j].x_offset = -pos[i].x_offset;
+
+ pos[j].attach_chain() = -chain;
+ pos[j].attach_type() = type;
+}
+
+
+struct CursivePosFormat1
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 1 */
+ Offset16To<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ Array16Of<EntryExitRecord>
+ entryExitRecord; /* Array of EntryExit records--in
+ * Coverage Index order */
+ public:
+ DEFINE_SIZE_ARRAY (6, entryExitRecord);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ { return (this+coverage).intersects (glyphs); }
+
+ void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ + hb_zip (this+coverage, entryExitRecord)
+ | hb_filter (c->glyph_set, hb_first)
+ | hb_map (hb_second)
+ | hb_apply ([&] (const EntryExitRecord& record) { record.collect_variation_indices (c, this); })
+ ;
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
+
+ const Coverage &get_coverage () const { return this+coverage; }
+
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+
+ const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
+ if (!this_record.entryAnchor) return_trace (false);
+
+ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, 1);
+ 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)
+ {
+ 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;
+
+ buffer->unsafe_to_break (i, j);
+ float entry_x, entry_y, exit_x, exit_y;
+ (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
+ (this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
+
+ hb_glyph_position_t *pos = buffer->pos;
+
+ hb_position_t d;
+ /* Main-direction adjustment */
+ switch (c->direction) {
+ case HB_DIRECTION_LTR:
+ pos[i].x_advance = roundf (exit_x) + pos[i].x_offset;
+
+ d = roundf (entry_x) + pos[j].x_offset;
+ pos[j].x_advance -= d;
+ pos[j].x_offset -= d;
+ break;
+ case HB_DIRECTION_RTL:
+ d = roundf (exit_x) + pos[i].x_offset;
+ pos[i].x_advance -= d;
+ pos[i].x_offset -= d;
+
+ pos[j].x_advance = roundf (entry_x) + pos[j].x_offset;
+ break;
+ case HB_DIRECTION_TTB:
+ pos[i].y_advance = roundf (exit_y) + pos[i].y_offset;
+
+ d = roundf (entry_y) + pos[j].y_offset;
+ pos[j].y_advance -= d;
+ pos[j].y_offset -= d;
+ break;
+ case HB_DIRECTION_BTT:
+ d = roundf (exit_y) + pos[i].y_offset;
+ pos[i].y_advance -= d;
+ pos[i].y_offset -= d;
+
+ pos[j].y_advance = roundf (entry_y);
+ break;
+ case HB_DIRECTION_INVALID:
+ default:
+ break;
+ }
+
+ /* Cross-direction adjustment */
+
+ /* We attach child to parent (think graph theory and rooted trees whereas
+ * the root stays on baseline and each node aligns itself against its
+ * parent.
+ *
+ * Optimize things for the case of RightToLeft, as that's most common in
+ * Arabic. */
+ unsigned int child = i;
+ unsigned int parent = j;
+ hb_position_t x_offset = entry_x - exit_x;
+ hb_position_t y_offset = entry_y - exit_y;
+ if (!(c->lookup_props & LookupFlag::RightToLeft))
+ {
+ unsigned int k = child;
+ child = parent;
+ parent = k;
+ x_offset = -x_offset;
+ y_offset = -y_offset;
+ }
+
+ /* If child was already connected to someone else, walk through its old
+ * chain and reverse the link direction, such that the whole tree of its
+ * previous connection now attaches to new parent. Watch out for case
+ * where new parent is on the path from old chain...
+ */
+ reverse_cursive_minor_offset (pos, child, c->direction, parent);
+
+ pos[child].attach_type() = ATTACH_TYPE_CURSIVE;
+ pos[child].attach_chain() = (int) parent - (int) child;
+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
+ pos[child].y_offset = y_offset;
+ else
+ pos[child].x_offset = x_offset;
+
+ /* If parent was attached to child, separate them.
+ * https://github.com/harfbuzz/harfbuzz/issues/2469
+ */
+ if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain()))
+ pos[parent].attach_chain() = 0;
+
+ buffer->idx++;
+ return_trace (true);
+ }
+
+ template <typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ void serialize (hb_subset_context_t *c,
+ Iterator it,
+ const void *src_base)
+ {
+ if (unlikely (!c->serializer->extend_min ((*this)))) return;
+ this->format = 1;
+ this->entryExitRecord.len = it.len ();
+
+ for (const EntryExitRecord& entry_record : + it
+ | hb_map (hb_second))
+ entry_record.subset (c, src_base);
+
+ auto glyphs =
+ + it
+ | hb_map_retains_sorting (hb_first)
+ ;
+
+ coverage.serialize_serialize (c->serializer, glyphs);
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!out)) return_trace (false);
+
+ auto it =
+ + hb_zip (this+coverage, entryExitRecord)
+ | hb_filter (glyphset, hb_first)
+ | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const EntryExitRecord&> p) -> hb_pair_t<hb_codepoint_t, const EntryExitRecord&>
+ { return hb_pair (glyph_map[p.first], p.second);})
+ ;
+
+ bool ret = bool (it);
+ out->serialize (c, it, this);
+ return_trace (ret);
+ }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ExtensionPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ExtensionPos.hh
new file mode 100644
index 0000000000..d1808adab4
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ExtensionPos.hh
@@ -0,0 +1,17 @@
+#ifndef OT_LAYOUT_GPOS_EXTENSIONPOS_HH
+#define OT_LAYOUT_GPOS_EXTENSIONPOS_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct ExtensionPos : Extension<ExtensionPos>
+{
+ typedef struct PosLookupSubTable SubTable;
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_EXTENSIONPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh
new file mode 100644
index 0000000000..f8cddd1991
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh
@@ -0,0 +1,113 @@
+#ifndef OT_LAYOUT_GPOS_MARKARRAY_HH
+#define OT_LAYOUT_GPOS_MARKARRAY_HH
+
+#include "AnchorMatrix.hh"
+#include "MarkRecord.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Coverage order */
+{
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (Array16Of<MarkRecord>::sanitize (c, this));
+ }
+
+ bool apply (hb_ot_apply_context_t *c,
+ unsigned int mark_index, unsigned int glyph_index,
+ const AnchorMatrix &anchors, unsigned int class_count,
+ unsigned int glyph_pos) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ const MarkRecord &record = Array16Of<MarkRecord>::operator[](mark_index);
+ unsigned int mark_class = record.klass;
+
+ const Anchor& mark_anchor = this + record.markAnchor;
+ bool found;
+ const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
+ /* If this subtable doesn't have an anchor for this base and this class,
+ * return false such that the subsequent subtables have a chance at it. */
+ if (unlikely (!found)) return_trace (false);
+
+ float mark_x, mark_y, base_x, base_y;
+
+ 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);
+
+ hb_glyph_position_t &o = buffer->cur_pos();
+ o.x_offset = roundf (base_x - mark_x);
+ o.y_offset = roundf (base_y - mark_y);
+ o.attach_type() = ATTACH_TYPE_MARK;
+ o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+
+ buffer->idx++;
+ return_trace (true);
+ }
+
+ template <typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ bool subset (hb_subset_context_t *c,
+ Iterator coverage,
+ const hb_map_t *klass_mapping) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+
+ auto* out = c->serializer->start_embed (this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ auto mark_iter =
+ + hb_zip (coverage, this->iter ())
+ | hb_filter (glyphset, hb_first)
+ | hb_map (hb_second)
+ ;
+
+ unsigned new_length = 0;
+ for (const auto& mark_record : mark_iter) {
+ if (unlikely (!mark_record.subset (c, this, klass_mapping)))
+ return_trace (false);
+ new_length++;
+ }
+
+ if (unlikely (!c->serializer->check_assign (out->len, new_length,
+ HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)))
+ return_trace (false);
+
+ return_trace (true);
+ }
+};
+
+static void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage,
+ const MarkArray &mark_array,
+ const hb_set_t &glyphset,
+ hb_map_t* klass_mapping /* INOUT */)
+{
+ hb_set_t orig_classes;
+
+ + hb_zip (mark_coverage, mark_array)
+ | hb_filter (glyphset, hb_first)
+ | hb_map (hb_second)
+ | hb_map (&MarkRecord::get_class)
+ | hb_sink (orig_classes)
+ ;
+
+ unsigned idx = 0;
+ for (auto klass : orig_classes.iter ())
+ {
+ if (klass_mapping->has (klass)) continue;
+ klass_mapping->set (klass, idx);
+ idx++;
+ }
+}
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKARRAY_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh
new file mode 100644
index 0000000000..e99e13ff84
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh
@@ -0,0 +1,35 @@
+#ifndef OT_LAYOUT_GPOS_MARKBASEPOS_HH
+#define OT_LAYOUT_GPOS_MARKBASEPOS_HH
+
+#include "MarkBasePosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkBasePos
+{
+ protected:
+ union {
+ HBUINT16 format; /* Format identifier */
+ MarkBasePosFormat1 format1;
+ } u;
+
+ public:
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKBASEPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
new file mode 100644
index 0000000000..a10b806fe5
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
@@ -0,0 +1,217 @@
+#ifndef OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH
+
+#include "MarkArray.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+typedef AnchorMatrix BaseArray; /* base-major--
+ * in order of BaseCoverage Index--,
+ * mark-minor--
+ * ordered by class--zero-based. */
+
+struct MarkBasePosFormat1
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 1 */
+ Offset16To<Coverage>
+ markCoverage; /* Offset to MarkCoverage table--from
+ * beginning of MarkBasePos subtable */
+ Offset16To<Coverage>
+ baseCoverage; /* Offset to BaseCoverage table--from
+ * beginning of MarkBasePos subtable */
+ HBUINT16 classCount; /* Number of classes defined for marks */
+ Offset16To<MarkArray>
+ markArray; /* Offset to MarkArray table--from
+ * beginning of MarkBasePos subtable */
+ Offset16To<BaseArray>
+ baseArray; /* Offset to BaseArray table--from
+ * beginning of MarkBasePos subtable */
+
+ public:
+ DEFINE_SIZE_STATIC (12);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ markCoverage.sanitize (c, this) &&
+ baseCoverage.sanitize (c, this) &&
+ markArray.sanitize (c, this) &&
+ baseArray.sanitize (c, this, (unsigned int) classCount));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ {
+ return (this+markCoverage).intersects (glyphs) &&
+ (this+baseCoverage).intersects (glyphs);
+ }
+
+ void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ + hb_zip (this+markCoverage, this+markArray)
+ | hb_filter (c->glyph_set, hb_first)
+ | hb_map (hb_second)
+ | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
+ ;
+
+ hb_map_t klass_mapping;
+ Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
+
+ unsigned basecount = (this+baseArray).rows;
+ auto base_iter =
+ + hb_zip (this+baseCoverage, hb_range (basecount))
+ | hb_filter (c->glyph_set, hb_first)
+ | hb_map (hb_second)
+ ;
+
+ hb_sorted_vector_t<unsigned> base_indexes;
+ for (const unsigned row : base_iter)
+ {
+ + hb_range ((unsigned) classCount)
+ | hb_filter (klass_mapping)
+ | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+ | hb_sink (base_indexes)
+ ;
+ }
+ (this+baseArray).collect_variation_indices (c, base_indexes.iter ());
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
+ if (unlikely (!(this+baseCoverage).collect_coverage (c->input))) return;
+ }
+
+ const Coverage &get_coverage () const { return this+markCoverage; }
+
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
+ if (likely (mark_index == NOT_COVERED)) return_trace (false);
+
+ /* Now we search backwards for a non-mark glyph */
+ 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);
+ do {
+ 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...
+ * ...but stop if we find a mark in the MultipleSubst sequence:
+ * https://github.com/harfbuzz/harfbuzz/issues/1020 */
+ if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) ||
+ 0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) ||
+ (skippy_iter.idx == 0 ||
+ _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx - 1]) ||
+ _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) !=
+ _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) ||
+ _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) !=
+ _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx - 1]) + 1
+ ))
+ break;
+ skippy_iter.reject ();
+ } while (true);
+
+ /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
+ //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)
+ {
+ 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));
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+
+ hb_map_t klass_mapping;
+ Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
+
+ if (!klass_mapping.get_population ()) return_trace (false);
+ out->classCount = klass_mapping.get_population ();
+
+ auto mark_iter =
+ + hb_zip (this+markCoverage, this+markArray)
+ | hb_filter (glyphset, hb_first)
+ ;
+
+ hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ + mark_iter
+ | hb_map (hb_first)
+ | hb_map (glyph_map)
+ | hb_sink (new_coverage)
+ ;
+
+ if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+ return_trace (false);
+
+ out->markArray.serialize_subset (c, markArray, this,
+ (this+markCoverage).iter (),
+ &klass_mapping);
+
+ unsigned basecount = (this+baseArray).rows;
+ auto base_iter =
+ + hb_zip (this+baseCoverage, hb_range (basecount))
+ | hb_filter (glyphset, hb_first)
+ ;
+
+ new_coverage.reset ();
+ + base_iter
+ | hb_map (hb_first)
+ | hb_map (glyph_map)
+ | hb_sink (new_coverage)
+ ;
+
+ if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+ return_trace (false);
+
+ hb_sorted_vector_t<unsigned> base_indexes;
+ for (const unsigned row : + base_iter
+ | hb_map (hb_second))
+ {
+ + hb_range ((unsigned) classCount)
+ | hb_filter (klass_mapping)
+ | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+ | hb_sink (base_indexes)
+ ;
+ }
+
+ out->baseArray.serialize_subset (c, baseArray, this,
+ base_iter.len (),
+ base_indexes.iter ());
+
+ return_trace (true);
+ }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh
new file mode 100644
index 0000000000..7e74aa73e0
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh
@@ -0,0 +1,35 @@
+#ifndef OT_LAYOUT_GPOS_MARKLIGPOS_HH
+#define OT_LAYOUT_GPOS_MARKLIGPOS_HH
+
+#include "MarkLigPosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkLigPos
+{
+ protected:
+ union {
+ HBUINT16 format; /* Format identifier */
+ MarkLigPosFormat1 format1;
+ } u;
+
+ public:
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKLIGPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
new file mode 100644
index 0000000000..4382aa6c6c
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
@@ -0,0 +1,244 @@
+#ifndef OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+typedef AnchorMatrix LigatureAttach; /* component-major--
+ * in order of writing direction--,
+ * mark-minor--
+ * ordered by class--zero-based. */
+
+/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
+struct LigatureArray : List16OfOffset16To<LigatureAttach>
+{
+ template <typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ bool subset (hb_subset_context_t *c,
+ Iterator coverage,
+ unsigned class_count,
+ const hb_map_t *klass_mapping) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+
+ auto *out = c->serializer->start_embed (this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ for (const auto _ : + hb_zip (coverage, *this)
+ | hb_filter (glyphset, hb_first))
+ {
+ auto *matrix = out->serialize_append (c->serializer);
+ if (unlikely (!matrix)) return_trace (false);
+
+ const LigatureAttach& src = (this + _.second);
+ auto indexes =
+ + hb_range (src.rows * class_count)
+ | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
+ ;
+ matrix->serialize_subset (c,
+ _.second,
+ this,
+ src.rows,
+ indexes);
+ }
+ return_trace (this->len);
+ }
+};
+
+struct MarkLigPosFormat1
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 1 */
+ Offset16To<Coverage>
+ markCoverage; /* Offset to Mark Coverage table--from
+ * beginning of MarkLigPos subtable */
+ Offset16To<Coverage>
+ ligatureCoverage; /* Offset to Ligature Coverage
+ * table--from beginning of MarkLigPos
+ * subtable */
+ HBUINT16 classCount; /* Number of defined mark classes */
+ Offset16To<MarkArray>
+ markArray; /* Offset to MarkArray table--from
+ * beginning of MarkLigPos subtable */
+ Offset16To<LigatureArray>
+ ligatureArray; /* Offset to LigatureArray table--from
+ * beginning of MarkLigPos subtable */
+ public:
+ DEFINE_SIZE_STATIC (12);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ markCoverage.sanitize (c, this) &&
+ ligatureCoverage.sanitize (c, this) &&
+ markArray.sanitize (c, this) &&
+ ligatureArray.sanitize (c, this, (unsigned int) classCount));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ {
+ return (this+markCoverage).intersects (glyphs) &&
+ (this+ligatureCoverage).intersects (glyphs);
+ }
+
+ void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ + hb_zip (this+markCoverage, this+markArray)
+ | hb_filter (c->glyph_set, hb_first)
+ | hb_map (hb_second)
+ | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
+ ;
+
+ hb_map_t klass_mapping;
+ Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
+
+ unsigned ligcount = (this+ligatureArray).len;
+ auto lig_iter =
+ + hb_zip (this+ligatureCoverage, hb_range (ligcount))
+ | hb_filter (c->glyph_set, hb_first)
+ | hb_map (hb_second)
+ ;
+
+ const LigatureArray& lig_array = this+ligatureArray;
+ for (const unsigned i : lig_iter)
+ {
+ hb_sorted_vector_t<unsigned> lig_indexes;
+ unsigned row_count = lig_array[i].rows;
+ for (unsigned row : + hb_range (row_count))
+ {
+ + hb_range ((unsigned) classCount)
+ | hb_filter (klass_mapping)
+ | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+ | hb_sink (lig_indexes)
+ ;
+ }
+
+ lig_array[i].collect_variation_indices (c, lig_indexes.iter ());
+ }
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
+ if (unlikely (!(this+ligatureCoverage).collect_coverage (c->input))) return;
+ }
+
+ const Coverage &get_coverage () const { return this+markCoverage; }
+
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
+ if (likely (mark_index == NOT_COVERED)) return_trace (false);
+
+ /* Now we search backwards for a non-mark glyph */
+ 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);
+ 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)
+ {
+ 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))
+ {
+ 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
+ * can directly use the component index. If not, we attach the mark
+ * glyph to the last component of the ligature. */
+ unsigned int comp_index;
+ unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+ unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ if (lig_id && lig_id == mark_id && mark_comp > 0)
+ comp_index = hb_min (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
+ else
+ comp_index = comp_count - 1;
+
+ return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+
+ hb_map_t klass_mapping;
+ Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
+
+ if (!klass_mapping.get_population ()) return_trace (false);
+ out->classCount = klass_mapping.get_population ();
+
+ auto mark_iter =
+ + hb_zip (this+markCoverage, this+markArray)
+ | hb_filter (glyphset, hb_first)
+ ;
+
+ auto new_mark_coverage =
+ + mark_iter
+ | hb_map_retains_sorting (hb_first)
+ | hb_map_retains_sorting (glyph_map)
+ ;
+
+ if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage))
+ return_trace (false);
+
+ out->markArray.serialize_subset (c, markArray, this,
+ (this+markCoverage).iter (),
+ &klass_mapping);
+
+ auto new_ligature_coverage =
+ + hb_iter (this + ligatureCoverage)
+ | hb_filter (glyphset)
+ | hb_map_retains_sorting (glyph_map)
+ ;
+
+ if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage))
+ return_trace (false);
+
+ out->ligatureArray.serialize_subset (c, ligatureArray, this,
+ hb_iter (this+ligatureCoverage), classCount, &klass_mapping);
+
+ return_trace (true);
+ }
+
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh
new file mode 100644
index 0000000000..c0eee6d54c
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh
@@ -0,0 +1,36 @@
+#ifndef OT_LAYOUT_GPOS_MARKMARKPOS_HH
+#define OT_LAYOUT_GPOS_MARKMARKPOS_HH
+
+#include "MarkMarkPosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkMarkPos
+{
+ protected:
+ union {
+ HBUINT16 format; /* Format identifier */
+ MarkMarkPosFormat1 format1;
+ } u;
+
+ public:
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKMARKPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
new file mode 100644
index 0000000000..c48a74f773
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
@@ -0,0 +1,227 @@
+#ifndef OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH
+
+#include "MarkMarkPosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+typedef AnchorMatrix Mark2Array; /* mark2-major--
+ * in order of Mark2Coverage Index--,
+ * mark1-minor--
+ * ordered by class--zero-based. */
+
+struct MarkMarkPosFormat1
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 1 */
+ Offset16To<Coverage>
+ mark1Coverage; /* Offset to Combining Mark1 Coverage
+ * table--from beginning of MarkMarkPos
+ * subtable */
+ Offset16To<Coverage>
+ mark2Coverage; /* Offset to Combining Mark2 Coverage
+ * table--from beginning of MarkMarkPos
+ * subtable */
+ HBUINT16 classCount; /* Number of defined mark classes */
+ Offset16To<MarkArray>
+ mark1Array; /* Offset to Mark1Array table--from
+ * beginning of MarkMarkPos subtable */
+ Offset16To<Mark2Array>
+ mark2Array; /* Offset to Mark2Array table--from
+ * beginning of MarkMarkPos subtable */
+ public:
+ DEFINE_SIZE_STATIC (12);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ mark1Coverage.sanitize (c, this) &&
+ mark2Coverage.sanitize (c, this) &&
+ mark1Array.sanitize (c, this) &&
+ mark2Array.sanitize (c, this, (unsigned int) classCount));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ {
+ return (this+mark1Coverage).intersects (glyphs) &&
+ (this+mark2Coverage).intersects (glyphs);
+ }
+
+ void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ + hb_zip (this+mark1Coverage, this+mark1Array)
+ | hb_filter (c->glyph_set, hb_first)
+ | hb_map (hb_second)
+ | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); })
+ ;
+
+ hb_map_t klass_mapping;
+ Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, *c->glyph_set, &klass_mapping);
+
+ unsigned mark2_count = (this+mark2Array).rows;
+ auto mark2_iter =
+ + hb_zip (this+mark2Coverage, hb_range (mark2_count))
+ | hb_filter (c->glyph_set, hb_first)
+ | hb_map (hb_second)
+ ;
+
+ hb_sorted_vector_t<unsigned> mark2_indexes;
+ for (const unsigned row : mark2_iter)
+ {
+ + hb_range ((unsigned) classCount)
+ | hb_filter (klass_mapping)
+ | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+ | hb_sink (mark2_indexes)
+ ;
+ }
+ (this+mark2Array).collect_variation_indices (c, mark2_indexes.iter ());
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ if (unlikely (!(this+mark1Coverage).collect_coverage (c->input))) return;
+ if (unlikely (!(this+mark2Coverage).collect_coverage (c->input))) return;
+ }
+
+ const Coverage &get_coverage () const { return this+mark1Coverage; }
+
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (mark1_index == NOT_COVERED)) return_trace (false);
+
+ /* now we search backwards for a suitable mark glyph until a non-mark glyph */
+ 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);
+ 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]))
+ {
+ buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+ return_trace (false);
+ }
+
+ unsigned int j = skippy_iter.idx;
+
+ unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+ unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
+
+ if (likely (id1 == id2))
+ {
+ if (id1 == 0) /* Marks belonging to the same base. */
+ goto good;
+ else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
+ goto good;
+ }
+ else
+ {
+ /* If ligature ids don't match, it may be the case that one of the marks
+ * itself is a ligature. In which case match. */
+ if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
+ goto good;
+ }
+
+ /* 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)
+ {
+ 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));
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+
+ hb_map_t klass_mapping;
+ Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping);
+
+ if (!klass_mapping.get_population ()) return_trace (false);
+ out->classCount = klass_mapping.get_population ();
+
+ auto mark1_iter =
+ + hb_zip (this+mark1Coverage, this+mark1Array)
+ | hb_filter (glyphset, hb_first)
+ ;
+
+ hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ + mark1_iter
+ | hb_map (hb_first)
+ | hb_map (glyph_map)
+ | hb_sink (new_coverage)
+ ;
+
+ if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+ return_trace (false);
+
+ out->mark1Array.serialize_subset (c, mark1Array, this,
+ (this+mark1Coverage).iter (),
+ &klass_mapping);
+
+ unsigned mark2count = (this+mark2Array).rows;
+ auto mark2_iter =
+ + hb_zip (this+mark2Coverage, hb_range (mark2count))
+ | hb_filter (glyphset, hb_first)
+ ;
+
+ new_coverage.reset ();
+ + mark2_iter
+ | hb_map (hb_first)
+ | hb_map (glyph_map)
+ | hb_sink (new_coverage)
+ ;
+
+ if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+ return_trace (false);
+
+ hb_sorted_vector_t<unsigned> mark2_indexes;
+ for (const unsigned row : + mark2_iter
+ | hb_map (hb_second))
+ {
+ + hb_range ((unsigned) classCount)
+ | hb_filter (klass_mapping)
+ | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+ | hb_sink (mark2_indexes)
+ ;
+ }
+
+ out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ());
+
+ return_trace (true);
+ }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh
new file mode 100644
index 0000000000..7a514453ae
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh
@@ -0,0 +1,52 @@
+#ifndef OT_LAYOUT_GPOS_MARKRECORD_HH
+#define OT_LAYOUT_GPOS_MARKRECORD_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkRecord
+{
+ friend struct MarkArray;
+
+ protected:
+ HBUINT16 klass; /* Class defined for this mark */
+ Offset16To<Anchor>
+ markAnchor; /* Offset to Anchor table--from
+ * beginning of MarkArray table */
+ public:
+ DEFINE_SIZE_STATIC (4);
+
+ unsigned get_class () const { return (unsigned) klass; }
+ bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
+ }
+
+ MarkRecord *subset (hb_subset_context_t *c,
+ const void *src_base,
+ const hb_map_t *klass_mapping) const
+ {
+ TRACE_SUBSET (this);
+ auto *out = c->serializer->embed (this);
+ if (unlikely (!out)) return_trace (nullptr);
+
+ out->klass = klass_mapping->get (klass);
+ out->markAnchor.serialize_subset (c, markAnchor, src_base);
+ return_trace (out);
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ const void *src_base) const
+ {
+ (src_base+markAnchor).collect_variation_indices (c);
+ }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKRECORD_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh
new file mode 100644
index 0000000000..8479178d38
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh
@@ -0,0 +1,38 @@
+#ifndef OT_LAYOUT_GPOS_PAIRPOS_HH
+#define OT_LAYOUT_GPOS_PAIRPOS_HH
+
+#include "PairPosFormat1.hh"
+#include "PairPosFormat2.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct PairPos
+{
+ protected:
+ union {
+ HBUINT16 format; /* Format identifier */
+ PairPosFormat1 format1;
+ PairPosFormat2 format2;
+ } u;
+
+ public:
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+};
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_PAIRPOS_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
new file mode 100644
index 0000000000..35a2db2d45
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
@@ -0,0 +1,420 @@
+#ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct PairValueRecord
+{
+ friend struct PairSet;
+
+ int cmp (hb_codepoint_t k) const
+ { return secondGlyph.cmp (k); }
+
+ struct context_t
+ {
+ const void *base;
+ const ValueFormat *valueFormats;
+ const ValueFormat *newFormats;
+ unsigned len1; /* valueFormats[0].get_len() */
+ const hb_map_t *glyph_map;
+ const hb_map_t *layout_variation_idx_map;
+ };
+
+ bool subset (hb_subset_context_t *c,
+ context_t *closure) const
+ {
+ TRACE_SERIALIZE (this);
+ auto *s = c->serializer;
+ auto *out = s->start_embed (*this);
+ if (unlikely (!s->extend_min (out))) return_trace (false);
+
+ out->secondGlyph = (*closure->glyph_map)[secondGlyph];
+
+ closure->valueFormats[0].copy_values (s,
+ closure->newFormats[0],
+ closure->base, &values[0],
+ closure->layout_variation_idx_map);
+ closure->valueFormats[1].copy_values (s,
+ closure->newFormats[1],
+ closure->base,
+ &values[closure->len1],
+ closure->layout_variation_idx_map);
+
+ return_trace (true);
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ const ValueFormat *valueFormats,
+ const void *base) const
+ {
+ unsigned record1_len = valueFormats[0].get_len ();
+ unsigned record2_len = valueFormats[1].get_len ();
+ const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len);
+
+ if (valueFormats[0].has_device ())
+ valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len));
+
+ if (valueFormats[1].has_device ())
+ valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len));
+ }
+
+ bool intersects (const hb_set_t& glyphset) const
+ {
+ return glyphset.has(secondGlyph);
+ }
+
+ const Value* get_values_1 () const
+ {
+ return &values[0];
+ }
+
+ const Value* get_values_2 (ValueFormat format1) const
+ {
+ return &values[format1.get_len ()];
+ }
+
+ protected:
+ HBGlyphID16 secondGlyph; /* GlyphID of second glyph in the
+ * pair--first glyph is listed in the
+ * Coverage table */
+ ValueRecord values; /* Positioning data for the first glyph
+ * followed by for second glyph */
+ public:
+ DEFINE_SIZE_ARRAY (2, values);
+};
+
+struct PairSet
+{
+ friend struct PairPosFormat1;
+
+ bool intersects (const hb_set_t *glyphs,
+ const ValueFormat *valueFormats) const
+ {
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (glyphs->has (record->secondGlyph))
+ return true;
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+ return false;
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ c->input->add_array (&record->secondGlyph, len, record_size);
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ unsigned len1 = valueFormats[0].get_len ();
+ unsigned len2 = valueFormats[1].get_len ();
+ unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned count = len;
+ for (unsigned i = 0; i < count; i++)
+ {
+ if (c->glyph_set->has (record->secondGlyph))
+ { record->collect_variation_indices (c, valueFormats, this); }
+
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+ }
+
+ bool apply (hb_ot_apply_context_t *c,
+ const ValueFormat *valueFormats,
+ unsigned int pos) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
+ &firstPairValueRecord,
+ len,
+ record_size);
+ if (record)
+ {
+ bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
+ bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+ if (applied_first || applied_second)
+ buffer->unsafe_to_break (buffer->idx, pos + 1);
+ if (len2)
+ pos++;
+ buffer->idx = pos;
+ return_trace (true);
+ }
+ buffer->unsafe_to_concat (buffer->idx, pos + 1);
+ return_trace (false);
+ }
+
+ bool subset (hb_subset_context_t *c,
+ const ValueFormat valueFormats[2],
+ const ValueFormat newFormats[2]) const
+ {
+ TRACE_SUBSET (this);
+ auto snap = c->serializer->snapshot ();
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->len = 0;
+
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ unsigned len1 = valueFormats[0].get_len ();
+ unsigned len2 = valueFormats[1].get_len ();
+ unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
+
+ PairValueRecord::context_t context =
+ {
+ this,
+ valueFormats,
+ newFormats,
+ len1,
+ &glyph_map,
+ c->plan->layout_variation_idx_map
+ };
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned count = len, num = 0;
+ for (unsigned i = 0; i < count; i++)
+ {
+ if (glyphset.has (record->secondGlyph)
+ && record->subset (c, &context)) num++;
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+
+ out->len = num;
+ if (!num) c->serializer->revert (snap);
+ return_trace (num);
+ }
+
+ struct sanitize_closure_t
+ {
+ const ValueFormat *valueFormats;
+ unsigned int len1; /* valueFormats[0].get_len() */
+ unsigned int stride; /* 1 + len1 + len2 */
+ };
+
+ bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
+ {
+ TRACE_SANITIZE (this);
+ if (!(c->check_struct (this)
+ && c->check_range (&firstPairValueRecord,
+ len,
+ HBUINT16::static_size,
+ closure->stride))) return_trace (false);
+
+ unsigned int count = len;
+ const PairValueRecord *record = &firstPairValueRecord;
+ return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
+ closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
+ }
+
+ protected:
+ HBUINT16 len; /* Number of PairValueRecords */
+ PairValueRecord firstPairValueRecord;
+ /* Array of PairValueRecords--ordered
+ * by GlyphID of the second glyph */
+ public:
+ DEFINE_SIZE_MIN (2);
+};
+
+struct PairPosFormat1
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 1 */
+ Offset16To<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat[2]; /* [0] Defines the types of data in
+ * ValueRecord1--for the first glyph
+ * in the pair--may be zero (0) */
+ /* [1] Defines the types of data in
+ * ValueRecord2--for the second glyph
+ * in the pair--may be zero (0) */
+ Array16OfOffset16To<PairSet>
+ pairSet; /* Array of PairSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (10, pairSet);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+
+ if (!c->check_struct (this)) return_trace (false);
+
+ unsigned int len1 = valueFormat[0].get_len ();
+ unsigned int len2 = valueFormat[1].get_len ();
+ PairSet::sanitize_closure_t closure =
+ {
+ valueFormat,
+ len1,
+ 1 + len1 + len2
+ };
+
+ return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
+ }
+
+
+ bool intersects (const hb_set_t *glyphs) const
+ {
+ return
+ + hb_zip (this+coverage, pairSet)
+ | hb_filter (*glyphs, hb_first)
+ | hb_map (hb_second)
+ | hb_map ([glyphs, this] (const Offset16To<PairSet> &_)
+ { return (this+_).intersects (glyphs, valueFormat); })
+ | hb_any
+ ;
+ }
+
+ void closure_lookups (hb_closure_lookups_context_t *c) const {}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ if ((!valueFormat[0].has_device ()) && (!valueFormat[1].has_device ())) return;
+
+ auto it =
+ + hb_zip (this+coverage, pairSet)
+ | hb_filter (c->glyph_set, hb_first)
+ | hb_map (hb_second)
+ ;
+
+ if (!it) return;
+ + it
+ | hb_map (hb_add (this))
+ | hb_apply ([&] (const PairSet& _) { _.collect_variation_indices (c, valueFormat); })
+ ;
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
+ unsigned int count = pairSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+pairSet[i]).collect_glyphs (c, valueFormat);
+ }
+
+ const Coverage &get_coverage () const { return this+coverage; }
+
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, 1);
+ 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));
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+ out->valueFormat[0] = valueFormat[0];
+ out->valueFormat[1] = valueFormat[1];
+ if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+ {
+ hb_pair_t<unsigned, unsigned> newFormats = compute_effective_value_formats (glyphset);
+ out->valueFormat[0] = newFormats.first;
+ out->valueFormat[1] = newFormats.second;
+ }
+
+ hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+
+ + hb_zip (this+coverage, pairSet)
+ | hb_filter (glyphset, hb_first)
+ | hb_filter ([this, c, out] (const Offset16To<PairSet>& _)
+ {
+ auto snap = c->serializer->snapshot ();
+ auto *o = out->pairSet.serialize_append (c->serializer);
+ if (unlikely (!o)) return false;
+ bool ret = o->serialize_subset (c, _, this, valueFormat, out->valueFormat);
+ if (!ret)
+ {
+ out->pairSet.pop ();
+ c->serializer->revert (snap);
+ }
+ return ret;
+ },
+ hb_second)
+ | hb_map (hb_first)
+ | hb_map (glyph_map)
+ | hb_sink (new_coverage)
+ ;
+
+ out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
+
+ return_trace (bool (new_coverage));
+ }
+
+
+ hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_set_t& glyphset) const
+ {
+ unsigned len1 = valueFormat[0].get_len ();
+ unsigned len2 = valueFormat[1].get_len ();
+ unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
+
+ unsigned format1 = 0;
+ unsigned format2 = 0;
+ for (const Offset16To<PairSet>& _ :
+ + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second))
+ {
+ const PairSet& set = (this + _);
+ const PairValueRecord *record = &set.firstPairValueRecord;
+
+ for (unsigned i = 0; i < set.len; i++)
+ {
+ if (record->intersects (glyphset))
+ {
+ format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 ());
+ format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0]));
+ }
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+ }
+
+ return hb_pair (format1, format2);
+ }
+};
+
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
new file mode 100644
index 0000000000..3f5f9959c4
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
@@ -0,0 +1,314 @@
+#ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT2_HH
+#define OT_LAYOUT_GPOS_PAIRPOSFORMAT2_HH
+
+#include "ValueFormat.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct PairPosFormat2
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 2 */
+ Offset16To<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat1; /* ValueRecord definition--for the
+ * first glyph of the pair--may be zero
+ * (0) */
+ ValueFormat valueFormat2; /* ValueRecord definition--for the
+ * second glyph of the pair--may be
+ * zero (0) */
+ Offset16To<ClassDef>
+ classDef1; /* Offset to ClassDef table--from
+ * beginning of PairPos subtable--for
+ * the first glyph of the pair */
+ Offset16To<ClassDef>
+ classDef2; /* Offset to ClassDef table--from
+ * beginning of PairPos subtable--for
+ * the second glyph of the pair */
+ HBUINT16 class1Count; /* Number of classes in ClassDef1
+ * table--includes Class0 */
+ HBUINT16 class2Count; /* Number of classes in ClassDef2
+ * table--includes Class0 */
+ ValueRecord values; /* Matrix of value pairs:
+ * class1-major, class2-minor,
+ * Each entry has value1 and value2 */
+ public:
+ DEFINE_SIZE_ARRAY (16, values);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!(c->check_struct (this)
+ && coverage.sanitize (c, this)
+ && classDef1.sanitize (c, this)
+ && classDef2.sanitize (c, this))) return_trace (false);
+
+ unsigned int len1 = valueFormat1.get_len ();
+ unsigned int len2 = valueFormat2.get_len ();
+ unsigned int stride = len1 + len2;
+ unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
+ unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
+ return_trace (c->check_range ((const void *) values,
+ count,
+ record_size) &&
+ valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
+ valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ {
+ return (this+coverage).intersects (glyphs) &&
+ (this+classDef2).intersects (glyphs);
+ }
+
+ void closure_lookups (hb_closure_lookups_context_t *c) const {}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ if (!intersects (c->glyph_set)) return;
+ if ((!valueFormat1.has_device ()) && (!valueFormat2.has_device ())) return;
+
+ hb_set_t klass1_glyphs, klass2_glyphs;
+ if (!(this+classDef1).collect_coverage (&klass1_glyphs)) return;
+ if (!(this+classDef2).collect_coverage (&klass2_glyphs)) return;
+
+ hb_set_t class1_set, class2_set;
+ for (const unsigned cp : + c->glyph_set->iter () | hb_filter (this + coverage))
+ {
+ if (!klass1_glyphs.has (cp)) class1_set.add (0);
+ else
+ {
+ unsigned klass1 = (this+classDef1).get (cp);
+ class1_set.add (klass1);
+ }
+ }
+
+ class2_set.add (0);
+ for (const unsigned cp : + c->glyph_set->iter () | hb_filter (klass2_glyphs))
+ {
+ unsigned klass2 = (this+classDef2).get (cp);
+ class2_set.add (klass2);
+ }
+
+ if (class1_set.is_empty ()
+ || class2_set.is_empty ()
+ || (class2_set.get_population() == 1 && class2_set.has(0)))
+ return;
+
+ unsigned len1 = valueFormat1.get_len ();
+ unsigned len2 = valueFormat2.get_len ();
+ const hb_array_t<const Value> values_array = values.as_array ((unsigned)class1Count * (unsigned) class2Count * (len1 + len2));
+ for (const unsigned class1_idx : class1_set.iter ())
+ {
+ for (const unsigned class2_idx : class2_set.iter ())
+ {
+ unsigned start_offset = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
+ if (valueFormat1.has_device ())
+ valueFormat1.collect_variation_indices (c, this, values_array.sub_array (start_offset, len1));
+
+ if (valueFormat2.has_device ())
+ valueFormat2.collect_variation_indices (c, this, values_array.sub_array (start_offset+len1, len2));
+ }
+ }
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
+ if (unlikely (!(this+classDef2).collect_coverage (c->input))) return;
+ }
+
+ const Coverage &get_coverage () const { return this+coverage; }
+
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, 1);
+ 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 ();
+ unsigned int record_len = len1 + len2;
+
+ 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))
+ {
+ 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 = false, applied_second = false;
+
+
+ /* Isolate simple kerning and apply it half to each side.
+ * Results in better cursor positinoing / underline drawing.
+ *
+ * Disabled, because causes issues... :-(
+ * https://github.com/harfbuzz/harfbuzz/issues/3408
+ * https://github.com/harfbuzz/harfbuzz/pull/3235#issuecomment-1029814978
+ */
+#ifndef HB_SPLIT_KERN
+ if (0)
+#endif
+ {
+ 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)
+ buffer->idx++;
+
+ return_trace (true);
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+
+ hb_map_t klass1_map;
+ out->classDef1.serialize_subset (c, classDef1, this, &klass1_map, true, true, &(this + coverage));
+ out->class1Count = klass1_map.get_population ();
+
+ hb_map_t klass2_map;
+ out->classDef2.serialize_subset (c, classDef2, this, &klass2_map, true, false);
+ out->class2Count = klass2_map.get_population ();
+
+ unsigned len1 = valueFormat1.get_len ();
+ unsigned len2 = valueFormat2.get_len ();
+
+ hb_pair_t<unsigned, unsigned> newFormats = hb_pair (valueFormat1, valueFormat2);
+ if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+ newFormats = compute_effective_value_formats (klass1_map, klass2_map);
+
+ out->valueFormat1 = newFormats.first;
+ out->valueFormat2 = newFormats.second;
+
+ for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
+ {
+ for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
+ {
+ unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
+ valueFormat1.copy_values (c->serializer, newFormats.first, this, &values[idx], c->plan->layout_variation_idx_map);
+ valueFormat2.copy_values (c->serializer, newFormats.second, this, &values[idx + len1], c->plan->layout_variation_idx_map);
+ }
+ }
+
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto it =
+ + hb_iter (this+coverage)
+ | hb_filter (glyphset)
+ | hb_map_retains_sorting (glyph_map)
+ ;
+
+ out->coverage.serialize_serialize (c->serializer, it);
+ return_trace (out->class1Count && out->class2Count && bool (it));
+ }
+
+
+ hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_map_t& klass1_map,
+ const hb_map_t& klass2_map) const
+ {
+ unsigned len1 = valueFormat1.get_len ();
+ unsigned len2 = valueFormat2.get_len ();
+
+ unsigned format1 = 0;
+ unsigned format2 = 0;
+
+ for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
+ {
+ for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
+ {
+ unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
+ format1 = format1 | valueFormat1.get_effective_format (&values[idx]);
+ format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]);
+ }
+ }
+
+ return hb_pair (format1, format2);
+ }
+};
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_PAIRPOSFORMAT2_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PosLookup.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PosLookup.hh
new file mode 100644
index 0000000000..c4e57bb543
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PosLookup.hh
@@ -0,0 +1,79 @@
+#ifndef OT_LAYOUT_GPOS_POSLOOKUP_HH
+#define OT_LAYOUT_GPOS_POSLOOKUP_HH
+
+#include "PosLookupSubTable.hh"
+#include "../../../hb-ot-layout-common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct PosLookup : Lookup
+{
+ using SubTable = PosLookupSubTable;
+
+ const SubTable& get_subtable (unsigned int i) const
+ { return Lookup::get_subtable<SubTable> (i); }
+
+ bool is_reverse () const
+ {
+ return false;
+ }
+
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ return_trace (dispatch (c));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ {
+ hb_intersects_context_t c (glyphs);
+ return dispatch (&c);
+ }
+
+ hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
+ { return dispatch (c); }
+
+ hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
+ {
+ if (c->is_lookup_visited (this_index))
+ return hb_closure_lookups_context_t::default_return_value ();
+
+ c->set_lookup_visited (this_index);
+ if (!intersects (c->glyphs))
+ {
+ c->set_lookup_inactive (this_index);
+ return hb_closure_lookups_context_t::default_return_value ();
+ }
+
+ hb_closure_lookups_context_t::return_t ret = dispatch (c);
+ return ret;
+ }
+
+ template <typename set_t>
+ void collect_coverage (set_t *glyphs) const
+ {
+ hb_collect_coverage_context_t<set_t> c (glyphs);
+ dispatch (&c);
+ }
+
+ template <typename context_t>
+ static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+ { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
+
+ bool subset (hb_subset_context_t *c) const
+ { return Lookup::subset<SubTable> (c); }
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ { return Lookup::sanitize<SubTable> (c); }
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_POSLOOKUP_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PosLookupSubTable.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PosLookupSubTable.hh
new file mode 100644
index 0000000000..c19fbc323f
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PosLookupSubTable.hh
@@ -0,0 +1,79 @@
+#ifndef OT_LAYOUT_GPOS_POSLOOKUPSUBTABLE_HH
+#define OT_LAYOUT_GPOS_POSLOOKUPSUBTABLE_HH
+
+#include "SinglePos.hh"
+#include "PairPos.hh"
+#include "CursivePos.hh"
+#include "MarkBasePos.hh"
+#include "MarkLigPos.hh"
+#include "MarkMarkPos.hh"
+#include "ContextPos.hh"
+#include "ChainContextPos.hh"
+#include "ExtensionPos.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct PosLookupSubTable
+{
+ friend struct ::OT::Lookup;
+ friend struct PosLookup;
+
+ enum Type {
+ Single = 1,
+ Pair = 2,
+ Cursive = 3,
+ MarkBase = 4,
+ MarkLig = 5,
+ MarkMark = 6,
+ Context = 7,
+ ChainContext = 8,
+ Extension = 9
+ };
+
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
+ {
+ TRACE_DISPATCH (this, lookup_type);
+ switch (lookup_type) {
+ case Single: return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...));
+ case Pair: return_trace (u.pair.dispatch (c, std::forward<Ts> (ds)...));
+ case Cursive: return_trace (u.cursive.dispatch (c, std::forward<Ts> (ds)...));
+ case MarkBase: return_trace (u.markBase.dispatch (c, std::forward<Ts> (ds)...));
+ case MarkLig: return_trace (u.markLig.dispatch (c, std::forward<Ts> (ds)...));
+ case MarkMark: return_trace (u.markMark.dispatch (c, std::forward<Ts> (ds)...));
+ case Context: return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...));
+ case ChainContext: return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...));
+ case Extension: return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...));
+ default: return_trace (c->default_return_value ());
+ }
+ }
+
+ bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
+ {
+ hb_intersects_context_t c (glyphs);
+ return dispatch (&c, lookup_type);
+ }
+
+ protected:
+ union {
+ SinglePos single;
+ PairPos pair;
+ CursivePos cursive;
+ MarkBasePos markBase;
+ MarkLigPos markLig;
+ MarkMarkPos markMark;
+ ContextPos context;
+ ChainContextPos chainContext;
+ ExtensionPos extension;
+ } u;
+ public:
+ DEFINE_SIZE_MIN (0);
+};
+
+}
+}
+}
+
+#endif /* HB_OT_LAYOUT_GPOS_POSLOOKUPSUBTABLE_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh
new file mode 100644
index 0000000000..57e146befd
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh
@@ -0,0 +1,98 @@
+#ifndef OT_LAYOUT_GPOS_SINGLEPOS_HH
+#define OT_LAYOUT_GPOS_SINGLEPOS_HH
+
+#include "SinglePosFormat1.hh"
+#include "SinglePosFormat2.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct SinglePos
+{
+ protected:
+ union {
+ HBUINT16 format; /* Format identifier */
+ SinglePosFormat1 format1;
+ SinglePosFormat2 format2;
+ } u;
+
+ public:
+ template<typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ unsigned get_format (Iterator glyph_val_iter_pairs)
+ {
+ hb_array_t<const Value> first_val_iter = hb_second (*glyph_val_iter_pairs);
+
+ for (const auto iter : glyph_val_iter_pairs)
+ for (const auto _ : hb_zip (iter.second, first_val_iter))
+ if (_.first != _.second)
+ return 2;
+
+ return 1;
+ }
+
+ template<typename Iterator,
+ typename SrcLookup,
+ hb_requires (hb_is_iterator (Iterator))>
+ void serialize (hb_serialize_context_t *c,
+ const SrcLookup* src,
+ Iterator glyph_val_iter_pairs,
+ const hb_map_t *layout_variation_idx_map)
+ {
+ if (unlikely (!c->extend_min (u.format))) return;
+ unsigned format = 2;
+ ValueFormat new_format = src->get_value_format ();
+
+ if (glyph_val_iter_pairs)
+ {
+ format = get_format (glyph_val_iter_pairs);
+ new_format = src->get_value_format ().get_effective_format (+ glyph_val_iter_pairs | hb_map (hb_second));
+ }
+
+ u.format = format;
+ switch (u.format) {
+ case 1: u.format1.serialize (c,
+ src,
+ glyph_val_iter_pairs,
+ new_format,
+ layout_variation_idx_map);
+ return;
+ case 2: u.format2.serialize (c,
+ src,
+ glyph_val_iter_pairs,
+ new_format,
+ layout_variation_idx_map);
+ return;
+ default:return;
+ }
+ }
+
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+};
+
+
+template<typename Iterator, typename SrcLookup>
+static void
+SinglePos_serialize (hb_serialize_context_t *c,
+ const SrcLookup *src,
+ Iterator it,
+ const hb_map_t *layout_variation_idx_map)
+{ c->start_embed<SinglePos> ()->serialize (c, src, it, layout_variation_idx_map); }
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_SINGLEPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh
new file mode 100644
index 0000000000..8b7840ed0e
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh
@@ -0,0 +1,124 @@
+#ifndef OT_LAYOUT_GPOS_SINGLEPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_SINGLEPOSFORMAT1_HH
+
+#include "Common.hh"
+#include "ValueFormat.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct SinglePosFormat1
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 1 */
+ Offset16To<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat; /* Defines the types of data in the
+ * ValueRecord */
+ ValueRecord values; /* Defines positioning
+ * value(s)--applied to all glyphs in
+ * the Coverage table */
+ public:
+ DEFINE_SIZE_ARRAY (6, values);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ coverage.sanitize (c, this) &&
+ valueFormat.sanitize_value (c, this, values));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ { return (this+coverage).intersects (glyphs); }
+
+ void closure_lookups (hb_closure_lookups_context_t *c) const {}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ if (!valueFormat.has_device ()) return;
+
+ auto it =
+ + hb_iter (this+coverage)
+ | hb_filter (c->glyph_set)
+ ;
+
+ if (!it) return;
+ valueFormat.collect_variation_indices (c, this, values.as_array (valueFormat.get_len ()));
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
+
+ const Coverage &get_coverage () const { return this+coverage; }
+
+ ValueFormat get_value_format () const { return valueFormat; }
+
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ valueFormat.apply_value (c, this, values, buffer->cur_pos());
+
+ buffer->idx++;
+ return_trace (true);
+ }
+
+ template<typename Iterator,
+ typename SrcLookup,
+ hb_requires (hb_is_iterator (Iterator))>
+ void serialize (hb_serialize_context_t *c,
+ const SrcLookup *src,
+ Iterator it,
+ ValueFormat newFormat,
+ const hb_map_t *layout_variation_idx_map)
+ {
+ if (unlikely (!c->extend_min (this))) return;
+ if (unlikely (!c->check_assign (valueFormat,
+ newFormat,
+ HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
+
+ for (const hb_array_t<const Value>& _ : + it | hb_map (hb_second))
+ {
+ src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map);
+ // Only serialize the first entry in the iterator, the rest are assumed to
+ // be the same.
+ break;
+ }
+
+ auto glyphs =
+ + it
+ | hb_map_retains_sorting (hb_first)
+ ;
+
+ coverage.serialize_serialize (c, glyphs);
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto it =
+ + hb_iter (this+coverage)
+ | hb_filter (glyphset)
+ | hb_map_retains_sorting (glyph_map)
+ | hb_zip (hb_repeat (values.as_array (valueFormat.get_len ())))
+ ;
+
+ bool ret = bool (it);
+ SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map);
+ return_trace (ret);
+ }
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_SINGLEPOSFORMAT1_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh
new file mode 100644
index 0000000000..0d038b4422
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat2.hh
@@ -0,0 +1,140 @@
+#ifndef OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH
+#define OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH
+
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct SinglePosFormat2
+{
+ protected:
+ HBUINT16 format; /* Format identifier--format = 2 */
+ Offset16To<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat; /* Defines the types of data in the
+ * ValueRecord */
+ HBUINT16 valueCount; /* Number of ValueRecords */
+ ValueRecord values; /* Array of ValueRecords--positioning
+ * values applied to glyphs */
+ public:
+ DEFINE_SIZE_ARRAY (8, values);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ coverage.sanitize (c, this) &&
+ valueFormat.sanitize_values (c, this, values, valueCount));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ { return (this+coverage).intersects (glyphs); }
+
+ void closure_lookups (hb_closure_lookups_context_t *c) const {}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ {
+ if (!valueFormat.has_device ()) return;
+
+ auto it =
+ + hb_zip (this+coverage, hb_range ((unsigned) valueCount))
+ | hb_filter (c->glyph_set, hb_first)
+ ;
+
+ if (!it) return;
+
+ unsigned sub_length = valueFormat.get_len ();
+ const hb_array_t<const Value> values_array = values.as_array (valueCount * sub_length);
+
+ for (unsigned i : + it
+ | hb_map (hb_second))
+ valueFormat.collect_variation_indices (c, this, values_array.sub_array (i * sub_length, sub_length));
+
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
+
+ const Coverage &get_coverage () const { return this+coverage; }
+
+ ValueFormat get_value_format () const { return valueFormat; }
+
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ if (likely (index >= valueCount)) return_trace (false);
+
+ valueFormat.apply_value (c, this,
+ &values[index * valueFormat.get_len ()],
+ buffer->cur_pos());
+
+ buffer->idx++;
+ return_trace (true);
+ }
+
+ template<typename Iterator,
+ typename SrcLookup,
+ hb_requires (hb_is_iterator (Iterator))>
+ void serialize (hb_serialize_context_t *c,
+ const SrcLookup *src,
+ Iterator it,
+ ValueFormat newFormat,
+ const hb_map_t *layout_variation_idx_map)
+ {
+ auto out = c->extend_min (this);
+ if (unlikely (!out)) return;
+ if (unlikely (!c->check_assign (valueFormat, newFormat, HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
+ if (unlikely (!c->check_assign (valueCount, it.len (), HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return;
+
+ + it
+ | hb_map (hb_second)
+ | hb_apply ([&] (hb_array_t<const Value> _)
+ { src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map); })
+ ;
+
+ auto glyphs =
+ + it
+ | hb_map_retains_sorting (hb_first)
+ ;
+
+ coverage.serialize_serialize (c, glyphs);
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ unsigned sub_length = valueFormat.get_len ();
+ auto values_array = values.as_array (valueCount * sub_length);
+
+ auto it =
+ + hb_zip (this+coverage, hb_range ((unsigned) valueCount))
+ | hb_filter (glyphset, hb_first)
+ | hb_map_retains_sorting ([&] (const hb_pair_t<hb_codepoint_t, unsigned>& _)
+ {
+ return hb_pair (glyph_map[_.first],
+ values_array.sub_array (_.second * sub_length,
+ sub_length));
+ })
+ ;
+
+ bool ret = bool (it);
+ SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map);
+ return_trace (ret);
+ }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh
new file mode 100644
index 0000000000..b29f287bce
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh
@@ -0,0 +1,329 @@
+#ifndef OT_LAYOUT_GPOS_VALUEFORMAT_HH
+#define OT_LAYOUT_GPOS_VALUEFORMAT_HH
+
+#include "../../../hb-ot-layout-gsubgpos.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+typedef HBUINT16 Value;
+
+typedef UnsizedArrayOf<Value> ValueRecord;
+
+struct ValueFormat : HBUINT16
+{
+ enum Flags {
+ xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */
+ yPlacement = 0x0002u, /* Includes vertical adjustment for placement */
+ xAdvance = 0x0004u, /* Includes horizontal adjustment for advance */
+ yAdvance = 0x0008u, /* Includes vertical adjustment for advance */
+ xPlaDevice = 0x0010u, /* Includes horizontal Device table for placement */
+ yPlaDevice = 0x0020u, /* Includes vertical Device table for placement */
+ xAdvDevice = 0x0040u, /* Includes horizontal Device table for advance */
+ yAdvDevice = 0x0080u, /* Includes vertical Device table for advance */
+ ignored = 0x0F00u, /* Was used in TrueType Open for MM fonts */
+ reserved = 0xF000u, /* For future use */
+
+ devices = 0x00F0u /* Mask for having any Device table */
+ };
+
+/* All fields are options. Only those available advance the value pointer. */
+#if 0
+ HBINT16 xPlacement; /* Horizontal adjustment for
+ * placement--in design units */
+ HBINT16 yPlacement; /* Vertical adjustment for
+ * placement--in design units */
+ HBINT16 xAdvance; /* Horizontal adjustment for
+ * advance--in design units (only used
+ * for horizontal writing) */
+ HBINT16 yAdvance; /* Vertical adjustment for advance--in
+ * design units (only used for vertical
+ * writing) */
+ Offset16To<Device> xPlaDevice; /* Offset to Device table for
+ * horizontal placement--measured from
+ * beginning of PosTable (may be NULL) */
+ Offset16To<Device> yPlaDevice; /* Offset to Device table for vertical
+ * placement--measured from beginning
+ * of PosTable (may be NULL) */
+ Offset16To<Device> xAdvDevice; /* Offset to Device table for
+ * horizontal advance--measured from
+ * beginning of PosTable (may be NULL) */
+ Offset16To<Device> yAdvDevice; /* Offset to Device table for vertical
+ * advance--measured from beginning of
+ * PosTable (may be NULL) */
+#endif
+
+ IntType& operator = (uint16_t i) { v = i; return *this; }
+
+ unsigned int get_len () const { return hb_popcount ((unsigned int) *this); }
+ unsigned int get_size () const { return get_len () * Value::static_size; }
+
+ bool apply_value (hb_ot_apply_context_t *c,
+ const void *base,
+ const Value *values,
+ hb_glyph_position_t &glyph_pos) const
+ {
+ bool ret = false;
+ unsigned int format = *this;
+ if (!format) return ret;
+
+ hb_font_t *font = c->font;
+ bool horizontal =
+#ifndef HB_NO_VERTICAL
+ HB_DIRECTION_IS_HORIZONTAL (c->direction)
+#else
+ true
+#endif
+ ;
+
+ if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++, &ret));
+ if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++, &ret));
+ if (format & xAdvance) {
+ if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values, &ret));
+ values++;
+ }
+ /* y_advance values grow downward but font-space grows upward, hence negation */
+ if (format & yAdvance) {
+ if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values, &ret));
+ values++;
+ }
+
+ if (!has_device ()) return ret;
+
+ bool use_x_device = font->x_ppem || font->num_coords;
+ bool use_y_device = font->y_ppem || font->num_coords;
+
+ if (!use_x_device && !use_y_device) return ret;
+
+ const VariationStore &store = c->var_store;
+ auto *cache = c->var_store_cache;
+
+ /* pixel -> fractional pixel */
+ if (format & xPlaDevice) {
+ if (use_x_device) glyph_pos.x_offset += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
+ values++;
+ }
+ if (format & yPlaDevice) {
+ if (use_y_device) glyph_pos.y_offset += (base + get_device (values, &ret)).get_y_delta (font, store, cache);
+ values++;
+ }
+ if (format & xAdvDevice) {
+ if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
+ values++;
+ }
+ if (format & yAdvDevice) {
+ /* y_advance values grow downward but font-space grows upward, hence negation */
+ if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store, cache);
+ values++;
+ }
+ return ret;
+ }
+
+ unsigned int get_effective_format (const Value *values) const
+ {
+ unsigned int format = *this;
+ for (unsigned flag = xPlacement; flag <= yAdvDevice; flag = flag << 1) {
+ if (format & flag) should_drop (*values++, (Flags) flag, &format);
+ }
+
+ return format;
+ }
+
+ template<typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ unsigned int get_effective_format (Iterator it) const {
+ unsigned int new_format = 0;
+
+ for (const hb_array_t<const Value>& values : it)
+ new_format = new_format | get_effective_format (&values);
+
+ return new_format;
+ }
+
+ void copy_values (hb_serialize_context_t *c,
+ unsigned int new_format,
+ const void *base,
+ const Value *values,
+ const hb_map_t *layout_variation_idx_map) const
+ {
+ unsigned int format = *this;
+ if (!format) return;
+
+ if (format & xPlacement) copy_value (c, new_format, xPlacement, *values++);
+ if (format & yPlacement) copy_value (c, new_format, yPlacement, *values++);
+ if (format & xAdvance) copy_value (c, new_format, xAdvance, *values++);
+ if (format & yAdvance) copy_value (c, new_format, yAdvance, *values++);
+
+ if (format & xPlaDevice) copy_device (c, base, values++, layout_variation_idx_map);
+ if (format & yPlaDevice) copy_device (c, base, values++, layout_variation_idx_map);
+ if (format & xAdvDevice) copy_device (c, base, values++, layout_variation_idx_map);
+ if (format & yAdvDevice) copy_device (c, base, values++, layout_variation_idx_map);
+ }
+
+ void copy_value (hb_serialize_context_t *c,
+ unsigned int new_format,
+ Flags flag,
+ Value value) const
+ {
+ // Filter by new format.
+ if (!(new_format & flag)) return;
+ c->copy (value);
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ const void *base,
+ const hb_array_t<const Value>& values) const
+ {
+ unsigned format = *this;
+ unsigned i = 0;
+ if (format & xPlacement) i++;
+ if (format & yPlacement) i++;
+ if (format & xAdvance) i++;
+ if (format & yAdvance) i++;
+ if (format & xPlaDevice)
+ {
+ (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices);
+ i++;
+ }
+
+ if (format & ValueFormat::yPlaDevice)
+ {
+ (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices);
+ i++;
+ }
+
+ if (format & ValueFormat::xAdvDevice)
+ {
+
+ (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices);
+ i++;
+ }
+
+ if (format & ValueFormat::yAdvDevice)
+ {
+
+ (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices);
+ i++;
+ }
+ }
+
+ private:
+ bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const
+ {
+ unsigned int format = *this;
+
+ if (format & xPlacement) values++;
+ if (format & yPlacement) values++;
+ if (format & xAdvance) values++;
+ if (format & yAdvance) values++;
+
+ if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
+ if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
+ if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
+ if ((format & yAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
+
+ return true;
+ }
+
+ static inline Offset16To<Device>& get_device (Value* value)
+ {
+ return *static_cast<Offset16To<Device> *> (value);
+ }
+ static inline const Offset16To<Device>& get_device (const Value* value, bool *worked=nullptr)
+ {
+ if (worked) *worked |= bool (*value);
+ return *static_cast<const Offset16To<Device> *> (value);
+ }
+
+ bool copy_device (hb_serialize_context_t *c, const void *base,
+ const Value *src_value, const hb_map_t *layout_variation_idx_map) const
+ {
+ Value *dst_value = c->copy (*src_value);
+
+ if (!dst_value) return false;
+ if (*dst_value == 0) return true;
+
+ *dst_value = 0;
+ c->push ();
+ if ((base + get_device (src_value)).copy (c, layout_variation_idx_map))
+ {
+ c->add_link (*dst_value, c->pop_pack ());
+ return true;
+ }
+ else
+ {
+ c->pop_discard ();
+ return false;
+ }
+ }
+
+ static inline const HBINT16& get_short (const Value* value, bool *worked=nullptr)
+ {
+ if (worked) *worked |= bool (*value);
+ return *reinterpret_cast<const HBINT16 *> (value);
+ }
+
+ public:
+
+ bool has_device () const
+ {
+ unsigned int format = *this;
+ return (format & devices) != 0;
+ }
+
+ bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
+ }
+
+ bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
+ {
+ TRACE_SANITIZE (this);
+ unsigned int len = get_len ();
+
+ if (!c->check_range (values, count, get_size ())) return_trace (false);
+
+ if (!has_device ()) return_trace (true);
+
+ for (unsigned int i = 0; i < count; i++) {
+ if (!sanitize_value_devices (c, base, values))
+ return_trace (false);
+ values += len;
+ }
+
+ return_trace (true);
+ }
+
+ /* Just sanitize referenced Device tables. Doesn't check the values themselves. */
+ bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const
+ {
+ TRACE_SANITIZE (this);
+
+ if (!has_device ()) return_trace (true);
+
+ for (unsigned int i = 0; i < count; i++) {
+ if (!sanitize_value_devices (c, base, values))
+ return_trace (false);
+ values += stride;
+ }
+
+ return_trace (true);
+ }
+
+ private:
+
+ void should_drop (Value value, Flags flag, unsigned int* format) const
+ {
+ if (value) return;
+ *format = *format & ~flag;
+ }
+
+};
+
+}
+}
+}
+
+#endif // #ifndef OT_LAYOUT_GPOS_VALUEFORMAT_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh
index ad153ce8d7..3f0c4b2ad9 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh
@@ -19,6 +19,8 @@ namespace GSUB {
struct GSUB : GSUBGPOS
{
+ using Lookup = SubstLookup;
+
static constexpr hb_tag_t tableTag = HB_OT_TAG_GSUB;
const SubstLookup& get_lookup (unsigned int i) const
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh
index 3419b5a734..8fb3b55097 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh
@@ -10,7 +10,7 @@ namespace GSUB {
struct SubstLookup : Lookup
{
- typedef SubstLookupSubTable SubTable;
+ using SubTable = SubstLookupSubTable;
bool sanitize (hb_sanitize_context_t *c) const
{ return Lookup::sanitize<SubTable> (c); }
@@ -73,8 +73,6 @@ struct SubstLookup : Lookup
return hb_closure_lookups_context_t::default_return_value ();
}
- c->set_recurse_func (dispatch_closure_lookups_recurse_func);
-
hb_closure_lookups_context_t::return_t ret = dispatch (c);
return ret;
}
@@ -100,8 +98,6 @@ struct SubstLookup : Lookup
return dispatch (c);
}
- static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
-
bool serialize_single (hb_serialize_context_t *c,
uint32_t lookup_props,
hb_sorted_array_t<const HBGlyphID16> glyphs,
@@ -206,8 +202,6 @@ struct SubstLookup : Lookup
return ret;
}
- HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned lookup_index);
-
template <typename context_t, typename ...Ts>
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{ return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
diff --git a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh
new file mode 100644
index 0000000000..c145beaa49
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh
@@ -0,0 +1,258 @@
+#ifndef OT_GLYF_COMPOSITEGLYPH_HH
+#define OT_GLYF_COMPOSITEGLYPH_HH
+
+
+#include "../../hb-open-type.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+struct CompositeGlyphRecord
+{
+ protected:
+ enum composite_glyph_flag_t
+ {
+ ARG_1_AND_2_ARE_WORDS = 0x0001,
+ ARGS_ARE_XY_VALUES = 0x0002,
+ ROUND_XY_TO_GRID = 0x0004,
+ WE_HAVE_A_SCALE = 0x0008,
+ MORE_COMPONENTS = 0x0020,
+ WE_HAVE_AN_X_AND_Y_SCALE = 0x0040,
+ WE_HAVE_A_TWO_BY_TWO = 0x0080,
+ WE_HAVE_INSTRUCTIONS = 0x0100,
+ USE_MY_METRICS = 0x0200,
+ OVERLAP_COMPOUND = 0x0400,
+ SCALED_COMPONENT_OFFSET = 0x0800,
+ UNSCALED_COMPONENT_OFFSET = 0x1000
+ };
+
+ public:
+ unsigned int get_size () const
+ {
+ unsigned int size = min_size;
+ /* arg1 and 2 are int16 */
+ if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
+ /* arg1 and 2 are int8 */
+ else size += 2;
+
+ /* One x 16 bit (scale) */
+ if (flags & WE_HAVE_A_SCALE) size += 2;
+ /* Two x 16 bit (xscale, yscale) */
+ else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
+ /* Four x 16 bit (xscale, scale01, scale10, yscale) */
+ else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
+
+ return size;
+ }
+
+ void drop_instructions_flag () { flags = (uint16_t) flags & ~WE_HAVE_INSTRUCTIONS; }
+ void set_overlaps_flag ()
+ {
+ flags = (uint16_t) flags | OVERLAP_COMPOUND;
+ }
+
+ bool has_instructions () const { return flags & WE_HAVE_INSTRUCTIONS; }
+
+ bool has_more () const { return flags & MORE_COMPONENTS; }
+ bool is_use_my_metrics () const { return flags & USE_MY_METRICS; }
+ bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); }
+ void get_anchor_points (unsigned int &point1, unsigned int &point2) const
+ {
+ const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex);
+ if (flags & ARG_1_AND_2_ARE_WORDS)
+ {
+ point1 = ((const HBUINT16 *) p)[0];
+ point2 = ((const HBUINT16 *) p)[1];
+ }
+ else
+ {
+ point1 = p[0];
+ point2 = p[1];
+ }
+ }
+
+ void transform_points (contour_point_vector_t &points) const
+ {
+ float matrix[4];
+ contour_point_t trans;
+ if (get_transformation (matrix, trans))
+ {
+ if (scaled_offsets ())
+ {
+ points.translate (trans);
+ points.transform (matrix);
+ }
+ else
+ {
+ points.transform (matrix);
+ points.translate (trans);
+ }
+ }
+ }
+
+ protected:
+ bool scaled_offsets () const
+ { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; }
+
+ bool get_transformation (float (&matrix)[4], contour_point_t &trans) const
+ {
+ matrix[0] = matrix[3] = 1.f;
+ matrix[1] = matrix[2] = 0.f;
+
+ int tx, ty;
+ const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex);
+ if (flags & ARG_1_AND_2_ARE_WORDS)
+ {
+ tx = *(const HBINT16 *) p;
+ p += HBINT16::static_size;
+ ty = *(const HBINT16 *) p;
+ p += HBINT16::static_size;
+ }
+ else
+ {
+ tx = *p++;
+ ty = *p++;
+ }
+ if (is_anchored ()) tx = ty = 0;
+
+ trans.init ((float) tx, (float) ty);
+
+ {
+ const F2DOT14 *points = (const F2DOT14 *) p;
+ if (flags & WE_HAVE_A_SCALE)
+ {
+ matrix[0] = matrix[3] = points[0].to_float ();
+ return true;
+ }
+ else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
+ {
+ matrix[0] = points[0].to_float ();
+ matrix[3] = points[1].to_float ();
+ return true;
+ }
+ else if (flags & WE_HAVE_A_TWO_BY_TWO)
+ {
+ matrix[0] = points[0].to_float ();
+ matrix[1] = points[1].to_float ();
+ matrix[2] = points[2].to_float ();
+ matrix[3] = points[3].to_float ();
+ return true;
+ }
+ }
+ return tx || ty;
+ }
+
+ public:
+ HBUINT16 flags;
+ HBGlyphID16 glyphIndex;
+ public:
+ DEFINE_SIZE_MIN (4);
+};
+
+struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphRecord &>
+{
+ typedef const CompositeGlyphRecord *__item_t__;
+ composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
+ glyph (glyph_), current (nullptr), current_size (0)
+ {
+ set_current (current_);
+ }
+
+ composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {}
+
+ item_t __item__ () const { return *current; }
+ bool __more__ () const { return current; }
+ void __next__ ()
+ {
+ if (!current->has_more ()) { current = nullptr; return; }
+
+ set_current (&StructAtOffset<CompositeGlyphRecord> (current, current_size));
+ }
+ composite_iter_t __end__ () const { return composite_iter_t (); }
+ bool operator != (const composite_iter_t& o) const
+ { return current != o.current; }
+
+
+ void set_current (__item_t__ current_)
+ {
+ if (!glyph.check_range (current_, CompositeGlyphRecord::min_size))
+ {
+ current = nullptr;
+ current_size = 0;
+ return;
+ }
+ unsigned size = current_->get_size ();
+ if (!glyph.check_range (current_, size))
+ {
+ current = nullptr;
+ current_size = 0;
+ return;
+ }
+
+ current = current_;
+ current_size = size;
+ }
+
+ private:
+ hb_bytes_t glyph;
+ __item_t__ current;
+ unsigned current_size;
+};
+
+struct CompositeGlyph
+{
+ const GlyphHeader &header;
+ hb_bytes_t bytes;
+ CompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
+ header (header_), bytes (bytes_) {}
+
+ composite_iter_t iter () const
+ { return composite_iter_t (bytes, &StructAfter<CompositeGlyphRecord, GlyphHeader> (header)); }
+
+ unsigned int instructions_length (hb_bytes_t bytes) const
+ {
+ unsigned int start = bytes.length;
+ unsigned int end = bytes.length;
+ const CompositeGlyphRecord *last = nullptr;
+ for (auto &item : iter ())
+ last = &item;
+ if (unlikely (!last)) return 0;
+
+ if (last->has_instructions ())
+ start = (char *) last - &bytes + last->get_size ();
+ if (unlikely (start > end)) return 0;
+ return end - start;
+ }
+
+ /* Trimming for composites not implemented.
+ * If removing hints it falls out of that. */
+ const hb_bytes_t trim_padding () const { return bytes; }
+
+ void drop_hints ()
+ {
+ for (const auto &_ : iter ())
+ const_cast<CompositeGlyphRecord &> (_).drop_instructions_flag ();
+ }
+
+ /* Chop instructions off the end */
+ void drop_hints_bytes (hb_bytes_t &dest_start) const
+ { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); }
+
+ void set_overlaps_flag ()
+ {
+ CompositeGlyphRecord& glyph_chain = const_cast<CompositeGlyphRecord &> (
+ StructAfter<CompositeGlyphRecord, GlyphHeader> (header));
+ if (!bytes.check_range(&glyph_chain, CompositeGlyphRecord::min_size))
+ return;
+ glyph_chain.set_overlaps_flag ();
+ }
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_COMPOSITEGLYPH_HH */
diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh
new file mode 100644
index 0000000000..2199d2c48b
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh
@@ -0,0 +1,233 @@
+#ifndef OT_GLYF_GLYPH_HH
+#define OT_GLYF_GLYPH_HH
+
+
+#include "../../hb-open-type.hh"
+
+#include "GlyphHeader.hh"
+#include "SimpleGlyph.hh"
+#include "CompositeGlyph.hh"
+
+
+namespace OT {
+
+struct glyf_accelerator_t;
+
+namespace glyf_impl {
+
+
+enum phantom_point_index_t
+{
+ PHANTOM_LEFT = 0,
+ PHANTOM_RIGHT = 1,
+ PHANTOM_TOP = 2,
+ PHANTOM_BOTTOM = 3,
+ PHANTOM_COUNT = 4
+};
+
+struct Glyph
+{
+ enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };
+
+ public:
+ composite_iter_t get_composite_iterator () const
+ {
+ if (type != COMPOSITE) return composite_iter_t ();
+ return CompositeGlyph (*header, bytes).iter ();
+ }
+
+ const hb_bytes_t trim_padding () const
+ {
+ switch (type) {
+ case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding ();
+ case SIMPLE: return SimpleGlyph (*header, bytes).trim_padding ();
+ default: return bytes;
+ }
+ }
+
+ void drop_hints ()
+ {
+ switch (type) {
+ case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return;
+ case SIMPLE: SimpleGlyph (*header, bytes).drop_hints (); return;
+ default: return;
+ }
+ }
+
+ void set_overlaps_flag ()
+ {
+ switch (type) {
+ case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return;
+ case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return;
+ default: return;
+ }
+ }
+
+ void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
+ {
+ switch (type) {
+ case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
+ case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
+ default: return;
+ }
+ }
+
+ /* Note: Recursively calls itself.
+ * all_points includes phantom points
+ */
+ template <typename accelerator_t>
+ bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
+ contour_point_vector_t &all_points /* OUT */,
+ bool phantom_only = false,
+ unsigned int depth = 0) const
+ {
+ if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
+ contour_point_vector_t stack_points;
+ bool inplace = type == SIMPLE && all_points.length == 0;
+ /* Load into all_points if it's empty, as an optimization. */
+ contour_point_vector_t &points = inplace ? all_points : stack_points;
+
+ switch (type) {
+ case COMPOSITE:
+ {
+ /* pseudo component points for each component in composite glyph */
+ unsigned num_points = hb_len (CompositeGlyph (*header, bytes).iter ());
+ if (unlikely (!points.resize (num_points))) return false;
+ break;
+ }
+ case SIMPLE:
+ if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
+ return false;
+ break;
+ }
+
+ /* Init phantom points */
+ if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
+ hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
+ {
+ int h_delta = (int) header->xMin -
+ glyf_accelerator.hmtx->get_side_bearing (gid);
+ int v_orig = (int) header->yMax +
+#ifndef HB_NO_VERTICAL
+ glyf_accelerator.vmtx->get_side_bearing (gid)
+#else
+ 0
+#endif
+ ;
+ unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid);
+ unsigned v_adv =
+#ifndef HB_NO_VERTICAL
+ glyf_accelerator.vmtx->get_advance (gid)
+#else
+ - font->face->get_upem ()
+#endif
+ ;
+ phantoms[PHANTOM_LEFT].x = h_delta;
+ phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
+ phantoms[PHANTOM_TOP].y = v_orig;
+ phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
+ }
+
+#ifndef HB_NO_VAR
+ glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ());
+#endif
+
+ switch (type) {
+ case SIMPLE:
+ if (!inplace)
+ all_points.extend (points.as_array ());
+ break;
+ case COMPOSITE:
+ {
+ contour_point_vector_t comp_points;
+ unsigned int comp_index = 0;
+ for (auto &item : get_composite_iterator ())
+ {
+ comp_points.reset ();
+ if (unlikely (!glyf_accelerator.glyph_for_gid (item.glyphIndex)
+ .get_points (font, glyf_accelerator, comp_points,
+ phantom_only, depth + 1)))
+ return false;
+
+ /* Copy phantom points from component if USE_MY_METRICS flag set */
+ if (item.is_use_my_metrics ())
+ for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
+ phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
+
+ /* Apply component transformation & translation */
+ item.transform_points (comp_points);
+
+ /* Apply translation from gvar */
+ comp_points.translate (points[comp_index]);
+
+ if (item.is_anchored ())
+ {
+ unsigned int p1, p2;
+ item.get_anchor_points (p1, p2);
+ if (likely (p1 < all_points.length && p2 < comp_points.length))
+ {
+ contour_point_t delta;
+ delta.init (all_points[p1].x - comp_points[p2].x,
+ all_points[p1].y - comp_points[p2].y);
+
+ comp_points.translate (delta);
+ }
+ }
+
+ all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
+
+ comp_index++;
+ }
+
+ all_points.extend (phantoms);
+ } break;
+ default:
+ all_points.extend (phantoms);
+ }
+
+ if (depth == 0) /* Apply at top level */
+ {
+ /* Undocumented rasterizer behavior:
+ * Shift points horizontally by the updated left side bearing
+ */
+ contour_point_t delta;
+ delta.init (-phantoms[PHANTOM_LEFT].x, 0.f);
+ if (delta.x) all_points.translate (delta);
+ }
+
+ return !all_points.in_error ();
+ }
+
+ bool get_extents (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator,
+ hb_glyph_extents_t *extents) const
+ {
+ if (type == EMPTY) return true; /* Empty glyph; zero extents. */
+ return header->get_extents (font, glyf_accelerator, gid, extents);
+ }
+
+ hb_bytes_t get_bytes () const { return bytes; }
+
+ Glyph (hb_bytes_t bytes_ = hb_bytes_t (),
+ hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_),
+ header (bytes.as<GlyphHeader> ()),
+ gid (gid_)
+ {
+ int num_contours = header->numberOfContours;
+ if (unlikely (num_contours == 0)) type = EMPTY;
+ else if (num_contours > 0) type = SIMPLE;
+ else type = COMPOSITE; /* negative numbers */
+ }
+
+ protected:
+ hb_bytes_t bytes;
+ const GlyphHeader *header;
+ hb_codepoint_t gid;
+ unsigned type;
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_GLYPH_HH */
diff --git a/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh b/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh
new file mode 100644
index 0000000000..792bd5478f
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh
@@ -0,0 +1,48 @@
+#ifndef OT_GLYF_GLYPHHEADER_HH
+#define OT_GLYF_GLYPHHEADER_HH
+
+
+#include "../../hb-open-type.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+struct GlyphHeader
+{
+ bool has_data () const { return numberOfContours; }
+
+ template <typename accelerator_t>
+ bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator,
+ hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+ {
+ /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */
+ /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */
+ extents->x_bearing = font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (gid));
+ extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax));
+ extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax));
+ extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax));
+
+ return true;
+ }
+
+ HBINT16 numberOfContours;
+ /* If the number of contours is
+ * greater than or equal to zero,
+ * this is a simple glyph; if negative,
+ * this is a composite glyph. */
+ FWORD xMin; /* Minimum x for coordinate data. */
+ FWORD yMin; /* Minimum y for coordinate data. */
+ FWORD xMax; /* Maximum x for coordinate data. */
+ FWORD yMax; /* Maximum y for coordinate data. */
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_GLYPHHEADER_HH */
diff --git a/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh
new file mode 100644
index 0000000000..6df978cf13
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh
@@ -0,0 +1,216 @@
+#ifndef OT_GLYF_SIMPLEGLYPH_HH
+#define OT_GLYF_SIMPLEGLYPH_HH
+
+
+#include "../../hb-open-type.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+struct SimpleGlyph
+{
+ enum simple_glyph_flag_t
+ {
+ FLAG_ON_CURVE = 0x01,
+ FLAG_X_SHORT = 0x02,
+ FLAG_Y_SHORT = 0x04,
+ FLAG_REPEAT = 0x08,
+ FLAG_X_SAME = 0x10,
+ FLAG_Y_SAME = 0x20,
+ FLAG_OVERLAP_SIMPLE = 0x40,
+ FLAG_RESERVED2 = 0x80
+ };
+
+ const GlyphHeader &header;
+ hb_bytes_t bytes;
+ SimpleGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
+ header (header_), bytes (bytes_) {}
+
+ unsigned int instruction_len_offset () const
+ { return GlyphHeader::static_size + 2 * header.numberOfContours; }
+
+ unsigned int length (unsigned int instruction_len) const
+ { return instruction_len_offset () + 2 + instruction_len; }
+
+ unsigned int instructions_length () const
+ {
+ unsigned int instruction_length_offset = instruction_len_offset ();
+ if (unlikely (instruction_length_offset + 2 > bytes.length)) return 0;
+
+ const HBUINT16 &instructionLength = StructAtOffset<HBUINT16> (&bytes, instruction_length_offset);
+ /* Out of bounds of the current glyph */
+ if (unlikely (length (instructionLength) > bytes.length)) return 0;
+ return instructionLength;
+ }
+
+ const hb_bytes_t trim_padding () const
+ {
+ /* based on FontTools _g_l_y_f.py::trim */
+ const uint8_t *glyph = (uint8_t*) bytes.arrayZ;
+ const uint8_t *glyph_end = glyph + bytes.length;
+ /* simple glyph w/contours, possibly trimmable */
+ glyph += instruction_len_offset ();
+
+ if (unlikely (glyph + 2 >= glyph_end)) return hb_bytes_t ();
+ unsigned int num_coordinates = StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
+ unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0);
+
+ glyph += 2 + num_instructions;
+
+ unsigned int coord_bytes = 0;
+ unsigned int coords_with_flags = 0;
+ while (glyph < glyph_end)
+ {
+ uint8_t flag = *glyph;
+ glyph++;
+
+ unsigned int repeat = 1;
+ if (flag & FLAG_REPEAT)
+ {
+ if (unlikely (glyph >= glyph_end)) return hb_bytes_t ();
+ repeat = *glyph + 1;
+ glyph++;
+ }
+
+ unsigned int xBytes, yBytes;
+ xBytes = yBytes = 0;
+ if (flag & FLAG_X_SHORT) xBytes = 1;
+ else if ((flag & FLAG_X_SAME) == 0) xBytes = 2;
+
+ if (flag & FLAG_Y_SHORT) yBytes = 1;
+ else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2;
+
+ coord_bytes += (xBytes + yBytes) * repeat;
+ coords_with_flags += repeat;
+ if (coords_with_flags >= num_coordinates) break;
+ }
+
+ if (unlikely (coords_with_flags != num_coordinates)) return hb_bytes_t ();
+ return bytes.sub_array (0, bytes.length + coord_bytes - (glyph_end - glyph));
+ }
+
+ /* zero instruction length */
+ void drop_hints ()
+ {
+ GlyphHeader &glyph_header = const_cast<GlyphHeader &> (header);
+ (HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0;
+ }
+
+ void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
+ {
+ unsigned int instructions_len = instructions_length ();
+ unsigned int glyph_length = length (instructions_len);
+ dest_start = bytes.sub_array (0, glyph_length - instructions_len);
+ dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length);
+ }
+
+ void set_overlaps_flag ()
+ {
+ if (unlikely (!header.numberOfContours)) return;
+
+ unsigned flags_offset = length (instructions_length ());
+ 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;
+ }
+
+ static bool read_flags (const HBUINT8 *&p /* IN/OUT */,
+ contour_point_vector_t &points_ /* IN/OUT */,
+ const HBUINT8 *end)
+ {
+ unsigned count = points_.length;
+ for (unsigned int i = 0; i < count;)
+ {
+ if (unlikely (p + 1 > end)) return false;
+ uint8_t flag = *p++;
+ points_.arrayZ[i++].flag = flag;
+ if (flag & FLAG_REPEAT)
+ {
+ if (unlikely (p + 1 > end)) return false;
+ unsigned int repeat_count = *p++;
+ unsigned stop = hb_min (i + repeat_count, count);
+ for (; i < stop;)
+ points_.arrayZ[i++].flag = flag;
+ }
+ }
+ return true;
+ }
+
+ static bool read_points (const HBUINT8 *&p /* IN/OUT */,
+ contour_point_vector_t &points_ /* IN/OUT */,
+ const HBUINT8 *end,
+ float contour_point_t::*m,
+ const simple_glyph_flag_t short_flag,
+ const simple_glyph_flag_t same_flag)
+ {
+ int v = 0;
+
+ unsigned count = points_.length;
+ for (unsigned i = 0; i < count; i++)
+ {
+ unsigned flag = points_[i].flag;
+ if (flag & short_flag)
+ {
+ if (unlikely (p + 1 > end)) return false;
+ if (flag & same_flag)
+ v += *p++;
+ else
+ v -= *p++;
+ }
+ else
+ {
+ if (!(flag & same_flag))
+ {
+ if (unlikely (p + HBINT16::static_size > end)) return false;
+ v += *(const HBINT16 *) p;
+ p += HBINT16::static_size;
+ }
+ }
+ points_.arrayZ[i].*m = v;
+ }
+ return true;
+ }
+
+ bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+ bool phantom_only = false) const
+ {
+ const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
+ int num_contours = header.numberOfContours;
+ assert (num_contours);
+ /* One extra item at the end, for the instruction-count below. */
+ if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours]))) return false;
+ unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
+
+ points_.alloc (num_points + 4); // Allocate for phantom points, to avoid a possible copy
+ if (!points_.resize (num_points)) return false;
+ if (phantom_only) return true;
+
+ for (int i = 0; i < num_contours; i++)
+ points_[endPtsOfContours[i]].is_end_point = true;
+
+ /* Skip instructions */
+ const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1],
+ endPtsOfContours[num_contours]);
+
+ if (unlikely ((const char *) p < bytes.arrayZ)) return false; /* Unlikely overflow */
+ const HBUINT8 *end = (const HBUINT8 *) (bytes.arrayZ + bytes.length);
+ if (unlikely (p >= end)) return false;
+
+ /* Read x & y coordinates */
+ return read_flags (p, points_, end)
+ && read_points (p, points_, end, &contour_point_t::x,
+ FLAG_X_SHORT, FLAG_X_SAME)
+ && read_points (p, points_, end, &contour_point_t::y,
+ FLAG_Y_SHORT, FLAG_Y_SAME);
+ }
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_SIMPLEGLYPH_HH */
diff --git a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh
new file mode 100644
index 0000000000..ebe4372047
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh
@@ -0,0 +1,72 @@
+#ifndef OT_GLYF_SUBSETGLYPH_HH
+#define OT_GLYF_SUBSETGLYPH_HH
+
+
+#include "../../hb-open-type.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+struct SubsetGlyph
+{
+ hb_codepoint_t new_gid;
+ hb_codepoint_t old_gid;
+ Glyph source_glyph;
+ hb_bytes_t dest_start; /* region of source_glyph to copy first */
+ hb_bytes_t dest_end; /* region of source_glyph to copy second */
+
+ bool serialize (hb_serialize_context_t *c,
+ bool use_short_loca,
+ const hb_subset_plan_t *plan) const
+ {
+ TRACE_SERIALIZE (this);
+
+ hb_bytes_t dest_glyph = dest_start.copy (c);
+ dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
+ unsigned int pad_length = use_short_loca ? padding () : 0;
+ DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
+
+ HBUINT8 pad;
+ pad = 0;
+ while (pad_length > 0)
+ {
+ c->embed (pad);
+ pad_length--;
+ }
+
+ if (unlikely (!dest_glyph.length)) return_trace (true);
+
+ /* update components gids */
+ for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
+ {
+ hb_codepoint_t new_gid;
+ if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid))
+ const_cast<CompositeGlyphRecord &> (_).glyphIndex = new_gid;
+ }
+
+ if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+ Glyph (dest_glyph).drop_hints ();
+
+ if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG)
+ Glyph (dest_glyph).set_overlaps_flag ();
+
+ return_trace (true);
+ }
+
+ void drop_hints_bytes ()
+ { source_glyph.drop_hints_bytes (dest_start, dest_end); }
+
+ unsigned int length () const { return dest_start.length + dest_end.length; }
+ /* pad to 2 to ensure 2-byte loca will be ok */
+ unsigned int padding () const { return length () % 2; }
+ unsigned int padded_size () const { return length () + padding (); }
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_SUBSETGLYPH_HH */
diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf-helpers.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf-helpers.hh
new file mode 100644
index 0000000000..f51f7a81fc
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/glyf/glyf-helpers.hh
@@ -0,0 +1,90 @@
+#ifndef OT_GLYF_GLYF_HELPERS_HH
+#define OT_GLYF_GLYF_HELPERS_HH
+
+
+#include "../../hb-open-type.hh"
+#include "../../hb-subset-plan.hh"
+
+#include "loca.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+template<typename IteratorIn, typename IteratorOut,
+ hb_requires (hb_is_source_of (IteratorIn, unsigned int)),
+ hb_requires (hb_is_sink_of (IteratorOut, unsigned))>
+static void
+_write_loca (IteratorIn it, bool short_offsets, IteratorOut dest)
+{
+ unsigned right_shift = short_offsets ? 1 : 0;
+ unsigned int offset = 0;
+ dest << 0;
+ + it
+ | hb_map ([=, &offset] (unsigned int padded_size)
+ {
+ offset += padded_size;
+ DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset);
+ return offset >> right_shift;
+ })
+ | hb_sink (dest)
+ ;
+}
+
+static bool
+_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
+{
+ hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source);
+ hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
+ hb_blob_destroy (head_blob);
+
+ if (unlikely (!head_prime_blob))
+ return false;
+
+ head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
+ head_prime->indexToLocFormat = use_short_loca ? 0 : 1;
+ bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
+
+ hb_blob_destroy (head_prime_blob);
+ return success;
+}
+
+template<typename Iterator,
+ hb_requires (hb_is_source_of (Iterator, unsigned int))>
+static bool
+_add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca)
+{
+ unsigned num_offsets = padded_offsets.len () + 1;
+ unsigned entry_size = use_short_loca ? 2 : 4;
+ char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets);
+
+ if (unlikely (!loca_prime_data)) return false;
+
+ DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d",
+ entry_size, num_offsets, entry_size * num_offsets);
+
+ if (use_short_loca)
+ _write_loca (padded_offsets, true, hb_array ((HBUINT16 *) loca_prime_data, num_offsets));
+ else
+ _write_loca (padded_offsets, false, hb_array ((HBUINT32 *) loca_prime_data, num_offsets));
+
+ hb_blob_t *loca_blob = hb_blob_create (loca_prime_data,
+ entry_size * num_offsets,
+ HB_MEMORY_MODE_WRITABLE,
+ loca_prime_data,
+ hb_free);
+
+ bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
+ && _add_head_and_set_loca_version (plan, use_short_loca);
+
+ hb_blob_destroy (loca_blob);
+ return result;
+}
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_GLYF_HELPERS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh
new file mode 100644
index 0000000000..f74513cb96
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh
@@ -0,0 +1,388 @@
+#ifndef OT_GLYF_GLYF_HH
+#define OT_GLYF_GLYF_HH
+
+
+#include "../../hb-open-type.hh"
+#include "../../hb-ot-head-table.hh"
+#include "../../hb-ot-hmtx-table.hh"
+#include "../../hb-ot-var-gvar-table.hh"
+#include "../../hb-draw.hh"
+
+#include "glyf-helpers.hh"
+#include "Glyph.hh"
+#include "SubsetGlyph.hh"
+#include "loca.hh"
+#include "path-builder.hh"
+
+
+namespace OT {
+
+
+/*
+ * glyf -- TrueType Glyph Data
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf
+ */
+#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
+
+
+struct glyf
+{
+ friend struct glyf_accelerator_t;
+
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf;
+
+ bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
+ {
+ TRACE_SANITIZE (this);
+ /* Runtime checks as eager sanitizing each glyph is costy */
+ return_trace (true);
+ }
+
+ /* requires source of SubsetGlyph complains the identifier isn't declared */
+ template <typename Iterator>
+ bool serialize (hb_serialize_context_t *c,
+ Iterator it,
+ bool use_short_loca,
+ const hb_subset_plan_t *plan)
+ {
+ TRACE_SERIALIZE (this);
+ unsigned init_len = c->length ();
+ for (const auto &_ : it) _.serialize (c, use_short_loca, plan);
+
+ /* As a special case when all glyph in the font are empty, add a zero byte
+ * to the table, so that OTS doesn’t reject it, and to make the table work
+ * on Windows as well.
+ * See https://github.com/khaledhosny/ots/issues/52 */
+ if (init_len == c->length ())
+ {
+ HBUINT8 empty_byte;
+ empty_byte = 0;
+ c->copy (empty_byte);
+ }
+ return_trace (true);
+ }
+
+ /* Byte region(s) per glyph to output
+ unpadded, hints removed if so requested
+ If we fail to process a glyph we produce an empty (0-length) glyph */
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+
+ glyf *glyf_prime = c->serializer->start_embed <glyf> ();
+ if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
+
+ hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
+ _populate_subset_glyphs (c->plan, &glyphs);
+
+ auto padded_offsets =
+ + hb_iter (glyphs)
+ | hb_map (&glyf_impl::SubsetGlyph::padded_size)
+ ;
+
+ unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
+ bool use_short_loca = max_offset < 0x1FFFF;
+
+
+ glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan);
+ if (!use_short_loca) {
+ padded_offsets =
+ + hb_iter (glyphs)
+ | hb_map (&glyf_impl::SubsetGlyph::length)
+ ;
+ }
+
+
+ if (unlikely (c->serializer->in_error ())) return_trace (false);
+ return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan,
+ padded_offsets,
+ use_short_loca)));
+ }
+
+ void
+ _populate_subset_glyphs (const hb_subset_plan_t *plan,
+ hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
+
+ protected:
+ UnsizedArrayOf<HBUINT8>
+ dataZ; /* Glyphs data. */
+ public:
+ DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
+ * check the size externally, allow Null() object of it by
+ * defining it _MIN instead. */
+};
+
+struct glyf_accelerator_t
+{
+ glyf_accelerator_t (hb_face_t *face)
+ {
+ short_offset = false;
+ num_glyphs = 0;
+ loca_table = nullptr;
+ glyf_table = nullptr;
+#ifndef HB_NO_VAR
+ gvar = nullptr;
+#endif
+ hmtx = nullptr;
+#ifndef HB_NO_VERTICAL
+ vmtx = nullptr;
+#endif
+ const OT::head &head = *face->table.head;
+ if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
+ /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
+ return;
+ short_offset = 0 == head.indexToLocFormat;
+
+ loca_table = face->table.loca.get_blob (); // Needs no destruct!
+ glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
+#ifndef HB_NO_VAR
+ gvar = face->table.gvar;
+#endif
+ hmtx = face->table.hmtx;
+#ifndef HB_NO_VERTICAL
+ vmtx = face->table.vmtx;
+#endif
+
+ num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
+ num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ());
+ }
+ ~glyf_accelerator_t ()
+ {
+ glyf_table.destroy ();
+ }
+
+ bool has_data () const { return num_glyphs; }
+
+ protected:
+ template<typename T>
+ bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) const
+ {
+ if (gid >= num_glyphs) return false;
+
+ /* Making this allocfree is not that easy
+ https://github.com/harfbuzz/harfbuzz/issues/2095
+ mostly because of gvar handling in VF fonts,
+ perhaps a separate path for non-VF fonts can be considered */
+ contour_point_vector_t all_points;
+
+ bool phantom_only = !consumer.is_consuming_contour_points ();
+ if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, phantom_only)))
+ return false;
+
+ if (consumer.is_consuming_contour_points ())
+ {
+ unsigned count = all_points.length;
+ assert (count >= glyf_impl::PHANTOM_COUNT);
+ count -= glyf_impl::PHANTOM_COUNT;
+ for (unsigned point_index = 0; point_index < count; point_index++)
+ consumer.consume_point (all_points[point_index]);
+ consumer.points_end ();
+ }
+
+ /* Where to write phantoms, nullptr if not requested */
+ contour_point_t *phantoms = consumer.get_phantoms_sink ();
+ if (phantoms)
+ for (unsigned i = 0; i < glyf_impl::PHANTOM_COUNT; ++i)
+ phantoms[i] = all_points[all_points.length - glyf_impl::PHANTOM_COUNT + i];
+
+ return true;
+ }
+
+#ifndef HB_NO_VAR
+ struct points_aggregator_t
+ {
+ hb_font_t *font;
+ hb_glyph_extents_t *extents;
+ contour_point_t *phantoms;
+
+ struct contour_bounds_t
+ {
+ contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; }
+
+ void add (const contour_point_t &p)
+ {
+ min_x = hb_min (min_x, p.x);
+ min_y = hb_min (min_y, p.y);
+ max_x = hb_max (max_x, p.x);
+ max_y = hb_max (max_y, p.y);
+ }
+
+ bool empty () const { return (min_x >= max_x) || (min_y >= max_y); }
+
+ void get_extents (hb_font_t *font, hb_glyph_extents_t *extents)
+ {
+ if (unlikely (empty ()))
+ {
+ extents->width = 0;
+ extents->x_bearing = 0;
+ extents->height = 0;
+ extents->y_bearing = 0;
+ return;
+ }
+ extents->x_bearing = font->em_scalef_x (min_x);
+ extents->width = font->em_scalef_x (max_x) - extents->x_bearing;
+ extents->y_bearing = font->em_scalef_y (max_y);
+ extents->height = font->em_scalef_y (min_y) - extents->y_bearing;
+ }
+
+ protected:
+ float min_x, min_y, max_x, max_y;
+ } bounds;
+
+ points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_)
+ {
+ font = font_;
+ extents = extents_;
+ phantoms = phantoms_;
+ if (extents) bounds = contour_bounds_t ();
+ }
+
+ void consume_point (const contour_point_t &point) { bounds.add (point); }
+ void points_end () { bounds.get_extents (font, extents); }
+
+ bool is_consuming_contour_points () { return extents; }
+ contour_point_t *get_phantoms_sink () { return phantoms; }
+ };
+
+ public:
+ unsigned
+ get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
+ {
+ if (unlikely (gid >= num_glyphs)) return 0;
+
+ bool success = false;
+
+ contour_point_t phantoms[glyf_impl::PHANTOM_COUNT];
+ if (likely (font->num_coords == gvar->get_axis_count ()))
+ success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms));
+
+ if (unlikely (!success))
+ return
+#ifndef HB_NO_VERTICAL
+ is_vertical ? vmtx->get_advance (gid) :
+#endif
+ hmtx->get_advance (gid);
+
+ float result = is_vertical
+ ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y
+ : phantoms[glyf_impl::PHANTOM_RIGHT].x - phantoms[glyf_impl::PHANTOM_LEFT].x;
+ return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2);
+ }
+
+ int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
+ {
+ if (unlikely (gid >= num_glyphs)) return 0;
+
+ hb_glyph_extents_t extents;
+
+ contour_point_t phantoms[glyf_impl::PHANTOM_COUNT];
+ if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms))))
+ return
+#ifndef HB_NO_VERTICAL
+ is_vertical ? vmtx->get_side_bearing (gid) :
+#endif
+ hmtx->get_side_bearing (gid);
+
+ return is_vertical
+ ? ceilf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing
+ : floorf (phantoms[glyf_impl::PHANTOM_LEFT].x);
+ }
+#endif
+
+ public:
+ bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+ {
+ if (unlikely (gid >= num_glyphs)) return false;
+
+#ifndef HB_NO_VAR
+ if (font->num_coords)
+ return get_points (font, gid, points_aggregator_t (font, extents, nullptr));
+#endif
+ return glyph_for_gid (gid).get_extents (font, *this, extents);
+ }
+
+ const glyf_impl::Glyph
+ glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const
+ {
+ if (unlikely (gid >= num_glyphs)) return glyf_impl::Glyph ();
+
+ unsigned int start_offset, end_offset;
+
+ if (short_offset)
+ {
+ const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
+ start_offset = 2 * offsets[gid];
+ end_offset = 2 * offsets[gid + 1];
+ }
+ else
+ {
+ const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
+ start_offset = offsets[gid];
+ end_offset = offsets[gid + 1];
+ }
+
+ if (unlikely (start_offset > end_offset || end_offset > glyf_table.get_length ()))
+ return glyf_impl::Glyph ();
+
+ glyf_impl::Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset,
+ end_offset - start_offset), gid);
+ return needs_padding_removal ? glyf_impl::Glyph (glyph.trim_padding (), gid) : glyph;
+ }
+
+ bool
+ get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
+ { return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session)); }
+
+#ifndef HB_NO_VAR
+ const gvar_accelerator_t *gvar;
+#endif
+ const hmtx_accelerator_t *hmtx;
+#ifndef HB_NO_VERTICAL
+ const vmtx_accelerator_t *vmtx;
+#endif
+
+ private:
+ bool short_offset;
+ unsigned int num_glyphs;
+ hb_blob_ptr_t<loca> loca_table;
+ hb_blob_ptr_t<glyf> glyf_table;
+};
+
+
+inline void
+glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
+ hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
+{
+ OT::glyf_accelerator_t glyf (plan->source);
+
+ + hb_range (plan->num_output_glyphs ())
+ | hb_map ([&] (hb_codepoint_t new_gid)
+ {
+ glyf_impl::SubsetGlyph subset_glyph = {0};
+ subset_glyph.new_gid = new_gid;
+
+ /* should never fail: all old gids should be mapped */
+ if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid))
+ return subset_glyph;
+
+ if (new_gid == 0 &&
+ !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+ subset_glyph.source_glyph = glyf_impl::Glyph ();
+ else
+ subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
+ if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+ subset_glyph.drop_hints_bytes ();
+ else
+ subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
+ return subset_glyph;
+ })
+ | hb_sink (glyphs)
+ ;
+}
+
+
+
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_GLYF_HH */
diff --git a/thirdparty/harfbuzz/src/OT/glyf/loca.hh b/thirdparty/harfbuzz/src/OT/glyf/loca.hh
new file mode 100644
index 0000000000..4481cba8ed
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/glyf/loca.hh
@@ -0,0 +1,43 @@
+#ifndef OT_GLYF_LOCA_HH
+#define OT_GLYF_LOCA_HH
+
+
+#include "../../hb-open-type.hh"
+
+
+namespace OT {
+
+
+/*
+ * loca -- Index to Location
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/loca
+ */
+#define HB_OT_TAG_loca HB_TAG('l','o','c','a')
+
+struct loca
+{
+ friend struct glyf;
+ friend struct glyf_accelerator_t;
+
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_loca;
+
+ bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (true);
+ }
+
+ protected:
+ UnsizedArrayOf<HBUINT8>
+ dataZ; /* Location data. */
+ public:
+ DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
+ * check the size externally, allow Null() object of it by
+ * defining it _MIN instead. */
+};
+
+
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_LOCA_HH */
diff --git a/thirdparty/harfbuzz/src/OT/glyf/path-builder.hh b/thirdparty/harfbuzz/src/OT/glyf/path-builder.hh
new file mode 100644
index 0000000000..9bfc45a1a6
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/glyf/path-builder.hh
@@ -0,0 +1,135 @@
+#ifndef OT_GLYF_PATH_BUILDER_HH
+#define OT_GLYF_PATH_BUILDER_HH
+
+
+#include "../../hb.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+struct path_builder_t
+{
+ hb_font_t *font;
+ hb_draw_session_t *draw_session;
+
+ struct optional_point_t
+ {
+ optional_point_t () {}
+ optional_point_t (float x_, float y_) : has_data (true), x (x_), y (y_) {}
+ operator bool () const { return has_data; }
+
+ bool has_data = false;
+ float x = 0.;
+ float y = 0.;
+
+ optional_point_t lerp (optional_point_t p, float t)
+ { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
+ } first_oncurve, first_offcurve, last_offcurve;
+
+ path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
+ {
+ font = font_;
+ draw_session = &draw_session_;
+ first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
+ }
+
+ /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
+ See also:
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
+ * https://stackoverflow.com/a/20772557 */
+ void consume_point (const contour_point_t &point)
+ {
+ bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
+ optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
+ if (!first_oncurve)
+ {
+ if (is_on_curve)
+ {
+ first_oncurve = p;
+ draw_session->move_to (p.x, p.y);
+ }
+ else
+ {
+ if (first_offcurve)
+ {
+ optional_point_t mid = first_offcurve.lerp (p, .5f);
+ first_oncurve = mid;
+ last_offcurve = p;
+ draw_session->move_to (mid.x, mid.y);
+ }
+ else
+ first_offcurve = p;
+ }
+ }
+ else
+ {
+ if (last_offcurve)
+ {
+ if (is_on_curve)
+ {
+ draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
+ p.x, p.y);
+ last_offcurve = optional_point_t ();
+ }
+ else
+ {
+ optional_point_t mid = last_offcurve.lerp (p, .5f);
+ draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
+ mid.x, mid.y);
+ last_offcurve = p;
+ }
+ }
+ else
+ {
+ if (is_on_curve)
+ draw_session->line_to (p.x, p.y);
+ else
+ last_offcurve = p;
+ }
+ }
+
+ if (point.is_end_point)
+ {
+ if (first_offcurve && last_offcurve)
+ {
+ optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
+ draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
+ mid.x, mid.y);
+ last_offcurve = optional_point_t ();
+ /* now check the rest */
+ }
+
+ if (first_offcurve && first_oncurve)
+ draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
+ first_oncurve.x, first_oncurve.y);
+ else if (last_offcurve && first_oncurve)
+ draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
+ first_oncurve.x, first_oncurve.y);
+ else if (first_oncurve)
+ draw_session->line_to (first_oncurve.x, first_oncurve.y);
+ else if (first_offcurve)
+ {
+ float x = first_offcurve.x, y = first_offcurve.y;
+ draw_session->move_to (x, y);
+ draw_session->quadratic_to (x, y, x, y);
+ }
+
+ /* Getting ready for the next contour */
+ first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
+ draw_session->close_path ();
+ }
+ }
+ void points_end () {}
+
+ bool is_consuming_contour_points () { return true; }
+ contour_point_t *get_phantoms_sink () { return nullptr; }
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_PATH_BUILDER_HH */
diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh
new file mode 100644
index 0000000000..52ca9dd142
--- /dev/null
+++ b/thirdparty/harfbuzz/src/graph/graph.hh
@@ -0,0 +1,860 @@
+/*
+ * Copyright © 2022 Google, Inc.
+ *
+ * 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): Garret Rieger
+ */
+
+#ifndef GRAPH_GRAPH_HH
+#define GRAPH_GRAPH_HH
+
+namespace graph {
+
+/**
+ * Represents a serialized table in the form of a graph.
+ * Provides methods for modifying and reordering the graph.
+ */
+struct graph_t
+{
+ struct vertex_t
+ {
+ hb_serialize_context_t::object_t obj;
+ int64_t distance = 0 ;
+ int64_t space = 0 ;
+ hb_vector_t<unsigned> parents;
+ unsigned start = 0;
+ unsigned end = 0;
+ unsigned priority = 0;
+
+ friend void swap (vertex_t& a, vertex_t& b)
+ {
+ hb_swap (a.obj, b.obj);
+ hb_swap (a.distance, b.distance);
+ hb_swap (a.space, b.space);
+ hb_swap (a.parents, b.parents);
+ hb_swap (a.start, b.start);
+ hb_swap (a.end, b.end);
+ hb_swap (a.priority, b.priority);
+ }
+
+ bool is_shared () const
+ {
+ return parents.length > 1;
+ }
+
+ unsigned incoming_edges () const
+ {
+ return parents.length;
+ }
+
+ void remove_parent (unsigned parent_index)
+ {
+ for (unsigned i = 0; i < parents.length; i++)
+ {
+ if (parents[i] != parent_index) continue;
+ parents.remove (i);
+ break;
+ }
+ }
+
+ void remap_parents (const hb_vector_t<unsigned>& id_map)
+ {
+ for (unsigned i = 0; i < parents.length; i++)
+ parents[i] = id_map[parents[i]];
+ }
+
+ void remap_parent (unsigned old_index, unsigned new_index)
+ {
+ for (unsigned i = 0; i < parents.length; i++)
+ {
+ if (parents[i] == old_index)
+ parents[i] = new_index;
+ }
+ }
+
+ bool is_leaf () const
+ {
+ return !obj.real_links.length && !obj.virtual_links.length;
+ }
+
+ bool raise_priority ()
+ {
+ if (has_max_priority ()) return false;
+ priority++;
+ return true;
+ }
+
+ bool has_max_priority () const {
+ return priority >= 3;
+ }
+
+ int64_t modified_distance (unsigned order) const
+ {
+ // TODO(garretrieger): once priority is high enough, should try
+ // setting distance = 0 which will force to sort immediately after
+ // it's parent where possible.
+
+ int64_t modified_distance =
+ hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF);
+ if (has_max_priority ()) {
+ modified_distance = 0;
+ }
+ return (modified_distance << 18) | (0x003FFFF & order);
+ }
+
+ int64_t distance_modifier () const
+ {
+ if (!priority) return 0;
+ int64_t table_size = obj.tail - obj.head;
+
+ if (priority == 1)
+ return -table_size / 2;
+
+ return -table_size;
+ }
+ };
+
+ /*
+ * A topological sorting of an object graph. Ordered
+ * in reverse serialization order (first object in the
+ * serialization is at the end of the list). This matches
+ * the 'packed' object stack used internally in the
+ * serializer
+ */
+ template<typename T>
+ graph_t (const T& objects)
+ : parents_invalid (true),
+ distance_invalid (true),
+ positions_invalid (true),
+ successful (true)
+ {
+ num_roots_for_space_.push (1);
+ bool removed_nil = false;
+ vertices_.alloc (objects.length);
+ vertices_scratch_.alloc (objects.length);
+ for (unsigned i = 0; i < objects.length; i++)
+ {
+ // TODO(grieger): check all links point to valid objects.
+
+ // If this graph came from a serialization buffer object 0 is the
+ // nil object. We don't need it for our purposes here so drop it.
+ if (i == 0 && !objects[i])
+ {
+ removed_nil = true;
+ continue;
+ }
+
+ vertex_t* v = vertices_.push ();
+ if (check_success (!vertices_.in_error ()))
+ v->obj = *objects[i];
+ if (!removed_nil) continue;
+ // Fix indices to account for removed nil object.
+ for (auto& l : v->obj.all_links_writer ()) {
+ l.objidx--;
+ }
+ }
+ }
+
+ ~graph_t ()
+ {
+ vertices_.fini ();
+ }
+
+ bool in_error () const
+ {
+ return !successful ||
+ vertices_.in_error () ||
+ num_roots_for_space_.in_error ();
+ }
+
+ const vertex_t& root () const
+ {
+ return vertices_[root_idx ()];
+ }
+
+ unsigned root_idx () const
+ {
+ // Object graphs are in reverse order, the first object is at the end
+ // of the vector. Since the graph is topologically sorted it's safe to
+ // assume the first object has no incoming edges.
+ return vertices_.length - 1;
+ }
+
+ const hb_serialize_context_t::object_t& object(unsigned i) const
+ {
+ return vertices_[i].obj;
+ }
+
+ /*
+ * Generates a new topological sorting of graph ordered by the shortest
+ * distance to each node.
+ */
+ void sort_shortest_distance ()
+ {
+ positions_invalid = true;
+
+ if (vertices_.length <= 1) {
+ // Graph of 1 or less doesn't need sorting.
+ return;
+ }
+
+ update_distances ();
+
+ hb_priority_queue_t queue;
+ hb_vector_t<vertex_t> &sorted_graph = vertices_scratch_;
+ if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
+ hb_vector_t<unsigned> id_map;
+ if (unlikely (!check_success (id_map.resize (vertices_.length)))) return;
+
+ hb_vector_t<unsigned> removed_edges;
+ if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return;
+ update_parents ();
+
+ queue.insert (root ().modified_distance (0), root_idx ());
+ int new_id = root_idx ();
+ unsigned order = 1;
+ while (!queue.in_error () && !queue.is_empty ())
+ {
+ unsigned next_id = queue.pop_minimum().second;
+
+ hb_swap (sorted_graph[new_id], vertices_[next_id]);
+ const vertex_t& next = sorted_graph[new_id];
+
+ id_map[next_id] = new_id--;
+
+ for (const auto& link : next.obj.all_links ()) {
+ removed_edges[link.objidx]++;
+ if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx]))
+ // Add the order that the links were encountered to the priority.
+ // This ensures that ties between priorities objects are broken in a consistent
+ // way. More specifically this is set up so that if a set of objects have the same
+ // distance they'll be added to the topological order in the order that they are
+ // referenced from the parent object.
+ queue.insert (vertices_[link.objidx].modified_distance (order++),
+ link.objidx);
+ }
+ }
+
+ check_success (!queue.in_error ());
+ check_success (!sorted_graph.in_error ());
+ if (!check_success (new_id == -1))
+ print_orphaned_nodes ();
+
+ remap_all_obj_indices (id_map, &sorted_graph);
+
+ hb_swap (vertices_, sorted_graph);
+ }
+
+ /*
+ * Assign unique space numbers to each connected subgraph of 32 bit offset(s).
+ */
+ bool assign_32bit_spaces ()
+ {
+ unsigned root_index = root_idx ();
+ hb_set_t visited;
+ hb_set_t roots;
+ for (unsigned i = 0; i <= root_index; i++)
+ {
+ // Only real links can form 32 bit spaces
+ for (auto& l : vertices_[i].obj.real_links)
+ {
+ if (l.width == 4 && !l.is_signed)
+ {
+ roots.add (l.objidx);
+ find_subgraph (l.objidx, visited);
+ }
+ }
+ }
+
+ // Mark everything not in the subgraphs of 32 bit roots as visited.
+ // This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs.
+ visited.invert ();
+
+ if (!roots) return false;
+
+ 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);
+ for (unsigned root : connected_roots)
+ {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Subgraph %u gets space %u", root, next_space);
+ vertices_[root].space = next_space;
+ num_roots_for_space_[next_space] = num_roots_for_space_[next_space] + 1;
+ distance_invalid = true;
+ positions_invalid = true;
+ }
+
+ // TODO(grieger): special case for GSUB/GPOS use extension promotions to move 16 bit space
+ // into the 32 bit space as needed, instead of using isolation.
+ }
+
+
+
+ return true;
+ }
+
+ /*
+ * Isolates the subgraph of nodes reachable from root. Any links to nodes in the subgraph
+ * that originate from outside of the subgraph will be removed by duplicating the linked to
+ * object.
+ *
+ * Indices stored in roots will be updated if any of the roots are duplicated to new indices.
+ */
+ bool isolate_subgraph (hb_set_t& roots)
+ {
+ update_parents ();
+ hb_map_t subgraph;
+
+ // incoming edges to root_idx should be all 32 bit in length so we don't need to de-dup these
+ // set the subgraph incoming edge count to match all of root_idx's incoming edges
+ hb_set_t parents;
+ for (unsigned root_idx : roots)
+ {
+ subgraph.set (root_idx, wide_parents (root_idx, parents));
+ find_subgraph (root_idx, subgraph);
+ }
+
+ unsigned original_root_idx = root_idx ();
+ hb_map_t index_map;
+ bool made_changes = false;
+ for (auto entry : subgraph.iter ())
+ {
+ const auto& node = vertices_[entry.first];
+ unsigned subgraph_incoming_edges = entry.second;
+
+ if (subgraph_incoming_edges < node.incoming_edges ())
+ {
+ // Only de-dup objects with incoming links from outside the subgraph.
+ made_changes = true;
+ duplicate_subgraph (entry.first, index_map);
+ }
+ }
+
+ if (!made_changes)
+ return false;
+
+ if (original_root_idx != root_idx ()
+ && parents.has (original_root_idx))
+ {
+ // If the root idx has changed since parents was determined, update root idx in parents
+ parents.add (root_idx ());
+ parents.del (original_root_idx);
+ }
+
+ auto new_subgraph =
+ + subgraph.keys ()
+ | hb_map([&] (unsigned node_idx) {
+ const unsigned *v;
+ if (index_map.has (node_idx, &v)) return *v;
+ return node_idx;
+ })
+ ;
+
+ remap_obj_indices (index_map, new_subgraph);
+ remap_obj_indices (index_map, parents.iter (), true);
+
+ // Update roots set with new indices as needed.
+ unsigned next = HB_SET_VALUE_INVALID;
+ while (roots.next (&next))
+ {
+ const unsigned *v;
+ if (index_map.has (next, &v))
+ {
+ roots.del (next);
+ roots.add (*v);
+ }
+ }
+
+ return true;
+ }
+
+ void find_subgraph (unsigned node_idx, hb_map_t& subgraph)
+ {
+ for (const auto& link : vertices_[node_idx].obj.all_links ())
+ {
+ const unsigned *v;
+ if (subgraph.has (link.objidx, &v))
+ {
+ subgraph.set (link.objidx, *v + 1);
+ continue;
+ }
+ subgraph.set (link.objidx, 1);
+ find_subgraph (link.objidx, subgraph);
+ }
+ }
+
+ void find_subgraph (unsigned node_idx, hb_set_t& subgraph)
+ {
+ if (subgraph.has (node_idx)) return;
+ subgraph.add (node_idx);
+ for (const auto& link : vertices_[node_idx].obj.all_links ())
+ find_subgraph (link.objidx, subgraph);
+ }
+
+ /*
+ * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign
+ * links. index_map is updated with mappings from old id to new id. If a duplication has already
+ * been performed for a given index, then it will be skipped.
+ */
+ void duplicate_subgraph (unsigned node_idx, hb_map_t& index_map)
+ {
+ if (index_map.has (node_idx))
+ return;
+
+ index_map.set (node_idx, duplicate (node_idx));
+ for (const auto& l : object (node_idx).all_links ()) {
+ duplicate_subgraph (l.objidx, index_map);
+ }
+ }
+
+ /*
+ * Creates a copy of node_idx and returns it's new index.
+ */
+ unsigned duplicate (unsigned node_idx)
+ {
+ positions_invalid = true;
+ distance_invalid = true;
+
+ auto* clone = vertices_.push ();
+ auto& child = vertices_[node_idx];
+ if (vertices_.in_error ()) {
+ return -1;
+ }
+
+ clone->obj.head = child.obj.head;
+ clone->obj.tail = child.obj.tail;
+ clone->distance = child.distance;
+ clone->space = child.space;
+ clone->parents.reset ();
+
+ unsigned clone_idx = vertices_.length - 2;
+ for (const auto& l : child.obj.real_links)
+ {
+ clone->obj.real_links.push (l);
+ vertices_[l.objidx].parents.push (clone_idx);
+ }
+ for (const auto& l : child.obj.virtual_links)
+ {
+ clone->obj.virtual_links.push (l);
+ vertices_[l.objidx].parents.push (clone_idx);
+ }
+
+ check_success (!clone->obj.real_links.in_error ());
+ check_success (!clone->obj.virtual_links.in_error ());
+
+ // The last object is the root of the graph, so swap back the root to the end.
+ // The root's obj idx does change, however since it's root nothing else refers to it.
+ // all other obj idx's will be unaffected.
+ hb_swap (vertices_[vertices_.length - 2], *clone);
+
+ // Since the root moved, update the parents arrays of all children on the root.
+ for (const auto& l : root ().obj.all_links ())
+ vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ());
+
+ return clone_idx;
+ }
+
+ /*
+ * Creates a copy of child and re-assigns the link from
+ * parent to the clone. The copy is a shallow copy, objects
+ * linked from child are not duplicated.
+ */
+ bool duplicate (unsigned parent_idx, unsigned child_idx)
+ {
+ update_parents ();
+
+ unsigned links_to_child = 0;
+ for (const auto& l : vertices_[parent_idx].obj.all_links ())
+ {
+ if (l.objidx == child_idx) links_to_child++;
+ }
+
+ if (vertices_[child_idx].incoming_edges () <= links_to_child)
+ {
+ // Can't duplicate this node, doing so would orphan the original one as all remaining links
+ // to child are from parent.
+ DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %d => %d",
+ parent_idx, child_idx);
+ return false;
+ }
+
+ DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d",
+ parent_idx, child_idx);
+
+ unsigned clone_idx = duplicate (child_idx);
+ if (clone_idx == (unsigned) -1) return false;
+ // duplicate shifts the root node idx, so if parent_idx was root update it.
+ if (parent_idx == clone_idx) parent_idx++;
+
+ auto& parent = vertices_[parent_idx];
+ for (auto& l : parent.obj.all_links_writer ())
+ {
+ if (l.objidx != child_idx)
+ continue;
+
+ reassign_link (l, parent_idx, clone_idx);
+ }
+
+ return true;
+ }
+
+ /*
+ * Raises the sorting priority of all children.
+ */
+ bool raise_childrens_priority (unsigned parent_idx)
+ {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %d",
+ parent_idx);
+ // This operation doesn't change ordering until a sort is run, so no need
+ // to invalidate positions. It does not change graph structure so no need
+ // to update distances or edge counts.
+ auto& parent = vertices_[parent_idx].obj;
+ bool made_change = false;
+ for (auto& l : parent.all_links_writer ())
+ made_change |= vertices_[l.objidx].raise_priority ();
+ return made_change;
+ }
+
+ void print_orphaned_nodes ()
+ {
+ if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
+
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected.");
+ parents_invalid = true;
+ update_parents();
+
+ for (unsigned i = 0; i < root_idx (); i++)
+ {
+ const auto& v = vertices_[i];
+ if (!v.parents)
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i);
+ }
+ }
+
+ unsigned num_roots_for_space (unsigned space) const
+ {
+ return num_roots_for_space_[space];
+ }
+
+ unsigned next_space () const
+ {
+ return num_roots_for_space_.length;
+ }
+
+ void move_to_new_space (const hb_set_t& indices)
+ {
+ num_roots_for_space_.push (0);
+ unsigned new_space = num_roots_for_space_.length - 1;
+
+ for (unsigned index : indices) {
+ auto& node = vertices_[index];
+ num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1;
+ num_roots_for_space_[new_space] = num_roots_for_space_[new_space] + 1;
+ node.space = new_space;
+ distance_invalid = true;
+ positions_invalid = true;
+ }
+ }
+
+ unsigned space_for (unsigned index, unsigned* root = nullptr) const
+ {
+ const auto& node = vertices_[index];
+ if (node.space)
+ {
+ if (root != nullptr)
+ *root = index;
+ return node.space;
+ }
+
+ if (!node.parents)
+ {
+ if (root)
+ *root = index;
+ return 0;
+ }
+
+ return space_for (node.parents[0], root);
+ }
+
+ void err_other_error () { this->successful = false; }
+
+ size_t total_size_in_bytes () const {
+ size_t total_size = 0;
+ for (unsigned i = 0; i < vertices_.length; i++) {
+ size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
+ total_size += size;
+ }
+ return total_size;
+ }
+
+
+ private:
+
+ /*
+ * Returns the numbers of incoming edges that are 32bits wide.
+ */
+ unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const
+ {
+ unsigned count = 0;
+ hb_set_t visited;
+ for (unsigned p : vertices_[node_idx].parents)
+ {
+ if (visited.has (p)) continue;
+ visited.add (p);
+
+ // Only real links can be wide
+ for (const auto& l : vertices_[p].obj.real_links)
+ {
+ if (l.objidx == node_idx && l.width == 4 && !l.is_signed)
+ {
+ count++;
+ parents.add (p);
+ }
+ }
+ }
+ return count;
+ }
+
+ bool check_success (bool success)
+ { return this->successful && (success || ((void) err_other_error (), false)); }
+
+ public:
+ /*
+ * Creates a map from objid to # of incoming edges.
+ */
+ void update_parents ()
+ {
+ if (!parents_invalid) return;
+
+ for (unsigned i = 0; i < vertices_.length; i++)
+ vertices_[i].parents.reset ();
+
+ for (unsigned p = 0; p < vertices_.length; p++)
+ {
+ for (auto& l : vertices_[p].obj.all_links ())
+ {
+ vertices_[l.objidx].parents.push (p);
+ }
+ }
+
+ parents_invalid = false;
+ }
+
+ /*
+ * compute the serialized start and end positions for each vertex.
+ */
+ void update_positions ()
+ {
+ if (!positions_invalid) return;
+
+ unsigned current_pos = 0;
+ for (int i = root_idx (); i >= 0; i--)
+ {
+ auto& v = vertices_[i];
+ v.start = current_pos;
+ current_pos += v.obj.tail - v.obj.head;
+ v.end = current_pos;
+ }
+
+ positions_invalid = false;
+ }
+
+ /*
+ * Finds the distance to each object in the graph
+ * from the initial node.
+ */
+ void update_distances ()
+ {
+ if (!distance_invalid) return;
+
+ // Uses Dijkstra's algorithm to find all of the shortest distances.
+ // https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
+ //
+ // Implementation Note:
+ // Since our priority queue doesn't support fast priority decreases
+ // we instead just add new entries into the queue when a priority changes.
+ // 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 fibonacci queue) with a fast decrease priority.
+ for (unsigned i = 0; i < vertices_.length; i++)
+ {
+ if (i == vertices_.length - 1)
+ vertices_[i].distance = 0;
+ else
+ vertices_[i].distance = hb_int_max (int64_t);
+ }
+
+ hb_priority_queue_t queue;
+ queue.insert (0, vertices_.length - 1);
+
+ hb_vector_t<bool> visited;
+ visited.resize (vertices_.length);
+
+ while (!queue.in_error () && !queue.is_empty ())
+ {
+ unsigned next_idx = queue.pop_minimum ().second;
+ if (visited[next_idx]) continue;
+ const auto& next = vertices_[next_idx];
+ int64_t next_distance = vertices_[next_idx].distance;
+ visited[next_idx] = true;
+
+ for (const auto& link : next.obj.all_links ())
+ {
+ if (visited[link.objidx]) continue;
+
+ const auto& child = vertices_[link.objidx].obj;
+ unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide
+ int64_t child_weight = (child.tail - child.head) +
+ ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1);
+ int64_t child_distance = next_distance + child_weight;
+
+ if (child_distance < vertices_[link.objidx].distance)
+ {
+ vertices_[link.objidx].distance = child_distance;
+ queue.insert (child_distance, link.objidx);
+ }
+ }
+ }
+
+ check_success (!queue.in_error ());
+ if (!check_success (queue.is_empty ()))
+ {
+ print_orphaned_nodes ();
+ return;
+ }
+
+ distance_invalid = false;
+ }
+
+ private:
+ /*
+ * Updates a link in the graph to point to a different object. Corrects the
+ * parents vector on the previous and new child nodes.
+ */
+ void reassign_link (hb_serialize_context_t::object_t::link_t& link,
+ unsigned parent_idx,
+ unsigned new_idx)
+ {
+ unsigned old_idx = link.objidx;
+ link.objidx = new_idx;
+ vertices_[old_idx].remove_parent (parent_idx);
+ vertices_[new_idx].parents.push (parent_idx);
+ }
+
+ /*
+ * Updates all objidx's in all links using the provided mapping. Corrects incoming edge counts.
+ */
+ template<typename Iterator, hb_requires (hb_is_iterator (Iterator))>
+ void remap_obj_indices (const hb_map_t& id_map,
+ Iterator subgraph,
+ bool only_wide = false)
+ {
+ if (!id_map) return;
+ for (unsigned i : subgraph)
+ {
+ for (auto& link : vertices_[i].obj.all_links_writer ())
+ {
+ const unsigned *v;
+ if (!id_map.has (link.objidx, &v)) continue;
+ if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
+
+ reassign_link (link, i, *v);
+ }
+ }
+ }
+
+ /*
+ * Updates all objidx's in all links using the provided mapping.
+ */
+ void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
+ hb_vector_t<vertex_t>* sorted_graph) const
+ {
+ for (unsigned i = 0; i < sorted_graph->length; i++)
+ {
+ (*sorted_graph)[i].remap_parents (id_map);
+ for (auto& link : (*sorted_graph)[i].obj.all_links_writer ())
+ {
+ link.objidx = id_map[link.objidx];
+ }
+ }
+ }
+
+ /*
+ * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped.
+ * For this search the graph is treated as being undirected.
+ *
+ * Connected targets will be added to connected and removed from targets. All visited nodes
+ * will be added to visited.
+ */
+ void find_connected_nodes (unsigned start_idx,
+ hb_set_t& targets,
+ 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);
+
+ if (targets.has (start_idx))
+ {
+ targets.del (start_idx);
+ connected.add (start_idx);
+ }
+
+ const auto& v = vertices_[start_idx];
+
+ // Graph is treated as undirected so search children and parents of start_idx
+ for (const auto& l : v.obj.all_links ())
+ find_connected_nodes (l.objidx, targets, visited, connected);
+
+ for (unsigned p : v.parents)
+ find_connected_nodes (p, targets, visited, connected);
+ }
+
+ public:
+ // TODO(garretrieger): make private, will need to move most of offset overflow code into graph.
+ hb_vector_t<vertex_t> vertices_;
+ hb_vector_t<vertex_t> vertices_scratch_;
+ private:
+ bool parents_invalid;
+ bool distance_invalid;
+ bool positions_invalid;
+ bool successful;
+ hb_vector_t<unsigned> num_roots_for_space_;
+};
+
+}
+
+#endif // GRAPH_GRAPH_HH
diff --git a/thirdparty/harfbuzz/src/graph/serialize.hh b/thirdparty/harfbuzz/src/graph/serialize.hh
new file mode 100644
index 0000000000..ecc6cc5aea
--- /dev/null
+++ b/thirdparty/harfbuzz/src/graph/serialize.hh
@@ -0,0 +1,249 @@
+/*
+ * Copyright © 2022 Google, Inc.
+ *
+ * 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): Garret Rieger
+ */
+
+#ifndef GRAPH_SERIALIZE_HH
+#define GRAPH_SERIALIZE_HH
+
+namespace graph {
+
+struct overflow_record_t
+{
+ unsigned parent;
+ unsigned child;
+};
+
+inline
+int64_t compute_offset (
+ const graph_t& graph,
+ unsigned parent_idx,
+ const hb_serialize_context_t::object_t::link_t& link)
+{
+ const auto& parent = graph.vertices_[parent_idx];
+ const auto& child = graph.vertices_[link.objidx];
+ int64_t offset = 0;
+ switch ((hb_serialize_context_t::whence_t) link.whence) {
+ case hb_serialize_context_t::whence_t::Head:
+ offset = child.start - parent.start; break;
+ case hb_serialize_context_t::whence_t::Tail:
+ offset = child.start - parent.end; break;
+ case hb_serialize_context_t::whence_t::Absolute:
+ offset = child.start; break;
+ }
+
+ assert (offset >= link.bias);
+ offset -= link.bias;
+ return offset;
+}
+
+inline
+bool is_valid_offset (int64_t offset,
+ const hb_serialize_context_t::object_t::link_t& link)
+{
+ if (unlikely (!link.width))
+ // Virtual links can't overflow.
+ return link.is_signed || offset >= 0;
+
+ if (link.is_signed)
+ {
+ if (link.width == 4)
+ return offset >= -((int64_t) 1 << 31) && offset < ((int64_t) 1 << 31);
+ else
+ return offset >= -(1 << 15) && offset < (1 << 15);
+ }
+ else
+ {
+ if (link.width == 4)
+ return offset >= 0 && offset < ((int64_t) 1 << 32);
+ else if (link.width == 3)
+ return offset >= 0 && offset < ((int32_t) 1 << 24);
+ else
+ return offset >= 0 && offset < (1 << 16);
+ }
+}
+
+/*
+ * Will any offsets overflow on graph when it's serialized?
+ */
+inline bool
+will_overflow (graph_t& graph,
+ hb_vector_t<overflow_record_t>* overflows = nullptr)
+{
+ if (overflows) overflows->resize (0);
+ graph.update_positions ();
+
+ const auto& vertices = graph.vertices_;
+ for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--)
+ {
+ // Don't need to check virtual links for overflow
+ for (const auto& link : vertices[parent_idx].obj.real_links)
+ {
+ int64_t offset = compute_offset (graph, parent_idx, link);
+ if (is_valid_offset (offset, link))
+ continue;
+
+ if (!overflows) return true;
+
+ overflow_record_t r;
+ r.parent = parent_idx;
+ r.child = link.objidx;
+ overflows->push (r);
+ }
+ }
+
+ if (!overflows) return false;
+ return overflows->length;
+}
+
+inline
+void print_overflows (graph_t& graph,
+ const hb_vector_t<overflow_record_t>& overflows)
+{
+ if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
+
+ graph.update_parents ();
+ int limit = 10;
+ for (const auto& o : overflows)
+ {
+ if (!limit--) break;
+ const auto& parent = graph.vertices_[o.parent];
+ const auto& child = graph.vertices_[o.child];
+ DEBUG_MSG (SUBSET_REPACK, nullptr,
+ " overflow from "
+ "%4d (%4d in, %4d out, space %2d) => "
+ "%4d (%4d in, %4d out, space %2d)",
+ o.parent,
+ parent.incoming_edges (),
+ parent.obj.real_links.length + parent.obj.virtual_links.length,
+ graph.space_for (o.parent),
+ o.child,
+ child.incoming_edges (),
+ child.obj.real_links.length + child.obj.virtual_links.length,
+ graph.space_for (o.child));
+ }
+ if (overflows.length > 10) {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %d more overflows.", overflows.length - 10);
+ }
+}
+
+template <typename O> inline void
+serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link,
+ char* head,
+ hb_serialize_context_t* c)
+{
+ OT::Offset<O>* offset = reinterpret_cast<OT::Offset<O>*> (head + link.position);
+ *offset = 0;
+ c->add_link (*offset,
+ // serializer has an extra nil object at the start of the
+ // object array. So all id's are +1 of what our id's are.
+ link.objidx + 1,
+ (hb_serialize_context_t::whence_t) link.whence,
+ link.bias);
+}
+
+inline
+void serialize_link (const hb_serialize_context_t::object_t::link_t& link,
+ char* head,
+ hb_serialize_context_t* c)
+{
+ switch (link.width)
+ {
+ case 0:
+ // Virtual links aren't serialized.
+ return;
+ case 4:
+ if (link.is_signed)
+ {
+ serialize_link_of_type<OT::HBINT32> (link, head, c);
+ } else {
+ serialize_link_of_type<OT::HBUINT32> (link, head, c);
+ }
+ return;
+ case 2:
+ if (link.is_signed)
+ {
+ serialize_link_of_type<OT::HBINT16> (link, head, c);
+ } else {
+ serialize_link_of_type<OT::HBUINT16> (link, head, c);
+ }
+ return;
+ case 3:
+ serialize_link_of_type<OT::HBUINT24> (link, head, c);
+ return;
+ default:
+ // Unexpected link width.
+ assert (0);
+ }
+}
+
+/*
+ * serialize graph into the provided serialization buffer.
+ */
+inline hb_blob_t* serialize (const graph_t& graph)
+{
+ hb_vector_t<char> buffer;
+ size_t size = graph.total_size_in_bytes ();
+ if (!buffer.alloc (size)) {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer.");
+ return nullptr;
+ }
+ hb_serialize_context_t c((void *) buffer, size);
+
+ c.start_serialize<void> ();
+ const auto& vertices = graph.vertices_;
+ for (unsigned i = 0; i < vertices.length; i++) {
+ c.push ();
+
+ size_t size = vertices[i].obj.tail - vertices[i].obj.head;
+ char* start = c.allocate_size <char> (size);
+ if (!start) {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space.");
+ return nullptr;
+ }
+
+ memcpy (start, vertices[i].obj.head, size);
+
+ // Only real links needs to be serialized.
+ for (const auto& link : vertices[i].obj.real_links)
+ serialize_link (link, start, &c);
+
+ // All duplications are already encoded in the graph, so don't
+ // enable sharing during packing.
+ c.pop_pack (false);
+ }
+ c.end_serialize ();
+
+ if (c.in_error ()) {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Error during serialization. Err flag: %d",
+ c.errors);
+ return nullptr;
+ }
+
+ return c.copy_blob ();
+}
+
+} // namespace graph
+
+#endif // GRAPH_SERIALIZE_HH
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh
index 0354b47d5a..6a24c90c31 100644
--- a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh
+++ b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh
@@ -287,7 +287,7 @@ struct KerxSubTableFormat1
* in the 'kern' table example. */
if (v == -0x8000)
{
- o.attach_type() = ATTACH_TYPE_NONE;
+ o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_NONE;
o.attach_chain() = 0;
o.y_offset = 0;
}
@@ -310,7 +310,7 @@ struct KerxSubTableFormat1
/* CoreText doesn't do crossStream kerning in vertical. We do. */
if (v == -0x8000)
{
- o.attach_type() = ATTACH_TYPE_NONE;
+ o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_NONE;
o.attach_chain() = 0;
o.x_offset = 0;
}
@@ -567,7 +567,7 @@ struct KerxSubTableFormat4
}
break;
}
- o.attach_type() = ATTACH_TYPE_MARK;
+ o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_MARK;
o.attach_chain() = (int) mark - (int) buffer->idx;
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
}
@@ -901,7 +901,7 @@ struct KerxTable
unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++)
{
- pos[i].attach_type() = ATTACH_TYPE_CURSIVE;
+ pos[i].attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_CURSIVE;
pos[i].attach_chain() = HB_DIRECTION_IS_FORWARD (c->buffer->props.direction) ? -1 : +1;
/* We intentionally don't set HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT,
* since there needs to be a non-zero attachment for post-positioning to
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh
index b77c1f4d44..3d053cb13e 100644
--- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh
+++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh
@@ -123,7 +123,7 @@ struct RearrangementSubtable
bool reverse_l = 3 == (m >> 4);
bool reverse_r = 3 == (m & 0x0F);
- if (end - start >= l + r)
+ if (end - start >= l + r && end-start <= HB_MAX_CONTEXT_LENGTH)
{
buffer->merge_clusters (start, hb_min (buffer->idx + 1, buffer->len));
buffer->merge_clusters (start, end);
diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh
index 05b4df52f1..f1633d886a 100644
--- a/thirdparty/harfbuzz/src/hb-algs.hh
+++ b/thirdparty/harfbuzz/src/hb-algs.hh
@@ -59,7 +59,7 @@
static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
- static inline constexpr T operator ~ (T r) { return T (~(unsigned int) r); } \
+ static inline constexpr unsigned operator ~ (T r) { return (~(unsigned) r); } \
static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
@@ -227,31 +227,26 @@ struct
}
HB_FUNCOBJ (hb_bool);
-template <typename T>
-static inline
-constexpr 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
-constexpr T hb_coerce (const V v) { return *v; }
-
struct
{
private:
template <typename T> constexpr auto
- impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+ impl (const T& v, hb_priority<1>) 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> constexpr uint32_t
+ impl (const hb::shared_ptr<T>& v, hb_priority<1>) const
+ {
+ return v.get () ? v.get ()->hash () : 0;
+ }
+ template <typename T> constexpr uint32_t
+ impl (const hb::unique_ptr<T>& v, hb_priority<1>) const
+ {
+ return v.get () ? v.get ()->hash () : 0;
+ }
- template <typename T,
- hb_enable_if (std::is_integral<T>::value)> constexpr auto
- impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
- (
- /* Knuth's multiplicative method: */
- (uint32_t) v * 2654435761u
- )
+ template <typename T> constexpr auto
+ impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
public:
@@ -862,6 +857,11 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
{
return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
}
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3, T lo4, T hi4)
+{
+ return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3) || hb_in_range (u, lo4, hi4);
+}
/*
diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh
index 1963698cf7..5baeb6f7fe 100644
--- a/thirdparty/harfbuzz/src/hb-array.hh
+++ b/thirdparty/harfbuzz/src/hb-array.hh
@@ -56,7 +56,6 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
hb_array_t& operator= (const hb_array_t&) = default;
hb_array_t& operator= (hb_array_t&&) = default;
- constexpr hb_array_t (std::nullptr_t) : hb_array_t () {}
constexpr hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
template <unsigned int length_>
constexpr hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {}
@@ -314,7 +313,6 @@ struct hb_sorted_array_t :
hb_sorted_array_t& operator= (const hb_sorted_array_t&) = default;
hb_sorted_array_t& operator= (hb_sorted_array_t&&) = default;
- constexpr hb_sorted_array_t (std::nullptr_t) : hb_sorted_array_t () {}
constexpr hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
template <unsigned int length_>
constexpr hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
diff --git a/thirdparty/harfbuzz/src/hb-bimap.hh b/thirdparty/harfbuzz/src/hb-bimap.hh
index 5b313bf59c..8e8c988716 100644
--- a/thirdparty/harfbuzz/src/hb-bimap.hh
+++ b/thirdparty/harfbuzz/src/hb-bimap.hh
@@ -54,17 +54,18 @@ struct hb_bimap_t
if (unlikely (rhs == HB_MAP_VALUE_INVALID)) { del (lhs); return; }
forw_map.set (lhs, rhs);
- if (in_error ()) return;
+ if (unlikely (in_error ())) return;
back_map.set (rhs, lhs);
- if (in_error ()) forw_map.del (lhs);
+ if (unlikely (in_error ())) forw_map.del (lhs);
}
hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); }
hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map.get (rhs); }
hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); }
- bool has (hb_codepoint_t lhs, hb_codepoint_t *vp = nullptr) const { return forw_map.has (lhs, vp); }
+ bool has (hb_codepoint_t lhs) const { return forw_map.has (lhs); }
+
void del (hb_codepoint_t lhs)
{
@@ -78,7 +79,7 @@ struct hb_bimap_t
back_map.clear ();
}
- bool is_empty () const { return get_population () == 0; }
+ bool is_empty () const { return forw_map.is_empty (); }
unsigned int get_population () const { return forw_map.get_population (); }
diff --git a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh
index caea47d8d3..27fb0732ea 100644
--- a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh
+++ b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh
@@ -80,7 +80,7 @@ struct hb_bit_set_invertible_t
next (&v);
return v == INVALID;
}
- uint32_t hash () const { return s.hash () ^ inverted; }
+ uint32_t hash () const { return s.hash () ^ (uint32_t) inverted; }
hb_codepoint_t get_min () const
{
@@ -100,7 +100,7 @@ struct hb_bit_set_invertible_t
void add (hb_codepoint_t g) { unlikely (inverted) ? s.del (g) : s.add (g); }
bool add_range (hb_codepoint_t a, hb_codepoint_t b)
- { return unlikely (inverted) ? (s.del_range (a, b), true) : s.add_range (a, b); }
+ { return unlikely (inverted) ? ((void) s.del_range (a, b), true) : s.add_range (a, b); }
template <typename T>
void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh
index 11a4359dc9..438fb66a2c 100644
--- a/thirdparty/harfbuzz/src/hb-bit-set.hh
+++ b/thirdparty/harfbuzz/src/hb-bit-set.hh
@@ -56,7 +56,7 @@ struct hb_bit_set_t
{
successful = true;
population = 0;
- last_page_lookup = 0;
+ last_page_lookup.set_relaxed (0);
page_map.init ();
pages.init ();
}
@@ -78,7 +78,7 @@ struct hb_bit_set_t
bool successful = true; /* Allocations successful */
mutable unsigned int population = 0;
- mutable unsigned int last_page_lookup = 0;
+ mutable hb_atomic_int_t last_page_lookup = 0;
hb_sorted_vector_t<page_map_t> page_map;
hb_vector_t<page_t> pages;
@@ -607,7 +607,7 @@ struct hb_bit_set_t
const auto* page_map_array = page_map.arrayZ;
unsigned int major = get_major (*codepoint);
- unsigned int i = last_page_lookup;
+ unsigned int i = last_page_lookup.get_relaxed ();
if (unlikely (i >= page_map.length || page_map_array[i].major != major))
{
@@ -625,7 +625,7 @@ struct hb_bit_set_t
if (pages_array[current.index].next (codepoint))
{
*codepoint += current.major * page_t::PAGE_BITS;
- last_page_lookup = i;
+ last_page_lookup.set_relaxed (i);
return true;
}
i++;
@@ -638,11 +638,11 @@ struct hb_bit_set_t
if (m != INVALID)
{
*codepoint = current.major * page_t::PAGE_BITS + m;
- last_page_lookup = i;
+ last_page_lookup.set_relaxed (i);
return true;
}
}
- last_page_lookup = 0;
+ last_page_lookup.set_relaxed (0);
*codepoint = INVALID;
return false;
}
@@ -725,7 +725,7 @@ struct hb_bit_set_t
{
const auto* page_map_array = page_map.arrayZ;
unsigned int major = get_major (codepoint);
- unsigned int i = last_page_lookup;
+ unsigned int i = last_page_lookup.get_relaxed ();
if (unlikely (i >= page_map.length || page_map_array[i].major != major))
{
page_map.bfind (major, &i, HB_NOT_FOUND_STORE_CLOSEST);
@@ -766,7 +766,7 @@ struct hb_bit_set_t
{
const auto* page_map_array = page_map.arrayZ;
unsigned int major = get_major (codepoint);
- unsigned int i = last_page_lookup;
+ unsigned int i = last_page_lookup.get_relaxed ();
if (unlikely (i >= page_map.length || page_map_array[i].major != major))
{
page_map.bfind(major, &i, HB_NOT_FOUND_STORE_CLOSEST);
@@ -893,15 +893,15 @@ struct hb_bit_set_t
/* The extra page_map length is necessary; can't just rely on vector here,
* since the next check would be tricked because a null page also has
* major==0, which we can't distinguish from an actualy major==0 page... */
- if (likely (last_page_lookup < page_map.length))
+ unsigned i = last_page_lookup.get_relaxed ();
+ if (likely (i < page_map.length))
{
- auto &cached_page = page_map.arrayZ[last_page_lookup];
+ auto &cached_page = page_map.arrayZ[i];
if (cached_page.major == major)
return &pages[cached_page.index];
}
page_map_t map = {major, pages.length};
- unsigned int i;
if (!page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST))
{
if (!insert)
@@ -917,7 +917,7 @@ struct hb_bit_set_t
page_map[i] = map;
}
- last_page_lookup = i;
+ last_page_lookup.set_relaxed (i);
return &pages[page_map[i].index];
}
const page_t *page_for (hb_codepoint_t g) const
@@ -927,19 +927,19 @@ struct hb_bit_set_t
/* The extra page_map length is necessary; can't just rely on vector here,
* since the next check would be tricked because a null page also has
* major==0, which we can't distinguish from an actualy major==0 page... */
- if (likely (last_page_lookup < page_map.length))
+ unsigned i = last_page_lookup.get_relaxed ();
+ if (likely (i < page_map.length))
{
- auto &cached_page = page_map.arrayZ[last_page_lookup];
+ auto &cached_page = page_map.arrayZ[i];
if (cached_page.major == major)
return &pages[cached_page.index];
}
page_map_t key = {major};
- unsigned int i;
if (!page_map.bfind (key, &i))
return nullptr;
- last_page_lookup = i;
+ last_page_lookup.set_relaxed (i);
return &pages[page_map[i].index];
}
page_t &page_at (unsigned int i) { return pages[page_map[i].index]; }
diff --git a/thirdparty/harfbuzz/src/hb-blob.cc b/thirdparty/harfbuzz/src/hb-blob.cc
index 65e44c7f6a..b561a9374e 100644
--- a/thirdparty/harfbuzz/src/hb-blob.cc
+++ b/thirdparty/harfbuzz/src/hb-blob.cc
@@ -369,7 +369,7 @@ hb_blob_get_length (hb_blob_t *blob)
*
* Fetches the data from a blob.
*
- * Returns: (transfer none) (array length=length): the byte data of @blob.
+ * Returns: (nullable) (transfer none) (array length=length): the byte data of @blob.
*
* Since: 0.9.2
**/
@@ -572,7 +572,7 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file)
strncpy (rsrc_name, file_name, name_len);
strncpy (rsrc_name + name_len, _PATH_RSRCFORKSPEC,
- sizeof (_PATH_RSRCFORKSPEC) - 1);
+ sizeof (_PATH_RSRCFORKSPEC));
int fd = open (rsrc_name, O_RDONLY | O_BINARY, 0);
hb_free (rsrc_name);
diff --git a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc
index 6539b89640..3f619a113e 100644
--- a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc
+++ b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc
@@ -31,7 +31,7 @@
#include "hb-buffer.hh"
-static const char *serialize_formats[] = {
+static const char *_hb_buffer_serialize_formats[] = {
"text",
"json",
nullptr
@@ -50,7 +50,7 @@ static const char *serialize_formats[] = {
const char **
hb_buffer_serialize_list_formats ()
{
- return serialize_formats;
+ return _hb_buffer_serialize_formats;
}
/**
@@ -91,8 +91,8 @@ hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{
switch ((unsigned) format)
{
- case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
- case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
+ case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return _hb_buffer_serialize_formats[0];
+ case HB_BUFFER_SERIALIZE_FORMAT_JSON: return _hb_buffer_serialize_formats[1];
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
}
@@ -400,9 +400,9 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
- * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf.
+ * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf.
* @font: (nullable): the #hb_font_t used to shape this buffer, needed to
- * read glyph names and extents. If %NULL, and empty font will be used.
+ * read glyph names and extents. If %NULL, an empty font will be used.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
* to serialize.
@@ -514,7 +514,7 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
- * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf.
+ * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
* to serialize.
@@ -637,9 +637,9 @@ _hb_buffer_serialize_invalid (hb_buffer_t *buffer,
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
- * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf.
+ * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf.
* @font: (nullable): the #hb_font_t used to shape this buffer, needed to
- * read glyph names and extents. If %NULL, and empty font will be used.
+ * read glyph names and extents. If %NULL, an empty font will be used.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
* to serialize.
diff --git a/thirdparty/harfbuzz/src/hb-buffer-verify.cc b/thirdparty/harfbuzz/src/hb-buffer-verify.cc
index dea2c11c35..5453e1ca94 100644
--- a/thirdparty/harfbuzz/src/hb-buffer-verify.cc
+++ b/thirdparty/harfbuzz/src/hb-buffer-verify.cc
@@ -102,9 +102,9 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer,
/* Check that breaking up shaping at safe-to-break is indeed safe. */
hb_buffer_t *fragment = hb_buffer_create_similar (buffer);
- hb_buffer_set_flags (fragment, hb_buffer_get_flags (fragment) & ~HB_BUFFER_FLAG_VERIFY);
+ hb_buffer_set_flags (fragment, (hb_buffer_flags_t (hb_buffer_get_flags (fragment) & ~HB_BUFFER_FLAG_VERIFY)));
hb_buffer_t *reconstruction = hb_buffer_create_similar (buffer);
- hb_buffer_set_flags (reconstruction, hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY);
+ hb_buffer_set_flags (reconstruction, (hb_buffer_flags_t (hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY)));
unsigned int num_glyphs;
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs);
@@ -169,6 +169,12 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer,
hb_buffer_destroy (fragment);
return false;
}
+ else if (!fragment->successful || fragment->shaping_failed)
+ {
+ hb_buffer_destroy (reconstruction);
+ hb_buffer_destroy (fragment);
+ return true;
+ }
hb_buffer_append (reconstruction, fragment, 0, -1);
start = end;
@@ -238,10 +244,10 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer,
hb_buffer_t *fragments[2] {hb_buffer_create_similar (buffer),
hb_buffer_create_similar (buffer)};
- hb_buffer_set_flags (fragments[0], hb_buffer_get_flags (fragments[0]) & ~HB_BUFFER_FLAG_VERIFY);
- hb_buffer_set_flags (fragments[1], hb_buffer_get_flags (fragments[1]) & ~HB_BUFFER_FLAG_VERIFY);
+ hb_buffer_set_flags (fragments[0], (hb_buffer_flags_t (hb_buffer_get_flags (fragments[0]) & ~HB_BUFFER_FLAG_VERIFY)));
+ hb_buffer_set_flags (fragments[1], (hb_buffer_flags_t (hb_buffer_get_flags (fragments[1]) & ~HB_BUFFER_FLAG_VERIFY)));
hb_buffer_t *reconstruction = hb_buffer_create_similar (buffer);
- hb_buffer_set_flags (reconstruction, hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY);
+ hb_buffer_set_flags (reconstruction, (hb_buffer_flags_t (hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY)));
hb_segment_properties_t props;
hb_buffer_get_segment_properties (buffer, &props);
hb_buffer_set_segment_properties (fragments[0], &props);
@@ -317,12 +323,22 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer,
ret = false;
goto out;
}
+ else if (!fragments[0]->successful || fragments[0]->shaping_failed)
+ {
+ ret = true;
+ goto out;
+ }
if (!hb_shape_full (font, fragments[1], features, num_features, shapers))
{
buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
ret = false;
goto out;
}
+ else if (!fragments[1]->successful || fragments[1]->shaping_failed)
+ {
+ ret = true;
+ goto out;
+ }
if (!forward)
{
@@ -402,6 +418,7 @@ hb_buffer_t::verify (hb_buffer_t *text_buffer,
ret = false;
if (!ret)
{
+#ifndef HB_NO_BUFFER_SERIALIZE
unsigned len = text_buffer->len;
hb_vector_t<char> bytes;
if (likely (bytes.resize (len * 10 + 16)))
@@ -414,6 +431,7 @@ hb_buffer_t::verify (hb_buffer_t *text_buffer,
HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS);
buffer_verify_error (this, font, BUFFER_VERIFY_ERROR "text was: %s.", bytes.arrayZ);
}
+#endif
}
return ret;
}
diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc
index 6a9ee3ccc8..2272ecf09b 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.cc
+++ b/thirdparty/harfbuzz/src/hb-buffer.cc
@@ -81,8 +81,8 @@ hb_segment_properties_equal (const hb_segment_properties_t *a,
unsigned int
hb_segment_properties_hash (const hb_segment_properties_t *p)
{
- return (unsigned int) p->direction ^
- (unsigned int) p->script ^
+ return ((unsigned int) p->direction * 31 +
+ (unsigned int) p->script) * 31 +
(intptr_t) (p->language);
}
@@ -289,6 +289,7 @@ hb_buffer_t::clear ()
props = default_props;
successful = true;
+ shaping_failed = false;
have_output = false;
have_positions = false;
@@ -310,6 +311,7 @@ hb_buffer_t::enter ()
{
deallocate_var_all ();
serial = 0;
+ shaping_failed = false;
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR)))
{
@@ -329,6 +331,7 @@ hb_buffer_t::leave ()
max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
deallocate_var_all ();
serial = 0;
+ // Intentionally not reseting shaping_failed, such that it can be inspected.
}
@@ -542,7 +545,8 @@ hb_buffer_t::delete_glyph ()
/* The logic here is duplicated in hb_ot_hide_default_ignorables(). */
unsigned int cluster = info[idx].cluster;
- if (idx + 1 < len && cluster == info[idx + 1].cluster)
+ if ((idx + 1 < len && cluster == info[idx + 1].cluster) ||
+ (out_len && cluster == out_info[out_len - 1].cluster))
{
/* Cluster survives; do nothing. */
goto done;
@@ -623,6 +627,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) =
HB_SEGMENT_PROPERTIES_DEFAULT,
false, /* successful */
+ true, /* shaping_failed */
false, /* have_output */
true /* have_positions */
@@ -631,7 +636,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) =
/**
- * hb_buffer_create: (Xconstructor)
+ * hb_buffer_create:
*
* Creates a new #hb_buffer_t with all properties to defaults.
*
@@ -834,7 +839,7 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
* Since: 0.9.5
**/
hb_buffer_content_type_t
-hb_buffer_get_content_type (hb_buffer_t *buffer)
+hb_buffer_get_content_type (const hb_buffer_t *buffer)
{
return buffer->content_type;
}
@@ -876,7 +881,7 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
* Since: 0.9.2
**/
hb_unicode_funcs_t *
-hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
+hb_buffer_get_unicode_funcs (const hb_buffer_t *buffer)
{
return buffer->unicode;
}
@@ -919,7 +924,7 @@ hb_buffer_set_direction (hb_buffer_t *buffer,
* Since: 0.9.2
**/
hb_direction_t
-hb_buffer_get_direction (hb_buffer_t *buffer)
+hb_buffer_get_direction (const hb_buffer_t *buffer)
{
return buffer->props.direction;
}
@@ -963,7 +968,7 @@ hb_buffer_set_script (hb_buffer_t *buffer,
* Since: 0.9.2
**/
hb_script_t
-hb_buffer_get_script (hb_buffer_t *buffer)
+hb_buffer_get_script (const hb_buffer_t *buffer)
{
return buffer->props.script;
}
@@ -1007,7 +1012,7 @@ hb_buffer_set_language (hb_buffer_t *buffer,
* Since: 0.9.2
**/
hb_language_t
-hb_buffer_get_language (hb_buffer_t *buffer)
+hb_buffer_get_language (const hb_buffer_t *buffer)
{
return buffer->props.language;
}
@@ -1043,7 +1048,7 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
* Since: 0.9.7
**/
void
-hb_buffer_get_segment_properties (hb_buffer_t *buffer,
+hb_buffer_get_segment_properties (const hb_buffer_t *buffer,
hb_segment_properties_t *props)
{
*props = buffer->props;
@@ -1081,7 +1086,7 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
* Since: 0.9.7
**/
hb_buffer_flags_t
-hb_buffer_get_flags (hb_buffer_t *buffer)
+hb_buffer_get_flags (const hb_buffer_t *buffer)
{
return buffer->flags;
}
@@ -1120,7 +1125,7 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer,
* Since: 0.9.42
**/
hb_buffer_cluster_level_t
-hb_buffer_get_cluster_level (hb_buffer_t *buffer)
+hb_buffer_get_cluster_level (const hb_buffer_t *buffer)
{
return buffer->cluster_level;
}
@@ -1161,7 +1166,7 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
* Since: 0.9.31
**/
hb_codepoint_t
-hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer)
+hb_buffer_get_replacement_codepoint (const hb_buffer_t *buffer)
{
return buffer->replacement;
}
@@ -1201,7 +1206,7 @@ hb_buffer_set_invisible_glyph (hb_buffer_t *buffer,
* Since: 2.0.0
**/
hb_codepoint_t
-hb_buffer_get_invisible_glyph (hb_buffer_t *buffer)
+hb_buffer_get_invisible_glyph (const hb_buffer_t *buffer)
{
return buffer->invisible;
}
@@ -1241,7 +1246,7 @@ hb_buffer_set_not_found_glyph (hb_buffer_t *buffer,
* Since: 3.1.0
**/
hb_codepoint_t
-hb_buffer_get_not_found_glyph (hb_buffer_t *buffer)
+hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer)
{
return buffer->not_found;
}
@@ -1381,7 +1386,7 @@ hb_buffer_set_length (hb_buffer_t *buffer,
* Since: 0.9.2
**/
unsigned int
-hb_buffer_get_length (hb_buffer_t *buffer)
+hb_buffer_get_length (const hb_buffer_t *buffer)
{
return buffer->len;
}
diff --git a/thirdparty/harfbuzz/src/hb-buffer.h b/thirdparty/harfbuzz/src/hb-buffer.h
index 14aaa5e1f5..22fb3496f2 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.h
+++ b/thirdparty/harfbuzz/src/hb-buffer.h
@@ -289,7 +289,7 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
hb_buffer_content_type_t content_type);
HB_EXTERN hb_buffer_content_type_t
-hb_buffer_get_content_type (hb_buffer_t *buffer);
+hb_buffer_get_content_type (const hb_buffer_t *buffer);
HB_EXTERN void
@@ -297,21 +297,21 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
hb_unicode_funcs_t *unicode_funcs);
HB_EXTERN hb_unicode_funcs_t *
-hb_buffer_get_unicode_funcs (hb_buffer_t *buffer);
+hb_buffer_get_unicode_funcs (const hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_direction (hb_buffer_t *buffer,
hb_direction_t direction);
HB_EXTERN hb_direction_t
-hb_buffer_get_direction (hb_buffer_t *buffer);
+hb_buffer_get_direction (const hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_script (hb_buffer_t *buffer,
hb_script_t script);
HB_EXTERN hb_script_t
-hb_buffer_get_script (hb_buffer_t *buffer);
+hb_buffer_get_script (const hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_language (hb_buffer_t *buffer,
@@ -319,14 +319,14 @@ hb_buffer_set_language (hb_buffer_t *buffer,
HB_EXTERN hb_language_t
-hb_buffer_get_language (hb_buffer_t *buffer);
+hb_buffer_get_language (const hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_segment_properties (hb_buffer_t *buffer,
const hb_segment_properties_t *props);
HB_EXTERN void
-hb_buffer_get_segment_properties (hb_buffer_t *buffer,
+hb_buffer_get_segment_properties (const hb_buffer_t *buffer,
hb_segment_properties_t *props);
HB_EXTERN void
@@ -373,6 +373,7 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
* flag indicating that the @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
* glyph-flag should be produced by the shaper. By default
* it will not be produced since it incurs a cost. Since: 4.0.0
+ * @HB_BUFFER_FLAG_DEFINED: All currently defined flags: Since: 4.4.0
*
* Flags for #hb_buffer_t.
*
@@ -386,7 +387,9 @@ typedef enum { /*< flags >*/
HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u,
HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u,
HB_BUFFER_FLAG_VERIFY = 0x00000020u,
- HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u
+ HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u,
+
+ HB_BUFFER_FLAG_DEFINED = 0x0000007Fu
} hb_buffer_flags_t;
HB_EXTERN void
@@ -394,7 +397,7 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
hb_buffer_flags_t flags);
HB_EXTERN hb_buffer_flags_t
-hb_buffer_get_flags (hb_buffer_t *buffer);
+hb_buffer_get_flags (const hb_buffer_t *buffer);
/**
* hb_buffer_cluster_level_t:
@@ -436,7 +439,7 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer,
hb_buffer_cluster_level_t cluster_level);
HB_EXTERN hb_buffer_cluster_level_t
-hb_buffer_get_cluster_level (hb_buffer_t *buffer);
+hb_buffer_get_cluster_level (const hb_buffer_t *buffer);
/**
* HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT:
@@ -453,21 +456,21 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
hb_codepoint_t replacement);
HB_EXTERN hb_codepoint_t
-hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer);
+hb_buffer_get_replacement_codepoint (const hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_invisible_glyph (hb_buffer_t *buffer,
hb_codepoint_t invisible);
HB_EXTERN hb_codepoint_t
-hb_buffer_get_invisible_glyph (hb_buffer_t *buffer);
+hb_buffer_get_invisible_glyph (const hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_not_found_glyph (hb_buffer_t *buffer,
hb_codepoint_t not_found);
HB_EXTERN hb_codepoint_t
-hb_buffer_get_not_found_glyph (hb_buffer_t *buffer);
+hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer);
/*
@@ -549,7 +552,7 @@ hb_buffer_set_length (hb_buffer_t *buffer,
unsigned int length);
HB_EXTERN unsigned int
-hb_buffer_get_length (hb_buffer_t *buffer);
+hb_buffer_get_length (const hb_buffer_t *buffer);
/* Getting glyphs out of the buffer */
@@ -583,6 +586,7 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
* @HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS: serialize glyph flags. Since: 1.5.0
* @HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES: do not serialize glyph advances,
* glyph offsets will reflect absolute glyph positions. Since: 1.8.0
+ * @HB_BUFFER_SERIALIZE_FLAG_DEFINED: All currently defined flags. Since: 4.4.0
*
* Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs().
*
@@ -595,7 +599,9 @@ typedef enum { /*< flags >*/
HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u,
HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u,
HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u,
- HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES = 0x00000020u
+ HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES = 0x00000020u,
+
+ HB_BUFFER_SERIALIZE_FLAG_DEFINED = 0x0000003Fu
} hb_buffer_serialize_flags_t;
/**
diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh
index bc6992905e..6ca78f28d4 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.hh
+++ b/thirdparty/harfbuzz/src/hb-buffer.hh
@@ -57,6 +57,7 @@
static_assert ((sizeof (hb_glyph_info_t) == 20), "");
static_assert ((sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)), "");
+HB_MARK_AS_FLAG_T (hb_glyph_flags_t);
HB_MARK_AS_FLAG_T (hb_buffer_flags_t);
HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t);
HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t);
@@ -69,12 +70,13 @@ enum hb_buffer_scratch_flags_t {
HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u,
HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u,
HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u,
+ HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000040u,
- /* Reserved for complex shapers' internal use. */
- HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u,
- HB_BUFFER_SCRATCH_FLAG_COMPLEX1 = 0x02000000u,
- HB_BUFFER_SCRATCH_FLAG_COMPLEX2 = 0x04000000u,
- HB_BUFFER_SCRATCH_FLAG_COMPLEX3 = 0x08000000u,
+ /* Reserved for shapers' internal use. */
+ HB_BUFFER_SCRATCH_FLAG_SHAPER0 = 0x01000000u,
+ HB_BUFFER_SCRATCH_FLAG_SHAPER1 = 0x02000000u,
+ HB_BUFFER_SCRATCH_FLAG_SHAPER2 = 0x04000000u,
+ HB_BUFFER_SCRATCH_FLAG_SHAPER3 = 0x08000000u,
};
HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t);
@@ -106,6 +108,7 @@ struct hb_buffer_t
hb_segment_properties_t props; /* Script, language, direction */
bool successful; /* Allocations successful */
+ bool shaping_failed; /* Shaping failure */
bool have_output; /* Whether we have an output buffer going on */
bool have_positions; /* Whether we have positions */
@@ -130,9 +133,7 @@ struct hb_buffer_t
* 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. */
@@ -161,38 +162,40 @@ struct hb_buffer_t
void allocate_var (unsigned int start, unsigned int count)
{
-#ifndef HB_NDEBUG
unsigned int end = start + count;
assert (end <= 8);
unsigned int bits = (1u<<end) - (1u<<start);
assert (0 == (allocated_var_bits & bits));
allocated_var_bits |= bits;
-#endif
+ }
+ bool try_allocate_var (unsigned int start, unsigned int count)
+ {
+ unsigned int end = start + count;
+ assert (end <= 8);
+ unsigned int bits = (1u<<end) - (1u<<start);
+ if (allocated_var_bits & bits)
+ return false;
+ allocated_var_bits |= bits;
+ return true;
}
void deallocate_var (unsigned int start, unsigned int count)
{
-#ifndef HB_NDEBUG
unsigned int end = start + count;
assert (end <= 8);
unsigned int bits = (1u<<end) - (1u<<start);
assert (bits == (allocated_var_bits & bits));
allocated_var_bits &= ~bits;
-#endif
}
void assert_var (unsigned int start, unsigned int count)
{
-#ifndef HB_NDEBUG
unsigned int end = start + count;
assert (end <= 8);
- unsigned int bits = (1u<<end) - (1u<<start);
+ HB_UNUSED unsigned int bits = (1u<<end) - (1u<<start);
assert (bits == (allocated_var_bits & bits));
-#endif
}
void deallocate_var_all ()
{
-#ifndef HB_NDEBUG
allocated_var_bits = 0;
-#endif
}
hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
@@ -549,7 +552,7 @@ struct hb_buffer_t
#ifdef HB_NO_BUFFER_MESSAGE
return true;
#else
- if (!messaging ())
+ if (likely (!messaging ()))
return true;
message_depth++;
@@ -619,9 +622,10 @@ DECLARE_NULL_INSTANCE (hb_buffer_t);
#define HB_BUFFER_XALLOCATE_VAR(b, func, var) \
b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \
sizeof (b->info[0].var))
-#define HB_BUFFER_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var ())
-#define HB_BUFFER_DEALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ())
-#define HB_BUFFER_ASSERT_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, assert_var, var ())
+#define HB_BUFFER_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var ())
+#define HB_BUFFER_TRY_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, try_allocate_var, var ())
+#define HB_BUFFER_DEALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ())
+#define HB_BUFFER_ASSERT_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, assert_var, var ())
#endif /* HB_BUFFER_HH */
diff --git a/thirdparty/harfbuzz/src/hb-cache.hh b/thirdparty/harfbuzz/src/hb-cache.hh
index e617b75de9..d6b229ed65 100644
--- a/thirdparty/harfbuzz/src/hb-cache.hh
+++ b/thirdparty/harfbuzz/src/hb-cache.hh
@@ -32,7 +32,7 @@
/* Implements a lockfree cache for int->int functions. */
-template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits>
+template <unsigned int key_bits=16, unsigned int value_bits=8 + 32 - key_bits, unsigned int cache_bits=8>
struct hb_cache_t
{
static_assert ((key_bits >= cache_bits), "");
diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc
index 41229b9183..7266d9b01f 100644
--- a/thirdparty/harfbuzz/src/hb-common.cc
+++ b/thirdparty/harfbuzz/src/hb-common.cc
@@ -160,7 +160,7 @@ hb_tag_to_string (hb_tag_t tag, char *buf)
/* hb_direction_t */
-const char direction_strings[][4] = {
+static const char direction_strings[][4] = {
"ltr",
"rtl",
"ttb",
diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh
index 4b46dea938..2578231d23 100644
--- a/thirdparty/harfbuzz/src/hb-config.hh
+++ b/thirdparty/harfbuzz/src/hb-config.hh
@@ -64,6 +64,7 @@
#define HB_NO_FACE_COLLECT_UNICODES
#define HB_NO_GETENV
#define HB_NO_HINTING
+#define HB_NO_LANGUAGE_LONG
#define HB_NO_LANGUAGE_PRIVATE_SUBTAG
#define HB_NO_LAYOUT_FEATURE_PARAMS
#define HB_NO_LAYOUT_COLLECT_GLYPHS
@@ -145,10 +146,10 @@
#endif
#ifdef HB_NO_OT_SHAPE_FALLBACK
-#define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK
-#define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
-#define HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
-#define HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
+#define HB_NO_OT_SHAPER_ARABIC_FALLBACK
+#define HB_NO_OT_SHAPER_HEBREW_FALLBACK
+#define HB_NO_OT_SHAPER_THAI_FALLBACK
+#define HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS
#endif
#ifdef NDEBUG
@@ -163,5 +164,9 @@
#endif
#endif
+#ifdef HB_OPTIMIZE_SIZE
+#define HB_NO_OT_LAYOUT_LOOKUP_CACHE
+#endif
+
#endif /* HB_CONFIG_HH */
diff --git a/thirdparty/harfbuzz/src/hb-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc
index 6ccc1b0a2b..99b33c001e 100644
--- a/thirdparty/harfbuzz/src/hb-coretext.cc
+++ b/thirdparty/harfbuzz/src/hb-coretext.cc
@@ -332,7 +332,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
return nullptr;
}
- if (font->coords)
+ if (font->num_coords)
{
CFMutableDictionaryRef variations =
CFDictionaryCreateMutable (kCFAllocatorDefault,
@@ -379,37 +379,6 @@ _hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data)
CFRelease ((CTFontRef) data);
}
-static const hb_coretext_font_data_t *
-hb_coretext_font_data_sync (hb_font_t *font)
-{
-retry:
- const hb_coretext_font_data_t *data = font->data.coretext;
- if (unlikely (!data)) return nullptr;
-
- if (fabs (CTFontGetSize ((CTFontRef) data) - (CGFloat) font->ptem) > (CGFloat) .5)
- {
- /* XXX-MT-bug
- * Note that evaluating condition above can be dangerous if another thread
- * got here first and destructed data. That's, as always, bad use pattern.
- * If you modify the font (change font size), other threads must not be
- * using it at the same time. However, since this check is delayed to
- * when one actually tries to shape something, this is a XXX race condition
- * (and the only one we have that I know of) right now. Ie. you modify the
- * font size in one thread, then (supposedly safely) try to use it from two
- * or more threads and BOOM! I'm not sure how to fix this. We want RCU.
- */
-
- /* Drop and recreate. */
- /* If someone dropped it in the mean time, throw it away and don't touch it.
- * Otherwise, destruct it. */
- if (likely (font->data.coretext.cmpexch (const_cast<hb_coretext_font_data_t *> (data), nullptr)))
- _hb_coretext_shaper_font_data_destroy (const_cast<hb_coretext_font_data_t *> (data));
- else
- goto retry;
- }
- return font->data.coretext;
-}
-
/**
* hb_coretext_font_create:
* @ct_font: The CTFontRef to work upon
@@ -455,8 +424,8 @@ hb_coretext_font_create (CTFontRef ct_font)
CTFontRef
hb_coretext_font_get_ct_font (hb_font_t *font)
{
- const hb_coretext_font_data_t *data = hb_coretext_font_data_sync (font);
- return data ? (CTFontRef) data : nullptr;
+ CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext;
+ return ct_font ? (CTFontRef) ct_font : nullptr;
}
@@ -516,7 +485,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
{
hb_face_t *face = font->face;
CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
- CTFontRef ct_font = (CTFontRef) hb_coretext_font_data_sync (font);
+ CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext;
CGFloat ct_font_size = CTFontGetSize (ct_font);
CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
@@ -1106,7 +1075,8 @@ resize_and_retry:
advance = positions[j + 1].x - positions[j].x;
else /* last glyph */
advance = run_advance - (positions[j].x - positions[0].x);
- info->mask = round (advance * x_mult);
+ /* int cast necessary to pass through negative values. */
+ info->mask = (int) round (advance * x_mult);
info->var1.i32 = x_offset;
info->var2.i32 = round (positions[j].y * y_mult);
info++;
@@ -1122,7 +1092,8 @@ resize_and_retry:
advance = positions[j + 1].y - positions[j].y;
else /* last glyph */
advance = run_advance - (positions[j].y - positions[0].y);
- info->mask = round (advance * y_mult);
+ /* int cast necessary to pass through negative values. */
+ info->mask = (int) round (advance * y_mult);
info->var1.i32 = round (positions[j].x * x_mult);
info->var2.i32 = y_offset;
info++;
@@ -1151,7 +1122,7 @@ resize_and_retry:
pos->x_offset = info->var1.i32;
pos->y_offset = info->var2.i32;
- info++, pos++;
+ info++; pos++;
}
else
for (unsigned int i = 0; i < count; i++)
@@ -1160,7 +1131,7 @@ resize_and_retry:
pos->x_offset = info->var1.i32;
pos->y_offset = info->var2.i32;
- info++, pos++;
+ info++; pos++;
}
/* Fix up clusters so that we never return out-of-order indices;
@@ -1173,7 +1144,8 @@ resize_and_retry:
* This does *not* mean we'll form the same clusters as Uniscribe
* or the native OT backend, only that the cluster indices will be
* monotonic in the output buffer. */
- if (count > 1 && (status_or & kCTRunStatusNonMonotonic))
+ if (count > 1 && (status_or & kCTRunStatusNonMonotonic) &&
+ buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
{
hb_glyph_info_t *info = buffer->info;
if (HB_DIRECTION_IS_FORWARD (buffer->props.direction))
@@ -1197,6 +1169,10 @@ resize_and_retry:
}
}
+ /* TODO: Sometimes the above positioning code generates negative
+ * advance values. Fix them up. Example, with NotoNastaliqUrdu
+ * font and sequence ابهد. */
+
buffer->clear_glyph_flags ();
buffer->unsafe_to_break ();
diff --git a/thirdparty/harfbuzz/src/hb-cplusplus.hh b/thirdparty/harfbuzz/src/hb-cplusplus.hh
new file mode 100644
index 0000000000..86d0452080
--- /dev/null
+++ b/thirdparty/harfbuzz/src/hb-cplusplus.hh
@@ -0,0 +1,192 @@
+/*
+ * Copyright © 2022 Behdad Esfahbod
+ *
+ * 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.
+ */
+
+#ifndef HB_CPLUSPLUS_HH
+#define HB_CPLUSPLUS_HH
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+HB_END_DECLS
+
+#ifdef __cplusplus
+
+#include <functional>
+#include <utility>
+
+#if 0
+#if !(__cplusplus >= 201103L)
+#error "HarfBuzz C++ helpers require C++11"
+#endif
+#endif
+
+namespace hb {
+
+
+template <typename T>
+struct vtable;
+
+template <typename T>
+struct shared_ptr
+{
+ using element_type = T;
+
+ using v = vtable<T>;
+
+ explicit shared_ptr (T *p = nullptr) : p (p) {}
+ shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {}
+ shared_ptr (shared_ptr &&o) : p (o.p) { o.p = nullptr; }
+ shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; }
+ shared_ptr& operator = (shared_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
+ ~shared_ptr () { v::destroy (p); p = nullptr; }
+
+ T* get() const { return p; }
+
+ void swap (shared_ptr &o) { std::swap (p, o.p); }
+ friend void swap (shared_ptr &a, shared_ptr &b) { std::swap (a.p, b.p); }
+
+ operator T * () const { return p; }
+ T& operator * () const { return *get (); }
+ T* operator -> () const { return get (); }
+ operator bool () { return p; }
+ bool operator == (const shared_ptr &o) { return p == o.p; }
+ bool operator != (const shared_ptr &o) { return p != o.p; }
+
+ static T* get_empty() { return v::get_empty (); }
+ T* reference() { return v::reference (p); }
+ void destroy() { v::destroy (p); }
+ void set_user_data (hb_user_data_key_t *key,
+ void *value,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace) { v::set_user_data (p, key, value, destroy, replace); }
+ void * get_user_data (hb_user_data_key_t *key) { return v::get_user_data (p, key); }
+
+ private:
+ T *p;
+};
+
+template<typename T> struct is_shared_ptr : std::false_type {};
+template<typename T> struct is_shared_ptr<shared_ptr<T>> : std::true_type {};
+
+template <typename T>
+struct unique_ptr
+{
+ using element_type = T;
+
+ using v = vtable<T>;
+
+ explicit unique_ptr (T *p = nullptr) : p (p) {}
+ unique_ptr (const unique_ptr &o) = delete;
+ unique_ptr (unique_ptr &&o) : p (o.p) { o.p = nullptr; }
+ unique_ptr& operator = (const unique_ptr &o) = delete;
+ unique_ptr& operator = (unique_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
+ ~unique_ptr () { v::destroy (p); p = nullptr; }
+
+ T* get() const { return p; }
+ T* release () { T* v = p; p = nullptr; return v; }
+
+ void swap (unique_ptr &o) { std::swap (p, o.p); }
+ friend void swap (unique_ptr &a, unique_ptr &b) { std::swap (a.p, b.p); }
+
+ operator T * () const { return p; }
+ T& operator * () const { return *get (); }
+ T* operator -> () const { return get (); }
+ operator bool () { return p; }
+
+ private:
+ T *p;
+};
+
+template<typename T> struct is_unique_ptr : std::false_type {};
+template<typename T> struct is_unique_ptr<unique_ptr<T>> : std::true_type {};
+
+template <typename T,
+ T * (*_get_empty) (void),
+ T * (*_reference) (T *),
+ void (*_destroy) (T *),
+ hb_bool_t (*_set_user_data) (T *,
+ hb_user_data_key_t *,
+ void *,
+ hb_destroy_func_t,
+ hb_bool_t),
+ void * (*_get_user_data) (T *,
+ hb_user_data_key_t *)>
+struct vtable_t
+{
+ static constexpr auto get_empty = _get_empty;
+ static constexpr auto reference = _reference;
+ static constexpr auto destroy = _destroy;
+ static constexpr auto set_user_data = _set_user_data;
+ static constexpr auto get_user_data = _get_user_data;
+};
+
+#define HB_DEFINE_VTABLE(name) \
+ template<> \
+ struct vtable<hb_##name##_t> \
+ : vtable_t<hb_##name##_t, \
+ &hb_##name##_get_empty, \
+ &hb_##name##_reference, \
+ &hb_##name##_destroy, \
+ &hb_##name##_set_user_data, \
+ &hb_##name##_get_user_data> {}
+
+HB_DEFINE_VTABLE (buffer);
+HB_DEFINE_VTABLE (blob);
+HB_DEFINE_VTABLE (face);
+HB_DEFINE_VTABLE (font);
+HB_DEFINE_VTABLE (font_funcs);
+HB_DEFINE_VTABLE (map);
+HB_DEFINE_VTABLE (set);
+HB_DEFINE_VTABLE (shape_plan);
+HB_DEFINE_VTABLE (unicode_funcs);
+
+#undef HB_DEFINE_VTABLE
+
+
+} // namespace hb
+
+template<typename T>
+struct std::hash<hb::shared_ptr<T>>
+{
+ std::size_t operator()(const hb::shared_ptr<T>& v) const noexcept
+ {
+ std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
+ return h;
+ }
+};
+
+template<typename T>
+struct std::hash<hb::unique_ptr<T>>
+{
+ std::size_t operator()(const hb::unique_ptr<T>& v) const noexcept
+ {
+ std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
+ return h;
+ }
+};
+
+
+#endif /* __cplusplus */
+
+#endif /* HB_CPLUSPLUS_HH */
diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc
index f177ff31c0..ce04f5bab1 100644
--- a/thirdparty/harfbuzz/src/hb-directwrite.cc
+++ b/thirdparty/harfbuzz/src/hb-directwrite.cc
@@ -241,17 +241,12 @@ struct hb_directwrite_font_data_t {};
hb_directwrite_font_data_t *
_hb_directwrite_shaper_font_data_create (hb_font_t *font)
{
- hb_directwrite_font_data_t *data = new hb_directwrite_font_data_t;
- if (unlikely (!data))
- return nullptr;
-
- return data;
+ return (hb_directwrite_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
_hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data)
{
- delete data;
}
diff --git a/thirdparty/harfbuzz/src/hb-draw.cc b/thirdparty/harfbuzz/src/hb-draw.cc
index b31019b07e..fdc71102d6 100644
--- a/thirdparty/harfbuzz/src/hb-draw.cc
+++ b/thirdparty/harfbuzz/src/hb-draw.cc
@@ -56,12 +56,14 @@ hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data,
float to_x, float to_y,
void *user_data HB_UNUSED)
{
+#define HB_ONE_THIRD 0.33333333f
dfuncs->emit_cubic_to (draw_data, *st,
- (st->current_x + 2.f * control_x) / 3.f,
- (st->current_y + 2.f * control_y) / 3.f,
- (to_x + 2.f * control_x) / 3.f,
- (to_y + 2.f * control_y) / 3.f,
+ (st->current_x + 2.f * control_x) * HB_ONE_THIRD,
+ (st->current_y + 2.f * control_y) * HB_ONE_THIRD,
+ (to_x + 2.f * control_x) * HB_ONE_THIRD,
+ (to_y + 2.f * control_y) * HB_ONE_THIRD,
to_x, to_y);
+#undef HB_ONE_THIRD
}
static void
@@ -89,25 +91,46 @@ hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \
if (hb_object_is_immutable (dfuncs)) \
return; \
\
- if (dfuncs->destroy.name) \
- dfuncs->destroy.name (dfuncs->user_data.name); \
- \
- if (func) { \
- dfuncs->func.name = func; \
- dfuncs->user_data.name = user_data; \
- dfuncs->destroy.name = destroy; \
- } else { \
- dfuncs->func.name = hb_draw_##name##_nil; \
- dfuncs->user_data.name = nullptr; \
- dfuncs->destroy.name = nullptr; \
- } \
+ if (dfuncs->destroy && dfuncs->destroy->name) \
+ dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \
+ \
+ if (user_data && !dfuncs->user_data) \
+ { \
+ dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); \
+ if (unlikely (!dfuncs->user_data)) \
+ goto fail; \
+ } \
+ if (destroy && !dfuncs->destroy) \
+ { \
+ dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); \
+ if (unlikely (!dfuncs->destroy)) \
+ goto fail; \
+ } \
+ \
+ if (func) { \
+ dfuncs->func.name = func; \
+ if (dfuncs->user_data) \
+ dfuncs->user_data->name = user_data; \
+ if (dfuncs->destroy) \
+ dfuncs->destroy->name = destroy; \
+ } else { \
+ dfuncs->func.name = hb_draw_##name##_nil; \
+ if (dfuncs->user_data) \
+ dfuncs->user_data->name = nullptr; \
+ if (dfuncs->destroy) \
+ dfuncs->destroy->name = nullptr; \
+ } \
+ \
+fail: \
+ if (destroy) \
+ destroy (user_data); \
}
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT
/**
- * hb_draw_funcs_create: (Xconstructor)
+ * hb_draw_funcs_create:
*
* Creates a new draw callbacks object.
*
@@ -177,11 +200,13 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs)
{
if (!hb_object_destroy (dfuncs)) return;
+ if (dfuncs->destroy)
+ {
#define HB_DRAW_FUNC_IMPLEMENT(name) \
- if (dfuncs->destroy.name) dfuncs->destroy.name (dfuncs->user_data.name);
- HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
+ if (dfuncs->destroy->name) dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name);
+ HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT
-
+ }
hb_free (dfuncs);
}
diff --git a/thirdparty/harfbuzz/src/hb-draw.hh b/thirdparty/harfbuzz/src/hb-draw.hh
index 28bc9218e1..768f51a875 100644
--- a/thirdparty/harfbuzz/src/hb-draw.hh
+++ b/thirdparty/harfbuzz/src/hb-draw.hh
@@ -54,31 +54,31 @@ struct hb_draw_funcs_t
#define HB_DRAW_FUNC_IMPLEMENT(name) void *name;
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT
- } user_data;
+ } *user_data;
struct {
#define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT
- } destroy;
+ } *destroy;
void emit_move_to (void *draw_data, hb_draw_state_t &st,
float to_x, float to_y)
{ func.move_to (this, draw_data, &st,
to_x, to_y,
- user_data.move_to); }
+ !user_data ? nullptr : user_data->move_to); }
void emit_line_to (void *draw_data, hb_draw_state_t &st,
float to_x, float to_y)
{ func.line_to (this, draw_data, &st,
to_x, to_y,
- user_data.line_to); }
+ !user_data ? nullptr : user_data->line_to); }
void emit_quadratic_to (void *draw_data, hb_draw_state_t &st,
float control_x, float control_y,
float to_x, float to_y)
{ func.quadratic_to (this, draw_data, &st,
control_x, control_y,
to_x, to_y,
- user_data.quadratic_to); }
+ !user_data ? nullptr : user_data->quadratic_to); }
void emit_cubic_to (void *draw_data, hb_draw_state_t &st,
float control1_x, float control1_y,
float control2_x, float control2_y,
@@ -87,10 +87,10 @@ struct hb_draw_funcs_t
control1_x, control1_y,
control2_x, control2_y,
to_x, to_y,
- user_data.cubic_to); }
+ !user_data ? nullptr : user_data->cubic_to); }
void emit_close_path (void *draw_data, hb_draw_state_t &st)
{ func.close_path (this, draw_data, &st,
- user_data.close_path); }
+ !user_data ? nullptr : user_data->close_path); }
void move_to (void *draw_data, hb_draw_state_t &st,
diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc
index 5365598636..7cdd6cb49f 100644
--- a/thirdparty/harfbuzz/src/hb-face.cc
+++ b/thirdparty/harfbuzz/src/hb-face.cc
@@ -190,7 +190,7 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
}
/**
- * hb_face_create: (Xconstructor)
+ * hb_face_create:
* @blob: #hb_blob_t to work upon
* @index: The index of the face within @blob
*
@@ -342,7 +342,7 @@ hb_face_set_user_data (hb_face_t *face,
* Since: 0.9.2
**/
void *
-hb_face_get_user_data (const hb_face_t *face,
+hb_face_get_user_data (hb_face_t *face,
hb_user_data_key_t *key)
{
return hb_object_get_user_data (face, key);
diff --git a/thirdparty/harfbuzz/src/hb-face.h b/thirdparty/harfbuzz/src/hb-face.h
index 6ef2f8b886..3b7477a76c 100644
--- a/thirdparty/harfbuzz/src/hb-face.h
+++ b/thirdparty/harfbuzz/src/hb-face.h
@@ -96,7 +96,7 @@ hb_face_set_user_data (hb_face_t *face,
hb_bool_t replace);
HB_EXTERN void *
-hb_face_get_user_data (const hb_face_t *face,
+hb_face_get_user_data (hb_face_t *face,
hb_user_data_key_t *key);
HB_EXTERN void
diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc
index 5700e06271..8c4fe863b6 100644
--- a/thirdparty/harfbuzz/src/hb-font.cc
+++ b/thirdparty/harfbuzz/src/hb-font.cc
@@ -636,16 +636,8 @@ DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
{
HB_OBJECT_HEADER_STATIC,
- {
-#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
- },
- {
-#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
- },
+ nullptr,
+ nullptr,
{
{
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
@@ -658,16 +650,8 @@ DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
static const hb_font_funcs_t _hb_font_funcs_default = {
HB_OBJECT_HEADER_STATIC,
- {
-#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
- },
- {
-#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
- },
+ nullptr,
+ nullptr,
{
{
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default,
@@ -679,7 +663,7 @@ static const hb_font_funcs_t _hb_font_funcs_default = {
/**
- * hb_font_funcs_create: (Xconstructor)
+ * hb_font_funcs_create:
*
* Creates a new #hb_font_funcs_t structure of font functions.
*
@@ -746,10 +730,16 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
{
if (!hb_object_destroy (ffuncs)) return;
-#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
- ffuncs->destroy.name (ffuncs->user_data.name);
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+ if (ffuncs->destroy)
+ {
+#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy->name) \
+ ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name);
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
+ }
+
+ hb_free (ffuncs->destroy);
+ hb_free (ffuncs->user_data);
hb_free (ffuncs);
}
@@ -841,24 +831,50 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
hb_destroy_func_t destroy) \
{ \
if (hb_object_is_immutable (ffuncs)) \
+ goto fail; \
+ \
+ if (!func) \
{ \
if (destroy) \
destroy (user_data); \
- return; \
+ destroy = nullptr; \
+ user_data = nullptr; \
} \
\
- if (ffuncs->destroy.name) \
- ffuncs->destroy.name (ffuncs->user_data.name); \
+ if (ffuncs->destroy && ffuncs->destroy->name) \
+ ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \
+ \
+ if (user_data && !ffuncs->user_data) \
+ { \
+ ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); \
+ if (unlikely (!ffuncs->user_data)) \
+ goto fail; \
+ } \
+ if (destroy && !ffuncs->destroy) \
+ { \
+ ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); \
+ if (unlikely (!ffuncs->destroy)) \
+ goto fail; \
+ } \
\
if (func) { \
ffuncs->get.f.name = func; \
- ffuncs->user_data.name = user_data; \
- ffuncs->destroy.name = destroy; \
+ if (ffuncs->user_data) \
+ ffuncs->user_data->name = user_data; \
+ if (ffuncs->destroy) \
+ ffuncs->destroy->name = destroy; \
} else { \
ffuncs->get.f.name = hb_font_get_##name##_default; \
- ffuncs->user_data.name = nullptr; \
- ffuncs->destroy.name = nullptr; \
+ if (ffuncs->user_data) \
+ ffuncs->user_data->name = nullptr; \
+ if (ffuncs->destroy) \
+ ffuncs->destroy->name = nullptr; \
} \
+ return; \
+ \
+fail: \
+ if (destroy) \
+ destroy (user_data); \
}
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
@@ -1623,6 +1639,9 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
{
HB_OBJECT_HEADER_STATIC,
+ 0, /* serial */
+ 0, /* serial_coords */
+
nullptr, /* parent */
const_cast<hb_face_t *> (&_hb_Null_hb_face_t),
@@ -1630,6 +1649,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
1000, /* y_scale */
0., /* slant */
0., /* slant_xy; */
+ 1.f, /* x_multf */
+ 1.f, /* y_multf */
1<<16, /* x_mult */
1<<16, /* y_mult */
@@ -1662,14 +1683,15 @@ _hb_font_create (hb_face_t *face)
font->face = hb_face_reference (face);
font->klass = hb_font_funcs_get_empty ();
font->data.init0 (font);
- font->x_scale = font->y_scale = hb_face_get_upem (face);
+ font->x_scale = font->y_scale = face->get_upem ();
+ font->x_multf = font->y_multf = 1.f;
font->x_mult = font->y_mult = 1 << 16;
return font;
}
/**
- * hb_font_create: (Xconstructor)
+ * hb_font_create:
* @face: a face.
*
* Constructs a new font object from the specified face.
@@ -1715,6 +1737,8 @@ _hb_font_adopt_var_coords (hb_font_t *font,
font->coords = coords;
font->design_coords = design_coords;
font->num_coords = coords_length;
+
+ font->mults_changed (); // Easiest to call this to drop cached data
}
/**
@@ -1744,7 +1768,6 @@ 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;
font->ptem = parent->ptem;
@@ -1767,6 +1790,8 @@ hb_font_create_sub_font (hb_font_t *parent)
}
}
+ font->mults_changed ();
+
return font;
}
@@ -1852,6 +1877,9 @@ hb_font_set_user_data (hb_font_t *font,
hb_destroy_func_t destroy /* May be NULL. */,
hb_bool_t replace)
{
+ if (!hb_object_is_immutable (font))
+ font->serial++;
+
return hb_object_set_user_data (font, key, data, destroy, replace);
}
@@ -1911,6 +1939,45 @@ hb_font_is_immutable (hb_font_t *font)
}
/**
+ * hb_font_get_serial:
+ * @font: #hb_font_t to work upon
+ *
+ * Returns the internal serial number of the font. The serial
+ * number is increased every time a setting on the font is
+ * changed, using a setter function.
+ *
+ * Return value: serial number
+ *
+ * Since: 4.4.0.
+ **/
+unsigned int
+hb_font_get_serial (hb_font_t *font)
+{
+ return font->serial;
+}
+
+/**
+ * hb_font_changed:
+ * @font: #hb_font_t to work upon
+ *
+ * Notifies the @font that underlying font data has changed.
+ * This has the effect of increasing the serial as returned
+ * by hb_font_get_serial(), which invalidates internal caches.
+ *
+ * Since: 4.4.0.
+ **/
+void
+hb_font_changed (hb_font_t *font)
+{
+ if (hb_object_is_immutable (font))
+ return;
+
+ font->serial++;
+
+ font->mults_changed ();
+}
+
+/**
* hb_font_set_parent:
* @font: #hb_font_t to work upon
* @parent: The parent font object to assign
@@ -1926,6 +1993,11 @@ hb_font_set_parent (hb_font_t *font,
if (hb_object_is_immutable (font))
return;
+ if (parent == font->parent)
+ return;
+
+ font->serial++;
+
if (!parent)
parent = hb_font_get_empty ();
@@ -1968,6 +2040,11 @@ hb_font_set_face (hb_font_t *font,
if (hb_object_is_immutable (font))
return;
+ if (face == font->face)
+ return;
+
+ font->serial++;
+
if (unlikely (!face))
face = hb_face_get_empty ();
@@ -2022,6 +2099,8 @@ hb_font_set_funcs (hb_font_t *font,
return;
}
+ font->serial++;
+
if (font->destroy)
font->destroy (font->user_data);
@@ -2059,6 +2138,8 @@ hb_font_set_funcs_data (hb_font_t *font,
return;
}
+ font->serial++;
+
if (font->destroy)
font->destroy (font->user_data);
@@ -2085,6 +2166,11 @@ hb_font_set_scale (hb_font_t *font,
if (hb_object_is_immutable (font))
return;
+ if (font->x_scale == x_scale && font->y_scale == y_scale)
+ return;
+
+ font->serial++;
+
font->x_scale = x_scale;
font->y_scale = y_scale;
font->mults_changed ();
@@ -2127,6 +2213,11 @@ hb_font_set_ppem (hb_font_t *font,
if (hb_object_is_immutable (font))
return;
+ if (font->x_ppem == x_ppem && font->y_ppem == y_ppem)
+ return;
+
+ font->serial++;
+
font->x_ppem = x_ppem;
font->y_ppem = y_ppem;
}
@@ -2169,6 +2260,11 @@ hb_font_set_ptem (hb_font_t *font,
if (hb_object_is_immutable (font))
return;
+ if (font->ptem == ptem)
+ return;
+
+ font->serial++;
+
font->ptem = ptem;
}
@@ -2216,6 +2312,11 @@ hb_font_set_synthetic_slant (hb_font_t *font, float slant)
if (hb_object_is_immutable (font))
return;
+ if (font->slant == slant)
+ return;
+
+ font->serial++;
+
font->slant = slant;
font->mults_changed ();
}
@@ -2263,6 +2364,8 @@ hb_font_set_variations (hb_font_t *font,
if (hb_object_is_immutable (font))
return;
+ font->serial_coords = ++font->serial;
+
if (!variations_length)
{
hb_font_set_var_coords_normalized (font, nullptr, 0);
@@ -2322,6 +2425,8 @@ hb_font_set_var_coords_design (hb_font_t *font,
if (hb_object_is_immutable (font))
return;
+ font->serial_coords = ++font->serial;
+
int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
@@ -2355,6 +2460,8 @@ hb_font_set_var_named_instance (hb_font_t *font,
if (hb_object_is_immutable (font))
return;
+ font->serial_coords = ++font->serial;
+
unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr);
float *coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
@@ -2391,6 +2498,8 @@ hb_font_set_var_coords_normalized (hb_font_t *font,
if (hb_object_is_immutable (font))
return;
+ font->serial_coords = ++font->serial;
+
int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr;
diff --git a/thirdparty/harfbuzz/src/hb-font.h b/thirdparty/harfbuzz/src/hb-font.h
index 9548857535..ca6ecf7963 100644
--- a/thirdparty/harfbuzz/src/hb-font.h
+++ b/thirdparty/harfbuzz/src/hb-font.h
@@ -1002,6 +1002,12 @@ hb_font_make_immutable (hb_font_t *font);
HB_EXTERN hb_bool_t
hb_font_is_immutable (hb_font_t *font);
+HB_EXTERN unsigned int
+hb_font_get_serial (hb_font_t *font);
+
+HB_EXTERN void
+hb_font_changed (hb_font_t *font);
+
HB_EXTERN void
hb_font_set_parent (hb_font_t *font,
hb_font_t *parent);
diff --git a/thirdparty/harfbuzz/src/hb-font.hh b/thirdparty/harfbuzz/src/hb-font.hh
index 70311b4a85..bb402e23eb 100644
--- a/thirdparty/harfbuzz/src/hb-font.hh
+++ b/thirdparty/harfbuzz/src/hb-font.hh
@@ -68,13 +68,13 @@ struct hb_font_funcs_t
#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
- } user_data;
+ } *user_data;
struct {
#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
- } destroy;
+ } *destroy;
/* Don't access these directly. Call font->get_*() instead. */
union get_t {
@@ -104,6 +104,8 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_t);
struct hb_font_t
{
hb_object_header_t header;
+ unsigned int serial;
+ unsigned int serial_coords;
hb_font_t *parent;
hb_face_t *face;
@@ -112,6 +114,8 @@ struct hb_font_t
int32_t y_scale;
float slant;
float slant_xy;
+ float x_multf;
+ float y_multf;
int64_t x_mult;
int64_t y_mult;
@@ -137,12 +141,12 @@ struct hb_font_t
{ return HB_DIRECTION_IS_VERTICAL(direction) ? y_mult : x_mult; }
hb_position_t em_scale_x (int16_t v) { return em_mult (v, x_mult); }
hb_position_t em_scale_y (int16_t v) { return em_mult (v, y_mult); }
- hb_position_t em_scalef_x (float v) { return em_scalef (v, x_scale); }
- hb_position_t em_scalef_y (float v) { return em_scalef (v, y_scale); }
- float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); }
- float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); }
- float em_fscalef_x (float v) { return em_fscalef (v, x_scale); }
- float em_fscalef_y (float v) { return em_fscalef (v, y_scale); }
+ hb_position_t em_scalef_x (float v) { return em_multf (v, x_multf); }
+ hb_position_t em_scalef_y (float v) { return em_multf (v, y_multf); }
+ float em_fscale_x (int16_t v) { return em_fmult (v, x_multf); }
+ float em_fscale_y (int16_t v) { return em_fmult (v, y_multf); }
+ float em_fscalef_x (float v) { return em_fmultf (v, x_multf); }
+ float em_fscalef_y (float v) { return em_fmultf (v, y_multf); }
hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
{ return em_mult (v, dir_mult (direction)); }
@@ -205,14 +209,14 @@ struct hb_font_t
memset (extents, 0, sizeof (*extents));
return klass->get.f.font_h_extents (this, user_data,
extents,
- klass->user_data.font_h_extents);
+ !klass->user_data ? nullptr : klass->user_data->font_h_extents);
}
hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
{
memset (extents, 0, sizeof (*extents));
return klass->get.f.font_v_extents (this, user_data,
extents,
- klass->user_data.font_v_extents);
+ !klass->user_data ? nullptr : klass->user_data->font_v_extents);
}
bool has_glyph (hb_codepoint_t unicode)
@@ -228,7 +232,7 @@ struct hb_font_t
*glyph = not_found;
return klass->get.f.nominal_glyph (this, user_data,
unicode, glyph,
- klass->user_data.nominal_glyph);
+ !klass->user_data ? nullptr : klass->user_data->nominal_glyph);
}
unsigned int get_nominal_glyphs (unsigned int count,
const hb_codepoint_t *first_unicode,
@@ -240,7 +244,7 @@ struct hb_font_t
count,
first_unicode, unicode_stride,
first_glyph, glyph_stride,
- klass->user_data.nominal_glyphs);
+ !klass->user_data ? nullptr : klass->user_data->nominal_glyphs);
}
hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
@@ -250,21 +254,21 @@ struct hb_font_t
*glyph = not_found;
return klass->get.f.variation_glyph (this, user_data,
unicode, variation_selector, glyph,
- klass->user_data.variation_glyph);
+ !klass->user_data ? nullptr : klass->user_data->variation_glyph);
}
hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
{
return klass->get.f.glyph_h_advance (this, user_data,
glyph,
- klass->user_data.glyph_h_advance);
+ !klass->user_data ? nullptr : klass->user_data->glyph_h_advance);
}
hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
{
return klass->get.f.glyph_v_advance (this, user_data,
glyph,
- klass->user_data.glyph_v_advance);
+ !klass->user_data ? nullptr : klass->user_data->glyph_v_advance);
}
void get_glyph_h_advances (unsigned int count,
@@ -277,7 +281,7 @@ struct hb_font_t
count,
first_glyph, glyph_stride,
first_advance, advance_stride,
- klass->user_data.glyph_h_advances);
+ !klass->user_data ? nullptr : klass->user_data->glyph_h_advances);
}
void get_glyph_v_advances (unsigned int count,
@@ -290,7 +294,7 @@ struct hb_font_t
count,
first_glyph, glyph_stride,
first_advance, advance_stride,
- klass->user_data.glyph_v_advances);
+ !klass->user_data ? nullptr : klass->user_data->glyph_v_advances);
}
hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
@@ -299,7 +303,7 @@ struct hb_font_t
*x = *y = 0;
return klass->get.f.glyph_h_origin (this, user_data,
glyph, x, y,
- klass->user_data.glyph_h_origin);
+ !klass->user_data ? nullptr : klass->user_data->glyph_h_origin);
}
hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
@@ -308,7 +312,7 @@ struct hb_font_t
*x = *y = 0;
return klass->get.f.glyph_v_origin (this, user_data,
glyph, x, y,
- klass->user_data.glyph_v_origin);
+ !klass->user_data ? nullptr : klass->user_data->glyph_v_origin);
}
hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph,
@@ -319,7 +323,7 @@ struct hb_font_t
#else
return klass->get.f.glyph_h_kerning (this, user_data,
left_glyph, right_glyph,
- klass->user_data.glyph_h_kerning);
+ !klass->user_data ? nullptr : klass->user_data->glyph_h_kerning);
#endif
}
@@ -331,7 +335,7 @@ struct hb_font_t
#else
return klass->get.f.glyph_v_kerning (this, user_data,
top_glyph, bottom_glyph,
- klass->user_data.glyph_v_kerning);
+ !klass->user_data ? nullptr : klass->user_data->glyph_v_kerning);
#endif
}
@@ -342,7 +346,7 @@ struct hb_font_t
return klass->get.f.glyph_extents (this, user_data,
glyph,
extents,
- klass->user_data.glyph_extents);
+ !klass->user_data ? nullptr : klass->user_data->glyph_extents);
}
hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
@@ -352,7 +356,7 @@ struct hb_font_t
return klass->get.f.glyph_contour_point (this, user_data,
glyph, point_index,
x, y,
- klass->user_data.glyph_contour_point);
+ !klass->user_data ? nullptr : klass->user_data->glyph_contour_point);
}
hb_bool_t get_glyph_name (hb_codepoint_t glyph,
@@ -362,7 +366,7 @@ struct hb_font_t
return klass->get.f.glyph_name (this, user_data,
glyph,
name, size,
- klass->user_data.glyph_name);
+ !klass->user_data ? nullptr : klass->user_data->glyph_name);
}
hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
@@ -373,7 +377,7 @@ struct hb_font_t
return klass->get.f.glyph_from_name (this, user_data,
name, len,
glyph,
- klass->user_data.glyph_from_name);
+ !klass->user_data ? nullptr : klass->user_data->glyph_from_name);
}
void get_glyph_shape (hb_codepoint_t glyph,
@@ -382,7 +386,7 @@ struct hb_font_t
klass->get.f.glyph_shape (this, user_data,
glyph,
draw_funcs, draw_data,
- klass->user_data.glyph_shape);
+ !klass->user_data ? nullptr : klass->user_data->glyph_shape);
}
@@ -444,7 +448,6 @@ struct hb_font_t
{
*x = get_glyph_h_advance (glyph) / 2;
- /* TODO cache this somehow?! */
hb_font_extents_t extents;
get_h_extents_with_fallback (&extents);
*y = extents.ascender;
@@ -628,20 +631,26 @@ struct hb_font_t
void mults_changed ()
{
- signed upem = face->get_upem ();
- x_mult = ((int64_t) x_scale << 16) / upem;
- y_mult = ((int64_t) y_scale << 16) / upem;
+ float upem = face->get_upem ();
+ x_multf = x_scale / upem;
+ y_multf = y_scale / upem;
+ bool x_neg = x_scale < 0;
+ x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem;
+ bool y_neg = y_scale < 0;
+ y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem;
slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
+
+ data.fini ();
}
hb_position_t em_mult (int16_t v, int64_t mult)
{ return (hb_position_t) ((v * mult + 32768) >> 16); }
- hb_position_t em_scalef (float v, int scale)
- { return (hb_position_t) roundf (em_fscalef (v, scale)); }
- float em_fscalef (float v, int scale)
- { return v * scale / face->get_upem (); }
- float em_fscale (int16_t v, int scale)
- { return (float) v * scale / face->get_upem (); }
+ hb_position_t em_multf (float v, float mult)
+ { return (hb_position_t) roundf (em_fmultf (v, mult)); }
+ float em_fmultf (float v, float mult)
+ { return v * mult; }
+ float em_fmult (int16_t v, float mult)
+ { return (float) v * mult; }
};
DECLARE_NULL_INSTANCE (hb_font_t);
diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc
index d3c5d3db93..b526a82865 100644
--- a/thirdparty/harfbuzz/src/hb-ft.cc
+++ b/thirdparty/harfbuzz/src/hb-ft.cc
@@ -37,6 +37,8 @@
#include "hb-font.hh"
#include "hb-machinery.hh"
#include "hb-cache.hh"
+#include "hb-ot-os2-table.hh"
+#include "hb-ot-shaper-arabic-pua.hh"
#include FT_ADVANCES_H
#include FT_MULTIPLE_MASTERS_H
@@ -86,7 +88,7 @@ struct hb_ft_font_t
mutable hb_mutex_t lock;
FT_Face ft_face;
- mutable int cached_x_scale;
+ mutable unsigned cached_serial;
mutable hb_advance_cache_t advance_cache;
};
@@ -103,7 +105,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
- ft_font->cached_x_scale = 0;
+ ft_font->cached_serial = (unsigned) -1;
ft_font->advance_cache.init ();
return ft_font;
@@ -130,6 +132,58 @@ _hb_ft_font_destroy (void *data)
hb_free (ft_font);
}
+
+/* hb_font changed, update FT_Face. */
+static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face)
+{
+
+ FT_Set_Char_Size (ft_face,
+ abs (font->x_scale), abs (font->y_scale),
+ 0, 0);
+#if 0
+ font->x_ppem * 72 * 64 / font->x_scale,
+ font->y_ppem * 72 * 64 / font->y_scale);
+#endif
+ if (font->x_scale < 0 || font->y_scale < 0)
+ {
+ FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0,
+ 0, font->y_scale < 0 ? -1 : +1};
+ FT_Set_Transform (ft_face, &matrix, nullptr);
+ }
+
+#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR)
+ unsigned int num_coords;
+ const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
+ if (num_coords)
+ {
+ FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed));
+ if (ft_coords)
+ {
+ for (unsigned int i = 0; i < num_coords; i++)
+ ft_coords[i] = coords[i] * 4;
+ FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords);
+ hb_free (ft_coords);
+ }
+ }
+#endif
+}
+
+/* Check if hb_font changed, update FT_Face. */
+static inline bool
+_hb_ft_hb_font_check_changed (hb_font_t *font,
+ const hb_ft_font_t *ft_font)
+{
+ if (font->serial != ft_font->cached_serial)
+ {
+ _hb_ft_hb_font_changed (font, ft_font->ft_face);
+ ft_font->advance_cache.clear ();
+ ft_font->cached_serial = font->serial;
+ return true;
+ }
+ return false;
+}
+
+
/**
* hb_ft_font_set_load_flags:
* @font: #hb_font_t to work upon
@@ -181,7 +235,7 @@ hb_ft_font_get_load_flags (hb_font_t *font)
}
/**
- * hb_ft_font_get_face:
+ * hb_ft_font_get_face: (skip)
* @font: #hb_font_t to work upon
*
* Fetches the FT_Face associated with the specified #hb_font_t
@@ -203,7 +257,7 @@ hb_ft_font_get_face (hb_font_t *font)
}
/**
- * hb_ft_font_lock_face:
+ * hb_ft_font_lock_face: (skip)
* @font: #hb_font_t to work upon
*
* Gets the FT_Face associated with @font, This face will be kept around until
@@ -246,7 +300,7 @@ hb_ft_font_unlock_face (hb_font_t *font)
static hb_bool_t
-hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
+hb_ft_get_nominal_glyph (hb_font_t *font,
void *font_data,
hb_codepoint_t unicode,
hb_codepoint_t *glyph,
@@ -258,14 +312,29 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
if (unlikely (!g))
{
- if (unlikely (ft_font->symbol) && unicode <= 0x00FFu)
+ if (unlikely (ft_font->symbol))
{
- /* For symbol-encoded OpenType fonts, we duplicate the
- * U+F000..F0FF range at U+0000..U+00FF. That's what
- * Windows seems to do, and that's hinted about at:
- * https://docs.microsoft.com/en-us/typography/opentype/spec/recom
- * under "Non-Standard (Symbol) Fonts". */
- g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode);
+ switch ((unsigned) font->face->table.OS2->get_font_page ()) {
+ case OT::OS2::font_page_t::FONT_PAGE_NONE:
+ if (unicode <= 0x00FFu)
+ /* For symbol-encoded OpenType fonts, we duplicate the
+ * U+F000..F0FF range at U+0000..U+00FF. That's what
+ * Windows seems to do, and that's hinted about at:
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/recom
+ * under "Non-Standard (Symbol) Fonts". */
+ g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode);
+ break;
+#ifndef HB_NO_OT_SHAPER_ARABIC_FALLBACK
+ case OT::OS2::font_page_t::FONT_PAGE_SIMP_ARABIC:
+ g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_simp_map (unicode));
+ break;
+ case OT::OS2::font_page_t::FONT_PAGE_TRAD_ARABIC:
+ g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_trad_map (unicode));
+ break;
+#endif
+ default:
+ break;
+ }
if (!g)
return false;
}
@@ -337,12 +406,6 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
int load_flags = ft_font->load_flags;
int mult = font->x_scale < 0 ? -1 : +1;
- if (font->x_scale != ft_font->cached_x_scale)
- {
- ft_font->advance_cache.clear ();
- ft_font->cached_x_scale = font->x_scale;
- }
-
for (unsigned int i = 0; i < count; i++)
{
FT_Fixed v = 0;
@@ -426,6 +489,7 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+ hb_lock_t lock (ft_font->lock);
FT_Vector kerningv;
FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
@@ -556,6 +620,7 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
+
metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale);
metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale);
metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender);
@@ -619,6 +684,8 @@ hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED,
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
+ _hb_ft_hb_font_check_changed (font, ft_font);
+
if (unlikely (FT_Load_Glyph (ft_face, glyph,
FT_LOAD_NO_BITMAP | ft_font->load_flags)))
return;
@@ -964,6 +1031,31 @@ hb_ft_font_changed (hb_font_t *font)
}
/**
+ * hb_ft_hb_font_changed:
+ * @font: #hb_font_t to work upon
+ *
+ * Refreshes the state of the underlying FT_Face of @font when the hb_font_t
+ * @font has changed.
+ * This function should be called after changing the size or
+ * variation-axis settings on the @font.
+ * This call is fast if nothing has changed on @font.
+ *
+ * Return value: true if changed, false otherwise
+ *
+ * Since: 4.4.0
+ **/
+hb_bool_t
+hb_ft_hb_font_changed (hb_font_t *font)
+{
+ if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+ return false;
+
+ hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
+
+ return _hb_ft_hb_font_check_changed (font, ft_font);
+}
+
+/**
* hb_ft_font_create_referenced:
* @ft_face: FT_Face to work upon
*
@@ -1081,35 +1173,7 @@ hb_ft_font_set_funcs (hb_font_t *font)
if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL))
FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
- FT_Set_Char_Size (ft_face,
- abs (font->x_scale), abs (font->y_scale),
- 0, 0);
-#if 0
- font->x_ppem * 72 * 64 / font->x_scale,
- font->y_ppem * 72 * 64 / font->y_scale);
-#endif
- if (font->x_scale < 0 || font->y_scale < 0)
- {
- FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0,
- 0, font->y_scale < 0 ? -1 : +1};
- FT_Set_Transform (ft_face, &matrix, nullptr);
- }
-
-#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR)
- unsigned int num_coords;
- const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
- if (num_coords)
- {
- FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed));
- if (ft_coords)
- {
- for (unsigned int i = 0; i < num_coords; i++)
- ft_coords[i] = coords[i] * 4;
- FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords);
- hb_free (ft_coords);
- }
- }
-#endif
+ _hb_ft_hb_font_changed (font, ft_face);
ft_face->generic.data = blob;
ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
diff --git a/thirdparty/harfbuzz/src/hb-ft.h b/thirdparty/harfbuzz/src/hb-ft.h
index bf07115ab9..6a8a7abe8c 100644
--- a/thirdparty/harfbuzz/src/hb-ft.h
+++ b/thirdparty/harfbuzz/src/hb-ft.h
@@ -122,10 +122,17 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
HB_EXTERN int
hb_ft_font_get_load_flags (hb_font_t *font);
-/* Call when size or variations settings on underlying FT_Face change. */
+/* Call when size or variations settings on underlying FT_Face changed,
+ * and you want to update the hb_font_t from it. */
HB_EXTERN void
hb_ft_font_changed (hb_font_t *font);
+/* Call when size or variations settings on underlying hb_font_t may have
+ * changed, and you want to update the FT_Face from it. This call is fast
+ * if nothing changed on hb_font_t. Returns true if changed. */
+HB_EXTERN hb_bool_t
+hb_ft_hb_font_changed (hb_font_t *font);
+
/* Makes an hb_font_t use FreeType internally to implement font functions.
* Note: this internally creates an FT_Face. Use it when you create your
* hb_face_t using hb_face_create(). */
diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh
index 43a3098f65..d4461f166c 100644
--- a/thirdparty/harfbuzz/src/hb-iter.hh
+++ b/thirdparty/harfbuzz/src/hb-iter.hh
@@ -43,17 +43,12 @@
* is writable, then the iterator returns lvalues, otherwise it
* returns rvalues.
*
- * TODO Document more.
- *
- * If iterator implementation implements operator!=, then can be
+ * If iterator implementation implements operator!=, then it can be
* used in range-based for loop. That already happens if the iterator
* is random-access. Otherwise, the range-based for loop incurs
* one traversal to find end(), which can be avoided if written
* as a while-style for loop, or if iterator implements a faster
- * __end__() method.
- * TODO When opting in for C++17, address this by changing return
- * type of .end()?
- */
+ * __end__() method. */
/*
* Base classes for iterators.
@@ -75,10 +70,6 @@ struct hb_iter_t
iter_t* thiz () { return static_cast< iter_t *> (this); }
public:
- /* TODO:
- * Port operators below to use hb_enable_if to sniff which method implements
- * an operator and use it, and remove hb_iter_fallback_mixin_t completely. */
-
/* Operators. */
iter_t iter () const { return *thiz(); }
iter_t operator + () const { return *thiz(); }
@@ -87,8 +78,7 @@ struct hb_iter_t
explicit operator bool () const { return thiz()->__more__ (); }
unsigned len () const { return thiz()->__len__ (); }
/* The following can only be enabled if item_t is reference type. Otherwise
- * it will be returning pointer to temporary rvalue.
- * TODO Use a wrapper return type to fix for non-reference type. */
+ * it will be returning pointer to temporary rvalue. */
template <typename T = item_t,
hb_enable_if (std::is_reference<T>::value)>
hb_remove_reference<item_t>* operator -> () const { return std::addressof (**thiz()); }
diff --git a/thirdparty/harfbuzz/src/hb-machinery.hh b/thirdparty/harfbuzz/src/hb-machinery.hh
index e52a6a4124..ff2a99f5ed 100644
--- a/thirdparty/harfbuzz/src/hb-machinery.hh
+++ b/thirdparty/harfbuzz/src/hb-machinery.hh
@@ -176,7 +176,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
void init0 () {} /* Init, when memory is already set to 0. No-op for us. */
void init () { instance.set_relaxed (nullptr); }
- void fini () { do_destroy (instance.get ()); }
+ void fini () { do_destroy (instance.get ()); init (); }
void free_instance ()
{
diff --git a/thirdparty/harfbuzz/src/hb-map.cc b/thirdparty/harfbuzz/src/hb-map.cc
index 6c83c670c9..089615c72a 100644
--- a/thirdparty/harfbuzz/src/hb-map.cc
+++ b/thirdparty/harfbuzz/src/hb-map.cc
@@ -40,7 +40,7 @@
/**
- * hb_map_create: (Xconstructor)
+ * hb_map_create:
*
* Creates a new, initially empty map.
*
@@ -172,6 +172,25 @@ hb_map_allocation_successful (const hb_map_t *map)
return map->successful;
}
+/**
+ * hb_map_copy:
+ * @map: A map
+ *
+ * Allocate a copy of @map.
+ *
+ * Return value: Newly-allocated map.
+ *
+ * Since: 4.4.0
+ **/
+hb_map_t *
+hb_map_copy (const hb_map_t *map)
+{
+ hb_map_t *copy = hb_map_create ();
+ if (unlikely (!copy)) return nullptr;
+ copy->resize (map->population);
+ hb_copy (*map, *copy);
+ return copy;
+}
/**
* hb_map_set:
@@ -309,3 +328,20 @@ hb_map_is_equal (const hb_map_t *map,
return map->is_equal (*other);
}
+/**
+ * hb_map_hash:
+ * @map: A map
+ *
+ * Creates a hash representing @map.
+ *
+ * Return value:
+ * A hash of @map.
+ *
+ * Since: 4.4.0
+ **/
+HB_EXTERN unsigned int
+hb_map_hash (const hb_map_t *map)
+{
+ return map->hash ();
+}
+
diff --git a/thirdparty/harfbuzz/src/hb-map.h b/thirdparty/harfbuzz/src/hb-map.h
index 3f67c50b92..41d877d6a1 100644
--- a/thirdparty/harfbuzz/src/hb-map.h
+++ b/thirdparty/harfbuzz/src/hb-map.h
@@ -82,6 +82,9 @@ hb_map_get_user_data (hb_map_t *map,
HB_EXTERN hb_bool_t
hb_map_allocation_successful (const hb_map_t *map);
+HB_EXTERN hb_map_t *
+hb_map_copy (const hb_map_t *map);
+
HB_EXTERN void
hb_map_clear (hb_map_t *map);
@@ -95,6 +98,9 @@ HB_EXTERN hb_bool_t
hb_map_is_equal (const hb_map_t *map,
const hb_map_t *other);
+HB_EXTERN unsigned int
+hb_map_hash (const hb_map_t *map);
+
HB_EXTERN void
hb_map_set (hb_map_t *map,
hb_codepoint_t key,
diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh
index aec7d87f42..5efad8d20c 100644
--- a/thirdparty/harfbuzz/src/hb-map.hh
+++ b/thirdparty/harfbuzz/src/hb-map.hh
@@ -34,15 +34,13 @@
* hb_hashmap_t
*/
+extern HB_INTERNAL const hb_codepoint_t minus_1;
+
template <typename K, typename V,
- typename k_invalid_t = K,
- typename v_invalid_t = V,
- 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>
+ bool minus_one = false>
struct hb_hashmap_t
{
hb_hashmap_t () { init (); }
- hb_hashmap_t (std::nullptr_t) : hb_hashmap_t () {}
~hb_hashmap_t () { fini (); }
hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (population); hb_copy (o, *this); }
@@ -68,38 +66,44 @@ struct hb_hashmap_t
struct item_t
{
K key;
+ uint32_t hash : 30;
+ uint32_t is_used_ : 1;
+ uint32_t is_tombstone_ : 1;
V value;
- uint32_t hash;
+
+ bool is_used () const { return is_used_; }
+ void set_used (bool is_used) { is_used_ = is_used; }
+ bool is_tombstone () const { return is_tombstone_; }
+ void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
+ bool is_real () const { return is_used_ && !is_tombstone_; }
+
+ template <bool v = minus_one,
+ hb_enable_if (v == false)>
+ static inline const V& default_value () { return Null(V); };
+ template <bool v = minus_one,
+ hb_enable_if (v == true)>
+ static inline const V& default_value ()
+ {
+ static_assert (hb_is_same (V, hb_codepoint_t), "");
+ return minus_1;
+ };
void clear ()
{
new (std::addressof (key)) K ();
- key = hb_coerce<K> (kINVALID);
new (std::addressof (value)) V ();
- value = hb_coerce<V> (vINVALID);
hash = 0;
+ is_used_ = false;
+ is_tombstone_ = false;
}
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
- {
- 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); }
+ hb_pair_t<const K &, const V &> get_pair_ref() const { return hb_pair_t<const K &, const V &> (key, value); }
+
+ uint32_t total_hash () const
+ { return (hash * 31) + hb_hash (value); }
};
hb_object_header_t header;
@@ -200,27 +204,39 @@ struct hb_hashmap_t
return true;
}
- bool set (K key, const V& value) { return set_with_hash (key, hb_hash (key), value); }
- bool set (K key, V&& value) { return set_with_hash (key, hb_hash (key), std::move (value)); }
+ template <typename VV>
+ bool set (K key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); }
- V get (K key) const
+ const V& get (K key) const
{
- if (unlikely (!items)) return hb_coerce<V> (vINVALID);
+ if (unlikely (!items)) return item_t::default_value ();
unsigned int i = bucket_for (key);
- return items[i].is_real () && items[i] == key ? items[i].value : hb_coerce<V> (vINVALID);
+ return items[i].is_real () && items[i] == key ? items[i].value : item_t::default_value ();
}
- void del (K key) { set (key, hb_coerce<V> (vINVALID)); }
+ void del (K key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
/* Has interface. */
- typedef V value_t;
+ typedef const V& value_t;
value_t operator [] (K k) const { return get (k); }
- bool has (K k, V *vp = nullptr) const
+ bool has (K key, const V **vp = nullptr) const
{
- V v = (*this)[k];
- if (vp) *vp = v;
- const V vinv = hb_coerce<V> (vINVALID);
- return v != vinv;
+ if (unlikely (!items))
+ {
+ if (vp) *vp = &item_t::default_value ();
+ return false;
+ }
+ unsigned int i = bucket_for (key);
+ if (items[i].is_real () && items[i] == key)
+ {
+ if (vp) *vp = &items[i].value;
+ return true;
+ }
+ else
+ {
+ if (vp) *vp = &item_t::default_value ();
+ return false;
+ }
}
/* Projection. */
V operator () (K k) const { return get (k); }
@@ -242,8 +258,9 @@ struct hb_hashmap_t
uint32_t hash () const
{
uint32_t h = 0;
- for (auto pair : iter ())
- h ^= (hb_hash (pair.first) * 31) + hb_hash (pair.second);
+ for (const auto &item : + hb_array (items, mask ? mask + 1 : 0)
+ | hb_filter (&item_t::is_real))
+ h ^= item.total_hash ();
return h;
}
@@ -271,6 +288,12 @@ struct hb_hashmap_t
| hb_filter (&item_t::is_real)
| hb_map (&item_t::get_pair)
)
+ auto iter_ref () const HB_AUTO_RETURN
+ (
+ + hb_array (items, mask ? mask + 1 : 0)
+ | hb_filter (&item_t::is_real)
+ | hb_map (&item_t::get_pair_ref)
+ )
auto keys () const HB_AUTO_RETURN
(
+ hb_array (items, mask ? mask + 1 : 0)
@@ -293,19 +316,16 @@ struct hb_hashmap_t
protected:
template <typename VV>
- bool set_with_hash (K key, uint32_t hash, VV&& value)
+ bool set_with_hash (K key, uint32_t hash, VV&& value, bool is_delete=false)
{
if (unlikely (!successful)) return false;
- 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);
- const V vinv = hb_coerce<V> (vINVALID);
- if (value == vinv && items[i].key != key)
+ if (is_delete && items[i].key != key)
return true; /* Trying to delete non-existent key. */
- if (!items[i].is_unused ())
+ if (items[i].is_used ())
{
occupancy--;
if (!items[i].is_tombstone ())
@@ -313,27 +333,30 @@ struct hb_hashmap_t
}
items[i].key = key;
- items[i].value = value;
+ items[i].value = std::forward<VV> (value);
items[i].hash = hash;
+ items[i].set_used (true);
+ items[i].set_tombstone (is_delete);
occupancy++;
- if (!items[i].is_tombstone ())
+ if (!is_delete)
population++;
return true;
}
- unsigned int bucket_for (K key) const
+ unsigned int bucket_for (const K &key) const
{
return bucket_for_hash (key, hb_hash (key));
}
- unsigned int bucket_for_hash (K key, uint32_t hash) const
+ unsigned int bucket_for_hash (const K &key, uint32_t hash) const
{
+ hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
unsigned int i = hash % prime;
unsigned int step = 0;
unsigned int tombstone = (unsigned) -1;
- while (!items[i].is_unused ())
+ while (items[i].is_used ())
{
if (items[i].hash == hash && items[i] == key)
return i;
@@ -402,21 +425,14 @@ struct hb_hashmap_t
struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t,
- hb_codepoint_t,
- hb_codepoint_t,
- HB_MAP_VALUE_INVALID,
- HB_MAP_VALUE_INVALID>
+ true>
{
using hashmap = hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t,
- hb_codepoint_t,
- hb_codepoint_t,
- HB_MAP_VALUE_INVALID,
- HB_MAP_VALUE_INVALID>;
+ true>;
~hb_map_t () = default;
hb_map_t () : hashmap () {}
- hb_map_t (std::nullptr_t) : hb_map_t () {}
hb_map_t (const hb_map_t &o) : hashmap ((hashmap &) o) {}
hb_map_t (hb_map_t &&o) : hashmap (std::move ((hashmap &) o)) {}
hb_map_t& operator= (const hb_map_t&) = default;
diff --git a/thirdparty/harfbuzz/src/hb-meta.hh b/thirdparty/harfbuzz/src/hb-meta.hh
index 90757d38ac..e97d790fc3 100644
--- a/thirdparty/harfbuzz/src/hb-meta.hh
+++ b/thirdparty/harfbuzz/src/hb-meta.hh
@@ -188,7 +188,7 @@ template <> struct hb_int_max<signed long long> : hb_integral_constant<signed l
template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigned long long, ULLONG_MAX> {};
#define hb_int_max(T) hb_int_max<T>::value
-#if __GNUG__ && __GNUC__ < 5
+#if defined(__GNUC__) && __GNUC__ < 5
#define hb_is_trivially_copyable(T) __has_trivial_copy(T)
#define hb_is_trivially_copy_assignable(T) __has_trivial_assign(T)
#define hb_is_trivially_constructible(T) __has_trivial_constructor(T)
diff --git a/thirdparty/harfbuzz/src/hb-null.hh b/thirdparty/harfbuzz/src/hb-null.hh
index db38a4dfd2..78eb6474d5 100644
--- a/thirdparty/harfbuzz/src/hb-null.hh
+++ b/thirdparty/harfbuzz/src/hb-null.hh
@@ -37,7 +37,7 @@
/* Global nul-content Null pool. Enlarge as necessary. */
-#define HB_NULL_POOL_SIZE 384
+#define HB_NULL_POOL_SIZE 448
/* Use SFINAE to sniff whether T has min_size; in which case return the larger
* of sizeof(T) and T::null_size, otherwise return sizeof(T).
@@ -108,7 +108,7 @@ struct NullHelper
/* Specializations for arbitrary-content Null objects expressed in bytes. */
#define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \
} /* Close namespace. */ \
- extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]; \
+ extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[hb_null_size (Namespace::Type)]; \
template <> \
struct Null<Namespace::Type> { \
static Namespace::Type const & get_null () { \
@@ -118,7 +118,7 @@ struct NullHelper
namespace Namespace { \
static_assert (true, "") /* Require semicolon after. */
#define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \
- const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]
+ const unsigned char _hb_Null_##Namespace##_##Type[hb_null_size (Namespace::Type)]
/* Specializations for arbitrary-content Null objects expressed as struct initializer. */
#define DECLARE_NULL_INSTANCE(Type) \
diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
index b5047002ac..4aa337f78b 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
@@ -406,6 +406,8 @@ struct Charset1_2 {
void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
{
hb_codepoint_t gid = 1;
+ if (gid >= num_glyphs)
+ return;
for (unsigned i = 0;; i++)
{
hb_codepoint_t sid = ranges[i].first;
@@ -1138,7 +1140,8 @@ struct cff1
cff1_top_dict_interp_env_t env (fontDictStr);
cff1_font_dict_interpreter_t font_interp (env);
font = fontDicts.push ();
- if (unlikely (font == &Crap (cff1_font_dict_values_t))) { fini (); return; }
+ if (unlikely (fontDicts.in_error ())) { fini (); return; }
+
font->init ();
if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
PRIVDICTVAL *priv = &privateDicts[i];
@@ -1333,7 +1336,7 @@ struct cff1
if (names)
{
names->fini ();
- free (names);
+ hb_free (names);
}
SUPER::fini ();
@@ -1379,7 +1382,7 @@ struct cff1
hb_sorted_vector_t<gname_t> *names = glyph_names.get ();
if (unlikely (!names))
{
- names = (hb_sorted_vector_t<gname_t> *) calloc (sizeof (hb_sorted_vector_t<gname_t>), 1);
+ names = (hb_sorted_vector_t<gname_t> *) hb_calloc (sizeof (hb_sorted_vector_t<gname_t>), 1);
if (likely (names))
{
names->init ();
@@ -1409,14 +1412,14 @@ struct cff1
if (names)
{
names->fini ();
- free (names);
+ hb_free (names);
}
goto retry;
}
- }
+ }
gname_t key = { hb_bytes_t (name, len), 0 };
- const gname_t *gname = glyph_names->bsearch (key);
+ const gname_t *gname = names ? names->bsearch (key) : nullptr;
if (!gname) return false;
hb_codepoint_t gid = sid_to_glyph (gname->sid);
if (!gid && gname->sid) return false;
diff --git a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
index 7e96d9c8b3..09c9fe93f3 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
@@ -27,6 +27,8 @@
#ifndef HB_OT_CMAP_TABLE_HH
#define HB_OT_CMAP_TABLE_HH
+#include "hb-ot-os2-table.hh"
+#include "hb-ot-shaper-arabic-pua.hh"
#include "hb-open-type.hh"
#include "hb-set.hh"
@@ -1476,33 +1478,47 @@ struct SubtableUnicodesCache {
private:
const void* base;
- hb_hashmap_t<intptr_t, hb_set_t*> cached_unicodes;
+ hb_hashmap_t<intptr_t, hb::unique_ptr<hb_set_t>> cached_unicodes;
public:
SubtableUnicodesCache(const void* cmap_base)
: base(cmap_base), cached_unicodes() {}
- ~SubtableUnicodesCache()
- {
- for (hb_set_t* s : cached_unicodes.values()) {
- hb_set_destroy (s);
- }
- }
- hb_set_t* set_for(const EncodingRecord* record)
+ hb_set_t* set_for (const EncodingRecord* record)
{
- if (!cached_unicodes.has ((intptr_t) record)) {
- hb_set_t* new_set = hb_set_create ();
- if (!cached_unicodes.set ((intptr_t) record, new_set)) {
- hb_set_destroy (new_set);
+ if (!cached_unicodes.has ((intptr_t) record))
+ {
+ hb_set_t *s = hb_set_create ();
+ if (unlikely (s->in_error ()))
+ return hb_set_get_empty ();
+
+ (base+record->subtable).collect_unicodes (s);
+
+ if (unlikely (!cached_unicodes.set ((intptr_t) record, hb::unique_ptr<hb_set_t> {s})))
return hb_set_get_empty ();
- }
- (base+record->subtable).collect_unicodes (cached_unicodes.get ((intptr_t) record));
+
+ return s;
}
return cached_unicodes.get ((intptr_t) record);
}
};
+static inline uint_fast16_t
+_hb_symbol_pua_map (unsigned codepoint)
+{
+ if (codepoint <= 0x00FFu)
+ {
+ /* For symbol-encoded OpenType fonts, we duplicate the
+ * U+F000..F0FF range at U+0000..U+00FF. That's what
+ * Windows seems to do, and that's hinted about at:
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/recom
+ * under "Non-Standard (Symbol) Fonts". */
+ return 0xF000u + codepoint;
+ }
+ return 0;
+}
+
struct cmap
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap;
@@ -1726,7 +1742,24 @@ struct cmap
this->get_glyph_data = subtable;
if (unlikely (symbol))
- this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>;
+ {
+ switch ((unsigned) face->table.OS2->get_font_page ()) {
+ case OS2::font_page_t::FONT_PAGE_NONE:
+ this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable, _hb_symbol_pua_map>;
+ break;
+#ifndef HB_NO_OT_SHAPER_ARABIC_FALLBACK
+ case OS2::font_page_t::FONT_PAGE_SIMP_ARABIC:
+ this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable, _hb_arabic_pua_simp_map>;
+ break;
+ case OS2::font_page_t::FONT_PAGE_TRAD_ARABIC:
+ this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable, _hb_arabic_pua_trad_map>;
+ break;
+#endif
+ default:
+ this->get_glyph_funcZ = get_glyph_from<CmapSubtable>;
+ break;
+ }
+ }
else
{
switch (subtable->u.format) {
@@ -1808,6 +1841,7 @@ struct cmap
typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
hb_codepoint_t codepoint,
hb_codepoint_t *glyph);
+ typedef uint_fast16_t (*hb_pua_remap_func_t) (unsigned);
template <typename Type>
HB_INTERNAL static bool get_glyph_from (const void *obj,
@@ -1818,7 +1852,7 @@ struct cmap
return typed_obj->get_glyph (codepoint, glyph);
}
- template <typename Type>
+ template <typename Type, hb_pua_remap_func_t remap>
HB_INTERNAL static bool get_glyph_from_symbol (const void *obj,
hb_codepoint_t codepoint,
hb_codepoint_t *glyph)
@@ -1827,15 +1861,8 @@ struct cmap
if (likely (typed_obj->get_glyph (codepoint, glyph)))
return true;
- if (codepoint <= 0x00FFu)
- {
- /* For symbol-encoded OpenType fonts, we duplicate the
- * U+F000..F0FF range at U+0000..U+00FF. That's what
- * Windows seems to do, and that's hinted about at:
- * https://docs.microsoft.com/en-us/typography/opentype/spec/recom
- * under "Non-Standard (Symbol) Fonts". */
- return typed_obj->get_glyph (0xF000u + codepoint, glyph);
- }
+ if (hb_codepoint_t c = remap (codepoint))
+ return typed_obj->get_glyph (c, glyph);
return false;
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-cpal-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-cpal-table.hh
index 24476eda17..bcab77f79d 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-cpal-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-cpal-table.hh
@@ -97,9 +97,10 @@ struct CPALV1Tail
c->push ();
for (const auto _ : colorLabels)
{
- if (!color_index_map->has (_)) continue;
+ const hb_codepoint_t *v;
+ if (!color_index_map->has (_, &v)) continue;
NameID new_color_idx;
- new_color_idx = color_index_map->get (_);
+ new_color_idx = *v;
if (!c->copy<NameID> (new_color_idx))
{
c->pop_discard ();
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh
index 9741ebd450..d0e2235fb2 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh
@@ -298,6 +298,12 @@ struct sbix
const PNGHeader &png = *blob->as<PNGHeader>();
+ if (png.IHDR.height >= 65536 || png.IHDR.width >= 65536)
+ {
+ hb_blob_destroy (blob);
+ return false;
+ }
+
extents->x_bearing = x_offset;
extents->y_bearing = png.IHDR.height + y_offset;
extents->width = png.IHDR.width;
diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc
index 0f44ee4d5f..af1bc86d48 100644
--- a/thirdparty/harfbuzz/src/hb-ot-font.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-font.cc
@@ -30,6 +30,7 @@
#include "hb-ot.h"
+#include "hb-cache.hh"
#include "hb-font.hh"
#include "hb-machinery.hh"
#include "hb-ot-face.hh"
@@ -58,6 +59,41 @@
* never need to call these functions directly.
**/
+struct hb_ot_font_t
+{
+ const hb_ot_face_t *ot_face;
+
+ /* h_advance caching */
+ mutable hb_atomic_int_t cached_coords_serial;
+ mutable hb_atomic_ptr_t<hb_advance_cache_t> advance_cache;
+};
+
+static hb_ot_font_t *
+_hb_ot_font_create (hb_font_t *font)
+{
+ hb_ot_font_t *ot_font = (hb_ot_font_t *) hb_calloc (1, sizeof (hb_ot_font_t));
+ if (unlikely (!ot_font))
+ return nullptr;
+
+ ot_font->ot_face = &font->face->table;
+
+ return ot_font;
+}
+
+static void
+_hb_ot_font_destroy (void *font_data)
+{
+ hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data;
+
+ auto *cache = ot_font->advance_cache.get_relaxed ();
+ if (cache)
+ {
+ cache->fini ();
+ hb_free (cache);
+ }
+
+ hb_free (ot_font);
+}
static hb_bool_t
hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
@@ -66,7 +102,8 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ const hb_ot_face_t *ot_face = ot_font->ot_face;
return ot_face->cmap->get_nominal_glyph (unicode, glyph);
}
@@ -80,7 +117,8 @@ hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
unsigned int glyph_stride,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ const hb_ot_face_t *ot_face = ot_font->ot_face;
return ot_face->cmap->get_nominal_glyphs (count,
first_unicode, unicode_stride,
first_glyph, glyph_stride);
@@ -94,7 +132,8 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ const hb_ot_face_t *ot_face = ot_font->ot_face;
return ot_face->cmap->get_variation_glyph (unicode, variation_selector, glyph);
}
@@ -107,15 +146,83 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
unsigned advance_stride,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ const hb_ot_face_t *ot_face = ot_font->ot_face;
const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
- for (unsigned int i = 0; i < count; i++)
+#ifndef HB_NO_VAR
+ const OT::HVARVVAR &HVAR = *hmtx.var_table;
+ const OT::VariationStore &varStore = &HVAR + HVAR.varStore;
+ OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr;
+
+ bool use_cache = font->num_coords;
+#else
+ OT::VariationStore::cache_t *varStore_cache = nullptr;
+ bool use_cache = false;
+#endif
+
+ hb_advance_cache_t *cache = nullptr;
+ if (use_cache)
{
- *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font));
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
+ retry:
+ cache = ot_font->advance_cache.get ();
+ if (unlikely (!cache))
+ {
+ cache = (hb_advance_cache_t *) hb_malloc (sizeof (hb_advance_cache_t));
+ if (unlikely (!cache))
+ {
+ use_cache = false;
+ goto out;
+ }
+
+ cache->init ();
+ if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache)))
+ {
+ hb_free (cache);
+ goto retry;
+ }
+ ot_font->cached_coords_serial.set (font->serial_coords);
+ }
+ }
+ out:
+
+ if (!use_cache)
+ {
+ for (unsigned int i = 0; i < count; i++)
+ {
+ *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font, varStore_cache));
+ first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
+ first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
+ }
}
+ else
+ { /* Use cache. */
+ if (ot_font->cached_coords_serial.get () != (int) font->serial_coords)
+ {
+ ot_font->advance_cache->init ();
+ ot_font->cached_coords_serial.set (font->serial_coords);
+ }
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ hb_position_t v;
+ unsigned cv;
+ if (ot_font->advance_cache->get (*first_glyph, &cv))
+ v = cv;
+ else
+ {
+ v = hmtx.get_advance (*first_glyph, font, varStore_cache);
+ ot_font->advance_cache->set (*first_glyph, v);
+ }
+ *first_advance = font->em_scale_x (v);
+ first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
+ first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
+ }
+ }
+
+#ifndef HB_NO_VAR
+ OT::VariationStore::destroy_cache (varStore_cache);
+#endif
}
#ifndef HB_NO_VERTICAL
@@ -128,16 +235,31 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
unsigned advance_stride,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ const hb_ot_face_t *ot_face = ot_font->ot_face;
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
if (vmtx.has_data ())
+ {
+#ifndef HB_NO_VAR
+ const OT::HVARVVAR &VVAR = *vmtx.var_table;
+ const OT::VariationStore &varStore = &VVAR + VVAR.varStore;
+ OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr;
+#else
+ OT::VariationStore::cache_t *varStore_cache = nullptr;
+#endif
+
for (unsigned int i = 0; i < count; i++)
{
- *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font));
+ *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font, varStore_cache));
first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
}
+
+#ifndef HB_NO_VAR
+ OT::VariationStore::destroy_cache (varStore_cache);
+#endif
+ }
else
{
hb_font_extents_t font_extents;
@@ -163,7 +285,8 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
hb_position_t *y,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ const hb_ot_face_t *ot_face = ot_font->ot_face;
*x = font->get_glyph_h_advance (glyph) / 2;
@@ -208,7 +331,8 @@ hb_ot_get_glyph_extents (hb_font_t *font,
hb_glyph_extents_t *extents,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ const hb_ot_face_t *ot_face = ot_font->ot_face;
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
@@ -234,7 +358,9 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
char *name, unsigned int size,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ const hb_ot_face_t *ot_face = ot_font->ot_face;
+
if (ot_face->post->get_glyph_name (glyph, name, size)) return true;
#ifndef HB_NO_OT_FONT_CFF
if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true;
@@ -248,7 +374,9 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ const hb_ot_face_t *ot_face = ot_font->ot_face;
+
if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true;
#ifndef HB_NO_OT_FONT_CFF
if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true;
@@ -364,10 +492,14 @@ _hb_ot_get_font_funcs ()
void
hb_ot_font_set_funcs (hb_font_t *font)
{
+ hb_ot_font_t *ot_font = _hb_ot_font_create (font);
+ if (unlikely (!ot_font))
+ return;
+
hb_font_set_funcs (font,
_hb_ot_get_font_funcs (),
- &font->face->table,
- nullptr);
+ ot_font,
+ _hb_ot_font_destroy);
}
#ifndef HB_NO_VAR
diff --git a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
index 866bb7e04c..c32ff7636d 100644
--- a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
@@ -30,1334 +30,6 @@
#ifndef HB_OT_GLYF_TABLE_HH
#define HB_OT_GLYF_TABLE_HH
-#include "hb-open-type.hh"
-#include "hb-ot-head-table.hh"
-#include "hb-ot-hmtx-table.hh"
-#include "hb-ot-var-gvar-table.hh"
-#include "hb-draw.hh"
-
-namespace OT {
-
-
-/*
- * loca -- Index to Location
- * https://docs.microsoft.com/en-us/typography/opentype/spec/loca
- */
-#define HB_OT_TAG_loca HB_TAG('l','o','c','a')
-
-#ifndef HB_MAX_COMPOSITE_OPERATIONS
-#define HB_MAX_COMPOSITE_OPERATIONS 100000
-#endif
-
-
-struct loca
-{
- friend struct glyf;
-
- static constexpr hb_tag_t tableTag = HB_OT_TAG_loca;
-
- bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
- {
- TRACE_SANITIZE (this);
- return_trace (true);
- }
-
- protected:
- UnsizedArrayOf<HBUINT8>
- dataZ; /* Location data. */
- public:
- DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
- * check the size externally, allow Null() object of it by
- * defining it _MIN instead. */
-};
-
-
-/*
- * glyf -- TrueType Glyph Data
- * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf
- */
-#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
-
-
-struct glyf
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf;
-
- bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
- {
- TRACE_SANITIZE (this);
- /* Runtime checks as eager sanitizing each glyph is costy */
- return_trace (true);
- }
-
- template<typename Iterator,
- hb_requires (hb_is_source_of (Iterator, unsigned int))>
- static bool
- _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca)
- {
- unsigned num_offsets = padded_offsets.len () + 1;
- unsigned entry_size = use_short_loca ? 2 : 4;
- char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets);
-
- if (unlikely (!loca_prime_data)) return false;
-
- DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d",
- entry_size, num_offsets, entry_size * num_offsets);
-
- if (use_short_loca)
- _write_loca (padded_offsets, 1, hb_array ((HBUINT16 *) loca_prime_data, num_offsets));
- else
- _write_loca (padded_offsets, 0, hb_array ((HBUINT32 *) loca_prime_data, num_offsets));
-
- hb_blob_t *loca_blob = hb_blob_create (loca_prime_data,
- entry_size * num_offsets,
- HB_MEMORY_MODE_WRITABLE,
- loca_prime_data,
- hb_free);
-
- bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
- && _add_head_and_set_loca_version (plan, use_short_loca);
-
- hb_blob_destroy (loca_blob);
- return result;
- }
-
- template<typename IteratorIn, typename IteratorOut,
- hb_requires (hb_is_source_of (IteratorIn, unsigned int)),
- hb_requires (hb_is_sink_of (IteratorOut, unsigned))>
- static void
- _write_loca (IteratorIn it, unsigned right_shift, IteratorOut dest)
- {
- unsigned int offset = 0;
- dest << 0;
- + it
- | hb_map ([=, &offset] (unsigned int padded_size)
- {
- offset += padded_size;
- DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset);
- return offset >> right_shift;
- })
- | hb_sink (dest)
- ;
- }
-
- /* requires source of SubsetGlyph complains the identifier isn't declared */
- template <typename Iterator>
- bool serialize (hb_serialize_context_t *c,
- Iterator it,
- bool use_short_loca,
- const hb_subset_plan_t *plan)
- {
- TRACE_SERIALIZE (this);
- unsigned init_len = c->length ();
- for (const auto &_ : it) _.serialize (c, use_short_loca, plan);
-
- /* As a special case when all glyph in the font are empty, add a zero byte
- * to the table, so that OTS doesn’t reject it, and to make the table work
- * on Windows as well.
- * See https://github.com/khaledhosny/ots/issues/52 */
- if (init_len == c->length ())
- {
- HBUINT8 empty_byte;
- empty_byte = 0;
- c->copy (empty_byte);
- }
- return_trace (true);
- }
-
- /* Byte region(s) per glyph to output
- unpadded, hints removed if so requested
- If we fail to process a glyph we produce an empty (0-length) glyph */
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- glyf *glyf_prime = c->serializer->start_embed <glyf> ();
- if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
-
- hb_vector_t<SubsetGlyph> glyphs;
- _populate_subset_glyphs (c->plan, &glyphs);
-
- auto padded_offsets =
- + hb_iter (glyphs)
- | hb_map (&SubsetGlyph::padded_size)
- ;
-
- unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
- bool use_short_loca = max_offset < 0x1FFFF;
-
-
- glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan);
- if (!use_short_loca) {
- padded_offsets =
- + hb_iter (glyphs)
- | hb_map (&SubsetGlyph::length)
- ;
- }
-
-
- if (unlikely (c->serializer->in_error ())) return_trace (false);
- return_trace (c->serializer->check_success (_add_loca_and_head (c->plan,
- padded_offsets,
- use_short_loca)));
- }
-
- template <typename SubsetGlyph>
- void
- _populate_subset_glyphs (const hb_subset_plan_t *plan,
- hb_vector_t<SubsetGlyph> *glyphs /* OUT */) const
- {
- OT::glyf::accelerator_t glyf (plan->source);
-
- + hb_range (plan->num_output_glyphs ())
- | hb_map ([&] (hb_codepoint_t new_gid)
- {
- SubsetGlyph subset_glyph = {0};
- subset_glyph.new_gid = new_gid;
-
- /* should never fail: all old gids should be mapped */
- if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid))
- return subset_glyph;
-
- if (new_gid == 0 &&
- !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
- subset_glyph.source_glyph = Glyph ();
- else
- subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
- if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- subset_glyph.drop_hints_bytes ();
- else
- subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
- return subset_glyph;
- })
- | hb_sink (glyphs)
- ;
- }
-
- static bool
- _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
- {
- hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source);
- hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
- hb_blob_destroy (head_blob);
-
- if (unlikely (!head_prime_blob))
- return false;
-
- head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
- head_prime->indexToLocFormat = use_short_loca ? 0 : 1;
- bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
-
- hb_blob_destroy (head_prime_blob);
- return success;
- }
-
- struct CompositeGlyphChain
- {
- protected:
- enum composite_glyph_flag_t
- {
- ARG_1_AND_2_ARE_WORDS = 0x0001,
- ARGS_ARE_XY_VALUES = 0x0002,
- ROUND_XY_TO_GRID = 0x0004,
- WE_HAVE_A_SCALE = 0x0008,
- MORE_COMPONENTS = 0x0020,
- WE_HAVE_AN_X_AND_Y_SCALE = 0x0040,
- WE_HAVE_A_TWO_BY_TWO = 0x0080,
- WE_HAVE_INSTRUCTIONS = 0x0100,
- USE_MY_METRICS = 0x0200,
- OVERLAP_COMPOUND = 0x0400,
- SCALED_COMPONENT_OFFSET = 0x0800,
- UNSCALED_COMPONENT_OFFSET = 0x1000
- };
-
- public:
- unsigned int get_size () const
- {
- unsigned int size = min_size;
- /* arg1 and 2 are int16 */
- if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
- /* arg1 and 2 are int8 */
- else size += 2;
-
- /* One x 16 bit (scale) */
- if (flags & WE_HAVE_A_SCALE) size += 2;
- /* Two x 16 bit (xscale, yscale) */
- else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
- /* Four x 16 bit (xscale, scale01, scale10, yscale) */
- else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
-
- return size;
- }
-
- void set_glyph_index (hb_codepoint_t new_gid) { glyphIndex = new_gid; }
- hb_codepoint_t get_glyph_index () const { return glyphIndex; }
-
- void drop_instructions_flag () { flags = (uint16_t) flags & ~WE_HAVE_INSTRUCTIONS; }
- void set_overlaps_flag ()
- {
- flags = (uint16_t) flags | OVERLAP_COMPOUND;
- }
-
- bool has_instructions () const { return flags & WE_HAVE_INSTRUCTIONS; }
-
- bool has_more () const { return flags & MORE_COMPONENTS; }
- bool is_use_my_metrics () const { return flags & USE_MY_METRICS; }
- bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); }
- void get_anchor_points (unsigned int &point1, unsigned int &point2) const
- {
- const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex);
- if (flags & ARG_1_AND_2_ARE_WORDS)
- {
- point1 = ((const HBUINT16 *) p)[0];
- point2 = ((const HBUINT16 *) p)[1];
- }
- else
- {
- point1 = p[0];
- point2 = p[1];
- }
- }
-
- void transform_points (contour_point_vector_t &points) const
- {
- float matrix[4];
- contour_point_t trans;
- if (get_transformation (matrix, trans))
- {
- if (scaled_offsets ())
- {
- points.translate (trans);
- points.transform (matrix);
- }
- else
- {
- points.transform (matrix);
- points.translate (trans);
- }
- }
- }
-
- protected:
- bool scaled_offsets () const
- { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; }
-
- bool get_transformation (float (&matrix)[4], contour_point_t &trans) const
- {
- matrix[0] = matrix[3] = 1.f;
- matrix[1] = matrix[2] = 0.f;
-
- int tx, ty;
- const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex);
- if (flags & ARG_1_AND_2_ARE_WORDS)
- {
- tx = *(const HBINT16 *) p;
- p += HBINT16::static_size;
- ty = *(const HBINT16 *) p;
- p += HBINT16::static_size;
- }
- else
- {
- tx = *p++;
- ty = *p++;
- }
- if (is_anchored ()) tx = ty = 0;
-
- trans.init ((float) tx, (float) ty);
-
- {
- const F2DOT14 *points = (const F2DOT14 *) p;
- if (flags & WE_HAVE_A_SCALE)
- {
- matrix[0] = matrix[3] = points[0].to_float ();
- return true;
- }
- else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
- {
- matrix[0] = points[0].to_float ();
- matrix[3] = points[1].to_float ();
- return true;
- }
- else if (flags & WE_HAVE_A_TWO_BY_TWO)
- {
- matrix[0] = points[0].to_float ();
- matrix[1] = points[1].to_float ();
- matrix[2] = points[2].to_float ();
- matrix[3] = points[3].to_float ();
- return true;
- }
- }
- return tx || ty;
- }
-
- protected:
- HBUINT16 flags;
- HBGlyphID16 glyphIndex;
- public:
- DEFINE_SIZE_MIN (4);
- };
-
- struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphChain &>
- {
- typedef const CompositeGlyphChain *__item_t__;
- composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
- glyph (glyph_), current (nullptr), current_size (0)
- {
- set_next (current_);
- }
-
- composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {}
-
- const CompositeGlyphChain &__item__ () const { return *current; }
- bool __more__ () const { return current; }
- void __next__ ()
- {
- if (!current->has_more ()) { current = nullptr; return; }
-
- set_next (&StructAtOffset<CompositeGlyphChain> (current, current_size));
- }
- bool operator != (const composite_iter_t& o) const
- { return glyph != o.glyph || current != o.current; }
-
-
- void set_next (const CompositeGlyphChain *composite)
- {
- if (!glyph.check_range (composite, CompositeGlyphChain::min_size))
- {
- current = nullptr;
- current_size = 0;
- return;
- }
- unsigned size = composite->get_size ();
- if (!glyph.check_range (composite, size))
- {
- current = nullptr;
- current_size = 0;
- return;
- }
-
- current = composite;
- current_size = size;
- }
-
- private:
- hb_bytes_t glyph;
- __item_t__ current;
- unsigned current_size;
- };
-
- enum phantom_point_index_t
- {
- PHANTOM_LEFT = 0,
- PHANTOM_RIGHT = 1,
- PHANTOM_TOP = 2,
- PHANTOM_BOTTOM = 3,
- PHANTOM_COUNT = 4
- };
-
- struct accelerator_t;
-
- struct Glyph
- {
- enum simple_glyph_flag_t
- {
- FLAG_ON_CURVE = 0x01,
- FLAG_X_SHORT = 0x02,
- FLAG_Y_SHORT = 0x04,
- FLAG_REPEAT = 0x08,
- FLAG_X_SAME = 0x10,
- FLAG_Y_SAME = 0x20,
- FLAG_OVERLAP_SIMPLE = 0x40,
- FLAG_RESERVED2 = 0x80
- };
-
- private:
- struct GlyphHeader
- {
- bool has_data () const { return numberOfContours; }
-
- bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator,
- hb_codepoint_t gid, hb_glyph_extents_t *extents) const
- {
- /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */
- /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */
- extents->x_bearing = font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (gid));
- extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax));
- extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax));
- extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax));
-
- return true;
- }
-
- HBINT16 numberOfContours;
- /* If the number of contours is
- * greater than or equal to zero,
- * this is a simple glyph; if negative,
- * this is a composite glyph. */
- FWORD xMin; /* Minimum x for coordinate data. */
- FWORD yMin; /* Minimum y for coordinate data. */
- FWORD xMax; /* Maximum x for coordinate data. */
- FWORD yMax; /* Maximum y for coordinate data. */
- public:
- DEFINE_SIZE_STATIC (10);
- };
-
- struct SimpleGlyph
- {
- const GlyphHeader &header;
- hb_bytes_t bytes;
- SimpleGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
- header (header_), bytes (bytes_) {}
-
- unsigned int instruction_len_offset () const
- { return GlyphHeader::static_size + 2 * header.numberOfContours; }
-
- unsigned int length (unsigned int instruction_len) const
- { return instruction_len_offset () + 2 + instruction_len; }
-
- unsigned int instructions_length () const
- {
- unsigned int instruction_length_offset = instruction_len_offset ();
- if (unlikely (instruction_length_offset + 2 > bytes.length)) return 0;
-
- const HBUINT16 &instructionLength = StructAtOffset<HBUINT16> (&bytes, instruction_length_offset);
- /* Out of bounds of the current glyph */
- if (unlikely (length (instructionLength) > bytes.length)) return 0;
- return instructionLength;
- }
-
- const Glyph trim_padding () const
- {
- /* based on FontTools _g_l_y_f.py::trim */
- const uint8_t *glyph = (uint8_t*) bytes.arrayZ;
- const uint8_t *glyph_end = glyph + bytes.length;
- /* simple glyph w/contours, possibly trimmable */
- glyph += instruction_len_offset ();
-
- if (unlikely (glyph + 2 >= glyph_end)) return Glyph ();
- unsigned int num_coordinates = StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
- unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0);
-
- glyph += 2 + num_instructions;
-
- unsigned int coord_bytes = 0;
- unsigned int coords_with_flags = 0;
- while (glyph < glyph_end)
- {
- uint8_t flag = *glyph;
- glyph++;
-
- unsigned int repeat = 1;
- if (flag & FLAG_REPEAT)
- {
- if (unlikely (glyph >= glyph_end)) return Glyph ();
- repeat = *glyph + 1;
- glyph++;
- }
-
- unsigned int xBytes, yBytes;
- xBytes = yBytes = 0;
- if (flag & FLAG_X_SHORT) xBytes = 1;
- else if ((flag & FLAG_X_SAME) == 0) xBytes = 2;
-
- if (flag & FLAG_Y_SHORT) yBytes = 1;
- else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2;
-
- coord_bytes += (xBytes + yBytes) * repeat;
- coords_with_flags += repeat;
- if (coords_with_flags >= num_coordinates) break;
- }
-
- if (unlikely (coords_with_flags != num_coordinates)) return Glyph ();
- return Glyph (bytes.sub_array (0, bytes.length + coord_bytes - (glyph_end - glyph)));
- }
-
- /* zero instruction length */
- void drop_hints ()
- {
- GlyphHeader &glyph_header = const_cast<GlyphHeader &> (header);
- (HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0;
- }
-
- void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
- {
- unsigned int instructions_len = instructions_length ();
- unsigned int glyph_length = length (instructions_len);
- dest_start = bytes.sub_array (0, glyph_length - instructions_len);
- dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length);
- }
-
- void set_overlaps_flag ()
- {
- if (unlikely (!header.numberOfContours)) return;
-
- unsigned flags_offset = length (instructions_length ());
- 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;
- }
-
- static bool read_points (const HBUINT8 *&p /* IN/OUT */,
- contour_point_vector_t &points_ /* IN/OUT */,
- const hb_bytes_t &bytes,
- void (* setter) (contour_point_t &_, float v),
- const simple_glyph_flag_t short_flag,
- const simple_glyph_flag_t same_flag)
- {
- float v = 0;
- for (unsigned i = 0; i < points_.length; i++)
- {
- uint8_t flag = points_[i].flag;
- if (flag & short_flag)
- {
- if (unlikely (!bytes.check_range (p))) return false;
- if (flag & same_flag)
- v += *p++;
- else
- v -= *p++;
- }
- else
- {
- if (!(flag & same_flag))
- {
- if (unlikely (!bytes.check_range ((const HBUINT16 *) p))) return false;
- v += *(const HBINT16 *) p;
- p += HBINT16::static_size;
- }
- }
- setter (points_[i], v);
- }
- return true;
- }
-
- bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
- bool phantom_only = false) const
- {
- const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
- int num_contours = header.numberOfContours;
- if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours + 1]))) return false;
- unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
-
- points_.resize (num_points);
- for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
- if (phantom_only) return true;
-
- for (int i = 0; i < num_contours; i++)
- points_[endPtsOfContours[i]].is_end_point = true;
-
- /* Skip instructions */
- const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1],
- endPtsOfContours[num_contours]);
-
- /* Read flags */
- for (unsigned int i = 0; i < num_points; i++)
- {
- if (unlikely (!bytes.check_range (p))) return false;
- uint8_t flag = *p++;
- points_[i].flag = flag;
- if (flag & FLAG_REPEAT)
- {
- if (unlikely (!bytes.check_range (p))) return false;
- unsigned int repeat_count = *p++;
- while ((repeat_count-- > 0) && (++i < num_points))
- points_[i].flag = flag;
- }
- }
-
- /* Read x & y coordinates */
- return read_points (p, points_, bytes, [] (contour_point_t &p, float v) { p.x = v; },
- FLAG_X_SHORT, FLAG_X_SAME)
- && read_points (p, points_, bytes, [] (contour_point_t &p, float v) { p.y = v; },
- FLAG_Y_SHORT, FLAG_Y_SAME);
- }
- };
-
- struct CompositeGlyph
- {
- const GlyphHeader &header;
- hb_bytes_t bytes;
- CompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
- header (header_), bytes (bytes_) {}
-
- composite_iter_t get_iterator () const
- { return composite_iter_t (bytes, &StructAfter<CompositeGlyphChain, GlyphHeader> (header)); }
-
- unsigned int instructions_length (hb_bytes_t bytes) const
- {
- unsigned int start = bytes.length;
- unsigned int end = bytes.length;
- const CompositeGlyphChain *last = nullptr;
- for (auto &item : get_iterator ())
- last = &item;
- if (unlikely (!last)) return 0;
-
- if (last->has_instructions ())
- start = (char *) last - &bytes + last->get_size ();
- if (unlikely (start > end)) return 0;
- return end - start;
- }
-
- /* Trimming for composites not implemented.
- * If removing hints it falls out of that. */
- const Glyph trim_padding () const { return Glyph (bytes); }
-
- void drop_hints ()
- {
- for (const auto &_ : get_iterator ())
- const_cast<CompositeGlyphChain &> (_).drop_instructions_flag ();
- }
-
- /* Chop instructions off the end */
- void drop_hints_bytes (hb_bytes_t &dest_start) const
- { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); }
-
- void set_overlaps_flag ()
- {
- const_cast<CompositeGlyphChain &> (StructAfter<CompositeGlyphChain, GlyphHeader> (header))
- .set_overlaps_flag ();
- }
- };
-
- enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };
-
- public:
- composite_iter_t get_composite_iterator () const
- {
- if (type != COMPOSITE) return composite_iter_t ();
- return CompositeGlyph (*header, bytes).get_iterator ();
- }
-
- const Glyph trim_padding () const
- {
- switch (type) {
- case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding ();
- case SIMPLE: return SimpleGlyph (*header, bytes).trim_padding ();
- default: return bytes;
- }
- }
-
- void drop_hints ()
- {
- switch (type) {
- case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return;
- case SIMPLE: SimpleGlyph (*header, bytes).drop_hints (); return;
- default: return;
- }
- }
-
- void set_overlaps_flag ()
- {
- switch (type) {
- case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return;
- case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return;
- default: return;
- }
- }
-
- void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
- {
- switch (type) {
- case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
- case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
- default: return;
- }
- }
-
- /* Note: Recursively calls itself.
- * all_points includes phantom points
- */
- bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
- contour_point_vector_t &all_points /* OUT */,
- bool phantom_only = false,
- unsigned int depth = 0) const
- {
- if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
- contour_point_vector_t points;
-
- switch (type) {
- case COMPOSITE:
- {
- /* pseudo component points for each component in composite glyph */
- unsigned num_points = hb_len (CompositeGlyph (*header, bytes).get_iterator ());
- if (unlikely (!points.resize (num_points))) return false;
- for (unsigned i = 0; i < points.length; i++)
- points[i].init ();
- break;
- }
- case SIMPLE:
- if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
- return false;
- break;
- }
-
- /* Init phantom points */
- if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
- hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
- {
- for (unsigned i = 0; i < PHANTOM_COUNT; ++i) phantoms[i].init ();
- int h_delta = (int) header->xMin -
- glyf_accelerator.hmtx->get_side_bearing (gid);
- int v_orig = (int) header->yMax +
-#ifndef HB_NO_VERTICAL
- glyf_accelerator.vmtx->get_side_bearing (gid)
-#else
- 0
-#endif
- ;
- unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid);
- unsigned v_adv =
-#ifndef HB_NO_VERTICAL
- glyf_accelerator.vmtx->get_advance (gid)
-#else
- - font->face->get_upem ()
-#endif
- ;
- phantoms[PHANTOM_LEFT].x = h_delta;
- phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
- phantoms[PHANTOM_TOP].y = v_orig;
- phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
- }
-
-#ifndef HB_NO_VAR
- glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ());
-#endif
-
- switch (type) {
- case SIMPLE:
- all_points.extend (points.as_array ());
- break;
- case COMPOSITE:
- {
- unsigned int comp_index = 0;
- for (auto &item : get_composite_iterator ())
- {
- contour_point_vector_t comp_points;
- if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_glyph_index ())
- .get_points (font, glyf_accelerator, comp_points,
- phantom_only, depth + 1)
- || comp_points.length < PHANTOM_COUNT))
- return false;
-
- /* Copy phantom points from component if USE_MY_METRICS flag set */
- if (item.is_use_my_metrics ())
- for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
- phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
-
- /* Apply component transformation & translation */
- item.transform_points (comp_points);
-
- /* Apply translation from gvar */
- comp_points.translate (points[comp_index]);
-
- if (item.is_anchored ())
- {
- unsigned int p1, p2;
- item.get_anchor_points (p1, p2);
- if (likely (p1 < all_points.length && p2 < comp_points.length))
- {
- contour_point_t delta;
- delta.init (all_points[p1].x - comp_points[p2].x,
- all_points[p1].y - comp_points[p2].y);
-
- comp_points.translate (delta);
- }
- }
-
- all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
-
- comp_index++;
- }
-
- all_points.extend (phantoms);
- } break;
- default:
- all_points.extend (phantoms);
- }
-
- if (depth == 0) /* Apply at top level */
- {
- /* Undocumented rasterizer behavior:
- * Shift points horizontally by the updated left side bearing
- */
- contour_point_t delta;
- delta.init (-phantoms[PHANTOM_LEFT].x, 0.f);
- if (delta.x) all_points.translate (delta);
- }
-
- return true;
- }
-
- bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator,
- hb_glyph_extents_t *extents) const
- {
- if (type == EMPTY) return true; /* Empty glyph; zero extents. */
- return header->get_extents (font, glyf_accelerator, gid, extents);
- }
-
- hb_bytes_t get_bytes () const { return bytes; }
-
- Glyph (hb_bytes_t bytes_ = hb_bytes_t (),
- hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_), gid (gid_),
- header (bytes.as<GlyphHeader> ())
- {
- int num_contours = header->numberOfContours;
- if (unlikely (num_contours == 0)) type = EMPTY;
- else if (num_contours > 0) type = SIMPLE;
- else type = COMPOSITE; /* negative numbers */
- }
-
- protected:
- hb_bytes_t bytes;
- hb_codepoint_t gid;
- const GlyphHeader *header;
- unsigned type;
- };
-
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- {
- short_offset = false;
- num_glyphs = 0;
- loca_table = nullptr;
- glyf_table = nullptr;
-#ifndef HB_NO_VAR
- gvar = nullptr;
-#endif
- hmtx = nullptr;
-#ifndef HB_NO_VERTICAL
- vmtx = nullptr;
-#endif
- const OT::head &head = *face->table.head;
- if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
- /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
- return;
- short_offset = 0 == head.indexToLocFormat;
-
- loca_table = face->table.loca.get_blob (); // Needs no destruct!
- glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
-#ifndef HB_NO_VAR
- gvar = face->table.gvar;
-#endif
- hmtx = face->table.hmtx;
-#ifndef HB_NO_VERTICAL
- vmtx = face->table.vmtx;
-#endif
-
- num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
- num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ());
- }
- ~accelerator_t ()
- {
- glyf_table.destroy ();
- }
-
- bool has_data () const { return num_glyphs; }
-
- protected:
- template<typename T>
- bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) const
- {
- if (gid >= num_glyphs) return false;
-
- /* Making this allocfree is not that easy
- https://github.com/harfbuzz/harfbuzz/issues/2095
- mostly because of gvar handling in VF fonts,
- perhaps a separate path for non-VF fonts can be considered */
- contour_point_vector_t all_points;
-
- bool phantom_only = !consumer.is_consuming_contour_points ();
- if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, phantom_only)))
- return false;
-
- if (consumer.is_consuming_contour_points ())
- {
- for (unsigned point_index = 0; point_index + 4 < all_points.length; ++point_index)
- consumer.consume_point (all_points[point_index]);
- consumer.points_end ();
- }
-
- /* Where to write phantoms, nullptr if not requested */
- contour_point_t *phantoms = consumer.get_phantoms_sink ();
- if (phantoms)
- for (unsigned i = 0; i < PHANTOM_COUNT; ++i)
- phantoms[i] = all_points[all_points.length - PHANTOM_COUNT + i];
-
- return true;
- }
-
-#ifndef HB_NO_VAR
- struct points_aggregator_t
- {
- hb_font_t *font;
- hb_glyph_extents_t *extents;
- contour_point_t *phantoms;
-
- struct contour_bounds_t
- {
- contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; }
-
- void add (const contour_point_t &p)
- {
- min_x = hb_min (min_x, p.x);
- min_y = hb_min (min_y, p.y);
- max_x = hb_max (max_x, p.x);
- max_y = hb_max (max_y, p.y);
- }
-
- bool empty () const { return (min_x >= max_x) || (min_y >= max_y); }
-
- void get_extents (hb_font_t *font, hb_glyph_extents_t *extents)
- {
- if (unlikely (empty ()))
- {
- extents->width = 0;
- extents->x_bearing = 0;
- extents->height = 0;
- extents->y_bearing = 0;
- return;
- }
- extents->x_bearing = font->em_scalef_x (min_x);
- extents->width = font->em_scalef_x (max_x) - extents->x_bearing;
- extents->y_bearing = font->em_scalef_y (max_y);
- extents->height = font->em_scalef_y (min_y) - extents->y_bearing;
- }
-
- protected:
- float min_x, min_y, max_x, max_y;
- } bounds;
-
- points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_)
- {
- font = font_;
- extents = extents_;
- phantoms = phantoms_;
- if (extents) bounds = contour_bounds_t ();
- }
-
- void consume_point (const contour_point_t &point) { bounds.add (point); }
- void points_end () { bounds.get_extents (font, extents); }
-
- bool is_consuming_contour_points () { return extents; }
- contour_point_t *get_phantoms_sink () { return phantoms; }
- };
-
- public:
- unsigned
- get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
- {
- if (unlikely (gid >= num_glyphs)) return 0;
-
- bool success = false;
-
- contour_point_t phantoms[PHANTOM_COUNT];
- if (likely (font->num_coords == gvar->get_axis_count ()))
- success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms));
-
- if (unlikely (!success))
- return
-#ifndef HB_NO_VERTICAL
- is_vertical ? vmtx->get_advance (gid) :
-#endif
- hmtx->get_advance (gid);
-
- float result = is_vertical
- ? phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y
- : phantoms[PHANTOM_RIGHT].x - phantoms[PHANTOM_LEFT].x;
- return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2);
- }
-
- int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
- {
- if (unlikely (gid >= num_glyphs)) return 0;
-
- hb_glyph_extents_t extents;
-
- contour_point_t phantoms[PHANTOM_COUNT];
- if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms))))
- return
-#ifndef HB_NO_VERTICAL
- is_vertical ? vmtx->get_side_bearing (gid) :
-#endif
- hmtx->get_side_bearing (gid);
-
- return is_vertical
- ? ceilf (phantoms[PHANTOM_TOP].y) - extents.y_bearing
- : floorf (phantoms[PHANTOM_LEFT].x);
- }
-#endif
-
- public:
- bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
- {
- if (unlikely (gid >= num_glyphs)) return false;
-
-#ifndef HB_NO_VAR
- if (font->num_coords && font->num_coords == gvar->get_axis_count ())
- return get_points (font, gid, points_aggregator_t (font, extents, nullptr));
-#endif
- return glyph_for_gid (gid).get_extents (font, *this, extents);
- }
-
- const Glyph
- glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const
- {
- if (unlikely (gid >= num_glyphs)) return Glyph ();
-
- unsigned int start_offset, end_offset;
-
- if (short_offset)
- {
- const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
- start_offset = 2 * offsets[gid];
- end_offset = 2 * offsets[gid + 1];
- }
- else
- {
- const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
- start_offset = offsets[gid];
- end_offset = offsets[gid + 1];
- }
-
- if (unlikely (start_offset > end_offset || end_offset > glyf_table.get_length ()))
- return Glyph ();
-
- Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset,
- end_offset - start_offset), gid);
- return needs_padding_removal ? glyph.trim_padding () : glyph;
- }
-
- unsigned
- add_gid_and_children (hb_codepoint_t gid,
- hb_set_t *gids_to_retain,
- unsigned depth = 0,
- unsigned operation_count = 0) const
- {
- if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
- if (unlikely (operation_count++ > HB_MAX_COMPOSITE_OPERATIONS)) return operation_count;
- /* Check if is already visited */
- if (gids_to_retain->has (gid)) return operation_count;
-
- gids_to_retain->add (gid);
-
- auto it = glyph_for_gid (gid).get_composite_iterator ();
- while (it)
- {
- auto item = *(it++);
- operation_count =
- add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth, operation_count);
- }
-
- return operation_count;
- }
-
- struct path_builder_t
- {
- hb_font_t *font;
- hb_draw_session_t *draw_session;
-
- struct optional_point_t
- {
- optional_point_t () { has_data = false; }
- optional_point_t (float x_, float y_) { x = x_; y = y_; has_data = true; }
-
- bool has_data;
- float x;
- float y;
-
- optional_point_t lerp (optional_point_t p, float t)
- { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
- } first_oncurve, first_offcurve, last_offcurve;
-
- path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
- {
- font = font_;
- draw_session = &draw_session_;
- first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
- }
-
- /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
- See also:
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
- * https://stackoverflow.com/a/20772557 */
- void consume_point (const contour_point_t &point)
- {
- bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE;
- optional_point_t p (point.x, point.y);
- if (!first_oncurve.has_data)
- {
- if (is_on_curve)
- {
- first_oncurve = p;
- draw_session->move_to (font->em_fscalef_x (p.x), font->em_fscalef_y (p.y));
- }
- else
- {
- if (first_offcurve.has_data)
- {
- optional_point_t mid = first_offcurve.lerp (p, .5f);
- first_oncurve = mid;
- last_offcurve = p;
- draw_session->move_to (font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y));
- }
- else
- first_offcurve = p;
- }
- }
- else
- {
- if (last_offcurve.has_data)
- {
- if (is_on_curve)
- {
- draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
- font->em_fscalef_x (p.x), font->em_fscalef_y (p.y));
- last_offcurve = optional_point_t ();
- }
- else
- {
- optional_point_t mid = last_offcurve.lerp (p, .5f);
- draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
- font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y));
- last_offcurve = p;
- }
- }
- else
- {
- if (is_on_curve)
- draw_session->line_to (font->em_fscalef_x (p.x), font->em_fscalef_y (p.y));
- else
- last_offcurve = p;
- }
- }
-
- if (point.is_end_point)
- {
- if (first_offcurve.has_data && last_offcurve.has_data)
- {
- optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
- draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
- font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y));
- last_offcurve = optional_point_t ();
- /* now check the rest */
- }
-
- if (first_offcurve.has_data && first_oncurve.has_data)
- draw_session->quadratic_to (font->em_fscalef_x (first_offcurve.x), font->em_fscalef_y (first_offcurve.y),
- font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y));
- else if (last_offcurve.has_data && first_oncurve.has_data)
- draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
- font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y));
- else if (first_oncurve.has_data)
- draw_session->line_to (font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y));
- else if (first_offcurve.has_data)
- {
- float x = font->em_fscalef_x (first_offcurve.x), y = font->em_fscalef_x (first_offcurve.y);
- draw_session->move_to (x, y);
- draw_session->quadratic_to (x, y, x, y);
- }
-
- /* Getting ready for the next contour */
- first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
- draw_session->close_path ();
- }
- }
- void points_end () {}
-
- bool is_consuming_contour_points () { return true; }
- contour_point_t *get_phantoms_sink () { return nullptr; }
- };
-
- bool
- get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
- { return get_points (font, gid, path_builder_t (font, draw_session)); }
-
-#ifndef HB_NO_VAR
- const gvar_accelerator_t *gvar;
-#endif
- const hmtx_accelerator_t *hmtx;
-#ifndef HB_NO_VERTICAL
- const vmtx_accelerator_t *vmtx;
-#endif
-
- private:
- bool short_offset;
- unsigned int num_glyphs;
- hb_blob_ptr_t<loca> loca_table;
- hb_blob_ptr_t<glyf> glyf_table;
- };
-
- struct SubsetGlyph
- {
- hb_codepoint_t new_gid;
- hb_codepoint_t old_gid;
- Glyph source_glyph;
- hb_bytes_t dest_start; /* region of source_glyph to copy first */
- hb_bytes_t dest_end; /* region of source_glyph to copy second */
-
- bool serialize (hb_serialize_context_t *c,
- bool use_short_loca,
- const hb_subset_plan_t *plan) const
- {
- TRACE_SERIALIZE (this);
-
- hb_bytes_t dest_glyph = dest_start.copy (c);
- dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
- unsigned int pad_length = use_short_loca ? padding () : 0;
- DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
-
- HBUINT8 pad;
- pad = 0;
- while (pad_length > 0)
- {
- c->embed (pad);
- pad_length--;
- }
-
- if (unlikely (!dest_glyph.length)) return_trace (true);
-
- /* update components gids */
- for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
- {
- hb_codepoint_t new_gid;
- if (plan->new_gid_for_old_gid (_.get_glyph_index (), &new_gid))
- const_cast<CompositeGlyphChain &> (_).set_glyph_index (new_gid);
- }
-
- if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- Glyph (dest_glyph).drop_hints ();
-
- if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG)
- Glyph (dest_glyph).set_overlaps_flag ();
-
- return_trace (true);
- }
-
- void drop_hints_bytes ()
- { source_glyph.drop_hints_bytes (dest_start, dest_end); }
-
- unsigned int length () const { return dest_start.length + dest_end.length; }
- /* pad to 2 to ensure 2-byte loca will be ok */
- unsigned int padding () const { return length () % 2; }
- unsigned int padded_size () const { return length () + padding (); }
- };
-
- protected:
- UnsizedArrayOf<HBUINT8>
- dataZ; /* Glyphs data. */
- public:
- DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
- * check the size externally, allow Null() object of it by
- * defining it _MIN instead. */
-};
-
-struct glyf_accelerator_t : glyf::accelerator_t {
- glyf_accelerator_t (hb_face_t *face) : glyf::accelerator_t (face) {}
-};
-
-
-} /* namespace OT */
-
+#include "OT/glyf/glyf.hh"
#endif /* HB_OT_GLYF_TABLE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
index d5e1fc91d2..d0e46e0b0f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
@@ -242,7 +242,7 @@ struct hmtxvmtx
return side_bearing;
if (var_table.get_length ())
- return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
+ return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords);
return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
#else
@@ -284,7 +284,8 @@ struct hmtxvmtx
}
unsigned int get_advance (hb_codepoint_t glyph,
- hb_font_t *font) const
+ hb_font_t *font,
+ VariationStore::cache_t *store_cache = nullptr) const
{
unsigned int advance = get_advance (glyph);
@@ -293,7 +294,7 @@ struct hmtxvmtx
return advance;
if (var_table.get_length ())
- return advance + roundf (var_table->get_advance_var (glyph, font)); // TODO Optimize?!
+ return advance + roundf (var_table->get_advance_var (glyph, font, store_cache)); // TODO Optimize?!
return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
#else
@@ -310,7 +311,7 @@ struct hmtxvmtx
unsigned int default_advance;
- private:
+ public:
hb_blob_ptr_t<hmtxvmtx> table;
hb_blob_ptr_t<HVARVVAR> var_table;
};
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
index b644df708d..d343805346 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
@@ -102,7 +102,7 @@ static void ClassDef_remap_and_serialize (
struct hb_prune_langsys_context_t
{
hb_prune_langsys_context_t (const void *table_,
- hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_,
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map_,
const hb_map_t *duplicate_feature_map_,
hb_set_t *new_collected_feature_indexes_)
:table (table_),
@@ -122,7 +122,7 @@ struct hb_prune_langsys_context_t
public:
const void *table;
- hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map;
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
const hb_map_t *duplicate_feature_map;
hb_set_t *new_feature_indexes;
@@ -162,14 +162,14 @@ struct hb_subset_layout_context_t :
hb_subset_context_t *subset_context;
const hb_tag_t table_tag;
const hb_map_t *lookup_index_map;
- const hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map;
+ const hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
const hb_map_t *feature_index_map;
unsigned cur_script_index;
hb_subset_layout_context_t (hb_subset_context_t *c_,
hb_tag_t tag_,
hb_map_t *lookup_map_,
- hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_,
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map_,
hb_map_t *feature_index_map_) :
subset_context (c_),
table_tag (tag_),
@@ -659,7 +659,8 @@ struct LangSys
auto *out = c->serializer->start_embed (*this);
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
- out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex) ? l->feature_index_map->get (reqFeatureIndex) : 0xFFFFu;
+ const unsigned *v;
+ out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu;
if (!l->visitFeatureIndex (featureIndex.len))
return_trace (false);
@@ -722,12 +723,8 @@ struct Script
if (!c->script_langsys_map->has (script_index))
{
- hb_set_t* empty_set = hb_set_create ();
- if (unlikely (!c->script_langsys_map->set (script_index, empty_set)))
- {
- hb_set_destroy (empty_set);
+ if (unlikely (!c->script_langsys_map->set (script_index, hb::unique_ptr<hb_set_t> {hb_set_create ()})))
return;
- }
}
unsigned langsys_count = get_lang_sys_count ();
@@ -2004,6 +2001,8 @@ struct ClassDefFormat1
return_trace (c->check_struct (this) && classValue.sanitize (c));
}
+ unsigned cost () const { return 1; }
+
template <typename set_t>
bool collect_coverage (set_t *glyphs) const
{
@@ -2240,6 +2239,8 @@ struct ClassDefFormat2
return_trace (rangeRecord.sanitize (c));
}
+ unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ }
+
template <typename set_t>
bool collect_coverage (set_t *glyphs) const
{
@@ -2480,6 +2481,15 @@ struct ClassDef
}
}
+ unsigned cost () const
+ {
+ switch (u.format) {
+ case 1: return u.format1.cost ();
+ case 2: return u.format2.cost ();
+ default:return 0u;
+ }
+ }
+
/* Might return false if array looks unsorted.
* Used for faster rejection of corrupt data. */
template <typename set_t>
@@ -2601,14 +2611,27 @@ struct VarRegionAxis
DEFINE_SIZE_STATIC (6);
};
+#define REGION_CACHE_ITEM_CACHE_INVALID 2.f
+
struct VarRegionList
{
+ using cache_t = float;
+
float evaluate (unsigned int region_index,
- const int *coords, unsigned int coord_len) const
+ const int *coords, unsigned int coord_len,
+ cache_t *cache = nullptr) const
{
if (unlikely (region_index >= regionCount))
return 0.;
+ float *cached_value = nullptr;
+ if (cache)
+ {
+ cached_value = &(cache[region_index]);
+ if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID))
+ return *cached_value;
+ }
+
const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount);
float v = 1.;
@@ -2618,9 +2641,16 @@ struct VarRegionList
int coord = i < coord_len ? coords[i] : 0;
float factor = axes[i].evaluate (coord);
if (factor == 0.f)
+ {
+ if (cache)
+ *cached_value = 0.;
return 0.;
+ }
v *= factor;
}
+
+ if (cache)
+ *cached_value = v;
return v;
}
@@ -2668,7 +2698,7 @@ struct VarData
{ return regionIndices.len; }
unsigned int get_row_size () const
- { return shortCount + regionIndices.len; }
+ { return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); }
unsigned int get_size () const
{ return min_size
@@ -2678,13 +2708,17 @@ struct VarData
float get_delta (unsigned int inner,
const int *coords, unsigned int coord_count,
- const VarRegionList &regions) const
+ const VarRegionList &regions,
+ VarRegionList::cache_t *cache = nullptr) const
{
if (unlikely (inner >= itemCount))
return 0.;
unsigned int count = regionIndices.len;
- unsigned int scount = shortCount;
+ bool is_long = longWords ();
+ unsigned word_count = wordCount ();
+ unsigned int scount = is_long ? count - word_count : word_count;
+ unsigned int lcount = is_long ? word_count : 0;
const HBUINT8 *bytes = get_delta_bytes ();
const HBUINT8 *row = bytes + inner * (scount + count);
@@ -2692,16 +2726,22 @@ struct VarData
float delta = 0.;
unsigned int i = 0;
- const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row);
+ const HBINT16 *lcursor = reinterpret_cast<const HBINT16 *> (row);
+ for (; i < lcount; i++)
+ {
+ float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
+ delta += scalar * *lcursor++;
+ }
+ const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (lcursor);
for (; i < scount; i++)
{
- float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
+ float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
delta += scalar * *scursor++;
}
const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor);
for (; i < count; i++)
{
- float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
+ float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
delta += scalar * *bcursor++;
}
@@ -2725,7 +2765,7 @@ struct VarData
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
regionIndices.sanitize (c) &&
- shortCount <= regionIndices.len &&
+ wordCount () <= regionIndices.len &&
c->check_range (get_delta_bytes (),
itemCount,
get_row_size ()));
@@ -2740,43 +2780,66 @@ struct VarData
if (unlikely (!c->extend_min (this))) return_trace (false);
itemCount = inner_map.get_next_value ();
- /* Optimize short count */
- unsigned short ri_count = src->regionIndices.len;
- enum delta_size_t { kZero=0, kByte, kShort };
+ /* Optimize word count */
+ unsigned ri_count = src->regionIndices.len;
+ enum delta_size_t { kZero=0, kNonWord, kWord };
hb_vector_t<delta_size_t> delta_sz;
hb_vector_t<unsigned int> ri_map; /* maps old index to new index */
delta_sz.resize (ri_count);
ri_map.resize (ri_count);
- unsigned int new_short_count = 0;
+ unsigned int new_word_count = 0;
unsigned int r;
+
+ bool has_long = false;
+ if (src->longWords ())
+ {
+ for (r = 0; r < ri_count; r++)
+ {
+ for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
+ {
+ unsigned int old = inner_map.backward (i);
+ int32_t delta = src->get_item_delta (old, r);
+ if (delta < -65536 || 65535 < delta)
+ {
+ has_long = true;
+ break;
+ }
+ }
+ }
+ }
+
+ signed min_threshold = has_long ? -65536 : -128;
+ signed max_threshold = has_long ? +65535 : +127;
for (r = 0; r < ri_count; r++)
{
delta_sz[r] = kZero;
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
{
unsigned int old = inner_map.backward (i);
- int16_t delta = src->get_item_delta (old, r);
- if (delta < -128 || 127 < delta)
+ int32_t delta = src->get_item_delta (old, r);
+ if (delta < min_threshold || max_threshold < delta)
{
- delta_sz[r] = kShort;
- new_short_count++;
+ delta_sz[r] = kWord;
+ new_word_count++;
break;
}
else if (delta != 0)
- delta_sz[r] = kByte;
+ delta_sz[r] = kNonWord;
}
}
- unsigned int short_index = 0;
- unsigned int byte_index = new_short_count;
+
+ unsigned int word_index = 0;
+ unsigned int non_word_index = new_word_count;
unsigned int new_ri_count = 0;
for (r = 0; r < ri_count; r++)
if (delta_sz[r])
{
- ri_map[r] = (delta_sz[r] == kShort)? short_index++ : byte_index++;
+ ri_map[r] = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
new_ri_count++;
}
- shortCount = new_short_count;
+ wordSizeCount = new_word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0);
+
regionIndices.len = new_ri_count;
if (unlikely (!c->extend (this))) return_trace (false);
@@ -2816,28 +2879,55 @@ struct VarData
HBUINT8 *get_delta_bytes ()
{ return &StructAfter<HBUINT8> (regionIndices); }
- int16_t get_item_delta (unsigned int item, unsigned int region) const
+ int32_t get_item_delta (unsigned int item, unsigned int region) const
{
if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0;
- const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size ();
- if (region < shortCount)
- return ((const HBINT16 *)p)[region];
+ const HBINT8 *p = (const HBINT8 *) get_delta_bytes () + item * get_row_size ();
+ unsigned word_count = wordCount ();
+ bool is_long = longWords ();
+ if (is_long)
+ {
+ if (region < word_count)
+ return ((const HBINT32 *) p)[region];
+ else
+ return ((const HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count];
+ }
else
- return (p + HBINT16::static_size * shortCount)[region - shortCount];
+ {
+ if (region < word_count)
+ return ((const HBINT16 *) p)[region];
+ else
+ return (p + HBINT16::static_size * word_count)[region - word_count];
+ }
}
- void set_item_delta (unsigned int item, unsigned int region, int16_t delta)
+ void set_item_delta (unsigned int item, unsigned int region, int32_t delta)
{
HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size ();
- if (region < shortCount)
- ((HBINT16 *)p)[region] = delta;
+ unsigned word_count = wordCount ();
+ bool is_long = longWords ();
+ if (is_long)
+ {
+ if (region < word_count)
+ ((HBINT32 *) p)[region] = delta;
+ else
+ ((HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count] = delta;
+ }
else
- (p + HBINT16::static_size * shortCount)[region - shortCount] = delta;
+ {
+ if (region < word_count)
+ ((HBINT16 *) p)[region] = delta;
+ else
+ (p + HBINT16::static_size * word_count)[region - word_count] = delta;
+ }
}
+ bool longWords () const { return wordSizeCount & 0x8000u /* LONG_WORDS */; }
+ unsigned wordCount () const { return wordSizeCount & 0x7FFFu /* WORD_DELTA_COUNT_MASK */; }
+
protected:
HBUINT16 itemCount;
- HBUINT16 shortCount;
+ HBUINT16 wordSizeCount;
Array16Of<HBUINT16> regionIndices;
/*UnsizedArrayOf<HBUINT8>bytesX;*/
public:
@@ -2846,9 +2936,28 @@ struct VarData
struct VariationStore
{
+ using cache_t = VarRegionList::cache_t;
+
+ cache_t *create_cache () const
+ {
+ auto &r = this+regions;
+ unsigned count = r.regionCount;
+
+ float *cache = (float *) hb_malloc (sizeof (float) * count);
+ if (unlikely (!cache)) return nullptr;
+
+ for (unsigned i = 0; i < count; i++)
+ cache[i] = REGION_CACHE_ITEM_CACHE_INVALID;
+
+ return cache;
+ }
+
+ static void destroy_cache (cache_t *cache) { hb_free (cache); }
+
private:
float get_delta (unsigned int outer, unsigned int inner,
- const int *coords, unsigned int coord_count) const
+ const int *coords, unsigned int coord_count,
+ VarRegionList::cache_t *cache = nullptr) const
{
#ifdef HB_NO_VAR
return 0.f;
@@ -2859,16 +2968,18 @@ struct VariationStore
return (this+dataSets[outer]).get_delta (inner,
coords, coord_count,
- this+regions);
+ this+regions,
+ cache);
}
public:
float get_delta (unsigned int index,
- const int *coords, unsigned int coord_count) const
+ const int *coords, unsigned int coord_count,
+ VarRegionList::cache_t *cache = nullptr) const
{
unsigned int outer = index >> 16;
unsigned int inner = index & 0xFFFF;
- return get_delta (outer, inner, coords, coord_count);
+ return get_delta (outer, inner, coords, coord_count, cache);
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -2995,6 +3106,8 @@ struct VariationStore
DEFINE_SIZE_ARRAY_SIZED (8, dataSets);
};
+#undef REGION_CACHE_ITEM_CACHE_INVALID
+
/*
* Feature Variations
*/
@@ -3462,11 +3575,15 @@ struct VariationDevice
private:
- hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store) const
- { return font->em_scalef_x (get_delta (font, store)); }
+ hb_position_t get_x_delta (hb_font_t *font,
+ const VariationStore &store,
+ VariationStore::cache_t *store_cache = nullptr) const
+ { return font->em_scalef_x (get_delta (font, store, store_cache)); }
- hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store) const
- { return font->em_scalef_y (get_delta (font, store)); }
+ hb_position_t get_y_delta (hb_font_t *font,
+ const VariationStore &store,
+ VariationStore::cache_t *store_cache = nullptr) const
+ { return font->em_scalef_y (get_delta (font, store, store_cache)); }
VariationDevice* copy (hb_serialize_context_t *c, const hb_map_t *layout_variation_idx_map) const
{
@@ -3500,9 +3617,11 @@ struct VariationDevice
private:
- float get_delta (hb_font_t *font, const VariationStore &store) const
+ float get_delta (hb_font_t *font,
+ const VariationStore &store,
+ VariationStore::cache_t *store_cache = nullptr) const
{
- return store.get_delta (varIdx, font->coords, font->num_coords);
+ return store.get_delta (varIdx, font->coords, font->num_coords, (VariationStore::cache_t *) store_cache);
}
protected:
@@ -3525,7 +3644,9 @@ struct DeviceHeader
struct Device
{
- hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const
+ hb_position_t get_x_delta (hb_font_t *font,
+ const VariationStore &store=Null (VariationStore),
+ VariationStore::cache_t *store_cache = nullptr) const
{
switch (u.b.format)
{
@@ -3535,13 +3656,15 @@ struct Device
#endif
#ifndef HB_NO_VAR
case 0x8000:
- return u.variation.get_x_delta (font, store);
+ return u.variation.get_x_delta (font, store, store_cache);
#endif
default:
return 0;
}
}
- hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const
+ hb_position_t get_y_delta (hb_font_t *font,
+ const VariationStore &store=Null (VariationStore),
+ VariationStore::cache_t *store_cache = nullptr) const
{
switch (u.b.format)
{
@@ -3551,7 +3674,7 @@ struct Device
#endif
#ifndef HB_NO_VAR
case 0x8000:
- return u.variation.get_y_delta (font, store);
+ return u.variation.get_y_delta (font, store, store_cache);
#endif
default:
return 0;
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh
index a76d644c4b..9d47bac2b9 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh
@@ -571,7 +571,7 @@ struct GDEF
static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks), "");
switch (klass) {
- default: return 0;
+ default: return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
case MarkGlyph:
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
index 2f9186a2a7..064d31cdff 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
@@ -29,3090 +29,14 @@
#ifndef HB_OT_LAYOUT_GPOS_TABLE_HH
#define HB_OT_LAYOUT_GPOS_TABLE_HH
-#include "hb-ot-layout-gsubgpos.hh"
-
+#include "OT/Layout/GPOS.hh"
namespace OT {
-struct MarkArray;
-static void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage,
- const MarkArray &mark_array,
- const hb_set_t &glyphset,
- hb_map_t* klass_mapping /* INOUT */);
-
-/* buffer **position** var allocations */
-#define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */
-#define attach_type() var.u8[2] /* attachment type */
-/* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */
-
-enum attach_type_t {
- ATTACH_TYPE_NONE = 0X00,
-
- /* Each attachment should be either a mark or a cursive; can't be both. */
- ATTACH_TYPE_MARK = 0X01,
- ATTACH_TYPE_CURSIVE = 0X02,
-};
-
-
-/* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
-
-typedef HBUINT16 Value;
-
-typedef UnsizedArrayOf<Value> ValueRecord;
-
-struct ValueFormat : HBUINT16
-{
- enum Flags {
- xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */
- yPlacement = 0x0002u, /* Includes vertical adjustment for placement */
- xAdvance = 0x0004u, /* Includes horizontal adjustment for advance */
- yAdvance = 0x0008u, /* Includes vertical adjustment for advance */
- xPlaDevice = 0x0010u, /* Includes horizontal Device table for placement */
- yPlaDevice = 0x0020u, /* Includes vertical Device table for placement */
- xAdvDevice = 0x0040u, /* Includes horizontal Device table for advance */
- yAdvDevice = 0x0080u, /* Includes vertical Device table for advance */
- ignored = 0x0F00u, /* Was used in TrueType Open for MM fonts */
- reserved = 0xF000u, /* For future use */
-
- devices = 0x00F0u /* Mask for having any Device table */
- };
-
-/* All fields are options. Only those available advance the value pointer. */
-#if 0
- HBINT16 xPlacement; /* Horizontal adjustment for
- * placement--in design units */
- HBINT16 yPlacement; /* Vertical adjustment for
- * placement--in design units */
- HBINT16 xAdvance; /* Horizontal adjustment for
- * advance--in design units (only used
- * for horizontal writing) */
- HBINT16 yAdvance; /* Vertical adjustment for advance--in
- * design units (only used for vertical
- * writing) */
- Offset16To<Device> xPlaDevice; /* Offset to Device table for
- * horizontal placement--measured from
- * beginning of PosTable (may be NULL) */
- Offset16To<Device> yPlaDevice; /* Offset to Device table for vertical
- * placement--measured from beginning
- * of PosTable (may be NULL) */
- Offset16To<Device> xAdvDevice; /* Offset to Device table for
- * horizontal advance--measured from
- * beginning of PosTable (may be NULL) */
- Offset16To<Device> yAdvDevice; /* Offset to Device table for vertical
- * advance--measured from beginning of
- * PosTable (may be NULL) */
-#endif
-
- IntType& operator = (uint16_t i) { v = i; return *this; }
-
- unsigned int get_len () const { return hb_popcount ((unsigned int) *this); }
- unsigned int get_size () const { return get_len () * Value::static_size; }
-
- bool apply_value (hb_ot_apply_context_t *c,
- const void *base,
- const Value *values,
- hb_glyph_position_t &glyph_pos) const
- {
- bool ret = false;
- unsigned int format = *this;
- if (!format) return ret;
-
- hb_font_t *font = c->font;
- bool horizontal =
-#ifndef HB_NO_VERTICAL
- HB_DIRECTION_IS_HORIZONTAL (c->direction)
-#else
- true
-#endif
- ;
-
- if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++, &ret));
- if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++, &ret));
- if (format & xAdvance) {
- if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values, &ret));
- values++;
- }
- /* y_advance values grow downward but font-space grows upward, hence negation */
- if (format & yAdvance) {
- if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values, &ret));
- values++;
- }
-
- if (!has_device ()) return ret;
-
- bool use_x_device = font->x_ppem || font->num_coords;
- bool use_y_device = font->y_ppem || font->num_coords;
-
- if (!use_x_device && !use_y_device) return ret;
-
- const VariationStore &store = c->var_store;
-
- /* pixel -> fractional pixel */
- if (format & xPlaDevice) {
- if (use_x_device) glyph_pos.x_offset += (base + get_device (values, &ret)).get_x_delta (font, store);
- values++;
- }
- if (format & yPlaDevice) {
- if (use_y_device) glyph_pos.y_offset += (base + get_device (values, &ret)).get_y_delta (font, store);
- values++;
- }
- if (format & xAdvDevice) {
- if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store);
- values++;
- }
- if (format & yAdvDevice) {
- /* y_advance values grow downward but font-space grows upward, hence negation */
- if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store);
- values++;
- }
- return ret;
- }
-
- unsigned int get_effective_format (const Value *values) const
- {
- unsigned int format = *this;
- for (unsigned flag = xPlacement; flag <= yAdvDevice; flag = flag << 1) {
- if (format & flag) should_drop (*values++, (Flags) flag, &format);
- }
-
- return format;
- }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- unsigned int get_effective_format (Iterator it) const {
- unsigned int new_format = 0;
-
- for (const hb_array_t<const Value>& values : it)
- new_format = new_format | get_effective_format (&values);
-
- return new_format;
- }
-
- void copy_values (hb_serialize_context_t *c,
- unsigned int new_format,
- const void *base,
- const Value *values,
- const hb_map_t *layout_variation_idx_map) const
- {
- unsigned int format = *this;
- if (!format) return;
-
- if (format & xPlacement) copy_value (c, new_format, xPlacement, *values++);
- if (format & yPlacement) copy_value (c, new_format, yPlacement, *values++);
- if (format & xAdvance) copy_value (c, new_format, xAdvance, *values++);
- if (format & yAdvance) copy_value (c, new_format, yAdvance, *values++);
-
- if (format & xPlaDevice) copy_device (c, base, values++, layout_variation_idx_map);
- if (format & yPlaDevice) copy_device (c, base, values++, layout_variation_idx_map);
- if (format & xAdvDevice) copy_device (c, base, values++, layout_variation_idx_map);
- if (format & yAdvDevice) copy_device (c, base, values++, layout_variation_idx_map);
- }
-
- void copy_value (hb_serialize_context_t *c,
- unsigned int new_format,
- Flags flag,
- Value value) const
- {
- // Filter by new format.
- if (!(new_format & flag)) return;
- c->copy (value);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const void *base,
- const hb_array_t<const Value>& values) const
- {
- unsigned format = *this;
- unsigned i = 0;
- if (format & xPlacement) i++;
- if (format & yPlacement) i++;
- if (format & xAdvance) i++;
- if (format & yAdvance) i++;
- if (format & xPlaDevice)
- {
- (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices);
- i++;
- }
-
- if (format & ValueFormat::yPlaDevice)
- {
- (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices);
- i++;
- }
-
- if (format & ValueFormat::xAdvDevice)
- {
-
- (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices);
- i++;
- }
-
- if (format & ValueFormat::yAdvDevice)
- {
-
- (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices);
- i++;
- }
- }
-
- private:
- bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const
- {
- unsigned int format = *this;
-
- if (format & xPlacement) values++;
- if (format & yPlacement) values++;
- if (format & xAdvance) values++;
- if (format & yAdvance) values++;
-
- if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
- if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
- if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
- if ((format & yAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
-
- return true;
- }
-
- static inline Offset16To<Device>& get_device (Value* value)
- {
- return *static_cast<Offset16To<Device> *> (value);
- }
- static inline const Offset16To<Device>& get_device (const Value* value, bool *worked=nullptr)
- {
- if (worked) *worked |= bool (*value);
- return *static_cast<const Offset16To<Device> *> (value);
- }
-
- bool copy_device (hb_serialize_context_t *c, const void *base,
- const Value *src_value, const hb_map_t *layout_variation_idx_map) const
- {
- Value *dst_value = c->copy (*src_value);
-
- if (!dst_value) return false;
- if (*dst_value == 0) return true;
-
- *dst_value = 0;
- c->push ();
- if ((base + get_device (src_value)).copy (c, layout_variation_idx_map))
- {
- c->add_link (*dst_value, c->pop_pack ());
- return true;
- }
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- static inline const HBINT16& get_short (const Value* value, bool *worked=nullptr)
- {
- if (worked) *worked |= bool (*value);
- return *reinterpret_cast<const HBINT16 *> (value);
- }
-
- public:
-
- bool has_device () const
- {
- unsigned int format = *this;
- return (format & devices) != 0;
- }
-
- bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
- }
-
- bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
- {
- TRACE_SANITIZE (this);
- unsigned int len = get_len ();
-
- if (!c->check_range (values, count, get_size ())) return_trace (false);
-
- if (!has_device ()) return_trace (true);
-
- for (unsigned int i = 0; i < count; i++) {
- if (!sanitize_value_devices (c, base, values))
- return_trace (false);
- values += len;
- }
-
- return_trace (true);
- }
-
- /* Just sanitize referenced Device tables. Doesn't check the values themselves. */
- bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const
- {
- TRACE_SANITIZE (this);
-
- if (!has_device ()) return_trace (true);
-
- for (unsigned int i = 0; i < count; i++) {
- if (!sanitize_value_devices (c, base, values))
- return_trace (false);
- values += stride;
- }
-
- return_trace (true);
- }
-
- private:
-
- void should_drop (Value value, Flags flag, unsigned int* format) const
- {
- if (value) return;
- *format = *format & ~flag;
- }
-
-};
-
-template<typename Iterator, typename SrcLookup>
-static void SinglePos_serialize (hb_serialize_context_t *c,
- const SrcLookup *src,
- Iterator it,
- const hb_map_t *layout_variation_idx_map);
-
-
-struct AnchorFormat1
-{
- void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
- float *x, float *y) const
- {
- hb_font_t *font = c->font;
- *x = font->em_fscale_x (xCoordinate);
- *y = font->em_fscale_y (yCoordinate);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- AnchorFormat1* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- AnchorFormat1* out = c->embed<AnchorFormat1> (this);
- if (!out) return_trace (out);
- out->format = 1;
- return_trace (out);
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- FWORD xCoordinate; /* Horizontal value--in design units */
- FWORD yCoordinate; /* Vertical value--in design units */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct AnchorFormat2
-{
- void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
- float *x, float *y) const
- {
- hb_font_t *font = c->font;
-
-#ifdef HB_NO_HINTING
- *x = font->em_fscale_x (xCoordinate);
- *y = font->em_fscale_y (yCoordinate);
- return;
-#endif
-
- unsigned int x_ppem = font->x_ppem;
- unsigned int y_ppem = font->y_ppem;
- hb_position_t cx = 0, cy = 0;
- bool ret;
-
- ret = (x_ppem || y_ppem) &&
- font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
- *x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate);
- *y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- AnchorFormat2* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- return_trace (c->embed<AnchorFormat2> (this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- FWORD xCoordinate; /* Horizontal value--in design units */
- FWORD yCoordinate; /* Vertical value--in design units */
- HBUINT16 anchorPoint; /* Index to glyph contour point */
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct AnchorFormat3
-{
- void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
- float *x, float *y) const
- {
- hb_font_t *font = c->font;
- *x = font->em_fscale_x (xCoordinate);
- *y = font->em_fscale_y (yCoordinate);
-
- if (font->x_ppem || font->num_coords)
- *x += (this+xDeviceTable).get_x_delta (font, c->var_store);
- if (font->y_ppem || font->num_coords)
- *y += (this+yDeviceTable).get_y_delta (font, c->var_store);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
- }
-
- AnchorFormat3* copy (hb_serialize_context_t *c,
- const hb_map_t *layout_variation_idx_map) const
- {
- TRACE_SERIALIZE (this);
- if (!layout_variation_idx_map) return_trace (nullptr);
-
- auto *out = c->embed<AnchorFormat3> (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- out->xDeviceTable.serialize_copy (c, xDeviceTable, this, 0, hb_serialize_context_t::Head, layout_variation_idx_map);
- out->yDeviceTable.serialize_copy (c, yDeviceTable, this, 0, hb_serialize_context_t::Head, layout_variation_idx_map);
- return_trace (out);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- (this+xDeviceTable).collect_variation_indices (c->layout_variation_indices);
- (this+yDeviceTable).collect_variation_indices (c->layout_variation_indices);
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 3 */
- FWORD xCoordinate; /* Horizontal value--in design units */
- FWORD yCoordinate; /* Vertical value--in design units */
- Offset16To<Device>
- xDeviceTable; /* Offset to Device table for X
- * coordinate-- from beginning of
- * Anchor table (may be NULL) */
- Offset16To<Device>
- yDeviceTable; /* Offset to Device table for Y
- * coordinate-- from beginning of
- * Anchor table (may be NULL) */
- public:
- DEFINE_SIZE_STATIC (10);
-};
-
-struct Anchor
-{
- void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
- float *x, float *y) const
- {
- *x = *y = 0;
- switch (u.format) {
- case 1: u.format1.get_anchor (c, glyph_id, x, y); return;
- case 2: u.format2.get_anchor (c, glyph_id, x, y); return;
- case 3: u.format3.get_anchor (c, glyph_id, x, y); return;
- default: return;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format) {
- case 1: return_trace (u.format1.sanitize (c));
- case 2: return_trace (u.format2.sanitize (c));
- case 3: return_trace (u.format3.sanitize (c));
- default:return_trace (true);
- }
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- switch (u.format) {
- case 1: return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
- case 2:
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- {
- // AnchorFormat 2 just containins extra hinting information, so
- // if hints are being dropped convert to format 1.
- return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
- }
- return_trace (bool (reinterpret_cast<Anchor *> (u.format2.copy (c->serializer))));
- case 3: return_trace (bool (reinterpret_cast<Anchor *> (u.format3.copy (c->serializer,
- c->plan->layout_variation_idx_map))));
- default:return_trace (false);
- }
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- switch (u.format) {
- case 1: case 2:
- return;
- case 3:
- u.format3.collect_variation_indices (c);
- return;
- default: return;
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- AnchorFormat1 format1;
- AnchorFormat2 format2;
- AnchorFormat3 format3;
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-};
-
-
-struct AnchorMatrix
-{
- const Anchor& get_anchor (unsigned int row, unsigned int col,
- unsigned int cols, bool *found) const
- {
- *found = false;
- if (unlikely (row >= rows || col >= cols)) return Null (Anchor);
- *found = !matrixZ[row * cols + col].is_null ();
- return this+matrixZ[row * cols + col];
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- Iterator index_iter) const
- {
- for (unsigned i : index_iter)
- (this+matrixZ[i]).collect_variation_indices (c);
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool subset (hb_subset_context_t *c,
- unsigned num_rows,
- Iterator index_iter) const
- {
- TRACE_SUBSET (this);
-
- auto *out = c->serializer->start_embed (this);
-
- if (!index_iter) return_trace (false);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- out->rows = num_rows;
- for (const unsigned i : index_iter)
- {
- auto *offset = c->serializer->embed (matrixZ[i]);
- if (!offset) return_trace (false);
- offset->serialize_subset (c, matrixZ[i], this);
- }
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
- {
- TRACE_SANITIZE (this);
- if (!c->check_struct (this)) return_trace (false);
- if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
- unsigned int count = rows * cols;
- if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
- for (unsigned int i = 0; i < count; i++)
- if (!matrixZ[i].sanitize (c, this)) return_trace (false);
- return_trace (true);
- }
-
- HBUINT16 rows; /* Number of rows */
- UnsizedArrayOf<Offset16To<Anchor>>
- matrixZ; /* Matrix of offsets to Anchor tables--
- * from beginning of AnchorMatrix table */
- public:
- DEFINE_SIZE_ARRAY (2, matrixZ);
-};
-
-
-struct MarkRecord
-{
- friend struct MarkArray;
-
- unsigned get_class () const { return (unsigned) klass; }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
- }
-
- MarkRecord *subset (hb_subset_context_t *c,
- const void *src_base,
- const hb_map_t *klass_mapping) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- out->klass = klass_mapping->get (klass);
- out->markAnchor.serialize_subset (c, markAnchor, src_base);
- return_trace (out);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const void *src_base) const
- {
- (src_base+markAnchor).collect_variation_indices (c);
- }
-
- protected:
- HBUINT16 klass; /* Class defined for this mark */
- Offset16To<Anchor>
- markAnchor; /* Offset to Anchor table--from
- * beginning of MarkArray table */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Coverage order */
-{
- bool apply (hb_ot_apply_context_t *c,
- unsigned int mark_index, unsigned int glyph_index,
- const AnchorMatrix &anchors, unsigned int class_count,
- unsigned int glyph_pos) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- const MarkRecord &record = Array16Of<MarkRecord>::operator[](mark_index);
- unsigned int mark_class = record.klass;
-
- const Anchor& mark_anchor = this + record.markAnchor;
- bool found;
- const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
- /* If this subtable doesn't have an anchor for this base and this class,
- * return false such that the subsequent subtables have a chance at it. */
- if (unlikely (!found)) return_trace (false);
-
- float mark_x, mark_y, base_x, base_y;
-
- 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);
-
- hb_glyph_position_t &o = buffer->cur_pos();
- o.x_offset = roundf (base_x - mark_x);
- o.y_offset = roundf (base_y - mark_y);
- o.attach_type() = ATTACH_TYPE_MARK;
- o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
-
- buffer->idx++;
- return_trace (true);
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool subset (hb_subset_context_t *c,
- Iterator coverage,
- const hb_map_t *klass_mapping) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-
- auto* out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- auto mark_iter =
- + hb_zip (coverage, this->iter ())
- | hb_filter (glyphset, hb_first)
- | hb_map (hb_second)
- ;
-
- unsigned new_length = 0;
- for (const auto& mark_record : mark_iter) {
- if (unlikely (!mark_record.subset (c, this, klass_mapping)))
- return_trace (false);
- new_length++;
- }
-
- if (unlikely (!c->serializer->check_assign (out->len, new_length,
- HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)))
- return_trace (false);
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (Array16Of<MarkRecord>::sanitize (c, this));
- }
-};
-
-
-/* Lookups */
-
-struct SinglePosFormat1
-{
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- if (!valueFormat.has_device ()) return;
-
- auto it =
- + hb_iter (this+coverage)
- | hb_filter (c->glyph_set)
- ;
-
- if (!it) return;
- valueFormat.collect_variation_indices (c, this, values.as_array (valueFormat.get_len ()));
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- ValueFormat get_value_format () const { return valueFormat; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- valueFormat.apply_value (c, this, values, buffer->cur_pos());
-
- buffer->idx++;
- return_trace (true);
- }
-
- template<typename Iterator,
- typename SrcLookup,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- const SrcLookup *src,
- Iterator it,
- ValueFormat newFormat,
- const hb_map_t *layout_variation_idx_map)
- {
- if (unlikely (!c->extend_min (this))) return;
- if (unlikely (!c->check_assign (valueFormat,
- newFormat,
- HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
-
- for (const hb_array_t<const Value>& _ : + it | hb_map (hb_second))
- {
- src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map);
- // Only serialize the first entry in the iterator, the rest are assumed to
- // be the same.
- break;
- }
-
- auto glyphs =
- + it
- | hb_map_retains_sorting (hb_first)
- ;
-
- coverage.serialize_serialize (c, glyphs);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto it =
- + hb_iter (this+coverage)
- | hb_filter (glyphset)
- | hb_map_retains_sorting (glyph_map)
- | hb_zip (hb_repeat (values.as_array (valueFormat.get_len ())))
- ;
-
- bool ret = bool (it);
- SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map);
- return_trace (ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- coverage.sanitize (c, this) &&
- valueFormat.sanitize_value (c, this, values));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- ValueFormat valueFormat; /* Defines the types of data in the
- * ValueRecord */
- ValueRecord values; /* Defines positioning
- * value(s)--applied to all glyphs in
- * the Coverage table */
- public:
- DEFINE_SIZE_ARRAY (6, values);
-};
-
-struct SinglePosFormat2
-{
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- if (!valueFormat.has_device ()) return;
-
- auto it =
- + hb_zip (this+coverage, hb_range ((unsigned) valueCount))
- | hb_filter (c->glyph_set, hb_first)
- ;
-
- if (!it) return;
-
- unsigned sub_length = valueFormat.get_len ();
- const hb_array_t<const Value> values_array = values.as_array (valueCount * sub_length);
-
- for (unsigned i : + it
- | hb_map (hb_second))
- valueFormat.collect_variation_indices (c, this, values_array.sub_array (i * sub_length, sub_length));
-
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- ValueFormat get_value_format () const { return valueFormat; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- if (likely (index >= valueCount)) return_trace (false);
-
- valueFormat.apply_value (c, this,
- &values[index * valueFormat.get_len ()],
- buffer->cur_pos());
-
- buffer->idx++;
- return_trace (true);
- }
-
- template<typename Iterator,
- typename SrcLookup,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- const SrcLookup *src,
- Iterator it,
- ValueFormat newFormat,
- const hb_map_t *layout_variation_idx_map)
- {
- auto out = c->extend_min (this);
- if (unlikely (!out)) return;
- if (unlikely (!c->check_assign (valueFormat, newFormat, HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
- if (unlikely (!c->check_assign (valueCount, it.len (), HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return;
-
- + it
- | hb_map (hb_second)
- | hb_apply ([&] (hb_array_t<const Value> _)
- { src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map); })
- ;
-
- auto glyphs =
- + it
- | hb_map_retains_sorting (hb_first)
- ;
-
- coverage.serialize_serialize (c, glyphs);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- unsigned sub_length = valueFormat.get_len ();
- auto values_array = values.as_array (valueCount * sub_length);
-
- auto it =
- + hb_zip (this+coverage, hb_range ((unsigned) valueCount))
- | hb_filter (glyphset, hb_first)
- | hb_map_retains_sorting ([&] (const hb_pair_t<hb_codepoint_t, unsigned>& _)
- {
- return hb_pair (glyph_map[_.first],
- values_array.sub_array (_.second * sub_length,
- sub_length));
- })
- ;
-
- bool ret = bool (it);
- SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map);
- return_trace (ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- coverage.sanitize (c, this) &&
- valueFormat.sanitize_values (c, this, values, valueCount));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- ValueFormat valueFormat; /* Defines the types of data in the
- * ValueRecord */
- HBUINT16 valueCount; /* Number of ValueRecords */
- ValueRecord values; /* Array of ValueRecords--positioning
- * values applied to glyphs */
- public:
- DEFINE_SIZE_ARRAY (8, values);
-};
-
-struct SinglePos
-{
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- unsigned get_format (Iterator glyph_val_iter_pairs)
- {
- hb_array_t<const Value> first_val_iter = hb_second (*glyph_val_iter_pairs);
-
- for (const auto iter : glyph_val_iter_pairs)
- for (const auto _ : hb_zip (iter.second, first_val_iter))
- if (_.first != _.second)
- return 2;
-
- return 1;
- }
-
-
- template<typename Iterator,
- typename SrcLookup,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- const SrcLookup* src,
- Iterator glyph_val_iter_pairs,
- const hb_map_t *layout_variation_idx_map)
- {
- if (unlikely (!c->extend_min (u.format))) return;
- unsigned format = 2;
- ValueFormat new_format = src->get_value_format ();
-
- if (glyph_val_iter_pairs)
- {
- format = get_format (glyph_val_iter_pairs);
- new_format = src->get_value_format ().get_effective_format (+ glyph_val_iter_pairs | hb_map (hb_second));
- }
-
- u.format = format;
- switch (u.format) {
- case 1: u.format1.serialize (c,
- src,
- glyph_val_iter_pairs,
- new_format,
- layout_variation_idx_map);
- return;
- case 2: u.format2.serialize (c,
- src,
- glyph_val_iter_pairs,
- new_format,
- layout_variation_idx_map);
- return;
- default:return;
- }
- }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- SinglePosFormat1 format1;
- SinglePosFormat2 format2;
- } u;
-};
-
-template<typename Iterator, typename SrcLookup>
-static void
-SinglePos_serialize (hb_serialize_context_t *c,
- const SrcLookup *src,
- Iterator it,
- const hb_map_t *layout_variation_idx_map)
-{ c->start_embed<SinglePos> ()->serialize (c, src, it, layout_variation_idx_map); }
-
-
-struct PairValueRecord
-{
- friend struct PairSet;
-
- int cmp (hb_codepoint_t k) const
- { return secondGlyph.cmp (k); }
-
- struct context_t
- {
- const void *base;
- const ValueFormat *valueFormats;
- const ValueFormat *newFormats;
- unsigned len1; /* valueFormats[0].get_len() */
- const hb_map_t *glyph_map;
- const hb_map_t *layout_variation_idx_map;
- };
-
- bool subset (hb_subset_context_t *c,
- context_t *closure) const
- {
- TRACE_SERIALIZE (this);
- auto *s = c->serializer;
- auto *out = s->start_embed (*this);
- if (unlikely (!s->extend_min (out))) return_trace (false);
-
- out->secondGlyph = (*closure->glyph_map)[secondGlyph];
-
- closure->valueFormats[0].copy_values (s,
- closure->newFormats[0],
- closure->base, &values[0],
- closure->layout_variation_idx_map);
- closure->valueFormats[1].copy_values (s,
- closure->newFormats[1],
- closure->base,
- &values[closure->len1],
- closure->layout_variation_idx_map);
-
- return_trace (true);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const ValueFormat *valueFormats,
- const void *base) const
- {
- unsigned record1_len = valueFormats[0].get_len ();
- unsigned record2_len = valueFormats[1].get_len ();
- const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len);
-
- if (valueFormats[0].has_device ())
- valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len));
-
- if (valueFormats[1].has_device ())
- valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len));
- }
-
- bool intersects (const hb_set_t& glyphset) const
- {
- return glyphset.has(secondGlyph);
- }
-
- const Value* get_values_1 () const
- {
- return &values[0];
- }
-
- const Value* get_values_2 (ValueFormat format1) const
- {
- return &values[format1.get_len ()];
- }
-
- protected:
- HBGlyphID16 secondGlyph; /* GlyphID of second glyph in the
- * pair--first glyph is listed in the
- * Coverage table */
- ValueRecord values; /* Positioning data for the first glyph
- * followed by for second glyph */
- public:
- DEFINE_SIZE_ARRAY (2, values);
-};
-
-struct PairSet
-{
- friend struct PairPosFormat1;
-
- bool intersects (const hb_set_t *glyphs,
- const ValueFormat *valueFormats) const
- {
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
- {
- if (glyphs->has (record->secondGlyph))
- return true;
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
- return false;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c,
- const ValueFormat *valueFormats) const
- {
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = &firstPairValueRecord;
- c->input->add_array (&record->secondGlyph, len, record_size);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const ValueFormat *valueFormats) const
- {
- unsigned len1 = valueFormats[0].get_len ();
- unsigned len2 = valueFormats[1].get_len ();
- unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned count = len;
- for (unsigned i = 0; i < count; i++)
- {
- if (c->glyph_set->has (record->secondGlyph))
- { record->collect_variation_indices (c, valueFormats, this); }
-
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
- }
-
- bool apply (hb_ot_apply_context_t *c,
- const ValueFormat *valueFormats,
- unsigned int pos) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
- &firstPairValueRecord,
- len,
- record_size);
- if (record)
- {
- bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
- bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
- if (applied_first || applied_second)
- buffer->unsafe_to_break (buffer->idx, pos + 1);
- if (len2)
- pos++;
- buffer->idx = pos;
- return_trace (true);
- }
- buffer->unsafe_to_concat (buffer->idx, pos + 1);
- return_trace (false);
- }
-
- bool subset (hb_subset_context_t *c,
- const ValueFormat valueFormats[2],
- const ValueFormat newFormats[2]) const
- {
- TRACE_SUBSET (this);
- auto snap = c->serializer->snapshot ();
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->len = 0;
-
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- unsigned len1 = valueFormats[0].get_len ();
- unsigned len2 = valueFormats[1].get_len ();
- unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
-
- PairValueRecord::context_t context =
- {
- this,
- valueFormats,
- newFormats,
- len1,
- &glyph_map,
- c->plan->layout_variation_idx_map
- };
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned count = len, num = 0;
- for (unsigned i = 0; i < count; i++)
- {
- if (glyphset.has (record->secondGlyph)
- && record->subset (c, &context)) num++;
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
-
- out->len = num;
- if (!num) c->serializer->revert (snap);
- return_trace (num);
- }
-
- struct sanitize_closure_t
- {
- const ValueFormat *valueFormats;
- unsigned int len1; /* valueFormats[0].get_len() */
- unsigned int stride; /* 1 + len1 + len2 */
- };
-
- bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
- {
- TRACE_SANITIZE (this);
- if (!(c->check_struct (this)
- && c->check_range (&firstPairValueRecord,
- len,
- HBUINT16::static_size,
- closure->stride))) return_trace (false);
-
- unsigned int count = len;
- const PairValueRecord *record = &firstPairValueRecord;
- return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
- closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
- }
-
- protected:
- HBUINT16 len; /* Number of PairValueRecords */
- PairValueRecord firstPairValueRecord;
- /* Array of PairValueRecords--ordered
- * by GlyphID of the second glyph */
- public:
- DEFINE_SIZE_MIN (2);
-};
-
-struct PairPosFormat1
-{
- bool intersects (const hb_set_t *glyphs) const
- {
- return
- + hb_zip (this+coverage, pairSet)
- | hb_filter (*glyphs, hb_first)
- | hb_map (hb_second)
- | hb_map ([glyphs, this] (const Offset16To<PairSet> &_)
- { return (this+_).intersects (glyphs, valueFormat); })
- | hb_any
- ;
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- if ((!valueFormat[0].has_device ()) && (!valueFormat[1].has_device ())) return;
-
- auto it =
- + hb_zip (this+coverage, pairSet)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- ;
-
- if (!it) return;
- + it
- | hb_map (hb_add (this))
- | hb_apply ([&] (const PairSet& _) { _.collect_variation_indices (c, valueFormat); })
- ;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
- unsigned int count = pairSet.len;
- for (unsigned int i = 0; i < count; i++)
- (this+pairSet[i]).collect_glyphs (c, valueFormat);
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
- 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));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
- out->valueFormat[0] = valueFormat[0];
- out->valueFormat[1] = valueFormat[1];
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- {
- hb_pair_t<unsigned, unsigned> newFormats = compute_effective_value_formats (glyphset);
- out->valueFormat[0] = newFormats.first;
- out->valueFormat[1] = newFormats.second;
- }
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
-
- + hb_zip (this+coverage, pairSet)
- | hb_filter (glyphset, hb_first)
- | hb_filter ([this, c, out] (const Offset16To<PairSet>& _)
- {
- auto snap = c->serializer->snapshot ();
- auto *o = out->pairSet.serialize_append (c->serializer);
- if (unlikely (!o)) return false;
- bool ret = o->serialize_subset (c, _, this, valueFormat, out->valueFormat);
- if (!ret)
- {
- out->pairSet.pop ();
- c->serializer->revert (snap);
- }
- return ret;
- },
- hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
-
- return_trace (bool (new_coverage));
- }
-
-
- hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_set_t& glyphset) const
- {
- unsigned len1 = valueFormat[0].get_len ();
- unsigned len2 = valueFormat[1].get_len ();
- unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
-
- unsigned format1 = 0;
- unsigned format2 = 0;
- for (const Offset16To<PairSet>& _ :
- + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second))
- {
- const PairSet& set = (this + _);
- const PairValueRecord *record = &set.firstPairValueRecord;
-
- for (unsigned i = 0; i < set.len; i++)
- {
- if (record->intersects (glyphset))
- {
- format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 ());
- format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0]));
- }
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
- }
-
- return hb_pair (format1, format2);
- }
-
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
-
- if (!c->check_struct (this)) return_trace (false);
-
- unsigned int len1 = valueFormat[0].get_len ();
- unsigned int len2 = valueFormat[1].get_len ();
- PairSet::sanitize_closure_t closure =
- {
- valueFormat,
- len1,
- 1 + len1 + len2
- };
-
- return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- ValueFormat valueFormat[2]; /* [0] Defines the types of data in
- * ValueRecord1--for the first glyph
- * in the pair--may be zero (0) */
- /* [1] Defines the types of data in
- * ValueRecord2--for the second glyph
- * in the pair--may be zero (0) */
- Array16OfOffset16To<PairSet>
- pairSet; /* Array of PairSet tables
- * ordered by Coverage Index */
- public:
- DEFINE_SIZE_ARRAY (10, pairSet);
-};
-
-struct PairPosFormat2
-{
- bool intersects (const hb_set_t *glyphs) const
- {
- return (this+coverage).intersects (glyphs) &&
- (this+classDef2).intersects (glyphs);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- if (!intersects (c->glyph_set)) return;
- if ((!valueFormat1.has_device ()) && (!valueFormat2.has_device ())) return;
-
- hb_set_t klass1_glyphs, klass2_glyphs;
- if (!(this+classDef1).collect_coverage (&klass1_glyphs)) return;
- if (!(this+classDef2).collect_coverage (&klass2_glyphs)) return;
-
- hb_set_t class1_set, class2_set;
- for (const unsigned cp : + c->glyph_set->iter () | hb_filter (this + coverage))
- {
- if (!klass1_glyphs.has (cp)) class1_set.add (0);
- else
- {
- unsigned klass1 = (this+classDef1).get (cp);
- class1_set.add (klass1);
- }
- }
-
- class2_set.add (0);
- for (const unsigned cp : + c->glyph_set->iter () | hb_filter (klass2_glyphs))
- {
- unsigned klass2 = (this+classDef2).get (cp);
- class2_set.add (klass2);
- }
-
- if (class1_set.is_empty ()
- || class2_set.is_empty ()
- || (class2_set.get_population() == 1 && class2_set.has(0)))
- return;
-
- unsigned len1 = valueFormat1.get_len ();
- unsigned len2 = valueFormat2.get_len ();
- const hb_array_t<const Value> values_array = values.as_array ((unsigned)class1Count * (unsigned) class2Count * (len1 + len2));
- for (const unsigned class1_idx : class1_set.iter ())
- {
- for (const unsigned class2_idx : class2_set.iter ())
- {
- unsigned start_offset = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
- if (valueFormat1.has_device ())
- valueFormat1.collect_variation_indices (c, this, values_array.sub_array (start_offset, len1));
-
- if (valueFormat2.has_device ())
- valueFormat2.collect_variation_indices (c, this, values_array.sub_array (start_offset+len1, len2));
- }
- }
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
- if (unlikely (!(this+classDef2).collect_coverage (c->input))) return;
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
- 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 ();
- unsigned int record_len = len1 + len2;
-
- 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))
- {
- 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 = false, applied_second = false;
-
-
- /* Isolate simple kerning and apply it half to each side.
- * Results in better cursor positinoing / underline drawing.
- *
- * Disabled, because causes issues... :-(
- * https://github.com/harfbuzz/harfbuzz/issues/3408
- * https://github.com/harfbuzz/harfbuzz/pull/3235#issuecomment-1029814978
- */
-#ifndef HB_SPLIT_KERN
- if (0)
-#endif
- {
- 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)
- buffer->idx++;
-
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_map_t klass1_map;
- out->classDef1.serialize_subset (c, classDef1, this, &klass1_map, true, true, &(this + coverage));
- out->class1Count = klass1_map.get_population ();
-
- hb_map_t klass2_map;
- out->classDef2.serialize_subset (c, classDef2, this, &klass2_map, true, false);
- out->class2Count = klass2_map.get_population ();
-
- unsigned len1 = valueFormat1.get_len ();
- unsigned len2 = valueFormat2.get_len ();
-
- hb_pair_t<unsigned, unsigned> newFormats = hb_pair (valueFormat1, valueFormat2);
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- newFormats = compute_effective_value_formats (klass1_map, klass2_map);
-
- out->valueFormat1 = newFormats.first;
- out->valueFormat2 = newFormats.second;
-
- for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
- {
- for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
- {
- unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
- valueFormat1.copy_values (c->serializer, newFormats.first, this, &values[idx], c->plan->layout_variation_idx_map);
- valueFormat2.copy_values (c->serializer, newFormats.second, this, &values[idx + len1], c->plan->layout_variation_idx_map);
- }
- }
-
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto it =
- + hb_iter (this+coverage)
- | hb_filter (glyphset)
- | hb_map_retains_sorting (glyph_map)
- ;
-
- out->coverage.serialize_serialize (c->serializer, it);
- return_trace (out->class1Count && out->class2Count && bool (it));
- }
-
-
- hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_map_t& klass1_map,
- const hb_map_t& klass2_map) const
- {
- unsigned len1 = valueFormat1.get_len ();
- unsigned len2 = valueFormat2.get_len ();
-
- unsigned format1 = 0;
- unsigned format2 = 0;
-
- for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
- {
- for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
- {
- unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
- format1 = format1 | valueFormat1.get_effective_format (&values[idx]);
- format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]);
- }
- }
-
- return hb_pair (format1, format2);
- }
-
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!(c->check_struct (this)
- && coverage.sanitize (c, this)
- && classDef1.sanitize (c, this)
- && classDef2.sanitize (c, this))) return_trace (false);
-
- unsigned int len1 = valueFormat1.get_len ();
- unsigned int len2 = valueFormat2.get_len ();
- unsigned int stride = len1 + len2;
- unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
- unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
- return_trace (c->check_range ((const void *) values,
- count,
- record_size) &&
- valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
- valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- ValueFormat valueFormat1; /* ValueRecord definition--for the
- * first glyph of the pair--may be zero
- * (0) */
- ValueFormat valueFormat2; /* ValueRecord definition--for the
- * second glyph of the pair--may be
- * zero (0) */
- Offset16To<ClassDef>
- classDef1; /* Offset to ClassDef table--from
- * beginning of PairPos subtable--for
- * the first glyph of the pair */
- Offset16To<ClassDef>
- classDef2; /* Offset to ClassDef table--from
- * beginning of PairPos subtable--for
- * the second glyph of the pair */
- HBUINT16 class1Count; /* Number of classes in ClassDef1
- * table--includes Class0 */
- HBUINT16 class2Count; /* Number of classes in ClassDef2
- * table--includes Class0 */
- ValueRecord values; /* Matrix of value pairs:
- * class1-major, class2-minor,
- * Each entry has value1 and value2 */
- public:
- DEFINE_SIZE_ARRAY (16, values);
-};
-
-struct PairPos
-{
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- PairPosFormat1 format1;
- PairPosFormat2 format2;
- } u;
-};
-
-
-struct EntryExitRecord
-{
- friend struct CursivePosFormat1;
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const void *src_base) const
- {
- (src_base+entryAnchor).collect_variation_indices (c);
- (src_base+exitAnchor).collect_variation_indices (c);
- }
-
- EntryExitRecord* subset (hb_subset_context_t *c,
- const void *src_base) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- out->entryAnchor.serialize_subset (c, entryAnchor, src_base);
- out->exitAnchor.serialize_subset (c, exitAnchor, src_base);
- return_trace (out);
- }
-
- protected:
- Offset16To<Anchor>
- entryAnchor; /* Offset to EntryAnchor table--from
- * beginning of CursivePos
- * subtable--may be NULL */
- Offset16To<Anchor>
- exitAnchor; /* Offset to ExitAnchor table--from
- * beginning of CursivePos
- * subtable--may be NULL */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-static void
-reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent);
-
-struct CursivePosFormat1
-{
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- + hb_zip (this+coverage, entryExitRecord)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_apply ([&] (const EntryExitRecord& record) { record.collect_variation_indices (c, this); })
- ;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
-
- const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
- if (!this_record.entryAnchor) return_trace (false);
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
- 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)
- {
- 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;
-
- buffer->unsafe_to_break (i, j);
- float entry_x, entry_y, exit_x, exit_y;
- (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
- (this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
-
- hb_glyph_position_t *pos = buffer->pos;
-
- hb_position_t d;
- /* Main-direction adjustment */
- switch (c->direction) {
- case HB_DIRECTION_LTR:
- pos[i].x_advance = roundf (exit_x) + pos[i].x_offset;
-
- d = roundf (entry_x) + pos[j].x_offset;
- pos[j].x_advance -= d;
- pos[j].x_offset -= d;
- break;
- case HB_DIRECTION_RTL:
- d = roundf (exit_x) + pos[i].x_offset;
- pos[i].x_advance -= d;
- pos[i].x_offset -= d;
-
- pos[j].x_advance = roundf (entry_x) + pos[j].x_offset;
- break;
- case HB_DIRECTION_TTB:
- pos[i].y_advance = roundf (exit_y) + pos[i].y_offset;
-
- d = roundf (entry_y) + pos[j].y_offset;
- pos[j].y_advance -= d;
- pos[j].y_offset -= d;
- break;
- case HB_DIRECTION_BTT:
- d = roundf (exit_y) + pos[i].y_offset;
- pos[i].y_advance -= d;
- pos[i].y_offset -= d;
-
- pos[j].y_advance = roundf (entry_y);
- break;
- case HB_DIRECTION_INVALID:
- default:
- break;
- }
-
- /* Cross-direction adjustment */
-
- /* We attach child to parent (think graph theory and rooted trees whereas
- * the root stays on baseline and each node aligns itself against its
- * parent.
- *
- * Optimize things for the case of RightToLeft, as that's most common in
- * Arabic. */
- unsigned int child = i;
- unsigned int parent = j;
- hb_position_t x_offset = entry_x - exit_x;
- hb_position_t y_offset = entry_y - exit_y;
- if (!(c->lookup_props & LookupFlag::RightToLeft))
- {
- unsigned int k = child;
- child = parent;
- parent = k;
- x_offset = -x_offset;
- y_offset = -y_offset;
- }
-
- /* If child was already connected to someone else, walk through its old
- * chain and reverse the link direction, such that the whole tree of its
- * previous connection now attaches to new parent. Watch out for case
- * where new parent is on the path from old chain...
- */
- reverse_cursive_minor_offset (pos, child, c->direction, parent);
-
- pos[child].attach_type() = ATTACH_TYPE_CURSIVE;
- pos[child].attach_chain() = (int) parent - (int) child;
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
- if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
- pos[child].y_offset = y_offset;
- else
- pos[child].x_offset = x_offset;
-
- /* If parent was attached to child, separate them.
- * https://github.com/harfbuzz/harfbuzz/issues/2469
- */
- if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain()))
- pos[parent].attach_chain() = 0;
-
- buffer->idx++;
- return_trace (true);
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_subset_context_t *c,
- Iterator it,
- const void *src_base)
- {
- if (unlikely (!c->serializer->extend_min ((*this)))) return;
- this->format = 1;
- this->entryExitRecord.len = it.len ();
-
- for (const EntryExitRecord& entry_record : + it
- | hb_map (hb_second))
- entry_record.subset (c, src_base);
-
- auto glyphs =
- + it
- | hb_map_retains_sorting (hb_first)
- ;
-
- coverage.serialize_serialize (c->serializer, glyphs);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- auto it =
- + hb_zip (this+coverage, entryExitRecord)
- | hb_filter (glyphset, hb_first)
- | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const EntryExitRecord&> p) -> hb_pair_t<hb_codepoint_t, const EntryExitRecord&>
- { return hb_pair (glyph_map[p.first], p.second);})
- ;
-
- bool ret = bool (it);
- out->serialize (c, it, this);
- return_trace (ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- Array16Of<EntryExitRecord>
- entryExitRecord; /* Array of EntryExit records--in
- * Coverage Index order */
- public:
- DEFINE_SIZE_ARRAY (6, entryExitRecord);
-};
-
-struct CursivePos
-{
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- CursivePosFormat1 format1;
- } u;
-};
-
-
-typedef AnchorMatrix BaseArray; /* base-major--
- * in order of BaseCoverage Index--,
- * mark-minor--
- * ordered by class--zero-based. */
-
-static void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage,
- const MarkArray &mark_array,
- const hb_set_t &glyphset,
- hb_map_t* klass_mapping /* INOUT */)
-{
- hb_set_t orig_classes;
-
- + hb_zip (mark_coverage, mark_array)
- | hb_filter (glyphset, hb_first)
- | hb_map (hb_second)
- | hb_map (&MarkRecord::get_class)
- | hb_sink (orig_classes)
- ;
-
- unsigned idx = 0;
- for (auto klass : orig_classes.iter ())
- {
- if (klass_mapping->has (klass)) continue;
- klass_mapping->set (klass, idx);
- idx++;
- }
-}
-
-struct MarkBasePosFormat1
-{
- bool intersects (const hb_set_t *glyphs) const
- {
- return (this+markCoverage).intersects (glyphs) &&
- (this+baseCoverage).intersects (glyphs);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- + hb_zip (this+markCoverage, this+markArray)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
- ;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
-
- unsigned basecount = (this+baseArray).rows;
- auto base_iter =
- + hb_zip (this+baseCoverage, hb_range (basecount))
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- ;
-
- hb_sorted_vector_t<unsigned> base_indexes;
- for (const unsigned row : base_iter)
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (base_indexes)
- ;
- }
- (this+baseArray).collect_variation_indices (c, base_indexes.iter ());
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
- if (unlikely (!(this+baseCoverage).collect_coverage (c->input))) return;
- }
-
- const Coverage &get_coverage () const { return this+markCoverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
- if (likely (mark_index == NOT_COVERED)) return_trace (false);
-
- /* Now we search backwards for a non-mark glyph */
- 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);
- do {
- 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...
- * ...but stop if we find a mark in the MultipleSubst sequence:
- * https://github.com/harfbuzz/harfbuzz/issues/1020 */
- if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) ||
- 0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) ||
- (skippy_iter.idx == 0 ||
- _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx - 1]) ||
- _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) !=
- _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) ||
- _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) !=
- _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx - 1]) + 1
- ))
- break;
- skippy_iter.reject ();
- } while (true);
-
- /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
- //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)
- {
- 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));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
-
- if (!klass_mapping.get_population ()) return_trace (false);
- out->classCount = klass_mapping.get_population ();
-
- auto mark_iter =
- + hb_zip (this+markCoverage, this+markArray)
- | hb_filter (glyphset, hb_first)
- ;
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + mark_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
- out->markArray.serialize_subset (c, markArray, this,
- (this+markCoverage).iter (),
- &klass_mapping);
-
- unsigned basecount = (this+baseArray).rows;
- auto base_iter =
- + hb_zip (this+baseCoverage, hb_range (basecount))
- | hb_filter (glyphset, hb_first)
- ;
-
- new_coverage.reset ();
- + base_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
- hb_sorted_vector_t<unsigned> base_indexes;
- for (const unsigned row : + base_iter
- | hb_map (hb_second))
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (base_indexes)
- ;
- }
-
- out->baseArray.serialize_subset (c, baseArray, this,
- base_iter.len (),
- base_indexes.iter ());
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- markCoverage.sanitize (c, this) &&
- baseCoverage.sanitize (c, this) &&
- markArray.sanitize (c, this) &&
- baseArray.sanitize (c, this, (unsigned int) classCount));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
- markCoverage; /* Offset to MarkCoverage table--from
- * beginning of MarkBasePos subtable */
- Offset16To<Coverage>
- baseCoverage; /* Offset to BaseCoverage table--from
- * beginning of MarkBasePos subtable */
- HBUINT16 classCount; /* Number of classes defined for marks */
- Offset16To<MarkArray>
- markArray; /* Offset to MarkArray table--from
- * beginning of MarkBasePos subtable */
- Offset16To<BaseArray>
- baseArray; /* Offset to BaseArray table--from
- * beginning of MarkBasePos subtable */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-struct MarkBasePos
-{
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- MarkBasePosFormat1 format1;
- } u;
-};
-
-
-typedef AnchorMatrix LigatureAttach; /* component-major--
- * in order of writing direction--,
- * mark-minor--
- * ordered by class--zero-based. */
-
-/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
-struct LigatureArray : List16OfOffset16To<LigatureAttach>
-{
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool subset (hb_subset_context_t *c,
- Iterator coverage,
- unsigned class_count,
- const hb_map_t *klass_mapping) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- for (const auto _ : + hb_zip (coverage, *this)
- | hb_filter (glyphset, hb_first))
- {
- auto *matrix = out->serialize_append (c->serializer);
- if (unlikely (!matrix)) return_trace (false);
-
- const LigatureAttach& src = (this + _.second);
- auto indexes =
- + hb_range (src.rows * class_count)
- | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
- ;
- matrix->serialize_subset (c,
- _.second,
- this,
- src.rows,
- indexes);
- }
- return_trace (this->len);
- }
-};
-
-struct MarkLigPosFormat1
-{
- bool intersects (const hb_set_t *glyphs) const
- {
- return (this+markCoverage).intersects (glyphs) &&
- (this+ligatureCoverage).intersects (glyphs);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- + hb_zip (this+markCoverage, this+markArray)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
- ;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
-
- unsigned ligcount = (this+ligatureArray).len;
- auto lig_iter =
- + hb_zip (this+ligatureCoverage, hb_range (ligcount))
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- ;
-
- const LigatureArray& lig_array = this+ligatureArray;
- for (const unsigned i : lig_iter)
- {
- hb_sorted_vector_t<unsigned> lig_indexes;
- unsigned row_count = lig_array[i].rows;
- for (unsigned row : + hb_range (row_count))
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (lig_indexes)
- ;
- }
-
- lig_array[i].collect_variation_indices (c, lig_indexes.iter ());
- }
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
- if (unlikely (!(this+ligatureCoverage).collect_coverage (c->input))) return;
- }
-
- const Coverage &get_coverage () const { return this+markCoverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
- if (likely (mark_index == NOT_COVERED)) return_trace (false);
-
- /* Now we search backwards for a non-mark glyph */
- 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);
- 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)
- {
- 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))
- {
- 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
- * can directly use the component index. If not, we attach the mark
- * glyph to the last component of the ligature. */
- unsigned int comp_index;
- unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
- unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
- unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
- if (lig_id && lig_id == mark_id && mark_comp > 0)
- comp_index = hb_min (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
- else
- comp_index = comp_count - 1;
-
- return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
-
- if (!klass_mapping.get_population ()) return_trace (false);
- out->classCount = klass_mapping.get_population ();
-
- auto mark_iter =
- + hb_zip (this+markCoverage, this+markArray)
- | hb_filter (glyphset, hb_first)
- ;
-
- auto new_mark_coverage =
- + mark_iter
- | hb_map_retains_sorting (hb_first)
- | hb_map_retains_sorting (glyph_map)
- ;
-
- if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage))
- return_trace (false);
-
- out->markArray.serialize_subset (c, markArray, this,
- (this+markCoverage).iter (),
- &klass_mapping);
-
- auto new_ligature_coverage =
- + hb_iter (this + ligatureCoverage)
- | hb_filter (glyphset)
- | hb_map_retains_sorting (glyph_map)
- ;
-
- if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage))
- return_trace (false);
-
- out->ligatureArray.serialize_subset (c, ligatureArray, this,
- hb_iter (this+ligatureCoverage), classCount, &klass_mapping);
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- markCoverage.sanitize (c, this) &&
- ligatureCoverage.sanitize (c, this) &&
- markArray.sanitize (c, this) &&
- ligatureArray.sanitize (c, this, (unsigned int) classCount));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
- markCoverage; /* Offset to Mark Coverage table--from
- * beginning of MarkLigPos subtable */
- Offset16To<Coverage>
- ligatureCoverage; /* Offset to Ligature Coverage
- * table--from beginning of MarkLigPos
- * subtable */
- HBUINT16 classCount; /* Number of defined mark classes */
- Offset16To<MarkArray>
- markArray; /* Offset to MarkArray table--from
- * beginning of MarkLigPos subtable */
- Offset16To<LigatureArray>
- ligatureArray; /* Offset to LigatureArray table--from
- * beginning of MarkLigPos subtable */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-
-struct MarkLigPos
-{
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- MarkLigPosFormat1 format1;
- } u;
-};
-
-
-typedef AnchorMatrix Mark2Array; /* mark2-major--
- * in order of Mark2Coverage Index--,
- * mark1-minor--
- * ordered by class--zero-based. */
-
-struct MarkMarkPosFormat1
-{
- bool intersects (const hb_set_t *glyphs) const
- {
- return (this+mark1Coverage).intersects (glyphs) &&
- (this+mark2Coverage).intersects (glyphs);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- + hb_zip (this+mark1Coverage, this+mark1Array)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); })
- ;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, *c->glyph_set, &klass_mapping);
-
- unsigned mark2_count = (this+mark2Array).rows;
- auto mark2_iter =
- + hb_zip (this+mark2Coverage, hb_range (mark2_count))
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- ;
-
- hb_sorted_vector_t<unsigned> mark2_indexes;
- for (const unsigned row : mark2_iter)
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (mark2_indexes)
- ;
- }
- (this+mark2Array).collect_variation_indices (c, mark2_indexes.iter ());
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+mark1Coverage).collect_coverage (c->input))) return;
- if (unlikely (!(this+mark2Coverage).collect_coverage (c->input))) return;
- }
-
- const Coverage &get_coverage () const { return this+mark1Coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint);
- if (likely (mark1_index == NOT_COVERED)) return_trace (false);
-
- /* now we search backwards for a suitable mark glyph until a non-mark glyph */
- 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);
- 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]))
- {
- buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
- return_trace (false);
- }
-
- unsigned int j = skippy_iter.idx;
-
- unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
- unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
- unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
- unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
-
- if (likely (id1 == id2))
- {
- if (id1 == 0) /* Marks belonging to the same base. */
- goto good;
- else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
- goto good;
- }
- else
- {
- /* If ligature ids don't match, it may be the case that one of the marks
- * itself is a ligature. In which case match. */
- if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
- goto good;
- }
-
- /* 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)
- {
- 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));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping);
-
- if (!klass_mapping.get_population ()) return_trace (false);
- out->classCount = klass_mapping.get_population ();
-
- auto mark1_iter =
- + hb_zip (this+mark1Coverage, this+mark1Array)
- | hb_filter (glyphset, hb_first)
- ;
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + mark1_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
- out->mark1Array.serialize_subset (c, mark1Array, this,
- (this+mark1Coverage).iter (),
- &klass_mapping);
-
- unsigned mark2count = (this+mark2Array).rows;
- auto mark2_iter =
- + hb_zip (this+mark2Coverage, hb_range (mark2count))
- | hb_filter (glyphset, hb_first)
- ;
-
- new_coverage.reset ();
- + mark2_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
- hb_sorted_vector_t<unsigned> mark2_indexes;
- for (const unsigned row : + mark2_iter
- | hb_map (hb_second))
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (mark2_indexes)
- ;
- }
-
- out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ());
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- mark1Coverage.sanitize (c, this) &&
- mark2Coverage.sanitize (c, this) &&
- mark1Array.sanitize (c, this) &&
- mark2Array.sanitize (c, this, (unsigned int) classCount));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
- mark1Coverage; /* Offset to Combining Mark1 Coverage
- * table--from beginning of MarkMarkPos
- * subtable */
- Offset16To<Coverage>
- mark2Coverage; /* Offset to Combining Mark2 Coverage
- * table--from beginning of MarkMarkPos
- * subtable */
- HBUINT16 classCount; /* Number of defined mark classes */
- Offset16To<MarkArray>
- mark1Array; /* Offset to Mark1Array table--from
- * beginning of MarkMarkPos subtable */
- Offset16To<Mark2Array>
- mark2Array; /* Offset to Mark2Array table--from
- * beginning of MarkMarkPos subtable */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-struct MarkMarkPos
-{
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- MarkMarkPosFormat1 format1;
- } u;
-};
-
-
-struct ContextPos : Context {};
-
-struct ChainContextPos : ChainContext {};
-
-struct ExtensionPos : Extension<ExtensionPos>
-{
- typedef struct PosLookupSubTable SubTable;
-};
-
-
-
-/*
- * PosLookup
- */
-
-
-struct PosLookupSubTable
-{
- friend struct Lookup;
- friend struct PosLookup;
-
- enum Type {
- Single = 1,
- Pair = 2,
- Cursive = 3,
- MarkBase = 4,
- MarkLig = 5,
- MarkMark = 6,
- Context = 7,
- ChainContext = 8,
- Extension = 9
- };
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
- {
- TRACE_DISPATCH (this, lookup_type);
- switch (lookup_type) {
- case Single: return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...));
- case Pair: return_trace (u.pair.dispatch (c, std::forward<Ts> (ds)...));
- case Cursive: return_trace (u.cursive.dispatch (c, std::forward<Ts> (ds)...));
- case MarkBase: return_trace (u.markBase.dispatch (c, std::forward<Ts> (ds)...));
- case MarkLig: return_trace (u.markLig.dispatch (c, std::forward<Ts> (ds)...));
- case MarkMark: return_trace (u.markMark.dispatch (c, std::forward<Ts> (ds)...));
- case Context: return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...));
- case ChainContext: return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...));
- case Extension: return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...));
- default: return_trace (c->default_return_value ());
- }
- }
-
- bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
- {
- hb_intersects_context_t c (glyphs);
- return dispatch (&c, lookup_type);
- }
-
- protected:
- union {
- SinglePos single;
- PairPos pair;
- CursivePos cursive;
- MarkBasePos markBase;
- MarkLigPos markLig;
- MarkMarkPos markMark;
- ContextPos context;
- ChainContextPos chainContext;
- ExtensionPos extension;
- } u;
- public:
- DEFINE_SIZE_MIN (0);
-};
-
-
-struct PosLookup : Lookup
-{
- typedef struct PosLookupSubTable SubTable;
-
- const SubTable& get_subtable (unsigned int i) const
- { return Lookup::get_subtable<SubTable> (i); }
-
- bool is_reverse () const
- {
- return false;
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- return_trace (dispatch (c));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- hb_intersects_context_t c (glyphs);
- return dispatch (&c);
- }
-
- hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
- { return dispatch (c); }
-
- hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
- {
- if (c->is_lookup_visited (this_index))
- return hb_closure_lookups_context_t::default_return_value ();
-
- c->set_lookup_visited (this_index);
- if (!intersects (c->glyphs))
- {
- c->set_lookup_inactive (this_index);
- return hb_closure_lookups_context_t::default_return_value ();
- }
- c->set_recurse_func (dispatch_closure_lookups_recurse_func);
-
- hb_closure_lookups_context_t::return_t ret = dispatch (c);
- return ret;
- }
-
- template <typename set_t>
- void collect_coverage (set_t *glyphs) const
- {
- hb_collect_coverage_context_t<set_t> c (glyphs);
- dispatch (&c);
- }
-
- static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
-
- template <typename context_t>
- static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
-
- HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index);
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
-
- bool subset (hb_subset_context_t *c) const
- { return Lookup::subset<SubTable> (c); }
-
- bool sanitize (hb_sanitize_context_t *c) const
- { return Lookup::sanitize<SubTable> (c); }
-};
-
-/*
- * GPOS -- Glyph Positioning
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos
- */
-
-struct GPOS : GSUBGPOS
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS;
-
- const PosLookup& get_lookup (unsigned int i) const
- { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); }
-
- static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
- static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer);
- static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer);
-
- bool subset (hb_subset_context_t *c) const
- {
- hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features);
- return GSUBGPOS::subset<PosLookup> (&l);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- { return GSUBGPOS::sanitize<PosLookup> (c); }
-
- HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
- hb_face_t *face) const;
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++)
- {
- if (!c->gpos_lookups->has (i)) continue;
- const PosLookup &l = get_lookup (i);
- l.dispatch (c);
- }
- }
-
- void closure_lookups (hb_face_t *face,
- const hb_set_t *glyphs,
- hb_set_t *lookup_indexes /* IN/OUT */) const
- { GSUBGPOS::closure_lookups<PosLookup> (face, glyphs, lookup_indexes); }
-
- typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t;
-};
-
-
-static void
-reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent)
-{
- int chain = pos[i].attach_chain(), type = pos[i].attach_type();
- if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE)))
- return;
-
- pos[i].attach_chain() = 0;
-
- unsigned int j = (int) i + chain;
-
- /* Stop if we see new parent in the chain. */
- if (j == new_parent)
- return;
-
- reverse_cursive_minor_offset (pos, j, direction, new_parent);
-
- if (HB_DIRECTION_IS_HORIZONTAL (direction))
- pos[j].y_offset = -pos[i].y_offset;
- else
- pos[j].x_offset = -pos[i].x_offset;
-
- pos[j].attach_chain() = -chain;
- pos[j].attach_type() = type;
-}
-static void
-propagate_attachment_offsets (hb_glyph_position_t *pos,
- unsigned int len,
- unsigned int i,
- hb_direction_t direction)
-{
- /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate
- * offset of glyph they are attached to. */
- int chain = pos[i].attach_chain(), type = pos[i].attach_type();
- if (likely (!chain))
- return;
-
- pos[i].attach_chain() = 0;
-
- unsigned int j = (int) i + chain;
-
- if (unlikely (j >= len))
- return;
-
- propagate_attachment_offsets (pos, len, j, direction);
-
- assert (!!(type & ATTACH_TYPE_MARK) ^ !!(type & ATTACH_TYPE_CURSIVE));
-
- if (type & ATTACH_TYPE_CURSIVE)
- {
- if (HB_DIRECTION_IS_HORIZONTAL (direction))
- pos[i].y_offset += pos[j].y_offset;
- else
- pos[i].x_offset += pos[j].x_offset;
- }
- else /*if (type & ATTACH_TYPE_MARK)*/
- {
- pos[i].x_offset += pos[j].x_offset;
- pos[i].y_offset += pos[j].y_offset;
-
- assert (j < i);
- if (HB_DIRECTION_IS_FORWARD (direction))
- for (unsigned int k = j; k < i; k++) {
- pos[i].x_offset -= pos[k].x_advance;
- pos[i].y_offset -= pos[k].y_advance;
- }
- else
- for (unsigned int k = j + 1; k < i + 1; k++) {
- pos[i].x_offset += pos[k].x_advance;
- pos[i].y_offset += pos[k].y_advance;
- }
- }
-}
-
-void
-GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
-{
- unsigned int count = buffer->len;
- for (unsigned int i = 0; i < count; i++)
- buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0;
-}
-
-void
-GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
-{
- //_hb_buffer_assert_gsubgpos_vars (buffer);
-}
-
-void
-GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
-{
- _hb_buffer_assert_gsubgpos_vars (buffer);
-
- unsigned int len;
- hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
- hb_direction_t direction = buffer->props.direction;
-
- /* Handle attachments */
- if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
- 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 {
- GPOS_accelerator_t (hb_face_t *face) : GPOS::accelerator_t (face) {}
-};
-
+using Layout::GPOS_impl::PosLookup;
+// TODO(garretrieger): Move into new layout directory.
/* Out-of-class implementation for methods recursing */
-
#ifndef HB_NO_OT_LAYOUT
template <typename context_t>
/*static*/ typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
@@ -3121,13 +45,16 @@ template <typename context_t>
return l.dispatch (c);
}
-/*static*/ inline hb_closure_lookups_context_t::return_t PosLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index)
+template <>
+inline hb_closure_lookups_context_t::return_t
+PosLookup::dispatch_recurse_func<hb_closure_lookups_context_t> (hb_closure_lookups_context_t *c, unsigned this_index)
{
const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (this_index);
return l.closure_lookups (c, this_index);
}
-/*static*/ bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
+template <>
+inline bool PosLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply_context_t *c, unsigned int lookup_index)
{
const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
unsigned int saved_lookup_props = c->lookup_props;
@@ -3141,7 +68,6 @@ template <typename context_t>
}
#endif
-
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh
index bef381430b..462542025b 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh
@@ -59,13 +59,16 @@ template <typename context_t>
return l.dispatch (c);
}
-/*static*/ inline hb_closure_lookups_context_t::return_t SubstLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index)
+template <>
+inline hb_closure_lookups_context_t::return_t
+SubstLookup::dispatch_recurse_func<hb_closure_lookups_context_t> (hb_closure_lookups_context_t *c, unsigned this_index)
{
const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (this_index);
return l.closure_lookups (c, this_index);
}
-/*static*/ bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
+template <>
+inline bool SubstLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply_context_t *c, unsigned int lookup_index)
{
const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
unsigned int saved_lookup_props = c->lookup_props;
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
index c9750ff63b..31da498652 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
@@ -109,14 +109,10 @@ struct hb_closure_context_t :
{
done_lookups_glyph_count->set (lookup_index, glyphs->get_population ());
- if (!done_lookups_glyph_set->get (lookup_index))
+ if (!done_lookups_glyph_set->has (lookup_index))
{
- hb_set_t* empty_set = hb_set_create ();
- if (unlikely (!done_lookups_glyph_set->set (lookup_index, empty_set)))
- {
- hb_set_destroy (empty_set);
+ if (unlikely (!done_lookups_glyph_set->set (lookup_index, hb::unique_ptr<hb_set_t> {hb_set_create ()})))
return true;
- }
}
hb_set_clear (done_lookups_glyph_set->get (lookup_index));
@@ -165,21 +161,19 @@ struct hb_closure_context_t :
hb_set_t *glyphs;
hb_set_t output[1];
hb_vector_t<hb_set_t> active_glyphs_stack;
- recurse_func_t recurse_func;
+ recurse_func_t recurse_func = nullptr;
unsigned int nesting_level_left;
hb_closure_context_t (hb_face_t *face_,
hb_set_t *glyphs_,
hb_map_t *done_lookups_glyph_count_,
- hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set_,
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *done_lookups_glyph_set_,
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
face (face_),
glyphs (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)
+ done_lookups_glyph_set (done_lookups_glyph_set_)
{}
~hb_closure_context_t () { flush (); }
@@ -197,8 +191,8 @@ struct hb_closure_context_t :
private:
hb_map_t *done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set;
- unsigned int lookup_count;
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *done_lookups_glyph_set;
+ unsigned int lookup_count = 0;
};
@@ -400,7 +394,6 @@ struct hb_collect_coverage_context_t :
set_t *set;
};
-
struct hb_ot_apply_context_t :
hb_dispatch_context_t<hb_ot_apply_context_t, bool, HB_DEBUG_APPLY>
{
@@ -416,7 +409,7 @@ struct hb_ot_apply_context_t :
match_func (nullptr),
match_data (nullptr) {}
- typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data);
+ typedef bool (*match_func_t) (hb_glyph_info_t &info, const HBUINT16 &value, const void *data);
void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
@@ -434,7 +427,7 @@ struct hb_ot_apply_context_t :
MATCH_MAYBE
};
- may_match_t may_match (const hb_glyph_info_t &info,
+ may_match_t may_match (hb_glyph_info_t &info,
const HBUINT16 *glyph_data) const
{
if (!(info.mask & mask) ||
@@ -442,7 +435,7 @@ struct hb_ot_apply_context_t :
return MATCH_NO;
if (match_func)
- return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
+ return match_func (info, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
return MATCH_MAYBE;
}
@@ -530,7 +523,7 @@ struct hb_ot_apply_context_t :
while (idx + num_items < end)
{
idx++;
- const hb_glyph_info_t &info = c->buffer->info[idx];
+ hb_glyph_info_t &info = c->buffer->info[idx];
matcher_t::may_skip_t skip = matcher.may_skip (c, info);
if (unlikely (skip == matcher_t::SKIP_YES))
@@ -563,7 +556,7 @@ struct hb_ot_apply_context_t :
while (idx > num_items - 1)
{
idx--;
- const hb_glyph_info_t &info = c->buffer->out_info[idx];
+ hb_glyph_info_t &info = c->buffer->out_info[idx];
matcher_t::may_skip_t skip = matcher.may_skip (c, info);
if (unlikely (skip == matcher_t::SKIP_YES))
@@ -611,7 +604,10 @@ struct hb_ot_apply_context_t :
return_t recurse (unsigned int sub_lookup_index)
{
if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0))
+ {
+ buffer->shaping_failed = true;
return default_return_value ();
+ }
nesting_level_left--;
bool ret = recurse_func (this, sub_lookup_index);
@@ -621,35 +617,34 @@ struct hb_ot_apply_context_t :
skipping_iterator_t iter_input, iter_context;
+ unsigned int table_index; /* GSUB/GPOS */
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
- recurse_func_t recurse_func;
+ recurse_func_t recurse_func = nullptr;
const GDEF &gdef;
const VariationStore &var_store;
+ VariationStore::cache_t *var_store_cache;
hb_direction_t direction;
- hb_mask_t lookup_mask;
- unsigned int table_index; /* GSUB/GPOS */
- unsigned int lookup_index;
- unsigned int lookup_props;
- unsigned int nesting_level_left;
+ hb_mask_t lookup_mask = 1;
+ unsigned int lookup_index = (unsigned) -1;
+ unsigned int lookup_props = 0;
+ unsigned int nesting_level_left = HB_MAX_NESTING_LEVEL;
bool has_glyph_classes;
- bool auto_zwnj;
- bool auto_zwj;
- bool per_syllable;
- bool random;
-
- uint32_t random_state;
-
+ bool auto_zwnj = true;
+ bool auto_zwj = true;
+ bool per_syllable = false;
+ bool random = false;
+ uint32_t random_state = 1;
+ unsigned new_syllables = (unsigned) -1;
hb_ot_apply_context_t (unsigned int table_index_,
hb_font_t *font_,
hb_buffer_t *buffer_) :
- iter_input (), iter_context (),
+ table_index (table_index_),
font (font_), face (font->face), buffer (buffer_),
- recurse_func (nullptr),
gdef (
#ifndef HB_NO_OT_LAYOUT
*face->table.GDEF->table
@@ -658,18 +653,23 @@ struct hb_ot_apply_context_t :
#endif
),
var_store (gdef.get_var_store ()),
+ var_store_cache (
+#ifndef HB_NO_VAR
+ table_index == 1 && font->num_coords ? var_store.create_cache () : nullptr
+#else
+ nullptr
+#endif
+ ),
direction (buffer_->props.direction),
- lookup_mask (1),
- table_index (table_index_),
- lookup_index ((unsigned int) -1),
- lookup_props (0),
- nesting_level_left (HB_MAX_NESTING_LEVEL),
- has_glyph_classes (gdef.has_glyph_classes ()),
- auto_zwnj (true),
- auto_zwj (true),
- per_syllable (false),
- random (false),
- random_state (1) { init_iters (); }
+ has_glyph_classes (gdef.has_glyph_classes ())
+ { init_iters (); }
+
+ ~hb_ot_apply_context_t ()
+ {
+#ifndef HB_NO_VAR
+ VariationStore::destroy_cache (var_store_cache);
+#endif
+ }
void init_iters ()
{
@@ -736,6 +736,9 @@ struct hb_ot_apply_context_t :
bool ligature = false,
bool component = false) const
{
+ if (new_syllables != (unsigned) -1)
+ buffer->cur().syllable() = new_syllables;
+
unsigned int props = _hb_glyph_info_get_glyph_props (&buffer->cur());
props |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
if (ligature)
@@ -790,8 +793,8 @@ struct hb_ot_apply_context_t :
};
-struct hb_get_subtables_context_t :
- hb_dispatch_context_t<hb_get_subtables_context_t>
+struct hb_accelerate_subtables_context_t :
+ hb_dispatch_context_t<hb_accelerate_subtables_context_t>
{
template <typename Type>
static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
@@ -800,15 +803,53 @@ struct hb_get_subtables_context_t :
return typed_obj->apply (c);
}
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ template <typename T>
+ static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) )
+ template <typename T>
+ static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
+ template <typename Type>
+ static inline bool apply_cached_to (const void *obj, OT::hb_ot_apply_context_t *c)
+ {
+ const Type *typed_obj = (const Type *) obj;
+ return apply_cached_ (typed_obj, c, hb_prioritize);
+ }
+
+ template <typename T>
+ static inline auto cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) )
+ template <typename T>
+ static inline bool cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; }
+ template <typename Type>
+ static inline bool cache_func_to (const void *obj, OT::hb_ot_apply_context_t *c, bool enter)
+ {
+ const Type *typed_obj = (const Type *) obj;
+ return cache_func_ (typed_obj, c, enter, hb_prioritize);
+ }
+#endif
+
typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c);
+ typedef bool (*hb_cache_func_t) (const void *obj, OT::hb_ot_apply_context_t *c, bool enter);
struct hb_applicable_t
{
+ friend struct hb_accelerate_subtables_context_t;
+ friend struct hb_ot_layout_lookup_accelerator_t;
+
template <typename T>
- void init (const T &obj_, hb_apply_func_t apply_func_)
+ void init (const T &obj_,
+ hb_apply_func_t apply_func_
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ , hb_apply_func_t apply_cached_func_
+ , hb_cache_func_t cache_func_
+#endif
+ )
{
obj = &obj_;
apply_func = apply_func_;
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ apply_cached_func = apply_cached_func_;
+ cache_func = cache_func_;
+#endif
digest.init ();
obj_.get_coverage ().collect_coverage (&digest);
}
@@ -817,38 +858,93 @@ struct hb_get_subtables_context_t :
{
return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c);
}
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ bool apply_cached (OT::hb_ot_apply_context_t *c) const
+ {
+ return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c);
+ }
+ bool cache_enter (OT::hb_ot_apply_context_t *c) const
+ {
+ return cache_func (obj, c, true);
+ }
+ void cache_leave (OT::hb_ot_apply_context_t *c) const
+ {
+ cache_func (obj, c, false);
+ }
+#endif
private:
const void *obj;
hb_apply_func_t apply_func;
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ hb_apply_func_t apply_cached_func;
+ hb_cache_func_t cache_func;
+#endif
hb_set_digest_t digest;
};
typedef hb_vector_t<hb_applicable_t> array_t;
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ template <typename T>
+ auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () )
+ template <typename T>
+ auto cache_cost (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( 0u )
+#endif
+
/* Dispatch interface. */
template <typename T>
return_t dispatch (const T &obj)
{
- hb_applicable_t *entry = array.push();
- entry->init (obj, apply_to<T>);
+ hb_applicable_t entry;
+
+ entry.init (obj,
+ apply_to<T>
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ , apply_cached_to<T>
+ , cache_func_to<T>
+#endif
+ );
+
+ array.push (entry);
+
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ /* Cache handling
+ *
+ * We allow one subtable from each lookup to use a cache. The assumption
+ * being that multiple subtables of the same lookup cannot use a cache
+ * because the resources they would use will collide. As such, we ask
+ * each subtable to tell us how much it costs (which a cache would avoid),
+ * and we allocate the cache opportunity to the costliest subtable.
+ */
+ unsigned cost = cache_cost (obj, hb_prioritize);
+ if (cost > cache_user_cost && !array.in_error ())
+ {
+ cache_user_idx = array.length - 1;
+ cache_user_cost = cost;
+ }
+#endif
+
return hb_empty_t ();
}
static return_t default_return_value () { return hb_empty_t (); }
- hb_get_subtables_context_t (array_t &array_) :
- array (array_) {}
+ hb_accelerate_subtables_context_t (array_t &array_) :
+ array (array_) {}
array_t &array;
-};
-
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ unsigned cache_user_idx = (unsigned) -1;
+ unsigned cache_user_cost = 0;
+#endif
+};
typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data);
typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs);
typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
-typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data);
+typedef bool (*match_func_t) (hb_glyph_info_t &info, const HBUINT16 &value, const void *data);
struct ContextClosureFuncs
{
@@ -863,6 +959,10 @@ struct ContextApplyFuncs
{
match_func_t match;
};
+struct ChainContextApplyFuncs
+{
+ match_func_t match[3];
+};
static inline bool intersects_glyph (const hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED)
@@ -939,19 +1039,30 @@ static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
}
-static inline bool match_glyph (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data HB_UNUSED)
+static inline bool match_glyph (hb_glyph_info_t &info, const HBUINT16 &value, const void *data HB_UNUSED)
{
- return glyph_id == value;
+ return info.codepoint == value;
}
-static inline bool match_class (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data)
+static inline bool match_class (hb_glyph_info_t &info, const HBUINT16 &value, const void *data)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
- return class_def.get_class (glyph_id) == value;
+ return class_def.get_class (info.codepoint) == value;
}
-static inline bool match_coverage (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data)
+static inline bool match_class_cached (hb_glyph_info_t &info, const HBUINT16 &value, const void *data)
+{
+ unsigned klass = info.syllable();
+ if (klass < 255)
+ return klass == value;
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ klass = class_def.get_class (info.codepoint);
+ if (likely (klass < 255))
+ info.syllable() = klass;
+ return klass == value;
+}
+static inline bool match_coverage (hb_glyph_info_t &info, const HBUINT16 &value, const void *data)
{
const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value;
- return (data+coverage).get_coverage (glyph_id) != NOT_COVERED;
+ return (data+coverage).get_coverage (info.codepoint) != NOT_COVERED;
}
static inline bool would_match_input (hb_would_apply_context_t *c,
@@ -964,8 +1075,12 @@ static inline bool would_match_input (hb_would_apply_context_t *c,
return false;
for (unsigned int i = 1; i < count; i++)
- if (likely (!match_func (c->glyphs[i], input[i - 1], match_data)))
+ {
+ hb_glyph_info_t info;
+ info.codepoint = c->glyphs[i];
+ if (likely (!match_func (info, input[i - 1], match_data)))
return false;
+ }
return true;
}
@@ -2125,19 +2240,54 @@ struct ContextFormat2
const Coverage &get_coverage () const { return this+coverage; }
- bool apply (hb_ot_apply_context_t *c) const
+ unsigned cache_cost () const
+ {
+ unsigned c = (this+classDef).cost () * ruleSet.len;
+ return c >= 4 ? c : 0;
+ }
+ bool cache_func (hb_ot_apply_context_t *c, bool enter) const
+ {
+ if (enter)
+ {
+ if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable))
+ return false;
+ auto &info = c->buffer->info;
+ unsigned count = c->buffer->len;
+ for (unsigned i = 0; i < count; i++)
+ info[i].syllable() = 255;
+ c->new_syllables = 255;
+ return true;
+ }
+ else
+ {
+ c->new_syllables = (unsigned) -1;
+ HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable);
+ return true;
+ }
+ }
+
+ bool apply (hb_ot_apply_context_t *c, bool cached = false) const
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
const ClassDef &class_def = this+classDef;
- index = class_def.get_class (c->buffer->cur().codepoint);
- const RuleSet &rule_set = this+ruleSet[index];
+
struct ContextApplyLookupContext lookup_context = {
- {match_class},
+ {cached ? match_class_cached : match_class},
&class_def
};
+
+ if (cached && c->buffer->cur().syllable() < 255)
+ index = c->buffer->cur().syllable ();
+ else
+ {
+ index = class_def.get_class (c->buffer->cur().codepoint);
+ if (cached && index < 255)
+ c->buffer->cur().syllable() = index;
+ }
+ const RuleSet &rule_set = this+ruleSet[index];
return_trace (rule_set.apply (c, lookup_context));
}
@@ -2411,7 +2561,7 @@ struct ChainContextCollectGlyphsLookupContext
struct ChainContextApplyLookupContext
{
- ContextApplyFuncs funcs;
+ ChainContextApplyFuncs funcs;
const void *match_data[3];
};
@@ -2499,7 +2649,7 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c
return (c->zero_context ? !backtrackCount && !lookaheadCount : true)
&& would_match_input (c,
inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data[1]);
+ lookup_context.funcs.match[1], lookup_context.match_data[1]);
}
static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
@@ -2518,11 +2668,11 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
if (!(match_input (c,
inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data[1],
+ lookup_context.funcs.match[1], 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],
+ lookup_context.funcs.match[2], lookup_context.match_data[2],
match_end, &end_index)))
{
c->buffer->unsafe_to_concat (c->buffer->idx, end_index);
@@ -2532,7 +2682,7 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
unsigned start_index = c->buffer->out_len;
if (!match_backtrack (c,
backtrackCount, backtrack,
- lookup_context.funcs.match, lookup_context.match_data[0],
+ lookup_context.funcs.match[0], lookup_context.match_data[0],
&start_index))
{
c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
@@ -2934,7 +3084,7 @@ struct ChainContextFormat1
{
const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
struct ChainContextApplyLookupContext lookup_context = {
- {match_glyph},
+ {{match_glyph, match_glyph, match_glyph}},
{nullptr, nullptr, nullptr}
};
return rule_set.would_apply (c, lookup_context);
@@ -2950,7 +3100,7 @@ struct ChainContextFormat1
const ChainRuleSet &rule_set = this+ruleSet[index];
struct ChainContextApplyLookupContext lookup_context = {
- {match_glyph},
+ {{match_glyph, match_glyph, match_glyph}},
{nullptr, nullptr, nullptr}
};
return_trace (rule_set.apply (c, lookup_context));
@@ -3134,7 +3284,7 @@ struct ChainContextFormat2
unsigned int index = input_class_def.get_class (c->glyphs[0]);
const ChainRuleSet &rule_set = this+ruleSet[index];
struct ChainContextApplyLookupContext lookup_context = {
- {match_class},
+ {{match_class, match_class, match_class}},
{&backtrack_class_def,
&input_class_def,
&lookahead_class_def}
@@ -3144,7 +3294,33 @@ struct ChainContextFormat2
const Coverage &get_coverage () const { return this+coverage; }
- bool apply (hb_ot_apply_context_t *c) const
+ unsigned cache_cost () const
+ {
+ unsigned c = (this+lookaheadClassDef).cost () * ruleSet.len;
+ return c >= 4 ? c : 0;
+ }
+ bool cache_func (hb_ot_apply_context_t *c, bool enter) const
+ {
+ if (enter)
+ {
+ if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable))
+ return false;
+ auto &info = c->buffer->info;
+ unsigned count = c->buffer->len;
+ for (unsigned i = 0; i < count; i++)
+ info[i].syllable() = 255;
+ c->new_syllables = 255;
+ return true;
+ }
+ else
+ {
+ c->new_syllables = (unsigned) -1;
+ HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable);
+ return true;
+ }
+ }
+
+ bool apply (hb_ot_apply_context_t *c, bool cached = false) const
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -3154,14 +3330,27 @@ struct ChainContextFormat2
const ClassDef &input_class_def = this+inputClassDef;
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
- index = input_class_def.get_class (c->buffer->cur().codepoint);
- const ChainRuleSet &rule_set = this+ruleSet[index];
+ /* For ChainContextFormat2 we cache the LookaheadClassDef instead of InputClassDef.
+ * The reason is that most heavy fonts want to identify a glyph in context and apply
+ * a lookup to it. In this scenario, the length of the input sequence is one, whereas
+ * the lookahead / backtrack are typically longer. The one glyph in input sequence is
+ * looked-up below and no input glyph is looked up in individual rules, whereas the
+ * lookahead and backtrack glyphs are tried. Since we match lookahead before backtrack,
+ * we should cache lookahead. This decisions showed a 20% improvement in shaping of
+ * the Gulzar font.
+ */
+
struct ChainContextApplyLookupContext lookup_context = {
- {match_class},
+ {{cached && &backtrack_class_def == &input_class_def ? match_class_cached : match_class,
+ cached && &input_class_def == &lookahead_class_def ? match_class_cached : match_class,
+ cached ? match_class_cached : match_class}},
{&backtrack_class_def,
&input_class_def,
&lookahead_class_def}
};
+
+ index = input_class_def.get_class (c->buffer->cur().codepoint);
+ const ChainRuleSet &rule_set = this+ruleSet[index];
return_trace (rule_set.apply (c, lookup_context));
}
@@ -3359,7 +3548,7 @@ struct ChainContextFormat3
const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input);
const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead);
struct ChainContextApplyLookupContext lookup_context = {
- {match_coverage},
+ {{match_coverage, match_coverage, match_coverage}},
{this, this, this}
};
return chain_context_would_apply_lookup (c,
@@ -3386,7 +3575,7 @@ struct ChainContextFormat3
const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input);
const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead);
struct ChainContextApplyLookupContext lookup_context = {
- {match_coverage},
+ {{match_coverage, match_coverage, match_coverage}},
{this, this, this}
};
return_trace (chain_context_apply_lookup (c,
@@ -3623,25 +3812,63 @@ struct hb_ot_layout_lookup_accelerator_t
lookup.collect_coverage (&digest);
subtables.init ();
- OT::hb_get_subtables_context_t c_get_subtables (subtables);
- lookup.dispatch (&c_get_subtables);
+ OT::hb_accelerate_subtables_context_t c_accelerate_subtables (subtables);
+ lookup.dispatch (&c_accelerate_subtables);
+
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ cache_user_idx = c_accelerate_subtables.cache_user_idx;
+ for (unsigned i = 0; i < subtables.length; i++)
+ if (i != cache_user_idx)
+ subtables[i].apply_cached_func = subtables[i].apply_func;
+#endif
}
void fini () { subtables.fini (); }
bool may_have (hb_codepoint_t g) const
{ return digest.may_have (g); }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, bool use_cache) const
{
- for (unsigned int i = 0; i < subtables.length; i++)
- if (subtables[i].apply (c))
- return true;
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ if (use_cache)
+ {
+ for (unsigned int i = 0; i < subtables.length; i++)
+ if (subtables[i].apply_cached (c))
+ return true;
+ }
+ else
+#endif
+ {
+ for (unsigned int i = 0; i < subtables.length; i++)
+ if (subtables[i].apply (c))
+ return true;
+ }
return false;
}
+ bool cache_enter (OT::hb_ot_apply_context_t *c) const
+ {
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ return cache_user_idx != (unsigned) -1 &&
+ subtables[cache_user_idx].cache_enter (c);
+#else
+ return false;
+#endif
+ }
+ void cache_leave (OT::hb_ot_apply_context_t *c) const
+ {
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ subtables[cache_user_idx].cache_leave (c);
+#endif
+ }
+
+
private:
hb_set_digest_t digest;
- hb_get_subtables_context_t::array_t subtables;
+ hb_accelerate_subtables_context_t::array_t subtables;
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+ unsigned cache_user_idx = (unsigned) -1;
+#endif
};
struct GSUBGPOS
@@ -3721,6 +3948,8 @@ struct GSUBGPOS
hb_set_t visited_lookups, inactive_lookups;
OT::hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups);
+ c.set_recurse_func (TLookup::template dispatch_recurse_func<hb_closure_lookups_context_t>);
+
for (unsigned lookup_index : + hb_iter (lookup_indexes))
reinterpret_cast<const TLookup &> (get_lookup (lookup_index)).closure_lookups (&c, lookup_index);
@@ -3729,7 +3958,7 @@ struct GSUBGPOS
}
void prune_langsys (const hb_map_t *duplicate_feature_map,
- hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map,
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map,
hb_set_t *new_feature_indexes /* OUT */) const
{
hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes);
@@ -3787,7 +4016,7 @@ struct GSUBGPOS
hb_map_t *duplicate_feature_map /* OUT */) const
{
if (feature_indices->is_empty ()) return;
- hb_hashmap_t<hb_tag_t, hb_set_t *> unique_features;
+ hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_set_t>> unique_features;
//find out duplicate features after subset
for (unsigned i : feature_indices->iter ())
{
@@ -3795,16 +4024,9 @@ struct GSUBGPOS
if (t == HB_MAP_VALUE_INVALID) continue;
if (!unique_features.has (t))
{
- hb_set_t* indices = hb_set_create ();
- if (unlikely (indices == hb_set_get_empty () ||
- !unique_features.set (t, indices)))
- {
- hb_set_destroy (indices);
- for (auto _ : unique_features.iter ())
- hb_set_destroy (_.second);
+ if (unlikely (!unique_features.set (t, hb::unique_ptr<hb_set_t> {hb_set_create ()})))
return;
- }
- if (unique_features.get (t))
+ if (unique_features.has (t))
unique_features.get (t)->add (i);
duplicate_feature_map->set (i, i);
continue;
@@ -3849,9 +4071,6 @@ struct GSUBGPOS
duplicate_feature_map->set (i, i);
}
}
-
- for (auto _ : unique_features.iter ())
- hb_set_destroy (_.second);
}
void prune_features (const hb_map_t *lookup_indices, /* IN */
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc
index f4ea21a4f9..142c843dad 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc
@@ -46,7 +46,7 @@
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
-#include "hb-ot-layout-base-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-ot-layout-base-table.hh"
#include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise.
#include "hb-ot-name-table.hh"
#include "hb-ot-os2-table.hh"
@@ -55,6 +55,7 @@
#include "hb-aat-layout-opbd-table.hh" // Just so we compile it; unused otherwise.
using OT::Layout::GSUB::GSUB;
+using OT::Layout::GPOS;
/**
* SECTION:hb-ot-layout
@@ -260,7 +261,6 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font,
{
_hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
_hb_glyph_info_clear_lig_props (&buffer->info[i]);
- buffer->info[i].syllable() = 0;
}
}
@@ -401,7 +401,7 @@ GSUB::is_blocklisted (hb_blob_t *blob HB_UNUSED,
}
bool
-OT::GPOS::is_blocklisted (hb_blob_t *blob HB_UNUSED,
+GPOS::is_blocklisted (hb_blob_t *blob HB_UNUSED,
hb_face_t *face HB_UNUSED) const
{
#ifdef HB_NO_OT_LAYOUT_BLOCKLIST
@@ -1501,15 +1501,12 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
hb_set_t *glyphs /* OUT */)
{
hb_map_t done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> 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);
l.closure (&c, lookup_index);
-
- for (auto _ : done_lookups_glyph_set.iter ())
- hb_set_destroy (_.second);
}
/**
@@ -1529,7 +1526,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
hb_set_t *glyphs /* OUT */)
{
hb_map_t done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> done_lookups_glyph_set;
OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
const GSUB& gsub = *face->table.GSUB->table;
@@ -1551,13 +1548,10 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
}
} while (iteration_count++ <= HB_CLOSURE_MAX_STAGES &&
glyphs_length != glyphs->get_population ());
-
- for (auto _ : done_lookups_glyph_set.iter ())
- hb_set_destroy (_.second);
}
/*
- * OT::GPOS
+ * GPOS
*/
@@ -1588,7 +1582,7 @@ hb_ot_layout_has_positioning (hb_face_t *face)
void
hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
{
- OT::GPOS::position_start (font, buffer);
+ GPOS::position_start (font, buffer);
}
@@ -1603,7 +1597,7 @@ hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
void
hb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer)
{
- OT::GPOS::position_finish_advances (font, buffer);
+ GPOS::position_finish_advances (font, buffer);
}
/**
@@ -1617,7 +1611,7 @@ hb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer)
void
hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
{
- OT::GPOS::position_finish_offsets (font, buffer);
+ GPOS::position_finish_offsets (font, buffer);
}
@@ -1652,7 +1646,7 @@ hb_ot_layout_get_size_params (hb_face_t *face,
unsigned int *range_start, /* OUT. May be NULL */
unsigned int *range_end /* OUT. May be NULL */)
{
- const OT::GPOS &gpos = *face->table.GPOS->table;
+ const GPOS &gpos = *face->table.GPOS->table;
const hb_tag_t tag = HB_TAG ('s','i','z','e');
unsigned int num_features = gpos.get_feature_count ();
@@ -1803,7 +1797,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face,
struct GSUBProxy
{
static constexpr unsigned table_index = 0u;
- static constexpr bool inplace = false;
+ static constexpr bool always_inplace = false;
typedef OT::SubstLookup Lookup;
GSUBProxy (hb_face_t *face) :
@@ -1817,14 +1811,14 @@ struct GSUBProxy
struct GPOSProxy
{
static constexpr unsigned table_index = 1u;
- static constexpr bool inplace = true;
+ static constexpr bool always_inplace = true;
typedef OT::PosLookup Lookup;
GPOSProxy (hb_face_t *face) :
table (*face->table.GPOS->table),
accels (face->table.GPOS->accels) {}
- const OT::GPOS &table;
+ const GPOS &table;
const OT::hb_ot_layout_lookup_accelerator_t *accels;
};
@@ -1833,6 +1827,8 @@ static inline bool
apply_forward (OT::hb_ot_apply_context_t *c,
const OT::hb_ot_layout_lookup_accelerator_t &accel)
{
+ bool use_cache = accel.cache_enter (c);
+
bool ret = false;
hb_buffer_t *buffer = c->buffer;
while (buffer->idx < buffer->len && buffer->successful)
@@ -1842,7 +1838,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
(buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props))
{
- applied = accel.apply (c);
+ applied = accel.apply (c, use_cache);
}
if (applied)
@@ -1850,6 +1846,10 @@ apply_forward (OT::hb_ot_apply_context_t *c,
else
(void) buffer->next_glyph ();
}
+
+ if (use_cache)
+ accel.cache_leave (c);
+
return ret;
}
@@ -1864,7 +1864,7 @@ apply_backward (OT::hb_ot_apply_context_t *c,
if (accel.may_have (buffer->cur().codepoint) &&
(buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props))
- ret |= accel.apply (c);
+ ret |= accel.apply (c, false);
/* The reverse lookup doesn't "advance" cursor (for good reason). */
buffer->idx--;
@@ -1890,13 +1890,13 @@ apply_string (OT::hb_ot_apply_context_t *c,
if (likely (!lookup.is_reverse ()))
{
/* in/out forward substitution/positioning */
- if (!Proxy::inplace)
+ if (!Proxy::always_inplace)
buffer->clear_output ();
buffer->idx = 0;
apply_forward (c, accel);
- if (!Proxy::inplace)
+ if (!Proxy::always_inplace)
buffer->sync ();
}
else
@@ -1917,7 +1917,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
const unsigned int table_index = proxy.table_index;
unsigned int i = 0;
OT::hb_ot_apply_context_t c (table_index, font, buffer);
- c.set_recurse_func (Proxy::Lookup::apply_recurse_func);
+ c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func<OT::hb_ot_apply_context_t>);
for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++)
{
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh
index 75bba0bc50..6395f06670 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh
@@ -589,13 +589,11 @@ _hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
{
HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
- HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
}
static inline void
_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
{
- HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
}
@@ -605,7 +603,6 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer)
{
HB_BUFFER_ASSERT_VAR (buffer, glyph_props);
HB_BUFFER_ASSERT_VAR (buffer, lig_props);
- HB_BUFFER_ASSERT_VAR (buffer, syllable);
}
/* Make sure no one directly touches our props... */
diff --git a/thirdparty/harfbuzz/src/hb-ot-name-language-static.hh b/thirdparty/harfbuzz/src/hb-ot-name-language-static.hh
index c496dc2981..0e0f2d632a 100644
--- a/thirdparty/harfbuzz/src/hb-ot-name-language-static.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-name-language-static.hh
@@ -45,7 +45,7 @@ struct hb_ot_language_map_t
};
static const hb_ot_language_map_t
-hb_ms_language_map[] =
+_hb_ms_language_map[] =
{
{0x0001, "ar"}, /* ??? */
{0x0004, "zh"}, /* ??? */
@@ -298,7 +298,7 @@ hb_ms_language_map[] =
};
static const hb_ot_language_map_t
-hb_mac_language_map[] =
+_hb_mac_language_map[] =
{
{ 0, "en"}, /* English */
{ 1, "fr"}, /* French */
@@ -441,16 +441,16 @@ hb_language_t
_hb_ot_name_language_for_ms_code (unsigned int code)
{
return _hb_ot_name_language_for (code,
- hb_ms_language_map,
- ARRAY_LENGTH (hb_ms_language_map));
+ _hb_ms_language_map,
+ ARRAY_LENGTH (_hb_ms_language_map));
}
hb_language_t
_hb_ot_name_language_for_mac_code (unsigned int code)
{
return _hb_ot_name_language_for (code,
- hb_mac_language_map,
- ARRAY_LENGTH (hb_mac_language_map));
+ _hb_mac_language_map,
+ ARRAY_LENGTH (_hb_mac_language_map));
}
#endif /* HB_OT_NAME_LANGUAGE_STATIC_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-name-table.hh b/thirdparty/harfbuzz/src/hb-ot-name-table.hh
index d52367e9b1..01107aad67 100644
--- a/thirdparty/harfbuzz/src/hb-ot-name-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-name-table.hh
@@ -156,7 +156,7 @@ struct NameRecord
};
static int
-_hb_ot_name_entry_cmp_key (const void *pa, const void *pb)
+_hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact)
{
const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
@@ -169,8 +169,23 @@ _hb_ot_name_entry_cmp_key (const void *pa, const void *pb)
if (a->language == b->language) return 0;
if (!a->language) return -1;
if (!b->language) return +1;
- return strcmp (hb_language_to_string (a->language),
- hb_language_to_string (b->language));
+
+ const char *astr = hb_language_to_string (a->language);
+ const char *bstr = hb_language_to_string (b->language);
+
+ signed c = strcmp (astr, bstr);
+
+ if (!exact && c)
+ {
+ unsigned la = strlen (astr);
+ unsigned lb = strlen (bstr);
+ // 'a' is the user request, and 'b' is string in the font.
+ // If eg. user asks for "en-us" and font has "en", approve.
+ if (la > lb && astr[lb] == '-' && !strncmp (astr, bstr, lb))
+ return 0;
+ }
+
+ return c;
}
static int
@@ -178,7 +193,7 @@ _hb_ot_name_entry_cmp (const void *pa, const void *pb)
{
/* Compare by name_id, then language, then score, then index. */
- int v = _hb_ot_name_entry_cmp_key (pa, pb);
+ int v = _hb_ot_name_entry_cmp_key (pa, pb, true);
if (v)
return v;
@@ -330,7 +345,18 @@ struct name
const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
this->names.length,
sizeof (hb_ot_name_entry_t),
- _hb_ot_name_entry_cmp_key);
+ _hb_ot_name_entry_cmp_key,
+ true);
+
+ if (!entry)
+ {
+ entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
+ this->names.length,
+ sizeof (hb_ot_name_entry_t),
+ _hb_ot_name_entry_cmp_key,
+ false);
+ }
+
if (!entry)
return -1;
diff --git a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh
index f0035e2f04..3473afef54 100644
--- a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh
@@ -224,9 +224,11 @@ struct OS2
*max_cp = hb_min (0xFFFFu, codepoints->get_max ());
}
- /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 */
+ /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681
+ * https://docs.microsoft.com/en-us/typography/legacy/legacy_arabic_fonts */
enum font_page_t
{
+ FONT_PAGE_NONE = 0,
FONT_PAGE_HEBREW = 0xB100, /* Hebrew Windows 3.1 font page */
FONT_PAGE_SIMP_ARABIC = 0xB200, /* Simplified Arabic Windows 3.1 font page */
FONT_PAGE_TRAD_ARABIC = 0xB300, /* Traditional Arabic Windows 3.1 font page */
diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
index 0f3cd8e24f..4d427e5431 100644
--- a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
@@ -52,16 +52,16 @@ HB_INTERNAL bool postV2Tail::serialize (hb_serialize_context_t *c,
{
unsigned glyph_id = _.first;
unsigned new_index = _.second;
-
+
if (new_index < 258) continue;
if (copied_indices.has (new_index)) continue;
copied_indices.add (new_index);
-
+
hb_bytes_t s = reinterpret_cast<const post::accelerator_t*> (_post)->find_glyph_name (glyph_id);
HBUINT8 *o = c->allocate_size<HBUINT8> (HBUINT8::static_size * (s.length + 1));
if (unlikely (!o)) return_trace (false);
if (!c->check_assign (o[0], s.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
- memcpy (o+1, s.arrayZ, HBUINT8::static_size * s.length);
+ hb_memcpy (o+1, s.arrayZ, HBUINT8::static_size * s.length);
}
return_trace (true);
@@ -78,17 +78,19 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
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;
+ hb_hashmap_t<hb_bytes_t, unsigned, true> glyph_name_to_new_index;
for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
{
hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
unsigned old_index = glyphNameIndex[old_gid];
unsigned new_index;
+ const unsigned *new_index2;
if (old_index <= 257) new_index = old_index;
- else if (old_new_index_map.has (old_index)) new_index = old_new_index_map.get (old_index);
- else
+ else if (old_new_index_map.has (old_index, &new_index2))
{
+ new_index = *new_index2;
+ } else {
hb_bytes_t s = _post.find_glyph_name (old_gid);
new_index = glyph_name_to_new_index.get (s);
if (new_index == (unsigned)-1)
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh
deleted file mode 100644
index 74bf3ca0fa..0000000000
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh
+++ /dev/null
@@ -1,603 +0,0 @@
-
-#line 1 "hb-ot-shape-complex-indic-machine.rl"
-/*
- * Copyright © 2011,2012 Google, Inc.
- *
- * 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
- */
-
-#ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH
-#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH
-
-#include "hb.hh"
-
-enum indic_syllable_type_t {
- indic_consonant_syllable,
- indic_vowel_syllable,
- indic_standalone_cluster,
- indic_symbol_cluster,
- indic_broken_cluster,
- indic_non_indic_cluster,
-};
-
-
-#line 45 "hb-ot-shape-complex-indic-machine.hh"
-#define indic_syllable_machine_ex_A 10u
-#define indic_syllable_machine_ex_C 1u
-#define indic_syllable_machine_ex_CM 17u
-#define indic_syllable_machine_ex_CS 19u
-#define indic_syllable_machine_ex_DOTTEDCIRCLE 12u
-#define indic_syllable_machine_ex_H 4u
-#define indic_syllable_machine_ex_M 7u
-#define indic_syllable_machine_ex_N 3u
-#define indic_syllable_machine_ex_PLACEHOLDER 11u
-#define indic_syllable_machine_ex_RS 13u
-#define indic_syllable_machine_ex_Ra 16u
-#define indic_syllable_machine_ex_Repha 15u
-#define indic_syllable_machine_ex_SM 8u
-#define indic_syllable_machine_ex_Symbol 18u
-#define indic_syllable_machine_ex_V 2u
-#define indic_syllable_machine_ex_ZWJ 6u
-#define indic_syllable_machine_ex_ZWNJ 5u
-
-
-#line 65 "hb-ot-shape-complex-indic-machine.hh"
-static const unsigned char _indic_syllable_machine_trans_keys[] = {
- 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u,
- 4u, 13u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u,
- 4u, 8u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u,
- 6u, 6u, 16u, 16u, 4u, 8u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 7u, 5u, 8u,
- 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 4u, 8u, 5u, 8u, 8u, 8u, 1u, 19u,
- 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 5u, 10u, 5u, 10u, 10u, 10u, 5u, 10u,
- 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 4u, 10u, 5u, 10u,
- 3u, 10u, 5u, 10u, 3u, 17u, 3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u,
- 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u,
- 1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u,
- 5u, 10u, 3u, 17u, 3u, 17u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u,
- 3u, 17u, 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 1u, 16u, 3u, 10u,
- 4u, 10u, 5u, 10u, 3u, 17u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 5u, 10u,
- 3u, 17u, 4u, 13u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u,
- 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 1u, 16u, 3u, 10u, 4u, 10u,
- 5u, 10u, 3u, 17u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 1u, 17u,
- 3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u,
- 5u, 10u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 0
-};
-
-static const char _indic_syllable_machine_key_spans[] = {
- 1, 5, 3, 4, 5, 1, 1, 5,
- 10, 5, 1, 3, 4, 5, 1, 1,
- 5, 10, 10, 10, 1, 3, 4, 5,
- 1, 1, 5, 5, 10, 1, 3, 4,
- 5, 1, 1, 5, 5, 4, 1, 19,
- 15, 15, 14, 16, 6, 6, 1, 6,
- 16, 16, 16, 8, 7, 6, 7, 6,
- 8, 6, 15, 15, 15, 15, 14, 16,
- 15, 15, 14, 16, 6, 1, 6, 16,
- 16, 8, 7, 6, 7, 6, 6, 8,
- 6, 15, 15, 5, 15, 15, 14, 16,
- 15, 16, 6, 1, 6, 16, 16, 8,
- 7, 6, 15, 7, 6, 6, 8, 6,
- 15, 10, 5, 15, 15, 14, 16, 15,
- 16, 6, 1, 6, 16, 16, 8, 7,
- 6, 15, 7, 6, 6, 8, 6, 17,
- 15, 17, 10, 6, 1, 6, 16, 8,
- 6, 6, 1, 6, 16
-};
-
-static const short _indic_syllable_machine_index_offsets[] = {
- 0, 2, 8, 12, 17, 23, 25, 27,
- 33, 44, 50, 52, 56, 61, 67, 69,
- 71, 77, 88, 99, 110, 112, 116, 121,
- 127, 129, 131, 137, 143, 154, 156, 160,
- 165, 171, 173, 175, 181, 187, 192, 194,
- 214, 230, 246, 261, 278, 285, 292, 294,
- 301, 318, 335, 352, 361, 369, 376, 384,
- 391, 400, 407, 423, 439, 455, 471, 486,
- 503, 519, 535, 550, 567, 574, 576, 583,
- 600, 617, 626, 634, 641, 649, 656, 663,
- 672, 679, 695, 711, 717, 733, 749, 764,
- 781, 797, 814, 821, 823, 830, 847, 864,
- 873, 881, 888, 904, 912, 919, 926, 935,
- 942, 958, 969, 975, 991, 1007, 1022, 1039,
- 1055, 1072, 1079, 1081, 1088, 1105, 1122, 1131,
- 1139, 1146, 1162, 1170, 1177, 1184, 1193, 1200,
- 1218, 1234, 1252, 1263, 1270, 1272, 1279, 1296,
- 1305, 1312, 1319, 1321, 1328
-};
-
-static const unsigned char _indic_syllable_machine_indicies[] = {
- 1, 0, 2, 3, 3, 4, 1, 0,
- 3, 3, 4, 0, 3, 3, 4, 1,
- 0, 5, 3, 3, 4, 1, 0, 6,
- 0, 7, 0, 8, 3, 3, 4, 1,
- 0, 2, 3, 3, 4, 1, 0, 0,
- 0, 0, 9, 0, 11, 12, 12, 13,
- 14, 10, 14, 10, 12, 12, 13, 10,
- 12, 12, 13, 14, 10, 15, 12, 12,
- 13, 14, 10, 16, 10, 17, 10, 18,
- 12, 12, 13, 14, 10, 11, 12, 12,
- 13, 14, 10, 10, 10, 10, 19, 10,
- 11, 12, 12, 13, 14, 10, 10, 10,
- 10, 20, 10, 22, 23, 23, 24, 25,
- 21, 21, 21, 21, 26, 21, 25, 21,
- 23, 23, 24, 27, 23, 23, 24, 25,
- 21, 28, 23, 23, 24, 25, 21, 29,
- 21, 30, 21, 22, 23, 23, 24, 25,
- 21, 31, 23, 23, 24, 25, 21, 33,
- 34, 34, 35, 36, 32, 32, 32, 32,
- 37, 32, 36, 32, 34, 34, 35, 32,
- 34, 34, 35, 36, 32, 38, 34, 34,
- 35, 36, 32, 39, 32, 40, 32, 33,
- 34, 34, 35, 36, 32, 41, 34, 34,
- 35, 36, 32, 23, 23, 24, 1, 0,
- 43, 42, 45, 46, 47, 48, 49, 50,
- 24, 25, 44, 51, 52, 52, 26, 44,
- 53, 54, 55, 56, 57, 44, 59, 60,
- 61, 62, 4, 1, 58, 63, 58, 58,
- 9, 58, 58, 58, 64, 58, 65, 60,
- 66, 66, 4, 1, 58, 63, 58, 58,
- 58, 58, 58, 58, 64, 58, 60, 66,
- 66, 4, 1, 58, 63, 58, 58, 58,
- 58, 58, 58, 64, 58, 45, 58, 58,
- 58, 67, 68, 58, 1, 58, 63, 58,
- 58, 58, 58, 58, 45, 58, 69, 69,
- 58, 1, 58, 63, 58, 63, 58, 58,
- 70, 58, 63, 58, 63, 58, 63, 58,
- 58, 58, 58, 63, 58, 45, 58, 71,
- 58, 69, 69, 58, 1, 58, 63, 58,
- 58, 58, 58, 58, 45, 58, 45, 58,
- 58, 58, 69, 69, 58, 1, 58, 63,
- 58, 58, 58, 58, 58, 45, 58, 45,
- 58, 58, 58, 69, 68, 58, 1, 58,
- 63, 58, 58, 58, 58, 58, 45, 58,
- 72, 7, 73, 74, 4, 1, 58, 63,
- 58, 7, 73, 74, 4, 1, 58, 63,
- 58, 73, 73, 4, 1, 58, 63, 58,
- 75, 76, 76, 4, 1, 58, 63, 58,
- 67, 77, 58, 1, 58, 63, 58, 67,
- 58, 69, 69, 58, 1, 58, 63, 58,
- 69, 77, 58, 1, 58, 63, 58, 59,
- 60, 66, 66, 4, 1, 58, 63, 58,
- 58, 58, 58, 58, 58, 64, 58, 59,
- 60, 61, 66, 4, 1, 58, 63, 58,
- 58, 9, 58, 58, 58, 64, 58, 79,
- 80, 81, 82, 13, 14, 78, 83, 78,
- 78, 20, 78, 78, 78, 84, 78, 85,
- 80, 86, 82, 13, 14, 78, 83, 78,
- 78, 78, 78, 78, 78, 84, 78, 80,
- 86, 82, 13, 14, 78, 83, 78, 78,
- 78, 78, 78, 78, 84, 78, 87, 78,
- 78, 78, 88, 89, 78, 14, 78, 83,
- 78, 78, 78, 78, 78, 87, 78, 90,
- 80, 91, 92, 13, 14, 78, 83, 78,
- 78, 19, 78, 78, 78, 84, 78, 93,
- 80, 86, 86, 13, 14, 78, 83, 78,
- 78, 78, 78, 78, 78, 84, 78, 80,
- 86, 86, 13, 14, 78, 83, 78, 78,
- 78, 78, 78, 78, 84, 78, 87, 78,
- 78, 78, 94, 89, 78, 14, 78, 83,
- 78, 78, 78, 78, 78, 87, 78, 83,
- 78, 78, 95, 78, 83, 78, 83, 78,
- 83, 78, 78, 78, 78, 83, 78, 87,
- 78, 96, 78, 94, 94, 78, 14, 78,
- 83, 78, 78, 78, 78, 78, 87, 78,
- 87, 78, 78, 78, 94, 94, 78, 14,
- 78, 83, 78, 78, 78, 78, 78, 87,
- 78, 97, 17, 98, 99, 13, 14, 78,
- 83, 78, 17, 98, 99, 13, 14, 78,
- 83, 78, 98, 98, 13, 14, 78, 83,
- 78, 100, 101, 101, 13, 14, 78, 83,
- 78, 88, 102, 78, 14, 78, 83, 78,
- 94, 94, 78, 14, 78, 83, 78, 88,
- 78, 94, 94, 78, 14, 78, 83, 78,
- 94, 102, 78, 14, 78, 83, 78, 90,
- 80, 86, 86, 13, 14, 78, 83, 78,
- 78, 78, 78, 78, 78, 84, 78, 90,
- 80, 91, 86, 13, 14, 78, 83, 78,
- 78, 19, 78, 78, 78, 84, 78, 11,
- 12, 12, 13, 14, 78, 79, 80, 86,
- 82, 13, 14, 78, 83, 78, 78, 78,
- 78, 78, 78, 84, 78, 104, 48, 105,
- 105, 24, 25, 103, 51, 103, 103, 103,
- 103, 103, 103, 55, 103, 48, 105, 105,
- 24, 25, 103, 51, 103, 103, 103, 103,
- 103, 103, 55, 103, 106, 103, 103, 103,
- 107, 108, 103, 25, 103, 51, 103, 103,
- 103, 103, 103, 106, 103, 47, 48, 109,
- 110, 24, 25, 103, 51, 103, 103, 26,
- 103, 103, 103, 55, 103, 106, 103, 103,
- 103, 111, 108, 103, 25, 103, 51, 103,
- 103, 103, 103, 103, 106, 103, 51, 103,
- 103, 112, 103, 51, 103, 51, 103, 51,
- 103, 103, 103, 103, 51, 103, 106, 103,
- 113, 103, 111, 111, 103, 25, 103, 51,
- 103, 103, 103, 103, 103, 106, 103, 106,
- 103, 103, 103, 111, 111, 103, 25, 103,
- 51, 103, 103, 103, 103, 103, 106, 103,
- 114, 30, 115, 116, 24, 25, 103, 51,
- 103, 30, 115, 116, 24, 25, 103, 51,
- 103, 115, 115, 24, 25, 103, 51, 103,
- 47, 48, 105, 105, 24, 25, 103, 51,
- 103, 103, 103, 103, 103, 103, 55, 103,
- 117, 118, 118, 24, 25, 103, 51, 103,
- 107, 119, 103, 25, 103, 51, 103, 111,
- 111, 103, 25, 103, 51, 103, 107, 103,
- 111, 111, 103, 25, 103, 51, 103, 111,
- 119, 103, 25, 103, 51, 103, 47, 48,
- 109, 105, 24, 25, 103, 51, 103, 103,
- 26, 103, 103, 103, 55, 103, 22, 23,
- 23, 24, 25, 120, 120, 120, 120, 26,
- 120, 22, 23, 23, 24, 25, 120, 122,
- 123, 124, 125, 35, 36, 121, 126, 121,
- 121, 37, 121, 121, 121, 127, 121, 128,
- 123, 125, 125, 35, 36, 121, 126, 121,
- 121, 121, 121, 121, 121, 127, 121, 123,
- 125, 125, 35, 36, 121, 126, 121, 121,
- 121, 121, 121, 121, 127, 121, 129, 121,
- 121, 121, 130, 131, 121, 36, 121, 126,
- 121, 121, 121, 121, 121, 129, 121, 122,
- 123, 124, 52, 35, 36, 121, 126, 121,
- 121, 37, 121, 121, 121, 127, 121, 129,
- 121, 121, 121, 132, 131, 121, 36, 121,
- 126, 121, 121, 121, 121, 121, 129, 121,
- 126, 121, 121, 133, 121, 126, 121, 126,
- 121, 126, 121, 121, 121, 121, 126, 121,
- 129, 121, 134, 121, 132, 132, 121, 36,
- 121, 126, 121, 121, 121, 121, 121, 129,
- 121, 129, 121, 121, 121, 132, 132, 121,
- 36, 121, 126, 121, 121, 121, 121, 121,
- 129, 121, 135, 40, 136, 137, 35, 36,
- 121, 126, 121, 40, 136, 137, 35, 36,
- 121, 126, 121, 136, 136, 35, 36, 121,
- 126, 121, 122, 123, 125, 125, 35, 36,
- 121, 126, 121, 121, 121, 121, 121, 121,
- 127, 121, 138, 139, 139, 35, 36, 121,
- 126, 121, 130, 140, 121, 36, 121, 126,
- 121, 132, 132, 121, 36, 121, 126, 121,
- 130, 121, 132, 132, 121, 36, 121, 126,
- 121, 132, 140, 121, 36, 121, 126, 121,
- 45, 46, 47, 48, 109, 105, 24, 25,
- 103, 51, 52, 52, 26, 103, 103, 45,
- 55, 103, 59, 141, 61, 62, 4, 1,
- 58, 63, 58, 58, 9, 58, 58, 58,
- 64, 58, 45, 46, 47, 48, 142, 143,
- 24, 144, 58, 145, 58, 52, 26, 58,
- 58, 45, 55, 58, 22, 146, 146, 24,
- 144, 58, 63, 58, 58, 26, 58, 145,
- 58, 58, 147, 58, 145, 58, 145, 58,
- 145, 58, 58, 58, 58, 145, 58, 45,
- 58, 71, 22, 146, 146, 24, 144, 58,
- 63, 58, 58, 58, 58, 58, 45, 58,
- 149, 148, 150, 150, 148, 43, 148, 151,
- 148, 150, 150, 148, 43, 148, 151, 148,
- 151, 148, 148, 152, 148, 151, 148, 151,
- 148, 151, 148, 148, 148, 148, 151, 148,
- 45, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 52, 120, 120, 120, 120, 45,
- 120, 0
-};
-
-static const unsigned char _indic_syllable_machine_trans_targs[] = {
- 39, 45, 50, 2, 51, 5, 6, 53,
- 57, 58, 39, 67, 11, 73, 68, 14,
- 15, 75, 80, 81, 84, 39, 89, 21,
- 95, 90, 98, 39, 24, 25, 97, 103,
- 39, 112, 30, 118, 113, 121, 33, 34,
- 120, 126, 39, 137, 39, 40, 60, 85,
- 87, 105, 106, 91, 107, 127, 128, 99,
- 135, 140, 39, 41, 43, 8, 59, 46,
- 54, 42, 1, 44, 48, 0, 47, 49,
- 52, 3, 4, 55, 7, 56, 39, 61,
- 63, 18, 83, 69, 76, 62, 9, 64,
- 78, 71, 65, 17, 82, 66, 10, 70,
- 72, 74, 12, 13, 77, 16, 79, 39,
- 86, 26, 88, 101, 93, 19, 104, 20,
- 92, 94, 96, 22, 23, 100, 27, 102,
- 39, 39, 108, 110, 28, 35, 114, 122,
- 109, 111, 124, 116, 29, 115, 117, 119,
- 31, 32, 123, 36, 125, 129, 130, 134,
- 131, 132, 37, 133, 39, 136, 38, 138,
- 139
-};
-
-static const char _indic_syllable_machine_trans_actions[] = {
- 1, 0, 2, 0, 2, 0, 0, 2,
- 2, 2, 3, 2, 0, 2, 0, 0,
- 0, 2, 2, 2, 2, 4, 2, 0,
- 5, 0, 5, 6, 0, 0, 5, 2,
- 7, 2, 0, 2, 0, 2, 0, 0,
- 2, 2, 8, 0, 11, 2, 2, 5,
- 0, 12, 12, 0, 2, 5, 2, 5,
- 2, 0, 13, 2, 0, 0, 2, 0,
- 2, 2, 0, 2, 2, 0, 0, 2,
- 2, 0, 0, 0, 0, 2, 14, 2,
- 0, 0, 2, 0, 2, 2, 0, 2,
- 2, 2, 2, 0, 2, 2, 0, 0,
- 2, 2, 0, 0, 0, 0, 2, 15,
- 5, 0, 5, 2, 2, 0, 5, 0,
- 0, 2, 5, 0, 0, 0, 0, 2,
- 16, 17, 2, 0, 0, 0, 0, 2,
- 2, 2, 2, 2, 0, 0, 2, 2,
- 0, 0, 0, 0, 2, 0, 18, 18,
- 0, 0, 0, 0, 19, 2, 0, 0,
- 0
-};
-
-static const char _indic_syllable_machine_to_state_actions[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 9,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0
-};
-
-static const char _indic_syllable_machine_from_state_actions[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 10,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0
-};
-
-static const short _indic_syllable_machine_eof_trans[] = {
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 22, 22, 28, 22, 22,
- 22, 22, 22, 22, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 1, 43, 0,
- 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 104, 104, 104,
- 104, 104, 104, 104, 104, 104, 104, 104,
- 104, 104, 104, 104, 104, 104, 104, 104,
- 104, 121, 121, 122, 122, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 104,
- 59, 59, 59, 59, 59, 59, 59, 149,
- 149, 149, 149, 149, 121
-};
-
-static const int indic_syllable_machine_start = 39;
-static const int indic_syllable_machine_first_final = 39;
-static const int indic_syllable_machine_error = -1;
-
-static const int indic_syllable_machine_en_main = 39;
-
-
-#line 46 "hb-ot-shape-complex-indic-machine.rl"
-
-
-
-#line 102 "hb-ot-shape-complex-indic-machine.rl"
-
-
-#define found_syllable(syllable_type) \
- HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
- for (unsigned int i = ts; i < te; i++) \
- info[i].syllable() = (syllable_serial << 4) | syllable_type; \
- syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
- } HB_STMT_END
-
-static void
-find_syllables_indic (hb_buffer_t *buffer)
-{
- unsigned int p, pe, eof, ts, te, act;
- int cs;
- hb_glyph_info_t *info = buffer->info;
-
-#line 440 "hb-ot-shape-complex-indic-machine.hh"
- {
- cs = indic_syllable_machine_start;
- ts = 0;
- te = 0;
- act = 0;
- }
-
-#line 122 "hb-ot-shape-complex-indic-machine.rl"
-
-
- p = 0;
- pe = eof = buffer->len;
-
- unsigned int syllable_serial = 1;
-
-#line 456 "hb-ot-shape-complex-indic-machine.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const unsigned char *_inds;
- if ( p == pe )
- goto _test_eof;
-_resume:
- switch ( _indic_syllable_machine_from_state_actions[cs] ) {
- case 10:
-#line 1 "NONE"
- {ts = p;}
- break;
-#line 470 "hb-ot-shape-complex-indic-machine.hh"
- }
-
- _keys = _indic_syllable_machine_trans_keys + (cs<<1);
- _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs];
-
- _slen = _indic_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) &&
- ( info[p].indic_category()) <= _keys[1] ?
- ( info[p].indic_category()) - _keys[0] : _slen ];
-
-_eof_trans:
- cs = _indic_syllable_machine_trans_targs[_trans];
-
- if ( _indic_syllable_machine_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _indic_syllable_machine_trans_actions[_trans] ) {
- case 2:
-#line 1 "NONE"
- {te = p+1;}
- break;
- case 11:
-#line 98 "hb-ot-shape-complex-indic-machine.rl"
- {te = p+1;{ found_syllable (indic_non_indic_cluster); }}
- break;
- case 13:
-#line 93 "hb-ot-shape-complex-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_consonant_syllable); }}
- break;
- case 14:
-#line 94 "hb-ot-shape-complex-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_vowel_syllable); }}
- break;
- case 17:
-#line 95 "hb-ot-shape-complex-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_standalone_cluster); }}
- break;
- case 19:
-#line 96 "hb-ot-shape-complex-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_symbol_cluster); }}
- break;
- case 15:
-#line 97 "hb-ot-shape-complex-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_broken_cluster); }}
- break;
- case 16:
-#line 98 "hb-ot-shape-complex-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_non_indic_cluster); }}
- break;
- case 1:
-#line 93 "hb-ot-shape-complex-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }}
- break;
- case 3:
-#line 94 "hb-ot-shape-complex-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }}
- break;
- case 7:
-#line 95 "hb-ot-shape-complex-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }}
- break;
- case 8:
-#line 96 "hb-ot-shape-complex-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }}
- break;
- case 4:
-#line 97 "hb-ot-shape-complex-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); }}
- break;
- case 6:
-#line 1 "NONE"
- { switch( act ) {
- case 1:
- {{p = ((te))-1;} found_syllable (indic_consonant_syllable); }
- break;
- case 5:
- {{p = ((te))-1;} found_syllable (indic_broken_cluster); }
- break;
- case 6:
- {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); }
- break;
- }
- }
- break;
- case 18:
-#line 1 "NONE"
- {te = p+1;}
-#line 93 "hb-ot-shape-complex-indic-machine.rl"
- {act = 1;}
- break;
- case 5:
-#line 1 "NONE"
- {te = p+1;}
-#line 97 "hb-ot-shape-complex-indic-machine.rl"
- {act = 5;}
- break;
- case 12:
-#line 1 "NONE"
- {te = p+1;}
-#line 98 "hb-ot-shape-complex-indic-machine.rl"
- {act = 6;}
- break;
-#line 573 "hb-ot-shape-complex-indic-machine.hh"
- }
-
-_again:
- switch ( _indic_syllable_machine_to_state_actions[cs] ) {
- case 9:
-#line 1 "NONE"
- {ts = 0;}
- break;
-#line 582 "hb-ot-shape-complex-indic-machine.hh"
- }
-
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- if ( _indic_syllable_machine_eof_trans[cs] > 0 ) {
- _trans = _indic_syllable_machine_eof_trans[cs] - 1;
- goto _eof_trans;
- }
- }
-
- }
-
-#line 130 "hb-ot-shape-complex-indic-machine.rl"
-
-}
-
-#undef found_syllable
-
-#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc
deleted file mode 100644
index 326aa9f96e..0000000000
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc
+++ /dev/null
@@ -1,501 +0,0 @@
-/* == Start of generated table == */
-/*
- * The following table is generated by running:
- *
- * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
- *
- * on files with these headers:
- *
- * # IndicSyllabicCategory-14.0.0.txt
- * # Date: 2021-05-22, 01:01:00 GMT [KW, RP]
- * # IndicPositionalCategory-14.0.0.txt
- * # Date: 2021-05-22, 01:01:00 GMT [KW, RP]
- * # Blocks-14.0.0.txt
- * # Date: 2021-01-22, 23:29:00 GMT [KW]
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shape-complex-indic.hh"
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-macros"
-
-#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 17 chars; Avagraha */
-#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 91 chars; Bindu */
-#define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */
-#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 59 chars; Cantillation_Mark */
-#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2206 chars; Consonant */
-#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 14 chars; Consonant_Dead */
-#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 70 chars; Consonant_Final */
-#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */
-#define ISC_CIP INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED /* 1 chars; Consonant_Initial_Postfixed */
-#define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */
-#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 31 chars; Consonant_Medial */
-#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 22 chars; Consonant_Placeholder */
-#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 3 chars; Consonant_Preceding_Repha */
-#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 10 chars; Consonant_Prefixed */
-#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 94 chars; Consonant_Subjoined */
-#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 1 chars; Consonant_Succeeding_Repha */
-#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 8 chars; Consonant_With_Stacker */
-#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 3 chars; Gemination_Mark */
-#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 12 chars; Invisible_Stacker */
-#define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */
-#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */
-#define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */
-#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 32 chars; Nukta */
-#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 491 chars; Number */
-#define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */
-#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */
-#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 25 chars; Pure_Killer */
-#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */
-#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 25 chars; Syllable_Modifier */
-#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */
-#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */
-#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 27 chars; Virama */
-#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 35 chars; Visarga */
-#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */
-#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 686 chars; Vowel_Dependent */
-#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 486 chars; Vowel_Independent */
-
-#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 352 chars; Bottom */
-#define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT /* 1 chars; Bottom_And_Left */
-#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 4 chars; Bottom_And_Right */
-#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 64 chars; Left */
-#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 22 chars; Left_And_Right */
-#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */
-#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */
-#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 290 chars; Right */
-#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 418 chars; Top */
-#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */
-#define IMC_TBL INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_LEFT /* 2 chars; Top_And_Bottom_And_Left */
-#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */
-#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */
-#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */
-#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 13 chars; Top_And_Right */
-#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 19 chars; Visual_Order_Left */
-
-#pragma GCC diagnostic pop
-
-#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
-
-
-static const uint16_t indic_table[] = {
-
-
-#define indic_offset_0x0028u 0
-
-
- /* Basic Latin */
-
- /* 0028 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), _(x,x), _(x,x),
- /* 0030 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0038 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
-
-#define indic_offset_0x00b0u 24
-
-
- /* Latin-1 Supplement */
-
- /* 00B0 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 00B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 00C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 00C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 00D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x),
-
-#define indic_offset_0x0900u 64
-
-
- /* Devanagari */
-
- /* 0900 */ _(Bi,T), _(Bi,T), _(Bi,T), _(Vs,R), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0908 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0910 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
- /* 0918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0920 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0928 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,B), _(A,x), _(M,R), _(M,L),
- /* 0940 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T),
- /* 0948 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(M,L), _(M,R),
- /* 0950 */ _(x,x), _(Ca,T), _(Ca,B), _(x,T), _(x,T), _(M,T), _(M,B), _(M,B),
- /* 0958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0960 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 0968 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0970 */ _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0978 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
-
- /* Bengali */
-
- /* 0980 */ _(CP,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
- /* 0990 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
- /* 0998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 09A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 09A8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 09B0 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
- /* 09B8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L),
- /* 09C0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
- /* 09C8 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,B), _(CD,x), _(x,x),
- /* 09D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
- /* 09D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
- /* 09E0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 09F0 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(Bi,x), _(x,x), _(SM,T), _(x,x),
-
- /* Gurmukhi */
-
- /* 0A00 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0A08 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x),
- /* 0A10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
- /* 0A18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0A28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0A30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x),
- /* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(x,x), _(M,R), _(M,L),
- /* 0A40 */ _(M,R), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T),
- /* 0A48 */ _(M,T), _(x,x), _(x,x), _(M,T), _(M,T), _(V,B), _(x,x), _(x,x),
- /* 0A50 */ _(x,x), _(Ca,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0A58 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x),
- /* 0A60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0A70 */ _(Bi,T), _(GM,T), _(CP,x), _(CP,x), _(x,x), _(CM,B), _(x,x), _(x,x),
- /* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
-
- /* Gujarati */
-
- /* 0A80 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0A88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x),
- /* 0A90 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
- /* 0A98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0AA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0AA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0AB0 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
- /* 0AB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L),
- /* 0AC0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(x,x), _(M,T),
- /* 0AC8 */ _(M,T), _(M,TR), _(x,x), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x),
- /* 0AD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0AD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0AE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0AF8 */ _(x,x), _(C,x), _(Ca,T), _(Ca,T), _(Ca,T), _(N,T), _(N,T), _(N,T),
-
- /* Oriya */
-
- /* 0B00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
- /* 0B10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
- /* 0B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0B28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0B30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
- /* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T),
- /* 0B40 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
- /* 0B48 */ _(M,TL), _(x,x), _(x,x), _(M,LR),_(M,TLR), _(V,B), _(x,x), _(x,x),
- /* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,T), _(M,TR),
- /* 0B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
- /* 0B60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 0B68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0B70 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
-
- /* Tamil */
-
- /* 0B80 */ _(x,x), _(x,x), _(Bi,T), _(ML,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0B88 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(VI,x),
- /* 0B90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(x,x), _(x,x),
- /* 0B98 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x), _(C,x),
- /* 0BA0 */ _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
- /* 0BA8 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
- /* 0BB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0BB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R),
- /* 0BC0 */ _(M,T), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(M,L), _(M,L),
- /* 0BC8 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(x,x), _(x,x),
- /* 0BD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
- /* 0BD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0BE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 0BE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0BF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
-
- /* Telugu */
-
- /* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(Bi,T), _(VI,x), _(VI,x), _(VI,x),
- /* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
- /* 0C10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
- /* 0C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0C28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0C30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0C38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,T), _(M,T),
- /* 0C40 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,T),
- /* 0C48 */ _(M,TB), _(x,x), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), _(x,x),
- /* 0C50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(x,x),
- /* 0C58 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(CD,x), _(x,x), _(x,x),
- /* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 0C68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0C70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0C78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
-
- /* Kannada */
-
- /* 0C80 */ _(Bi,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0C88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
- /* 0C90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
- /* 0C98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0CA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0CA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0CB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
- /* 0CB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T),
- /* 0CC0 */ _(M,TR), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,TR),
- /* 0CC8 */ _(M,TR), _(x,x), _(M,TR), _(M,TR), _(M,T), _(V,T), _(x,x), _(x,x),
- /* 0CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), _(x,x),
- /* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(C,x), _(x,x),
- /* 0CE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0CF0 */ _(x,x),_(CWS,x),_(CWS,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
-
- /* Malayalam */
-
- /* 0D00 */ _(Bi,T), _(Bi,T), _(Bi,R), _(Vs,R), _(Bi,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
- /* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
- /* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0D20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0D28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0D30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0D38 */ _(C,x), _(C,x), _(C,x), _(PK,T), _(PK,T), _(A,x), _(M,R), _(M,R),
- /* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L),
- /* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T),_(CPR,T), _(x,x),
- /* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(M,R),
- /* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x),
- /* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 0D68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0D70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0D78 */ _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x),
-
- /* Sinhala */
-
- /* 0D80 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
- /* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x),
- /* 0D98 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0DA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0DA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0DB0 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0DB8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x),
- /* 0DC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
- /* 0DC8 */ _(x,x), _(x,x), _(V,T), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
- /* 0DD0 */ _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), _(x,x), _(M,B), _(x,x),
- /* 0DD8 */ _(M,R), _(M,L), _(M,TL), _(M,L), _(M,LR),_(M,TLR), _(M,LR), _(M,R),
- /* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
- /* 0DE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x),
-
-#define indic_offset_0x1000u 1336
-
-
- /* Myanmar */
-
- /* 1000 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 1008 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 1010 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 1018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 1020 */ _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
- /* 1028 */ _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), _(M,T), _(M,T), _(M,B),
- /* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,T), _(TM,B),
- /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R),_(CM,TBL), _(CM,B), _(CM,B), _(C,x),
- /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(CP,x), _(x,x), _(x,x), _(CP,x), _(x,x),
- /* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R),
- /* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,B), _(CM,B),
- /* 1060 */ _(CM,B), _(C,x), _(M,R), _(TM,R), _(TM,R), _(C,x), _(C,x), _(M,R),
- /* 1068 */ _(M,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(C,x), _(C,x),
- /* 1070 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(C,x), _(C,x), _(C,x),
- /* 1078 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 1080 */ _(C,x), _(C,x), _(CM,B), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,R),
- /* 1088 */ _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,B), _(C,x), _(TM,R),
- /* 1090 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 1098 */ _(Nd,x), _(Nd,x), _(TM,R), _(TM,R), _(M,R), _(M,T), _(x,x), _(x,x),
-
-#define indic_offset_0x1780u 1496
-
-
- /* Khmer */
-
- /* 1780 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 1788 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 1790 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 1798 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 17A0 */ _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
- /* 17A8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
- /* 17B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(M,R), _(M,T),
- /* 17B8 */ _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,TL),_(M,TLR),
- /* 17C0 */ _(M,LR), _(M,L), _(M,L), _(M,L), _(M,LR), _(M,LR), _(Bi,T), _(Vs,R),
- /* 17C8 */ _(M,R), _(RS,T), _(RS,T), _(SM,T),_(CSR,T), _(CK,T), _(SM,T), _(SM,T),
- /* 17D0 */ _(SM,T), _(PK,T), _(IS,x), _(SM,T), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(SM,T), _(x,x), _(x,x),
- /* 17E0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* 17E8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
-
-#define indic_offset_0x1cd0u 1608
-
-
- /* Vedic Extensions */
-
- /* 1CD0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(Ca,O), _(Ca,B), _(Ca,B), _(Ca,B),
- /* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B),
- /* 1CE0 */ _(Ca,T), _(Ca,R), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O),
- /* 1CE8 */ _(x,O), _(x,x), _(x,x), _(x,x), _(x,x), _(x,B), _(x,x), _(x,x),
- /* 1CF0 */ _(x,x), _(x,x), _(CD,x), _(CD,x), _(Ca,T),_(CWS,x),_(CWS,x), _(Ca,R),
- /* 1CF8 */ _(Ca,x), _(Ca,x), _(CP,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
-
-#define indic_offset_0x2008u 1656
-
-
- /* General Punctuation */
-
- /* 2008 */ _(x,x), _(x,x), _(x,x), _(x,x),_(ZWNJ,x),_(ZWJ,x), _(x,x), _(x,x),
- /* 2010 */ _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), _(x,x), _(x,x),
-
-#define indic_offset_0x2070u 1672
-
-
- /* Superscripts and Subscripts */
-
- /* 2070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(SM,x), _(x,x), _(x,x), _(x,x),
- /* 2078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 2080 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x),
-
-#define indic_offset_0xa8e0u 1696
-
-
- /* Devanagari Extended */
-
- /* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
- /* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
- /* A8F0 */ _(Ca,T), _(Ca,T), _(Bi,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* A8F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(M,T),
-
-#define indic_offset_0xa9e0u 1728
-
-
- /* Myanmar Extended-B */
-
- /* A9E0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), _(x,x), _(C,x),
- /* A9E8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
- /* A9F8 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
-
-#define indic_offset_0xaa60u 1760
-
-
- /* Myanmar Extended-A */
-
- /* AA60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* AA68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(CP,x), _(CP,x), _(CP,x), _(x,x),
- /* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,R), _(TM,T), _(TM,R), _(C,x), _(C,x),
-
-}; /* Table items: 1792; occupancy: 71% */
-
-uint16_t
-hb_indic_get_categories (hb_codepoint_t u)
-{
- switch (u >> 12)
- {
- case 0x0u:
- if (unlikely (u == 0x00A0u)) return _(CP,x);
- if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
- if (hb_in_range<hb_codepoint_t> (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u];
- if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
- break;
-
- case 0x1u:
- if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u];
- if (hb_in_range<hb_codepoint_t> (u, 0x1780u, 0x17EFu)) return indic_table[u - 0x1780u + indic_offset_0x1780u];
- if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
- break;
-
- case 0x2u:
- if (unlikely (u == 0x25CCu)) return _(CP,x);
- if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u];
- if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u];
- break;
-
- case 0xAu:
- if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8FFu)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u];
- if (hb_in_range<hb_codepoint_t> (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u];
- if (hb_in_range<hb_codepoint_t> (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u];
- break;
-
- default:
- break;
- }
- return _(x,x);
-}
-
-#undef _
-
-#undef ISC_A
-#undef ISC_Bi
-#undef ISC_BJN
-#undef ISC_Ca
-#undef ISC_C
-#undef ISC_CD
-#undef ISC_CF
-#undef ISC_CHL
-#undef ISC_CIP
-#undef ISC_CK
-#undef ISC_CM
-#undef ISC_CP
-#undef ISC_CPR
-#undef ISC_CPrf
-#undef ISC_CS
-#undef ISC_CSR
-#undef ISC_CWS
-#undef ISC_GM
-#undef ISC_IS
-#undef ISC_ZWJ
-#undef ISC_ML
-#undef ISC_ZWNJ
-#undef ISC_N
-#undef ISC_Nd
-#undef ISC_NJ
-#undef ISC_x
-#undef ISC_PK
-#undef ISC_RS
-#undef ISC_SM
-#undef ISC_TL
-#undef ISC_TM
-#undef ISC_V
-#undef ISC_Vs
-#undef ISC_Vo
-#undef ISC_M
-#undef ISC_VI
-
-#undef IMC_B
-#undef IMC_BL
-#undef IMC_BR
-#undef IMC_L
-#undef IMC_LR
-#undef IMC_x
-#undef IMC_O
-#undef IMC_R
-#undef IMC_T
-#undef IMC_TB
-#undef IMC_TBL
-#undef IMC_TBR
-#undef IMC_TL
-#undef IMC_TLR
-#undef IMC_TR
-#undef IMC_VOL
-
-#endif
-
-/* == End of generated table == */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.hh
deleted file mode 100644
index da77a2887c..0000000000
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.hh
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright © 2012 Google, Inc.
- *
- * 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
- */
-
-#ifndef HB_OT_SHAPE_COMPLEX_INDIC_HH
-#define HB_OT_SHAPE_COMPLEX_INDIC_HH
-
-#include "hb.hh"
-
-#include "hb-ot-shape-complex-syllabic.hh"
-
-
-/* buffer var allocations */
-#define indic_category() complex_var_u8_category() /* indic_category_t */
-#define indic_position() complex_var_u8_auxiliary() /* indic_position_t */
-
-
-/* Cateories used in the OpenType spec:
- * https://docs.microsoft.com/en-us/typography/script-development/devanagari
- */
-/* Note: This enum is duplicated in the -machine.rl source file.
- * Not sure how to avoid duplication. */
-enum indic_category_t {
- OT_X = 0,
- OT_C = 1,
- OT_V = 2,
- OT_N = 3,
- OT_H = 4,
- OT_ZWNJ = 5,
- OT_ZWJ = 6,
- OT_M = 7,
- OT_SM = 8,
- /* OT_VD = 9, UNUSED; we use OT_A instead. */
- OT_A = 10,
- OT_PLACEHOLDER = 11,
- OT_DOTTEDCIRCLE = 12,
- OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
- OT_Coeng = 14, /* Khmer-style Virama. */
- OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
- OT_Ra = 16,
- OT_CM = 17, /* Consonant-Medial. */
- OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
- OT_CS = 19,
-
- /* The following are used by Khmer & Myanmar shapers. Defined
- * here for them to share. */
- OT_VAbv = 26,
- OT_VBlw = 27,
- OT_VPre = 28,
- OT_VPst = 29,
-};
-
-#define MEDIAL_FLAGS (FLAG (OT_CM))
-
-/* Note:
- *
- * We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
- * cannot happen in a consonant syllable. The plus side however is, we can call the
- * consonant syllable logic from the vowel syllable function and get it all right! */
-#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
-#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
-
-
-/* Visual positions in a syllable from left to right. */
-enum indic_position_t {
- POS_START = 0,
-
- POS_RA_TO_BECOME_REPH = 1,
- POS_PRE_M = 2,
- POS_PRE_C = 3,
-
- POS_BASE_C = 4,
- POS_AFTER_MAIN = 5,
-
- POS_ABOVE_C = 6,
-
- POS_BEFORE_SUB = 7,
- POS_BELOW_C = 8,
- POS_AFTER_SUB = 9,
-
- POS_BEFORE_POST = 10,
- POS_POST_C = 11,
- POS_AFTER_POST = 12,
-
- POS_FINAL_C = 13,
- POS_SMVD = 14,
-
- POS_END = 15
-};
-
-/* Categories used in IndicSyllabicCategory.txt from UCD. */
-enum indic_syllabic_category_t {
- INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
-
- INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_Symbol,
- INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
- INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER = OT_PLACEHOLDER, /* Don't care. */
- INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK = OT_A,
- INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_CM,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER = OT_M, /* U+17CD only. */
- INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_PLACEHOLDER,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA = OT_Repha,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED = OT_X, /* Don't care. */
- INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_CM,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_CS,
- INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM, /* https://github.com/harfbuzz/harfbuzz/issues/552 */
- INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_Coeng,
- INDIC_SYLLABIC_CATEGORY_JOINER = OT_ZWJ,
- INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
- INDIC_SYLLABIC_CATEGORY_NON_JOINER = OT_ZWNJ,
- INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
- INDIC_SYLLABIC_CATEGORY_NUMBER = OT_PLACEHOLDER,
- INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER = OT_PLACEHOLDER, /* Don't care. */
- INDIC_SYLLABIC_CATEGORY_PURE_KILLER = OT_M, /* Is like a vowel matra. */
- INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS,
- INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER = OT_SM,
- INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
- INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N,
- INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
- INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
- INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
- INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M,
- INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V
-};
-
-/* Categories used in IndicSMatraCategory.txt from UCD */
-enum indic_matra_category_t {
- INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_END,
-
- INDIC_MATRA_CATEGORY_LEFT = POS_PRE_C,
- INDIC_MATRA_CATEGORY_TOP = POS_ABOVE_C,
- INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW_C,
- INDIC_MATRA_CATEGORY_RIGHT = POS_POST_C,
-
- /* These should resolve to the position of the last part of the split sequence. */
- INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
- INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
- INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM,
- INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_LEFT = INDIC_MATRA_CATEGORY_BOTTOM,
- INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
- INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_TOP,
- INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
- INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
-
- INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN,
- INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M
-};
-
-#define INDIC_COMBINE_CATEGORIES(S,M) \
- ( \
- static_assert_expr (S < 255 && M < 255) + \
- ( S | \
- ( \
- ( \
- S == INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL || \
- S == INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK || \
- S == INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER || \
- S == INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA || \
- S == INDIC_SYLLABIC_CATEGORY_VIRAMA || \
- S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT || \
- false \
- ? M : INDIC_MATRA_CATEGORY_NOT_APPLICABLE \
- ) << 8 \
- ) \
- ) \
- )
-
-HB_INTERNAL uint16_t
-hb_indic_get_categories (hb_codepoint_t u);
-
-
-static inline bool
-is_one_of (const hb_glyph_info_t &info, unsigned int flags)
-{
- /* If it ligated, all bets are off. */
- if (_hb_glyph_info_ligated (&info)) return false;
- return !!(FLAG_UNSAFE (info.indic_category()) & flags);
-}
-
-static inline bool
-is_joiner (const hb_glyph_info_t &info)
-{
- return is_one_of (info, JOINER_FLAGS);
-}
-
-static inline bool
-is_consonant (const hb_glyph_info_t &info)
-{
- return is_one_of (info, CONSONANT_FLAGS);
-}
-
-static inline bool
-is_halant (const hb_glyph_info_t &info)
-{
- return is_one_of (info, FLAG (OT_H));
-}
-
-#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base))
-
-#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u))
-#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u))
-#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u))
-#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u))
-#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u))
-#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u))
-#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u))
-#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u))
-#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u))
-#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u))
-
-
-#define MATRA_POS_LEFT(u) POS_PRE_M
-#define MATRA_POS_RIGHT(u) ( \
- IS_DEVA(u) ? POS_AFTER_SUB : \
- IS_BENG(u) ? POS_AFTER_POST : \
- IS_GURU(u) ? POS_AFTER_POST : \
- IS_GUJR(u) ? POS_AFTER_POST : \
- IS_ORYA(u) ? POS_AFTER_POST : \
- IS_TAML(u) ? POS_AFTER_POST : \
- IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
- IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
- IS_MLYM(u) ? POS_AFTER_POST : \
- IS_SINH(u) ? POS_AFTER_SUB : \
- /*default*/ POS_AFTER_SUB \
- )
-#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \
- IS_DEVA(u) ? POS_AFTER_SUB : \
- IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \
- IS_GUJR(u) ? POS_AFTER_SUB : \
- IS_ORYA(u) ? POS_AFTER_MAIN : \
- IS_TAML(u) ? POS_AFTER_SUB : \
- IS_TELU(u) ? POS_BEFORE_SUB : \
- IS_KNDA(u) ? POS_BEFORE_SUB : \
- IS_SINH(u) ? POS_AFTER_SUB : \
- /*default*/ POS_AFTER_SUB \
- )
-#define MATRA_POS_BOTTOM(u) ( \
- IS_DEVA(u) ? POS_AFTER_SUB : \
- IS_BENG(u) ? POS_AFTER_SUB : \
- IS_GURU(u) ? POS_AFTER_POST : \
- IS_GUJR(u) ? POS_AFTER_POST : \
- IS_ORYA(u) ? POS_AFTER_SUB : \
- IS_TAML(u) ? POS_AFTER_POST : \
- IS_TELU(u) ? POS_BEFORE_SUB : \
- IS_KNDA(u) ? POS_BEFORE_SUB : \
- IS_MLYM(u) ? POS_AFTER_POST : \
- IS_SINH(u) ? POS_AFTER_SUB : \
- /*default*/ POS_AFTER_SUB \
- )
-
-static inline indic_position_t
-matra_position_indic (hb_codepoint_t u, indic_position_t side)
-{
- switch ((int) side)
- {
- case POS_PRE_C: return MATRA_POS_LEFT (u);
- case POS_POST_C: return MATRA_POS_RIGHT (u);
- case POS_ABOVE_C: return MATRA_POS_TOP (u);
- case POS_BELOW_C: return MATRA_POS_BOTTOM (u);
- }
- return side;
-}
-
-/* XXX
- * This is a hack for now. We should move this data into the main Indic table.
- * Or completely remove it and just check in the tables.
- */
-static const hb_codepoint_t ra_chars[] = {
- 0x0930u, /* Devanagari */
- 0x09B0u, /* Bengali */
- 0x09F0u, /* Bengali */
- 0x0A30u, /* Gurmukhi */ /* No Reph */
- 0x0AB0u, /* Gujarati */
- 0x0B30u, /* Oriya */
- 0x0BB0u, /* Tamil */ /* No Reph */
- 0x0C30u, /* Telugu */ /* Reph formed only with ZWJ */
- 0x0CB0u, /* Kannada */
- 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */
-
- 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */
-};
-
-static inline bool
-is_ra (hb_codepoint_t u)
-{
- return hb_array (ra_chars).lfind (u);
-}
-
-static inline void
-set_indic_properties (hb_glyph_info_t &info)
-{
- hb_codepoint_t u = info.codepoint;
- unsigned int type = hb_indic_get_categories (u);
- indic_category_t cat = (indic_category_t) (type & 0xFFu);
- indic_position_t pos = (indic_position_t) (type >> 8);
-
-
- /*
- * Re-assign category
- */
-
- /* The following act more like the Bindus. */
- if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0953u, 0x0954u)))
- cat = OT_SM;
- /* The following act like consonants. */
- else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x0A72u, 0x0A73u,
- 0x1CF5u, 0x1CF6u)))
- cat = OT_C;
- /* TODO: The following should only be allowed after a Visarga.
- * For now, just treat them like regular tone marks. */
- else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1CE2u, 0x1CE8u)))
- cat = OT_A;
- /* TODO: The following should only be allowed after some of
- * the nasalization marks, maybe only for U+1CE9..U+1CF1.
- * For now, just treat them like tone marks. */
- else if (unlikely (u == 0x1CEDu))
- cat = OT_A;
- /* The following take marks in standalone clusters, similar to Avagraha. */
- else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0xA8F2u, 0xA8F7u,
- 0x1CE9u, 0x1CECu,
- 0x1CEEu, 0x1CF1u)))
- {
- cat = OT_Symbol;
- static_assert (((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol), "");
- }
- else if (unlikely (u == 0x0A51u))
- {
- /* https://github.com/harfbuzz/harfbuzz/issues/524 */
- cat = OT_M;
- pos = POS_BELOW_C;
- }
-
- /* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
- * so the Indic shaper needs to know their categories. */
- else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM;
- else if (unlikely (u == 0x1133Bu || u == 0x1133Cu)) cat = OT_N;
-
- else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */
- else if (unlikely (u == 0x0B55u)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/2849 */
-
- else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */
- else if (unlikely (u == 0x09FCu)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/1613 */
- else if (unlikely (u == 0x0C80u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/623 */
- else if (unlikely (u == 0x0D04u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/3511 */
- else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u)))
- cat = OT_PLACEHOLDER;
- else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;
-
-
- /*
- * Re-assign position.
- */
-
- if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS))
- {
- pos = POS_BASE_C;
- if (is_ra (u))
- cat = OT_Ra;
- }
- else if (cat == OT_M)
- {
- pos = matra_position_indic (u, pos);
- }
- else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) /* | FLAG (OT_VD) */ | FLAG (OT_A) | FLAG (OT_Symbol))))
- {
- pos = POS_SMVD;
- }
-
- if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */
-
-
-
- info.indic_category() = cat;
- info.indic_position() = pos;
-}
-
-struct hb_indic_would_substitute_feature_t
-{
- void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
- {
- zero_context = zero_context_;
- map->get_stage_lookups (0/*GSUB*/,
- map->get_feature_stage (0/*GSUB*/, feature_tag),
- &lookups, &count);
- }
-
- bool would_substitute (const hb_codepoint_t *glyphs,
- unsigned int glyphs_count,
- hb_face_t *face) const
- {
- for (unsigned int i = 0; i < count; i++)
- if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
- return true;
- return false;
- }
-
- private:
- const hb_ot_map_t::lookup_map_t *lookups;
- unsigned int count;
- bool zero_context;
-};
-
-
-#endif /* HB_OT_SHAPE_COMPLEX_INDIC_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh
deleted file mode 100644
index c52f72f394..0000000000
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh
+++ /dev/null
@@ -1,396 +0,0 @@
-
-#line 1 "hb-ot-shape-complex-khmer-machine.rl"
-/*
- * Copyright © 2011,2012 Google, Inc.
- *
- * 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
- */
-
-#ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH
-#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH
-
-#include "hb.hh"
-
-enum khmer_syllable_type_t {
- khmer_consonant_syllable,
- khmer_broken_cluster,
- khmer_non_khmer_cluster,
-};
-
-
-#line 42 "hb-ot-shape-complex-khmer-machine.hh"
-#define khmer_syllable_machine_ex_C 1u
-#define khmer_syllable_machine_ex_Coeng 14u
-#define khmer_syllable_machine_ex_DOTTEDCIRCLE 12u
-#define khmer_syllable_machine_ex_PLACEHOLDER 11u
-#define khmer_syllable_machine_ex_Ra 16u
-#define khmer_syllable_machine_ex_Robatic 20u
-#define khmer_syllable_machine_ex_V 2u
-#define khmer_syllable_machine_ex_VAbv 26u
-#define khmer_syllable_machine_ex_VBlw 27u
-#define khmer_syllable_machine_ex_VPre 28u
-#define khmer_syllable_machine_ex_VPst 29u
-#define khmer_syllable_machine_ex_Xgroup 21u
-#define khmer_syllable_machine_ex_Ygroup 22u
-#define khmer_syllable_machine_ex_ZWJ 6u
-#define khmer_syllable_machine_ex_ZWNJ 5u
-
-
-#line 60 "hb-ot-shape-complex-khmer-machine.hh"
-static const unsigned char _khmer_syllable_machine_trans_keys[] = {
- 5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u,
- 5u, 26u, 5u, 21u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u,
- 5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 1u, 29u, 5u, 29u, 5u, 29u, 5u, 29u,
- 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 26u, 5u, 29u,
- 5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 29u, 5u, 29u,
- 0
-};
-
-static const char _khmer_syllable_machine_key_spans[] = {
- 22, 17, 22, 17, 16, 17, 22, 17,
- 22, 17, 17, 22, 17, 16, 17, 22,
- 17, 22, 17, 22, 29, 25, 25, 25,
- 1, 18, 25, 25, 25, 16, 22, 25,
- 25, 1, 18, 25, 25, 16, 25, 25
-};
-
-static const short _khmer_syllable_machine_index_offsets[] = {
- 0, 23, 41, 64, 82, 99, 117, 140,
- 158, 181, 199, 217, 240, 258, 275, 293,
- 316, 334, 357, 375, 398, 428, 454, 480,
- 506, 508, 527, 553, 579, 605, 622, 645,
- 671, 697, 699, 718, 744, 770, 787, 813
-};
-
-static const char _khmer_syllable_machine_indicies[] = {
- 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 2,
- 3, 0, 0, 0, 0, 4, 0, 1,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 3, 0, 0, 0, 0, 4, 0,
- 5, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 0, 6, 6, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 6, 0, 7, 7, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 8, 0, 9, 9, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 10, 0, 0,
- 0, 0, 4, 0, 9, 9, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 10, 0, 11, 11,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12, 0,
- 0, 0, 0, 4, 0, 11, 11, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 12, 0, 14,
- 14, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 15,
- 13, 14, 14, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 15, 16, 16, 16, 16, 17, 16,
- 18, 18, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 17, 16, 19, 19, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 19, 16, 20, 20, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 21, 16, 22, 22, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 23, 16, 16,
- 16, 16, 17, 16, 22, 22, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 23, 16, 24, 24,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 25, 16,
- 16, 16, 16, 17, 16, 24, 24, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 25, 16, 14,
- 14, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 26, 15,
- 16, 16, 16, 16, 17, 16, 28, 28,
- 27, 27, 29, 29, 27, 27, 27, 27,
- 2, 2, 27, 30, 27, 28, 27, 27,
- 27, 27, 15, 19, 27, 27, 27, 17,
- 23, 25, 21, 27, 32, 32, 31, 31,
- 31, 31, 31, 31, 31, 33, 31, 31,
- 31, 31, 31, 2, 3, 6, 31, 31,
- 31, 4, 10, 12, 8, 31, 34, 34,
- 31, 31, 31, 31, 31, 31, 31, 35,
- 31, 31, 31, 31, 31, 31, 3, 6,
- 31, 31, 31, 4, 10, 12, 8, 31,
- 5, 5, 31, 31, 31, 31, 31, 31,
- 31, 35, 31, 31, 31, 31, 31, 31,
- 4, 6, 31, 31, 31, 31, 31, 31,
- 8, 31, 6, 31, 7, 7, 31, 31,
- 31, 31, 31, 31, 31, 35, 31, 31,
- 31, 31, 31, 31, 8, 6, 31, 36,
- 36, 31, 31, 31, 31, 31, 31, 31,
- 35, 31, 31, 31, 31, 31, 31, 10,
- 6, 31, 31, 31, 4, 31, 31, 8,
- 31, 37, 37, 31, 31, 31, 31, 31,
- 31, 31, 35, 31, 31, 31, 31, 31,
- 31, 12, 6, 31, 31, 31, 4, 10,
- 31, 8, 31, 34, 34, 31, 31, 31,
- 31, 31, 31, 31, 33, 31, 31, 31,
- 31, 31, 31, 3, 6, 31, 31, 31,
- 4, 10, 12, 8, 31, 28, 28, 31,
- 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 28, 31, 14, 14,
- 38, 38, 38, 38, 38, 38, 38, 38,
- 38, 38, 38, 38, 38, 38, 15, 38,
- 38, 38, 38, 17, 38, 40, 40, 39,
- 39, 39, 39, 39, 39, 39, 41, 39,
- 39, 39, 39, 39, 39, 15, 19, 39,
- 39, 39, 17, 23, 25, 21, 39, 18,
- 18, 39, 39, 39, 39, 39, 39, 39,
- 41, 39, 39, 39, 39, 39, 39, 17,
- 19, 39, 39, 39, 39, 39, 39, 21,
- 39, 19, 39, 20, 20, 39, 39, 39,
- 39, 39, 39, 39, 41, 39, 39, 39,
- 39, 39, 39, 21, 19, 39, 42, 42,
- 39, 39, 39, 39, 39, 39, 39, 41,
- 39, 39, 39, 39, 39, 39, 23, 19,
- 39, 39, 39, 17, 39, 39, 21, 39,
- 43, 43, 39, 39, 39, 39, 39, 39,
- 39, 41, 39, 39, 39, 39, 39, 39,
- 25, 19, 39, 39, 39, 17, 23, 39,
- 21, 39, 44, 44, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 44, 39, 45, 45, 39, 39, 39,
- 39, 39, 39, 39, 30, 39, 39, 39,
- 39, 39, 26, 15, 19, 39, 39, 39,
- 17, 23, 25, 21, 39, 40, 40, 39,
- 39, 39, 39, 39, 39, 39, 30, 39,
- 39, 39, 39, 39, 39, 15, 19, 39,
- 39, 39, 17, 23, 25, 21, 39, 0
-};
-
-static const char _khmer_syllable_machine_trans_targs[] = {
- 20, 1, 28, 22, 23, 3, 24, 5,
- 25, 7, 26, 9, 27, 20, 10, 31,
- 20, 32, 12, 33, 14, 34, 16, 35,
- 18, 36, 39, 20, 21, 30, 37, 20,
- 0, 29, 2, 4, 6, 8, 20, 20,
- 11, 13, 15, 17, 38, 19
-};
-
-static const char _khmer_syllable_machine_trans_actions[] = {
- 1, 0, 2, 2, 2, 0, 0, 0,
- 2, 0, 2, 0, 2, 3, 0, 4,
- 5, 2, 0, 0, 0, 2, 0, 2,
- 0, 2, 4, 8, 2, 9, 0, 10,
- 0, 0, 0, 0, 0, 0, 11, 12,
- 0, 0, 0, 0, 4, 0
-};
-
-static const char _khmer_syllable_machine_to_state_actions[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const char _khmer_syllable_machine_from_state_actions[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 7, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const unsigned char _khmer_syllable_machine_eof_trans[] = {
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 14, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 0, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 39, 40,
- 40, 40, 40, 40, 40, 40, 40, 40
-};
-
-static const int khmer_syllable_machine_start = 20;
-static const int khmer_syllable_machine_first_final = 20;
-static const int khmer_syllable_machine_error = -1;
-
-static const int khmer_syllable_machine_en_main = 20;
-
-
-#line 43 "hb-ot-shape-complex-khmer-machine.rl"
-
-
-
-#line 86 "hb-ot-shape-complex-khmer-machine.rl"
-
-
-#define found_syllable(syllable_type) \
- HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
- for (unsigned int i = ts; i < te; i++) \
- info[i].syllable() = (syllable_serial << 4) | syllable_type; \
- syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
- } HB_STMT_END
-
-static void
-find_syllables_khmer (hb_buffer_t *buffer)
-{
- unsigned int p, pe, eof, ts, te, act HB_UNUSED;
- int cs;
- hb_glyph_info_t *info = buffer->info;
-
-#line 266 "hb-ot-shape-complex-khmer-machine.hh"
- {
- cs = khmer_syllable_machine_start;
- ts = 0;
- te = 0;
- act = 0;
- }
-
-#line 106 "hb-ot-shape-complex-khmer-machine.rl"
-
-
- p = 0;
- pe = eof = buffer->len;
-
- unsigned int syllable_serial = 1;
-
-#line 282 "hb-ot-shape-complex-khmer-machine.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
-_resume:
- switch ( _khmer_syllable_machine_from_state_actions[cs] ) {
- case 7:
-#line 1 "NONE"
- {ts = p;}
- break;
-#line 296 "hb-ot-shape-complex-khmer-machine.hh"
- }
-
- _keys = _khmer_syllable_machine_trans_keys + (cs<<1);
- _inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs];
-
- _slen = _khmer_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) &&
- ( info[p].khmer_category()) <= _keys[1] ?
- ( info[p].khmer_category()) - _keys[0] : _slen ];
-
-_eof_trans:
- cs = _khmer_syllable_machine_trans_targs[_trans];
-
- if ( _khmer_syllable_machine_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _khmer_syllable_machine_trans_actions[_trans] ) {
- case 2:
-#line 1 "NONE"
- {te = p+1;}
- break;
- case 8:
-#line 82 "hb-ot-shape-complex-khmer-machine.rl"
- {te = p+1;{ found_syllable (khmer_non_khmer_cluster); }}
- break;
- case 10:
-#line 80 "hb-ot-shape-complex-khmer-machine.rl"
- {te = p;p--;{ found_syllable (khmer_consonant_syllable); }}
- break;
- case 12:
-#line 81 "hb-ot-shape-complex-khmer-machine.rl"
- {te = p;p--;{ found_syllable (khmer_broken_cluster); }}
- break;
- case 11:
-#line 82 "hb-ot-shape-complex-khmer-machine.rl"
- {te = p;p--;{ found_syllable (khmer_non_khmer_cluster); }}
- break;
- case 1:
-#line 80 "hb-ot-shape-complex-khmer-machine.rl"
- {{p = ((te))-1;}{ found_syllable (khmer_consonant_syllable); }}
- break;
- case 5:
-#line 81 "hb-ot-shape-complex-khmer-machine.rl"
- {{p = ((te))-1;}{ found_syllable (khmer_broken_cluster); }}
- break;
- case 3:
-#line 1 "NONE"
- { switch( act ) {
- case 2:
- {{p = ((te))-1;} found_syllable (khmer_broken_cluster); }
- break;
- case 3:
- {{p = ((te))-1;} found_syllable (khmer_non_khmer_cluster); }
- break;
- }
- }
- break;
- case 4:
-#line 1 "NONE"
- {te = p+1;}
-#line 81 "hb-ot-shape-complex-khmer-machine.rl"
- {act = 2;}
- break;
- case 9:
-#line 1 "NONE"
- {te = p+1;}
-#line 82 "hb-ot-shape-complex-khmer-machine.rl"
- {act = 3;}
- break;
-#line 366 "hb-ot-shape-complex-khmer-machine.hh"
- }
-
-_again:
- switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
- case 6:
-#line 1 "NONE"
- {ts = 0;}
- break;
-#line 375 "hb-ot-shape-complex-khmer-machine.hh"
- }
-
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) {
- _trans = _khmer_syllable_machine_eof_trans[cs] - 1;
- goto _eof_trans;
- }
- }
-
- }
-
-#line 114 "hb-ot-shape-complex-khmer-machine.rl"
-
-}
-
-#undef found_syllable
-
-#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh
deleted file mode 100644
index 35bfbb64d5..0000000000
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright © 2018 Google, Inc.
- *
- * 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
- */
-
-#ifndef HB_OT_SHAPE_COMPLEX_KHMER_HH
-#define HB_OT_SHAPE_COMPLEX_KHMER_HH
-
-#include "hb.hh"
-
-#include "hb-ot-shape-complex-indic.hh"
-
-
-/* buffer var allocations */
-#define khmer_category() indic_category() /* khmer_category_t */
-
-
-/* Note: This enum is duplicated in the -machine.rl source file.
- * Not sure how to avoid duplication. */
-enum khmer_category_t
-{
- OT_Robatic = 20,
- OT_Xgroup = 21,
- OT_Ygroup = 22,
- //OT_VAbv = 26,
- //OT_VBlw = 27,
- //OT_VPre = 28,
- //OT_VPst = 29,
-};
-
-using khmer_position_t = indic_position_t;
-
-static inline void
-set_khmer_properties (hb_glyph_info_t &info)
-{
- hb_codepoint_t u = info.codepoint;
- unsigned int type = hb_indic_get_categories (u);
- khmer_category_t cat = (khmer_category_t) (type & 0xFFu);
- khmer_position_t pos = (khmer_position_t) (type >> 8);
-
-
- /*
- * Re-assign category
- *
- * These categories are experimentally extracted from what Uniscribe allows.
- */
- switch (u)
- {
- case 0x179Au:
- cat = (khmer_category_t) OT_Ra;
- break;
-
- case 0x17CCu:
- case 0x17C9u:
- case 0x17CAu:
- cat = OT_Robatic;
- break;
-
- case 0x17C6u:
- case 0x17CBu:
- case 0x17CDu:
- case 0x17CEu:
- case 0x17CFu:
- case 0x17D0u:
- case 0x17D1u:
- cat = OT_Xgroup;
- break;
-
- case 0x17C7u:
- case 0x17C8u:
- case 0x17DDu:
- case 0x17D3u: /* Just guessing. Uniscribe doesn't categorize it. */
- cat = OT_Ygroup;
- break;
- }
-
- /*
- * Re-assign position.
- */
- if (cat == (khmer_category_t) OT_M)
- switch ((int) pos)
- {
- case POS_PRE_C: cat = (khmer_category_t) OT_VPre; break;
- case POS_BELOW_C: cat = (khmer_category_t) OT_VBlw; break;
- case POS_ABOVE_C: cat = (khmer_category_t) OT_VAbv; break;
- case POS_POST_C: cat = (khmer_category_t) OT_VPst; break;
- default: assert (0);
- }
-
- info.khmer_category() = cat;
-}
-
-
-#endif /* HB_OT_SHAPE_COMPLEX_KHMER_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh
deleted file mode 100644
index f4ef33004d..0000000000
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh
+++ /dev/null
@@ -1,492 +0,0 @@
-
-#line 1 "hb-ot-shape-complex-myanmar-machine.rl"
-/*
- * Copyright © 2011,2012 Google, Inc.
- *
- * 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
- */
-
-#ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
-#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
-
-#include "hb.hh"
-
-enum myanmar_syllable_type_t {
- myanmar_consonant_syllable,
- myanmar_punctuation_cluster,
- myanmar_broken_cluster,
- myanmar_non_myanmar_cluster,
-};
-
-
-#line 43 "hb-ot-shape-complex-myanmar-machine.hh"
-#define myanmar_syllable_machine_ex_A 10u
-#define myanmar_syllable_machine_ex_As 18u
-#define myanmar_syllable_machine_ex_C 1u
-#define myanmar_syllable_machine_ex_CS 19u
-#define myanmar_syllable_machine_ex_D 32u
-#define myanmar_syllable_machine_ex_D0 20u
-#define myanmar_syllable_machine_ex_DB 3u
-#define myanmar_syllable_machine_ex_GB 11u
-#define myanmar_syllable_machine_ex_H 4u
-#define myanmar_syllable_machine_ex_IV 2u
-#define myanmar_syllable_machine_ex_MH 21u
-#define myanmar_syllable_machine_ex_ML 33u
-#define myanmar_syllable_machine_ex_MR 22u
-#define myanmar_syllable_machine_ex_MW 23u
-#define myanmar_syllable_machine_ex_MY 24u
-#define myanmar_syllable_machine_ex_P 31u
-#define myanmar_syllable_machine_ex_PT 25u
-#define myanmar_syllable_machine_ex_Ra 16u
-#define myanmar_syllable_machine_ex_V 8u
-#define myanmar_syllable_machine_ex_VAbv 26u
-#define myanmar_syllable_machine_ex_VBlw 27u
-#define myanmar_syllable_machine_ex_VPre 28u
-#define myanmar_syllable_machine_ex_VPst 29u
-#define myanmar_syllable_machine_ex_VS 30u
-#define myanmar_syllable_machine_ex_ZWJ 6u
-#define myanmar_syllable_machine_ex_ZWNJ 5u
-
-
-#line 72 "hb-ot-shape-complex-myanmar-machine.hh"
-static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
- 1u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
- 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u,
- 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u, 3u, 33u,
- 3u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
- 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u,
- 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u,
- 3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 1u, 33u, 1u, 32u, 8u, 8u,
- 0
-};
-
-static const char _myanmar_syllable_machine_key_spans[] = {
- 33, 31, 25, 4, 25, 23, 21, 21,
- 31, 27, 27, 27, 31, 16, 31, 31,
- 27, 27, 27, 28, 27, 31, 31, 31,
- 31, 31, 25, 4, 25, 23, 21, 21,
- 31, 27, 27, 27, 31, 16, 31, 31,
- 31, 27, 27, 27, 28, 27, 31, 31,
- 31, 31, 31, 31, 31, 33, 32, 1
-};
-
-static const short _myanmar_syllable_machine_index_offsets[] = {
- 0, 34, 66, 92, 97, 123, 147, 169,
- 191, 223, 251, 279, 307, 339, 356, 388,
- 420, 448, 476, 504, 533, 561, 593, 625,
- 657, 689, 721, 747, 752, 778, 802, 824,
- 846, 878, 906, 934, 962, 994, 1011, 1043,
- 1075, 1107, 1135, 1163, 1191, 1220, 1248, 1280,
- 1312, 1344, 1376, 1408, 1440, 1472, 1506, 1539
-};
-
-static const char _myanmar_syllable_machine_indicies[] = {
- 1, 1, 2, 3, 4, 4, 0, 5,
- 0, 6, 1, 0, 0, 0, 0, 7,
- 0, 8, 9, 0, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 1,
- 21, 0, 23, 24, 25, 25, 22, 26,
- 22, 27, 22, 22, 22, 22, 22, 22,
- 22, 28, 22, 22, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 22, 22,
- 39, 22, 25, 25, 22, 26, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 40,
- 22, 22, 22, 22, 22, 22, 33, 22,
- 22, 22, 37, 22, 25, 25, 22, 26,
- 22, 25, 25, 22, 26, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 33, 22, 22,
- 22, 37, 22, 41, 22, 25, 25, 22,
- 26, 22, 33, 22, 22, 22, 22, 22,
- 22, 22, 42, 22, 22, 22, 22, 22,
- 22, 33, 22, 25, 25, 22, 26, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 42, 22, 22, 22, 22, 22, 22, 33,
- 22, 25, 25, 22, 26, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 33, 22, 23,
- 22, 25, 25, 22, 26, 22, 27, 22,
- 22, 22, 22, 22, 22, 22, 43, 22,
- 22, 44, 22, 22, 22, 33, 45, 22,
- 22, 37, 22, 22, 22, 43, 22, 23,
- 22, 25, 25, 22, 26, 22, 27, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 33, 22, 22,
- 22, 37, 22, 23, 22, 25, 25, 22,
- 26, 22, 27, 22, 22, 22, 22, 22,
- 22, 22, 43, 22, 22, 22, 22, 22,
- 22, 33, 45, 22, 22, 37, 22, 23,
- 22, 25, 25, 22, 26, 22, 27, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 33, 45, 22,
- 22, 37, 22, 23, 22, 25, 25, 22,
- 26, 22, 27, 22, 22, 22, 22, 22,
- 22, 22, 43, 22, 22, 22, 22, 22,
- 22, 33, 45, 22, 22, 37, 22, 22,
- 22, 43, 22, 1, 1, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 1, 22, 23, 22, 25, 25,
- 22, 26, 22, 27, 22, 22, 22, 22,
- 22, 22, 22, 28, 22, 22, 29, 30,
- 31, 32, 33, 34, 35, 36, 37, 22,
- 22, 22, 39, 22, 23, 22, 25, 25,
- 22, 26, 22, 27, 22, 22, 22, 22,
- 22, 22, 22, 46, 22, 22, 22, 22,
- 22, 22, 33, 34, 35, 36, 37, 22,
- 22, 22, 39, 22, 23, 22, 25, 25,
- 22, 26, 22, 27, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 33, 34, 35, 36, 37, 22,
- 23, 22, 25, 25, 22, 26, 22, 27,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 33, 34,
- 35, 22, 37, 22, 23, 22, 25, 25,
- 22, 26, 22, 27, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 33, 22, 35, 22, 37, 22,
- 23, 22, 25, 25, 22, 26, 22, 27,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 33, 34,
- 35, 36, 37, 46, 22, 23, 22, 25,
- 25, 22, 26, 22, 27, 22, 22, 22,
- 22, 22, 22, 22, 46, 22, 22, 22,
- 22, 22, 22, 33, 34, 35, 36, 37,
- 22, 23, 22, 25, 25, 22, 26, 22,
- 27, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 29, 22, 31, 22, 33,
- 34, 35, 36, 37, 22, 22, 22, 39,
- 22, 23, 22, 25, 25, 22, 26, 22,
- 27, 22, 22, 22, 22, 22, 22, 22,
- 46, 22, 22, 29, 22, 22, 22, 33,
- 34, 35, 36, 37, 22, 22, 22, 39,
- 22, 23, 22, 25, 25, 22, 26, 22,
- 27, 22, 22, 22, 22, 22, 22, 22,
- 47, 22, 22, 29, 30, 31, 22, 33,
- 34, 35, 36, 37, 22, 22, 22, 39,
- 22, 23, 22, 25, 25, 22, 26, 22,
- 27, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 29, 30, 31, 22, 33,
- 34, 35, 36, 37, 22, 22, 22, 39,
- 22, 23, 24, 25, 25, 22, 26, 22,
- 27, 22, 22, 22, 22, 22, 22, 22,
- 28, 22, 22, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 22, 22, 22, 39,
- 22, 49, 49, 48, 5, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 50, 48,
- 48, 48, 48, 48, 48, 14, 48, 48,
- 48, 18, 48, 49, 49, 48, 5, 48,
- 49, 49, 48, 5, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 14, 48, 48, 48,
- 18, 48, 51, 48, 49, 49, 48, 5,
- 48, 14, 48, 48, 48, 48, 48, 48,
- 48, 52, 48, 48, 48, 48, 48, 48,
- 14, 48, 49, 49, 48, 5, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 52,
- 48, 48, 48, 48, 48, 48, 14, 48,
- 49, 49, 48, 5, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 14, 48, 2, 48,
- 49, 49, 48, 5, 48, 6, 48, 48,
- 48, 48, 48, 48, 48, 53, 48, 48,
- 54, 48, 48, 48, 14, 55, 48, 48,
- 18, 48, 48, 48, 53, 48, 2, 48,
- 49, 49, 48, 5, 48, 6, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 14, 48, 48, 48,
- 18, 48, 2, 48, 49, 49, 48, 5,
- 48, 6, 48, 48, 48, 48, 48, 48,
- 48, 53, 48, 48, 48, 48, 48, 48,
- 14, 55, 48, 48, 18, 48, 2, 48,
- 49, 49, 48, 5, 48, 6, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 14, 55, 48, 48,
- 18, 48, 2, 48, 49, 49, 48, 5,
- 48, 6, 48, 48, 48, 48, 48, 48,
- 48, 53, 48, 48, 48, 48, 48, 48,
- 14, 55, 48, 48, 18, 48, 48, 48,
- 53, 48, 56, 56, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 56, 48, 2, 3, 49, 49, 48,
- 5, 48, 6, 48, 48, 48, 48, 48,
- 48, 48, 8, 48, 48, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 48,
- 48, 21, 48, 2, 48, 49, 49, 48,
- 5, 48, 6, 48, 48, 48, 48, 48,
- 48, 48, 8, 48, 48, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 48, 48,
- 48, 21, 48, 2, 48, 49, 49, 48,
- 5, 48, 6, 48, 48, 48, 48, 48,
- 48, 48, 57, 48, 48, 48, 48, 48,
- 48, 14, 15, 16, 17, 18, 48, 48,
- 48, 21, 48, 2, 48, 49, 49, 48,
- 5, 48, 6, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 14, 15, 16, 17, 18, 48, 2,
- 48, 49, 49, 48, 5, 48, 6, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 14, 15, 16,
- 48, 18, 48, 2, 48, 49, 49, 48,
- 5, 48, 6, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 14, 48, 16, 48, 18, 48, 2,
- 48, 49, 49, 48, 5, 48, 6, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 14, 15, 16,
- 17, 18, 57, 48, 2, 48, 49, 49,
- 48, 5, 48, 6, 48, 48, 48, 48,
- 48, 48, 48, 57, 48, 48, 48, 48,
- 48, 48, 14, 15, 16, 17, 18, 48,
- 2, 48, 49, 49, 48, 5, 48, 6,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 10, 48, 12, 48, 14, 15,
- 16, 17, 18, 48, 48, 48, 21, 48,
- 2, 48, 49, 49, 48, 5, 48, 6,
- 48, 48, 48, 48, 48, 48, 48, 57,
- 48, 48, 10, 48, 48, 48, 14, 15,
- 16, 17, 18, 48, 48, 48, 21, 48,
- 2, 48, 49, 49, 48, 5, 48, 6,
- 48, 48, 48, 48, 48, 48, 48, 58,
- 48, 48, 10, 11, 12, 48, 14, 15,
- 16, 17, 18, 48, 48, 48, 21, 48,
- 2, 48, 49, 49, 48, 5, 48, 6,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 10, 11, 12, 48, 14, 15,
- 16, 17, 18, 48, 48, 48, 21, 48,
- 2, 3, 49, 49, 48, 5, 48, 6,
- 48, 48, 48, 48, 48, 48, 48, 8,
- 48, 48, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 48, 48, 48, 21, 48,
- 23, 24, 25, 25, 22, 26, 22, 27,
- 22, 22, 22, 22, 22, 22, 22, 59,
- 22, 22, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 22, 22, 39, 22,
- 23, 60, 25, 25, 22, 26, 22, 27,
- 22, 22, 22, 22, 22, 22, 22, 28,
- 22, 22, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 22, 22, 22, 39, 22,
- 1, 1, 2, 3, 49, 49, 48, 5,
- 48, 6, 1, 48, 48, 48, 48, 1,
- 48, 8, 48, 48, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 48, 1,
- 21, 48, 1, 1, 61, 61, 61, 61,
- 61, 61, 61, 61, 1, 61, 61, 61,
- 61, 1, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 1, 61, 62, 61, 0
-};
-
-static const char _myanmar_syllable_machine_trans_targs[] = {
- 0, 1, 26, 37, 0, 27, 33, 51,
- 39, 54, 40, 46, 47, 48, 29, 42,
- 43, 44, 32, 50, 55, 45, 0, 2,
- 13, 0, 3, 9, 14, 15, 21, 22,
- 23, 5, 17, 18, 19, 8, 25, 20,
- 4, 6, 7, 10, 12, 11, 16, 24,
- 0, 0, 28, 30, 31, 34, 36, 35,
- 38, 41, 49, 52, 53, 0, 0
-};
-
-static const char _myanmar_syllable_machine_trans_actions[] = {
- 3, 0, 0, 0, 4, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5, 0,
- 0, 6, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 7, 8, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 9, 10
-};
-
-static const char _myanmar_syllable_machine_to_state_actions[] = {
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const char _myanmar_syllable_machine_from_state_actions[] = {
- 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const short _myanmar_syllable_machine_eof_trans[] = {
- 0, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 23, 23, 49, 62, 62
-};
-
-static const int myanmar_syllable_machine_start = 0;
-static const int myanmar_syllable_machine_first_final = 0;
-static const int myanmar_syllable_machine_error = -1;
-
-static const int myanmar_syllable_machine_en_main = 0;
-
-
-#line 44 "hb-ot-shape-complex-myanmar-machine.rl"
-
-
-
-#line 102 "hb-ot-shape-complex-myanmar-machine.rl"
-
-
-#define found_syllable(syllable_type) \
- HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
- for (unsigned int i = ts; i < te; i++) \
- info[i].syllable() = (syllable_serial << 4) | syllable_type; \
- syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
- } HB_STMT_END
-
-static void
-find_syllables_myanmar (hb_buffer_t *buffer)
-{
- unsigned int p, pe, eof, ts, te, act HB_UNUSED;
- int cs;
- hb_glyph_info_t *info = buffer->info;
-
-#line 382 "hb-ot-shape-complex-myanmar-machine.hh"
- {
- cs = myanmar_syllable_machine_start;
- ts = 0;
- te = 0;
- act = 0;
- }
-
-#line 122 "hb-ot-shape-complex-myanmar-machine.rl"
-
-
- p = 0;
- pe = eof = buffer->len;
-
- unsigned int syllable_serial = 1;
-
-#line 398 "hb-ot-shape-complex-myanmar-machine.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
-_resume:
- switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
- case 2:
-#line 1 "NONE"
- {ts = p;}
- break;
-#line 412 "hb-ot-shape-complex-myanmar-machine.hh"
- }
-
- _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
- _inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
-
- _slen = _myanmar_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
- ( info[p].myanmar_category()) <= _keys[1] ?
- ( info[p].myanmar_category()) - _keys[0] : _slen ];
-
-_eof_trans:
- cs = _myanmar_syllable_machine_trans_targs[_trans];
-
- if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
- case 6:
-#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
- {te = p+1;{ found_syllable (myanmar_consonant_syllable); }}
- break;
- case 4:
-#line 95 "hb-ot-shape-complex-myanmar-machine.rl"
- {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
- break;
- case 10:
-#line 96 "hb-ot-shape-complex-myanmar-machine.rl"
- {te = p+1;{ found_syllable (myanmar_punctuation_cluster); }}
- break;
- case 8:
-#line 97 "hb-ot-shape-complex-myanmar-machine.rl"
- {te = p+1;{ found_syllable (myanmar_broken_cluster); }}
- break;
- case 3:
-#line 98 "hb-ot-shape-complex-myanmar-machine.rl"
- {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
- break;
- case 5:
-#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
- {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }}
- break;
- case 7:
-#line 97 "hb-ot-shape-complex-myanmar-machine.rl"
- {te = p;p--;{ found_syllable (myanmar_broken_cluster); }}
- break;
- case 9:
-#line 98 "hb-ot-shape-complex-myanmar-machine.rl"
- {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
- break;
-#line 462 "hb-ot-shape-complex-myanmar-machine.hh"
- }
-
-_again:
- switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
- case 1:
-#line 1 "NONE"
- {ts = 0;}
- break;
-#line 471 "hb-ot-shape-complex-myanmar-machine.hh"
- }
-
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
- _trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
- goto _eof_trans;
- }
- }
-
- }
-
-#line 130 "hb-ot-shape-complex-myanmar-machine.rl"
-
-}
-
-#undef found_syllable
-
-#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh
deleted file mode 100644
index 7fbca3878f..0000000000
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright © 2018 Google, Inc.
- *
- * 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
- */
-
-#ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_HH
-#define HB_OT_SHAPE_COMPLEX_MYANMAR_HH
-
-#include "hb.hh"
-
-#include "hb-ot-shape-complex-indic.hh"
-
-
-/* buffer var allocations */
-#define myanmar_category() indic_category() /* myanmar_category_t */
-#define myanmar_position() indic_position() /* myanmar_position_t */
-
-
-/* Note: This enum is duplicated in the -machine.rl source file.
- * Not sure how to avoid duplication. */
-enum myanmar_category_t {
- OT_As = 18, /* Asat */
- OT_D0 = 20, /* Digit zero */
- OT_DB = OT_N, /* Dot below */
- OT_GB = OT_PLACEHOLDER,
- OT_MH = 21, /* Various consonant medial types */
- OT_MR = 22, /* Various consonant medial types */
- OT_MW = 23, /* Various consonant medial types */
- OT_MY = 24, /* Various consonant medial types */
- OT_PT = 25, /* Pwo and other tones */
- //OT_VAbv = 26,
- //OT_VBlw = 27,
- //OT_VPre = 28,
- //OT_VPst = 29,
- OT_VS = 30, /* Variation selectors */
- OT_P = 31, /* Punctuation */
- OT_D = 32, /* Digits except zero */
- OT_ML = 33, /* Various consonant medial types */
-};
-
-using myanmar_position_t = indic_position_t;
-
-static inline void
-set_myanmar_properties (hb_glyph_info_t &info)
-{
- hb_codepoint_t u = info.codepoint;
- unsigned int type = hb_indic_get_categories (u);
- unsigned int cat = type & 0xFFu;
- myanmar_position_t pos = (myanmar_position_t) (type >> 8);
-
- /* Myanmar
- * https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze
- */
- if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)))
- cat = OT_VS;
-
- switch (u)
- {
- case 0x104Eu:
- cat = OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
- break;
-
- case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u:
- case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u:
- case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu:
- case 0x25FEu:
- cat = OT_GB;
- break;
-
- case 0x1004u: case 0x101Bu: case 0x105Au:
- cat = OT_Ra;
- break;
-
- case 0x1032u: case 0x1036u:
- cat = OT_A;
- break;
-
- case 0x1039u:
- cat = OT_H;
- break;
-
- case 0x103Au:
- cat = OT_As;
- break;
-
- case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u:
- case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u:
- case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u:
- case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u:
- case 0x1097u: case 0x1098u: case 0x1099u:
- cat = OT_D;
- break;
-
- case 0x1040u:
- cat = OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
- break;
-
- case 0x103Eu:
- cat = OT_MH;
- break;
-
- case 0x1060u:
- cat = OT_ML;
- break;
-
- case 0x103Cu:
- cat = OT_MR;
- break;
-
- case 0x103Du: case 0x1082u:
- cat = OT_MW;
- break;
-
- case 0x103Bu: case 0x105Eu: case 0x105Fu:
- cat = OT_MY;
- break;
-
- case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au:
- case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu:
- cat = OT_PT;
- break;
-
- case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u:
- case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du:
- case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu:
- cat = OT_SM;
- break;
-
- case 0x104Au: case 0x104Bu:
- cat = OT_P;
- break;
-
- case 0xAA74u: case 0xAA75u: case 0xAA76u:
- /* https://github.com/harfbuzz/harfbuzz/issues/218 */
- cat = OT_C;
- break;
- }
-
- if (cat == OT_M)
- {
- switch ((int) pos)
- {
- case POS_PRE_C: cat = (myanmar_category_t) OT_VPre;
- pos = POS_PRE_M; break;
- case POS_ABOVE_C: cat = (myanmar_category_t) OT_VAbv; break;
- case POS_BELOW_C: cat = (myanmar_category_t) OT_VBlw; break;
- case POS_POST_C: cat = (myanmar_category_t) OT_VPst; break;
- }
- }
-
- info.myanmar_category() = cat;
- info.myanmar_position() = pos;
-}
-
-
-#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh
deleted file mode 100644
index 468bd95c3f..0000000000
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh
+++ /dev/null
@@ -1,849 +0,0 @@
-
-#line 1 "hb-ot-shape-complex-use-machine.rl"
-/*
- * Copyright © 2015 Mozilla Foundation.
- * Copyright © 2015 Google, Inc.
- *
- * 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.
- *
- * Mozilla Author(s): Jonathan Kew
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH
-#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH
-
-#include "hb.hh"
-
-#include "hb-ot-shape-complex-syllabic.hh"
-
-/* buffer var allocations */
-#define use_category() complex_var_u8_category()
-
-#define USE(Cat) use_syllable_machine_ex_##Cat
-
-enum use_syllable_type_t {
- use_virama_terminated_cluster,
- use_sakot_terminated_cluster,
- use_standard_cluster,
- use_number_joiner_terminated_cluster,
- use_numeral_cluster,
- use_symbol_cluster,
- use_hieroglyph_cluster,
- use_broken_cluster,
- use_non_cluster,
-};
-
-
-#line 57 "hb-ot-shape-complex-use-machine.hh"
-#define use_syllable_machine_ex_B 1u
-#define use_syllable_machine_ex_CGJ 6u
-#define use_syllable_machine_ex_CMAbv 31u
-#define use_syllable_machine_ex_CMBlw 32u
-#define use_syllable_machine_ex_CS 43u
-#define use_syllable_machine_ex_FAbv 24u
-#define use_syllable_machine_ex_FBlw 25u
-#define use_syllable_machine_ex_FMAbv 45u
-#define use_syllable_machine_ex_FMBlw 46u
-#define use_syllable_machine_ex_FMPst 47u
-#define use_syllable_machine_ex_FPst 26u
-#define use_syllable_machine_ex_G 49u
-#define use_syllable_machine_ex_GB 5u
-#define use_syllable_machine_ex_H 12u
-#define use_syllable_machine_ex_HN 13u
-#define use_syllable_machine_ex_IS 44u
-#define use_syllable_machine_ex_J 50u
-#define use_syllable_machine_ex_MAbv 27u
-#define use_syllable_machine_ex_MBlw 28u
-#define use_syllable_machine_ex_MPre 30u
-#define use_syllable_machine_ex_MPst 29u
-#define use_syllable_machine_ex_N 4u
-#define use_syllable_machine_ex_O 0u
-#define use_syllable_machine_ex_R 18u
-#define use_syllable_machine_ex_SB 51u
-#define use_syllable_machine_ex_SE 52u
-#define use_syllable_machine_ex_SMAbv 41u
-#define use_syllable_machine_ex_SMBlw 42u
-#define use_syllable_machine_ex_SUB 11u
-#define use_syllable_machine_ex_Sk 48u
-#define use_syllable_machine_ex_VAbv 33u
-#define use_syllable_machine_ex_VBlw 34u
-#define use_syllable_machine_ex_VMAbv 37u
-#define use_syllable_machine_ex_VMBlw 38u
-#define use_syllable_machine_ex_VMPre 23u
-#define use_syllable_machine_ex_VMPst 39u
-#define use_syllable_machine_ex_VPre 22u
-#define use_syllable_machine_ex_VPst 35u
-#define use_syllable_machine_ex_WJ 16u
-#define use_syllable_machine_ex_ZWNJ 14u
-
-
-#line 100 "hb-ot-shape-complex-use-machine.hh"
-static const unsigned char _use_syllable_machine_trans_keys[] = {
- 0u, 51u, 11u, 48u, 11u, 48u, 1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u,
- 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u,
- 23u, 48u, 23u, 48u, 23u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u,
- 1u, 1u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 48u, 23u, 48u,
- 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u,
- 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 12u, 48u, 12u, 48u,
- 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 13u, 13u, 4u, 4u, 11u, 48u, 11u, 48u,
- 1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u,
- 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u,
- 12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 11u, 48u, 11u, 48u,
- 1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u,
- 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u,
- 12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 4u, 4u, 13u, 13u,
- 1u, 48u, 11u, 48u, 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u,
- 0
-};
-
-static const char _use_syllable_machine_key_spans[] = {
- 52, 38, 38, 48, 26, 24, 23, 22,
- 2, 1, 25, 25, 25, 1, 25, 27,
- 26, 26, 26, 37, 37, 37, 37, 38,
- 1, 38, 2, 1, 38, 38, 48, 26,
- 24, 23, 22, 2, 1, 25, 25, 25,
- 1, 25, 27, 26, 26, 26, 37, 37,
- 37, 37, 38, 1, 1, 1, 38, 38,
- 48, 26, 24, 23, 22, 2, 1, 25,
- 25, 25, 1, 25, 27, 26, 26, 26,
- 37, 37, 37, 37, 38, 1, 38, 38,
- 48, 26, 24, 23, 22, 2, 1, 25,
- 25, 25, 1, 25, 27, 26, 26, 26,
- 37, 37, 37, 37, 38, 1, 1, 1,
- 48, 38, 2, 1, 5, 3, 4, 3
-};
-
-static const short _use_syllable_machine_index_offsets[] = {
- 0, 53, 92, 131, 180, 207, 232, 256,
- 279, 282, 284, 310, 336, 362, 364, 390,
- 418, 445, 472, 499, 537, 575, 613, 651,
- 690, 692, 731, 734, 736, 775, 814, 863,
- 890, 915, 939, 962, 965, 967, 993, 1019,
- 1045, 1047, 1073, 1101, 1128, 1155, 1182, 1220,
- 1258, 1296, 1334, 1373, 1375, 1377, 1379, 1418,
- 1457, 1506, 1533, 1558, 1582, 1605, 1608, 1610,
- 1636, 1662, 1688, 1690, 1716, 1744, 1771, 1798,
- 1825, 1863, 1901, 1939, 1977, 2016, 2018, 2057,
- 2096, 2145, 2172, 2197, 2221, 2244, 2247, 2249,
- 2275, 2301, 2327, 2329, 2355, 2383, 2410, 2437,
- 2464, 2502, 2540, 2578, 2616, 2655, 2657, 2659,
- 2661, 2710, 2749, 2752, 2754, 2760, 2764, 2769
-};
-
-static const char _use_syllable_machine_indicies[] = {
- 0, 1, 2, 2, 3, 4, 2, 2,
- 2, 2, 2, 5, 6, 7, 2, 2,
- 2, 2, 8, 2, 2, 2, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 2, 23, 24, 25,
- 2, 26, 27, 28, 29, 30, 31, 32,
- 29, 33, 2, 34, 2, 36, 37, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 35, 52,
- 53, 54, 35, 55, 56, 35, 57, 58,
- 59, 60, 57, 35, 36, 37, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 38,
- 39, 40, 41, 42, 43, 44, 45, 46,
- 48, 48, 49, 50, 51, 35, 52, 53,
- 54, 35, 35, 35, 35, 57, 58, 59,
- 60, 57, 35, 36, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 39, 40, 41, 42, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 52,
- 53, 54, 35, 35, 35, 35, 35, 58,
- 59, 60, 61, 35, 39, 40, 41, 42,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 52, 53, 54, 35, 35, 35,
- 35, 35, 58, 59, 60, 61, 35, 40,
- 41, 42, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 58, 59, 60, 35,
- 41, 42, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 58, 59, 60, 35,
- 42, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 58, 59, 60, 35, 58,
- 59, 35, 59, 35, 40, 41, 42, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 52, 53, 54, 35, 35, 35, 35,
- 35, 58, 59, 60, 61, 35, 40, 41,
- 42, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 53, 54, 35, 35,
- 35, 35, 35, 58, 59, 60, 61, 35,
- 40, 41, 42, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 54,
- 35, 35, 35, 35, 35, 58, 59, 60,
- 61, 35, 62, 35, 40, 41, 42, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 58, 59, 60, 61, 35, 38, 39,
- 40, 41, 42, 35, 35, 35, 35, 35,
- 35, 49, 50, 51, 35, 52, 53, 54,
- 35, 35, 35, 35, 35, 58, 59, 60,
- 61, 35, 39, 40, 41, 42, 35, 35,
- 35, 35, 35, 35, 49, 50, 51, 35,
- 52, 53, 54, 35, 35, 35, 35, 35,
- 58, 59, 60, 61, 35, 39, 40, 41,
- 42, 35, 35, 35, 35, 35, 35, 35,
- 50, 51, 35, 52, 53, 54, 35, 35,
- 35, 35, 35, 58, 59, 60, 61, 35,
- 39, 40, 41, 42, 35, 35, 35, 35,
- 35, 35, 35, 35, 51, 35, 52, 53,
- 54, 35, 35, 35, 35, 35, 58, 59,
- 60, 61, 35, 39, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 38, 39, 40,
- 41, 42, 35, 44, 45, 35, 35, 35,
- 49, 50, 51, 35, 52, 53, 54, 35,
- 35, 35, 35, 35, 58, 59, 60, 61,
- 35, 39, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 38, 39, 40, 41, 42,
- 35, 35, 45, 35, 35, 35, 49, 50,
- 51, 35, 52, 53, 54, 35, 35, 35,
- 35, 35, 58, 59, 60, 61, 35, 39,
- 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 38, 39, 40, 41, 42, 35, 35,
- 35, 35, 35, 35, 49, 50, 51, 35,
- 52, 53, 54, 35, 35, 35, 35, 35,
- 58, 59, 60, 61, 35, 39, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 38,
- 39, 40, 41, 42, 43, 44, 45, 35,
- 35, 35, 49, 50, 51, 35, 52, 53,
- 54, 35, 35, 35, 35, 35, 58, 59,
- 60, 61, 35, 36, 37, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 35,
- 48, 49, 50, 51, 35, 52, 53, 54,
- 35, 35, 35, 35, 57, 58, 59, 60,
- 57, 35, 36, 35, 36, 37, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 38,
- 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 35, 52, 53,
- 54, 35, 35, 35, 35, 57, 58, 59,
- 60, 57, 35, 55, 56, 35, 56, 35,
- 64, 65, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 1, 75, 76, 77,
- 78, 63, 79, 80, 81, 63, 63, 63,
- 63, 82, 83, 84, 85, 86, 63, 64,
- 65, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 75, 76, 77, 78,
- 63, 79, 80, 81, 63, 63, 63, 63,
- 82, 83, 84, 85, 86, 63, 64, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 67, 68, 69, 70,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 79, 80, 81, 63, 63, 63,
- 63, 63, 83, 84, 85, 87, 63, 67,
- 68, 69, 70, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 79, 80, 81,
- 63, 63, 63, 63, 63, 83, 84, 85,
- 87, 63, 68, 69, 70, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 83,
- 84, 85, 63, 69, 70, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 83,
- 84, 85, 63, 70, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 83, 84,
- 85, 63, 83, 84, 63, 84, 63, 68,
- 69, 70, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 79, 80, 81, 63,
- 63, 63, 63, 63, 83, 84, 85, 87,
- 63, 68, 69, 70, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 80,
- 81, 63, 63, 63, 63, 63, 83, 84,
- 85, 87, 63, 68, 69, 70, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 81, 63, 63, 63, 63, 63,
- 83, 84, 85, 87, 63, 89, 88, 68,
- 69, 70, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 83, 84, 85, 87,
- 63, 66, 67, 68, 69, 70, 63, 63,
- 63, 63, 63, 63, 76, 77, 78, 63,
- 79, 80, 81, 63, 63, 63, 63, 63,
- 83, 84, 85, 87, 63, 67, 68, 69,
- 70, 63, 63, 63, 63, 63, 63, 76,
- 77, 78, 63, 79, 80, 81, 63, 63,
- 63, 63, 63, 83, 84, 85, 87, 63,
- 67, 68, 69, 70, 63, 63, 63, 63,
- 63, 63, 63, 77, 78, 63, 79, 80,
- 81, 63, 63, 63, 63, 63, 83, 84,
- 85, 87, 63, 67, 68, 69, 70, 63,
- 63, 63, 63, 63, 63, 63, 63, 78,
- 63, 79, 80, 81, 63, 63, 63, 63,
- 63, 83, 84, 85, 87, 63, 67, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 66, 67, 68, 69, 70, 63, 72, 73,
- 63, 63, 63, 76, 77, 78, 63, 79,
- 80, 81, 63, 63, 63, 63, 63, 83,
- 84, 85, 87, 63, 67, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 66, 67,
- 68, 69, 70, 63, 63, 73, 63, 63,
- 63, 76, 77, 78, 63, 79, 80, 81,
- 63, 63, 63, 63, 63, 83, 84, 85,
- 87, 63, 67, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 66, 67, 68, 69,
- 70, 63, 63, 63, 63, 63, 63, 76,
- 77, 78, 63, 79, 80, 81, 63, 63,
- 63, 63, 63, 83, 84, 85, 87, 63,
- 67, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 66, 67, 68, 69, 70, 71,
- 72, 73, 63, 63, 63, 76, 77, 78,
- 63, 79, 80, 81, 63, 63, 63, 63,
- 63, 83, 84, 85, 87, 63, 64, 65,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 63, 75, 76, 77, 78, 63,
- 79, 80, 81, 63, 63, 63, 63, 82,
- 83, 84, 85, 86, 63, 64, 90, 92,
- 91, 3, 93, 94, 95, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 96, 97,
- 98, 99, 100, 101, 102, 103, 104, 105,
- 106, 107, 108, 109, 63, 110, 111, 112,
- 63, 55, 56, 63, 113, 114, 115, 85,
- 116, 63, 94, 95, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 96, 97, 98,
- 99, 100, 101, 102, 103, 104, 106, 106,
- 107, 108, 109, 63, 110, 111, 112, 63,
- 63, 63, 63, 113, 114, 115, 85, 116,
- 63, 94, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 97,
- 98, 99, 100, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 110, 111, 112,
- 63, 63, 63, 63, 63, 114, 115, 85,
- 117, 63, 97, 98, 99, 100, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 110, 111, 112, 63, 63, 63, 63, 63,
- 114, 115, 85, 117, 63, 98, 99, 100,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 114, 115, 85, 63, 99, 100,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 114, 115, 85, 63, 100, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 114, 115, 85, 63, 114, 115, 63,
- 115, 63, 98, 99, 100, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 110,
- 111, 112, 63, 63, 63, 63, 63, 114,
- 115, 85, 117, 63, 98, 99, 100, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 111, 112, 63, 63, 63, 63,
- 63, 114, 115, 85, 117, 63, 98, 99,
- 100, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 112, 63, 63,
- 63, 63, 63, 114, 115, 85, 117, 63,
- 118, 88, 98, 99, 100, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 114,
- 115, 85, 117, 63, 96, 97, 98, 99,
- 100, 63, 63, 63, 63, 63, 63, 107,
- 108, 109, 63, 110, 111, 112, 63, 63,
- 63, 63, 63, 114, 115, 85, 117, 63,
- 97, 98, 99, 100, 63, 63, 63, 63,
- 63, 63, 107, 108, 109, 63, 110, 111,
- 112, 63, 63, 63, 63, 63, 114, 115,
- 85, 117, 63, 97, 98, 99, 100, 63,
- 63, 63, 63, 63, 63, 63, 108, 109,
- 63, 110, 111, 112, 63, 63, 63, 63,
- 63, 114, 115, 85, 117, 63, 97, 98,
- 99, 100, 63, 63, 63, 63, 63, 63,
- 63, 63, 109, 63, 110, 111, 112, 63,
- 63, 63, 63, 63, 114, 115, 85, 117,
- 63, 97, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 96, 97, 98, 99, 100,
- 63, 102, 103, 63, 63, 63, 107, 108,
- 109, 63, 110, 111, 112, 63, 63, 63,
- 63, 63, 114, 115, 85, 117, 63, 97,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 96, 97, 98, 99, 100, 63, 63,
- 103, 63, 63, 63, 107, 108, 109, 63,
- 110, 111, 112, 63, 63, 63, 63, 63,
- 114, 115, 85, 117, 63, 97, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 96,
- 97, 98, 99, 100, 63, 63, 63, 63,
- 63, 63, 107, 108, 109, 63, 110, 111,
- 112, 63, 63, 63, 63, 63, 114, 115,
- 85, 117, 63, 97, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 96, 97, 98,
- 99, 100, 101, 102, 103, 63, 63, 63,
- 107, 108, 109, 63, 110, 111, 112, 63,
- 63, 63, 63, 63, 114, 115, 85, 117,
- 63, 94, 95, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 96, 97, 98, 99,
- 100, 101, 102, 103, 104, 63, 106, 107,
- 108, 109, 63, 110, 111, 112, 63, 63,
- 63, 63, 113, 114, 115, 85, 116, 63,
- 94, 90, 94, 95, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 96, 97, 98,
- 99, 100, 101, 102, 103, 104, 105, 106,
- 107, 108, 109, 63, 110, 111, 112, 63,
- 63, 63, 63, 113, 114, 115, 85, 116,
- 63, 5, 6, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 19, 19, 20,
- 21, 22, 119, 23, 24, 25, 119, 119,
- 119, 119, 29, 30, 31, 32, 29, 119,
- 5, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 10, 11,
- 12, 13, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 23, 24, 25, 119,
- 119, 119, 119, 119, 30, 31, 32, 120,
- 119, 10, 11, 12, 13, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 23,
- 24, 25, 119, 119, 119, 119, 119, 30,
- 31, 32, 120, 119, 11, 12, 13, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 30, 31, 32, 119, 12, 13, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 30, 31, 32, 119, 13, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 30, 31, 32, 119, 30, 31, 119, 31,
- 119, 11, 12, 13, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 23, 24,
- 25, 119, 119, 119, 119, 119, 30, 31,
- 32, 120, 119, 11, 12, 13, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 24, 25, 119, 119, 119, 119, 119,
- 30, 31, 32, 120, 119, 11, 12, 13,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 25, 119, 119, 119,
- 119, 119, 30, 31, 32, 120, 119, 121,
- 119, 11, 12, 13, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 30, 31,
- 32, 120, 119, 9, 10, 11, 12, 13,
- 119, 119, 119, 119, 119, 119, 20, 21,
- 22, 119, 23, 24, 25, 119, 119, 119,
- 119, 119, 30, 31, 32, 120, 119, 10,
- 11, 12, 13, 119, 119, 119, 119, 119,
- 119, 20, 21, 22, 119, 23, 24, 25,
- 119, 119, 119, 119, 119, 30, 31, 32,
- 120, 119, 10, 11, 12, 13, 119, 119,
- 119, 119, 119, 119, 119, 21, 22, 119,
- 23, 24, 25, 119, 119, 119, 119, 119,
- 30, 31, 32, 120, 119, 10, 11, 12,
- 13, 119, 119, 119, 119, 119, 119, 119,
- 119, 22, 119, 23, 24, 25, 119, 119,
- 119, 119, 119, 30, 31, 32, 120, 119,
- 10, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 9, 10, 11, 12, 13, 119,
- 15, 16, 119, 119, 119, 20, 21, 22,
- 119, 23, 24, 25, 119, 119, 119, 119,
- 119, 30, 31, 32, 120, 119, 10, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 9, 10, 11, 12, 13, 119, 119, 16,
- 119, 119, 119, 20, 21, 22, 119, 23,
- 24, 25, 119, 119, 119, 119, 119, 30,
- 31, 32, 120, 119, 10, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 9, 10,
- 11, 12, 13, 119, 119, 119, 119, 119,
- 119, 20, 21, 22, 119, 23, 24, 25,
- 119, 119, 119, 119, 119, 30, 31, 32,
- 120, 119, 10, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 9, 10, 11, 12,
- 13, 14, 15, 16, 119, 119, 119, 20,
- 21, 22, 119, 23, 24, 25, 119, 119,
- 119, 119, 119, 30, 31, 32, 120, 119,
- 5, 6, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 119, 19, 20, 21,
- 22, 119, 23, 24, 25, 119, 119, 119,
- 119, 29, 30, 31, 32, 29, 119, 5,
- 119, 122, 119, 7, 119, 1, 119, 119,
- 119, 1, 119, 119, 119, 119, 119, 5,
- 6, 7, 119, 119, 119, 119, 119, 119,
- 119, 119, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22,
- 119, 23, 24, 25, 119, 26, 27, 119,
- 29, 30, 31, 32, 29, 119, 5, 6,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 119,
- 23, 24, 25, 119, 119, 119, 119, 29,
- 30, 31, 32, 29, 119, 26, 27, 119,
- 27, 119, 1, 123, 123, 123, 1, 123,
- 125, 124, 33, 124, 33, 125, 124, 125,
- 124, 33, 124, 34, 124, 0
-};
-
-static const char _use_syllable_machine_trans_targs[] = {
- 1, 28, 0, 52, 54, 79, 80, 102,
- 104, 92, 81, 82, 83, 84, 96, 97,
- 98, 99, 105, 100, 93, 94, 95, 87,
- 88, 89, 106, 107, 108, 101, 85, 86,
- 0, 109, 111, 0, 2, 3, 15, 4,
- 5, 6, 7, 19, 20, 21, 22, 25,
- 23, 16, 17, 18, 10, 11, 12, 26,
- 27, 24, 8, 9, 0, 13, 14, 0,
- 29, 30, 42, 31, 32, 33, 34, 46,
- 47, 48, 49, 50, 43, 44, 45, 37,
- 38, 39, 51, 35, 36, 0, 51, 40,
- 0, 41, 0, 0, 53, 0, 55, 56,
- 68, 57, 58, 59, 60, 72, 73, 74,
- 75, 78, 76, 69, 70, 71, 63, 64,
- 65, 77, 61, 62, 77, 66, 67, 0,
- 90, 91, 103, 0, 0, 110
-};
-
-static const char _use_syllable_machine_trans_actions[] = {
- 0, 0, 3, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 0, 0, 5, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 0, 0, 7,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 8, 0, 0, 9, 10, 0,
- 11, 0, 12, 13, 0, 14, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8, 0, 0, 10, 0, 0, 15,
- 0, 0, 0, 16, 17, 0
-};
-
-static const char _use_syllable_machine_to_state_actions[] = {
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const char _use_syllable_machine_from_state_actions[] = {
- 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const short _use_syllable_machine_eof_trans[] = {
- 0, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 89, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 91, 92, 94, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 89, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 91, 64, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 124, 125, 125, 125
-};
-
-static const int use_syllable_machine_start = 0;
-static const int use_syllable_machine_first_final = 0;
-static const int use_syllable_machine_error = -1;
-
-static const int use_syllable_machine_en_main = 0;
-
-
-#line 58 "hb-ot-shape-complex-use-machine.rl"
-
-
-
-#line 181 "hb-ot-shape-complex-use-machine.rl"
-
-
-#define found_syllable(syllable_type) \
- HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
- for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
- info[i].syllable() = (syllable_serial << 4) | syllable_type; \
- syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
- } HB_STMT_END
-
-
-template <typename Iter>
-struct machine_index_t :
- hb_iter_with_fallback_t<machine_index_t<Iter>,
- typename Iter::item_t>
-{
- machine_index_t (const Iter& it) : it (it) {}
- machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>,
- typename Iter::item_t> (),
- it (o.it), is_null (o.is_null) {}
-
- static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
- static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
-
- typename Iter::item_t __item__ () const { return *it; }
- typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; }
- unsigned __len__ () const { return it.len (); }
- void __next__ () { ++it; }
- void __forward__ (unsigned n) { it += n; }
- void __prev__ () { --it; }
- void __rewind__ (unsigned n) { it -= n; }
-
- void operator = (unsigned n)
- {
- assert (n == 0);
- is_null = true;
- }
- explicit operator bool () { return !is_null; }
-
- void operator = (const machine_index_t& o)
- {
- is_null = o.is_null;
- unsigned index = (*it).first;
- unsigned n = (*o.it).first;
- if (index < n) it += n - index; else if (index > n) it -= index - n;
- }
- bool operator == (const machine_index_t& o) const
- { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; }
- bool operator != (const machine_index_t& o) const { return !(*this == o); }
-
- private:
- Iter it;
- bool is_null = false;
-};
-struct
-{
- template <typename Iter,
- hb_requires (hb_is_iterable (Iter))>
- machine_index_t<hb_iter_type<Iter>>
- operator () (Iter&& it) const
- { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); }
-}
-HB_FUNCOBJ (machine_index);
-
-
-
-static bool
-not_ccs_default_ignorable (const hb_glyph_info_t &i)
-{ return i.use_category() != USE(CGJ); }
-
-static inline void
-find_syllables_use (hb_buffer_t *buffer)
-{
- hb_glyph_info_t *info = buffer->info;
- auto p =
- + hb_iter (info, buffer->len)
- | hb_enumerate
- | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); },
- hb_second)
- | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
- {
- if (p.second.use_category() == USE(ZWNJ))
- for (unsigned i = p.first + 1; i < buffer->len; ++i)
- if (not_ccs_default_ignorable (info[i]))
- return !_hb_glyph_info_is_unicode_mark (&info[i]);
- return true;
- })
- | hb_enumerate
- | machine_index
- ;
- auto pe = p + p.len ();
- auto eof = +pe;
- auto ts = +p;
- auto te = +p;
- unsigned int act HB_UNUSED;
- int cs;
-
-#line 702 "hb-ot-shape-complex-use-machine.hh"
- {
- cs = use_syllable_machine_start;
- ts = 0;
- te = 0;
- act = 0;
- }
-
-#line 281 "hb-ot-shape-complex-use-machine.rl"
-
-
- unsigned int syllable_serial = 1;
-
-#line 715 "hb-ot-shape-complex-use-machine.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
-_resume:
- switch ( _use_syllable_machine_from_state_actions[cs] ) {
- case 2:
-#line 1 "NONE"
- {ts = p;}
- break;
-#line 729 "hb-ot-shape-complex-use-machine.hh"
- }
-
- _keys = _use_syllable_machine_trans_keys + (cs<<1);
- _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs];
-
- _slen = _use_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( (*p).second.second.use_category()) &&
- ( (*p).second.second.use_category()) <= _keys[1] ?
- ( (*p).second.second.use_category()) - _keys[0] : _slen ];
-
-_eof_trans:
- cs = _use_syllable_machine_trans_targs[_trans];
-
- if ( _use_syllable_machine_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _use_syllable_machine_trans_actions[_trans] ) {
- case 9:
-#line 171 "hb-ot-shape-complex-use-machine.rl"
- {te = p+1;{ found_syllable (use_standard_cluster); }}
- break;
- case 6:
-#line 174 "hb-ot-shape-complex-use-machine.rl"
- {te = p+1;{ found_syllable (use_symbol_cluster); }}
- break;
- case 4:
-#line 176 "hb-ot-shape-complex-use-machine.rl"
- {te = p+1;{ found_syllable (use_broken_cluster); }}
- break;
- case 3:
-#line 177 "hb-ot-shape-complex-use-machine.rl"
- {te = p+1;{ found_syllable (use_non_cluster); }}
- break;
- case 11:
-#line 170 "hb-ot-shape-complex-use-machine.rl"
- {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
- break;
- case 7:
-#line 171 "hb-ot-shape-complex-use-machine.rl"
- {te = p;p--;{ found_syllable (use_standard_cluster); }}
- break;
- case 14:
-#line 172 "hb-ot-shape-complex-use-machine.rl"
- {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
- break;
- case 13:
-#line 173 "hb-ot-shape-complex-use-machine.rl"
- {te = p;p--;{ found_syllable (use_numeral_cluster); }}
- break;
- case 5:
-#line 174 "hb-ot-shape-complex-use-machine.rl"
- {te = p;p--;{ found_syllable (use_symbol_cluster); }}
- break;
- case 17:
-#line 175 "hb-ot-shape-complex-use-machine.rl"
- {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
- break;
- case 15:
-#line 176 "hb-ot-shape-complex-use-machine.rl"
- {te = p;p--;{ found_syllable (use_broken_cluster); }}
- break;
- case 16:
-#line 177 "hb-ot-shape-complex-use-machine.rl"
- {te = p;p--;{ found_syllable (use_non_cluster); }}
- break;
- case 12:
-#line 1 "NONE"
- { switch( act ) {
- case 1:
- {{p = ((te))-1;} found_syllable (use_virama_terminated_cluster); }
- break;
- case 2:
- {{p = ((te))-1;} found_syllable (use_sakot_terminated_cluster); }
- break;
- }
- }
- break;
- case 8:
-#line 1 "NONE"
- {te = p+1;}
-#line 169 "hb-ot-shape-complex-use-machine.rl"
- {act = 1;}
- break;
- case 10:
-#line 1 "NONE"
- {te = p+1;}
-#line 170 "hb-ot-shape-complex-use-machine.rl"
- {act = 2;}
- break;
-#line 819 "hb-ot-shape-complex-use-machine.hh"
- }
-
-_again:
- switch ( _use_syllable_machine_to_state_actions[cs] ) {
- case 1:
-#line 1 "NONE"
- {ts = 0;}
- break;
-#line 828 "hb-ot-shape-complex-use-machine.hh"
- }
-
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- if ( _use_syllable_machine_eof_trans[cs] > 0 ) {
- _trans = _use_syllable_machine_eof_trans[cs] - 1;
- goto _eof_trans;
- }
- }
-
- }
-
-#line 286 "hb-ot-shape-complex-use-machine.rl"
-
-}
-
-#undef found_syllable
-
-#endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
index aa5a8eeaa3..7db0b25b73 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
@@ -29,7 +29,7 @@
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-normalize.hh"
-#include "hb-ot-shape-complex.hh"
+#include "hb-ot-shaper.hh"
#include "hb-ot-shape.hh"
@@ -69,7 +69,7 @@
* - When a font does not support a character but supports its canonical
* decomposition, well, use the decomposition.
*
- * - The complex shapers can customize the compose and decompose functions to
+ * - The shapers can customize the compose and decompose functions to
* offload some of their requirements to the normalizer. For example, the
* Indic shaper may want to disallow recomposing of two matras.
*/
@@ -143,8 +143,7 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint
return 1;
}
- unsigned int ret;
- if ((ret = decompose (c, shortest, a))) {
+ if (unsigned ret = decompose (c, shortest, a)) {
if (b) {
output_char (buffer, b, b_glyph);
return ret + 1;
@@ -223,7 +222,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c,
unsigned int end,
bool short_circuit HB_UNUSED)
{
- /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
+ /* Currently if there's a variation-selector we give-up on normalization, it's just too hard. */
hb_buffer_t * const buffer = c->buffer;
hb_font_t * const font = c->font;
for (; buffer->idx < end - 1 && buffer->successful;) {
@@ -395,7 +394,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
break;
/* We are going to do a O(n^2). Only do this if the sequence is short. */
- if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
+ if (end - i > HB_OT_SHAPE_MAX_COMBINING_MARKS) {
i = end;
continue;
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc
index 99aadab3f0..0806abb7dd 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc
@@ -37,7 +37,7 @@
#include "hb-shaper-impl.hh"
#include "hb-ot-shape.hh"
-#include "hb-ot-shape-complex.hh"
+#include "hb-ot-shaper.hh"
#include "hb-ot-shape-fallback.hh"
#include "hb-ot-shape-normalize.hh"
@@ -86,14 +86,14 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac
, apply_morx (_hb_apply_morx (face, props))
#endif
{
- shaper = hb_ot_shape_complex_categorize (this);
+ shaper = hb_ot_shaper_categorize (this);
script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE;
script_fallback_mark_positioning = shaper->fallback_position;
/* https://github.com/harfbuzz/harfbuzz/issues/1528 */
- if (apply_morx && shaper != &_hb_ot_complex_shaper_default)
- shaper = &_hb_ot_complex_shaper_dumber;
+ if (apply_morx && shaper != &_hb_ot_shaper_default)
+ shaper = &_hb_ot_shaper_dumber;
}
void
@@ -927,7 +927,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c)
}
static inline void
-hb_ot_substitute_complex (const hb_ot_shape_context_t *c)
+hb_ot_substitute_plan (const hb_ot_shape_context_t *c)
{
hb_buffer_t *buffer = c->buffer;
@@ -946,7 +946,7 @@ hb_ot_substitute_pre (const hb_ot_shape_context_t *c)
_hb_buffer_allocate_gsubgpos_vars (c->buffer);
- hb_ot_substitute_complex (c);
+ hb_ot_substitute_plan (c);
#ifndef HB_NO_AAT_SHAPE
if (c->plan->apply_morx && c->plan->apply_gpos)
@@ -1039,7 +1039,7 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
}
static inline void
-hb_ot_position_complex (const hb_ot_shape_context_t *c)
+hb_ot_position_plan (const hb_ot_shape_context_t *c)
{
unsigned int count = c->buffer->len;
hb_glyph_info_t *info = c->buffer->info;
@@ -1124,7 +1124,7 @@ hb_ot_position (const hb_ot_shape_context_t *c)
hb_ot_position_default (c);
- hb_ot_position_complex (c);
+ hb_ot_position_plan (c);
if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
hb_buffer_reverse (c->buffer);
@@ -1159,8 +1159,6 @@ hb_propagate_flags (hb_buffer_t *buffer)
static void
hb_ot_shape_internal (hb_ot_shape_context_t *c)
{
- c->buffer->enter ();
-
/* Save the original direction, we use it later. */
c->target_direction = c->buffer->props.direction;
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.hh b/thirdparty/harfbuzz/src/hb-ot-shape.hh
index e8c81015c7..17fa58b337 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shape.hh
@@ -61,7 +61,7 @@ struct hb_shape_plan_key_t;
struct hb_ot_shape_plan_t
{
hb_segment_properties_t props;
- const struct hb_ot_complex_shaper_t *shaper;
+ const struct hb_ot_shaper_t *shaper;
hb_ot_map_t map;
hb_aat_map_t aat_map;
const void *data;
@@ -158,7 +158,7 @@ struct hb_ot_shape_planner_t
#endif
bool script_zero_marks : 1;
bool script_fallback_mark_positioning : 1;
- const struct hb_ot_complex_shaper_t *shaper;
+ const struct hb_ot_shaper_t *shaper;
HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face,
const hb_segment_properties_t *props);
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-fallback.hh
index 78f46c1cac..b9f92f72d6 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-fallback.hh
@@ -24,8 +24,8 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
-#define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
+#ifndef HB_OT_SHAPER_ARABIC_FALLBACK_HH
+#define HB_OT_SHAPER_ARABIC_FALLBACK_HH
#include "hb.hh"
@@ -34,7 +34,11 @@
/* Features ordered the same as the entries in shaping_table rows,
- * followed by rlig. Don't change. */
+ * followed by rlig. Don't change.
+ *
+ * We currently support one subtable per lookup, and one lookup
+ * per feature. But we allow duplicate features, so we use that!
+ */
static const hb_tag_t arabic_fallback_features[] =
{
HB_TAG('i','n','i','t'),
@@ -42,6 +46,8 @@ static const hb_tag_t arabic_fallback_features[] =
HB_TAG('f','i','n','a'),
HB_TAG('i','s','o','l'),
HB_TAG('r','l','i','g'),
+ HB_TAG('r','l','i','g'),
+ HB_TAG('r','l','i','g'),
};
static OT::SubstLookup *
@@ -95,20 +101,25 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
return ret && !c.in_error () ? c.copy<OT::SubstLookup> () : nullptr;
}
+template <typename T>
static OT::SubstLookup *
arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font)
+ hb_font_t *font,
+ const T &ligature_table,
+ unsigned lookup_flags)
{
OT::HBGlyphID16 first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
unsigned int num_first_glyphs = 0;
- /* We know that all our ligatures are 2-component */
+ /* We know that all our ligatures have the same number of components. */
OT::HBGlyphID16 ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
- OT::HBGlyphID16 component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
+ OT::HBGlyphID16 component_list[ARRAY_LENGTH_CONST (ligature_list) *
+ ARRAY_LENGTH_CONST (ligature_table[0].ligatures[0].components)];
unsigned int num_ligatures = 0;
+ unsigned int num_components = 0;
/* Populate arrays */
@@ -133,21 +144,32 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
{
unsigned int first_glyph_idx = first_glyphs_indirection[i];
- for (unsigned int second_glyph_idx = 0; second_glyph_idx < ARRAY_LENGTH (ligature_table[0].ligatures); second_glyph_idx++)
+ for (unsigned int ligature_idx = 0; ligature_idx < ARRAY_LENGTH (ligature_table[0].ligatures); ligature_idx++)
{
- hb_codepoint_t second_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].second;
- hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].ligature;
- hb_codepoint_t second_glyph, ligature_glyph;
- if (!second_u ||
- !hb_font_get_glyph (font, second_u, 0, &second_glyph) ||
- !hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph))
+ hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[ligature_idx].ligature;
+ hb_codepoint_t ligature_glyph;
+ if (!hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph))
continue;
- ligature_per_first_glyph_count_list[i]++;
+ const auto &components = ligature_table[first_glyph_idx].ligatures[ligature_idx].components;
+ unsigned component_count = ARRAY_LENGTH_CONST (components);
+
+ for (unsigned i = 0; i < component_count; i++)
+ {
+ hb_codepoint_t component_u = ligature_table[first_glyph_idx].ligatures[ligature_idx].components[i];
+ hb_codepoint_t component_glyph;
+ if (!component_u ||
+ !hb_font_get_glyph (font, component_u, 0, &component_glyph))
+ continue;
+ component_list[num_components++] = component_glyph;
+ }
+
+ component_count_list[num_ligatures] = 1 + component_count;
ligature_list[num_ligatures] = ligature_glyph;
- component_count_list[num_ligatures] = 2;
- component_list[num_ligatures] = second_glyph;
+
+ ligature_per_first_glyph_count_list[i]++;
+
num_ligatures++;
}
}
@@ -161,14 +183,13 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
hb_serialize_context_t c (buf, sizeof (buf));
OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
bool ret = lookup->serialize_ligature (&c,
- OT::LookupFlag::IgnoreMarks,
+ lookup_flags,
hb_sorted_array (first_glyphs, num_first_glyphs),
hb_array (ligature_per_first_glyph_count_list, num_first_glyphs),
hb_array (ligature_list, num_ligatures),
hb_array (component_count_list, num_ligatures),
- hb_array (component_list, num_ligatures));
+ hb_array (component_list, num_components));
c.end_serialize ();
- /* TODO sanitize the results? */
return ret && !c.in_error () ? c.copy<OT::SubstLookup> () : nullptr;
}
@@ -181,10 +202,18 @@ arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan,
if (feature_index < 4)
return arabic_fallback_synthesize_lookup_single (plan, font, feature_index);
else
- return arabic_fallback_synthesize_lookup_ligature (plan, font);
+ {
+ switch (feature_index) {
+ case 4: return arabic_fallback_synthesize_lookup_ligature (plan, font, ligature_3_table, OT::LookupFlag::IgnoreMarks);
+ case 5: return arabic_fallback_synthesize_lookup_ligature (plan, font, ligature_table, OT::LookupFlag::IgnoreMarks);
+ case 6: return arabic_fallback_synthesize_lookup_ligature (plan, font, ligature_mark_table, 0);
+ }
+ }
+ assert (false);
+ return nullptr;
}
-#define ARABIC_FALLBACK_MAX_LOOKUPS 5
+#define ARABIC_FALLBACK_MAX_LOOKUPS ARRAY_LENGTH_CONST (arabic_fallback_features)
struct arabic_fallback_plan_t
{
@@ -201,7 +230,7 @@ struct arabic_fallback_plan_t
#endif
#ifdef HB_WITH_WIN1256
-#include "hb-ot-shape-complex-arabic-win1256.hh"
+#include "hb-ot-shaper-arabic-win1256.hh"
#endif
struct ManifestLookup
@@ -230,9 +259,8 @@ arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUS
return false;
const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
- static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) ==
+ static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) <=
ARABIC_FALLBACK_MAX_LOOKUPS * sizeof (ManifestLookup), "");
- /* TODO sanitize the table? */
unsigned j = 0;
unsigned int count = manifest.len;
@@ -264,7 +292,7 @@ arabic_fallback_plan_init_unicode (arabic_fallback_plan_t *fallback_plan,
const hb_ot_shape_plan_t *plan,
hb_font_t *font)
{
- static_assert ((ARRAY_LENGTH_CONST(arabic_fallback_features) <= ARABIC_FALLBACK_MAX_LOOKUPS), "");
+ static_assert ((ARRAY_LENGTH_CONST (arabic_fallback_features) <= ARABIC_FALLBACK_MAX_LOOKUPS), "");
unsigned int j = 0;
for (unsigned int i = 0; i < ARRAY_LENGTH(arabic_fallback_features) ; i++)
{
@@ -345,4 +373,4 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
}
-#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH */
+#endif /* HB_OT_SHAPER_ARABIC_FALLBACK_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-joining-list.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh
index e6339ee72b..a5ce3a6c93 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-joining-list.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh
@@ -12,8 +12,8 @@
* # Date: 2021-07-10, 00:35:31 GMT
*/
-#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH
-#define HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH
+#ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH
+#define HB_OT_SHAPER_ARABIC_JOINING_LIST_HH
static bool
has_arabic_joining (hb_script_t script)
@@ -42,6 +42,6 @@ has_arabic_joining (hb_script_t script)
}
-#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH */
+#endif /* HB_OT_SHAPER_ARABIC_JOINING_LIST_HH */
/* == End of generated function == */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-pua.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-pua.hh
new file mode 100644
index 0000000000..ba86772f84
--- /dev/null
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-pua.hh
@@ -0,0 +1,118 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ * ./gen-arabic-pua.py
+ *
+ */
+
+#ifndef HB_OT_SHAPER_ARABIC_PUA_HH
+#define HB_OT_SHAPER_ARABIC_PUA_HH
+
+static const uint8_t
+_hb_arabic_u8[464] =
+{
+ 84, 86, 85, 85, 85, 85, 85,213, 16, 34, 34, 34, 34, 34, 35, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 36, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 82, 16, 0, 0, 0, 0, 1, 2, 3, 4,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7,
+ 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 0, 0, 0, 22, 0, 23, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 16, 34, 34, 34, 35, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 66, 16, 50, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68,101, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+ 71, 68, 68, 68, 68, 68, 68, 68,152,186, 76, 77, 68,254, 16, 50,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 5, 6,
+ 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 13, 0, 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 23, 23, 29, 30, 31, 32, 33, 0, 0, 0, 0,
+ 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 36, 37, 38, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 40,
+ 41, 42, 0, 43, 44, 0, 0, 45, 46, 0, 47, 48, 49, 0, 0, 0,
+ 0, 50, 0, 0, 51, 52, 0, 53, 54, 55, 56, 57, 58, 0, 0, 0,
+ 0, 0, 59, 60, 61, 62, 63, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 66,
+ 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+};
+static const uint16_t
+_hb_arabic_u16[720] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0,61728,61729,61730, 0, 0,61733, 0, 0,
+ 61736,61737,61738,61739,61790,61741,61742,61743,61872,61873,61874,61875,61876,61877,61878,61879,
+ 61880,61881,61754,61755, 0,61757, 0,61759, 0, 0, 0,61787,61788,61789, 0, 0,
+ 0, 0, 0,61731, 0, 0, 0, 0, 0, 0, 0,61732, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,61734, 0, 0, 0, 0, 0, 0, 0,61735,
+ 0, 0, 0, 0,61740, 0, 0, 0, 0, 0, 0,61755, 0, 0, 0,61759,
+ 0,61869,61765,61763,61883,61767,61882,61761,61770,61865,61772,61774,61777,61780,61783,61784,
+ 61785,61786,61792,61794,61796,61798,61800,61801,61802,61806,61810,61696,61696,61696,61696,61696,
+ 61791,61813,61816,61818,61820,61822,61921,61860,61861,61868,61864,61895,61896,61899,61892,61893,
+ 61898,61897,61894,61696,61696,61696,61696,61696,61696,61696,61696,61696,61696,61696,61696, 0,
+ 61744,61745,61746,61747,61748,61749,61750,61751,61752,61753, 0,61790,61790, 0, 0, 0,
+ 0, 0, 0, 0,61708,61709,61710,61711,61756,61758, 0, 0, 0, 0, 0, 0,
+ 0,61765,61766,61763,61764,61883,61883,61767,61768,61882,61871,61870,61870,61761,61762,61770,
+ 61770,61769,61769,61865,61866,61772,61772,61771,61771,61774,61774,61773,61773,61777,61776,61775,
+ 61775,61780,61779,61778,61778,61783,61782,61781,61781,61784,61784,61785,61785,61786,61786,61792,
+ 61792,61794,61794,61793,61793,61796,61796,61795,61795,61798,61798,61797,61797,61800,61800,61799,
+ 61799,61801,61801,61801,61801,61802,61802,61802,61802,61806,61805,61803,61804,61810,61809,61807,
+ 61808,61813,61813,61811,61812,61816,61816,61814,61815,61818,61818,61817,61817,61820,61820,61819,
+ 61819,61822,61822,61821,61821,61921,61921,61823,61823,61860,61859,61857,61858,61861,61861,61868,
+ 61867,61864,61863,61862,61862,61888,61889,61886,61887,61890,61891,61885,61884, 0, 0, 0,
+ 0, 0, 0, 0,61984,61985,61986, 0, 0,61989, 0, 0,61992,61993,61994,61995,
+ 62046,61997,61998,61999, 0, 0,62010,62011, 0,62013, 0,62015, 0, 0, 0,62043,
+ 0,62045, 0, 0, 0, 0, 0,61987, 0, 0, 0,61988, 0, 0, 0,61990,
+ 0, 0, 0,61991,61996, 0, 0, 0, 0, 0, 0,62011, 0, 0, 0,62015,
+ 0,62165,62021,62019,62170,62023,62169,62017,62028,62161,62032,62036,62040,62048,62052,62053,
+ 62055,62057,62059,62064,62068,62072,62078,62114,62115,62122,62126,61952,61952,61952,61952,61952,
+ 62047,62130,62134,62138,62142,62146,62150,62154,62155,62164,62160,62183,62184,62187,62180,62181,
+ 62186,62185,62182,61952,61952,61952,61952, 0,62000,62001,62002,62003,62004,62005,62006,62007,
+ 62008,62009, 0,62046,62046, 0, 0, 0,61964,61965,61966,61967,62012,62014, 0, 0,
+ 61954, 0,61981, 0, 0, 0,61955, 0,61982, 0,61956, 0, 0, 0,62111, 0,
+ 0, 0, 0,61970,61971,61972,61957, 0,61980, 0, 0, 0, 0, 0,61958, 0,
+ 61983, 0, 0, 0, 0, 0,62191, 0,62188,62189,62192, 0, 0, 0,61973, 0,
+ 0,62098, 0, 0,61974, 0, 0,62099, 0, 0,62101, 0, 0,61975, 0, 0,
+ 62100, 0, 0, 0,62080,62081,62082,62102, 0,62083,62084,62085,62103, 0, 0, 0,
+ 62106, 0,62107, 0,62108, 0, 0, 0,61976, 0, 0, 0, 0,62086,62087,62088,
+ 62109,61978,62089,62090,62091,62110,62093,62094, 0,62104, 0, 0, 0, 0,62095,62096,
+ 62097,62105, 0, 0,61977, 0, 0, 0, 0, 0,62075,62077,61968, 0, 0, 0,
+ 0,62021,62022,62019,62020,62170,62171,62023,62024,62169,62168,62166,62167,62017,62018,62028,
+ 62027,62025,62026,62161,62162,62032,62031,62029,62030,62036,62035,62033,62034,62040,62039,62037,
+ 62038,62048,62044,62041,62042,62052,62051,62049,62050,62053,62054,62055,62056,62057,62058,62059,
+ 62060,62064,62063,62061,62062,62068,62067,62065,62066,62072,62071,62069,62070,62078,62076,62073,
+ 62074,62114,62113,62079,62193,62118,62117,62115,62116,62122,62121,62119,62120,62126,62125,62123,
+ 62124,62130,62129,62127,62128,62134,62133,62131,62132,62138,62137,62135,62136,62142,62141,62139,
+ 62140,62146,62145,62143,62144,62150,62149,62147,62148,62154,62153,62151,62152,62155,62156,62164,
+ 62163,62160,62159,62157,62158,62176,62177,62174,62175,62178,62179,62172,62173, 0, 0, 0,
+};
+
+static inline unsigned
+_hb_arabic_b2 (const uint8_t* a, unsigned i)
+{
+ return (a[i>>2]>>((i&3u)<<1))&3u;
+}
+static inline unsigned
+_hb_arabic_b4 (const uint8_t* a, unsigned i)
+{
+ return (a[i>>1]>>((i&1u)<<2))&15u;
+}
+static inline uint_fast16_t
+_hb_arabic_pua_simp_map (unsigned u)
+{
+ return u<65277u?_hb_arabic_u16[((_hb_arabic_u8[40+(((_hb_arabic_b4(8+_hb_arabic_u8,((_hb_arabic_b2(_hb_arabic_u8,u>>3>>4>>4))<<4)+((u>>3>>4)&15u)))<<4)+((u>>3)&15u))])<<3)+((u)&7u)]:0;
+}
+static inline uint_fast16_t
+_hb_arabic_pua_trad_map (unsigned u)
+{
+ return u<65277u?_hb_arabic_u16[320+(((_hb_arabic_u8[208+(((_hb_arabic_b4(168+_hb_arabic_u8,((_hb_arabic_b4(136+_hb_arabic_u8,u>>2>>4>>4))<<4)+((u>>2>>4)&15u)))<<4)+((u>>2)&15u))])<<2)+((u)&3u))]:0;
+}
+
+#endif /* HB_OT_SHAPER_ARABIC_PUA_HH */
+
+/* == End of generated table == */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh
index c158964f2c..fd3d8645d1 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh
@@ -13,8 +13,8 @@
* UnicodeData.txt does not have a header.
*/
-#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
-#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
+#ifndef HB_OT_SHAPER_ARABIC_TABLE_HH
+#define HB_OT_SHAPER_ARABIC_TABLE_HH
#define A JOINING_GROUP_ALAPH
@@ -416,26 +416,141 @@ static const uint16_t shaping_table[][4] =
static const struct ligature_set_t {
uint16_t first;
struct ligature_pairs_t {
- uint16_t second;
+ uint16_t components[1];
uint16_t ligature;
- } ligatures[4];
+ } ligatures[14];
} ligature_table[] =
{
+ { 0xFE91u, {
+ { {0xFEE2u}, 0xFC08u }, /* ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM */
+ { {0xFEE4u}, 0xFC9Fu }, /* ARABIC LIGATURE BEH WITH MEEM INITIAL FORM */
+ { {0xFEA0u}, 0xFC9Cu }, /* ARABIC LIGATURE BEH WITH JEEM INITIAL FORM */
+ { {0xFEA4u}, 0xFC9Du }, /* ARABIC LIGATURE BEH WITH HAH INITIAL FORM */
+ { {0xFEA8u}, 0xFC9Eu }, /* ARABIC LIGATURE BEH WITH KHAH INITIAL FORM */
+ }},
+ { 0xFE92u, {
+ { {0xFEAEu}, 0xFC6Au }, /* ARABIC LIGATURE BEH WITH REH FINAL FORM */
+ { {0xFEE6u}, 0xFC6Du }, /* ARABIC LIGATURE BEH WITH NOON FINAL FORM */
+ { {0xFEF2u}, 0xFC6Fu }, /* ARABIC LIGATURE BEH WITH YEH FINAL FORM */
+ }},
+ { 0xFE97u, {
+ { {0xFEE2u}, 0xFC0Eu }, /* ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM */
+ { {0xFEE4u}, 0xFCA4u }, /* ARABIC LIGATURE TEH WITH MEEM INITIAL FORM */
+ { {0xFEA0u}, 0xFCA1u }, /* ARABIC LIGATURE TEH WITH JEEM INITIAL FORM */
+ { {0xFEA4u}, 0xFCA2u }, /* ARABIC LIGATURE TEH WITH HAH INITIAL FORM */
+ { {0xFEA8u}, 0xFCA3u }, /* ARABIC LIGATURE TEH WITH KHAH INITIAL FORM */
+ }},
+ { 0xFE98u, {
+ { {0xFEAEu}, 0xFC70u }, /* ARABIC LIGATURE TEH WITH REH FINAL FORM */
+ { {0xFEE6u}, 0xFC73u }, /* ARABIC LIGATURE TEH WITH NOON FINAL FORM */
+ { {0xFEF2u}, 0xFC75u }, /* ARABIC LIGATURE TEH WITH YEH FINAL FORM */
+ }},
+ { 0xFE9Bu, {
+ { {0xFEE2u}, 0xFC12u }, /* ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM */
+ }},
+ { 0xFE9Fu, {
+ { {0xFEE4u}, 0xFCA8u }, /* ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM */
+ }},
+ { 0xFEA3u, {
+ { {0xFEE4u}, 0xFCAAu }, /* ARABIC LIGATURE HAH WITH MEEM INITIAL FORM */
+ }},
+ { 0xFEA7u, {
+ { {0xFEE4u}, 0xFCACu }, /* ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM */
+ }},
+ { 0xFEB3u, {
+ { {0xFEE4u}, 0xFCB0u }, /* ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM */
+ }},
+ { 0xFEB7u, {
+ { {0xFEE4u}, 0xFD30u }, /* ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM */
+ }},
+ { 0xFED3u, {
+ { {0xFEF2u}, 0xFC32u }, /* ARABIC LIGATURE FEH WITH YEH ISOLATED FORM */
+ }},
{ 0xFEDFu, {
- { 0xFE82u, 0xFEF5u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
- { 0xFE84u, 0xFEF7u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
- { 0xFE88u, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
- { 0xFE8Eu, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
+ { {0xFE9Eu}, 0xFC3Fu }, /* ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM */
+ { {0xFEA0u}, 0xFCC9u }, /* ARABIC LIGATURE LAM WITH JEEM INITIAL FORM */
+ { {0xFEA2u}, 0xFC40u }, /* ARABIC LIGATURE LAM WITH HAH ISOLATED FORM */
+ { {0xFEA4u}, 0xFCCAu }, /* ARABIC LIGATURE LAM WITH HAH INITIAL FORM */
+ { {0xFEA6u}, 0xFC41u }, /* ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM */
+ { {0xFEA8u}, 0xFCCBu }, /* ARABIC LIGATURE LAM WITH KHAH INITIAL FORM */
+ { {0xFEE2u}, 0xFC42u }, /* ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM */
+ { {0xFEE4u}, 0xFCCCu }, /* ARABIC LIGATURE LAM WITH MEEM INITIAL FORM */
+ { {0xFEF2u}, 0xFC44u }, /* ARABIC LIGATURE LAM WITH YEH ISOLATED FORM */
+ { {0xFEECu}, 0xFCCDu }, /* ARABIC LIGATURE LAM WITH HEH INITIAL FORM */
+ { {0xFE82u}, 0xFEF5u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
+ { {0xFE84u}, 0xFEF7u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
+ { {0xFE88u}, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
+ { {0xFE8Eu}, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
}},
{ 0xFEE0u, {
- { 0xFE82u, 0xFEF6u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
- { 0xFE84u, 0xFEF8u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
- { 0xFE88u, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
- { 0xFE8Eu, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
+ { {0xFEF0u}, 0xFC86u }, /* ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM */
+ { {0xFE82u}, 0xFEF6u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
+ { {0xFE84u}, 0xFEF8u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
+ { {0xFE88u}, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
+ { {0xFE8Eu}, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
+ }},
+ { 0xFEE3u, {
+ { {0xFEA0u}, 0xFCCEu }, /* ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM */
+ { {0xFEA4u}, 0xFCCFu }, /* ARABIC LIGATURE MEEM WITH HAH INITIAL FORM */
+ { {0xFEA8u}, 0xFCD0u }, /* ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM */
+ { {0xFEE4u}, 0xFCD1u }, /* ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM */
+ }},
+ { 0xFEE7u, {
+ { {0xFEE2u}, 0xFC4Eu }, /* ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM */
+ { {0xFEE4u}, 0xFCD5u }, /* ARABIC LIGATURE NOON WITH MEEM INITIAL FORM */
+ { {0xFEA0u}, 0xFCD2u }, /* ARABIC LIGATURE NOON WITH JEEM INITIAL FORM */
+ { {0xFEA4u}, 0xFCD3u }, /* ARABIC LIGATURE NOON WITH HAH INITIAL FORM */
+ }},
+ { 0xFEE8u, {
+ { {0xFEF2u}, 0xFC8Fu }, /* ARABIC LIGATURE NOON WITH YEH FINAL FORM */
+ }},
+ { 0xFEF3u, {
+ { {0xFEA0u}, 0xFCDAu }, /* ARABIC LIGATURE YEH WITH JEEM INITIAL FORM */
+ { {0xFEA4u}, 0xFCDBu }, /* ARABIC LIGATURE YEH WITH HAH INITIAL FORM */
+ { {0xFEA8u}, 0xFCDCu }, /* ARABIC LIGATURE YEH WITH KHAH INITIAL FORM */
+ { {0xFEE4u}, 0xFCDDu }, /* ARABIC LIGATURE YEH WITH MEEM INITIAL FORM */
+ }},
+ { 0xFEF4u, {
+ { {0xFEAEu}, 0xFC91u }, /* ARABIC LIGATURE YEH WITH REH FINAL FORM */
+ { {0xFEE6u}, 0xFC94u }, /* ARABIC LIGATURE YEH WITH NOON FINAL FORM */
+ }},
+};
+
+
+static const struct ligature_mark_set_t {
+ uint16_t first;
+ struct ligature_pairs_t {
+ uint16_t components[1];
+ uint16_t ligature;
+ } ligatures[5];
+} ligature_mark_table[] =
+{
+ { 0x0651u, {
+ { {0x064Cu}, 0xFC5Eu }, /* ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM */
+ { {0x064Eu}, 0xFC60u }, /* ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM */
+ { {0x064Fu}, 0xFC61u }, /* ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM */
+ { {0x0650u}, 0xFC62u }, /* ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM */
+ { {0x064Bu}, 0xF2EEu }, /* PUA ARABIC LIGATURE SHADDA WITH FATHATAN ISOLATED FORM */
+ }},
+};
+
+
+static const struct ligature_3_set_t {
+ uint16_t first;
+ struct ligature_triplets_t {
+ uint16_t components[2];
+ uint16_t ligature;
+ } ligatures[3];
+} ligature_3_table[] =
+{
+ { 0xFEDFu, {
+ { {0xFEE4u, 0xFEA4u}, 0xFD88u}, /* ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM */
+ { {0xFEE0u, 0xFEEAu}, 0xF201u}, /* PUA ARABIC LIGATURE LELLAH ISOLATED FORM */
+ { {0xFEE4u, 0xFEA0u}, 0xF211u}, /* PUA ARABIC LIGATURE LAM WITH MEEM WITH JEEM INITIAL FORM */
}},
};
-#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */
+#endif /* HB_OT_SHAPER_ARABIC_TABLE_HH */
/* == End of generated table == */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-win1256.hh
index 429974d05b..b8d481c813 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-win1256.hh
@@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
+#ifndef HB_OT_SHAPER_ARABIC_WIN1256_HH
/*
@@ -342,8 +342,8 @@ OT_TABLE_END
#include "hb.hh" /* Make check-includes.sh happy. */
#endif
#ifdef OT_MEASURE
-#include "hb-ot-shape-complex-arabic-win1256.hh"
+#include "hb-ot-shaper-arabic-win1256.hh"
#endif
-#define HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
-#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH */
+#define HB_OT_SHAPER_ARABIC_WIN1256_HH
+#endif /* HB_OT_SHAPER_ARABIC_WIN1256_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc
index 224f8b842e..e869d78509 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc
@@ -28,14 +28,14 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex-arabic.hh"
+#include "hb-ot-shaper-arabic.hh"
#include "hb-ot-shape.hh"
/* buffer var allocations */
-#define arabic_shaping_action() complex_var_u8_auxiliary() /* arabic shaping action */
+#define arabic_shaping_action() ot_shaper_var_u8_auxiliary() /* arabic shaping action */
-#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0
+#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_SHAPER0
/* See:
* https://github.com/harfbuzz/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */
@@ -81,7 +81,7 @@ enum hb_arabic_joining_type_t {
JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */
};
-#include "hb-ot-shape-complex-arabic-table.hh"
+#include "hb-ot-shaper-arabic-table.hh"
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
{
@@ -172,6 +172,14 @@ record_stch (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer);
static void
+deallocate_buffer_var (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
+}
+
+static void
collect_features_arabic (hb_ot_shape_planner_t *plan)
{
hb_ot_map_builder_t *map = &plan->map;
@@ -213,6 +221,7 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
map->add_feature (arabic_features[i], has_fallback ? F_HAS_FALLBACK : F_NONE);
map->add_gsub_pause (nullptr);
}
+ map->add_gsub_pause (deallocate_buffer_var);
/* Normally, Unicode says a ZWNJ means "don't ligate". In Arabic script
* however, it says a ZWJ should also mean "don't ligate". So we run
@@ -240,7 +249,7 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
map->enable_feature (HB_TAG('m','s','e','t'));
}
-#include "hb-ot-shape-complex-arabic-fallback.hh"
+#include "hb-ot-shaper-arabic-fallback.hh"
struct arabic_shape_plan_t
{
@@ -405,7 +414,7 @@ arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
-#ifdef HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK
+#ifdef HB_NO_OT_SHAPER_ARABIC_FALLBACK
return;
#endif
@@ -619,8 +628,6 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan,
hb_font_t *font)
{
apply_stch (plan, buffer, font);
-
- HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
/* https://www.unicode.org/reports/tr53/ */
@@ -689,7 +696,7 @@ reorder_marks_arabic (const hb_ot_shape_plan_t *plan HB_UNUSED,
/* Shift it! */
DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d", cc, i, j);
- hb_glyph_info_t temp[HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS];
+ hb_glyph_info_t temp[HB_OT_SHAPE_MAX_COMBINING_MARKS];
assert (j - i <= ARRAY_LENGTH (temp));
buffer->merge_clusters (start, j);
memmove (temp, &info[i], (j - i) * sizeof (hb_glyph_info_t));
@@ -720,7 +727,7 @@ reorder_marks_arabic (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
}
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
+const hb_ot_shaper_t _hb_ot_shaper_arabic =
{
collect_features_arabic,
nullptr, /* override_features */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.hh
index 5bf6ff6338..a025b1a399 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.hh
@@ -26,12 +26,12 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_HH
-#define HB_OT_SHAPE_COMPLEX_ARABIC_HH
+#ifndef HB_OT_SHAPER_ARABIC_HH
+#define HB_OT_SHAPER_ARABIC_HH
#include "hb.hh"
-#include "hb-ot-shape-complex.hh"
+#include "hb-ot-shaper.hh"
struct arabic_shape_plan_t;
@@ -47,4 +47,4 @@ setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan,
hb_buffer_t *buffer,
hb_script_t script);
-#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_HH */
+#endif /* HB_OT_SHAPER_ARABIC_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-default.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc
index a755aea098..25716aa81f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-default.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc
@@ -28,10 +28,10 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex.hh"
+#include "hb-ot-shaper.hh"
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
+const hb_ot_shaper_t _hb_ot_shaper_default =
{
nullptr, /* collect_features */
nullptr, /* override_features */
@@ -51,7 +51,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
/* Same as default but no mark advance zeroing / fallback positioning.
* Dumbest shaper ever, basically. */
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_dumber =
+const hb_ot_shaper_t _hb_ot_shaper_dumber =
{
nullptr, /* collect_features */
nullptr, /* override_features */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc
index 3bc9e9b961..aa507c75ca 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc
@@ -28,7 +28,7 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex.hh"
+#include "hb-ot-shaper.hh"
/* Hangul shaper */
@@ -119,7 +119,7 @@ data_destroy_hangul (void *data)
#define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302Eu, 0x302Fu))
/* buffer var allocations */
-#define hangul_shaping_feature() complex_var_u8_auxiliary() /* hangul jamo shaping feature */
+#define hangul_shaping_feature() ot_shaper_var_u8_auxiliary() /* hangul jamo shaping feature */
static bool
is_zero_width_char (hb_font_t *font,
@@ -414,7 +414,7 @@ setup_masks_hangul (const hb_ot_shape_plan_t *plan,
}
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
+const hb_ot_shaper_t _hb_ot_shaper_hangul =
{
collect_features_hangul,
override_features_hangul,
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hebrew.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc
index 334d3ded82..f3b6cde179 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hebrew.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc
@@ -28,7 +28,7 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex.hh"
+#include "hb-ot-shaper.hh"
static bool
@@ -74,7 +74,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
bool found = (bool) c->unicode->compose (a, b, ab);
-#ifdef HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
+#ifdef HB_NO_OT_SHAPER_HEBREW_FALLBACK
return found;
#endif
@@ -163,7 +163,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
}
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
+const hb_ot_shaper_t _hb_ot_shaper_hebrew =
{
nullptr, /* collect_features */
nullptr, /* override_features */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh
new file mode 100644
index 0000000000..d52b13f616
--- /dev/null
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh
@@ -0,0 +1,589 @@
+
+#line 1 "hb-ot-shaper-indic-machine.rl"
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * 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
+ */
+
+#ifndef HB_OT_SHAPER_INDIC_MACHINE_HH
+#define HB_OT_SHAPER_INDIC_MACHINE_HH
+
+#include "hb.hh"
+
+#include "hb-ot-layout.hh"
+#include "hb-ot-shaper-indic.hh"
+
+/* buffer var allocations */
+#define indic_category() ot_shaper_var_u8_category() /* indic_category_t */
+#define indic_position() ot_shaper_var_u8_auxiliary() /* indic_position_t */
+
+using indic_category_t = unsigned;
+using indic_position_t = ot_position_t;
+
+#define I_Cat(Cat) indic_syllable_machine_ex_##Cat
+
+enum indic_syllable_type_t {
+ indic_consonant_syllable,
+ indic_vowel_syllable,
+ indic_standalone_cluster,
+ indic_symbol_cluster,
+ indic_broken_cluster,
+ indic_non_indic_cluster,
+};
+
+
+#line 57 "hb-ot-shaper-indic-machine.hh"
+#define indic_syllable_machine_ex_A 9u
+#define indic_syllable_machine_ex_C 1u
+#define indic_syllable_machine_ex_CM 16u
+#define indic_syllable_machine_ex_CS 18u
+#define indic_syllable_machine_ex_DOTTEDCIRCLE 11u
+#define indic_syllable_machine_ex_H 4u
+#define indic_syllable_machine_ex_M 7u
+#define indic_syllable_machine_ex_N 3u
+#define indic_syllable_machine_ex_PLACEHOLDER 10u
+#define indic_syllable_machine_ex_RS 12u
+#define indic_syllable_machine_ex_Ra 15u
+#define indic_syllable_machine_ex_Repha 14u
+#define indic_syllable_machine_ex_SM 8u
+#define indic_syllable_machine_ex_Symbol 17u
+#define indic_syllable_machine_ex_V 2u
+#define indic_syllable_machine_ex_VD 9u
+#define indic_syllable_machine_ex_X 0u
+#define indic_syllable_machine_ex_ZWJ 6u
+#define indic_syllable_machine_ex_ZWNJ 5u
+
+
+#line 79 "hb-ot-shaper-indic-machine.hh"
+static const unsigned char _indic_syllable_machine_trans_keys[] = {
+ 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 8u, 8u, 8u,
+ 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 12u, 4u, 12u, 8u, 8u, 5u, 7u,
+ 5u, 8u, 4u, 8u, 4u, 8u, 4u, 12u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u,
+ 4u, 8u, 5u, 8u, 8u, 8u, 1u, 18u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u,
+ 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 1u, 15u, 1u, 15u, 3u, 9u,
+ 4u, 9u, 5u, 9u, 4u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u,
+ 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u,
+ 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u,
+ 4u, 9u, 5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 8u,
+ 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u,
+ 5u, 9u, 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u,
+ 5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 12u, 4u, 8u, 3u, 16u,
+ 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u,
+ 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u, 5u, 9u,
+ 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 12u, 5u, 9u,
+ 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u,
+ 1u, 15u, 0
+};
+
+static const char _indic_syllable_machine_key_spans[] = {
+ 1, 5, 3, 4, 5, 9, 5, 1,
+ 3, 4, 5, 9, 9, 9, 1, 3,
+ 4, 5, 5, 9, 1, 3, 4, 5,
+ 5, 4, 1, 18, 14, 14, 13, 15,
+ 5, 5, 1, 5, 15, 15, 15, 7,
+ 6, 5, 6, 5, 7, 5, 14, 14,
+ 14, 14, 13, 15, 14, 14, 13, 15,
+ 5, 1, 5, 15, 15, 7, 6, 5,
+ 6, 5, 5, 7, 5, 14, 14, 5,
+ 14, 14, 13, 15, 14, 15, 5, 1,
+ 5, 15, 15, 7, 6, 5, 14, 6,
+ 5, 5, 7, 5, 14, 9, 5, 14,
+ 14, 13, 15, 14, 15, 5, 1, 5,
+ 15, 15, 7, 6, 5, 14, 6, 5,
+ 5, 7, 5, 16, 14, 16, 9, 5,
+ 1, 5, 15, 7, 5, 5, 1, 5,
+ 15
+};
+
+static const short _indic_syllable_machine_index_offsets[] = {
+ 0, 2, 8, 12, 17, 23, 33, 39,
+ 41, 45, 50, 56, 66, 76, 86, 88,
+ 92, 97, 103, 109, 119, 121, 125, 130,
+ 136, 142, 147, 149, 168, 183, 198, 212,
+ 228, 234, 240, 242, 248, 264, 280, 296,
+ 304, 311, 317, 324, 330, 338, 344, 359,
+ 374, 389, 404, 418, 434, 449, 464, 478,
+ 494, 500, 502, 508, 524, 540, 548, 555,
+ 561, 568, 574, 580, 588, 594, 609, 624,
+ 630, 645, 660, 674, 690, 705, 721, 727,
+ 729, 735, 751, 767, 775, 782, 788, 803,
+ 810, 816, 822, 830, 836, 851, 861, 867,
+ 882, 897, 911, 927, 942, 958, 964, 966,
+ 972, 988, 1004, 1012, 1019, 1025, 1040, 1047,
+ 1053, 1059, 1067, 1073, 1090, 1105, 1122, 1132,
+ 1138, 1140, 1146, 1162, 1170, 1176, 1182, 1184,
+ 1190
+};
+
+static const unsigned char _indic_syllable_machine_indicies[] = {
+ 1, 0, 2, 3, 3, 4, 1, 0,
+ 3, 3, 4, 0, 3, 3, 4, 1,
+ 0, 5, 3, 3, 4, 1, 0, 2,
+ 3, 3, 4, 1, 0, 0, 0, 6,
+ 0, 8, 9, 9, 10, 11, 7, 11,
+ 7, 9, 9, 10, 7, 9, 9, 10,
+ 11, 7, 12, 9, 9, 10, 11, 7,
+ 8, 9, 9, 10, 11, 7, 7, 7,
+ 13, 7, 8, 9, 9, 10, 11, 7,
+ 7, 7, 14, 7, 16, 17, 17, 18,
+ 19, 15, 15, 15, 20, 15, 19, 15,
+ 17, 17, 18, 21, 17, 17, 18, 19,
+ 15, 16, 17, 17, 18, 19, 15, 22,
+ 17, 17, 18, 19, 15, 24, 25, 25,
+ 26, 27, 23, 23, 23, 28, 23, 27,
+ 23, 25, 25, 26, 23, 25, 25, 26,
+ 27, 23, 24, 25, 25, 26, 27, 23,
+ 29, 25, 25, 26, 27, 23, 17, 17,
+ 18, 1, 0, 31, 30, 33, 34, 35,
+ 36, 37, 38, 18, 19, 39, 40, 40,
+ 20, 32, 41, 42, 43, 44, 45, 32,
+ 47, 48, 49, 50, 4, 1, 51, 46,
+ 46, 6, 46, 46, 46, 52, 46, 53,
+ 48, 54, 54, 4, 1, 51, 46, 46,
+ 46, 46, 46, 46, 52, 46, 48, 54,
+ 54, 4, 1, 51, 46, 46, 46, 46,
+ 46, 46, 52, 46, 33, 46, 46, 46,
+ 55, 56, 46, 1, 51, 46, 46, 46,
+ 46, 46, 33, 46, 57, 57, 46, 1,
+ 51, 46, 51, 46, 46, 58, 51, 46,
+ 51, 46, 51, 46, 46, 46, 51, 46,
+ 33, 46, 59, 46, 57, 57, 46, 1,
+ 51, 46, 46, 46, 46, 46, 33, 46,
+ 33, 46, 46, 46, 57, 57, 46, 1,
+ 51, 46, 46, 46, 46, 46, 33, 46,
+ 33, 46, 46, 46, 57, 56, 46, 1,
+ 51, 46, 46, 46, 46, 46, 33, 46,
+ 60, 61, 62, 62, 4, 1, 51, 46,
+ 61, 62, 62, 4, 1, 51, 46, 62,
+ 62, 4, 1, 51, 46, 63, 64, 64,
+ 4, 1, 51, 46, 55, 65, 46, 1,
+ 51, 46, 55, 46, 57, 57, 46, 1,
+ 51, 46, 57, 65, 46, 1, 51, 46,
+ 47, 48, 54, 54, 4, 1, 51, 46,
+ 46, 46, 46, 46, 46, 52, 46, 47,
+ 48, 49, 54, 4, 1, 51, 46, 46,
+ 6, 46, 46, 46, 52, 46, 67, 68,
+ 69, 70, 10, 11, 71, 66, 66, 14,
+ 66, 66, 66, 72, 66, 73, 68, 74,
+ 70, 10, 11, 71, 66, 66, 66, 66,
+ 66, 66, 72, 66, 68, 74, 70, 10,
+ 11, 71, 66, 66, 66, 66, 66, 66,
+ 72, 66, 75, 66, 66, 66, 76, 77,
+ 66, 11, 71, 66, 66, 66, 66, 66,
+ 75, 66, 78, 68, 79, 80, 10, 11,
+ 71, 66, 66, 13, 66, 66, 66, 72,
+ 66, 81, 68, 74, 74, 10, 11, 71,
+ 66, 66, 66, 66, 66, 66, 72, 66,
+ 68, 74, 74, 10, 11, 71, 66, 66,
+ 66, 66, 66, 66, 72, 66, 75, 66,
+ 66, 66, 82, 77, 66, 11, 71, 66,
+ 66, 66, 66, 66, 75, 66, 71, 66,
+ 66, 83, 71, 66, 71, 66, 71, 66,
+ 66, 66, 71, 66, 75, 66, 84, 66,
+ 82, 82, 66, 11, 71, 66, 66, 66,
+ 66, 66, 75, 66, 75, 66, 66, 66,
+ 82, 82, 66, 11, 71, 66, 66, 66,
+ 66, 66, 75, 66, 85, 86, 87, 87,
+ 10, 11, 71, 66, 86, 87, 87, 10,
+ 11, 71, 66, 87, 87, 10, 11, 71,
+ 66, 88, 89, 89, 10, 11, 71, 66,
+ 76, 90, 66, 11, 71, 66, 82, 82,
+ 66, 11, 71, 66, 76, 66, 82, 82,
+ 66, 11, 71, 66, 82, 90, 66, 11,
+ 71, 66, 78, 68, 74, 74, 10, 11,
+ 71, 66, 66, 66, 66, 66, 66, 72,
+ 66, 78, 68, 79, 74, 10, 11, 71,
+ 66, 66, 13, 66, 66, 66, 72, 66,
+ 8, 9, 9, 10, 11, 66, 67, 68,
+ 74, 70, 10, 11, 71, 66, 66, 66,
+ 66, 66, 66, 72, 66, 92, 36, 93,
+ 93, 18, 19, 39, 91, 91, 91, 91,
+ 91, 91, 43, 91, 36, 93, 93, 18,
+ 19, 39, 91, 91, 91, 91, 91, 91,
+ 43, 91, 94, 91, 91, 91, 95, 96,
+ 91, 19, 39, 91, 91, 91, 91, 91,
+ 94, 91, 35, 36, 97, 98, 18, 19,
+ 39, 91, 91, 20, 91, 91, 91, 43,
+ 91, 94, 91, 91, 91, 99, 96, 91,
+ 19, 39, 91, 91, 91, 91, 91, 94,
+ 91, 39, 91, 91, 100, 39, 91, 39,
+ 91, 39, 91, 91, 91, 39, 91, 94,
+ 91, 101, 91, 99, 99, 91, 19, 39,
+ 91, 91, 91, 91, 91, 94, 91, 94,
+ 91, 91, 91, 99, 99, 91, 19, 39,
+ 91, 91, 91, 91, 91, 94, 91, 102,
+ 103, 104, 104, 18, 19, 39, 91, 103,
+ 104, 104, 18, 19, 39, 91, 104, 104,
+ 18, 19, 39, 91, 35, 36, 93, 93,
+ 18, 19, 39, 91, 91, 91, 91, 91,
+ 91, 43, 91, 105, 106, 106, 18, 19,
+ 39, 91, 95, 107, 91, 19, 39, 91,
+ 99, 99, 91, 19, 39, 91, 95, 91,
+ 99, 99, 91, 19, 39, 91, 99, 107,
+ 91, 19, 39, 91, 35, 36, 97, 93,
+ 18, 19, 39, 91, 91, 20, 91, 91,
+ 91, 43, 91, 16, 17, 17, 18, 19,
+ 108, 108, 108, 20, 108, 16, 17, 17,
+ 18, 19, 108, 110, 111, 112, 113, 26,
+ 27, 114, 109, 109, 28, 109, 109, 109,
+ 115, 109, 116, 111, 113, 113, 26, 27,
+ 114, 109, 109, 109, 109, 109, 109, 115,
+ 109, 111, 113, 113, 26, 27, 114, 109,
+ 109, 109, 109, 109, 109, 115, 109, 117,
+ 109, 109, 109, 118, 119, 109, 27, 114,
+ 109, 109, 109, 109, 109, 117, 109, 110,
+ 111, 112, 40, 26, 27, 114, 109, 109,
+ 28, 109, 109, 109, 115, 109, 117, 109,
+ 109, 109, 120, 119, 109, 27, 114, 109,
+ 109, 109, 109, 109, 117, 109, 114, 109,
+ 109, 121, 114, 109, 114, 109, 114, 109,
+ 109, 109, 114, 109, 117, 109, 122, 109,
+ 120, 120, 109, 27, 114, 109, 109, 109,
+ 109, 109, 117, 109, 117, 109, 109, 109,
+ 120, 120, 109, 27, 114, 109, 109, 109,
+ 109, 109, 117, 109, 123, 124, 125, 125,
+ 26, 27, 114, 109, 124, 125, 125, 26,
+ 27, 114, 109, 125, 125, 26, 27, 114,
+ 109, 110, 111, 113, 113, 26, 27, 114,
+ 109, 109, 109, 109, 109, 109, 115, 109,
+ 126, 127, 127, 26, 27, 114, 109, 118,
+ 128, 109, 27, 114, 109, 120, 120, 109,
+ 27, 114, 109, 118, 109, 120, 120, 109,
+ 27, 114, 109, 120, 128, 109, 27, 114,
+ 109, 33, 34, 35, 36, 97, 93, 18,
+ 19, 39, 40, 40, 20, 91, 91, 33,
+ 43, 91, 47, 129, 49, 50, 4, 1,
+ 51, 46, 46, 6, 46, 46, 46, 52,
+ 46, 33, 34, 35, 36, 130, 131, 18,
+ 132, 133, 46, 40, 20, 46, 46, 33,
+ 43, 46, 16, 134, 134, 18, 132, 51,
+ 46, 46, 20, 46, 133, 46, 46, 135,
+ 133, 46, 133, 46, 133, 46, 46, 46,
+ 133, 46, 33, 46, 59, 16, 134, 134,
+ 18, 132, 51, 46, 46, 46, 46, 46,
+ 33, 46, 137, 136, 138, 138, 136, 31,
+ 139, 136, 138, 138, 136, 31, 139, 136,
+ 139, 136, 136, 140, 139, 136, 139, 136,
+ 139, 136, 136, 136, 139, 136, 33, 108,
+ 108, 108, 108, 108, 108, 108, 108, 40,
+ 108, 108, 108, 108, 33, 108, 0
+};
+
+static const unsigned char _indic_syllable_machine_trans_targs[] = {
+ 27, 33, 38, 2, 39, 45, 46, 27,
+ 55, 8, 61, 56, 68, 69, 72, 27,
+ 77, 15, 83, 78, 86, 27, 91, 27,
+ 100, 21, 106, 101, 109, 114, 27, 125,
+ 27, 28, 48, 73, 75, 93, 94, 79,
+ 95, 115, 116, 87, 123, 128, 27, 29,
+ 31, 5, 47, 34, 42, 30, 1, 32,
+ 36, 0, 35, 37, 40, 41, 3, 43,
+ 4, 44, 27, 49, 51, 12, 71, 57,
+ 64, 50, 6, 52, 66, 59, 53, 11,
+ 70, 54, 7, 58, 60, 62, 63, 9,
+ 65, 10, 67, 27, 74, 17, 76, 89,
+ 81, 13, 92, 14, 80, 82, 84, 85,
+ 16, 88, 18, 90, 27, 27, 96, 98,
+ 19, 23, 102, 110, 97, 99, 112, 104,
+ 20, 103, 105, 107, 108, 22, 111, 24,
+ 113, 117, 118, 122, 119, 120, 25, 121,
+ 27, 124, 26, 126, 127
+};
+
+static const char _indic_syllable_machine_trans_actions[] = {
+ 1, 0, 2, 0, 2, 2, 2, 3,
+ 2, 0, 2, 0, 2, 2, 2, 4,
+ 2, 0, 5, 0, 5, 6, 2, 7,
+ 2, 0, 2, 0, 2, 2, 8, 0,
+ 11, 2, 2, 5, 0, 12, 12, 0,
+ 2, 5, 2, 5, 2, 0, 13, 2,
+ 0, 0, 2, 0, 2, 2, 0, 2,
+ 2, 0, 0, 2, 2, 2, 0, 0,
+ 0, 2, 14, 2, 0, 0, 2, 0,
+ 2, 2, 0, 2, 2, 2, 2, 0,
+ 2, 2, 0, 0, 2, 2, 2, 0,
+ 0, 0, 2, 15, 5, 0, 5, 2,
+ 2, 0, 5, 0, 0, 2, 5, 5,
+ 0, 0, 0, 2, 16, 17, 2, 0,
+ 0, 0, 0, 2, 2, 2, 2, 2,
+ 0, 0, 2, 2, 2, 0, 0, 0,
+ 2, 0, 18, 18, 0, 0, 0, 0,
+ 19, 2, 0, 0, 0
+};
+
+static const char _indic_syllable_machine_to_state_actions[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 9, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0
+};
+
+static const char _indic_syllable_machine_from_state_actions[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0
+};
+
+static const short _indic_syllable_machine_eof_trans[] = {
+ 1, 1, 1, 1, 1, 1, 8, 8,
+ 8, 8, 8, 8, 8, 16, 16, 22,
+ 16, 16, 16, 24, 24, 24, 24, 24,
+ 24, 1, 31, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 109, 109, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 92, 47, 47, 47, 47,
+ 47, 47, 47, 137, 137, 137, 137, 137,
+ 109
+};
+
+static const int indic_syllable_machine_start = 27;
+static const int indic_syllable_machine_first_final = 27;
+static const int indic_syllable_machine_error = -1;
+
+static const int indic_syllable_machine_en_main = 27;
+
+
+#line 58 "hb-ot-shaper-indic-machine.rl"
+
+
+
+#line 117 "hb-ot-shaper-indic-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+ for (unsigned int i = ts; i < te; i++) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+inline void
+find_syllables_indic (hb_buffer_t *buffer)
+{
+ unsigned int p, pe, eof, ts, te, act;
+ int cs;
+ hb_glyph_info_t *info = buffer->info;
+
+#line 426 "hb-ot-shaper-indic-machine.hh"
+ {
+ cs = indic_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 137 "hb-ot-shaper-indic-machine.rl"
+
+
+ p = 0;
+ pe = eof = buffer->len;
+
+ unsigned int syllable_serial = 1;
+
+#line 442 "hb-ot-shaper-indic-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const unsigned char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _indic_syllable_machine_from_state_actions[cs] ) {
+ case 10:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 456 "hb-ot-shaper-indic-machine.hh"
+ }
+
+ _keys = _indic_syllable_machine_trans_keys + (cs<<1);
+ _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs];
+
+ _slen = _indic_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) &&
+ ( info[p].indic_category()) <= _keys[1] ?
+ ( info[p].indic_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _indic_syllable_machine_trans_targs[_trans];
+
+ if ( _indic_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _indic_syllable_machine_trans_actions[_trans] ) {
+ case 2:
+#line 1 "NONE"
+ {te = p+1;}
+ break;
+ case 11:
+#line 113 "hb-ot-shaper-indic-machine.rl"
+ {te = p+1;{ found_syllable (indic_non_indic_cluster); }}
+ break;
+ case 13:
+#line 108 "hb-ot-shaper-indic-machine.rl"
+ {te = p;p--;{ found_syllable (indic_consonant_syllable); }}
+ break;
+ case 14:
+#line 109 "hb-ot-shaper-indic-machine.rl"
+ {te = p;p--;{ found_syllable (indic_vowel_syllable); }}
+ break;
+ case 17:
+#line 110 "hb-ot-shaper-indic-machine.rl"
+ {te = p;p--;{ found_syllable (indic_standalone_cluster); }}
+ break;
+ case 19:
+#line 111 "hb-ot-shaper-indic-machine.rl"
+ {te = p;p--;{ found_syllable (indic_symbol_cluster); }}
+ break;
+ case 15:
+#line 112 "hb-ot-shaper-indic-machine.rl"
+ {te = p;p--;{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+ break;
+ case 16:
+#line 113 "hb-ot-shaper-indic-machine.rl"
+ {te = p;p--;{ found_syllable (indic_non_indic_cluster); }}
+ break;
+ case 1:
+#line 108 "hb-ot-shaper-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }}
+ break;
+ case 3:
+#line 109 "hb-ot-shaper-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }}
+ break;
+ case 7:
+#line 110 "hb-ot-shaper-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }}
+ break;
+ case 8:
+#line 111 "hb-ot-shaper-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }}
+ break;
+ case 4:
+#line 112 "hb-ot-shaper-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+ break;
+ case 6:
+#line 1 "NONE"
+ { switch( act ) {
+ case 1:
+ {{p = ((te))-1;} found_syllable (indic_consonant_syllable); }
+ break;
+ case 5:
+ {{p = ((te))-1;} found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }
+ break;
+ case 6:
+ {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); }
+ break;
+ }
+ }
+ break;
+ case 18:
+#line 1 "NONE"
+ {te = p+1;}
+#line 108 "hb-ot-shaper-indic-machine.rl"
+ {act = 1;}
+ break;
+ case 5:
+#line 1 "NONE"
+ {te = p+1;}
+#line 112 "hb-ot-shaper-indic-machine.rl"
+ {act = 5;}
+ break;
+ case 12:
+#line 1 "NONE"
+ {te = p+1;}
+#line 113 "hb-ot-shaper-indic-machine.rl"
+ {act = 6;}
+ break;
+#line 559 "hb-ot-shaper-indic-machine.hh"
+ }
+
+_again:
+ switch ( _indic_syllable_machine_to_state_actions[cs] ) {
+ case 9:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 568 "hb-ot-shaper-indic-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _indic_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _indic_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 145 "hb-ot-shaper-indic-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPER_INDIC_MACHINE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc
new file mode 100644
index 0000000000..8994f3ca59
--- /dev/null
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc
@@ -0,0 +1,560 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
+ *
+ * on files with these headers:
+ *
+ * # IndicSyllabicCategory-14.0.0.txt
+ * # Date: 2021-05-22, 01:01:00 GMT [KW, RP]
+ * # IndicPositionalCategory-14.0.0.txt
+ * # Date: 2021-05-22, 01:01:00 GMT [KW, RP]
+ * # Blocks-14.0.0.txt
+ * # Date: 2021-01-22, 23:29:00 GMT [KW]
+ */
+
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
+#include "hb-ot-shaper-indic.hh"
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-macros"
+
+#include "hb-ot-shaper-indic-machine.hh"
+#include "hb-ot-shaper-khmer-machine.hh"
+#include "hb-ot-shaper-myanmar-machine.hh"
+
+/* indic */
+#define OT_X I_Cat(X)
+#define OT_C I_Cat(C)
+#define OT_V I_Cat(V)
+#define OT_N I_Cat(N)
+#define OT_H I_Cat(H)
+#define OT_ZWNJ I_Cat(ZWNJ)
+#define OT_ZWJ I_Cat(ZWJ)
+#define OT_M I_Cat(M)
+#define OT_SM I_Cat(SM)
+#define OT_A I_Cat(A)
+#define OT_VD I_Cat(VD)
+#define OT_PLACEHOLDER I_Cat(PLACEHOLDER)
+#define OT_DOTTEDCIRCLE I_Cat(DOTTEDCIRCLE)
+#define OT_RS I_Cat(RS)
+#define OT_Repha I_Cat(Repha)
+#define OT_Ra I_Cat(Ra)
+#define OT_CM I_Cat(CM)
+#define OT_Symbol I_Cat(Symbol)
+#define OT_CS I_Cat(CS)
+/* khmer */
+#define OT_VAbv K_Cat(VAbv)
+#define OT_VBlw K_Cat(VBlw)
+#define OT_VPre K_Cat(VPre)
+#define OT_VPst K_Cat(VPst)
+#define OT_Robatic K_Cat(Robatic)
+#define OT_Xgroup K_Cat(Xgroup)
+#define OT_Ygroup K_Cat(Ygroup)
+/* myanmar */
+static_assert (OT_VAbv == M_Cat(VAbv), "");
+static_assert (OT_VBlw == M_Cat(VBlw), "");
+static_assert (OT_VPre == M_Cat(VPre), "");
+static_assert (OT_VPst == M_Cat(VPst), "");
+#define OT_IV M_Cat(IV)
+#define OT_As M_Cat(As)
+#define OT_DB M_Cat(DB)
+#define OT_GB M_Cat(GB)
+#define OT_MH M_Cat(MH)
+#define OT_MR M_Cat(MR)
+#define OT_MW M_Cat(MW)
+#define OT_MY M_Cat(MY)
+#define OT_PT M_Cat(PT)
+#define OT_VS M_Cat(VS)
+#define OT_ML M_Cat(ML)
+
+
+#define _OT_A OT_A /* 53 chars; A */
+#define _OT_As OT_As /* 1 chars; As */
+#define _OT_C OT_C /* 478 chars; C */
+#define _OT_CM OT_CM /* 1 chars; CM */
+#define _OT_CS OT_CS /* 2 chars; CS */
+#define _OT_DC OT_DOTTEDCIRCLE /* 1 chars; DOTTEDCIRCLE */
+#define _OT_H OT_H /* 11 chars; H */
+#define _OT_M OT_M /* 143 chars; M */
+#define _OT_MH OT_MH /* 1 chars; MH */
+#define _OT_ML OT_ML /* 1 chars; ML */
+#define _OT_MR OT_MR /* 1 chars; MR */
+#define _OT_MW OT_MW /* 2 chars; MW */
+#define _OT_MY OT_MY /* 3 chars; MY */
+#define _OT_N OT_N /* 17 chars; N */
+#define _OT_GB OT_PLACEHOLDER /* 165 chars; PLACEHOLDER */
+#define _OT_PT OT_PT /* 8 chars; PT */
+#define _OT_R OT_Ra /* 14 chars; Ra */
+#define _OT_Rf OT_Repha /* 1 chars; Repha */
+#define _OT_Rt OT_Robatic /* 3 chars; Robatic */
+#define _OT_SM OT_SM /* 55 chars; SM */
+#define _OT_S OT_Symbol /* 22 chars; Symbol */
+#define _OT_V OT_V /* 172 chars; V */
+#define _OT_VA OT_VAbv /* 18 chars; VAbv */
+#define _OT_VB OT_VBlw /* 7 chars; VBlw */
+#define _OT_VL OT_VPre /* 5 chars; VPre */
+#define _OT_VR OT_VPst /* 13 chars; VPst */
+#define _OT_VS OT_VS /* 16 chars; VS */
+#define _OT_X OT_X /* 2 chars; X */
+#define _OT_Xg OT_Xgroup /* 7 chars; Xgroup */
+#define _OT_Yg OT_Ygroup /* 4 chars; Ygroup */
+#define _OT_ZWJ OT_ZWJ /* 1 chars; ZWJ */
+#define _OT_ZWNJ OT_ZWNJ /* 1 chars; ZWNJ */
+
+#define _POS_T POS_ABOVE_C /* 22 chars; ABOVE_C */
+#define _POS_A POS_AFTER_MAIN /* 3 chars; AFTER_MAIN */
+#define _POS_AP POS_AFTER_POST /* 50 chars; AFTER_POST */
+#define _POS_AS POS_AFTER_SUB /* 51 chars; AFTER_SUB */
+#define _POS_C POS_BASE_C /* 833 chars; BASE_C */
+#define _POS_BS POS_BEFORE_SUB /* 25 chars; BEFORE_SUB */
+#define _POS_B POS_BELOW_C /* 13 chars; BELOW_C */
+#define _POS_X POS_END /* 71 chars; END */
+#define _POS_R POS_POST_C /* 13 chars; POST_C */
+#define _POS_L POS_PRE_C /* 5 chars; PRE_C */
+#define _POS_LM POS_PRE_M /* 14 chars; PRE_M */
+#define _POS_SM POS_SMVD /* 129 chars; SMVD */
+
+#pragma GCC diagnostic pop
+
+#define INDIC_COMBINE_CATEGORIES(S,M) ((S) | ((M) << 8))
+
+#define _(S,M) INDIC_COMBINE_CATEGORIES (_OT_##S, _POS_##M)
+
+
+static const uint16_t indic_table[] = {
+
+
+#define indic_offset_0x0028u 0
+
+
+ /* Basic Latin */
+
+ /* 0028 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(X,X), _(X,X),
+ /* 0030 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 0038 */ _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+#define indic_offset_0x00b0u 24
+
+
+ /* Latin-1 Supplement */
+
+ /* 00B0 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 00B8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 00C0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 00C8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 00D0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C),
+
+#define indic_offset_0x0900u 64
+
+
+ /* Devanagari */
+
+ /* 0900 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(V,C), _(V,C), _(V,C), _(V,C),
+ /* 0908 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
+ /* 0910 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
+ /* 0918 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0920 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0928 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0930 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0938 */ _(C,C), _(C,C), _(M,AS), _(M,AS), _(N,X), _(S,SM), _(M,AS), _(M,LM),
+ /* 0940 */ _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS),
+ /* 0948 */ _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(H,B), _(M,LM), _(M,AS),
+ /* 0950 */ _(X,X), _(A,SM), _(A,SM),_(SM,SM),_(SM,SM), _(M,AS), _(M,AS), _(M,AS),
+ /* 0958 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0960 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C),
+ /* 0968 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 0970 */ _(X,X), _(X,X), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
+ /* 0978 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+
+ /* Bengali */
+
+ /* 0980 */ _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
+ /* 0988 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(V,C),
+ /* 0990 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
+ /* 0998 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 09A0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 09A8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 09B0 */ _(R,C), _(X,X), _(C,C), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C),
+ /* 09B8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,LM),
+ /* 09C0 */ _(M,AP), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(X,X), _(X,X), _(M,LM),
+ /* 09C8 */ _(M,LM), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(C,C), _(X,X),
+ /* 09D0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP),
+ /* 09D8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C),
+ /* 09E0 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C),
+ /* 09E8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 09F0 */ _(R,C), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 09F8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(X,X),_(SM,SM), _(X,X),
+
+ /* Gurmukhi */
+
+ /* 0A00 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
+ /* 0A08 */ _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C),
+ /* 0A10 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
+ /* 0A18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0A20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0A28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0A30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(X,X),
+ /* 0A38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(X,X), _(M,AP), _(M,LM),
+ /* 0A40 */ _(M,AP), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP),
+ /* 0A48 */ _(M,AP), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X),
+ /* 0A50 */ _(X,X), _(M,B), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0A58 */ _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X),
+ /* 0A60 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C),
+ /* 0A68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 0A70 */_(SM,SM),_(SM,SM), _(C,C), _(C,C), _(X,X), _(CM,C), _(X,X), _(X,X),
+ /* 0A78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+ /* Gujarati */
+
+ /* 0A80 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
+ /* 0A88 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C),
+ /* 0A90 */ _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
+ /* 0A98 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0AA0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0AA8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0AB0 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C),
+ /* 0AB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,LM),
+ /* 0AC0 */ _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AS), _(X,X), _(M,AS),
+ /* 0AC8 */ _(M,AS), _(M,AP), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X),
+ /* 0AD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0AD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0AE0 */ _(V,C), _(V,C), _(M,AP), _(M,AP), _(X,X), _(X,X), _(GB,C), _(GB,C),
+ /* 0AE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 0AF0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0AF8 */ _(X,X), _(C,C), _(A,SM), _(N,X), _(A,SM), _(N,X), _(N,X), _(N,X),
+
+ /* Oriya */
+
+ /* 0B00 */ _(X,X),_(SM,BS),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
+ /* 0B08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(V,C),
+ /* 0B10 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
+ /* 0B18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0B20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0B28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0B30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C),
+ /* 0B38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,A),
+ /* 0B40 */ _(M,AP), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(X,X), _(X,X), _(M,LM),
+ /* 0B48 */ _(M,A), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X),
+ /* 0B50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(N,X), _(M,A), _(M,AP),
+ /* 0B58 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C),
+ /* 0B60 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C),
+ /* 0B68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 0B70 */ _(X,X), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0B78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+ /* Tamil */
+
+ /* 0B80 */ _(X,X), _(X,X),_(SM,SM), _(X,X), _(X,X), _(V,C), _(V,C), _(V,C),
+ /* 0B88 */ _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(X,X), _(V,C), _(V,C),
+ /* 0B90 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(X,X), _(X,X),
+ /* 0B98 */ _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X), _(C,C), _(C,C),
+ /* 0BA0 */ _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(X,X), _(X,X),
+ /* 0BA8 */ _(C,C), _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C),
+ /* 0BB0 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0BB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), _(M,AP),
+ /* 0BC0 */ _(M,AS), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(M,LM), _(M,LM),
+ /* 0BC8 */ _(M,LM), _(X,X), _(M,AP), _(M,AP), _(M,AP), _(H,T), _(X,X), _(X,X),
+ /* 0BD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP),
+ /* 0BD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0BE0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C),
+ /* 0BE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 0BF0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0BF8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+ /* Telugu */
+
+ /* 0C00 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(V,C), _(V,C), _(V,C),
+ /* 0C08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C),
+ /* 0C10 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
+ /* 0C18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0C20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0C28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0C30 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0C38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,BS), _(M,BS),
+ /* 0C40 */ _(M,BS), _(M,BS), _(M,BS), _(M,AS), _(M,AS), _(X,X), _(M,BS), _(M,BS),
+ /* 0C48 */ _(M,BS), _(X,X), _(M,BS), _(M,BS), _(M,BS), _(H,T), _(X,X), _(X,X),
+ /* 0C50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,BS), _(M,BS), _(X,X),
+ /* 0C58 */ _(C,C), _(C,C), _(C,C), _(X,X), _(X,X), _(C,C), _(X,X), _(X,X),
+ /* 0C60 */ _(V,C), _(V,C), _(M,BS), _(M,BS), _(X,X), _(X,X), _(GB,C), _(GB,C),
+ /* 0C68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 0C70 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0C78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+ /* Kannada */
+
+ /* 0C80 */ _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
+ /* 0C88 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C),
+ /* 0C90 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
+ /* 0C98 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0CA0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0CA8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0CB0 */ _(R,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C),
+ /* 0CB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,BS), _(M,BS),
+ /* 0CC0 */ _(M,BS), _(M,BS), _(M,BS), _(M,AS), _(M,AS), _(X,X), _(M,BS), _(M,AS),
+ /* 0CC8 */ _(M,AS), _(X,X), _(M,AS), _(M,AS), _(M,BS), _(H,T), _(X,X), _(X,X),
+ /* 0CD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AS), _(M,AS), _(X,X),
+ /* 0CD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X),
+ /* 0CE0 */ _(V,C), _(V,C), _(M,BS), _(M,BS), _(X,X), _(X,X), _(GB,C), _(GB,C),
+ /* 0CE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 0CF0 */ _(X,X), _(CS,C), _(CS,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0CF8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+ /* Malayalam */
+
+ /* 0D00 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(GB,C), _(V,C), _(V,C), _(V,C),
+ /* 0D08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C),
+ /* 0D10 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
+ /* 0D18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0D20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0D28 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0D30 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 0D38 */ _(C,C), _(C,C), _(C,C), _(M,AS), _(M,AS), _(S,SM), _(M,AP), _(M,AP),
+ /* 0D40 */ _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(X,X), _(M,LM), _(M,LM),
+ /* 0D48 */ _(M,LM), _(X,X), _(M,AP), _(M,AP), _(M,AP), _(H,T), _(Rf,X), _(X,X),
+ /* 0D50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(C,C), _(M,AP),
+ /* 0D58 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C),
+ /* 0D60 */ _(V,C), _(V,C), _(M,AP), _(M,AP), _(X,X), _(X,X), _(GB,C), _(GB,C),
+ /* 0D68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 0D70 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 0D78 */ _(X,X), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+
+#define indic_offset_0x1000u 1216
+
+
+ /* Myanmar */
+
+ /* 1000 */ _(C,C), _(C,C), _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C),
+ /* 1008 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 1010 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 1018 */ _(C,C), _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 1020 */ _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
+ /* 1028 */ _(V,C), _(V,C), _(V,C), _(VR,R), _(VR,R), _(VA,T), _(VA,T), _(VB,B),
+ /* 1030 */ _(VB,B), _(VL,L), _(A,SM), _(VA,T), _(VA,T), _(VA,T), _(A,SM), _(N,X),
+ /* 1038 */_(SM,SM), _(H,X), _(As,X), _(MY,X), _(MR,X), _(MW,X), _(MH,X), _(C,C),
+ /* 1040 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 1048 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X), _(C,C), _(X,X),
+ /* 1050 */ _(C,C), _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(VR,R), _(VR,R),
+ /* 1058 */ _(VB,B), _(VB,B), _(R,C), _(C,C), _(C,C), _(C,C), _(MY,X), _(MY,X),
+ /* 1060 */ _(ML,X), _(C,C), _(VR,R), _(PT,X), _(PT,X), _(C,C), _(C,C), _(VR,R),
+ /* 1068 */ _(VR,R), _(PT,X), _(PT,X), _(PT,X), _(PT,X), _(PT,X), _(C,C), _(C,C),
+ /* 1070 */ _(C,C), _(VA,T), _(VA,T), _(VA,T), _(VA,T), _(C,C), _(C,C), _(C,C),
+ /* 1078 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 1080 */ _(C,C), _(C,C), _(MW,X), _(VR,R), _(VL,L), _(VA,T), _(VA,T),_(SM,SM),
+ /* 1088 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(C,C),_(SM,SM),
+ /* 1090 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 1098 */ _(GB,C), _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(VA,T), _(X,X), _(X,X),
+
+#define indic_offset_0x1780u 1376
+
+
+ /* Khmer */
+
+ /* 1780 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 1788 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 1790 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 1798 */ _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* 17A0 */ _(C,C), _(C,C), _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
+ /* 17A8 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
+ /* 17B0 */ _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(VR,R), _(VA,T),
+ /* 17B8 */ _(VA,T), _(VA,T), _(VA,T), _(VB,B), _(VB,B), _(VB,B), _(VA,T), _(VR,R),
+ /* 17C0 */ _(VR,R), _(VL,L), _(VL,L), _(VL,L), _(VR,R), _(VR,R), _(Xg,X), _(Yg,X),
+ /* 17C8 */ _(Yg,X), _(Rt,X), _(Rt,X), _(Xg,X), _(Rt,X), _(Xg,X), _(Xg,X), _(Xg,X),
+ /* 17D0 */ _(Xg,X), _(Xg,X), _(H,X), _(Yg,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 17D8 */ _(X,X), _(GB,C), _(X,X), _(X,X), _(S,SM), _(Yg,X), _(X,X), _(X,X),
+ /* 17E0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* 17E8 */ _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+#define indic_offset_0x1cd0u 1488
+
+
+ /* Vedic Extensions */
+
+ /* 1CD0 */ _(A,SM), _(A,SM), _(A,SM), _(X,X), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
+ /* 1CD8 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
+ /* 1CE0 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
+ /* 1CE8 */ _(A,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(A,SM), _(S,SM), _(S,SM),
+ /* 1CF0 */ _(S,SM), _(S,SM), _(C,C), _(C,C), _(A,SM), _(C,C), _(C,C), _(A,SM),
+ /* 1CF8 */ _(A,SM), _(A,SM), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+#define indic_offset_0x2008u 1536
+
+
+ /* General Punctuation */
+
+ /* 2008 */ _(X,X), _(X,X), _(X,X), _(X,X),_(ZWNJ,X),_(ZWJ,X), _(X,X), _(X,X),
+ /* 2010 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X),
+ /* 2018 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 2020 */ _(X,X), _(X,X), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+#define indic_offset_0x2070u 1568
+
+
+ /* Superscripts and Subscripts */
+
+ /* 2070 */ _(X,X), _(X,X), _(X,X), _(X,X),_(SM,SM), _(X,X), _(X,X), _(X,X),
+ /* 2078 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 2080 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X),
+
+#define indic_offset_0x25f8u 1592
+
+
+ /* Geometric Shapes */
+
+ /* 25F8 */ _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X),
+
+#define indic_offset_0xa8e0u 1600
+
+
+ /* Devanagari Extended */
+
+ /* A8E0 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
+ /* A8E8 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
+ /* A8F0 */ _(A,SM), _(A,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM),
+ /* A8F8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C), _(M,AS),
+
+#define indic_offset_0xa9e0u 1632
+
+
+ /* Myanmar Extended-B */
+
+ /* A9E0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(VA,T), _(X,X), _(C,C),
+ /* A9E8 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* A9F0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
+ /* A9F8 */ _(GB,C), _(GB,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X),
+
+#define indic_offset_0xaa60u 1664
+
+
+ /* Myanmar Extended-A */
+
+ /* AA60 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* AA68 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
+ /* AA70 */ _(X,X), _(C,C), _(C,C), _(C,C), _(GB,C), _(GB,C), _(GB,C), _(X,X),
+ /* AA78 */ _(X,X), _(X,X), _(C,C), _(PT,X), _(N,X), _(N,X), _(C,C), _(C,C),
+
+#define indic_offset_0xfe00u 1696
+
+
+ /* Variation Selectors */
+
+ /* FE00 */ _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X),
+ /* FE08 */ _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X),
+
+#define indic_offset_0x11300u 1712
+
+
+ /* Grantha */
+
+ /* 11300 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 11308 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 11310 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 11318 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 11320 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 11328 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 11330 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+ /* 11338 */ _(X,X), _(X,X), _(X,X), _(N,X), _(N,X), _(X,X), _(X,X), _(X,X),
+
+}; /* Table items: 1776; occupancy: 69% */
+
+uint16_t
+hb_indic_get_categories (hb_codepoint_t u)
+{
+ switch (u >> 12)
+ {
+ case 0x0u:
+ if (unlikely (u == 0x00A0u)) return _(GB,C);
+ if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0D7Fu)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
+ break;
+
+ case 0x1u:
+ if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1780u, 0x17EFu)) return indic_table[u - 0x1780u + indic_offset_0x1780u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
+ break;
+
+ case 0x2u:
+ if (unlikely (u == 0x25CCu)) return _(DC,C);
+ if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2027u)) return indic_table[u - 0x2008u + indic_offset_0x2008u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x25F8u, 0x25FFu)) return indic_table[u - 0x25F8u + indic_offset_0x25f8u];
+ break;
+
+ case 0xAu:
+ if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8FFu)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u];
+ break;
+
+ case 0xFu:
+ if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return indic_table[u - 0xFE00u + indic_offset_0xfe00u];
+ break;
+
+ case 0x11u:
+ if (hb_in_range<hb_codepoint_t> (u, 0x11300u, 0x1133Fu)) return indic_table[u - 0x11300u + indic_offset_0x11300u];
+ break;
+
+ default:
+ break;
+ }
+ return _(X,X);
+}
+
+#undef _
+#undef INDIC_COMBINE_CATEGORIES
+
+#undef _OT_A
+#undef _OT_As
+#undef _OT_C
+#undef _OT_CM
+#undef _OT_CS
+#undef _OT_DC
+#undef _OT_H
+#undef _OT_M
+#undef _OT_MH
+#undef _OT_ML
+#undef _OT_MR
+#undef _OT_MW
+#undef _OT_MY
+#undef _OT_N
+#undef _OT_GB
+#undef _OT_PT
+#undef _OT_R
+#undef _OT_Rf
+#undef _OT_Rt
+#undef _OT_SM
+#undef _OT_S
+#undef _OT_V
+#undef _OT_VA
+#undef _OT_VB
+#undef _OT_VL
+#undef _OT_VR
+#undef _OT_VS
+#undef _OT_X
+#undef _OT_Xg
+#undef _OT_Yg
+#undef _OT_ZWJ
+#undef _OT_ZWNJ
+
+#undef _POS_T
+#undef _POS_A
+#undef _POS_AP
+#undef _POS_AS
+#undef _POS_C
+#undef _POS_BS
+#undef _POS_B
+#undef _POS_X
+#undef _POS_R
+#undef _POS_L
+#undef _POS_LM
+#undef _POS_SM
+
+#endif
+
+/* == End of generated table == */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc
index c80f7df6a9..48a3c74463 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc
@@ -28,9 +28,9 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex-indic.hh"
-#include "hb-ot-shape-complex-indic-machine.hh"
-#include "hb-ot-shape-complex-vowel-constraints.hh"
+#include "hb-ot-shaper-indic.hh"
+#include "hb-ot-shaper-indic-machine.hh"
+#include "hb-ot-shaper-vowel-constraints.hh"
#include "hb-ot-layout.hh"
@@ -39,6 +39,81 @@
*/
+static inline void
+set_indic_properties (hb_glyph_info_t &info)
+{
+ hb_codepoint_t u = info.codepoint;
+ unsigned int type = hb_indic_get_categories (u);
+
+ info.indic_category() = (indic_category_t) (type & 0xFFu);
+ info.indic_position() = (indic_position_t) (type >> 8);
+}
+
+
+static inline bool
+is_one_of (const hb_glyph_info_t &info, unsigned int flags)
+{
+ /* If it ligated, all bets are off. */
+ if (_hb_glyph_info_ligated (&info)) return false;
+ return !!(FLAG_UNSAFE (info.indic_category()) & flags);
+}
+
+/* Note:
+ *
+ * We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
+ * cannot happen in a consonant syllable. The plus side however is, we can call the
+ * consonant syllable logic from the vowel syllable function and get it all right!
+ *
+ * Keep in sync with consonant_categories in the generator. */
+#define CONSONANT_FLAGS_INDIC (FLAG (I_Cat(C)) | FLAG (I_Cat(CS)) | FLAG (I_Cat(Ra)) | FLAG (I_Cat(CM)) | FLAG (I_Cat(V)) | FLAG (I_Cat(PLACEHOLDER)) | FLAG (I_Cat(DOTTEDCIRCLE)))
+
+static inline bool
+is_consonant (const hb_glyph_info_t &info)
+{
+ return is_one_of (info, CONSONANT_FLAGS_INDIC);
+}
+
+#define JOINER_FLAGS (FLAG (I_Cat(ZWJ)) | FLAG (I_Cat(ZWNJ)))
+
+static inline bool
+is_joiner (const hb_glyph_info_t &info)
+{
+ return is_one_of (info, JOINER_FLAGS);
+}
+
+static inline bool
+is_halant (const hb_glyph_info_t &info)
+{
+ return is_one_of (info, FLAG (I_Cat(H)));
+}
+
+struct hb_indic_would_substitute_feature_t
+{
+ void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
+ {
+ zero_context = zero_context_;
+ map->get_stage_lookups (0/*GSUB*/,
+ map->get_feature_stage (0/*GSUB*/, feature_tag),
+ &lookups, &count);
+ }
+
+ bool would_substitute (const hb_codepoint_t *glyphs,
+ unsigned int glyphs_count,
+ hb_face_t *face) const
+ {
+ for (unsigned int i = 0; i < count; i++)
+ if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
+ return true;
+ return false;
+ }
+
+ private:
+ const hb_ot_map_t::lookup_map_t *lookups;
+ unsigned int count;
+ bool zero_context;
+};
+
+
/*
* Indic configurations. Note that we do not want to keep every single script-specific
* behavior in these tables necessarily. This should mainly be used for per-script
@@ -47,10 +122,6 @@
* instead of adding a new flag in these structs.
*/
-enum base_position_t {
- BASE_POS_LAST_SINHALA,
- BASE_POS_LAST
-};
enum reph_position_t {
REPH_POS_AFTER_MAIN = POS_AFTER_MAIN,
REPH_POS_BEFORE_SUB = POS_BEFORE_SUB,
@@ -72,7 +143,6 @@ struct indic_config_t
hb_script_t script;
bool has_old_spec;
hb_codepoint_t virama;
- base_position_t base_pos;
reph_position_t reph_pos;
reph_mode_t reph_mode;
blwf_mode_t blwf_mode;
@@ -81,26 +151,19 @@ struct indic_config_t
static const indic_config_t indic_configs[] =
{
/* Default. Should be first. */
- {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_DEVANAGARI,true, 0x094Du,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_BENGALI, true, 0x09CDu,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_GURMUKHI, true, 0x0A4Du,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_GUJARATI, true, 0x0ACDu,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_ORIYA, true, 0x0B4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_TAMIL, true, 0x0BCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_TELUGU, true, 0x0C4Du,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY},
- {HB_SCRIPT_KANNADA, true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY},
- {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_SINHALA, false,0x0DCAu,BASE_POS_LAST_SINHALA,
- REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_INVALID, false, 0,REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_DEVANAGARI,true, 0x094Du,REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_BENGALI, true, 0x09CDu,REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_GURMUKHI, true, 0x0A4Du,REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_GUJARATI, true, 0x0ACDu,REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_ORIYA, true, 0x0B4Du,REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_TAMIL, true, 0x0BCDu,REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_TELUGU, true, 0x0C4Du,REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY},
+ {HB_SCRIPT_KANNADA, true, 0x0CCDu,REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY},
+ {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
};
-
-/*
- * Indic shaper.
- */
-
static const hb_ot_map_feature_t
indic_features[] =
{
@@ -207,6 +270,7 @@ static void
override_features_indic (hb_ot_shape_planner_t *plan)
{
plan->map.disable_feature (HB_TAG('l','i','g','a'));
+ plan->map.add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var
}
@@ -356,6 +420,7 @@ setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
+ HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
find_syllables_indic (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
@@ -367,7 +432,7 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
int a = pa->indic_position();
int b = pb->indic_position();
- return a < b ? -1 : a == b ? 0 : +1;
+ return (int) a - (int) b;
}
@@ -379,9 +444,6 @@ update_consonant_positions_indic (const hb_ot_shape_plan_t *plan,
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
- if (indic_plan->config->base_pos != BASE_POS_LAST)
- return;
-
hb_codepoint_t virama;
if (indic_plan->load_virama_glyph (font, &virama))
{
@@ -416,9 +478,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
*/
if (buffer->props.script == HB_SCRIPT_KANNADA &&
start + 3 <= end &&
- is_one_of (info[start ], FLAG (OT_Ra)) &&
- is_one_of (info[start+1], FLAG (OT_H)) &&
- is_one_of (info[start+2], FLAG (OT_ZWJ)))
+ is_one_of (info[start ], FLAG (I_Cat(Ra))) &&
+ is_one_of (info[start+1], FLAG (I_Cat(H))) &&
+ is_one_of (info[start+2], FLAG (I_Cat(ZWJ))))
{
buffer->merge_clusters (start+1, start+3);
hb_glyph_info_t tmp = info[start+1];
@@ -452,7 +514,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
start + 3 <= end &&
(
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
- (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ)
+ (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == I_Cat(ZWJ))
))
{
/* See if it matches the 'rphf' feature. */
@@ -470,7 +532,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
base = start;
has_reph = true;
}
- } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == OT_Repha)
+ } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == I_Cat(Repha))
{
limit += 1;
while (limit < end && is_joiner (info[limit]))
@@ -479,84 +541,51 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
has_reph = true;
}
- switch (indic_plan->config->base_pos)
{
- case BASE_POS_LAST:
- {
- /* -> starting from the end of the syllable, move backwards */
- unsigned int i = end;
- bool seen_below = false;
- do {
- i--;
- /* -> until a consonant is found */
- if (is_consonant (info[i]))
+ /* -> starting from the end of the syllable, move backwards */
+ unsigned int i = end;
+ bool seen_below = false;
+ do {
+ i--;
+ /* -> until a consonant is found */
+ if (is_consonant (info[i]))
+ {
+ /* -> that does not have a below-base or post-base form
+ * (post-base forms have to follow below-base forms), */
+ if (info[i].indic_position() != POS_BELOW_C &&
+ (info[i].indic_position() != POS_POST_C || seen_below))
{
- /* -> that does not have a below-base or post-base form
- * (post-base forms have to follow below-base forms), */
- if (info[i].indic_position() != POS_BELOW_C &&
- (info[i].indic_position() != POS_POST_C || seen_below))
- {
- base = i;
- break;
- }
- if (info[i].indic_position() == POS_BELOW_C)
- seen_below = true;
-
- /* -> or that is not a pre-base-reordering Ra,
- *
- * IMPLEMENTATION NOTES:
- *
- * Our pre-base-reordering Ra's are marked POS_POST_C, so will be skipped
- * by the logic above already.
- */
-
- /* -> or arrive at the first consonant. The consonant stopped at will
- * be the base. */
base = i;
+ break;
}
- else
- {
- /* A ZWJ after a Halant stops the base search, and requests an explicit
- * half form.
- * A ZWJ before a Halant, requests a subjoined form instead, and hence
- * search continues. This is particularly important for Bengali
- * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
- if (start < i &&
- info[i].indic_category() == OT_ZWJ &&
- info[i - 1].indic_category() == OT_H)
- break;
- }
- } while (i > limit);
- }
- break;
-
- case BASE_POS_LAST_SINHALA:
- {
- /* Sinhala base positioning is slightly different from main Indic, in that:
- * 1. Its ZWJ behavior is different,
- * 2. We don't need to look into the font for consonant positions.
- */
-
- if (!has_reph)
- base = limit;
+ if (info[i].indic_position() == POS_BELOW_C)
+ seen_below = true;
- /* Find the last base consonant that is not blocked by ZWJ. If there is
- * a ZWJ right before a base consonant, that would request a subjoined form. */
- for (unsigned int i = limit; i < end; i++)
- if (is_consonant (info[i]))
- {
- if (limit < i && info[i - 1].indic_category() == OT_ZWJ)
- break;
- else
- base = i;
- }
+ /* -> or that is not a pre-base-reordering Ra,
+ *
+ * IMPLEMENTATION NOTES:
+ *
+ * Our pre-base-reordering Ra's are marked POS_POST_C, so will be skipped
+ * by the logic above already.
+ */
- /* Mark all subsequent consonants as below. */
- for (unsigned int i = base + 1; i < end; i++)
- if (is_consonant (info[i]))
- info[i].indic_position() = POS_BELOW_C;
- }
- break;
+ /* -> or arrive at the first consonant. The consonant stopped at will
+ * be the base. */
+ base = i;
+ }
+ else
+ {
+ /* A ZWJ after a Halant stops the base search, and requests an explicit
+ * half form.
+ * A ZWJ before a Halant, requests a subjoined form instead, and hence
+ * search continues. This is particularly important for Bengali
+ * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
+ if (start < i &&
+ info[i].indic_category() == I_Cat(ZWJ) &&
+ info[i - 1].indic_category() == I_Cat(H))
+ break;
+ }
+ } while (i > limit);
}
/* -> If the syllable starts with Ra + Halant (in a script that has Reph)
@@ -611,18 +640,6 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (base < end)
info[base].indic_position() = POS_BASE_C;
- /* Mark final consonants. A final consonant is one appearing after a matra.
- * Happens in Sinhala. */
- for (unsigned int i = base + 1; i < end; i++)
- if (info[i].indic_category() == OT_M) {
- for (unsigned int j = i + 1; j < end; j++)
- if (is_consonant (info[j])) {
- info[j].indic_position() = POS_FINAL_C;
- break;
- }
- break;
- }
-
/* Handle beginning Ra */
if (has_reph)
info[start].indic_position() = POS_RA_TO_BECOME_REPH;
@@ -659,14 +676,14 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
{
bool disallow_double_halants = buffer->props.script == HB_SCRIPT_KANNADA;
for (unsigned int i = base + 1; i < end; i++)
- if (info[i].indic_category() == OT_H)
+ if (info[i].indic_category() == I_Cat(H))
{
unsigned int j;
for (j = end - 1; j > i; j--)
if (is_consonant (info[j]) ||
- (disallow_double_halants && info[j].indic_category() == OT_H))
+ (disallow_double_halants && info[j].indic_category() == I_Cat(H)))
break;
- if (info[j].indic_category() != OT_H && j > i) {
+ if (info[j].indic_category() != I_Cat(H) && j > i) {
/* Move Halant to after last consonant. */
hb_glyph_info_t t = info[i];
memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0]));
@@ -681,20 +698,16 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
indic_position_t last_pos = POS_START;
for (unsigned int i = start; i < end; i++)
{
- if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_H))))
+ if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (I_Cat(N)) | FLAG (I_Cat(RS)) | FLAG (I_Cat(CM)) | FLAG (I_Cat(H)))))
{
info[i].indic_position() = last_pos;
- if (unlikely (info[i].indic_category() == OT_H &&
+ if (unlikely (info[i].indic_category() == I_Cat(H) &&
info[i].indic_position() == POS_PRE_M))
{
/*
* Uniscribe doesn't move the Halant with Left Matra.
- * TEST: U+092B,U+093F,U+094DE
- * We follow. This is important for the Sinhala
- * U+0DDA split matra since it decomposes to U+0DD9,U+0DCA
- * where U+0DD9 is a left matra and U+0DCA is the virama.
- * We don't want to move the virama with the left matra.
- * TEST: U+0D9A,U+0DDA
+ * TEST: U+092B,U+093F,U+094D
+ * We follow.
*/
for (unsigned int j = i; j > start; j--)
if (info[j - 1].indic_position() != POS_PRE_M) {
@@ -718,7 +731,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (info[j].indic_position() < POS_SMVD)
info[j].indic_position() = info[i].indic_position();
last = i;
- } else if (info[i].indic_category() == OT_M)
+ } else if (info[i].indic_category() == I_Cat(M))
last = i;
}
@@ -849,10 +862,10 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915
*/
for (unsigned int i = start; i + 1 < base; i++)
- if (info[i ].indic_category() == OT_Ra &&
- info[i+1].indic_category() == OT_H &&
+ if (info[i ].indic_category() == I_Cat(Ra) &&
+ info[i+1].indic_category() == I_Cat(H) &&
(i + 2 == base ||
- info[i+2].indic_category() != OT_ZWJ))
+ info[i+2].indic_category() != I_Cat(ZWJ)))
{
info[i ].mask |= indic_plan->mask_array[INDIC_BLWF];
info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF];
@@ -879,7 +892,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Apply ZWJ/ZWNJ effects */
for (unsigned int i = start + 1; i < end; i++)
if (is_joiner (info[i])) {
- bool non_joiner = info[i].indic_category() == OT_ZWNJ;
+ bool non_joiner = info[i].indic_category() == I_Cat(ZWNJ);
unsigned int j = i;
do {
@@ -912,7 +925,7 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
/* For dotted-circle, this is what Uniscribe does:
* If dotted-circle is the last glyph, it just does nothing.
* Ie. It doesn't form Reph. */
- if (buffer->info[end - 1].indic_category() == OT_DOTTEDCIRCLE)
+ if (buffer->info[end - 1].indic_category() == I_Cat(DOTTEDCIRCLE))
return;
}
@@ -955,8 +968,8 @@ initial_reordering_indic (const hb_ot_shape_plan_t *plan,
update_consonant_positions_indic (plan, font, buffer);
hb_syllabic_insert_dotted_circles (font, buffer,
indic_broken_cluster,
- OT_DOTTEDCIRCLE,
- OT_Repha,
+ I_Cat(DOTTEDCIRCLE),
+ I_Cat(Repha),
POS_END);
foreach_syllable (buffer, start, end)
@@ -978,7 +991,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
* and possibly multiple substitutions happened prior to this
* phase, and that might have messed up our properties. Recover
* from a particular case of that where we're fairly sure that a
- * class of OT_H is desired but has been lost. */
+ * class of I_Cat(H) is desired but has been lost. */
/* We don't call load_virama_glyph(), since we know it's already
* loaded. */
hb_codepoint_t virama_glyph = indic_plan->virama_glyph.get_relaxed ();
@@ -990,7 +1003,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
_hb_glyph_info_multiplied (&info[i]))
{
/* This will make sure that this glyph passes is_halant() test. */
- info[i].indic_category() = OT_H;
+ info[i].indic_category() = I_Cat(H);
_hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
}
}
@@ -1056,11 +1069,11 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
break;
}
if (base == end && start < base &&
- is_one_of (info[base - 1], FLAG (OT_ZWJ)))
+ is_one_of (info[base - 1], FLAG (I_Cat(ZWJ))))
base--;
if (base < end)
while (start < base &&
- is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_H))))
+ is_one_of (info[base], (FLAG (I_Cat(N)) | FLAG (I_Cat(H)))))
base--;
@@ -1105,7 +1118,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
{
search:
while (new_pos > start &&
- !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H)))))
+ !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(H))))))
new_pos--;
/* If we found no Halant we are done.
@@ -1122,7 +1135,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
if (new_pos + 1 < end)
{
/* -> If ZWJ follows this halant, matra is NOT repositioned after this halant. */
- if (info[new_pos + 1].indic_category() == OT_ZWJ)
+ if (info[new_pos + 1].indic_category() == I_Cat(ZWJ))
{
/* Keep searching. */
if (new_pos > start)
@@ -1195,7 +1208,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
*/
if (start + 1 < end &&
info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
- ((info[start].indic_category() == OT_Repha) ^
+ ((info[start].indic_category() == I_Cat(Repha)) ^
_hb_glyph_info_ligated_and_didnt_multiply (&info[start])))
{
unsigned int new_reph_pos;
@@ -1305,7 +1318,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
unlikely (is_halant (info[new_reph_pos])))
{
for (unsigned int i = base + 1; i < new_reph_pos; i++)
- if (info[i].indic_category() == OT_M) {
+ if (info[i].indic_category() == I_Cat(M)) {
/* Ok, got it. */
new_reph_pos--;
}
@@ -1365,7 +1378,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
{
while (new_pos > start &&
- !(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_H))))
+ !(is_one_of (info[new_pos - 1], FLAG(I_Cat(M)) | FLAG (I_Cat(H)))))
new_pos--;
}
@@ -1414,11 +1427,10 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
switch ((hb_tag_t) plan->props.script)
{
case HB_SCRIPT_TAMIL:
- case HB_SCRIPT_SINHALA:
break;
default:
- /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.
+ /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil.
* This means, half forms are submerged into the main consonant's cluster.
* This is unnecessary, and makes cursor positioning harder, but that's what
* Uniscribe does. */
@@ -1453,7 +1465,9 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font)
{
- _hb_preprocess_text_vowel_constraints (plan, buffer, font);
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
+ if (!indic_plan->uniscribe_bug_compatible)
+ _hb_preprocess_text_vowel_constraints (plan, buffer, font);
}
static bool
@@ -1486,48 +1500,6 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
#endif
}
- if ((ab == 0x0DDAu || hb_in_range<hb_codepoint_t> (ab, 0x0DDCu, 0x0DDEu)))
- {
- /*
- * Sinhala split matras... Let the fun begin.
- *
- * These four characters have Unicode decompositions. However, Uniscribe
- * decomposes them "Khmer-style", that is, it uses the character itself to
- * get the second half. The first half of all four decompositions is always
- * U+0DD9.
- *
- * Now, there are buggy fonts, namely, the widely used lklug.ttf, that are
- * broken with Uniscribe. But we need to support them. As such, we only
- * do the Uniscribe-style decomposition if the character is transformed into
- * its "sec.half" form by the 'pstf' feature. Otherwise, we fall back to
- * Unicode decomposition.
- *
- * Note that we can't unconditionally use Unicode decomposition. That would
- * break some other fonts, that are designed to work with Uniscribe, and
- * don't have positioning features for the Unicode-style decomposition.
- *
- * Argh...
- *
- * The Uniscribe behavior is now documented in the newly published Sinhala
- * spec in 2012:
- *
- * https://docs.microsoft.com/en-us/typography/script-development/sinhala#shaping
- */
-
-
- const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
- hb_codepoint_t glyph;
- if (indic_plan->uniscribe_bug_compatible ||
- (c->font->get_nominal_glyph (ab, &glyph) &&
- indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
- {
- /* Ok, safe to use Uniscribe-style decomposition. */
- *a = 0x0DD9u;
- *b = ab;
- return true;
- }
- }
-
return (bool) c->unicode->decompose (ab, a, b);
}
@@ -1548,7 +1520,7 @@ compose_indic (const hb_ot_shape_normalize_context_t *c,
}
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
+const hb_ot_shaper_t _hb_ot_shaper_indic =
{
collect_features_indic,
override_features_indic,
diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.hh
new file mode 100644
index 0000000000..4f822c26e9
--- /dev/null
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.hh
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * 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
+ */
+
+#ifndef HB_OT_SHAPER_INDIC_HH
+#define HB_OT_SHAPER_INDIC_HH
+
+#include "hb.hh"
+
+#include "hb-ot-shaper-syllabic.hh"
+
+
+/* Visual positions in a syllable from left to right. */
+enum ot_position_t {
+ POS_START = 0,
+
+ POS_RA_TO_BECOME_REPH = 1,
+ POS_PRE_M = 2,
+ POS_PRE_C = 3,
+
+ POS_BASE_C = 4,
+ POS_AFTER_MAIN = 5,
+
+ POS_ABOVE_C = 6,
+
+ POS_BEFORE_SUB = 7,
+ POS_BELOW_C = 8,
+ POS_AFTER_SUB = 9,
+
+ POS_BEFORE_POST = 10,
+ POS_POST_C = 11,
+ POS_AFTER_POST = 12,
+
+ POS_SMVD = 13,
+
+ POS_END = 14
+};
+
+
+HB_INTERNAL uint16_t
+hb_indic_get_categories (hb_codepoint_t u);
+
+
+#endif /* HB_OT_SHAPER_INDIC_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh
new file mode 100644
index 0000000000..e18bd75ef1
--- /dev/null
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh
@@ -0,0 +1,428 @@
+
+#line 1 "hb-ot-shaper-khmer-machine.rl"
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * 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
+ */
+
+#ifndef HB_OT_SHAPER_KHMER_MACHINE_HH
+#define HB_OT_SHAPER_KHMER_MACHINE_HH
+
+#include "hb.hh"
+
+#include "hb-ot-layout.hh"
+#include "hb-ot-shaper-indic.hh"
+
+/* buffer var allocations */
+#define khmer_category() ot_shaper_var_u8_category() /* khmer_category_t */
+
+using khmer_category_t = unsigned;
+
+#define K_Cat(Cat) khmer_syllable_machine_ex_##Cat
+
+enum khmer_syllable_type_t {
+ khmer_consonant_syllable,
+ khmer_broken_cluster,
+ khmer_non_khmer_cluster,
+};
+
+
+#line 52 "hb-ot-shaper-khmer-machine.hh"
+#define khmer_syllable_machine_ex_C 1u
+#define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u
+#define khmer_syllable_machine_ex_H 4u
+#define khmer_syllable_machine_ex_PLACEHOLDER 10u
+#define khmer_syllable_machine_ex_Ra 15u
+#define khmer_syllable_machine_ex_Robatic 25u
+#define khmer_syllable_machine_ex_V 2u
+#define khmer_syllable_machine_ex_VAbv 20u
+#define khmer_syllable_machine_ex_VBlw 21u
+#define khmer_syllable_machine_ex_VPre 22u
+#define khmer_syllable_machine_ex_VPst 23u
+#define khmer_syllable_machine_ex_Xgroup 26u
+#define khmer_syllable_machine_ex_Ygroup 27u
+#define khmer_syllable_machine_ex_ZWJ 6u
+#define khmer_syllable_machine_ex_ZWNJ 5u
+
+
+#line 70 "hb-ot-shaper-khmer-machine.hh"
+static const unsigned char _khmer_syllable_machine_trans_keys[] = {
+ 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u,
+ 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u,
+ 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 27u, 4u, 27u, 1u, 15u,
+ 4u, 27u, 4u, 27u, 27u, 27u, 4u, 27u, 4u, 27u, 4u, 27u, 4u, 27u, 4u, 27u,
+ 4u, 27u, 1u, 15u, 4u, 27u, 4u, 27u, 27u, 27u, 4u, 27u, 4u, 27u, 4u, 27u,
+ 4u, 27u, 4u, 27u, 5u, 26u, 0
+};
+
+static const char _khmer_syllable_machine_key_spans[] = {
+ 22, 22, 15, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 15, 22, 22,
+ 22, 22, 22, 22, 22, 27, 24, 15,
+ 24, 24, 1, 24, 24, 24, 24, 24,
+ 24, 15, 24, 24, 1, 24, 24, 24,
+ 24, 24, 22
+};
+
+static const short _khmer_syllable_machine_index_offsets[] = {
+ 0, 23, 46, 62, 85, 108, 131, 154,
+ 177, 200, 223, 246, 269, 292, 308, 331,
+ 354, 377, 400, 423, 446, 469, 497, 522,
+ 538, 563, 588, 590, 615, 640, 665, 690,
+ 715, 740, 756, 781, 806, 808, 833, 858,
+ 883, 908, 933
+};
+
+static const char _khmer_syllable_machine_indicies[] = {
+ 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 3, 4, 0, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4, 0, 5, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 4, 0, 6, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 7, 7, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 0, 9, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 0, 0,
+ 10, 0, 9, 9, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 10,
+ 0, 11, 11, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 12, 0,
+ 11, 11, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 12, 0, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0,
+ 0, 0, 0, 13, 4, 0, 15, 15,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 16, 14, 14,
+ 14, 14, 17, 18, 14, 15, 15, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 18, 19, 20, 20, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 20, 14, 15, 15, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 16, 14, 14, 14, 14,
+ 14, 18, 14, 21, 21, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 16, 14, 22, 22, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 23,
+ 14, 24, 24, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 16, 14, 14, 14, 14, 14, 25, 14,
+ 24, 24, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 25, 14, 26,
+ 26, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 16, 14,
+ 14, 14, 14, 14, 27, 14, 26, 26,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 27, 14, 29, 29, 28,
+ 30, 31, 31, 28, 28, 28, 13, 13,
+ 28, 28, 28, 29, 28, 28, 28, 28,
+ 16, 25, 27, 23, 28, 17, 18, 20,
+ 28, 33, 34, 34, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 2, 10, 12, 8, 32, 13, 4,
+ 5, 32, 35, 35, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 35, 32, 33, 36, 36, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 2, 10, 12, 8, 32, 3,
+ 4, 5, 32, 37, 38, 38, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 2, 10, 12, 8, 32,
+ 32, 4, 5, 32, 5, 32, 37, 6,
+ 6, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 8, 32, 32, 2, 5, 32, 37,
+ 7, 7, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 8, 5, 32,
+ 37, 39, 39, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 2, 32, 32, 8, 32, 32, 10, 5,
+ 32, 37, 40, 40, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 2, 10, 32, 8, 32, 32, 12,
+ 5, 32, 33, 38, 38, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 2, 10, 12, 8, 32, 32,
+ 4, 5, 32, 33, 38, 38, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 2, 10, 12, 8, 32,
+ 3, 4, 5, 32, 42, 42, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 42, 41, 30, 43, 43, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 16, 25, 27, 23,
+ 41, 17, 18, 20, 41, 44, 45, 45,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 16, 25, 27,
+ 23, 41, 41, 18, 20, 41, 20, 41,
+ 44, 21, 21, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 23, 41, 41, 16, 20,
+ 41, 44, 22, 22, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 23,
+ 20, 41, 44, 46, 46, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 16, 41, 41, 23, 41, 41,
+ 25, 20, 41, 44, 47, 47, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 16, 25, 41, 23, 41,
+ 41, 27, 20, 41, 30, 45, 45, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 16, 25, 27, 23,
+ 41, 41, 18, 20, 41, 15, 15, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 16, 48, 48, 48,
+ 48, 48, 18, 48, 0
+};
+
+static const char _khmer_syllable_machine_trans_targs[] = {
+ 21, 1, 27, 31, 25, 26, 4, 5,
+ 28, 7, 29, 9, 30, 32, 21, 12,
+ 37, 41, 35, 21, 36, 15, 16, 38,
+ 18, 39, 20, 40, 21, 22, 33, 42,
+ 21, 23, 10, 24, 0, 2, 3, 6,
+ 8, 21, 34, 11, 13, 14, 17, 19,
+ 21
+};
+
+static const char _khmer_syllable_machine_trans_actions[] = {
+ 1, 0, 2, 2, 2, 0, 0, 0,
+ 2, 0, 2, 0, 2, 2, 3, 0,
+ 2, 4, 4, 5, 0, 0, 0, 2,
+ 0, 2, 0, 2, 8, 2, 0, 9,
+ 10, 0, 0, 2, 0, 0, 0, 0,
+ 0, 11, 4, 0, 0, 0, 0, 0,
+ 12
+};
+
+static const char _khmer_syllable_machine_to_state_actions[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+static const char _khmer_syllable_machine_from_state_actions[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+static const short _khmer_syllable_machine_eof_trans[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 15, 20, 15, 15, 15,
+ 15, 15, 15, 15, 15, 0, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 49
+};
+
+static const int khmer_syllable_machine_start = 21;
+static const int khmer_syllable_machine_first_final = 21;
+static const int khmer_syllable_machine_error = -1;
+
+static const int khmer_syllable_machine_en_main = 21;
+
+
+#line 53 "hb-ot-shaper-khmer-machine.rl"
+
+
+
+#line 102 "hb-ot-shaper-khmer-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+ for (unsigned int i = ts; i < te; i++) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+inline void
+find_syllables_khmer (hb_buffer_t *buffer)
+{
+ unsigned int p, pe, eof, ts, te, act HB_UNUSED;
+ int cs;
+ hb_glyph_info_t *info = buffer->info;
+
+#line 298 "hb-ot-shaper-khmer-machine.hh"
+ {
+ cs = khmer_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 122 "hb-ot-shaper-khmer-machine.rl"
+
+
+ p = 0;
+ pe = eof = buffer->len;
+
+ unsigned int syllable_serial = 1;
+
+#line 314 "hb-ot-shaper-khmer-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _khmer_syllable_machine_from_state_actions[cs] ) {
+ case 7:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 328 "hb-ot-shaper-khmer-machine.hh"
+ }
+
+ _keys = _khmer_syllable_machine_trans_keys + (cs<<1);
+ _inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs];
+
+ _slen = _khmer_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) &&
+ ( info[p].khmer_category()) <= _keys[1] ?
+ ( info[p].khmer_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _khmer_syllable_machine_trans_targs[_trans];
+
+ if ( _khmer_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _khmer_syllable_machine_trans_actions[_trans] ) {
+ case 2:
+#line 1 "NONE"
+ {te = p+1;}
+ break;
+ case 8:
+#line 98 "hb-ot-shaper-khmer-machine.rl"
+ {te = p+1;{ found_syllable (khmer_non_khmer_cluster); }}
+ break;
+ case 10:
+#line 96 "hb-ot-shaper-khmer-machine.rl"
+ {te = p;p--;{ found_syllable (khmer_consonant_syllable); }}
+ break;
+ case 11:
+#line 97 "hb-ot-shaper-khmer-machine.rl"
+ {te = p;p--;{ found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+ break;
+ case 12:
+#line 98 "hb-ot-shaper-khmer-machine.rl"
+ {te = p;p--;{ found_syllable (khmer_non_khmer_cluster); }}
+ break;
+ case 1:
+#line 96 "hb-ot-shaper-khmer-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (khmer_consonant_syllable); }}
+ break;
+ case 3:
+#line 97 "hb-ot-shaper-khmer-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+ break;
+ case 5:
+#line 1 "NONE"
+ { switch( act ) {
+ case 2:
+ {{p = ((te))-1;} found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }
+ break;
+ case 3:
+ {{p = ((te))-1;} found_syllable (khmer_non_khmer_cluster); }
+ break;
+ }
+ }
+ break;
+ case 4:
+#line 1 "NONE"
+ {te = p+1;}
+#line 97 "hb-ot-shaper-khmer-machine.rl"
+ {act = 2;}
+ break;
+ case 9:
+#line 1 "NONE"
+ {te = p+1;}
+#line 98 "hb-ot-shaper-khmer-machine.rl"
+ {act = 3;}
+ break;
+#line 398 "hb-ot-shaper-khmer-machine.hh"
+ }
+
+_again:
+ switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
+ case 6:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 407 "hb-ot-shaper-khmer-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _khmer_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 130 "hb-ot-shaper-khmer-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPER_KHMER_MACHINE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc
index a7d5bf574b..e04d633195 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc
@@ -28,8 +28,8 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex-khmer.hh"
-#include "hb-ot-shape-complex-khmer-machine.hh"
+#include "hb-ot-shaper-khmer-machine.hh"
+#include "hb-ot-shaper-indic.hh"
#include "hb-ot-layout.hh"
@@ -37,6 +37,7 @@
* Khmer shaper.
*/
+
static const hb_ot_map_feature_t
khmer_features[] =
{
@@ -79,6 +80,15 @@ enum {
KHMER_BASIC_FEATURES = _KHMER_PRES, /* Don't forget to update this! */
};
+static inline void
+set_khmer_properties (hb_glyph_info_t &info)
+{
+ hb_codepoint_t u = info.codepoint;
+ unsigned int type = hb_indic_get_categories (u);
+
+ info.khmer_category() = (khmer_category_t) (type & 0xFFu);
+}
+
static void
setup_syllables_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
@@ -115,7 +125,7 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
map->add_feature (khmer_features[i]);
/* https://github.com/harfbuzz/harfbuzz/issues/3531 */
- map->add_gsub_pause (nullptr);
+ map->add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var
for (; i < KHMER_NUM_FEATURES; i++)
map->add_feature (khmer_features[i]);
@@ -187,6 +197,7 @@ setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
+ HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
find_syllables_khmer (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
@@ -230,11 +241,11 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
* the 'pref' OpenType feature applied to them.
* """
*/
- if (info[i].khmer_category() == OT_Coeng && num_coengs <= 2 && i + 1 < end)
+ if (info[i].khmer_category() == K_Cat(H) && num_coengs <= 2 && i + 1 < end)
{
num_coengs++;
- if (info[i + 1].khmer_category() == OT_Ra)
+ if (info[i + 1].khmer_category() == K_Cat(Ra))
{
for (unsigned int j = 0; j < 2; j++)
info[i + j].mask |= khmer_plan->mask_array[KHMER_PREF];
@@ -262,7 +273,7 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
/* Reorder left matra piece. */
- else if (info[i].khmer_category() == OT_VPre)
+ else if (info[i].khmer_category() == K_Cat(VPre))
{
/* Move to the start. */
buffer->merge_clusters (start, i + 1);
@@ -301,8 +312,8 @@ reorder_khmer (const hb_ot_shape_plan_t *plan,
{
hb_syllabic_insert_dotted_circles (font, buffer,
khmer_broken_cluster,
- OT_DOTTEDCIRCLE,
- OT_Repha);
+ K_Cat(DOTTEDCIRCLE),
+ (unsigned) -1);
foreach_syllable (buffer, start, end)
reorder_syllable_khmer (plan, font->face, buffer, start, end);
@@ -349,7 +360,7 @@ compose_khmer (const hb_ot_shape_normalize_context_t *c,
}
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_khmer =
+const hb_ot_shaper_t _hb_ot_shaper_khmer =
{
collect_features_khmer,
override_features_khmer,
diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh
new file mode 100644
index 0000000000..b109708937
--- /dev/null
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh
@@ -0,0 +1,553 @@
+
+#line 1 "hb-ot-shaper-myanmar-machine.rl"
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * 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
+ */
+
+#ifndef HB_OT_SHAPER_MYANMAR_MACHINE_HH
+#define HB_OT_SHAPER_MYANMAR_MACHINE_HH
+
+#include "hb.hh"
+
+#include "hb-ot-layout.hh"
+#include "hb-ot-shaper-indic.hh"
+
+/* buffer var allocations */
+#define myanmar_category() ot_shaper_var_u8_category() /* myanmar_category_t */
+#define myanmar_position() ot_shaper_var_u8_auxiliary() /* myanmar_position_t */
+
+using myanmar_category_t = unsigned;
+using myanmar_position_t = ot_position_t;
+
+#define M_Cat(Cat) myanmar_syllable_machine_ex_##Cat
+
+enum myanmar_syllable_type_t {
+ myanmar_consonant_syllable,
+ myanmar_broken_cluster,
+ myanmar_non_myanmar_cluster,
+};
+
+
+#line 54 "hb-ot-shaper-myanmar-machine.hh"
+#define myanmar_syllable_machine_ex_A 9u
+#define myanmar_syllable_machine_ex_As 32u
+#define myanmar_syllable_machine_ex_C 1u
+#define myanmar_syllable_machine_ex_CS 18u
+#define myanmar_syllable_machine_ex_DB 3u
+#define myanmar_syllable_machine_ex_DOTTEDCIRCLE 11u
+#define myanmar_syllable_machine_ex_GB 10u
+#define myanmar_syllable_machine_ex_H 4u
+#define myanmar_syllable_machine_ex_IV 2u
+#define myanmar_syllable_machine_ex_MH 35u
+#define myanmar_syllable_machine_ex_ML 41u
+#define myanmar_syllable_machine_ex_MR 36u
+#define myanmar_syllable_machine_ex_MW 37u
+#define myanmar_syllable_machine_ex_MY 38u
+#define myanmar_syllable_machine_ex_PT 39u
+#define myanmar_syllable_machine_ex_Ra 15u
+#define myanmar_syllable_machine_ex_SM 8u
+#define myanmar_syllable_machine_ex_VAbv 20u
+#define myanmar_syllable_machine_ex_VBlw 21u
+#define myanmar_syllable_machine_ex_VPre 22u
+#define myanmar_syllable_machine_ex_VPst 23u
+#define myanmar_syllable_machine_ex_VS 40u
+#define myanmar_syllable_machine_ex_ZWJ 6u
+#define myanmar_syllable_machine_ex_ZWNJ 5u
+
+
+#line 81 "hb-ot-shaper-myanmar-machine.hh"
+static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
+ 1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u,
+ 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u,
+ 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 41u,
+ 3u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u,
+ 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 41u, 3u, 39u,
+ 3u, 39u, 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u,
+ 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 1u, 41u, 1u, 15u, 0
+};
+
+static const char _myanmar_syllable_machine_key_spans[] = {
+ 41, 39, 35, 4, 39, 37, 37, 35,
+ 35, 37, 37, 39, 35, 15, 37, 37,
+ 38, 37, 39, 39, 37, 39, 39, 39,
+ 39, 39, 35, 4, 39, 37, 37, 35,
+ 35, 37, 37, 39, 35, 15, 39, 37,
+ 37, 38, 37, 39, 39, 37, 39, 39,
+ 39, 39, 39, 39, 39, 41, 15
+};
+
+static const short _myanmar_syllable_machine_index_offsets[] = {
+ 0, 42, 82, 118, 123, 163, 201, 239,
+ 275, 311, 349, 387, 427, 463, 479, 517,
+ 555, 594, 632, 672, 712, 750, 790, 830,
+ 870, 910, 950, 986, 991, 1031, 1069, 1107,
+ 1143, 1179, 1217, 1255, 1295, 1331, 1347, 1387,
+ 1425, 1463, 1502, 1540, 1580, 1620, 1658, 1698,
+ 1738, 1778, 1818, 1858, 1898, 1938, 1980
+};
+
+static const char _myanmar_syllable_machine_indicies[] = {
+ 1, 1, 2, 3, 4, 4, 0, 5,
+ 6, 1, 1, 0, 0, 0, 7, 0,
+ 0, 8, 0, 9, 10, 11, 12, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13,
+ 0, 0, 14, 15, 16, 17, 18, 19,
+ 20, 0, 22, 23, 24, 24, 21, 25,
+ 26, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 27, 28, 29, 30, 21,
+ 21, 21, 21, 21, 21, 21, 21, 31,
+ 21, 21, 32, 33, 34, 35, 36, 37,
+ 38, 21, 24, 24, 21, 25, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 30, 21, 21, 21,
+ 21, 21, 21, 21, 21, 39, 21, 21,
+ 21, 21, 21, 21, 36, 21, 24, 24,
+ 21, 25, 21, 22, 21, 24, 24, 21,
+ 25, 26, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 40, 21, 21, 30,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 41, 21, 21, 42, 21, 21, 21, 36,
+ 21, 41, 21, 22, 21, 24, 24, 21,
+ 25, 26, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 30,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 36,
+ 21, 43, 21, 24, 24, 21, 25, 36,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 44, 21,
+ 21, 21, 21, 21, 21, 36, 21, 24,
+ 24, 21, 25, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 44, 21, 21, 21, 21, 21,
+ 21, 36, 21, 24, 24, 21, 25, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 36, 21, 22,
+ 21, 24, 24, 21, 25, 26, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 40, 21, 21, 30, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 36, 21, 22, 21, 24,
+ 24, 21, 25, 26, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 40, 21,
+ 21, 30, 21, 21, 21, 21, 21, 21,
+ 21, 21, 41, 21, 21, 21, 21, 21,
+ 21, 36, 21, 22, 21, 24, 24, 21,
+ 25, 26, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 40, 21, 21, 30,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 41, 21, 21, 21, 21, 21, 21, 36,
+ 21, 41, 21, 24, 24, 21, 25, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 30, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 36, 21, 1,
+ 1, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 1, 21, 22,
+ 21, 24, 24, 21, 25, 26, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 27, 28, 21, 30, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 36, 21, 22, 21, 24,
+ 24, 21, 25, 26, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 28,
+ 21, 30, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 36, 21, 22, 21, 24, 24, 21,
+ 25, 26, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 27, 28, 29, 30,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 36,
+ 45, 21, 22, 21, 24, 24, 21, 25,
+ 26, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 27, 28, 29, 30, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 36, 21,
+ 22, 21, 24, 24, 21, 25, 26, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 27, 28, 29, 30, 21, 21, 21,
+ 21, 21, 21, 21, 21, 31, 21, 21,
+ 32, 33, 34, 35, 36, 21, 38, 21,
+ 22, 21, 24, 24, 21, 25, 26, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 27, 28, 29, 30, 21, 21, 21,
+ 21, 21, 21, 21, 21, 45, 21, 21,
+ 21, 21, 21, 21, 36, 21, 38, 21,
+ 22, 21, 24, 24, 21, 25, 26, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 27, 28, 29, 30, 21, 21, 21,
+ 21, 21, 21, 21, 21, 45, 21, 21,
+ 21, 21, 21, 21, 36, 21, 22, 21,
+ 24, 24, 21, 25, 26, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 27,
+ 28, 29, 30, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 32, 21,
+ 34, 21, 36, 21, 38, 21, 22, 21,
+ 24, 24, 21, 25, 26, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 27,
+ 28, 29, 30, 21, 21, 21, 21, 21,
+ 21, 21, 21, 45, 21, 21, 32, 21,
+ 21, 21, 36, 21, 38, 21, 22, 21,
+ 24, 24, 21, 25, 26, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 27,
+ 28, 29, 30, 21, 21, 21, 21, 21,
+ 21, 21, 21, 46, 21, 21, 32, 33,
+ 34, 21, 36, 21, 38, 21, 22, 21,
+ 24, 24, 21, 25, 26, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 27,
+ 28, 29, 30, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 32, 33,
+ 34, 21, 36, 21, 38, 21, 22, 23,
+ 24, 24, 21, 25, 26, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 27,
+ 28, 29, 30, 21, 21, 21, 21, 21,
+ 21, 21, 21, 31, 21, 21, 32, 33,
+ 34, 35, 36, 21, 38, 21, 48, 48,
+ 47, 5, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 12, 47, 47, 47, 47, 47, 47, 47,
+ 47, 49, 47, 47, 47, 47, 47, 47,
+ 18, 47, 48, 48, 47, 5, 47, 2,
+ 47, 48, 48, 47, 5, 6, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 50, 47, 47, 12, 47, 47, 47, 47,
+ 47, 47, 47, 47, 51, 47, 47, 52,
+ 47, 47, 47, 18, 47, 51, 47, 2,
+ 47, 48, 48, 47, 5, 6, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 12, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 18, 47, 53, 47, 48,
+ 48, 47, 5, 18, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 54, 47, 47, 47, 47, 47,
+ 47, 18, 47, 48, 48, 47, 5, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 54, 47,
+ 47, 47, 47, 47, 47, 18, 47, 48,
+ 48, 47, 5, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 18, 47, 2, 47, 48, 48, 47,
+ 5, 6, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 50, 47, 47, 12,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 18,
+ 47, 2, 47, 48, 48, 47, 5, 6,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 50, 47, 47, 12, 47, 47,
+ 47, 47, 47, 47, 47, 47, 51, 47,
+ 47, 47, 47, 47, 47, 18, 47, 2,
+ 47, 48, 48, 47, 5, 6, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 50, 47, 47, 12, 47, 47, 47, 47,
+ 47, 47, 47, 47, 51, 47, 47, 47,
+ 47, 47, 47, 18, 47, 51, 47, 48,
+ 48, 47, 5, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 12, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 18, 47, 55, 55, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 55, 47, 2, 3, 48, 48, 47,
+ 5, 6, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 9, 10, 11, 12,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 13, 47, 47, 14, 15, 16, 17, 18,
+ 19, 20, 47, 2, 47, 48, 48, 47,
+ 5, 6, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 9, 10, 47, 12,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 18,
+ 47, 2, 47, 48, 48, 47, 5, 6,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 10, 47, 12, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 18, 47, 2,
+ 47, 48, 48, 47, 5, 6, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 9, 10, 11, 12, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 18, 56, 47, 2, 47,
+ 48, 48, 47, 5, 6, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 9,
+ 10, 11, 12, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 18, 47, 2, 47, 48, 48,
+ 47, 5, 6, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 9, 10, 11,
+ 12, 47, 47, 47, 47, 47, 47, 47,
+ 47, 13, 47, 47, 14, 15, 16, 17,
+ 18, 47, 20, 47, 2, 47, 48, 48,
+ 47, 5, 6, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 9, 10, 11,
+ 12, 47, 47, 47, 47, 47, 47, 47,
+ 47, 56, 47, 47, 47, 47, 47, 47,
+ 18, 47, 20, 47, 2, 47, 48, 48,
+ 47, 5, 6, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 9, 10, 11,
+ 12, 47, 47, 47, 47, 47, 47, 47,
+ 47, 56, 47, 47, 47, 47, 47, 47,
+ 18, 47, 2, 47, 48, 48, 47, 5,
+ 6, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 9, 10, 11, 12, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 14, 47, 16, 47, 18, 47,
+ 20, 47, 2, 47, 48, 48, 47, 5,
+ 6, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 9, 10, 11, 12, 47,
+ 47, 47, 47, 47, 47, 47, 47, 56,
+ 47, 47, 14, 47, 47, 47, 18, 47,
+ 20, 47, 2, 47, 48, 48, 47, 5,
+ 6, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 9, 10, 11, 12, 47,
+ 47, 47, 47, 47, 47, 47, 47, 57,
+ 47, 47, 14, 15, 16, 47, 18, 47,
+ 20, 47, 2, 47, 48, 48, 47, 5,
+ 6, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 9, 10, 11, 12, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 14, 15, 16, 47, 18, 47,
+ 20, 47, 2, 3, 48, 48, 47, 5,
+ 6, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 9, 10, 11, 12, 47,
+ 47, 47, 47, 47, 47, 47, 47, 13,
+ 47, 47, 14, 15, 16, 17, 18, 47,
+ 20, 47, 22, 23, 24, 24, 21, 25,
+ 26, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 27, 28, 29, 30, 21,
+ 21, 21, 21, 21, 21, 21, 21, 58,
+ 21, 21, 32, 33, 34, 35, 36, 37,
+ 38, 21, 22, 59, 24, 24, 21, 25,
+ 26, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 27, 28, 29, 30, 21,
+ 21, 21, 21, 21, 21, 21, 21, 31,
+ 21, 21, 32, 33, 34, 35, 36, 21,
+ 38, 21, 1, 1, 2, 3, 48, 48,
+ 47, 5, 6, 1, 1, 47, 47, 47,
+ 1, 47, 47, 47, 47, 9, 10, 11,
+ 12, 47, 47, 47, 47, 47, 47, 47,
+ 47, 13, 47, 47, 14, 15, 16, 17,
+ 18, 19, 20, 47, 1, 1, 60, 60,
+ 60, 60, 60, 60, 60, 1, 1, 60,
+ 60, 60, 1, 60, 0
+};
+
+static const char _myanmar_syllable_machine_trans_targs[] = {
+ 0, 1, 26, 37, 0, 27, 29, 51,
+ 54, 39, 40, 41, 28, 43, 44, 46,
+ 47, 48, 30, 50, 45, 0, 2, 13,
+ 0, 3, 5, 14, 15, 16, 4, 18,
+ 19, 21, 22, 23, 6, 25, 20, 12,
+ 9, 10, 11, 7, 8, 17, 24, 0,
+ 0, 36, 33, 34, 35, 31, 32, 38,
+ 42, 49, 52, 53, 0
+};
+
+static const char _myanmar_syllable_machine_trans_actions[] = {
+ 3, 0, 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7,
+ 8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 9
+};
+
+static const char _myanmar_syllable_machine_to_state_actions[] = {
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static const char _myanmar_syllable_machine_from_state_actions[] = {
+ 2, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static const short _myanmar_syllable_machine_eof_trans[] = {
+ 0, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 22, 22, 48, 61
+};
+
+static const int myanmar_syllable_machine_start = 0;
+static const int myanmar_syllable_machine_first_final = 0;
+static const int myanmar_syllable_machine_error = -1;
+
+static const int myanmar_syllable_machine_en_main = 0;
+
+
+#line 55 "hb-ot-shaper-myanmar-machine.rl"
+
+
+
+#line 117 "hb-ot-shaper-myanmar-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+ for (unsigned int i = ts; i < te; i++) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+inline void
+find_syllables_myanmar (hb_buffer_t *buffer)
+{
+ unsigned int p, pe, eof, ts, te, act HB_UNUSED;
+ int cs;
+ hb_glyph_info_t *info = buffer->info;
+
+#line 447 "hb-ot-shaper-myanmar-machine.hh"
+ {
+ cs = myanmar_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 137 "hb-ot-shaper-myanmar-machine.rl"
+
+
+ p = 0;
+ pe = eof = buffer->len;
+
+ unsigned int syllable_serial = 1;
+
+#line 463 "hb-ot-shaper-myanmar-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
+ case 2:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 477 "hb-ot-shaper-myanmar-machine.hh"
+ }
+
+ _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
+ _inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
+
+ _slen = _myanmar_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
+ ( info[p].myanmar_category()) <= _keys[1] ?
+ ( info[p].myanmar_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _myanmar_syllable_machine_trans_targs[_trans];
+
+ if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
+ case 6:
+#line 110 "hb-ot-shaper-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (myanmar_consonant_syllable); }}
+ break;
+ case 4:
+#line 111 "hb-ot-shaper-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
+ break;
+ case 8:
+#line 112 "hb-ot-shaper-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+ break;
+ case 3:
+#line 113 "hb-ot-shaper-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
+ break;
+ case 5:
+#line 110 "hb-ot-shaper-myanmar-machine.rl"
+ {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }}
+ break;
+ case 7:
+#line 112 "hb-ot-shaper-myanmar-machine.rl"
+ {te = p;p--;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+ break;
+ case 9:
+#line 113 "hb-ot-shaper-myanmar-machine.rl"
+ {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
+ break;
+#line 523 "hb-ot-shaper-myanmar-machine.hh"
+ }
+
+_again:
+ switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
+ case 1:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 532 "hb-ot-shaper-myanmar-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 145 "hb-ot-shaper-myanmar-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPER_MYANMAR_MACHINE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc
index 13beaf4d4c..1ccafbca7e 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc
@@ -28,14 +28,16 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex-myanmar.hh"
-#include "hb-ot-shape-complex-myanmar-machine.hh"
+#include "hb-ot-shaper-myanmar-machine.hh"
+#include "hb-ot-shaper-indic.hh"
+#include "hb-ot-layout.hh"
/*
* Myanmar shaper.
*/
+
static const hb_tag_t
myanmar_basic_features[] =
{
@@ -62,6 +64,40 @@ myanmar_other_features[] =
HB_TAG('p','s','t','s'),
};
+static inline void
+set_myanmar_properties (hb_glyph_info_t &info)
+{
+ hb_codepoint_t u = info.codepoint;
+ unsigned int type = hb_indic_get_categories (u);
+
+ info.myanmar_category() = (myanmar_category_t) (type & 0xFFu);
+}
+
+
+static inline bool
+is_one_of_myanmar (const hb_glyph_info_t &info, unsigned int flags)
+{
+ /* If it ligated, all bets are off. */
+ if (_hb_glyph_info_ligated (&info)) return false;
+ return !!(FLAG_UNSAFE (info.myanmar_category()) & flags);
+}
+
+/* Note:
+ *
+ * We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
+ * cannot happen in a consonant syllable. The plus side however is, we can call the
+ * consonant syllable logic from the vowel syllable function and get it all right!
+ *
+ * Keep in sync with consonant_categories in the generator. */
+#define CONSONANT_FLAGS_MYANMAR (FLAG (M_Cat(C)) | FLAG (M_Cat(CS)) | FLAG (M_Cat(Ra)) | /* FLAG (M_Cat(CM)) | */ FLAG (M_Cat(IV)) | FLAG (M_Cat(GB)) | FLAG (M_Cat(DOTTEDCIRCLE)))
+
+static inline bool
+is_consonant_myanmar (const hb_glyph_info_t &info)
+{
+ return is_one_of_myanmar (info, CONSONANT_FLAGS_MYANMAR);
+}
+
+
static void
setup_syllables_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
@@ -92,6 +128,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
map->enable_feature (myanmar_basic_features[i], F_MANUAL_ZWJ | F_PER_SYLLABLE);
map->add_gsub_pause (nullptr);
}
+ map->add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var
for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_other_features); i++)
map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
@@ -118,6 +155,7 @@ setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
+ HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
find_syllables_myanmar (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
@@ -129,7 +167,7 @@ compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
int a = pa->myanmar_position();
int b = pb->myanmar_position();
- return a < b ? -1 : a == b ? 0 : +1;
+ return (int) a - (int) b;
}
@@ -148,9 +186,9 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
{
unsigned int limit = start;
if (start + 3 <= end &&
- info[start ].myanmar_category() == OT_Ra &&
- info[start+1].myanmar_category() == OT_As &&
- info[start+2].myanmar_category() == OT_H)
+ info[start ].myanmar_category() == M_Cat(Ra) &&
+ info[start+1].myanmar_category() == M_Cat(As) &&
+ info[start+2].myanmar_category() == M_Cat(H))
{
limit += 3;
base = start;
@@ -162,7 +200,7 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
base = limit;
for (unsigned int i = limit; i < end; i++)
- if (is_consonant (info[i]))
+ if (is_consonant_myanmar (info[i]))
{
base = i;
break;
@@ -187,39 +225,40 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
* Myanmar reordering! */
for (; i < end; i++)
{
- if (info[i].myanmar_category() == OT_MR) /* Pre-base reordering */
+ if (info[i].myanmar_category() == M_Cat(MR)) /* Pre-base reordering */
{
info[i].myanmar_position() = POS_PRE_C;
continue;
}
- if (info[i].myanmar_position() < POS_BASE_C) /* Left matra */
+ if (info[i].myanmar_category() == M_Cat(VPre)) /* Left matra */
{
+ info[i].myanmar_position() = POS_PRE_M;
continue;
}
- if (info[i].myanmar_category() == OT_VS)
+ if (info[i].myanmar_category() == M_Cat(VS))
{
info[i].myanmar_position() = info[i - 1].myanmar_position();
continue;
}
- if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == OT_VBlw)
+ if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == M_Cat(VBlw))
{
pos = POS_BELOW_C;
info[i].myanmar_position() = pos;
continue;
}
- if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_A)
+ if (pos == POS_BELOW_C && info[i].myanmar_category() == M_Cat(A))
{
info[i].myanmar_position() = POS_BEFORE_SUB;
continue;
}
- if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_VBlw)
+ if (pos == POS_BELOW_C && info[i].myanmar_category() == M_Cat(VBlw))
{
info[i].myanmar_position() = pos;
continue;
}
- if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A)
+ if (pos == POS_BELOW_C && info[i].myanmar_category() != M_Cat(A))
{
pos = POS_AFTER_SUB;
info[i].myanmar_position() = pos;
@@ -247,7 +286,6 @@ reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
initial_reordering_consonant_syllable (buffer, start, end);
break;
- case myanmar_punctuation_cluster:
case myanmar_non_myanmar_cluster:
break;
}
@@ -262,7 +300,7 @@ reorder_myanmar (const hb_ot_shape_plan_t *plan,
{
hb_syllabic_insert_dotted_circles (font, buffer,
myanmar_broken_cluster,
- OT_GB);
+ M_Cat(DOTTEDCIRCLE));
foreach_syllable (buffer, start, end)
reorder_syllable_myanmar (plan, font->face, buffer, start, end);
@@ -274,7 +312,7 @@ reorder_myanmar (const hb_ot_shape_plan_t *plan,
}
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
+const hb_ot_shaper_t _hb_ot_shaper_myanmar =
{
collect_features_myanmar,
nullptr, /* override_features */
@@ -296,7 +334,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
/* Ugly Zawgyi encoding.
* Disable all auto processing.
* https://github.com/harfbuzz/harfbuzz/issues/1162 */
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_zawgyi =
+const hb_ot_shaper_t _hb_ot_shaper_myanmar_zawgyi =
{
nullptr, /* collect_features */
nullptr, /* override_features */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc
index 76092c7f38..a8e0d8e8c1 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.cc
@@ -26,7 +26,7 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex-syllabic.hh"
+#include "hb-ot-shaper-syllabic.hh"
void
@@ -39,31 +39,18 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font,
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
-
- /* Note: This loop is extra overhead, but should not be measurable.
- * TODO Use a buffer scratch flag to remove the loop. */
- bool has_broken_syllables = false;
- unsigned int count = buffer->len;
- hb_glyph_info_t *info = buffer->info;
- for (unsigned int i = 0; i < count; i++)
- if ((info[i].syllable() & 0x0F) == broken_syllable_type)
- {
- has_broken_syllables = true;
- break;
- }
- if (likely (!has_broken_syllables))
+ if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE)))
return;
-
hb_codepoint_t dottedcircle_glyph;
if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
return;
hb_glyph_info_t dottedcircle = {0};
dottedcircle.codepoint = 0x25CCu;
- dottedcircle.complex_var_u8_category() = dottedcircle_category;
+ dottedcircle.ot_shaper_var_u8_category() = dottedcircle_category;
if (dottedcircle_position != -1)
- dottedcircle.complex_var_u8_auxiliary() = dottedcircle_position;
+ dottedcircle.ot_shaper_var_u8_auxiliary() = dottedcircle_position;
dottedcircle.codepoint = dottedcircle_glyph;
buffer->clear_output ();
@@ -87,7 +74,7 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font,
{
while (buffer->idx < buffer->len && buffer->successful &&
last_syllable == buffer->cur().syllable() &&
- buffer->cur().complex_var_u8_category() == (unsigned) repha_category)
+ buffer->cur().ot_shaper_var_u8_category() == (unsigned) repha_category)
(void) buffer->next_glyph ();
}
@@ -99,5 +86,13 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font,
buffer->sync ();
}
+HB_INTERNAL void
+hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
+}
+
#endif
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.hh
index b901a660d3..e8a15bb48a 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-syllabic.hh
@@ -22,12 +22,12 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
-#ifndef HB_OT_SHAPE_COMPLEX_SYLLABIC_HH
-#define HB_OT_SHAPE_COMPLEX_SYLLABIC_HH
+#ifndef HB_OT_SHAPER_SYLLABIC_HH
+#define HB_OT_SHAPER_SYLLABIC_HH
#include "hb.hh"
-#include "hb-ot-shape-complex.hh"
+#include "hb-ot-shaper.hh"
HB_INTERNAL void
@@ -38,5 +38,10 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font,
int repha_category = -1,
int dottedcircle_position = -1);
+HB_INTERNAL void
+hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
-#endif /* HB_OT_SHAPE_COMPLEX_SYLLABIC_HH */
+#endif /* HB_OT_SHAPER_SYLLABIC_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc
index a1e27a83be..1280e7ed17 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc
@@ -28,7 +28,7 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex.hh"
+#include "hb-ot-shaper.hh"
/* Thai / Lao shaper */
@@ -222,7 +222,7 @@ do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
hb_font_t *font)
{
-#ifdef HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
+#ifdef HB_NO_OT_SHAPER_THAI_FALLBACK
return;
#endif
@@ -279,7 +279,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
* to be what Uniscribe and other engines implement. According to Eric Muller:
*
* When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the
- * NIKHAHIT backwards over any tone mark (0E48-0E4B).
+ * NIKHAHIT backwards over any above-base marks.
*
* <0E14, 0E4B, 0E33> -> <0E14, 0E4D, 0E4B, 0E32>
*
@@ -308,8 +308,8 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
* Nikhahit: U+0E4D U+0ECD
*
* Testing shows that Uniscribe reorder the following marks:
- * Thai: <0E31,0E34..0E37,0E47..0E4E>
- * Lao: <0EB1,0EB4..0EB7,0EC7..0ECE>
+ * Thai: <0E31,0E34..0E37, 0E47..0E4E>
+ * Lao: <0EB1,0EB4..0EB7,0EBB,0EC8..0ECD>
*
* Note how the Lao versions are the same as Thai + 0x80.
*/
@@ -319,7 +319,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
#define IS_SARA_AM(x) (((x) & ~0x0080u) == 0x0E33u)
#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0x0E33u + 0x0E4Du)
#define SARA_AA_FROM_SARA_AM(x) ((x) - 1)
-#define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u))
+#define IS_ABOVE_BASE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u, 0x0E3Bu, 0x0E3Bu))
buffer->clear_output ();
unsigned int count = buffer->len;
@@ -343,7 +343,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
/* Ok, let's see... */
unsigned int start = end - 2;
- while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint))
+ while (start > 0 && IS_ABOVE_BASE_MARK (buffer->out_info[start - 1].codepoint))
start--;
if (start + 2 < end)
@@ -371,7 +371,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
do_thai_pua_shaping (plan, buffer, font);
}
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
+const hb_ot_shaper_t _hb_ot_shaper_thai =
{
nullptr, /* collect_features */
nullptr, /* override_features */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh
new file mode 100644
index 0000000000..65e65ff39d
--- /dev/null
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh
@@ -0,0 +1,931 @@
+
+#line 1 "hb-ot-shaper-use-machine.rl"
+/*
+ * Copyright © 2015 Mozilla Foundation.
+ * Copyright © 2015 Google, Inc.
+ *
+ * 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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPER_USE_MACHINE_HH
+#define HB_OT_SHAPER_USE_MACHINE_HH
+
+#include "hb.hh"
+
+#include "hb-ot-shaper-syllabic.hh"
+
+/* buffer var allocations */
+#define use_category() ot_shaper_var_u8_category()
+
+#define USE(Cat) use_syllable_machine_ex_##Cat
+
+enum use_syllable_type_t {
+ use_virama_terminated_cluster,
+ use_sakot_terminated_cluster,
+ use_standard_cluster,
+ use_number_joiner_terminated_cluster,
+ use_numeral_cluster,
+ use_symbol_cluster,
+ use_hieroglyph_cluster,
+ use_broken_cluster,
+ use_non_cluster,
+};
+
+
+#line 57 "hb-ot-shaper-use-machine.hh"
+#define use_syllable_machine_ex_B 1u
+#define use_syllable_machine_ex_CGJ 6u
+#define use_syllable_machine_ex_CMAbv 31u
+#define use_syllable_machine_ex_CMBlw 32u
+#define use_syllable_machine_ex_CS 43u
+#define use_syllable_machine_ex_FAbv 24u
+#define use_syllable_machine_ex_FBlw 25u
+#define use_syllable_machine_ex_FMAbv 45u
+#define use_syllable_machine_ex_FMBlw 46u
+#define use_syllable_machine_ex_FMPst 47u
+#define use_syllable_machine_ex_FPst 26u
+#define use_syllable_machine_ex_G 49u
+#define use_syllable_machine_ex_GB 5u
+#define use_syllable_machine_ex_H 12u
+#define use_syllable_machine_ex_HN 13u
+#define use_syllable_machine_ex_HVM 53u
+#define use_syllable_machine_ex_IS 44u
+#define use_syllable_machine_ex_J 50u
+#define use_syllable_machine_ex_MAbv 27u
+#define use_syllable_machine_ex_MBlw 28u
+#define use_syllable_machine_ex_MPre 30u
+#define use_syllable_machine_ex_MPst 29u
+#define use_syllable_machine_ex_N 4u
+#define use_syllable_machine_ex_O 0u
+#define use_syllable_machine_ex_R 18u
+#define use_syllable_machine_ex_SB 51u
+#define use_syllable_machine_ex_SE 52u
+#define use_syllable_machine_ex_SMAbv 41u
+#define use_syllable_machine_ex_SMBlw 42u
+#define use_syllable_machine_ex_SUB 11u
+#define use_syllable_machine_ex_Sk 48u
+#define use_syllable_machine_ex_VAbv 33u
+#define use_syllable_machine_ex_VBlw 34u
+#define use_syllable_machine_ex_VMAbv 37u
+#define use_syllable_machine_ex_VMBlw 38u
+#define use_syllable_machine_ex_VMPre 23u
+#define use_syllable_machine_ex_VMPst 39u
+#define use_syllable_machine_ex_VPre 22u
+#define use_syllable_machine_ex_VPst 35u
+#define use_syllable_machine_ex_WJ 16u
+#define use_syllable_machine_ex_ZWNJ 14u
+
+
+#line 101 "hb-ot-shaper-use-machine.hh"
+static const unsigned char _use_syllable_machine_trans_keys[] = {
+ 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u,
+ 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 53u,
+ 23u, 53u, 23u, 53u, 23u, 53u, 12u, 53u, 23u, 53u, 12u, 53u, 12u, 53u, 12u, 53u,
+ 11u, 53u, 1u, 1u, 1u, 48u, 11u, 53u, 41u, 42u, 42u, 42u, 11u, 53u, 11u, 53u,
+ 1u, 53u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u,
+ 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 53u, 23u, 53u, 23u, 53u, 23u, 53u,
+ 12u, 53u, 23u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 1u, 1u, 48u,
+ 13u, 13u, 4u, 4u, 11u, 53u, 11u, 53u, 1u, 53u, 23u, 48u, 24u, 47u, 25u, 47u,
+ 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u,
+ 22u, 53u, 23u, 53u, 23u, 53u, 23u, 53u, 12u, 53u, 23u, 53u, 12u, 53u, 12u, 53u,
+ 12u, 53u, 11u, 53u, 1u, 1u, 1u, 48u, 11u, 53u, 11u, 53u, 1u, 53u, 23u, 48u,
+ 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u,
+ 1u, 1u, 24u, 48u, 22u, 53u, 23u, 53u, 23u, 53u, 23u, 53u, 12u, 53u, 23u, 53u,
+ 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 1u, 1u, 48u, 4u, 4u, 13u, 13u,
+ 1u, 53u, 11u, 53u, 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u,
+ 0
+};
+
+static const char _use_syllable_machine_key_spans[] = {
+ 54, 43, 43, 53, 26, 24, 23, 22,
+ 2, 1, 25, 25, 25, 1, 25, 32,
+ 31, 31, 31, 42, 31, 42, 42, 42,
+ 43, 1, 48, 43, 2, 1, 43, 43,
+ 53, 26, 24, 23, 22, 2, 1, 25,
+ 25, 25, 1, 25, 32, 31, 31, 31,
+ 42, 31, 42, 42, 42, 43, 1, 48,
+ 1, 1, 43, 43, 53, 26, 24, 23,
+ 22, 2, 1, 25, 25, 25, 1, 25,
+ 32, 31, 31, 31, 42, 31, 42, 42,
+ 42, 43, 1, 48, 43, 43, 53, 26,
+ 24, 23, 22, 2, 1, 25, 25, 25,
+ 1, 25, 32, 31, 31, 31, 42, 31,
+ 42, 42, 42, 43, 1, 48, 1, 1,
+ 53, 43, 2, 1, 5, 3, 4, 3
+};
+
+static const short _use_syllable_machine_index_offsets[] = {
+ 0, 55, 99, 143, 197, 224, 249, 273,
+ 296, 299, 301, 327, 353, 379, 381, 407,
+ 440, 472, 504, 536, 579, 611, 654, 697,
+ 740, 784, 786, 835, 879, 882, 884, 928,
+ 972, 1026, 1053, 1078, 1102, 1125, 1128, 1130,
+ 1156, 1182, 1208, 1210, 1236, 1269, 1301, 1333,
+ 1365, 1408, 1440, 1483, 1526, 1569, 1613, 1615,
+ 1664, 1666, 1668, 1712, 1756, 1810, 1837, 1862,
+ 1886, 1909, 1912, 1914, 1940, 1966, 1992, 1994,
+ 2020, 2053, 2085, 2117, 2149, 2192, 2224, 2267,
+ 2310, 2353, 2397, 2399, 2448, 2492, 2536, 2590,
+ 2617, 2642, 2666, 2689, 2692, 2694, 2720, 2746,
+ 2772, 2774, 2800, 2833, 2865, 2897, 2929, 2972,
+ 3004, 3047, 3090, 3133, 3177, 3179, 3228, 3230,
+ 3232, 3286, 3330, 3333, 3335, 3341, 3345, 3350
+};
+
+static const unsigned char _use_syllable_machine_indicies[] = {
+ 0, 1, 2, 2, 3, 4, 2, 2,
+ 2, 2, 2, 5, 6, 7, 2, 2,
+ 2, 2, 8, 2, 2, 2, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 2, 23, 24, 25,
+ 2, 26, 27, 28, 29, 30, 31, 32,
+ 29, 33, 2, 34, 2, 35, 2, 37,
+ 38, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52,
+ 36, 53, 54, 55, 36, 56, 57, 36,
+ 58, 59, 60, 61, 58, 36, 36, 36,
+ 36, 62, 36, 37, 38, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 49,
+ 49, 50, 51, 52, 36, 53, 54, 55,
+ 36, 36, 36, 36, 58, 59, 60, 61,
+ 58, 36, 36, 36, 36, 62, 36, 37,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 40, 41, 42,
+ 43, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 53, 54, 55, 36, 36,
+ 36, 36, 36, 59, 60, 61, 63, 36,
+ 36, 36, 36, 40, 36, 40, 41, 42,
+ 43, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 53, 54, 55, 36, 36,
+ 36, 36, 36, 59, 60, 61, 63, 36,
+ 41, 42, 43, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 59, 60, 61,
+ 36, 42, 43, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 59, 60, 61,
+ 36, 43, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 59, 60, 61, 36,
+ 59, 60, 36, 60, 36, 41, 42, 43,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 53, 54, 55, 36, 36, 36,
+ 36, 36, 59, 60, 61, 63, 36, 41,
+ 42, 43, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 54, 55, 36,
+ 36, 36, 36, 36, 59, 60, 61, 63,
+ 36, 41, 42, 43, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 55, 36, 36, 36, 36, 36, 59, 60,
+ 61, 63, 36, 64, 36, 41, 42, 43,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 59, 60, 61, 63, 36, 39,
+ 40, 41, 42, 43, 36, 36, 36, 36,
+ 36, 36, 50, 51, 52, 36, 53, 54,
+ 55, 36, 36, 36, 36, 36, 59, 60,
+ 61, 63, 36, 36, 36, 36, 40, 36,
+ 40, 41, 42, 43, 36, 36, 36, 36,
+ 36, 36, 50, 51, 52, 36, 53, 54,
+ 55, 36, 36, 36, 36, 36, 59, 60,
+ 61, 63, 36, 36, 36, 36, 40, 36,
+ 40, 41, 42, 43, 36, 36, 36, 36,
+ 36, 36, 36, 51, 52, 36, 53, 54,
+ 55, 36, 36, 36, 36, 36, 59, 60,
+ 61, 63, 36, 36, 36, 36, 40, 36,
+ 40, 41, 42, 43, 36, 36, 36, 36,
+ 36, 36, 36, 36, 52, 36, 53, 54,
+ 55, 36, 36, 36, 36, 36, 59, 60,
+ 61, 63, 36, 36, 36, 36, 40, 36,
+ 65, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 39, 40, 41, 42, 43, 36,
+ 45, 46, 36, 36, 36, 50, 51, 52,
+ 36, 53, 54, 55, 36, 36, 36, 36,
+ 36, 59, 60, 61, 63, 36, 36, 36,
+ 36, 40, 36, 40, 41, 42, 43, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 53, 54, 55, 36, 36, 36, 36,
+ 36, 59, 60, 61, 63, 36, 36, 36,
+ 36, 40, 36, 65, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 39, 40, 41,
+ 42, 43, 36, 36, 46, 36, 36, 36,
+ 50, 51, 52, 36, 53, 54, 55, 36,
+ 36, 36, 36, 36, 59, 60, 61, 63,
+ 36, 36, 36, 36, 40, 36, 65, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 39, 40, 41, 42, 43, 36, 36, 36,
+ 36, 36, 36, 50, 51, 52, 36, 53,
+ 54, 55, 36, 36, 36, 36, 36, 59,
+ 60, 61, 63, 36, 36, 36, 36, 40,
+ 36, 65, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 39, 40, 41, 42, 43,
+ 44, 45, 46, 36, 36, 36, 50, 51,
+ 52, 36, 53, 54, 55, 36, 36, 36,
+ 36, 36, 59, 60, 61, 63, 36, 36,
+ 36, 36, 40, 36, 37, 38, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 36, 49, 50, 51, 52, 36, 53, 54,
+ 55, 36, 36, 36, 36, 58, 59, 60,
+ 61, 58, 36, 36, 36, 36, 62, 36,
+ 37, 36, 37, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 40, 41, 42, 43, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 53, 54,
+ 55, 36, 36, 36, 36, 36, 59, 60,
+ 61, 63, 36, 37, 38, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 36, 53, 54, 55,
+ 36, 36, 36, 36, 58, 59, 60, 61,
+ 58, 36, 36, 36, 36, 62, 36, 56,
+ 57, 36, 57, 36, 67, 68, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77,
+ 1, 78, 79, 80, 81, 66, 82, 83,
+ 84, 66, 66, 66, 66, 85, 86, 87,
+ 88, 89, 66, 66, 66, 66, 90, 66,
+ 67, 68, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 78, 79, 80,
+ 81, 66, 82, 83, 84, 66, 66, 66,
+ 66, 85, 86, 87, 88, 89, 66, 66,
+ 66, 66, 90, 66, 67, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 70, 71, 72, 73, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 82, 83, 84, 66, 66, 66, 66, 66,
+ 86, 87, 88, 91, 66, 66, 66, 66,
+ 70, 66, 70, 71, 72, 73, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 82, 83, 84, 66, 66, 66, 66, 66,
+ 86, 87, 88, 91, 66, 71, 72, 73,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 86, 87, 88, 66, 72, 73,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 86, 87, 88, 66, 73, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 86, 87, 88, 66, 86, 87, 66,
+ 87, 66, 71, 72, 73, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 82,
+ 83, 84, 66, 66, 66, 66, 66, 86,
+ 87, 88, 91, 66, 71, 72, 73, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 83, 84, 66, 66, 66, 66,
+ 66, 86, 87, 88, 91, 66, 71, 72,
+ 73, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 84, 66, 66,
+ 66, 66, 66, 86, 87, 88, 91, 66,
+ 93, 92, 71, 72, 73, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 86,
+ 87, 88, 91, 66, 69, 70, 71, 72,
+ 73, 66, 66, 66, 66, 66, 66, 79,
+ 80, 81, 66, 82, 83, 84, 66, 66,
+ 66, 66, 66, 86, 87, 88, 91, 66,
+ 66, 66, 66, 70, 66, 70, 71, 72,
+ 73, 66, 66, 66, 66, 66, 66, 79,
+ 80, 81, 66, 82, 83, 84, 66, 66,
+ 66, 66, 66, 86, 87, 88, 91, 66,
+ 66, 66, 66, 70, 66, 70, 71, 72,
+ 73, 66, 66, 66, 66, 66, 66, 66,
+ 80, 81, 66, 82, 83, 84, 66, 66,
+ 66, 66, 66, 86, 87, 88, 91, 66,
+ 66, 66, 66, 70, 66, 70, 71, 72,
+ 73, 66, 66, 66, 66, 66, 66, 66,
+ 66, 81, 66, 82, 83, 84, 66, 66,
+ 66, 66, 66, 86, 87, 88, 91, 66,
+ 66, 66, 66, 70, 66, 94, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 69,
+ 70, 71, 72, 73, 66, 75, 76, 66,
+ 66, 66, 79, 80, 81, 66, 82, 83,
+ 84, 66, 66, 66, 66, 66, 86, 87,
+ 88, 91, 66, 66, 66, 66, 70, 66,
+ 70, 71, 72, 73, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 82, 83,
+ 84, 66, 66, 66, 66, 66, 86, 87,
+ 88, 91, 66, 66, 66, 66, 70, 66,
+ 94, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 69, 70, 71, 72, 73, 66,
+ 66, 76, 66, 66, 66, 79, 80, 81,
+ 66, 82, 83, 84, 66, 66, 66, 66,
+ 66, 86, 87, 88, 91, 66, 66, 66,
+ 66, 70, 66, 94, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 69, 70, 71,
+ 72, 73, 66, 66, 66, 66, 66, 66,
+ 79, 80, 81, 66, 82, 83, 84, 66,
+ 66, 66, 66, 66, 86, 87, 88, 91,
+ 66, 66, 66, 66, 70, 66, 94, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 69, 70, 71, 72, 73, 74, 75, 76,
+ 66, 66, 66, 79, 80, 81, 66, 82,
+ 83, 84, 66, 66, 66, 66, 66, 86,
+ 87, 88, 91, 66, 66, 66, 66, 70,
+ 66, 67, 68, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 66, 78, 79,
+ 80, 81, 66, 82, 83, 84, 66, 66,
+ 66, 66, 85, 86, 87, 88, 89, 66,
+ 66, 66, 66, 90, 66, 67, 95, 67,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 70, 71, 72,
+ 73, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 82, 83, 84, 66, 66,
+ 66, 66, 66, 86, 87, 88, 91, 66,
+ 97, 96, 3, 98, 99, 100, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 66, 115, 116,
+ 117, 66, 56, 57, 66, 118, 119, 120,
+ 88, 121, 66, 66, 66, 66, 122, 66,
+ 99, 100, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 111, 111, 112, 113,
+ 114, 66, 115, 116, 117, 66, 66, 66,
+ 66, 118, 119, 120, 88, 121, 66, 66,
+ 66, 66, 122, 66, 99, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 102, 103, 104, 105, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 115, 116, 117, 66, 66, 66, 66, 66,
+ 119, 120, 88, 123, 66, 66, 66, 66,
+ 102, 66, 102, 103, 104, 105, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 115, 116, 117, 66, 66, 66, 66, 66,
+ 119, 120, 88, 123, 66, 103, 104, 105,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 119, 120, 88, 66, 104, 105,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 119, 120, 88, 66, 105, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 119, 120, 88, 66, 119, 120, 66,
+ 120, 66, 103, 104, 105, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 115,
+ 116, 117, 66, 66, 66, 66, 66, 119,
+ 120, 88, 123, 66, 103, 104, 105, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 116, 117, 66, 66, 66, 66,
+ 66, 119, 120, 88, 123, 66, 103, 104,
+ 105, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 117, 66, 66,
+ 66, 66, 66, 119, 120, 88, 123, 66,
+ 124, 92, 103, 104, 105, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 119,
+ 120, 88, 123, 66, 101, 102, 103, 104,
+ 105, 66, 66, 66, 66, 66, 66, 112,
+ 113, 114, 66, 115, 116, 117, 66, 66,
+ 66, 66, 66, 119, 120, 88, 123, 66,
+ 66, 66, 66, 102, 66, 102, 103, 104,
+ 105, 66, 66, 66, 66, 66, 66, 112,
+ 113, 114, 66, 115, 116, 117, 66, 66,
+ 66, 66, 66, 119, 120, 88, 123, 66,
+ 66, 66, 66, 102, 66, 102, 103, 104,
+ 105, 66, 66, 66, 66, 66, 66, 66,
+ 113, 114, 66, 115, 116, 117, 66, 66,
+ 66, 66, 66, 119, 120, 88, 123, 66,
+ 66, 66, 66, 102, 66, 102, 103, 104,
+ 105, 66, 66, 66, 66, 66, 66, 66,
+ 66, 114, 66, 115, 116, 117, 66, 66,
+ 66, 66, 66, 119, 120, 88, 123, 66,
+ 66, 66, 66, 102, 66, 125, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 101,
+ 102, 103, 104, 105, 66, 107, 108, 66,
+ 66, 66, 112, 113, 114, 66, 115, 116,
+ 117, 66, 66, 66, 66, 66, 119, 120,
+ 88, 123, 66, 66, 66, 66, 102, 66,
+ 102, 103, 104, 105, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 115, 116,
+ 117, 66, 66, 66, 66, 66, 119, 120,
+ 88, 123, 66, 66, 66, 66, 102, 66,
+ 125, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 101, 102, 103, 104, 105, 66,
+ 66, 108, 66, 66, 66, 112, 113, 114,
+ 66, 115, 116, 117, 66, 66, 66, 66,
+ 66, 119, 120, 88, 123, 66, 66, 66,
+ 66, 102, 66, 125, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 101, 102, 103,
+ 104, 105, 66, 66, 66, 66, 66, 66,
+ 112, 113, 114, 66, 115, 116, 117, 66,
+ 66, 66, 66, 66, 119, 120, 88, 123,
+ 66, 66, 66, 66, 102, 66, 125, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 101, 102, 103, 104, 105, 106, 107, 108,
+ 66, 66, 66, 112, 113, 114, 66, 115,
+ 116, 117, 66, 66, 66, 66, 66, 119,
+ 120, 88, 123, 66, 66, 66, 66, 102,
+ 66, 99, 100, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 66, 111, 112,
+ 113, 114, 66, 115, 116, 117, 66, 66,
+ 66, 66, 118, 119, 120, 88, 121, 66,
+ 66, 66, 66, 122, 66, 99, 95, 99,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 102, 103, 104,
+ 105, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 115, 116, 117, 66, 66,
+ 66, 66, 66, 119, 120, 88, 123, 66,
+ 99, 100, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113,
+ 114, 66, 115, 116, 117, 66, 66, 66,
+ 66, 118, 119, 120, 88, 121, 66, 66,
+ 66, 66, 122, 66, 5, 6, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17,
+ 19, 19, 20, 21, 22, 126, 23, 24,
+ 25, 126, 126, 126, 126, 29, 30, 31,
+ 32, 29, 126, 126, 126, 126, 35, 126,
+ 5, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 10, 11,
+ 12, 13, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 23, 24, 25, 126,
+ 126, 126, 126, 126, 30, 31, 32, 127,
+ 126, 126, 126, 126, 10, 126, 10, 11,
+ 12, 13, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 23, 24, 25, 126,
+ 126, 126, 126, 126, 30, 31, 32, 127,
+ 126, 11, 12, 13, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 30, 31,
+ 32, 126, 12, 13, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 30, 31,
+ 32, 126, 13, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 30, 31, 32,
+ 126, 30, 31, 126, 31, 126, 11, 12,
+ 13, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 23, 24, 25, 126, 126,
+ 126, 126, 126, 30, 31, 32, 127, 126,
+ 11, 12, 13, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 24, 25,
+ 126, 126, 126, 126, 126, 30, 31, 32,
+ 127, 126, 11, 12, 13, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 25, 126, 126, 126, 126, 126, 30,
+ 31, 32, 127, 126, 128, 126, 11, 12,
+ 13, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 30, 31, 32, 127, 126,
+ 9, 10, 11, 12, 13, 126, 126, 126,
+ 126, 126, 126, 20, 21, 22, 126, 23,
+ 24, 25, 126, 126, 126, 126, 126, 30,
+ 31, 32, 127, 126, 126, 126, 126, 10,
+ 126, 10, 11, 12, 13, 126, 126, 126,
+ 126, 126, 126, 20, 21, 22, 126, 23,
+ 24, 25, 126, 126, 126, 126, 126, 30,
+ 31, 32, 127, 126, 126, 126, 126, 10,
+ 126, 10, 11, 12, 13, 126, 126, 126,
+ 126, 126, 126, 126, 21, 22, 126, 23,
+ 24, 25, 126, 126, 126, 126, 126, 30,
+ 31, 32, 127, 126, 126, 126, 126, 10,
+ 126, 10, 11, 12, 13, 126, 126, 126,
+ 126, 126, 126, 126, 126, 22, 126, 23,
+ 24, 25, 126, 126, 126, 126, 126, 30,
+ 31, 32, 127, 126, 126, 126, 126, 10,
+ 126, 129, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 9, 10, 11, 12, 13,
+ 126, 15, 16, 126, 126, 126, 20, 21,
+ 22, 126, 23, 24, 25, 126, 126, 126,
+ 126, 126, 30, 31, 32, 127, 126, 126,
+ 126, 126, 10, 126, 10, 11, 12, 13,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 23, 24, 25, 126, 126, 126,
+ 126, 126, 30, 31, 32, 127, 126, 126,
+ 126, 126, 10, 126, 129, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 9, 10,
+ 11, 12, 13, 126, 126, 16, 126, 126,
+ 126, 20, 21, 22, 126, 23, 24, 25,
+ 126, 126, 126, 126, 126, 30, 31, 32,
+ 127, 126, 126, 126, 126, 10, 126, 129,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 9, 10, 11, 12, 13, 126, 126,
+ 126, 126, 126, 126, 20, 21, 22, 126,
+ 23, 24, 25, 126, 126, 126, 126, 126,
+ 30, 31, 32, 127, 126, 126, 126, 126,
+ 10, 126, 129, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 9, 10, 11, 12,
+ 13, 14, 15, 16, 126, 126, 126, 20,
+ 21, 22, 126, 23, 24, 25, 126, 126,
+ 126, 126, 126, 30, 31, 32, 127, 126,
+ 126, 126, 126, 10, 126, 5, 6, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 126, 19, 20, 21, 22, 126, 23,
+ 24, 25, 126, 126, 126, 126, 29, 30,
+ 31, 32, 29, 126, 126, 126, 126, 35,
+ 126, 5, 126, 5, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 10, 11, 12, 13, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 23,
+ 24, 25, 126, 126, 126, 126, 126, 30,
+ 31, 32, 127, 126, 130, 126, 7, 126,
+ 1, 126, 126, 126, 1, 126, 126, 126,
+ 126, 126, 5, 6, 7, 126, 126, 126,
+ 126, 126, 126, 126, 126, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 126, 23, 24, 25, 126,
+ 26, 27, 126, 29, 30, 31, 32, 29,
+ 126, 126, 126, 126, 35, 126, 5, 6,
+ 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 126,
+ 23, 24, 25, 126, 126, 126, 126, 29,
+ 30, 31, 32, 29, 126, 126, 126, 126,
+ 35, 126, 26, 27, 126, 27, 126, 1,
+ 131, 131, 131, 1, 131, 133, 132, 33,
+ 132, 33, 133, 132, 133, 132, 33, 132,
+ 34, 132, 0
+};
+
+static const char _use_syllable_machine_trans_targs[] = {
+ 1, 30, 0, 56, 58, 85, 86, 110,
+ 112, 98, 87, 88, 89, 90, 102, 104,
+ 105, 106, 113, 107, 99, 100, 101, 93,
+ 94, 95, 114, 115, 116, 108, 91, 92,
+ 0, 117, 119, 109, 0, 2, 3, 15,
+ 4, 5, 6, 7, 19, 21, 22, 23,
+ 27, 24, 16, 17, 18, 10, 11, 12,
+ 28, 29, 25, 8, 9, 0, 26, 13,
+ 14, 20, 0, 31, 32, 44, 33, 34,
+ 35, 36, 48, 50, 51, 52, 53, 45,
+ 46, 47, 39, 40, 41, 54, 37, 38,
+ 0, 54, 55, 42, 0, 43, 49, 0,
+ 0, 57, 0, 59, 60, 72, 61, 62,
+ 63, 64, 76, 78, 79, 80, 84, 81,
+ 73, 74, 75, 67, 68, 69, 82, 65,
+ 66, 82, 83, 70, 71, 77, 0, 96,
+ 97, 103, 111, 0, 0, 118
+};
+
+static const char _use_syllable_machine_trans_actions[] = {
+ 0, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 0,
+ 0, 0, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 8, 0, 0,
+ 9, 10, 0, 0, 11, 0, 0, 12,
+ 13, 0, 14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 8, 0,
+ 0, 10, 0, 0, 0, 0, 15, 0,
+ 0, 0, 0, 16, 17, 0
+};
+
+static const char _use_syllable_machine_to_state_actions[] = {
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const char _use_syllable_machine_from_state_actions[] = {
+ 2, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const short _use_syllable_machine_eof_trans[] = {
+ 0, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 93, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 96, 67,
+ 97, 99, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 93, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 96, 67, 67, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 132, 133, 133, 133
+};
+
+static const int use_syllable_machine_start = 0;
+static const int use_syllable_machine_first_final = 0;
+static const int use_syllable_machine_error = -1;
+
+static const int use_syllable_machine_en_main = 0;
+
+
+#line 58 "hb-ot-shaper-use-machine.rl"
+
+
+
+#line 182 "hb-ot-shaper-use-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
+ for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+
+template <typename Iter>
+struct machine_index_t :
+ hb_iter_with_fallback_t<machine_index_t<Iter>,
+ typename Iter::item_t>
+{
+ machine_index_t (const Iter& it) : it (it) {}
+ machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>,
+ typename Iter::item_t> (),
+ it (o.it), is_null (o.is_null) {}
+
+ static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
+ static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
+
+ typename Iter::item_t __item__ () const { return *it; }
+ typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; }
+ unsigned __len__ () const { return it.len (); }
+ void __next__ () { ++it; }
+ void __forward__ (unsigned n) { it += n; }
+ void __prev__ () { --it; }
+ void __rewind__ (unsigned n) { it -= n; }
+
+ void operator = (unsigned n)
+ {
+ assert (n == 0);
+ is_null = true;
+ }
+ explicit operator bool () { return !is_null; }
+
+ void operator = (const machine_index_t& o)
+ {
+ is_null = o.is_null;
+ unsigned index = (*it).first;
+ unsigned n = (*o.it).first;
+ if (index < n) it += n - index; else if (index > n) it -= index - n;
+ }
+ bool operator == (const machine_index_t& o) const
+ { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; }
+ bool operator != (const machine_index_t& o) const { return !(*this == o); }
+
+ private:
+ Iter it;
+ bool is_null = false;
+};
+struct
+{
+ template <typename Iter,
+ hb_requires (hb_is_iterable (Iter))>
+ machine_index_t<hb_iter_type<Iter>>
+ operator () (Iter&& it) const
+ { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); }
+}
+HB_FUNCOBJ (machine_index);
+
+
+
+static bool
+not_ccs_default_ignorable (const hb_glyph_info_t &i)
+{ return i.use_category() != USE(CGJ); }
+
+static inline void
+find_syllables_use (hb_buffer_t *buffer)
+{
+ hb_glyph_info_t *info = buffer->info;
+ auto p =
+ + hb_iter (info, buffer->len)
+ | hb_enumerate
+ | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); },
+ hb_second)
+ | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
+ {
+ if (p.second.use_category() == USE(ZWNJ))
+ for (unsigned i = p.first + 1; i < buffer->len; ++i)
+ if (not_ccs_default_ignorable (info[i]))
+ return !_hb_glyph_info_is_unicode_mark (&info[i]);
+ return true;
+ })
+ | hb_enumerate
+ | machine_index
+ ;
+ auto pe = p + p.len ();
+ auto eof = +pe;
+ auto ts = +p;
+ auto te = +p;
+ unsigned int act HB_UNUSED;
+ int cs;
+
+#line 784 "hb-ot-shaper-use-machine.hh"
+ {
+ cs = use_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 282 "hb-ot-shaper-use-machine.rl"
+
+
+ unsigned int syllable_serial = 1;
+
+#line 797 "hb-ot-shaper-use-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const unsigned char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _use_syllable_machine_from_state_actions[cs] ) {
+ case 2:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 811 "hb-ot-shaper-use-machine.hh"
+ }
+
+ _keys = _use_syllable_machine_trans_keys + (cs<<1);
+ _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs];
+
+ _slen = _use_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( (*p).second.second.use_category()) &&
+ ( (*p).second.second.use_category()) <= _keys[1] ?
+ ( (*p).second.second.use_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _use_syllable_machine_trans_targs[_trans];
+
+ if ( _use_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _use_syllable_machine_trans_actions[_trans] ) {
+ case 9:
+#line 172 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{ found_syllable (use_standard_cluster); }}
+ break;
+ case 6:
+#line 175 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{ found_syllable (use_symbol_cluster); }}
+ break;
+ case 4:
+#line 177 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+ break;
+ case 3:
+#line 178 "hb-ot-shaper-use-machine.rl"
+ {te = p+1;{ found_syllable (use_non_cluster); }}
+ break;
+ case 11:
+#line 171 "hb-ot-shaper-use-machine.rl"
+ {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
+ break;
+ case 7:
+#line 172 "hb-ot-shaper-use-machine.rl"
+ {te = p;p--;{ found_syllable (use_standard_cluster); }}
+ break;
+ case 14:
+#line 173 "hb-ot-shaper-use-machine.rl"
+ {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
+ break;
+ case 13:
+#line 174 "hb-ot-shaper-use-machine.rl"
+ {te = p;p--;{ found_syllable (use_numeral_cluster); }}
+ break;
+ case 5:
+#line 175 "hb-ot-shaper-use-machine.rl"
+ {te = p;p--;{ found_syllable (use_symbol_cluster); }}
+ break;
+ case 17:
+#line 176 "hb-ot-shaper-use-machine.rl"
+ {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
+ break;
+ case 15:
+#line 177 "hb-ot-shaper-use-machine.rl"
+ {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+ break;
+ case 16:
+#line 178 "hb-ot-shaper-use-machine.rl"
+ {te = p;p--;{ found_syllable (use_non_cluster); }}
+ break;
+ case 12:
+#line 1 "NONE"
+ { switch( act ) {
+ case 1:
+ {{p = ((te))-1;} found_syllable (use_virama_terminated_cluster); }
+ break;
+ case 2:
+ {{p = ((te))-1;} found_syllable (use_sakot_terminated_cluster); }
+ break;
+ }
+ }
+ break;
+ case 8:
+#line 1 "NONE"
+ {te = p+1;}
+#line 170 "hb-ot-shaper-use-machine.rl"
+ {act = 1;}
+ break;
+ case 10:
+#line 1 "NONE"
+ {te = p+1;}
+#line 171 "hb-ot-shaper-use-machine.rl"
+ {act = 2;}
+ break;
+#line 901 "hb-ot-shaper-use-machine.hh"
+ }
+
+_again:
+ switch ( _use_syllable_machine_to_state_actions[cs] ) {
+ case 1:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 910 "hb-ot-shaper-use-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _use_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _use_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 287 "hb-ot-shaper-use-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPER_USE_MACHINE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh
index c8e5151694..5aa025fb4c 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh
@@ -37,12 +37,12 @@
* UnicodeData.txt does not have a header.
*/
-#ifndef HB_OT_SHAPE_COMPLEX_USE_TABLE_HH
-#define HB_OT_SHAPE_COMPLEX_USE_TABLE_HH
+#ifndef HB_OT_SHAPER_USE_TABLE_HH
+#define HB_OT_SHAPER_USE_TABLE_HH
#include "hb.hh"
-#include "hb-ot-shape-complex-use-machine.hh"
+#include "hb-ot-shaper-use-machine.hh"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros"
@@ -53,6 +53,7 @@
#define GB USE(GB) /* BASE_OTHER */
#define H USE(H) /* HALANT */
#define HN USE(HN) /* HALANT_NUM */
+#define HVM USE(HVM) /* HALANT_OR_VOWEL_MODIFIER */
#define IS USE(IS) /* INVISIBLE_STACKER */
#define J USE(J) /* HIEROGLYPH_JOINER */
#define N USE(N) /* BASE_NUM */
@@ -246,7 +247,7 @@ static const uint8_t use_table[] = {
/* 0D90 */ B, B, B, B, B, B, B, WJ, WJ, WJ, B, B, B, B, B, B,
/* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0DB0 */ B, B, WJ, B, B, B, B, B, B, B, B, B, WJ, B, WJ, WJ,
- /* 0DC0 */ B, B, B, B, B, B, B, WJ, WJ, WJ, H, WJ, WJ, WJ, WJ, VPst,
+ /* 0DC0 */ B, B, B, B, B, B, B, WJ, WJ, WJ, HVM, WJ, WJ, WJ, WJ, VPst,
/* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, WJ, VBlw, WJ, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst,
/* 0DE0 */ WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, B, B, B, B,
/* 0DF0 */ WJ, WJ, VPst, VPst, O, WJ, WJ, WJ,
@@ -1531,6 +1532,7 @@ hb_use_get_category (hb_glyph_info_t info)
#undef GB
#undef H
#undef HN
+#undef HVM
#undef IS
#undef J
#undef N
@@ -1566,5 +1568,5 @@ hb_use_get_category (hb_glyph_info_t info)
#undef VMPre
-#endif /* HB_OT_SHAPE_COMPLEX_USE_TABLE_HH */
+#endif /* HB_OT_SHAPER_USE_TABLE_HH */
/* == End of generated table == */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc
index 1d13c8a126..60394ed4d8 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc
@@ -30,11 +30,11 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex-use-machine.hh"
-#include "hb-ot-shape-complex-use-table.hh"
-#include "hb-ot-shape-complex-arabic.hh"
-#include "hb-ot-shape-complex-arabic-joining-list.hh"
-#include "hb-ot-shape-complex-vowel-constraints.hh"
+#include "hb-ot-shaper-use-machine.hh"
+#include "hb-ot-shaper-use-table.hh"
+#include "hb-ot-shaper-arabic.hh"
+#include "hb-ot-shaper-arabic-joining-list.hh"
+#include "hb-ot-shaper-vowel-constraints.hh"
/*
@@ -133,6 +133,7 @@ collect_features_use (hb_ot_shape_planner_t *plan)
map->enable_feature (use_basic_features[i], F_MANUAL_ZWJ | F_PER_SYLLABLE);
map->add_gsub_pause (reorder_use);
+ map->add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var
/* "Topographical features" */
for (unsigned int i = 0; i < ARRAY_LENGTH (use_topographical_features); i++)
@@ -297,6 +298,7 @@ setup_syllables_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
+ HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
find_syllables_use (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
@@ -349,7 +351,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
static inline bool
is_halant_use (const hb_glyph_info_t &info)
{
- return (info.use_category() == USE(H) || info.use_category() == USE(IS)) &&
+ return (info.use_category() == USE(H) || info.use_category() == USE(HVM) || info.use_category() == USE(IS)) &&
!_hb_glyph_info_ligated (&info);
}
@@ -480,7 +482,7 @@ compose_use (const hb_ot_shape_normalize_context_t *c,
}
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use =
+const hb_ot_shaper_t _hb_ot_shaper_use =
{
collect_features_use,
nullptr, /* override_features */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc
index d2cca105a4..be4ac813b1 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc
@@ -18,7 +18,7 @@
#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shape-complex-vowel-constraints.hh"
+#include "hb-ot-shaper-vowel-constraints.hh"
static void
_output_dotted_circle (hb_buffer_t *buffer)
@@ -39,7 +39,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
hb_font_t *font HB_UNUSED)
{
-#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
+#ifdef HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS
return;
#endif
if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.hh
index d9082d4ead..5a7ee1b0f2 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.hh
@@ -24,16 +24,16 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS_HH
-#define HB_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS_HH
+#ifndef HB_OT_SHAPER_VOWEL_CONSTRAINTS_HH
+#define HB_OT_SHAPER_VOWEL_CONSTRAINTS_HH
#include "hb.hh"
-#include "hb-ot-shape-complex.hh"
+#include "hb-ot-shaper.hh"
HB_INTERNAL void
_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font);
-#endif /* HB_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS_HH */
+#endif /* HB_OT_SHAPER_VOWEL_CONSTRAINTS_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh b/thirdparty/harfbuzz/src/hb-ot-shaper.hh
index 8012a9ae94..b823bf003c 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shaper.hh
@@ -24,8 +24,8 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPE_COMPLEX_HH
-#define HB_OT_SHAPE_COMPLEX_HH
+#ifndef HB_OT_SHAPER_HH
+#define HB_OT_SHAPER_HH
#include "hb.hh"
@@ -34,12 +34,12 @@
#include "hb-ot-shape-normalize.hh"
-/* buffer var allocations, used by complex shapers */
-#define complex_var_u8_category() var2.u8[2]
-#define complex_var_u8_auxiliary() var2.u8[3]
+/* buffer var allocations, used by all OT shapers */
+#define ot_shaper_var_u8_category() var2.u8[2]
+#define ot_shaper_var_u8_auxiliary() var2.u8[3]
-#define HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS 32
+#define HB_OT_SHAPE_MAX_COMBINING_MARKS 32
enum hb_ot_shape_zero_width_marks_type_t {
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
@@ -49,22 +49,22 @@ enum hb_ot_shape_zero_width_marks_type_t {
/* Master OT shaper list */
-#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
- HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
- HB_COMPLEX_SHAPER_IMPLEMENT (default) \
- HB_COMPLEX_SHAPER_IMPLEMENT (dumber) \
- HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \
- HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \
- HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
- HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \
- HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
- HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \
- HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
- HB_COMPLEX_SHAPER_IMPLEMENT (use) \
+#define HB_OT_SHAPERS_IMPLEMENT_SHAPERS \
+ HB_OT_SHAPER_IMPLEMENT (arabic) \
+ HB_OT_SHAPER_IMPLEMENT (default) \
+ HB_OT_SHAPER_IMPLEMENT (dumber) \
+ HB_OT_SHAPER_IMPLEMENT (hangul) \
+ HB_OT_SHAPER_IMPLEMENT (hebrew) \
+ HB_OT_SHAPER_IMPLEMENT (indic) \
+ HB_OT_SHAPER_IMPLEMENT (khmer) \
+ HB_OT_SHAPER_IMPLEMENT (myanmar) \
+ HB_OT_SHAPER_IMPLEMENT (myanmar_zawgyi) \
+ HB_OT_SHAPER_IMPLEMENT (thai) \
+ HB_OT_SHAPER_IMPLEMENT (use) \
/* ^--- Add new shapers here; keep sorted. */
-struct hb_ot_complex_shaper_t
+struct hb_ot_shaper_t
{
/* collect_features()
* Called during shape_plan().
@@ -168,18 +168,18 @@ struct hb_ot_complex_shaper_t
bool fallback_position;
};
-#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
-HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_COMPLEX_SHAPER_IMPLEMENT
+#define HB_OT_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_shaper_t _hb_ot_shaper_##name;
+HB_OT_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_OT_SHAPER_IMPLEMENT
-static inline const hb_ot_complex_shaper_t *
-hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
+static inline const hb_ot_shaper_t *
+hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner)
{
switch ((hb_tag_t) planner->props.script)
{
default:
- return &_hb_ot_complex_shaper_default;
+ return &_hb_ot_shaper_default;
/* Unicode-1.1 additions */
@@ -195,28 +195,28 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
if ((planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
planner->props.script == HB_SCRIPT_ARABIC) &&
HB_DIRECTION_IS_HORIZONTAL(planner->props.direction))
- return &_hb_ot_complex_shaper_arabic;
+ return &_hb_ot_shaper_arabic;
else
- return &_hb_ot_complex_shaper_default;
+ return &_hb_ot_shaper_default;
/* Unicode-1.1 additions */
case HB_SCRIPT_THAI:
case HB_SCRIPT_LAO:
- return &_hb_ot_complex_shaper_thai;
+ return &_hb_ot_shaper_thai;
/* Unicode-1.1 additions */
case HB_SCRIPT_HANGUL:
- return &_hb_ot_complex_shaper_hangul;
+ return &_hb_ot_shaper_hangul;
/* Unicode-1.1 additions */
case HB_SCRIPT_HEBREW:
- return &_hb_ot_complex_shaper_hebrew;
+ return &_hb_ot_shaper_hebrew;
/* Unicode-1.1 additions */
@@ -230,9 +230,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_TAMIL:
case HB_SCRIPT_TELUGU:
- /* Unicode-3.0 additions */
- case HB_SCRIPT_SINHALA:
-
/* If the designer designed the font for the 'DFLT' script,
* (or we ended up arbitrarily pick 'latn'), use the default shaper.
* Otherwise, use the specific shaper.
@@ -240,14 +237,14 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
* If it's indy3 tag, send to USE. */
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
- return &_hb_ot_complex_shaper_default;
+ return &_hb_ot_shaper_default;
else if ((planner->map.chosen_script[0] & 0x000000FF) == '3')
- return &_hb_ot_complex_shaper_use;
+ return &_hb_ot_shaper_use;
else
- return &_hb_ot_complex_shaper_indic;
+ return &_hb_ot_shaper_indic;
case HB_SCRIPT_KHMER:
- return &_hb_ot_complex_shaper_khmer;
+ return &_hb_ot_shaper_khmer;
case HB_SCRIPT_MYANMAR:
/* If the designer designed the font for the 'DFLT' script,
@@ -260,16 +257,16 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
planner->map.chosen_script[0] == HB_TAG ('l','a','t','n') ||
planner->map.chosen_script[0] == HB_TAG ('m','y','m','r'))
- return &_hb_ot_complex_shaper_default;
+ return &_hb_ot_shaper_default;
else
- return &_hb_ot_complex_shaper_myanmar;
+ return &_hb_ot_shaper_myanmar;
#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g'))
case HB_SCRIPT_MYANMAR_ZAWGYI:
/* https://github.com/harfbuzz/harfbuzz/issues/1162 */
- return &_hb_ot_complex_shaper_myanmar_zawgyi;
+ return &_hb_ot_shaper_myanmar_zawgyi;
/* Unicode-2.0 additions */
@@ -277,7 +274,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-3.0 additions */
case HB_SCRIPT_MONGOLIAN:
- //case HB_SCRIPT_SINHALA:
+ case HB_SCRIPT_SINHALA:
/* Unicode-3.2 additions */
case HB_SCRIPT_BUHID:
@@ -390,11 +387,11 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
* GSUB/GPOS needed, so there may be no scripts found! */
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
- return &_hb_ot_complex_shaper_default;
+ return &_hb_ot_shaper_default;
else
- return &_hb_ot_complex_shaper_use;
+ return &_hb_ot_shaper_use;
}
}
-#endif /* HB_OT_SHAPE_COMPLEX_HH */
+#endif /* HB_OT_SHAPER_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
index b242fba2d8..9394b90ee6 100644
--- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
@@ -219,6 +219,7 @@ static const LangTag ot_languages2[] = {
{HB_TAG('z','u',' ',' '), HB_TAG('Z','U','L',' ')}, /* Zulu */
};
+#ifndef HB_NO_LANGUAGE_LONG
static const LangTag ot_languages3[] = {
{HB_TAG('a','a','e',' '), HB_TAG('S','Q','I',' ')}, /* Arbëreshë Albanian -> Albanian */
{HB_TAG('a','a','o',' '), HB_TAG('A','R','A',' ')}, /* Algerian Saharan Arabic -> Arabic */
@@ -1621,6 +1622,7 @@ static const LangTag ot_languages3[] = {
/*{HB_TAG('z','z','a',' '), HB_TAG('Z','Z','A',' ')},*/ /* Zazaki [macrolanguage] */
{HB_TAG('z','z','j',' '), HB_TAG('Z','H','A',' ')}, /* Zuojiang Zhuang -> Zhuang */
};
+#endif
/**
* hb_ot_tags_from_complex_language:
@@ -1636,7 +1638,7 @@ static const LangTag ot_languages3[] = {
*
* Return value: Whether any language systems were retrieved.
**/
-static bool
+static inline bool
hb_ot_tags_from_complex_language (const char *lang_str,
const char *limit,
unsigned int *count /* IN/OUT */,
@@ -2818,7 +2820,7 @@ out:
* Return value: The #hb_language_t corresponding to the BCP 47 language tag,
* or #HB_LANGUAGE_INVALID if @tag is not ambiguous.
**/
-static hb_language_t
+static inline hb_language_t
hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
{
switch (tag)
diff --git a/thirdparty/harfbuzz/src/hb-ot-tag.cc b/thirdparty/harfbuzz/src/hb-ot-tag.cc
index a4a9515362..ce5cdce98b 100644
--- a/thirdparty/harfbuzz/src/hb-ot-tag.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-tag.cc
@@ -263,15 +263,19 @@ hb_ot_tags_from_language (const char *lang_str,
unsigned int *count,
hb_tag_t *tags)
{
- const char *s;
+#ifndef HB_NO_LANGUAGE_LONG
/* Check for matches of multiple subtags. */
if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags))
return;
+#endif
/* Find a language matching in the first component. */
- s = strchr (lang_str, '-');
+#ifndef HB_NO_LANGUAGE_LONG
+ const char *s; s = strchr (lang_str, '-');
+#endif
{
+#ifndef HB_NO_LANGUAGE_LONG
if (s && limit - lang_str >= 6)
{
const char *extlang_end = strchr (s + 1, '-');
@@ -280,6 +284,7 @@ hb_ot_tags_from_language (const char *lang_str,
ISALPHA (s[1]))
lang_str = s + 1;
}
+#endif
const LangTag *ot_languages = nullptr;
unsigned ot_languages_len = 0;
const char *dash = strchr (lang_str, '-');
@@ -289,21 +294,23 @@ hb_ot_tags_from_language (const char *lang_str,
ot_languages = ot_languages2;
ot_languages_len = ARRAY_LENGTH (ot_languages2);
}
+#ifndef HB_NO_LANGUAGE_LONG
else if (first_len == 3)
{
ot_languages = ot_languages3;
ot_languages_len = ARRAY_LENGTH (ot_languages3);
}
+#endif
hb_tag_t lang_tag = hb_tag_from_string (lang_str, first_len);
- static unsigned last_tag_idx; /* Poor man's cache. */
- unsigned tag_idx = last_tag_idx;
+ static hb_atomic_int_t last_tag_idx; /* Poor man's cache. */
+ unsigned tag_idx = last_tag_idx.get_relaxed ();
if (likely (tag_idx < ot_languages_len && ot_languages[tag_idx].language == lang_tag) ||
hb_sorted_array (ot_languages, ot_languages_len).bfind (lang_tag, &tag_idx))
{
- last_tag_idx = tag_idx;
+ last_tag_idx.set_relaxed (tag_idx);
unsigned int i;
while (tag_idx != 0 &&
ot_languages[tag_idx].language == ot_languages[tag_idx - 1].language)
@@ -320,6 +327,7 @@ hb_ot_tags_from_language (const char *lang_str,
}
}
+#ifndef HB_NO_LANGUAGE_LONG
if (!s)
s = lang_str + strlen (lang_str);
if (s - lang_str == 3) {
@@ -328,6 +336,7 @@ hb_ot_tags_from_language (const char *lang_str,
*count = 1;
return;
}
+#endif
*count = 0;
}
@@ -472,11 +481,13 @@ hb_ot_tag_to_language (hb_tag_t tag)
if (tag == HB_OT_TAG_DEFAULT_LANGUAGE)
return nullptr;
+#ifndef HB_NO_LANGUAGE_LONG
{
hb_language_t disambiguated_tag = hb_ot_ambiguous_tag_to_language (tag);
if (disambiguated_tag != HB_LANGUAGE_INVALID)
return disambiguated_tag;
}
+#endif
char buf[4];
for (i = 0; i < ARRAY_LENGTH (ot_languages2); i++)
@@ -485,12 +496,14 @@ hb_ot_tag_to_language (hb_tag_t tag)
hb_tag_to_string (ot_languages2[i].language, buf);
return hb_language_from_string (buf, 2);
}
+#ifndef HB_NO_LANGUAGE_LONG
for (i = 0; i < ARRAY_LENGTH (ot_languages3); i++)
if (ot_languages3[i].tag == tag)
{
hb_tag_to_string (ot_languages3[i].language, buf);
return hb_language_from_string (buf, 3);
}
+#endif
/* Return a custom language in the form of "x-hbot-AABBCCDD".
* If it's three letters long, also guess it's ISO 639-3 and lower-case and
@@ -596,6 +609,7 @@ test_langs_sorted ()
abort();
}
}
+#ifndef HB_NO_LANGUAGE_LONG
for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages3); i++)
{
int c = ot_languages3[i].cmp (&ot_languages3[i - 1]);
@@ -606,6 +620,7 @@ test_langs_sorted ()
abort();
}
}
+#endif
}
int
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
index e066558683..c5c476bc0e 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
@@ -213,7 +213,7 @@ struct fvar
if (!axis_index) axis_index = &i;
*axis_index = HB_OT_VAR_NO_AXIS_INDEX;
auto axes = get_axes ();
- return axes.lfind (tag, axis_index) && (axes[*axis_index].get_axis_deprecated (info), true);
+ return axes.lfind (tag, axis_index) && ((void) axes[*axis_index].get_axis_deprecated (info), true);
}
#endif
bool
@@ -221,7 +221,7 @@ struct fvar
{
unsigned i;
auto axes = get_axes ();
- return axes.lfind (tag, &i) && (axes[i].get_axis_info (i, info), true);
+ return axes.lfind (tag, &i) && ((void) axes[i].get_axis_info (i, info), true);
}
int normalize_axis_value (unsigned int axis_index, float v) const
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh
index 3b2a38b9a6..bf1039d1d6 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh
@@ -45,9 +45,10 @@ struct contour_point_t
void translate (const contour_point_t &p) { x += p.x; y += p.y; }
- uint8_t flag;
- float x, y;
- bool is_end_point;
+ float x = 0.f;
+ float y = 0.f;
+ uint8_t flag = 0;
+ bool is_end_point = false;
};
struct contour_point_vector_t : hb_vector_t<contour_point_t>
@@ -55,16 +56,24 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t>
void extend (const hb_array_t<contour_point_t> &a)
{
unsigned int old_len = length;
- resize (old_len + a.length);
- for (unsigned int i = 0; i < a.length; i++)
- (*this)[old_len + i] = a[i];
+ if (unlikely (!resize (old_len + a.length)))
+ return;
+ auto arrayZ = this->arrayZ + old_len;
+ unsigned count = a.length;
+ for (unsigned int i = 0; i < count; i++)
+ arrayZ[i] = a.arrayZ[i];
}
void transform (const float (&matrix)[4])
{
- for (unsigned int i = 0; i < length; i++)
+ if (matrix[0] == 1.f && matrix[1] == 0.f &&
+ matrix[2] == 0.f && matrix[3] == 1.f)
+ return;
+ auto arrayZ = this->arrayZ;
+ unsigned count = length;
+ for (unsigned i = 0; i < count; i++)
{
- contour_point_t &p = (*this)[i];
+ contour_point_t &p = arrayZ[i];
float x_ = p.x * matrix[0] + p.y * matrix[2];
p.y = p.x * matrix[1] + p.y * matrix[3];
p.x = x_;
@@ -73,8 +82,12 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t>
void translate (const contour_point_t& delta)
{
- for (unsigned int i = 0; i < length; i++)
- (*this)[i].translate (delta);
+ if (delta.x == 0.f && delta.y == 0.f)
+ return;
+ auto arrayZ = this->arrayZ;
+ unsigned count = length;
+ for (unsigned i = 0; i < count; i++)
+ arrayZ[i].translate (delta);
}
};
@@ -89,7 +102,7 @@ struct TupleVariationHeader
const TupleVariationHeader &get_next (unsigned axis_count) const
{ return StructAtOffset<TupleVariationHeader> (this, get_size (axis_count)); }
- float calculate_scalar (const int *coords, unsigned int coord_count,
+ float calculate_scalar (hb_array_t<int> coords, unsigned int coord_count,
const hb_array_t<const F2DOT14> shared_tuples) const
{
hb_array_t<const F2DOT14> peak_tuple;
@@ -208,7 +221,7 @@ struct GlyphVariationData
{
const HBUINT8 *base = &(var_data+var_data->data);
const HBUINT8 *p = base;
- if (!unpack_points (p, shared_indices, var_data_bytes)) return false;
+ if (!unpack_points (p, shared_indices, (const HBUINT8 *) (var_data_bytes.arrayZ + var_data_bytes.length))) return false;
data_offset = p - base;
}
return true;
@@ -258,7 +271,7 @@ struct GlyphVariationData
static bool unpack_points (const HBUINT8 *&p /* IN/OUT */,
hb_vector_t<unsigned int> &points /* OUT */,
- const hb_bytes_t &bytes)
+ const HBUINT8 *end)
{
enum packed_point_flag_t
{
@@ -266,21 +279,21 @@ struct GlyphVariationData
POINT_RUN_COUNT_MASK = 0x7F
};
- if (unlikely (!bytes.check_range (p))) return false;
+ if (unlikely (p + 1 > end)) return false;
uint16_t count = *p++;
if (count & POINTS_ARE_WORDS)
{
- if (unlikely (!bytes.check_range (p))) return false;
+ if (unlikely (p + 1 > end)) return false;
count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
}
- points.resize (count);
+ if (unlikely (!points.resize (count))) return false;
unsigned int n = 0;
uint16_t i = 0;
while (i < count)
{
- if (unlikely (!bytes.check_range (p))) return false;
+ if (unlikely (p + 1 > end)) return false;
uint16_t j;
uint8_t control = *p++;
uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1;
@@ -288,8 +301,7 @@ struct GlyphVariationData
{
for (j = 0; j < run_count && i < count; j++, i++)
{
- if (unlikely (!bytes.check_range ((const HBUINT16 *) p)))
- return false;
+ if (unlikely (p + HBUINT16::static_size > end)) return false;
n += *(const HBUINT16 *)p;
points[i] = n;
p += HBUINT16::static_size;
@@ -299,7 +311,7 @@ struct GlyphVariationData
{
for (j = 0; j < run_count && i < count; j++, i++)
{
- if (unlikely (!bytes.check_range (p))) return false;
+ if (unlikely (p + 1 > end)) return false;
n += *p++;
points[i] = n;
}
@@ -311,7 +323,7 @@ struct GlyphVariationData
static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */,
hb_vector_t<int> &deltas /* IN/OUT */,
- const hb_bytes_t &bytes)
+ const HBUINT8 *end)
{
enum packed_delta_flag_t
{
@@ -324,7 +336,7 @@ struct GlyphVariationData
unsigned int count = deltas.length;
while (i < count)
{
- if (unlikely (!bytes.check_range (p))) return false;
+ if (unlikely (p + 1 > end)) return false;
uint8_t control = *p++;
unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
unsigned int j;
@@ -334,16 +346,14 @@ struct GlyphVariationData
else if (control & DELTAS_ARE_WORDS)
for (j = 0; j < run_count && i < count; j++, i++)
{
- if (unlikely (!bytes.check_range ((const HBUINT16 *) p)))
- return false;
+ if (unlikely (p + HBUINT16::static_size > end)) return false;
deltas[i] = *(const HBINT16 *) p;
p += HBUINT16::static_size;
}
else
for (j = 0; j < run_count && i < count; j++, i++)
{
- if (unlikely (!bytes.check_range (p)))
- return false;
+ if (unlikely (p + 1 > end)) return false;
deltas[i] = *(const HBINT8 *) p++;
}
if (j < run_count)
@@ -505,19 +515,17 @@ struct gvar
~accelerator_t () { table.destroy (); }
private:
- struct x_getter { static float get (const contour_point_t &p) { return p.x; } };
- struct y_getter { static float get (const contour_point_t &p) { return p.y; } };
- template <typename T>
static float infer_delta (const hb_array_t<contour_point_t> points,
const hb_array_t<contour_point_t> deltas,
- unsigned int target, unsigned int prev, unsigned int next)
+ unsigned int target, unsigned int prev, unsigned int next,
+ float contour_point_t::*m)
{
- float target_val = T::get (points[target]);
- float prev_val = T::get (points[prev]);
- float next_val = T::get (points[next]);
- float prev_delta = T::get (deltas[prev]);
- float next_delta = T::get (deltas[next]);
+ float target_val = points[target].*m;
+ float prev_val = points[prev].*m;
+ float next_val = points[next].*m;
+ float prev_delta = deltas[prev].*m;
+ float next_delta = deltas[next].*m;
if (prev_val == next_val)
return (prev_delta == next_delta) ? prev_delta : 0.f;
@@ -528,7 +536,7 @@ struct gvar
/* linear interpolation */
float r = (target_val - prev_val) / (next_val - prev_val);
- return (1.f - r) * prev_delta + r * next_delta;
+ return prev_delta + r * (next_delta - prev_delta);
}
static unsigned int next_index (unsigned int i, unsigned int start, unsigned int end)
@@ -538,8 +546,7 @@ struct gvar
bool apply_deltas_to_points (hb_codepoint_t glyph, hb_font_t *font,
const hb_array_t<contour_point_t> points) const
{
- /* num_coords should exactly match gvar's axisCount due to how GlyphVariationData tuples are aligned */
- if (!font->num_coords || font->num_coords != table->axisCount) return true;
+ if (!font->num_coords) return true;
if (unlikely (glyph >= table->glyphCount)) return true;
@@ -553,21 +560,25 @@ struct gvar
/* Save original points for inferred delta calculation */
contour_point_vector_t orig_points;
- orig_points.resize (points.length);
+ if (unlikely (!orig_points.resize (points.length))) return false;
for (unsigned int i = 0; i < orig_points.length; i++)
- orig_points[i] = points[i];
+ orig_points.arrayZ[i] = points.arrayZ[i];
contour_point_vector_t deltas; /* flag is used to indicate referenced point */
- deltas.resize (points.length);
+ if (unlikely (!deltas.resize (points.length))) return false;
hb_vector_t<unsigned> end_points;
for (unsigned i = 0; i < points.length; ++i)
if (points[i].is_end_point)
end_points.push (i);
- int *coords = font->coords;
- unsigned num_coords = font->num_coords;
+ auto coords = hb_array (font->coords, font->num_coords);
+ unsigned num_coords = table->axisCount;
hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
+
+ hb_vector_t<unsigned int> private_indices;
+ hb_vector_t<int> x_deltas;
+ hb_vector_t<int> y_deltas;
do
{
float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples);
@@ -577,33 +588,30 @@ struct gvar
if (unlikely (!iterator.var_data_bytes.check_range (p, length)))
return false;
- hb_bytes_t bytes ((const char *) p, length);
- hb_vector_t<unsigned int> private_indices;
+ const HBUINT8 *end = p + length;
+
bool has_private_points = iterator.current_tuple->has_private_points ();
if (has_private_points &&
- !GlyphVariationData::unpack_points (p, private_indices, bytes))
+ !GlyphVariationData::unpack_points (p, private_indices, end))
return false;
const hb_array_t<unsigned int> &indices = has_private_points ? private_indices : shared_indices;
bool apply_to_all = (indices.length == 0);
unsigned int num_deltas = apply_to_all ? points.length : indices.length;
- hb_vector_t<int> x_deltas;
- x_deltas.resize (num_deltas);
- if (!GlyphVariationData::unpack_deltas (p, x_deltas, bytes))
- return false;
- hb_vector_t<int> y_deltas;
- y_deltas.resize (num_deltas);
- if (!GlyphVariationData::unpack_deltas (p, y_deltas, bytes))
- return false;
+ if (unlikely (!x_deltas.resize (num_deltas))) return false;
+ if (unlikely (!GlyphVariationData::unpack_deltas (p, x_deltas, end))) return false;
+ if (unlikely (!y_deltas.resize (num_deltas))) return false;
+ if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false;
for (unsigned int i = 0; i < deltas.length; i++)
deltas[i].init ();
for (unsigned int i = 0; i < num_deltas; i++)
{
unsigned int pt_index = apply_to_all ? i : indices[i];
- deltas[pt_index].flag = 1; /* this point is referenced, i.e., explicit deltas specified */
- deltas[pt_index].x += x_deltas[i] * scalar;
- deltas[pt_index].y += y_deltas[i] * scalar;
+ if (unlikely (pt_index >= deltas.length)) continue;
+ deltas.arrayZ[pt_index].flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+ deltas.arrayZ[pt_index].x += x_deltas.arrayZ[i] * scalar;
+ deltas.arrayZ[pt_index].y += y_deltas.arrayZ[i] * scalar;
}
/* infer deltas for unreferenced points */
@@ -647,20 +655,20 @@ struct gvar
{
i = next_index (i, start_point, end_point);
if (i == next) break;
- deltas[i].x = infer_delta<x_getter> (orig_points.as_array (), deltas.as_array (), i, prev, next);
- deltas[i].y = infer_delta<y_getter> (orig_points.as_array (), deltas.as_array (), i, prev, next);
+ deltas[i].x = infer_delta (orig_points.as_array (), deltas.as_array (), i, prev, next, &contour_point_t::x);
+ deltas[i].y = infer_delta (orig_points.as_array (), deltas.as_array (), i, prev, next, &contour_point_t::y);
if (--unref_count == 0) goto no_more_gaps;
}
}
-no_more_gaps:
+ no_more_gaps:
start_point = end_point + 1;
}
/* apply specified / inferred deltas to points */
for (unsigned int i = 0; i < points.length; i++)
{
- points[i].x += deltas[i].x;
- points[i].y += deltas[i].y;
+ points.arrayZ[i].x += deltas.arrayZ[i].x;
+ points.arrayZ[i].y += deltas.arrayZ[i].y;
}
} while (iterator.move_to_next ());
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh
index e9d90352f0..56efcdbee9 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh
@@ -319,10 +319,15 @@ struct HVARVVAR
hvar_plan.index_map_plans.as_array ()));
}
- float get_advance_var (hb_codepoint_t glyph, hb_font_t *font) const
+ float get_advance_var (hb_codepoint_t glyph,
+ hb_font_t *font,
+ VariationStore::cache_t *store_cache = nullptr) const
{
uint32_t varidx = (this+advMap).map (glyph);
- return (this+varStore).get_delta (varidx, font->coords, font->num_coords);
+ return (this+varStore).get_delta (varidx,
+ font->coords,
+ font->num_coords,
+ store_cache);
}
float get_side_bearing_var (hb_codepoint_t glyph,
@@ -335,7 +340,7 @@ struct HVARVVAR
bool has_side_bearing_deltas () const { return lsbMap && rsbMap; }
- protected:
+ public:
FixedVersion<>version; /* Version of the metrics variation table
* initially set to 0x00010000u */
Offset32To<VariationStore>
diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh
index ce9ff90bb4..683a441ec3 100644
--- a/thirdparty/harfbuzz/src/hb-repacker.hh
+++ b/thirdparty/harfbuzz/src/hb-repacker.hh
@@ -32,1033 +32,18 @@
#include "hb-priority-queue.hh"
#include "hb-serialize.hh"
#include "hb-vector.hh"
+#include "graph/graph.hh"
+#include "graph/serialize.hh"
+
+using graph::graph_t;
/*
* For a detailed writeup on the overflow resolution algorithm see:
* docs/repacker.md
*/
-struct graph_t
-{
- struct vertex_t
- {
- hb_serialize_context_t::object_t obj;
- int64_t distance = 0 ;
- int64_t space = 0 ;
- hb_vector_t<unsigned> parents;
- unsigned start = 0;
- unsigned end = 0;
- unsigned priority = 0;
-
- friend void swap (vertex_t& a, vertex_t& b)
- {
- hb_swap (a.obj, b.obj);
- hb_swap (a.distance, b.distance);
- hb_swap (a.space, b.space);
- hb_swap (a.parents, b.parents);
- hb_swap (a.start, b.start);
- hb_swap (a.end, b.end);
- hb_swap (a.priority, b.priority);
- }
-
- bool is_shared () const
- {
- return parents.length > 1;
- }
-
- unsigned incoming_edges () const
- {
- return parents.length;
- }
-
- void remove_parent (unsigned parent_index)
- {
- for (unsigned i = 0; i < parents.length; i++)
- {
- if (parents[i] != parent_index) continue;
- parents.remove (i);
- break;
- }
- }
-
- void remap_parents (const hb_vector_t<unsigned>& id_map)
- {
- for (unsigned i = 0; i < parents.length; i++)
- parents[i] = id_map[parents[i]];
- }
-
- void remap_parent (unsigned old_index, unsigned new_index)
- {
- for (unsigned i = 0; i < parents.length; i++)
- {
- if (parents[i] == old_index)
- parents[i] = new_index;
- }
- }
-
- bool is_leaf () const
- {
- return !obj.real_links.length && !obj.virtual_links.length;
- }
-
- bool raise_priority ()
- {
- if (has_max_priority ()) return false;
- priority++;
- return true;
- }
-
- bool has_max_priority () const {
- return priority >= 3;
- }
-
- int64_t modified_distance (unsigned order) const
- {
- // TODO(garretrieger): once priority is high enough, should try
- // setting distance = 0 which will force to sort immediately after
- // it's parent where possible.
-
- int64_t modified_distance =
- hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF);
- if (has_max_priority ()) {
- modified_distance = 0;
- }
- return (modified_distance << 18) | (0x003FFFF & order);
- }
-
- int64_t distance_modifier () const
- {
- if (!priority) return 0;
- int64_t table_size = obj.tail - obj.head;
-
- if (priority == 1)
- return -table_size / 2;
-
- return -table_size;
- }
- };
-
- struct overflow_record_t
- {
- unsigned parent;
- unsigned child;
- };
-
- /*
- * A topological sorting of an object graph. Ordered
- * in reverse serialization order (first object in the
- * serialization is at the end of the list). This matches
- * the 'packed' object stack used internally in the
- * serializer
- */
- template<typename T>
- graph_t (const T& objects)
- : parents_invalid (true),
- distance_invalid (true),
- positions_invalid (true),
- successful (true)
- {
- num_roots_for_space_.push (1);
- bool removed_nil = false;
- vertices_.alloc (objects.length);
- vertices_scratch_.alloc (objects.length);
- for (unsigned i = 0; i < objects.length; i++)
- {
- // TODO(grieger): check all links point to valid objects.
-
- // If this graph came from a serialization buffer object 0 is the
- // nil object. We don't need it for our purposes here so drop it.
- if (i == 0 && !objects[i])
- {
- removed_nil = true;
- continue;
- }
-
- vertex_t* v = vertices_.push ();
- if (check_success (!vertices_.in_error ()))
- v->obj = *objects[i];
- if (!removed_nil) continue;
- // Fix indices to account for removed nil object.
- for (auto& l : v->obj.all_links_writer ()) {
- l.objidx--;
- }
- }
- }
-
- ~graph_t ()
- {
- vertices_.fini ();
- }
-
- bool in_error () const
- {
- return !successful ||
- vertices_.in_error () ||
- num_roots_for_space_.in_error ();
- }
-
- const vertex_t& root () const
- {
- return vertices_[root_idx ()];
- }
-
- unsigned root_idx () const
- {
- // Object graphs are in reverse order, the first object is at the end
- // of the vector. Since the graph is topologically sorted it's safe to
- // assume the first object has no incoming edges.
- return vertices_.length - 1;
- }
-
- const hb_serialize_context_t::object_t& object(unsigned i) const
- {
- return vertices_[i].obj;
- }
-
- /*
- * serialize graph into the provided serialization buffer.
- */
- hb_blob_t* serialize () const
- {
- hb_vector_t<char> buffer;
- size_t size = serialized_length ();
- if (!buffer.alloc (size)) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer.");
- return nullptr;
- }
- hb_serialize_context_t c((void *) buffer, size);
-
- c.start_serialize<void> ();
- for (unsigned i = 0; i < vertices_.length; i++) {
- c.push ();
-
- size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
- char* start = c.allocate_size <char> (size);
- if (!start) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space.");
- return nullptr;
- }
-
- memcpy (start, vertices_[i].obj.head, size);
-
- // Only real links needs to be serialized.
- for (const auto& link : vertices_[i].obj.real_links)
- serialize_link (link, start, &c);
-
- // All duplications are already encoded in the graph, so don't
- // enable sharing during packing.
- c.pop_pack (false);
- }
- c.end_serialize ();
-
- if (c.in_error ()) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Error during serialization. Err flag: %d",
- c.errors);
- return nullptr;
- }
-
- return c.copy_blob ();
- }
-
- /*
- * Generates a new topological sorting of graph ordered by the shortest
- * distance to each node.
- */
- void sort_shortest_distance ()
- {
- positions_invalid = true;
-
- if (vertices_.length <= 1) {
- // Graph of 1 or less doesn't need sorting.
- return;
- }
-
- update_distances ();
-
- hb_priority_queue_t queue;
- hb_vector_t<vertex_t> &sorted_graph = vertices_scratch_;
- if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
- hb_vector_t<unsigned> id_map;
- if (unlikely (!check_success (id_map.resize (vertices_.length)))) return;
-
- hb_vector_t<unsigned> removed_edges;
- if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return;
- update_parents ();
-
- queue.insert (root ().modified_distance (0), root_idx ());
- int new_id = root_idx ();
- unsigned order = 1;
- while (!queue.in_error () && !queue.is_empty ())
- {
- unsigned next_id = queue.pop_minimum().second;
-
- hb_swap (sorted_graph[new_id], vertices_[next_id]);
- const vertex_t& next = sorted_graph[new_id];
-
- id_map[next_id] = new_id--;
-
- for (const auto& link : next.obj.all_links ()) {
- removed_edges[link.objidx]++;
- if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx]))
- // Add the order that the links were encountered to the priority.
- // This ensures that ties between priorities objects are broken in a consistent
- // way. More specifically this is set up so that if a set of objects have the same
- // distance they'll be added to the topological order in the order that they are
- // referenced from the parent object.
- queue.insert (vertices_[link.objidx].modified_distance (order++),
- link.objidx);
- }
- }
-
- check_success (!queue.in_error ());
- check_success (!sorted_graph.in_error ());
- if (!check_success (new_id == -1))
- print_orphaned_nodes ();
-
- remap_all_obj_indices (id_map, &sorted_graph);
-
- hb_swap (vertices_, sorted_graph);
- }
-
- /*
- * Assign unique space numbers to each connected subgraph of 32 bit offset(s).
- */
- bool assign_32bit_spaces ()
- {
- unsigned root_index = root_idx ();
- hb_set_t visited;
- hb_set_t roots;
- for (unsigned i = 0; i <= root_index; i++)
- {
- // Only real links can form 32 bit spaces
- for (auto& l : vertices_[i].obj.real_links)
- {
- if (l.width == 4 && !l.is_signed)
- {
- roots.add (l.objidx);
- find_subgraph (l.objidx, visited);
- }
- }
- }
-
- // Mark everything not in the subgraphs of 32 bit roots as visited.
- // This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs.
- visited.invert ();
-
- if (!roots) return false;
-
- 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);
- for (unsigned root : connected_roots)
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Subgraph %u gets space %u", root, next_space);
- vertices_[root].space = next_space;
- num_roots_for_space_[next_space] = num_roots_for_space_[next_space] + 1;
- distance_invalid = true;
- positions_invalid = true;
- }
-
- // TODO(grieger): special case for GSUB/GPOS use extension promotions to move 16 bit space
- // into the 32 bit space as needed, instead of using isolation.
- }
-
-
-
- return true;
- }
-
- /*
- * Isolates the subgraph of nodes reachable from root. Any links to nodes in the subgraph
- * that originate from outside of the subgraph will be removed by duplicating the linked to
- * object.
- *
- * Indices stored in roots will be updated if any of the roots are duplicated to new indices.
- */
- bool isolate_subgraph (hb_set_t& roots)
- {
- update_parents ();
- hb_hashmap_t<unsigned, unsigned> subgraph;
-
- // incoming edges to root_idx should be all 32 bit in length so we don't need to de-dup these
- // set the subgraph incoming edge count to match all of root_idx's incoming edges
- hb_set_t parents;
- for (unsigned root_idx : roots)
- {
- subgraph.set (root_idx, wide_parents (root_idx, parents));
- find_subgraph (root_idx, subgraph);
- }
-
- unsigned original_root_idx = root_idx ();
- hb_hashmap_t<unsigned, unsigned> index_map;
- bool made_changes = false;
- for (auto entry : subgraph.iter ())
- {
- const auto& node = vertices_[entry.first];
- unsigned subgraph_incoming_edges = entry.second;
-
- if (subgraph_incoming_edges < node.incoming_edges ())
- {
- // Only de-dup objects with incoming links from outside the subgraph.
- made_changes = true;
- duplicate_subgraph (entry.first, index_map);
- }
- }
-
- if (!made_changes)
- return false;
-
- if (original_root_idx != root_idx ()
- && parents.has (original_root_idx))
- {
- // If the root idx has changed since parents was determined, update root idx in parents
- parents.add (root_idx ());
- parents.del (original_root_idx);
- }
-
- auto new_subgraph =
- + subgraph.keys ()
- | hb_map([&] (unsigned node_idx) {
- if (index_map.has (node_idx)) return index_map[node_idx];
- return node_idx;
- })
- ;
-
- remap_obj_indices (index_map, new_subgraph);
- remap_obj_indices (index_map, parents.iter (), true);
-
- // Update roots set with new indices as needed.
- unsigned next = HB_SET_VALUE_INVALID;
- while (roots.next (&next))
- {
- if (index_map.has (next))
- {
- roots.del (next);
- roots.add (index_map[next]);
- }
- }
-
- return true;
- }
-
- void find_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& subgraph)
- {
- for (const auto& link : vertices_[node_idx].obj.all_links ())
- {
- if (subgraph.has (link.objidx))
- {
- subgraph.set (link.objidx, subgraph[link.objidx] + 1);
- continue;
- }
- subgraph.set (link.objidx, 1);
- find_subgraph (link.objidx, subgraph);
- }
- }
-
- void find_subgraph (unsigned node_idx, hb_set_t& subgraph)
- {
- if (subgraph.has (node_idx)) return;
- subgraph.add (node_idx);
- for (const auto& link : vertices_[node_idx].obj.all_links ())
- find_subgraph (link.objidx, subgraph);
- }
-
- /*
- * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign
- * links. index_map is updated with mappings from old id to new id. If a duplication has already
- * been performed for a given index, then it will be skipped.
- */
- void duplicate_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& index_map)
- {
- if (index_map.has (node_idx))
- return;
-
- index_map.set (node_idx, duplicate (node_idx));
- for (const auto& l : object (node_idx).all_links ()) {
- duplicate_subgraph (l.objidx, index_map);
- }
- }
-
- /*
- * Creates a copy of node_idx and returns it's new index.
- */
- unsigned duplicate (unsigned node_idx)
- {
- positions_invalid = true;
- distance_invalid = true;
-
- auto* clone = vertices_.push ();
- auto& child = vertices_[node_idx];
- if (vertices_.in_error ()) {
- return -1;
- }
-
- clone->obj.head = child.obj.head;
- clone->obj.tail = child.obj.tail;
- clone->distance = child.distance;
- clone->space = child.space;
- clone->parents.reset ();
-
- unsigned clone_idx = vertices_.length - 2;
- for (const auto& l : child.obj.real_links)
- {
- clone->obj.real_links.push (l);
- vertices_[l.objidx].parents.push (clone_idx);
- }
- for (const auto& l : child.obj.virtual_links)
- {
- clone->obj.virtual_links.push (l);
- vertices_[l.objidx].parents.push (clone_idx);
- }
-
- check_success (!clone->obj.real_links.in_error ());
- check_success (!clone->obj.virtual_links.in_error ());
-
- // The last object is the root of the graph, so swap back the root to the end.
- // The root's obj idx does change, however since it's root nothing else refers to it.
- // all other obj idx's will be unaffected.
- hb_swap (vertices_[vertices_.length - 2], *clone);
-
- // Since the root moved, update the parents arrays of all children on the root.
- for (const auto& l : root ().obj.all_links ())
- vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ());
-
- return clone_idx;
- }
-
- /*
- * Creates a copy of child and re-assigns the link from
- * parent to the clone. The copy is a shallow copy, objects
- * linked from child are not duplicated.
- */
- bool duplicate (unsigned parent_idx, unsigned child_idx)
- {
- update_parents ();
-
- unsigned links_to_child = 0;
- for (const auto& l : vertices_[parent_idx].obj.all_links ())
- {
- if (l.objidx == child_idx) links_to_child++;
- }
-
- if (vertices_[child_idx].incoming_edges () <= links_to_child)
- {
- // Can't duplicate this node, doing so would orphan the original one as all remaining links
- // to child are from parent.
- DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %d => %d",
- parent_idx, child_idx);
- return false;
- }
-
- DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d",
- parent_idx, child_idx);
-
- unsigned clone_idx = duplicate (child_idx);
- if (clone_idx == (unsigned) -1) return false;
- // duplicate shifts the root node idx, so if parent_idx was root update it.
- if (parent_idx == clone_idx) parent_idx++;
-
- auto& parent = vertices_[parent_idx];
- for (auto& l : parent.obj.all_links_writer ())
- {
- if (l.objidx != child_idx)
- continue;
-
- reassign_link (l, parent_idx, clone_idx);
- }
-
- return true;
- }
-
- /*
- * Raises the sorting priority of all children.
- */
- bool raise_childrens_priority (unsigned parent_idx)
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %d",
- parent_idx);
- // This operation doesn't change ordering until a sort is run, so no need
- // to invalidate positions. It does not change graph structure so no need
- // to update distances or edge counts.
- auto& parent = vertices_[parent_idx].obj;
- bool made_change = false;
- for (auto& l : parent.all_links_writer ())
- made_change |= vertices_[l.objidx].raise_priority ();
- return made_change;
- }
-
- /*
- * Will any offsets overflow on graph when it's serialized?
- */
- bool will_overflow (hb_vector_t<overflow_record_t>* overflows = nullptr)
- {
- if (overflows) overflows->resize (0);
- update_positions ();
-
- for (int parent_idx = vertices_.length - 1; parent_idx >= 0; parent_idx--)
- {
- // Don't need to check virtual links for overflow
- for (const auto& link : vertices_[parent_idx].obj.real_links)
- {
- int64_t offset = compute_offset (parent_idx, link);
- if (is_valid_offset (offset, link))
- continue;
-
- if (!overflows) return true;
-
- overflow_record_t r;
- r.parent = parent_idx;
- r.child = link.objidx;
- overflows->push (r);
- }
- }
-
- if (!overflows) return false;
- return overflows->length;
- }
-
- void print_orphaned_nodes ()
- {
- if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
-
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected.");
- parents_invalid = true;
- update_parents();
-
- for (unsigned i = 0; i < root_idx (); i++)
- {
- const auto& v = vertices_[i];
- if (!v.parents)
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i);
- }
- }
-
- void print_overflows (const hb_vector_t<overflow_record_t>& overflows)
- {
- if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
-
- update_parents ();
- int limit = 10;
- for (const auto& o : overflows)
- {
- if (!limit--) break;
- const auto& parent = vertices_[o.parent];
- const auto& child = vertices_[o.child];
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- " overflow from "
- "%4d (%4d in, %4d out, space %2d) => "
- "%4d (%4d in, %4d out, space %2d)",
- o.parent,
- parent.incoming_edges (),
- parent.obj.real_links.length + parent.obj.virtual_links.length,
- space_for (o.parent),
- o.child,
- child.incoming_edges (),
- child.obj.real_links.length + child.obj.virtual_links.length,
- space_for (o.child));
- }
- if (overflows.length > 10) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %d more overflows.", overflows.length - 10);
- }
- }
-
- unsigned num_roots_for_space (unsigned space) const
- {
- return num_roots_for_space_[space];
- }
-
- unsigned next_space () const
- {
- return num_roots_for_space_.length;
- }
-
- void move_to_new_space (const hb_set_t& indices)
- {
- num_roots_for_space_.push (0);
- unsigned new_space = num_roots_for_space_.length - 1;
-
- for (unsigned index : indices) {
- auto& node = vertices_[index];
- num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1;
- num_roots_for_space_[new_space] = num_roots_for_space_[new_space] + 1;
- node.space = new_space;
- distance_invalid = true;
- positions_invalid = true;
- }
- }
-
- unsigned space_for (unsigned index, unsigned* root = nullptr) const
- {
- const auto& node = vertices_[index];
- if (node.space)
- {
- if (root != nullptr)
- *root = index;
- return node.space;
- }
-
- if (!node.parents)
- {
- if (root)
- *root = index;
- return 0;
- }
-
- return space_for (node.parents[0], root);
- }
-
- void err_other_error () { this->successful = false; }
-
- private:
-
- size_t serialized_length () const {
- size_t total_size = 0;
- for (unsigned i = 0; i < vertices_.length; i++) {
- size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
- total_size += size;
- }
- return total_size;
- }
-
- /*
- * Returns the numbers of incoming edges that are 32bits wide.
- */
- unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const
- {
- unsigned count = 0;
- hb_set_t visited;
- for (unsigned p : vertices_[node_idx].parents)
- {
- if (visited.has (p)) continue;
- visited.add (p);
-
- // Only real links can be wide
- for (const auto& l : vertices_[p].obj.real_links)
- {
- if (l.objidx == node_idx && l.width == 4 && !l.is_signed)
- {
- count++;
- parents.add (p);
- }
- }
- }
- return count;
- }
-
- bool check_success (bool success)
- { return this->successful && (success || (err_other_error (), false)); }
-
- /*
- * Creates a map from objid to # of incoming edges.
- */
- void update_parents ()
- {
- if (!parents_invalid) return;
-
- for (unsigned i = 0; i < vertices_.length; i++)
- vertices_[i].parents.reset ();
-
- for (unsigned p = 0; p < vertices_.length; p++)
- {
- for (auto& l : vertices_[p].obj.all_links ())
- {
- vertices_[l.objidx].parents.push (p);
- }
- }
-
- parents_invalid = false;
- }
-
- /*
- * compute the serialized start and end positions for each vertex.
- */
- void update_positions ()
- {
- if (!positions_invalid) return;
-
- unsigned current_pos = 0;
- for (int i = root_idx (); i >= 0; i--)
- {
- auto& v = vertices_[i];
- v.start = current_pos;
- current_pos += v.obj.tail - v.obj.head;
- v.end = current_pos;
- }
-
- positions_invalid = false;
- }
-
- /*
- * Finds the distance to each object in the graph
- * from the initial node.
- */
- void update_distances ()
- {
- if (!distance_invalid) return;
-
- // Uses Dijkstra's algorithm to find all of the shortest distances.
- // https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
- //
- // Implementation Note:
- // Since our priority queue doesn't support fast priority decreases
- // we instead just add new entries into the queue when a priority changes.
- // 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 fibonacci queue) with a fast decrease priority.
- for (unsigned i = 0; i < vertices_.length; i++)
- {
- if (i == vertices_.length - 1)
- vertices_[i].distance = 0;
- else
- vertices_[i].distance = hb_int_max (int64_t);
- }
-
- hb_priority_queue_t queue;
- queue.insert (0, vertices_.length - 1);
-
- hb_vector_t<bool> visited;
- visited.resize (vertices_.length);
-
- while (!queue.in_error () && !queue.is_empty ())
- {
- unsigned next_idx = queue.pop_minimum ().second;
- if (visited[next_idx]) continue;
- const auto& next = vertices_[next_idx];
- int64_t next_distance = vertices_[next_idx].distance;
- visited[next_idx] = true;
-
- for (const auto& link : next.obj.all_links ())
- {
- if (visited[link.objidx]) continue;
-
- const auto& child = vertices_[link.objidx].obj;
- unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide
- int64_t child_weight = (child.tail - child.head) +
- ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1);
- int64_t child_distance = next_distance + child_weight;
-
- if (child_distance < vertices_[link.objidx].distance)
- {
- vertices_[link.objidx].distance = child_distance;
- queue.insert (child_distance, link.objidx);
- }
- }
- }
-
- check_success (!queue.in_error ());
- if (!check_success (queue.is_empty ()))
- {
- print_orphaned_nodes ();
- return;
- }
-
- distance_invalid = false;
- }
-
- int64_t compute_offset (
- unsigned parent_idx,
- const hb_serialize_context_t::object_t::link_t& link) const
- {
- const auto& parent = vertices_[parent_idx];
- const auto& child = vertices_[link.objidx];
- int64_t offset = 0;
- switch ((hb_serialize_context_t::whence_t) link.whence) {
- case hb_serialize_context_t::whence_t::Head:
- offset = child.start - parent.start; break;
- case hb_serialize_context_t::whence_t::Tail:
- offset = child.start - parent.end; break;
- case hb_serialize_context_t::whence_t::Absolute:
- offset = child.start; break;
- }
-
- assert (offset >= link.bias);
- offset -= link.bias;
- return offset;
- }
-
- bool is_valid_offset (int64_t offset,
- const hb_serialize_context_t::object_t::link_t& link) const
- {
- if (unlikely (!link.width))
- // Virtual links can't overflow.
- return link.is_signed || offset >= 0;
-
- if (link.is_signed)
- {
- if (link.width == 4)
- return offset >= -((int64_t) 1 << 31) && offset < ((int64_t) 1 << 31);
- else
- return offset >= -(1 << 15) && offset < (1 << 15);
- }
- else
- {
- if (link.width == 4)
- return offset >= 0 && offset < ((int64_t) 1 << 32);
- else if (link.width == 3)
- return offset >= 0 && offset < ((int32_t) 1 << 24);
- else
- return offset >= 0 && offset < (1 << 16);
- }
- }
-
- /*
- * Updates a link in the graph to point to a different object. Corrects the
- * parents vector on the previous and new child nodes.
- */
- void reassign_link (hb_serialize_context_t::object_t::link_t& link,
- unsigned parent_idx,
- unsigned new_idx)
- {
- unsigned old_idx = link.objidx;
- link.objidx = new_idx;
- vertices_[old_idx].remove_parent (parent_idx);
- vertices_[new_idx].parents.push (parent_idx);
- }
-
- /*
- * Updates all objidx's in all links using the provided mapping. Corrects incoming edge counts.
- */
- template<typename Iterator, hb_requires (hb_is_iterator (Iterator))>
- void remap_obj_indices (const hb_hashmap_t<unsigned, unsigned>& id_map,
- Iterator subgraph,
- bool only_wide = false)
- {
- if (!id_map) return;
- for (unsigned i : subgraph)
- {
- for (auto& link : vertices_[i].obj.all_links_writer ())
- {
- if (!id_map.has (link.objidx)) continue;
- if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
-
- reassign_link (link, i, id_map[link.objidx]);
- }
- }
- }
-
- /*
- * Updates all objidx's in all links using the provided mapping.
- */
- void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
- hb_vector_t<vertex_t>* sorted_graph) const
- {
- for (unsigned i = 0; i < sorted_graph->length; i++)
- {
- (*sorted_graph)[i].remap_parents (id_map);
- for (auto& link : (*sorted_graph)[i].obj.all_links_writer ())
- {
- link.objidx = id_map[link.objidx];
- }
- }
- }
-
- template <typename O> void
- serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link,
- char* head,
- hb_serialize_context_t* c) const
- {
- OT::Offset<O>* offset = reinterpret_cast<OT::Offset<O>*> (head + link.position);
- *offset = 0;
- c->add_link (*offset,
- // serializer has an extra nil object at the start of the
- // object array. So all id's are +1 of what our id's are.
- link.objidx + 1,
- (hb_serialize_context_t::whence_t) link.whence,
- link.bias);
- }
-
- void serialize_link (const hb_serialize_context_t::object_t::link_t& link,
- char* head,
- hb_serialize_context_t* c) const
- {
- switch (link.width)
- {
- case 0:
- // Virtual links aren't serialized.
- return;
- case 4:
- if (link.is_signed)
- {
- serialize_link_of_type<OT::HBINT32> (link, head, c);
- } else {
- serialize_link_of_type<OT::HBUINT32> (link, head, c);
- }
- return;
- case 2:
- if (link.is_signed)
- {
- serialize_link_of_type<OT::HBINT16> (link, head, c);
- } else {
- serialize_link_of_type<OT::HBUINT16> (link, head, c);
- }
- return;
- case 3:
- serialize_link_of_type<OT::HBUINT24> (link, head, c);
- return;
- default:
- // Unexpected link width.
- assert (0);
- }
- }
-
- /*
- * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped.
- * For this search the graph is treated as being undirected.
- *
- * Connected targets will be added to connected and removed from targets. All visited nodes
- * will be added to visited.
- */
- void find_connected_nodes (unsigned start_idx,
- hb_set_t& targets,
- 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);
-
- if (targets.has (start_idx))
- {
- targets.del (start_idx);
- connected.add (start_idx);
- }
-
- const auto& v = vertices_[start_idx];
-
- // Graph is treated as undirected so search children and parents of start_idx
- for (const auto& l : v.obj.all_links ())
- find_connected_nodes (l.objidx, targets, visited, connected);
-
- for (unsigned p : v.parents)
- find_connected_nodes (p, targets, visited, connected);
- }
-
- public:
- // TODO(garretrieger): make private, will need to move most of offset overflow code into graph.
- hb_vector_t<vertex_t> vertices_;
- hb_vector_t<vertex_t> vertices_scratch_;
- private:
- bool parents_invalid;
- bool distance_invalid;
- bool positions_invalid;
- bool successful;
- hb_vector_t<unsigned> num_roots_for_space_;
-};
static inline
-bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& overflows,
+bool _try_isolating_subgraphs (const hb_vector_t<graph::overflow_record_t>& overflows,
graph_t& sorted_graph)
{
unsigned space = 0;
@@ -1066,7 +51,7 @@ bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& ov
for (int i = overflows.length - 1; i >= 0; i--)
{
- const graph_t::overflow_record_t& r = overflows[i];
+ const graph::overflow_record_t& r = overflows[i];
unsigned root;
unsigned overflow_space = sorted_graph.space_for (r.parent, &root);
@@ -1108,7 +93,7 @@ bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& ov
}
static inline
-bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows,
+bool _process_overflows (const hb_vector_t<graph::overflow_record_t>& overflows,
hb_set_t& priority_bumped_parents,
graph_t& sorted_graph)
{
@@ -1117,7 +102,7 @@ bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflow
// Try resolving the furthest overflows first.
for (int i = overflows.length - 1; i >= 0; i--)
{
- const graph_t::overflow_record_t& r = overflows[i];
+ const graph::overflow_record_t& r = overflows[i];
const auto& child = sorted_graph.vertices_[r.child];
if (child.is_shared ())
{
@@ -1173,19 +158,18 @@ inline hb_blob_t*
hb_resolve_overflows (const T& packed,
hb_tag_t table_tag,
unsigned max_rounds = 20) {
- // Kahn sort is ~twice as fast as shortest distance sort and works for many fonts
- // so try it first to save time.
graph_t sorted_graph (packed);
- if (!sorted_graph.will_overflow ())
+ sorted_graph.sort_shortest_distance ();
+
+ bool will_overflow = graph::will_overflow (sorted_graph);
+ if (!will_overflow)
{
- return sorted_graph.serialize ();
+ return graph::serialize (sorted_graph);
}
- sorted_graph.sort_shortest_distance ();
-
if ((table_tag == HB_OT_TAG_GPOS
|| table_tag == HB_OT_TAG_GSUB)
- && sorted_graph.will_overflow ())
+ && will_overflow)
{
DEBUG_MSG (SUBSET_REPACK, nullptr, "Assigning spaces to 32 bit subgraphs.");
if (sorted_graph.assign_32bit_spaces ())
@@ -1193,13 +177,13 @@ hb_resolve_overflows (const T& packed,
}
unsigned round = 0;
- hb_vector_t<graph_t::overflow_record_t> overflows;
+ hb_vector_t<graph::overflow_record_t> overflows;
// TODO(garretrieger): select a good limit for max rounds.
while (!sorted_graph.in_error ()
- && sorted_graph.will_overflow (&overflows)
+ && graph::will_overflow (sorted_graph, &overflows)
&& round++ < max_rounds) {
DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Overflow resolution round %d ===", round);
- sorted_graph.print_overflows (overflows);
+ print_overflows (sorted_graph, overflows);
hb_set_t priority_bumped_parents;
@@ -1221,13 +205,13 @@ hb_resolve_overflows (const T& packed,
return nullptr;
}
- if (sorted_graph.will_overflow ())
+ if (graph::will_overflow (sorted_graph))
{
DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed.");
return nullptr;
}
- return sorted_graph.serialize ();
+ return graph::serialize (sorted_graph);
}
#endif /* HB_REPACKER_HH */
diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh
index 5663b290c3..cecdcdeb74 100644
--- a/thirdparty/harfbuzz/src/hb-serialize.hh
+++ b/thirdparty/harfbuzz/src/hb-serialize.hh
@@ -695,7 +695,7 @@ struct hb_serialize_context_t
check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW);
}
- public: /* TODO Make private. */
+ public:
char *start, *head, *tail, *end;
unsigned int debug_depth;
hb_serialize_error_t errors;
@@ -719,9 +719,7 @@ struct hb_serialize_context_t
hb_vector_t<object_t *> packed;
/* Map view of packed objects. */
- hb_hashmap_t<const object_t *, objidx_t,
- const object_t *, objidx_t,
- nullptr, 0> packed_map;
+ hb_hashmap_t<const object_t *, objidx_t> packed_map;
};
#endif /* HB_SERIALIZE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-set-digest.hh b/thirdparty/harfbuzz/src/hb-set-digest.hh
index 7d4979b73b..fab36216e4 100644
--- a/thirdparty/harfbuzz/src/hb-set-digest.hh
+++ b/thirdparty/harfbuzz/src/hb-set-digest.hh
@@ -30,7 +30,7 @@
#include "hb.hh"
/*
- * The set digests here implement various "filters" that support
+ * The set-digests here implement various "filters" that support
* "approximate member query". Conceptually these are like Bloom
* Filter and Quotient Filter, however, much smaller, faster, and
* designed to fit the requirements of our uses for glyph coverage
@@ -40,13 +40,25 @@
* set of glyphs, but fully flooded and ineffective if coverage is
* all over the place.
*
- * The frozen-set can be used instead of a digest, to trade more
- * memory for 100% accuracy, but in practice, that doesn't look like
- * an attractive trade-off.
+ * The way these are used is that the filter is first populated by
+ * a lookup's or subtable's Coverage table(s), and then when we
+ * want to apply the lookup or subtable to a glyph, before trying
+ * to apply, we ask the filter if the glyph may be covered. If it's
+ * not, we return early.
+ *
+ * We use these filters both at the lookup-level, and then again,
+ * at the subtable-level. Both have performance win.
+ *
+ * The main filter we use is a combination of three bits-pattern
+ * filters. A bits-pattern filter checks a number of bits (5 or 6)
+ * of the input number (glyph-id in this case) and checks whether
+ * its pattern is amongst the patterns of any of the accepted values.
+ * The accepted patterns are represented as a "long" integer. The
+ * check is done using four bitwise operations only.
*/
template <typename mask_t, unsigned int shift>
-struct hb_set_digest_lowest_bits_t
+struct hb_set_digest_bits_pattern_t
{
static constexpr unsigned mask_bytes = sizeof (mask_t);
static constexpr unsigned mask_bits = sizeof (mask_t) * 8;
@@ -102,7 +114,7 @@ struct hb_set_digest_lowest_bits_t
bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
bool may_have (hb_codepoint_t g) const
- { return !!(mask & mask_for (g)); }
+ { return mask & mask_for (g); }
private:
@@ -171,11 +183,11 @@ struct hb_set_digest_combiner_t
using hb_set_digest_t =
hb_set_digest_combiner_t
<
- hb_set_digest_lowest_bits_t<unsigned long, 4>,
+ hb_set_digest_bits_pattern_t<unsigned long, 4>,
hb_set_digest_combiner_t
<
- hb_set_digest_lowest_bits_t<unsigned long, 0>,
- hb_set_digest_lowest_bits_t<unsigned long, 9>
+ hb_set_digest_bits_pattern_t<unsigned long, 0>,
+ hb_set_digest_bits_pattern_t<unsigned long, 9>
>
>
;
diff --git a/thirdparty/harfbuzz/src/hb-set.cc b/thirdparty/harfbuzz/src/hb-set.cc
index 0e2c1f77ef..2d458294f8 100644
--- a/thirdparty/harfbuzz/src/hb-set.cc
+++ b/thirdparty/harfbuzz/src/hb-set.cc
@@ -40,7 +40,7 @@
/**
- * hb_set_create: (Xconstructor)
+ * hb_set_create:
*
* Creates a new, initially empty set.
*
@@ -186,6 +186,7 @@ hb_set_t *
hb_set_copy (const hb_set_t *set)
{
hb_set_t *copy = hb_set_create ();
+ if (unlikely (!copy)) return nullptr;
copy->set (*set);
return copy;
}
@@ -359,6 +360,23 @@ hb_set_is_equal (const hb_set_t *set,
}
/**
+ * hb_set_hash:
+ * @set: A set
+ *
+ * Creates a hash representing @set.
+ *
+ * Return value:
+ * A hash of @set.
+ *
+ * Since: 4.4.0
+ **/
+HB_EXTERN unsigned int
+hb_set_hash (const hb_set_t *set)
+{
+ return set->hash ();
+}
+
+/**
* hb_set_is_subset:
* @set: A set
* @larger_set: Another set
diff --git a/thirdparty/harfbuzz/src/hb-set.h b/thirdparty/harfbuzz/src/hb-set.h
index 10ce7c10d4..56902c267e 100644
--- a/thirdparty/harfbuzz/src/hb-set.h
+++ b/thirdparty/harfbuzz/src/hb-set.h
@@ -128,6 +128,9 @@ HB_EXTERN hb_bool_t
hb_set_is_equal (const hb_set_t *set,
const hb_set_t *other);
+HB_EXTERN unsigned int
+hb_set_hash (const hb_set_t *set);
+
HB_EXTERN hb_bool_t
hb_set_is_subset (const hb_set_t *set,
const hb_set_t *larger_set);
diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh
index 6025626363..7eb5e19a2a 100644
--- a/thirdparty/harfbuzz/src/hb-set.hh
+++ b/thirdparty/harfbuzz/src/hb-set.hh
@@ -166,7 +166,6 @@ struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t>
~hb_set_t () = default;
hb_set_t () : sparseset () {};
- hb_set_t (std::nullptr_t) : hb_set_t () {};
hb_set_t (const hb_set_t &o) : sparseset ((sparseset &) o) {};
hb_set_t (hb_set_t&& o) : sparseset (std::move ((sparseset &) o)) {}
hb_set_t& operator = (const hb_set_t&) = default;
diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.cc b/thirdparty/harfbuzz/src/hb-shape-plan.cc
index 66332165c3..0af07825fc 100644
--- a/thirdparty/harfbuzz/src/hb-shape-plan.cc
+++ b/thirdparty/harfbuzz/src/hb-shape-plan.cc
@@ -170,7 +170,7 @@ hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
/**
- * hb_shape_plan_create: (Xconstructor)
+ * hb_shape_plan_create:
* @face: #hb_face_t to use
* @props: The #hb_segment_properties_t of the segment
* @user_features: (array length=num_user_features): The list of user-selected features
@@ -198,7 +198,7 @@ hb_shape_plan_create (hb_face_t *face,
}
/**
- * hb_shape_plan_create2: (Xconstructor)
+ * hb_shape_plan_create2:
* @face: #hb_face_t to use
* @props: The #hb_segment_properties_t of the segment
* @user_features: (array length=num_user_features): The list of user-selected features
@@ -231,7 +231,8 @@ hb_shape_plan_create2 (hb_face_t *face,
num_coords,
shaper_list);
- assert (props->direction != HB_DIRECTION_INVALID);
+ if (unlikely (props->direction == HB_DIRECTION_INVALID))
+ return hb_shape_plan_get_empty ();
hb_shape_plan_t *shape_plan;
diff --git a/thirdparty/harfbuzz/src/hb-shape.cc b/thirdparty/harfbuzz/src/hb-shape.cc
index 3407e1af42..14ec92828f 100644
--- a/thirdparty/harfbuzz/src/hb-shape.cc
+++ b/thirdparty/harfbuzz/src/hb-shape.cc
@@ -50,7 +50,7 @@
static inline void free_static_shaper_list ();
-static const char *nil_shaper_list[] = {nullptr};
+static const char * const nil_shaper_list[] = {nullptr};
static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *,
hb_shaper_list_lazy_loader_t>
@@ -73,7 +73,7 @@ static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *,
}
static void destroy (const char **l)
{ hb_free (l); }
- static const char ** get_null ()
+ static const char * const * get_null ()
{ return nil_shaper_list; }
} static_shaper_list;
@@ -126,6 +126,11 @@ hb_shape_full (hb_font_t *font,
unsigned int num_features,
const char * const *shaper_list)
{
+ if (unlikely (!buffer->len))
+ return true;
+
+ buffer->enter ();
+
hb_buffer_t *text_buffer = nullptr;
if (buffer->flags & HB_BUFFER_FLAG_VERIFY)
{
@@ -137,12 +142,19 @@ hb_shape_full (hb_font_t *font,
features, num_features,
font->coords, font->num_coords,
shaper_list);
+
hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
+
+ if (buffer->max_ops <= 0)
+ buffer->shaping_failed = true;
+
hb_shape_plan_destroy (shape_plan);
if (text_buffer)
{
- if (res && !buffer->verify (text_buffer,
+ if (res && buffer->successful && !buffer->shaping_failed
+ && text_buffer->successful
+ && !buffer->verify (text_buffer,
font,
features,
num_features,
@@ -151,6 +163,8 @@ hb_shape_full (hb_font_t *font,
hb_buffer_destroy (text_buffer);
}
+ buffer->leave ();
+
return res;
}
diff --git a/thirdparty/harfbuzz/src/hb-shaper.cc b/thirdparty/harfbuzz/src/hb-shaper.cc
index a11ed83afd..da4253ed64 100644
--- a/thirdparty/harfbuzz/src/hb-shaper.cc
+++ b/thirdparty/harfbuzz/src/hb-shaper.cc
@@ -29,18 +29,18 @@
#include "hb-machinery.hh"
-static const hb_shaper_entry_t all_shapers[] = {
+static const hb_shaper_entry_t _hb_all_shapers[] = {
#define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
};
#ifndef HB_NO_SHAPER
-static_assert (0 != ARRAY_LENGTH_CONST (all_shapers), "No shaper enabled.");
+static_assert (0 != ARRAY_LENGTH_CONST (_hb_all_shapers), "No shaper enabled.");
#endif
static inline void free_static_shapers ();
-static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_t,
+static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<hb_shaper_entry_t,
hb_shapers_lazy_loader_t>
{
static hb_shaper_entry_t *create ()
@@ -49,11 +49,11 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_
if (!env || !*env)
return nullptr;
- hb_shaper_entry_t *shapers = (hb_shaper_entry_t *) hb_calloc (1, sizeof (all_shapers));
+ hb_shaper_entry_t *shapers = (hb_shaper_entry_t *) hb_calloc (1, sizeof (_hb_all_shapers));
if (unlikely (!shapers))
return nullptr;
- memcpy (shapers, all_shapers, sizeof (all_shapers));
+ memcpy (shapers, _hb_all_shapers, sizeof (_hb_all_shapers));
/* Reorder shaper list to prefer requested shapers. */
unsigned int i = 0;
@@ -64,7 +64,7 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_
if (!end)
end = p + strlen (p);
- for (unsigned int j = i; j < ARRAY_LENGTH (all_shapers); j++)
+ for (unsigned int j = i; j < ARRAY_LENGTH (_hb_all_shapers); j++)
if (end - p == (int) strlen (shapers[j].name) &&
0 == strncmp (shapers[j].name, p, end - p))
{
@@ -85,8 +85,8 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_
return shapers;
}
- static void destroy (const hb_shaper_entry_t *p) { hb_free ((void *) p); }
- static const hb_shaper_entry_t *get_null () { return all_shapers; }
+ static void destroy (hb_shaper_entry_t *p) { hb_free (p); }
+ static const hb_shaper_entry_t *get_null () { return _hb_all_shapers; }
} static_shapers;
static inline
diff --git a/thirdparty/harfbuzz/src/hb-static.cc b/thirdparty/harfbuzz/src/hb-static.cc
index 7cc51be611..5c5ecce880 100644
--- a/thirdparty/harfbuzz/src/hb-static.cc
+++ b/thirdparty/harfbuzz/src/hb-static.cc
@@ -53,6 +53,9 @@ DEFINE_NULL_NAMESPACE_BYTES (AAT, SettingName) = {0xFF,0xFF, 0xFF,0xFF};
const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF};
+/* hb_map_t */
+
+const hb_codepoint_t minus_1 = -1;
/* hb_face_t */
diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh
index ae155b4e3c..bb9f27eec1 100644
--- a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh
+++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh
@@ -44,7 +44,8 @@ struct str_encoder_t
void encode_byte (unsigned char b)
{
- if (unlikely (buff.push (b) == &Crap (unsigned char)))
+ buff.push (b);
+ if (unlikely (buff.in_error ()))
set_error ();
}
diff --git a/thirdparty/harfbuzz/src/hb-subset-input.cc b/thirdparty/harfbuzz/src/hb-subset-input.cc
index 4885280996..028ddf9035 100644
--- a/thirdparty/harfbuzz/src/hb-subset-input.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-input.cc
@@ -140,7 +140,20 @@ hb_subset_input_create_or_fail (void)
HB_TAG ('r', 't', 'l', 'a'),
HB_TAG ('r', 't', 'l', 'm'),
- //Complex shapers
+ //random
+ HB_TAG ('r', 'a', 'n', 'd'),
+
+ //justify
+ HB_TAG ('j', 'a', 'l', 't'), // HarfBuzz doesn't use; others might
+
+ //private
+ HB_TAG ('H', 'a', 'r', 'f'),
+ HB_TAG ('H', 'A', 'R', 'F'),
+ HB_TAG ('B', 'u', 'z', 'z'),
+ HB_TAG ('B', 'U', 'Z', 'Z'),
+
+ //shapers
+
//arabic
HB_TAG ('i', 'n', 'i', 't'),
HB_TAG ('m', 'e', 'd', 'i'),
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc
index a62ae8e024..4e3bb1d477 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc
@@ -41,9 +41,9 @@
#include "hb-ot-math-table.hh"
using OT::Layout::GSUB::GSUB;
+using OT::Layout::GPOS;
-
-typedef hb_hashmap_t<unsigned, hb_set_t *> script_langsys_map;
+typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map;
#ifndef HB_NO_SUBSET_CFF
static inline void
_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
@@ -204,7 +204,7 @@ static inline void
hb_map_t *layout_variation_idx_map)
{
hb_blob_ptr_t<OT::GDEF> gdef = hb_sanitize_context_t ().reference_table<OT::GDEF> (face);
- hb_blob_ptr_t<OT::GPOS> gpos = hb_sanitize_context_t ().reference_table<OT::GPOS> (face);
+ hb_blob_ptr_t<GPOS> gpos = hb_sanitize_context_t ().reference_table<GPOS> (face);
if (!gdef->has_data ())
{
@@ -347,13 +347,42 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes,
}
}
+#ifndef HB_COMPOSITE_OPERATIONS_PER_GLYPH
+#define HB_COMPOSITE_OPERATIONS_PER_GLYPH 64
+#endif
+
+static unsigned
+_glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf,
+ hb_codepoint_t gid,
+ hb_set_t *gids_to_retain,
+ int operation_count,
+ unsigned depth = 0)
+{
+ if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
+ if (unlikely (--operation_count < 0)) return operation_count;
+ /* Check if is already visited */
+ if (gids_to_retain->has (gid)) return operation_count;
+
+ gids_to_retain->add (gid);
+
+ for (auto item : glyf.glyph_for_gid (gid).get_composite_iterator ())
+ operation_count =
+ _glyf_add_gid_and_children (glyf,
+ item.glyphIndex,
+ gids_to_retain,
+ operation_count,
+ depth);
+
+ return operation_count;
+}
+
static void
_populate_gids_to_retain (hb_subset_plan_t* plan,
bool close_over_gsub,
bool close_over_gpos,
bool close_over_gdef)
{
- OT::glyf::accelerator_t glyf (plan->source);
+ OT::glyf_accelerator_t glyf (plan->source);
#ifndef HB_NO_SUBSET_CFF
OT::cff1::accelerator_t cff (plan->source);
#endif
@@ -374,7 +403,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
plan->gsub_langsys);
if (close_over_gpos)
- _closure_glyphs_lookups_features<OT::GPOS> (
+ _closure_glyphs_lookups_features<GPOS> (
plan->source,
plan->_glyphset_gsub,
plan->layout_features,
@@ -398,7 +427,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
* composite glyphs. */
if (glyf.has_data ())
for (hb_codepoint_t gid : cur_glyphset)
- glyf.add_gid_and_children (gid, plan->_glyphset);
+ _glyf_add_gid_and_children (glyf, gid, plan->_glyphset,
+ cur_glyphset.get_population () * HB_COMPOSITE_OPERATIONS_PER_GLYPH);
else
plan->_glyphset->union_ (cur_glyphset);
#ifndef HB_NO_SUBSET_CFF
@@ -630,9 +660,6 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
if (plan->gsub_langsys)
{
- for (auto _ : plan->gsub_langsys->iter ())
- hb_set_destroy (_.second);
-
hb_object_destroy (plan->gsub_langsys);
plan->gsub_langsys->fini_shallow ();
hb_free (plan->gsub_langsys);
@@ -640,9 +667,6 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
if (plan->gpos_langsys)
{
- for (auto _ : plan->gpos_langsys->iter ())
- hb_set_destroy (_.second);
-
hb_object_destroy (plan->gpos_langsys);
plan->gpos_langsys->fini_shallow ();
hb_free (plan->gpos_langsys);
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh
index cb567b769e..2aaf19c61d 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.hh
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh
@@ -87,8 +87,8 @@ struct hb_subset_plan_t
hb_map_t *gpos_lookups;
//active langsys we'd like to retain
- hb_hashmap_t<unsigned, hb_set_t *> *gsub_langsys;
- hb_hashmap_t<unsigned, hb_set_t *> *gpos_langsys;
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *gsub_langsys;
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *gpos_langsys;
//active features after removing redundant langsys and prune_features
hb_map_t *gsub_features;
diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc
index 31ddb4f894..10c572c2f7 100644
--- a/thirdparty/harfbuzz/src/hb-subset.cc
+++ b/thirdparty/harfbuzz/src/hb-subset.cc
@@ -56,6 +56,7 @@
#include "hb-repacker.hh"
using OT::Layout::GSUB::GSUB;
+using OT::Layout::GPOS;
/**
* SECTION:hb-subset
@@ -78,6 +79,108 @@ using OT::Layout::GSUB::GSUB;
* retain glyph ids option and configure the subset to pass through the layout tables untouched.
*/
+/*
+ * The list of tables in the open type spec. Used to check for tables that may need handling
+ * if we are unable to list the tables in a face.
+ */
+static hb_tag_t known_tables[] {
+ HB_TAG ('a', 'v', 'a', 'r'),
+ HB_OT_TAG_BASE,
+ HB_OT_TAG_CBDT,
+ HB_OT_TAG_CBLC,
+ HB_OT_TAG_cff1,
+ HB_OT_TAG_cff2,
+ HB_OT_TAG_cmap,
+ HB_OT_TAG_COLR,
+ HB_OT_TAG_CPAL,
+ HB_TAG ('c', 'v', 'a', 'r'),
+ HB_TAG ('c', 'v', 't', ' '),
+ HB_TAG ('D', 'S', 'I', 'G'),
+ HB_TAG ('E', 'B', 'D', 'T'),
+ HB_TAG ('E', 'B', 'L', 'C'),
+ HB_TAG ('E', 'B', 'S', 'C'),
+ HB_TAG ('f', 'p', 'g', 'm'),
+ HB_TAG ('f', 'v', 'a', 'r'),
+ HB_TAG ('g', 'a', 's', 'p'),
+ HB_OT_TAG_GDEF,
+ HB_OT_TAG_glyf,
+ HB_OT_TAG_GPOS,
+ HB_OT_TAG_GSUB,
+ HB_OT_TAG_gvar,
+ HB_OT_TAG_hdmx,
+ HB_OT_TAG_head,
+ HB_OT_TAG_hhea,
+ HB_OT_TAG_hmtx,
+ HB_OT_TAG_HVAR,
+ HB_OT_TAG_JSTF,
+ HB_TAG ('k', 'e', 'r', 'n'),
+ HB_OT_TAG_loca,
+ HB_TAG ('L', 'T', 'S', 'H'),
+ HB_OT_TAG_MATH,
+ HB_OT_TAG_maxp,
+ HB_TAG ('M', 'E', 'R', 'G'),
+ HB_TAG ('m', 'e', 't', 'a'),
+ HB_TAG ('M', 'V', 'A', 'R'),
+ HB_TAG ('P', 'C', 'L', 'T'),
+ HB_OT_TAG_post,
+ HB_TAG ('p', 'r', 'e', 'p'),
+ HB_OT_TAG_sbix,
+ HB_TAG ('S', 'T', 'A', 'T'),
+ HB_TAG ('S', 'V', 'G', ' '),
+ HB_TAG ('V', 'D', 'M', 'X'),
+ HB_OT_TAG_vhea,
+ HB_OT_TAG_vmtx,
+ HB_OT_TAG_VORG,
+ HB_OT_TAG_VVAR,
+ HB_OT_TAG_name,
+ HB_OT_TAG_OS2
+};
+
+static bool _table_is_empty (const hb_face_t *face, hb_tag_t tag)
+{
+ hb_blob_t* blob = hb_face_reference_table (face, tag);
+ bool result = (blob == hb_blob_get_empty ());
+ hb_blob_destroy (blob);
+ return result;
+}
+
+static unsigned int
+_get_table_tags (const hb_subset_plan_t* plan,
+ unsigned int start_offset,
+ unsigned int *table_count, /* IN/OUT */
+ hb_tag_t *table_tags /* OUT */)
+{
+ unsigned num_tables = hb_face_get_table_tags (plan->source, 0, nullptr, nullptr);
+ if (num_tables)
+ return hb_face_get_table_tags (plan->source, start_offset, table_count, table_tags);
+
+ // If face has 0 tables associated with it, assume that it was built from
+ // hb_face_create_tables and thus is unable to list its tables. Fallback to
+ // checking each table type we can handle for existence instead.
+ auto it =
+ hb_concat (
+ + hb_array (known_tables)
+ | hb_filter ([&] (hb_tag_t tag) {
+ return !_table_is_empty (plan->source, tag) && !plan->no_subset_tables->has (tag);
+ })
+ | hb_map ([] (hb_tag_t tag) -> hb_tag_t { return tag; }),
+
+ plan->no_subset_tables->iter ()
+ | hb_filter([&] (hb_tag_t tag) {
+ return !_table_is_empty (plan->source, tag);
+ }));
+
+ it += start_offset;
+
+ unsigned num_written = 0;
+ while (bool (it) && num_written < *table_count)
+ table_tags[num_written++] = *it++;
+
+ *table_count = num_written;
+ return num_written;
+}
+
+
static unsigned
_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
unsigned table_len,
@@ -224,9 +327,17 @@ _subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf)
static bool
_is_table_present (hb_face_t *source, hb_tag_t tag)
{
+
+ if (!hb_face_get_table_tags (source, 0, nullptr, nullptr)) {
+ // If face has 0 tables associated with it, assume that it was built from
+ // hb_face_create_tables and thus is unable to list its tables. Fallback to
+ // checking if the blob associated with tag is empty.
+ return !_table_is_empty (source, tag);
+ }
+
hb_tag_t table_tags[32];
unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
- while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables))
+ while (((void) hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables))
{
for (unsigned i = 0; i < num_tables; ++i)
if (table_tags[i] == tag)
@@ -322,7 +433,7 @@ _subset_table (hb_subset_plan_t *plan,
#ifndef HB_NO_SUBSET_LAYOUT
case HB_OT_TAG_GDEF: return _subset<const OT::GDEF> (plan, buf);
case HB_OT_TAG_GSUB: return _subset<const GSUB> (plan, buf);
- case HB_OT_TAG_GPOS: return _subset<const OT::GPOS> (plan, buf);
+ case HB_OT_TAG_GPOS: return _subset<const GPOS> (plan, buf);
case HB_OT_TAG_gvar: return _subset<const OT::gvar> (plan, buf);
case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan, buf);
case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan, buf);
@@ -388,7 +499,8 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan)
unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
hb_vector_t<char> buf;
buf.alloc (4096 - 16);
- while ((hb_face_get_table_tags (plan->source, offset, &num_tables, table_tags), num_tables))
+
+ while (((void) _get_table_tags (plan, offset, &num_tables, table_tags), num_tables))
{
for (unsigned i = 0; i < num_tables; ++i)
{
@@ -400,7 +512,7 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan)
}
offset += num_tables;
}
-end:
+end:
return success ? hb_face_reference (plan->dest) : nullptr;
}
diff --git a/thirdparty/harfbuzz/src/hb-ucd-table.hh b/thirdparty/harfbuzz/src/hb-ucd-table.hh
index 1a4c89c17f..9e76ca460b 100644
--- a/thirdparty/harfbuzz/src/hb-ucd-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ucd-table.hh
@@ -13,7 +13,7 @@
#include "hb.hh"
static const hb_script_t
-_hb_ucd_sc_map[162] =
+_hb_ucd_sc_map[163] =
{
HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED,
HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC,
@@ -96,6 +96,7 @@ _hb_ucd_sc_map[162] =
HB_SCRIPT_YEZIDI, HB_SCRIPT_CYPRO_MINOAN,
HB_SCRIPT_OLD_UYGHUR, HB_SCRIPT_TANGSA,
HB_SCRIPT_TOTO, HB_SCRIPT_VITHKUQI,
+ HB_SCRIPT_MATH,
};
static const uint16_t
_hb_ucd_dm1_p0_map[825] =
diff --git a/thirdparty/harfbuzz/src/hb-unicode.cc b/thirdparty/harfbuzz/src/hb-unicode.cc
index 83ead6398b..05f74b9237 100644
--- a/thirdparty/harfbuzz/src/hb-unicode.cc
+++ b/thirdparty/harfbuzz/src/hb-unicode.cc
@@ -169,7 +169,7 @@ hb_unicode_funcs_get_default ()
#endif
/**
- * hb_unicode_funcs_create: (Xconstructor)
+ * hb_unicode_funcs_create:
* @parent: (nullable): Parent Unicode-functions structure
*
* Creates a new #hb_unicode_funcs_t structure of Unicode functions.
diff --git a/thirdparty/harfbuzz/src/hb-unicode.hh b/thirdparty/harfbuzz/src/hb-unicode.hh
index 4c28bb0cdf..39aaee5baa 100644
--- a/thirdparty/harfbuzz/src/hb-unicode.hh
+++ b/thirdparty/harfbuzz/src/hb-unicode.hh
@@ -105,12 +105,9 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
unsigned int
modified_combining_class (hb_codepoint_t u)
{
- /* XXX This hack belongs to the USE shaper (for Tai Tham):
- * Reorder SAKOT to ensure it comes after any tone marks. */
+ /* Reorder SAKOT to ensure it comes after any tone marks. */
if (unlikely (u == 0x1A60u)) return 254;
-
- /* XXX This hack belongs to the Tibetan shaper:
- * Reorder PADMA to ensure it comes after any vowel marks. */
+ /* Reorder PADMA to ensure it comes after any vowel marks. */
if (unlikely (u == 0x0FC6u)) return 254;
/* Reorder TSA -PHRU to reorder before U+0F74 */
if (unlikely (u == 0x0F39u)) return 127;
diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h
index ae707cde6c..f036a12226 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 3
+#define HB_VERSION_MINOR 4
/**
* 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 "4.3.0"
+#define HB_VERSION_STRING "4.4.1"
/**
* HB_VERSION_ATLEAST:
diff --git a/thirdparty/harfbuzz/src/hb.hh b/thirdparty/harfbuzz/src/hb.hh
index b9f5f71415..8ec638a2b4 100644
--- a/thirdparty/harfbuzz/src/hb.hh
+++ b/thirdparty/harfbuzz/src/hb.hh
@@ -29,7 +29,6 @@
#ifndef HB_HH
#define HB_HH
-
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC
#ifdef _MSC_VER
#pragma warning( disable: 4068 ) /* Unknown pragma */
@@ -65,6 +64,7 @@
#pragma GCC diagnostic error "-Wbitwise-instead-of-logical"
#pragma GCC diagnostic error "-Wcast-align"
#pragma GCC diagnostic error "-Wcast-function-type"
+#pragma GCC diagnostic error "-Wcomma"
#pragma GCC diagnostic error "-Wdelete-non-virtual-dtor"
#pragma GCC diagnostic error "-Wembedded-directive"
#pragma GCC diagnostic error "-Wextra-semi-stmt"
@@ -183,7 +183,7 @@
#include <cassert>
#include <cfloat>
#include <climits>
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
# define _USE_MATH_DEFINES
#endif
#include <cmath>
@@ -470,6 +470,7 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
/* Headers we include for everyone. Keep topologically sorted by dependency.
* They express dependency amongst themselves, but no other file should include
* them directly.*/
+#include "hb-cplusplus.hh"
#include "hb-meta.hh"
#include "hb-mutex.hh"
#include "hb-number.hh"
diff --git a/thirdparty/mbedtls/LICENSE b/thirdparty/mbedtls/LICENSE
index e15ea821d2..d645695673 100644
--- a/thirdparty/mbedtls/LICENSE
+++ b/thirdparty/mbedtls/LICENSE
@@ -1,5 +1,202 @@
-Unless specifically indicated otherwise in a file, Mbed TLS files are provided
-under the Apache License 2.0, or the GNU General Public License v2.0 or later
-(SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later).
-A copy of these licenses can be found in apache-2.0.txt and gpl-2.0.txt
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/thirdparty/mbedtls/apache-2.0.txt b/thirdparty/mbedtls/apache-2.0.txt
deleted file mode 100644
index d645695673..0000000000
--- a/thirdparty/mbedtls/apache-2.0.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/thirdparty/mbedtls/include/mbedtls/aes.h b/thirdparty/mbedtls/include/mbedtls/aes.h
index e280dbb1c6..401ac39de8 100644
--- a/thirdparty/mbedtls/include/mbedtls/aes.h
+++ b/thirdparty/mbedtls/include/mbedtls/aes.h
@@ -564,7 +564,7 @@ int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
* for example, with 96-bit random nonces, you should not encrypt
* more than 2**32 messages with the same key.
*
- * Note that for both stategies, sizes are measured in blocks and
+ * Note that for both strategies, sizes are measured in blocks and
* that an AES block is 16 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
diff --git a/thirdparty/mbedtls/include/mbedtls/aria.h b/thirdparty/mbedtls/include/mbedtls/aria.h
index 226e2dbf3c..d294c47f2d 100644
--- a/thirdparty/mbedtls/include/mbedtls/aria.h
+++ b/thirdparty/mbedtls/include/mbedtls/aria.h
@@ -44,7 +44,7 @@
#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */
#define MBEDTLS_ARIA_BLOCKSIZE 16 /**< ARIA block size in bytes. */
-#define MBEDTLS_ARIA_MAX_ROUNDS 16 /**< Maxiumum number of rounds in ARIA. */
+#define MBEDTLS_ARIA_MAX_ROUNDS 16 /**< Maximum number of rounds in ARIA. */
#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
@@ -321,7 +321,7 @@ int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
* for example, with 96-bit random nonces, you should not encrypt
* more than 2**32 messages with the same key.
*
- * Note that for both stategies, sizes are measured in blocks and
+ * Note that for both strategies, sizes are measured in blocks and
* that an ARIA block is 16 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
diff --git a/thirdparty/mbedtls/include/mbedtls/asn1.h b/thirdparty/mbedtls/include/mbedtls/asn1.h
index 10f7905b7e..5117fc7a41 100644
--- a/thirdparty/mbedtls/include/mbedtls/asn1.h
+++ b/thirdparty/mbedtls/include/mbedtls/asn1.h
@@ -61,7 +61,7 @@
/** Buffer too small when writing ASN.1 data structure. */
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C
-/* \} name */
+/** \} name ASN1 Error codes */
/**
* \name DER constants
@@ -121,8 +121,7 @@
#define MBEDTLS_ASN1_TAG_PC_MASK 0x20
#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F
-/* \} name */
-/* \} addtogroup asn1_module */
+/** \} name DER constants */
/** Returns the size of the binary string, without the trailing \\0 */
#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1)
@@ -210,7 +209,7 @@ mbedtls_asn1_named_data;
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
* would end beyond \p end.
- * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable.
*/
int mbedtls_asn1_get_len( unsigned char **p,
const unsigned char *end,
@@ -235,7 +234,7 @@ int mbedtls_asn1_get_len( unsigned char **p,
* with the requested tag.
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
* would end beyond \p end.
- * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable.
*/
int mbedtls_asn1_get_tag( unsigned char **p,
const unsigned char *end,
@@ -607,6 +606,9 @@ void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
*/
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
+/** \} name Functions to parse ASN.1 data structures */
+/** \} addtogroup asn1_module */
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/bignum.h b/thirdparty/mbedtls/include/mbedtls/bignum.h
index 9d2cff3275..dd594c512d 100644
--- a/thirdparty/mbedtls/include/mbedtls/bignum.h
+++ b/thirdparty/mbedtls/include/mbedtls/bignum.h
@@ -989,7 +989,7 @@ MBEDTLS_DEPRECATED int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
* generate yourself and that are supposed to be prime, then
* \p rounds should be at least the half of the security
* strength of the cryptographic algorithm. On the other hand,
- * if \p X is chosen uniformly or non-adversially (as is the
+ * if \p X is chosen uniformly or non-adversarially (as is the
* case when mbedtls_mpi_gen_prime calls this function), then
* \p rounds can be much lower.
*
diff --git a/thirdparty/mbedtls/include/mbedtls/blowfish.h b/thirdparty/mbedtls/include/mbedtls/blowfish.h
index 77dca70d31..d5f809921f 100644
--- a/thirdparty/mbedtls/include/mbedtls/blowfish.h
+++ b/thirdparty/mbedtls/include/mbedtls/blowfish.h
@@ -185,7 +185,7 @@ int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
* #MBEDTLS_BLOWFISH_DECRYPT for decryption.
* \param length The length of the input data in Bytes.
- * \param iv_off The offset in the initialiation vector.
+ * \param iv_off The offset in the initialization vector.
* The value pointed to must be smaller than \c 8 Bytes.
* It is updated by this function to support the aforementioned
* streaming usage.
@@ -246,7 +246,7 @@ int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
* The recommended way to ensure uniqueness is to use a message
* counter.
*
- * Note that for both stategies, sizes are measured in blocks and
+ * Note that for both strategies, sizes are measured in blocks and
* that a Blowfish block is 8 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
diff --git a/thirdparty/mbedtls/include/mbedtls/camellia.h b/thirdparty/mbedtls/include/mbedtls/camellia.h
index 925a623e47..d39d932fa2 100644
--- a/thirdparty/mbedtls/include/mbedtls/camellia.h
+++ b/thirdparty/mbedtls/include/mbedtls/camellia.h
@@ -273,7 +273,7 @@ int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
* encrypted: for example, with 96-bit random nonces, you should
* not encrypt more than 2**32 messages with the same key.
*
- * Note that for both stategies, sizes are measured in blocks and
+ * Note that for both strategies, sizes are measured in blocks and
* that a CAMELLIA block is \c 16 Bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
diff --git a/thirdparty/mbedtls/include/mbedtls/chachapoly.h b/thirdparty/mbedtls/include/mbedtls/chachapoly.h
index c4ec7b5f2a..ed568bc98b 100644
--- a/thirdparty/mbedtls/include/mbedtls/chachapoly.h
+++ b/thirdparty/mbedtls/include/mbedtls/chachapoly.h
@@ -161,7 +161,7 @@ int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
* \param ctx The ChaCha20-Poly1305 context. This must be initialized
* and bound to a key.
* \param nonce The nonce/IV to use for the message.
- * This must be a redable buffer of length \c 12 Bytes.
+ * This must be a readable buffer of length \c 12 Bytes.
* \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
* #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
*
diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h
index 396fe7dfc2..be5c548e56 100644
--- a/thirdparty/mbedtls/include/mbedtls/check_config.h
+++ b/thirdparty/mbedtls/include/mbedtls/check_config.h
@@ -173,7 +173,11 @@
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
-#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
+#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PKCS5_C) && !defined(MBEDTLS_MD_C)
+#error "MBEDTLS_PKCS5_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
@@ -214,11 +218,32 @@
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too"
#endif
+#if defined(MBEDTLS_CCM_C) && ( \
+ !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
+#error "MBEDTLS_CCM_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_CCM_C) && !defined(MBEDTLS_CIPHER_C)
+#error "MBEDTLS_CCM_C defined, but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_GCM_C) && ( \
- !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
+ !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
+#error "MBEDTLS_GCM_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CIPHER_C)
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_CHACHA20_C)
+#error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_POLY1305_C)
+#error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites"
#endif
@@ -338,11 +363,11 @@
#endif
#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
-#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites"
+#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
-#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites"
+#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
@@ -619,6 +644,18 @@
#error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined, but it cannot coexist with MBEDTLS_USE_PSA_CRYPTO."
#endif
+#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ !defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_ECDSA_C)
+#error "MBEDTLS_PK_C in configuration with MBEDTLS_USE_PSA_CRYPTO and \
+ MBEDTLS_ECDSA_C requires MBEDTLS_PK_WRITE_C to be defined."
+#endif
+
+#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V15) && \
+ !defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_PSA_CRYPTO_C)
+#error "MBEDTLS_PSA_CRYPTO_C, MBEDTLS_RSA_C and MBEDTLS_PKCS1_V15 defined, \
+ but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) )
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
@@ -761,14 +798,14 @@
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
+#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
+#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
diff --git a/thirdparty/mbedtls/include/mbedtls/config.h b/thirdparty/mbedtls/include/mbedtls/config.h
index 87b4e9192e..1cd6eb6634 100644
--- a/thirdparty/mbedtls/include/mbedtls/config.h
+++ b/thirdparty/mbedtls/include/mbedtls/config.h
@@ -128,7 +128,12 @@
* MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and
* MBEDTLS_PLATFORM_STD_TIME.
*
- * Comment if your system does not support time functions
+ * Comment if your system does not support time functions.
+ *
+ * \note If MBEDTLS_TIMING_C is set - to enable the semi-portable timing
+ * interface - timing.c will include time.h on suitable platforms
+ * regardless of the setting of MBEDTLS_HAVE_TIME, unless
+ * MBEDTLS_TIMING_ALT is used. See timing.c for more information.
*/
#define MBEDTLS_HAVE_TIME
@@ -321,7 +326,7 @@
*/
//#define MBEDTLS_CHECK_PARAMS_ASSERT
-/* \} name SECTION: System support */
+/** \} name SECTION: System support */
/**
* \name SECTION: mbed TLS feature support
@@ -395,7 +400,7 @@
//#define MBEDTLS_XTEA_ALT
/*
- * When replacing the elliptic curve module, pleace consider, that it is
+ * When replacing the elliptic curve module, please consider, that it is
* implemented with two .c files:
* - ecp.c
* - ecp_curves.c
@@ -1493,7 +1498,7 @@
* Enable an implementation of SHA-256 that has lower ROM footprint but also
* lower performance.
*
- * The default implementation is meant to be a reasonnable compromise between
+ * The default implementation is meant to be a reasonable compromise between
* performance and size. This version optimizes more aggressively for size at
* the expense of performance. Eg on Cortex-M4 it reduces the size of
* mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
@@ -1658,7 +1663,7 @@
* Enable support for RFC 7627: Session Hash and Extended Master Secret
* Extension.
*
- * This was introduced as "the proper fix" to the Triple Handshake familiy of
+ * This was introduced as "the proper fix" to the Triple Handshake family of
* attacks, but it is recommended to always use it (even if you disable
* renegotiation), since it actually fixes a more fundamental issue in the
* original SSL/TLS design, and has implications beyond Triple Handshake.
@@ -1704,7 +1709,7 @@
* \note This option has no influence on the protection against the
* triple handshake attack. Even if it is disabled, Mbed TLS will
* still ensure that certificates do not change during renegotiation,
- * for exaple by keeping a hash of the peer's certificate.
+ * for example by keeping a hash of the peer's certificate.
*
* Comment this macro to disable storing the peer's certificate
* after the handshake.
@@ -1909,7 +1914,7 @@
* unless you know for sure amplification cannot be a problem in the
* environment in which your server operates.
*
- * \warning Disabling this can ba a security risk! (see above)
+ * \warning Disabling this can be a security risk! (see above)
*
* Requires: MBEDTLS_SSL_PROTO_DTLS
*
@@ -2162,8 +2167,19 @@
* This setting allows support for cryptographic mechanisms through the PSA
* API to be configured separately from support through the mbedtls API.
*
- * Uncomment this to enable use of PSA Crypto configuration settings which
- * can be found in include/psa/crypto_config.h.
+ * When this option is disabled, the PSA API exposes the cryptographic
+ * mechanisms that can be implemented on top of the `mbedtls_xxx` API
+ * configured with `MBEDTLS_XXX` symbols.
+ *
+ * When this option is enabled, the PSA API exposes the cryptographic
+ * mechanisms requested by the `PSA_WANT_XXX` symbols defined in
+ * include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are
+ * automatically enabled if required (i.e. if no PSA driver provides the
+ * mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols
+ * in config.h.
+ *
+ * If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies
+ * an alternative header to include instead of include/psa/crypto_config.h.
*
* If you enable this option and write your own configuration file, you must
* include mbedtls/config_psa.h in your configuration file. The default
@@ -2289,7 +2305,7 @@
* Uncomment to enable use of ZLIB
*/
//#define MBEDTLS_ZLIB_SUPPORT
-/* \} name SECTION: mbed TLS feature support */
+/** \} name SECTION: mbed TLS feature support */
/**
* \name SECTION: mbed TLS modules
@@ -2902,7 +2918,7 @@
*
* Requires: MBEDTLS_MD_C
*
- * Uncomment to enable the HMAC_DRBG random number geerator.
+ * Uncomment to enable the HMAC_DRBG random number generator.
*/
#define MBEDTLS_HMAC_DRBG_C
@@ -3096,7 +3112,7 @@
/**
* \def MBEDTLS_PK_C
*
- * Enable the generic public (asymetric) key layer.
+ * Enable the generic public (asymmetric) key layer.
*
* Module: library/pk.c
* Caller: library/ssl_tls.c
@@ -3112,7 +3128,7 @@
/**
* \def MBEDTLS_PK_PARSE_C
*
- * Enable the generic public (asymetric) key parser.
+ * Enable the generic public (asymmetric) key parser.
*
* Module: library/pkparse.c
* Caller: library/x509_crt.c
@@ -3127,7 +3143,7 @@
/**
* \def MBEDTLS_PK_WRITE_C
*
- * Enable the generic public (asymetric) key writer.
+ * Enable the generic public (asymmetric) key writer.
*
* Module: library/pkwrite.c
* Caller: library/x509write.c
@@ -3466,6 +3482,10 @@
* your own implementation of the whole module by setting
* \c MBEDTLS_TIMING_ALT in the current file.
*
+ * \note The timing module will include time.h on suitable platforms
+ * regardless of the setting of MBEDTLS_HAVE_TIME, unless
+ * MBEDTLS_TIMING_ALT is used. See timing.c for more information.
+ *
* \note See also our Knowledge Base article about porting to a new
* environment:
* https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
@@ -3598,7 +3618,88 @@
*/
#define MBEDTLS_XTEA_C
-/* \} name SECTION: mbed TLS modules */
+/** \} name SECTION: mbed TLS modules */
+
+/**
+ * \name SECTION: General configuration options
+ *
+ * This section contains Mbed TLS build settings that are not associated
+ * with a particular module.
+ *
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_CONFIG_FILE
+ *
+ * If defined, this is a header which will be included instead of
+ * `"mbedtls/config.h"`.
+ * This header file specifies the compile-time configuration of Mbed TLS.
+ * Unlike other configuration options, this one must be defined on the
+ * compiler command line: a definition in `config.h` would have no effect.
+ *
+ * This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
+ * non-standard feature of the C language, so this feature is only available
+ * with compilers that perform macro expansion on an <tt>\#include</tt> line.
+ *
+ * The value of this symbol is typically a path in double quotes, either
+ * absolute or relative to a directory on the include search path.
+ */
+//#define MBEDTLS_CONFIG_FILE "mbedtls/config.h"
+
+/**
+ * \def MBEDTLS_USER_CONFIG_FILE
+ *
+ * If defined, this is a header which will be included after
+ * `"mbedtls/config.h"` or #MBEDTLS_CONFIG_FILE.
+ * This allows you to modify the default configuration, including the ability
+ * to undefine options that are enabled by default.
+ *
+ * This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
+ * non-standard feature of the C language, so this feature is only available
+ * with compilers that perform macro expansion on an <tt>\#include</tt> line.
+ *
+ * The value of this symbol is typically a path in double quotes, either
+ * absolute or relative to a directory on the include search path.
+ */
+//#define MBEDTLS_USER_CONFIG_FILE "/dev/null"
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE
+ *
+ * If defined, this is a header which will be included instead of
+ * `"psa/crypto_config.h"`.
+ * This header file specifies which cryptographic mechanisms are available
+ * through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and
+ * is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled.
+ *
+ * This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
+ * non-standard feature of the C language, so this feature is only available
+ * with compilers that perform macro expansion on an <tt>\#include</tt> line.
+ *
+ * The value of this symbol is typically a path in double quotes, either
+ * absolute or relative to a directory on the include search path.
+ */
+//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h"
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
+ *
+ * If defined, this is a header which will be included after
+ * `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE.
+ * This allows you to modify the default configuration, including the ability
+ * to undefine options that are enabled by default.
+ *
+ * This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
+ * non-standard feature of the C language, so this feature is only available
+ * with compilers that perform macro expansion on an <tt>\#include</tt> line.
+ *
+ * The value of this symbol is typically a path in double quotes, either
+ * absolute or relative to a directory on the include search path.
+ */
+//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null"
+
+/** \} name SECTION: General configuration options */
/**
* \name SECTION: Module configuration options
@@ -3609,11 +3710,15 @@
*
* Our advice is to enable options and change their values here
* only if you have a good reason and know the consequences.
- *
- * Please check the respective header file for documentation on these
- * parameters (to prevent duplicate documentation).
* \{
*/
+/* The Doxygen documentation here is used when a user comments out a
+ * setting and runs doxygen themselves. On the other hand, when we typeset
+ * the full documentation including disabled settings, the documentation
+ * in specific modules' header files is used if present. When editing this
+ * file, make sure that each option is documented in exactly one place,
+ * plus optionally a same-line Doxygen comment here if there is a Doxygen
+ * comment in the specific module. */
/* MPI / BIGNUM options */
//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */
@@ -4002,7 +4107,7 @@
*/
//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
-/* \} name SECTION: Customisation configuration options */
+/** \} name SECTION: Module configuration options */
/* Target and application specific configurations
*
diff --git a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h
index dc4adc896d..e68237a439 100644
--- a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h
+++ b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h
@@ -138,7 +138,7 @@
/**< The maximum size of seed or reseed buffer in bytes. */
#endif
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
#define MBEDTLS_CTR_DRBG_PR_OFF 0
/**< Prediction resistance is disabled. */
diff --git a/thirdparty/mbedtls/include/mbedtls/debug.h b/thirdparty/mbedtls/include/mbedtls/debug.h
index 3c08244f3d..4fc4662d9a 100644
--- a/thirdparty/mbedtls/include/mbedtls/debug.h
+++ b/thirdparty/mbedtls/include/mbedtls/debug.h
@@ -139,7 +139,7 @@ extern "C" {
* discarded.
* (Default value: 0 = No debug )
*
- * \param threshold theshold level of messages to filter on. Messages at a
+ * \param threshold threshold level of messages to filter on. Messages at a
* higher level will be discarded.
* - Debug levels
* - 0 No debug
diff --git a/thirdparty/mbedtls/include/mbedtls/ecjpake.h b/thirdparty/mbedtls/include/mbedtls/ecjpake.h
index 891705d8c4..3564ff8dd3 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecjpake.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecjpake.h
@@ -68,7 +68,7 @@ typedef enum {
* (KeyExchange) as defined by the Thread spec.
*
* In order to benefit from this symmetry, we choose a different naming
- * convetion from the Thread v1.0 spec. Correspondance is indicated in the
+ * convention from the Thread v1.0 spec. Correspondence is indicated in the
* description as a pair C: client name, S: server name
*/
typedef struct mbedtls_ecjpake_context
diff --git a/thirdparty/mbedtls/include/mbedtls/ecp.h b/thirdparty/mbedtls/include/mbedtls/ecp.h
index 0924341e00..64a0bccda0 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecp.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecp.h
@@ -315,7 +315,7 @@ mbedtls_ecp_group;
#if !defined(MBEDTLS_ECP_WINDOW_SIZE)
/*
* Maximum "window" size used for point multiplication.
- * Default: a point where higher memory usage yields disminishing performance
+ * Default: a point where higher memory usage yields diminishing performance
* returns.
* Minimum value: 2. Maximum value: 7.
*
@@ -351,7 +351,7 @@ mbedtls_ecp_group;
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */
#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
#else /* MBEDTLS_ECP_ALT */
#include "ecp_alt.h"
diff --git a/thirdparty/mbedtls/include/mbedtls/entropy.h b/thirdparty/mbedtls/include/mbedtls/entropy.h
index deb3c50300..40259ebc8a 100644
--- a/thirdparty/mbedtls/include/mbedtls/entropy.h
+++ b/thirdparty/mbedtls/include/mbedtls/entropy.h
@@ -75,7 +75,7 @@
#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
#endif
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
diff --git a/thirdparty/mbedtls/include/mbedtls/hkdf.h b/thirdparty/mbedtls/include/mbedtls/hkdf.h
index 223004b8ed..111d960e56 100644
--- a/thirdparty/mbedtls/include/mbedtls/hkdf.h
+++ b/thirdparty/mbedtls/include/mbedtls/hkdf.h
@@ -39,7 +39,7 @@
*/
/** Bad input parameters to function. */
#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80
-/* \} name */
+/** \} name */
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h
index 79132d4d91..6d372b9788 100644
--- a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h
+++ b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h
@@ -74,7 +74,7 @@
#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
#endif
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */
#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */
@@ -207,7 +207,7 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
size_t len );
/**
- * \brief Initilisation of simpified HMAC_DRBG (never reseeds).
+ * \brief Initialisation of simplified HMAC_DRBG (never reseeds).
*
* This function is meant for use in algorithms that need a pseudorandom
* input such as deterministic ECDSA.
diff --git a/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h b/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h
index 233977252a..3954b36ab5 100644
--- a/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h
+++ b/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h
@@ -42,7 +42,7 @@
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */
#endif
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
#define MBEDTLS_MEMORY_VERIFY_NONE 0
#define MBEDTLS_MEMORY_VERIFY_ALLOC (1 << 0)
diff --git a/thirdparty/mbedtls/include/mbedtls/oid.h b/thirdparty/mbedtls/include/mbedtls/oid.h
index 1c39186a49..0186217804 100644
--- a/thirdparty/mbedtls/include/mbedtls/oid.h
+++ b/thirdparty/mbedtls/include/mbedtls/oid.h
@@ -143,7 +143,7 @@
#define MBEDTLS_OID_AT_GIVEN_NAME MBEDTLS_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */
#define MBEDTLS_OID_AT_INITIALS MBEDTLS_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */
#define MBEDTLS_OID_AT_GENERATION_QUALIFIER MBEDTLS_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */
-#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributType:= {id-at 45} */
+#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributeType:= {id-at 45} */
#define MBEDTLS_OID_AT_DN_QUALIFIER MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */
#define MBEDTLS_OID_AT_PSEUDONYM MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */
diff --git a/thirdparty/mbedtls/include/mbedtls/pem.h b/thirdparty/mbedtls/include/mbedtls/pem.h
index dfb4ff218e..daa71c886b 100644
--- a/thirdparty/mbedtls/include/mbedtls/pem.h
+++ b/thirdparty/mbedtls/include/mbedtls/pem.h
@@ -54,7 +54,7 @@
#define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE -0x1400
/** Bad input parameters to function. */
#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA -0x1480
-/* \} name */
+/** \} name PEM Error codes */
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/mbedtls/include/mbedtls/pk.h b/thirdparty/mbedtls/include/mbedtls/pk.h
index 8f2abf2a60..c9a13f484e 100644
--- a/thirdparty/mbedtls/include/mbedtls/pk.h
+++ b/thirdparty/mbedtls/include/mbedtls/pk.h
@@ -217,32 +217,6 @@ typedef struct
typedef void mbedtls_pk_restart_ctx;
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
-#if defined(MBEDTLS_RSA_C)
-/**
- * Quick access to an RSA context inside a PK context.
- *
- * \warning You must make sure the PK context actually holds an RSA context
- * before using this function!
- */
-static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk )
-{
- return( (mbedtls_rsa_context *) (pk).pk_ctx );
-}
-#endif /* MBEDTLS_RSA_C */
-
-#if defined(MBEDTLS_ECP_C)
-/**
- * Quick access to an EC context inside a PK context.
- *
- * \warning You must make sure the PK context actually holds an EC context
- * before using this function!
- */
-static inline mbedtls_ecp_keypair *mbedtls_pk_ec( const mbedtls_pk_context pk )
-{
- return( (mbedtls_ecp_keypair *) (pk).pk_ctx );
-}
-#endif /* MBEDTLS_ECP_C */
-
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/**
* \brief Types for RSA-alt abstraction
@@ -656,6 +630,55 @@ const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx );
*/
mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
+#if defined(MBEDTLS_RSA_C)
+/**
+ * Quick access to an RSA context inside a PK context.
+ *
+ * \warning This function can only be used when the type of the context, as
+ * returned by mbedtls_pk_get_type(), is #MBEDTLS_PK_RSA.
+ * Ensuring that is the caller's responsibility.
+ * Alternatively, you can check whether this function returns NULL.
+ *
+ * \return The internal RSA context held by the PK context, or NULL.
+ */
+static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk )
+{
+ switch( mbedtls_pk_get_type( &pk ) )
+ {
+ case MBEDTLS_PK_RSA:
+ return( (mbedtls_rsa_context *) (pk).pk_ctx );
+ default:
+ return( NULL );
+ }
+}
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_ECP_C)
+/**
+ * Quick access to an EC context inside a PK context.
+ *
+ * \warning This function can only be used when the type of the context, as
+ * returned by mbedtls_pk_get_type(), is #MBEDTLS_PK_ECKEY,
+ * #MBEDTLS_PK_ECKEY_DH, or #MBEDTLS_PK_ECDSA.
+ * Ensuring that is the caller's responsibility.
+ * Alternatively, you can check whether this function returns NULL.
+ *
+ * \return The internal EC context held by the PK context, or NULL.
+ */
+static inline mbedtls_ecp_keypair *mbedtls_pk_ec( const mbedtls_pk_context pk )
+{
+ switch( mbedtls_pk_get_type( &pk ) )
+ {
+ case MBEDTLS_PK_ECKEY:
+ case MBEDTLS_PK_ECKEY_DH:
+ case MBEDTLS_PK_ECDSA:
+ return( (mbedtls_ecp_keypair *) (pk).pk_ctx );
+ default:
+ return( NULL );
+ }
+}
+#endif /* MBEDTLS_ECP_C */
+
#if defined(MBEDTLS_PK_PARSE_C)
/** \ingroup pk_module */
/**
diff --git a/thirdparty/mbedtls/include/mbedtls/platform.h b/thirdparty/mbedtls/include/mbedtls/platform.h
index bdef07498d..06dd192eab 100644
--- a/thirdparty/mbedtls/include/mbedtls/platform.h
+++ b/thirdparty/mbedtls/include/mbedtls/platform.h
@@ -70,7 +70,9 @@ extern "C" {
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#include <stdio.h>
#include <stdlib.h>
+#if defined(MBEDTLS_HAVE_TIME)
#include <time.h>
+#endif
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */
@@ -127,7 +129,7 @@ extern "C" {
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
/*
* The function pointers for calloc and free.
diff --git a/thirdparty/mbedtls/include/mbedtls/platform_time.h b/thirdparty/mbedtls/include/mbedtls/platform_time.h
index 7e7daab692..94055711b2 100644
--- a/thirdparty/mbedtls/include/mbedtls/platform_time.h
+++ b/thirdparty/mbedtls/include/mbedtls/platform_time.h
@@ -32,14 +32,6 @@
extern "C" {
#endif
-/**
- * \name SECTION: Module settings
- *
- * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
- * \{
- */
-
/*
* The time_t datatype
*/
diff --git a/thirdparty/mbedtls/include/mbedtls/platform_util.h b/thirdparty/mbedtls/include/mbedtls/platform_util.h
index f982db8c01..cd112ab58e 100644
--- a/thirdparty/mbedtls/include/mbedtls/platform_util.h
+++ b/thirdparty/mbedtls/include/mbedtls/platform_util.h
@@ -67,7 +67,7 @@ extern "C" {
* \brief User supplied callback function for parameter validation failure.
* See #MBEDTLS_CHECK_PARAMS for context.
*
- * This function will be called unless an alternative treatement
+ * This function will be called unless an alternative treatment
* is defined through the #MBEDTLS_PARAM_FAILED macro.
*
* This function can return, and the operation will be aborted, or
@@ -198,7 +198,7 @@ MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
*
* This macro has an empty expansion. It exists for documentation purposes:
* a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function
- * has been analyzed for return-check usefuless, whereas the lack of
+ * has been analyzed for return-check usefulness, whereas the lack of
* an annotation indicates that the function has not been analyzed and its
* return-check usefulness is unknown.
*/
diff --git a/thirdparty/mbedtls/include/mbedtls/rsa.h b/thirdparty/mbedtls/include/mbedtls/rsa.h
index 3c481e12a1..062df73aa0 100644
--- a/thirdparty/mbedtls/include/mbedtls/rsa.h
+++ b/thirdparty/mbedtls/include/mbedtls/rsa.h
@@ -88,7 +88,7 @@
/*
* The above constants may be used even if the RSA module is compile out,
- * eg for alternative (PKCS#11) RSA implemenations in the PK layers.
+ * eg for alternative (PKCS#11) RSA implementations in the PK layers.
*/
#ifdef __cplusplus
@@ -552,7 +552,7 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
*
* \note Blinding is used if and only if a PRNG is provided.
*
- * \note If blinding is used, both the base of exponentation
+ * \note If blinding is used, both the base of exponentiation
* and the exponent are blinded, providing protection
* against some side-channel attacks.
*
@@ -687,7 +687,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
* mode being set to #MBEDTLS_RSA_PRIVATE and might instead
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
*
- * \param ctx The initnialized RSA context to use.
+ * \param ctx The initialized RSA context to use.
* \param f_rng The RNG function to use. This is needed for padding
* generation and must be provided.
* \param p_rng The RNG context to be passed to \p f_rng. This may
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl.h b/thirdparty/mbedtls/include/mbedtls/ssl.h
index 209dbf6053..5064ec5689 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl.h
@@ -349,7 +349,7 @@
#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1
#endif
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
/*
* Length of the verify data for secure renegotiation
@@ -1152,7 +1152,7 @@ struct mbedtls_ssl_config
#endif
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
- /** Callback to create & write a cookie for ClientHello veirifcation */
+ /** Callback to create & write a cookie for ClientHello verification */
int (*f_cookie_write)( void *, unsigned char **, unsigned char *,
const unsigned char *, size_t );
/** Callback to verify validity of a ClientHello cookie */
@@ -1405,7 +1405,7 @@ struct mbedtls_ssl_context
unsigned char *compress_buf; /*!< zlib data buffer */
#endif /* MBEDTLS_ZLIB_SUPPORT */
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- signed char split_done; /*!< current record already splitted? */
+ signed char split_done; /*!< current record already split? */
#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
/*
@@ -1688,7 +1688,7 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
*
* \note The two most common use cases are:
* - non-blocking I/O, f_recv != NULL, f_recv_timeout == NULL
- * - blocking I/O, f_recv == NULL, f_recv_timout != NULL
+ * - blocking I/O, f_recv == NULL, f_recv_timeout != NULL
*
* \note For DTLS, you need to provide either a non-NULL
* f_recv_timeout callback, or a f_recv that doesn't block.
@@ -1846,7 +1846,7 @@ int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
/**
- * \brief Set the Maximum Tranport Unit (MTU).
+ * \brief Set the Maximum Transport Unit (MTU).
* Special value: 0 means unset (no limit).
* This represents the maximum size of a datagram payload
* handled by the transport layer (usually UDP) as determined
@@ -2387,7 +2387,7 @@ void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode );
* ones going through the authentication-decryption phase.
*
* \note This is a security trade-off related to the fact that it's
- * often relatively easy for an active attacker ot inject UDP
+ * often relatively easy for an active attacker to inject UDP
* datagrams. On one hand, setting a low limit here makes it
* easier for such an attacker to forcibly terminated a
* connection. On the other hand, a high limit or no limit
@@ -2498,7 +2498,7 @@ void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min,
* successfully cached, return 1 otherwise.
*
* \param conf SSL configuration
- * \param p_cache parmater (context) for both callbacks
+ * \param p_cache parameter (context) for both callbacks
* \param f_get_cache session get callback
* \param f_set_cache session set callback
*/
@@ -2529,7 +2529,7 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session
/**
* \brief Load serialized session data into a session structure.
* On client, this can be used for loading saved sessions
- * before resuming them with mbedstls_ssl_set_session().
+ * before resuming them with mbedtls_ssl_set_session().
* On server, this can be used for alternative implementations
* of session cache or session tickets.
*
@@ -2793,7 +2793,7 @@ void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf,
*
* \note On client, only the first call has any effect. That is,
* only one client certificate can be provisioned. The
- * server's preferences in its CertficateRequest message will
+ * server's preferences in its CertificateRequest message will
* be ignored and our only cert will be sent regardless of
* whether it matches those preferences - the server can then
* decide what it wants to do with it.
@@ -3241,7 +3241,7 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
* \param protos Pointer to a NULL-terminated list of supported protocols,
* in decreasing preference order. The pointer to the list is
* recorded by the library for later reference as required, so
- * the lifetime of the table must be atleast as long as the
+ * the lifetime of the table must be at least as long as the
* lifetime of the SSL configuration structure.
*
* \return 0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
@@ -3255,7 +3255,7 @@ int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **prot
*
* \param ssl SSL context
*
- * \return Protcol name, or NULL if no protocol was negotiated.
+ * \return Protocol name, or NULL if no protocol was negotiated.
*/
const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_ALPN */
@@ -3338,7 +3338,7 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
unsigned char *mki_value,
uint16_t mki_len );
/**
- * \brief Get the negotiated DTLS-SRTP informations:
+ * \brief Get the negotiated DTLS-SRTP information:
* Protection profile and MKI value.
*
* \warning This function must be called after the handshake is
@@ -3346,7 +3346,7 @@ int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
* not be trusted or acted upon before the handshake completes.
*
* \param ssl The SSL context to query.
- * \param dtls_srtp_info The negotiated DTLS-SRTP informations:
+ * \param dtls_srtp_info The negotiated DTLS-SRTP information:
* - Protection profile in use.
* A direct mapping of the iana defined value for protection
* profile on an uint16_t.
@@ -3508,7 +3508,7 @@ void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf,
* \c mbedtls_ssl_get_record_expansion().
*
* \note For DTLS, it is also possible to set a limit for the total
- * size of daragrams passed to the transport layer, including
+ * size of datagrams passed to the transport layer, including
* record overhead, see \c mbedtls_ssl_set_mtu().
*
* \param conf SSL configuration
@@ -3568,7 +3568,7 @@ void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets
* initiated by peer
* (Default: MBEDTLS_SSL_RENEGOTIATION_DISABLED)
*
- * \warning It is recommended to always disable renegotation unless you
+ * \warning It is recommended to always disable renegotiation unless you
* know you need it and you know what you're doing. In the
* past, there have been several issues associated with
* renegotiation or a poor understanding of its properties.
@@ -3631,7 +3631,7 @@ void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_
* scenario.
*
* \note With DTLS and server-initiated renegotiation, the
- * HelloRequest is retransmited every time mbedtls_ssl_read() times
+ * HelloRequest is retransmitted every time mbedtls_ssl_read() times
* out or receives Application Data, until:
* - max_records records have beens seen, if it is >= 0, or
* - the number of retransmits that would happen during an
@@ -4263,7 +4263,7 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
* \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed
- * while reseting the context.
+ * while resetting the context.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if a handshake is in
* progress, or there is pending data for reading or sending,
* or the connection does not use DTLS 1.2 with an AEAD
@@ -4357,7 +4357,7 @@ int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
void mbedtls_ssl_config_init( mbedtls_ssl_config *conf );
/**
- * \brief Load reasonnable default SSL configuration values.
+ * \brief Load reasonable default SSL configuration values.
* (You need to call mbedtls_ssl_config_init() first.)
*
* \param conf SSL configuration context
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h
index c6ef2960f4..02eab96d45 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h
@@ -50,7 +50,7 @@
#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */
#endif
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h
index 0a238708e5..2aa373177b 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h
@@ -45,7 +45,7 @@
#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
#endif
-/* \} name SECTION: Module settings */
+/** \} name SECTION: Module settings */
#ifdef __cplusplus
extern "C" {
@@ -84,7 +84,7 @@ int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
* \brief Set expiration delay for cookies
* (Default MBEDTLS_SSL_COOKIE_TIMEOUT)
*
- * \param ctx Cookie contex
+ * \param ctx Cookie context
* \param delay Delay, in seconds if HAVE_TIME, or in number of cookies
* issued in the meantime.
* 0 to disable expiration (NOT recommended)
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h
index 6913dc0f66..46ade67b9c 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h
@@ -934,16 +934,22 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform );
*/
void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl );
void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl );
void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl );
@@ -1023,27 +1029,39 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl );
* following the above definition.
*
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
unsigned update_hs_digest );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl );
void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t *ciphersuite_info );
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex );
/**
@@ -1108,13 +1126,18 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig );
mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash );
unsigned char mbedtls_ssl_hash_from_md_alg( int md );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md );
#if defined(MBEDTLS_ECP_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id );
+MBEDTLS_CHECK_RETURN_CRITICAL
+int mbedtls_ssl_check_curve_tls_id( const mbedtls_ssl_context *ssl, uint16_t tls_id );
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
mbedtls_md_type_t md );
#endif
@@ -1170,6 +1193,7 @@ static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl )
*
* Return 0 if everything is OK, -1 if not.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
const mbedtls_ssl_ciphersuite_t *ciphersuite,
int cert_endpoint,
@@ -1218,21 +1242,26 @@ static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_PROTO_DTLS)
void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl );
void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_resend( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl );
#endif
/* Visible for testing purposes only */
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl );
void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl );
#endif
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
const mbedtls_ssl_session *src );
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1)
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
unsigned char *output,
unsigned char *data, size_t data_len );
@@ -1242,6 +1271,7 @@ int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
/* The hash buffer must have at least MBEDTLS_MD_MAX_SIZE bytes of length. */
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
unsigned char *hash, size_t *hashlen,
unsigned char *data, size_t data_len,
@@ -1254,11 +1284,13 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
#endif
void mbedtls_ssl_transform_init( mbedtls_ssl_transform *transform );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform,
mbedtls_record *rec,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
mbedtls_ssl_transform *transform,
mbedtls_record *rec );
@@ -1276,10 +1308,12 @@ static inline size_t mbedtls_ssl_ep_len( const mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_resend_hello_request( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_PROTO_DTLS */
void mbedtls_ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_check_timer( mbedtls_ssl_context *ssl );
void mbedtls_ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
@@ -1287,6 +1321,7 @@ void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl,
mbedtls_ssl_transform *transform );
void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
@@ -1296,6 +1331,7 @@ void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
void mbedtls_ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_RENEGOTIATION)
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_start_renegotiation( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_RENEGOTIATION */
@@ -1305,4 +1341,12 @@ void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl );
void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight );
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_TEST_HOOKS)
+int mbedtls_ssl_check_dtls_clihlo_cookie(
+ mbedtls_ssl_context *ssl,
+ const unsigned char *cli_id, size_t cli_id_len,
+ const unsigned char *in, size_t in_len,
+ unsigned char *obuf, size_t buf_len, size_t *olen );
+#endif
+
#endif /* ssl_internal.h */
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h
index a882eed23b..8221051b24 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h
@@ -101,7 +101,7 @@ void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx );
* supported. Usually that means a 256-bit key.
*
* \note The lifetime of the keys is twice the lifetime of tickets.
- * It is recommended to pick a reasonnable lifetime so as not
+ * It is recommended to pick a reasonable lifetime so as not
* to negate the benefits of forward secrecy.
*
* \return 0 if successful,
diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h
index b1a92b2bcf..44adcbfe03 100644
--- a/thirdparty/mbedtls/include/mbedtls/version.h
+++ b/thirdparty/mbedtls/include/mbedtls/version.h
@@ -38,16 +38,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 28
-#define MBEDTLS_VERSION_PATCH 0
+#define MBEDTLS_VERSION_PATCH 1
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x021C0000
-#define MBEDTLS_VERSION_STRING "2.28.0"
-#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.28.0"
+#define MBEDTLS_VERSION_NUMBER 0x021C0100
+#define MBEDTLS_VERSION_STRING "2.28.1"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.28.1"
#if defined(MBEDTLS_VERSION_C)
diff --git a/thirdparty/mbedtls/include/mbedtls/x509.h b/thirdparty/mbedtls/include/mbedtls/x509.h
index c177501430..31b78df32f 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509.h
@@ -96,7 +96,7 @@
#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980
/** A fatal error occurred, eg the chain is too long or the vrfy callback failed. */
#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000
-/* \} name */
+/** \} name X509 Error codes */
/**
* \name X509 Verify codes
@@ -124,8 +124,8 @@
#define MBEDTLS_X509_BADCRL_BAD_PK 0x040000 /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
#define MBEDTLS_X509_BADCRL_BAD_KEY 0x080000 /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */
-/* \} name */
-/* \} addtogroup x509_module */
+/** \} name X509 Verify codes */
+/** \} addtogroup x509_module */
/*
* X.509 v3 Subject Alternative Name types.
@@ -255,7 +255,6 @@ typedef struct mbedtls_x509_time
mbedtls_x509_time;
/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */
-/** \} addtogroup x509_module */
/**
* \brief Store the certificate DN in printable form into buf;
@@ -311,6 +310,8 @@ int mbedtls_x509_time_is_past( const mbedtls_x509_time *to );
*/
int mbedtls_x509_time_is_future( const mbedtls_x509_time *from );
+/** \} addtogroup x509_module */
+
#if defined(MBEDTLS_SELF_TEST)
/**
diff --git a/thirdparty/mbedtls/include/mbedtls/x509_crl.h b/thirdparty/mbedtls/include/mbedtls/x509_crl.h
index 7e9e8885f4..9222009019 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509_crl.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509_crl.h
@@ -162,8 +162,8 @@ void mbedtls_x509_crl_init( mbedtls_x509_crl *crl );
*/
void mbedtls_x509_crl_free( mbedtls_x509_crl *crl );
-/* \} name */
-/* \} addtogroup x509_module */
+/** \} name Structures and functions for parsing CRLs */
+/** \} addtogroup x509_module */
#ifdef __cplusplus
}
diff --git a/thirdparty/mbedtls/include/mbedtls/x509_crt.h b/thirdparty/mbedtls/include/mbedtls/x509_crt.h
index 64ccb433ba..0f2885a7ee 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509_crt.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509_crt.h
@@ -107,7 +107,7 @@ mbedtls_x509_crt;
typedef struct mbedtls_x509_san_other_name
{
/**
- * The type_id is an OID as deifned in RFC 5280.
+ * The type_id is an OID as defined in RFC 5280.
* To check the value of the type id, you should use
* \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
*/
@@ -159,7 +159,9 @@ mbedtls_x509_subject_alternative_name;
typedef struct mbedtls_x509_crt_profile
{
uint32_t allowed_mds; /**< MDs for signatures */
- uint32_t allowed_pks; /**< PK algs for signatures */
+ uint32_t allowed_pks; /**< PK algs for public keys;
+ * this applies to all certificates
+ * in the provided chain. */
uint32_t allowed_curves; /**< Elliptic curves for ECDSA */
uint32_t rsa_min_bitlen; /**< Minimum size for RSA keys */
}
@@ -850,8 +852,7 @@ void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
-/* \} name */
-/* \} addtogroup x509_module */
+/** \} name Structures and functions for parsing and writing X.509 certificates */
#if defined(MBEDTLS_X509_CRT_WRITE_C)
/**
@@ -862,7 +863,7 @@ void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx );
void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx );
/**
- * \brief Set the verion for a Certificate
+ * \brief Set the version for a Certificate
* Default: MBEDTLS_X509_CRT_VERSION_3
*
* \param ctx CRT context to use
@@ -978,7 +979,7 @@ int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
* \param is_ca is this a CA certificate
* \param max_pathlen maximum length of certificate chains below this
* certificate (only for CA certificates, -1 is
- * inlimited)
+ * unlimited)
*
* \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
*/
@@ -1087,6 +1088,8 @@ int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *ctx, unsigned char *buf,
#endif /* MBEDTLS_PEM_WRITE_C */
#endif /* MBEDTLS_X509_CRT_WRITE_C */
+/** \} addtogroup x509_module */
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/x509_csr.h b/thirdparty/mbedtls/include/mbedtls/x509_csr.h
index b1dfc21f1f..2a1c046131 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509_csr.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509_csr.h
@@ -151,8 +151,7 @@ void mbedtls_x509_csr_init( mbedtls_x509_csr *csr );
void mbedtls_x509_csr_free( mbedtls_x509_csr *csr );
#endif /* MBEDTLS_X509_CSR_PARSE_C */
-/* \} name */
-/* \} addtogroup x509_module */
+/** \} name Structures and functions for X.509 Certificate Signing Requests (CSR) */
#if defined(MBEDTLS_X509_CSR_WRITE_C)
/**
@@ -182,7 +181,7 @@ int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
* private key used to sign the CSR when writing it)
*
* \param ctx CSR context to use
- * \param key Asymetric key to include
+ * \param key Asymmetric key to include
*/
void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key );
@@ -298,6 +297,8 @@ int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, s
#endif /* MBEDTLS_PEM_WRITE_C */
#endif /* MBEDTLS_X509_CSR_WRITE_C */
+/** \} addtogroup x509_module */
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/library/aes.c b/thirdparty/mbedtls/library/aes.c
index 31824e75cf..03d8b7ea61 100644
--- a/thirdparty/mbedtls/library/aes.c
+++ b/thirdparty/mbedtls/library/aes.c
@@ -1106,7 +1106,7 @@ typedef unsigned char mbedtls_be128[16];
*
* This function multiplies a field element by x in the polynomial field
* representation. It uses 64-bit word operations to gain speed but compensates
- * for machine endianess and hence works correctly on both big and little
+ * for machine endianness and hence works correctly on both big and little
* endian machines.
*/
static void mbedtls_gf128mul_x_ble( unsigned char r[16],
@@ -1206,7 +1206,7 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
unsigned char *prev_output = output - 16;
/* Copy ciphertext bytes from the previous block to our output for each
- * byte of cyphertext we won't steal. At the same time, copy the
+ * byte of ciphertext we won't steal. At the same time, copy the
* remainder of the input for this final round (since the loop bounds
* are the same). */
for( i = 0; i < leftover; i++ )
diff --git a/thirdparty/mbedtls/library/asn1write.c b/thirdparty/mbedtls/library/asn1write.c
index 3811ef27a3..afa26a6be9 100644
--- a/thirdparty/mbedtls/library/asn1write.c
+++ b/thirdparty/mbedtls/library/asn1write.c
@@ -133,6 +133,11 @@ int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedt
//
len = mbedtls_mpi_size( X );
+ /* DER represents 0 with a sign bit (0=nonnegative) and 7 value bits, not
+ * as 0 digits. We need to end up with 020100, not with 0200. */
+ if( len == 0 )
+ len = 1;
+
if( *p < start || (size_t)( *p - start ) < len )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
@@ -472,7 +477,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
cur->val.len = val_len;
}
- if( val != NULL )
+ if( val != NULL && val_len != 0 )
memcpy( cur->val.p, val, val_len );
return( cur );
diff --git a/thirdparty/mbedtls/library/bignum.c b/thirdparty/mbedtls/library/bignum.c
index 62e7f76727..32578e2c68 100644
--- a/thirdparty/mbedtls/library/bignum.c
+++ b/thirdparty/mbedtls/library/bignum.c
@@ -1829,7 +1829,7 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_
/*
* handle trivial cases
*/
- if( b == 1 )
+ if( b == 1 || A->n == 0 )
{
*r = 0;
return( 0 );
@@ -2317,7 +2317,7 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
* TA-TB is even so the division by 2 has an integer result.
* Invariant (I) is preserved since any odd divisor of both TA and TB
* also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
- * also divides TB, and any odd divisior of both TB and |TA-TB|/2 also
+ * also divides TB, and any odd divisor of both TB and |TA-TB|/2 also
* divides TA.
*/
if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
diff --git a/thirdparty/mbedtls/library/cipher.c b/thirdparty/mbedtls/library/cipher.c
index 4ec40d2cac..f3b4bd29ce 100644
--- a/thirdparty/mbedtls/library/cipher.c
+++ b/thirdparty/mbedtls/library/cipher.c
@@ -386,6 +386,12 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CHACHA20_C)
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
{
+ /* Even though the actual_iv_size is overwritten with a correct value
+ * of 12 from the cipher info, return an error to indicate that
+ * the input iv_len is wrong. */
+ if( iv_len != 12 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
iv,
0U ) ) /* Initial counter value */
@@ -393,6 +399,11 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
}
+#if defined(MBEDTLS_CHACHAPOLY_C)
+ if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&
+ iv_len != 12 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#endif
#endif
if ( actual_iv_size != 0 )
diff --git a/thirdparty/mbedtls/library/constant_time.c b/thirdparty/mbedtls/library/constant_time.c
index 18f1b20daa..e276d23ca0 100644
--- a/thirdparty/mbedtls/library/constant_time.c
+++ b/thirdparty/mbedtls/library/constant_time.c
@@ -489,6 +489,12 @@ int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
+ /* Fill the hash buffer in advance with something that is
+ * not a valid hash (barring an attack on the hash and
+ * deliberately-crafted input), in case the caller doesn't
+ * check the return status properly. */
+ memset( output, '!', hash_size );
+
/* For each possible length, compute the hash up to that point */
for( offset = min_data_len; offset <= max_data_len; offset++ )
{
@@ -533,6 +539,13 @@ cleanup:
* about whether the assignment was made or not.
* (Leaking information about the respective sizes of X and Y is ok however.)
*/
+#if defined(_MSC_VER) && defined(_M_ARM64) && (_MSC_FULL_VER < 193131103)
+/*
+ * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
+ * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
+ */
+__declspec(noinline)
+#endif
int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X,
const mbedtls_mpi *Y,
unsigned char assign )
@@ -562,7 +575,7 @@ cleanup:
/*
* Conditionally swap X and Y, without leaking information
* about whether the swap was made or not.
- * Here it is not ok to simply swap the pointers, which whould lead to
+ * Here it is not ok to simply swap the pointers, which would lead to
* different memory access patterns when X and Y are used afterwards.
*/
int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X,
diff --git a/thirdparty/mbedtls/library/constant_time_internal.h b/thirdparty/mbedtls/library/constant_time_internal.h
index bbb3a90670..a550b38fa5 100644
--- a/thirdparty/mbedtls/library/constant_time_internal.h
+++ b/thirdparty/mbedtls/library/constant_time_internal.h
@@ -221,6 +221,13 @@ void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
* offset_secret, but only on \p offset_min, \p offset_max and \p len.
* Functionally equivalent to `memcpy(dst, src + offset_secret, len)`.
*
+ * \note This function reads from \p dest, but the value that
+ * is read does not influence the result and this
+ * function's behavior is well-defined regardless of the
+ * contents of the buffers. This may result in false
+ * positives from static or dynamic analyzers, especially
+ * if \p dest is not initialized.
+ *
* \param dest The destination buffer. This must point to a writable
* buffer of at least \p len bytes.
* \param src The base of the source buffer. This must point to a
diff --git a/thirdparty/mbedtls/library/ctr_drbg.c b/thirdparty/mbedtls/library/ctr_drbg.c
index a604ec0761..a00d66ce87 100644
--- a/thirdparty/mbedtls/library/ctr_drbg.c
+++ b/thirdparty/mbedtls/library/ctr_drbg.c
@@ -828,7 +828,7 @@ static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
return( 1 ); \
}
-#define SELF_TEST_OUPUT_DISCARD_LENGTH 64
+#define SELF_TEST_OUTPUT_DISCARD_LENGTH 64
/*
* Checkup routine
@@ -854,7 +854,7 @@ int mbedtls_ctr_drbg_self_test( int verbose )
(void *) entropy_source_pr,
pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_pr ) ) );
CHK( memcmp( buf, result_pr, sizeof( result_pr ) ) );
@@ -879,7 +879,7 @@ int mbedtls_ctr_drbg_self_test( int verbose )
(void *) entropy_source_nopr,
pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH ) );
CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_nopr ) ) );
CHK( memcmp( buf, result_nopr, sizeof( result_nopr ) ) );
diff --git a/thirdparty/mbedtls/library/ecdh.c b/thirdparty/mbedtls/library/ecdh.c
index 9dfa868063..60c6e429de 100644
--- a/thirdparty/mbedtls/library/ecdh.c
+++ b/thirdparty/mbedtls/library/ecdh.c
@@ -399,7 +399,7 @@ static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx,
}
/*
- * Read the ServerKeyExhange parameters (RFC 4492)
+ * Read the ServerKeyExchange parameters (RFC 4492)
* struct {
* ECParameters curve_params;
* ECPoint public;
diff --git a/thirdparty/mbedtls/library/ecjpake.c b/thirdparty/mbedtls/library/ecjpake.c
index 368b6c7124..0b9bffb93e 100644
--- a/thirdparty/mbedtls/library/ecjpake.c
+++ b/thirdparty/mbedtls/library/ecjpake.c
@@ -435,7 +435,7 @@ cleanup:
/*
* Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
- * Ouputs: verified peer public keys Xa, Xb
+ * Outputs: verified peer public keys Xa, Xb
*/
static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
const mbedtls_ecp_group *grp,
diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c
index 7f9e1045d4..890f364a08 100644
--- a/thirdparty/mbedtls/library/ecp.c
+++ b/thirdparty/mbedtls/library/ecp.c
@@ -1307,7 +1307,7 @@ cleanup:
* For curves in short Weierstrass form, we do all the internal operations in
* Jacobian coordinates.
*
- * For multiplication, we'll use a comb method with coutermeasueres against
+ * For multiplication, we'll use a comb method with countermeasures against
* SPA, hence timing attacks.
*/
@@ -2251,7 +2251,7 @@ static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp,
* This function is mainly responsible for administrative work:
* - managing the restart context if enabled
* - managing the table of precomputed points (passed between the below two
- * functions): allocation, computation, ownership tranfer, freeing.
+ * functions): allocation, computation, ownership transfer, freeing.
*
* It delegates the actual arithmetic work to:
* ecp_precompute_comb() and ecp_mul_comb_with_precomp()
@@ -2422,7 +2422,7 @@ cleanup:
/*
* For Montgomery curves, we do all the internal arithmetic in projective
* coordinates. Import/export of points uses only the x coordinates, which is
- * internaly represented as X / Z.
+ * internally represented as X / Z.
*
* For scalar multiplication, we'll use a Montgomery ladder.
*/
@@ -2592,7 +2592,7 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) );
mbedtls_mpi_free( &R->Y );
- /* RP.X might be sligtly larger than P, so reduce it */
+ /* RP.X might be slightly larger than P, so reduce it */
MOD_ADD( RP.X );
/* Randomize coordinates of the starting point */
diff --git a/thirdparty/mbedtls/library/ecp_curves.c b/thirdparty/mbedtls/library/ecp_curves.c
index ff26a18e8f..2199be6461 100644
--- a/thirdparty/mbedtls/library/ecp_curves.c
+++ b/thirdparty/mbedtls/library/ecp_curves.c
@@ -755,6 +755,8 @@ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
ECP_VALIDATE_RET( grp != NULL );
mbedtls_ecp_group_free( grp );
+ mbedtls_ecp_group_init( grp );
+
grp->id = id;
switch( id )
diff --git a/thirdparty/mbedtls/library/memory_buffer_alloc.c b/thirdparty/mbedtls/library/memory_buffer_alloc.c
index 0d5d27d3de..cc62324bdc 100644
--- a/thirdparty/mbedtls/library/memory_buffer_alloc.c
+++ b/thirdparty/mbedtls/library/memory_buffer_alloc.c
@@ -555,8 +555,8 @@ static void *buffer_alloc_calloc_mutexed( size_t n, size_t size )
static void buffer_alloc_free_mutexed( void *ptr )
{
- /* We have to good option here, but corrupting the heap seems
- * worse than loosing memory. */
+ /* We have no good option here, but corrupting the heap seems
+ * worse than losing memory. */
if( mbedtls_mutex_lock( &heap.mutex ) )
return;
buffer_alloc_free( ptr );
diff --git a/thirdparty/mbedtls/library/mps_common.h b/thirdparty/mbedtls/library/mps_common.h
index d20776f159..668876ccfc 100644
--- a/thirdparty/mbedtls/library/mps_common.h
+++ b/thirdparty/mbedtls/library/mps_common.h
@@ -51,7 +51,7 @@
* the function's behavior is entirely undefined.
* In addition to state integrity, all MPS structures have a more refined
* notion of abstract state that the API operates on. For example, all layers
- * have a notion of 'abtract read state' which indicates if incoming data has
+ * have a notion of 'abstract read state' which indicates if incoming data has
* been passed to the user, e.g. through mps_l2_read_start() for Layer 2
* or mps_l3_read() in Layer 3. After such a call, it doesn't make sense to
* call these reading functions again until the incoming data has been
diff --git a/thirdparty/mbedtls/library/net_sockets.c b/thirdparty/mbedtls/library/net_sockets.c
index 5fbe1f764a..8c765e1c8c 100644
--- a/thirdparty/mbedtls/library/net_sockets.c
+++ b/thirdparty/mbedtls/library/net_sockets.c
@@ -107,7 +107,9 @@ static int wsa_init_done = 0;
#include <stdio.h>
+#if defined(MBEDTLS_HAVE_TIME)
#include <time.h>
+#endif
#include <stdint.h>
diff --git a/thirdparty/mbedtls/library/pkparse.c b/thirdparty/mbedtls/library/pkparse.c
index 535ed70eb1..ea5c6b69cb 100644
--- a/thirdparty/mbedtls/library/pkparse.c
+++ b/thirdparty/mbedtls/library/pkparse.c
@@ -474,7 +474,7 @@ static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *g
}
/*
- * grp may already be initilialized; if so, make sure IDs match
+ * grp may already be initialized; if so, make sure IDs match
*/
if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id )
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
@@ -807,7 +807,7 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
goto cleanup;
#else
- /* Verify existance of the CRT params */
+ /* Verify existence of the CRT params */
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 )
@@ -1463,10 +1463,16 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
{
p = pem.buf;
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
+ {
+ mbedtls_pem_free( &pem );
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+ }
if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
+ {
+ mbedtls_pem_free( &pem );
return( ret );
+ }
if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 )
mbedtls_pk_free( ctx );
diff --git a/thirdparty/mbedtls/library/rsa.c b/thirdparty/mbedtls/library/rsa.c
index 8a5d40ff1e..d1f6ddb177 100644
--- a/thirdparty/mbedtls/library/rsa.c
+++ b/thirdparty/mbedtls/library/rsa.c
@@ -832,10 +832,10 @@ cleanup:
* the more bits of the key can be recovered. See [3].
*
* Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
- * observations on avarage.
+ * observations on average.
*
* For example with 28 byte blinding to achieve 2 collisions the adversary has
- * to make 2^112 observations on avarage.
+ * to make 2^112 observations on average.
*
* (With the currently (as of 2017 April) known best algorithms breaking 2048
* bit RSA requires approximately as much time as trying out 2^112 random keys.
diff --git a/thirdparty/mbedtls/library/ssl_ciphersuites.c b/thirdparty/mbedtls/library/ssl_ciphersuites.c
index 3826ad27fa..ceec77efb0 100644
--- a/thirdparty/mbedtls/library/ssl_ciphersuites.c
+++ b/thirdparty/mbedtls/library/ssl_ciphersuites.c
@@ -2181,6 +2181,7 @@ const int *mbedtls_ssl_list_ciphersuites( void )
static int supported_ciphersuites[MAX_CIPHERSUITES];
static int supported_init = 0;
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ciphersuite_is_removed( const mbedtls_ssl_ciphersuite_t *cs_info )
{
(void)cs_info;
diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c
index b87879ce6a..72351c9757 100644
--- a/thirdparty/mbedtls/library/ssl_cli.c
+++ b/thirdparty/mbedtls/library/ssl_cli.c
@@ -53,6 +53,7 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_conf_has_static_psk( mbedtls_ssl_config const *conf )
{
if( conf->psk_identity == NULL ||
@@ -73,6 +74,7 @@ static int ssl_conf_has_static_psk( mbedtls_ssl_config const *conf )
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_conf_has_static_raw_psk( mbedtls_ssl_config const *conf )
{
if( conf->psk_identity == NULL ||
@@ -91,6 +93,7 @@ static int ssl_conf_has_static_raw_psk( mbedtls_ssl_config const *conf )
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -161,6 +164,7 @@ static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_SSL_RENEGOTIATION)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -204,6 +208,7 @@ static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
*/
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -302,6 +307,7 @@ static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -373,6 +379,7 @@ static int ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -404,6 +411,7 @@ static int ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -477,6 +485,7 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_cid_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -523,6 +532,7 @@ static int ssl_write_cid_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -555,6 +565,7 @@ static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -585,6 +596,7 @@ static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -616,6 +628,7 @@ static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -647,6 +660,7 @@ static int ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -689,6 +703,7 @@ static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_ALPN)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -748,6 +763,7 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ALPN */
#if defined(MBEDTLS_SSL_DTLS_SRTP)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -868,6 +884,7 @@ static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
/*
* Generate random bytes for ClientHello
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_generate_random( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -917,6 +934,7 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
*
* \return 0 if valid, else 1
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_validate_ciphersuite(
const mbedtls_ssl_ciphersuite_t * suite_info,
const mbedtls_ssl_context * ssl,
@@ -960,6 +978,7 @@ static int ssl_validate_ciphersuite(
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -1450,6 +1469,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1494,6 +1514,7 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
}
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1520,6 +1541,7 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1545,6 +1567,7 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1601,6 +1624,7 @@ static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1627,6 +1651,7 @@ static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1653,6 +1678,7 @@ static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1679,6 +1705,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1724,6 +1751,7 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1758,6 +1786,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
@@ -1828,6 +1857,7 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ALPN */
#if defined(MBEDTLS_SSL_DTLS_SRTP)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -1948,6 +1978,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
* Parse HelloVerifyRequest. Only called after verifying the HS type.
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
{
const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
@@ -2031,6 +2062,7 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
{
int ret, i;
@@ -2276,16 +2308,6 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
else
{
ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
-
- if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
- mbedtls_ssl_send_alert_message(
- ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
- return( ret );
- }
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
@@ -2538,6 +2560,24 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
}
/*
+ * mbedtls_ssl_derive_keys() has to be called after the parsing of the
+ * extensions. It sets the transform data for the resumed session which in
+ * case of DTLS includes the server CID extracted from the CID extension.
+ */
+ if( ssl->handshake->resume )
+ {
+ if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+ return( ret );
+ }
+ }
+
+ /*
* Renegotiation security checks
*/
if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
@@ -2591,6 +2631,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end )
@@ -2637,6 +2678,7 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl,
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
{
const mbedtls_ecp_curve_info *curve_info;
@@ -2678,6 +2720,7 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) )
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_ecdh_params_psa( mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end )
@@ -2703,6 +2746,10 @@ static int ssl_parse_server_ecdh_params_psa( mbedtls_ssl_context *ssl,
tls_id <<= 8;
tls_id |= *(*p)++;
+ /* Check it's a curve we offered */
+ if( mbedtls_ssl_check_curve_tls_id( ssl, tls_id ) != 0 )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
/* Convert EC group to PSA key type. */
if( ( handshake->ecdh_psa_type =
mbedtls_psa_parse_tls_ecc_group( tls_id, &ecdh_bits ) ) == 0 )
@@ -2740,6 +2787,7 @@ static int ssl_parse_server_ecdh_params_psa( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end )
@@ -2779,6 +2827,7 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end )
@@ -2825,6 +2874,7 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
/*
* Generate a pre-master secret and encrypt it with the server's RSA key
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
size_t offset, size_t *olen,
size_t pms_offset )
@@ -2912,6 +2962,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end,
@@ -2978,6 +3029,7 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -2996,6 +3048,8 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
peer_pk = &ssl->session_negotiate->peer_cert->pk;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ /* This is a public key, so it can't be opaque, so can_do() is a good
+ * enough check to ensure pk_ec() is safe to use below. */
if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECKEY ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
@@ -3029,6 +3083,7 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3147,7 +3202,7 @@ start_processing:
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
- } /* FALLTROUGH */
+ } /* FALLTHROUGH */
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
@@ -3435,6 +3490,7 @@ exit:
}
#if ! defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@@ -3453,6 +3509,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
#else /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3624,6 +3681,7 @@ exit:
}
#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3663,6 +3721,7 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3718,7 +3777,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
{
- psa_status_t status;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_attributes_t key_attributes;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@@ -3761,13 +3821,19 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
own_pubkey, sizeof( own_pubkey ),
&own_pubkey_len );
if( status != PSA_SUCCESS )
+ {
+ psa_destroy_key( handshake->ecdh_psa_privkey );
+ handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
if( mbedtls_psa_tls_psa_ec_to_ecpoint( own_pubkey,
own_pubkey_len,
&own_pubkey_ecpoint,
&own_pubkey_ecpoint_len ) != 0 )
{
+ psa_destroy_key( handshake->ecdh_psa_privkey );
+ handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
@@ -3787,13 +3853,12 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
ssl->handshake->premaster,
sizeof( ssl->handshake->premaster ),
&ssl->handshake->pmslen );
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- status = psa_destroy_key( handshake->ecdh_psa_privkey );
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ destruction_status = psa_destroy_key( handshake->ecdh_psa_privkey );
handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
+
+ if( status != PSA_SUCCESS || destruction_status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
else
#endif /* MBEDTLS_USE_PSA_CRYPTO &&
@@ -3918,7 +3983,10 @@ ecdh_calc_secret:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only suites. */
if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with RSA-PSK" ) );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = ssl_write_encrypted_pms( ssl, header_len,
@@ -3933,7 +4001,10 @@ ecdh_calc_secret:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only suites. */
if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with DHE-PSK" ) );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/*
@@ -3970,7 +4041,10 @@ ecdh_calc_secret:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only suites. */
if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with ECDHE-PSK" ) );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/*
@@ -4080,6 +4154,7 @@ ecdh_calc_secret:
}
#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@@ -4105,6 +4180,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -4277,6 +4353,7 @@ sign:
#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
diff --git a/thirdparty/mbedtls/library/ssl_cookie.c b/thirdparty/mbedtls/library/ssl_cookie.c
index abf29ae717..3781796b72 100644
--- a/thirdparty/mbedtls/library/ssl_cookie.c
+++ b/thirdparty/mbedtls/library/ssl_cookie.c
@@ -63,7 +63,7 @@
/*
* Cookies are formed of a 4-bytes timestamp (or serial number) and
- * an HMAC of timestemp and client ID.
+ * an HMAC of timestamp and client ID.
*/
#define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN )
@@ -122,6 +122,7 @@ int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
/*
* Generate the HMAC part of a cookie
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx,
const unsigned char time[4],
unsigned char **p, unsigned char *end,
diff --git a/thirdparty/mbedtls/library/ssl_msg.c b/thirdparty/mbedtls/library/ssl_msg.c
index 0b696dd561..e47c538888 100644
--- a/thirdparty/mbedtls/library/ssl_msg.c
+++ b/thirdparty/mbedtls/library/ssl_msg.c
@@ -91,6 +91,7 @@ int mbedtls_ssl_check_timer( mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
unsigned char *buf,
size_t len,
@@ -165,11 +166,16 @@ exit:
static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
uint8_t slot );
static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_message( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
mbedtls_record const *rec );
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
@@ -187,6 +193,7 @@ static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
return( out_buf_len );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
{
size_t const bytes_written = ssl->out_left;
@@ -203,6 +210,7 @@ static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
return( (int) ( mtu - bytes_written ) );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -254,6 +262,7 @@ static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl
* Double the retransmit timeout value, within the allowed range,
* returning -1 if the maximum value has already been reached.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
{
uint32_t new_timeout;
@@ -353,6 +362,7 @@ static size_t ssl_compute_padding_length( size_t len,
* - A negative error code if `max_len` didn't offer enough space
* for the expansion.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_build_inner_plaintext( unsigned char *content,
size_t *content_size,
size_t remaining,
@@ -380,6 +390,7 @@ static int ssl_build_inner_plaintext( unsigned char *content,
/* This function parses a (D)TLSInnerPlaintext structure.
* See ssl_build_inner_plaintext() for details. */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_inner_plaintext( unsigned char const *content,
size_t *content_size,
uint8_t *rec_type )
@@ -474,6 +485,7 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data,
/*
* SSLv3.0 MAC functions
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_mac( mbedtls_md_context_t *md_ctx,
const unsigned char *secret,
const unsigned char *buf, size_t len,
@@ -541,6 +553,7 @@ static int ssl_mac( mbedtls_md_context_t *md_ctx,
#if defined(MBEDTLS_GCM_C) || \
defined(MBEDTLS_CCM_C) || \
defined(MBEDTLS_CHACHAPOLY_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_transform_aead_dynamic_iv_is_explicit(
mbedtls_ssl_transform const *transform )
{
@@ -1245,7 +1258,7 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
add_data, add_data_len );
/* Because of the check above, we know that there are
- * explicit_iv_len Bytes preceeding data, and taglen
+ * explicit_iv_len Bytes preceding data, and taglen
* bytes following data + data_len. This justifies
* the debug message and the invocation of
* mbedtls_cipher_auth_decrypt() below. */
@@ -1590,8 +1603,8 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
if( auth_done == 0 )
{
- unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
- unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
+ unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 };
+ unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 };
/* If the initial value of padlen was such that
* data_len < maclen + padlen + 1, then padlen
@@ -1738,6 +1751,7 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
/*
* Compression/decompression functions
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_compress_buf( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -1790,6 +1804,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl )
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -2149,6 +2164,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
/*
* Append current handshake message to current outgoing flight
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_flight_append( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_flight_item *msg;
@@ -2215,6 +2231,7 @@ void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight )
/*
* Swap transform_out and out_ctr with the alternative ones
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_transform *tmp_transform;
@@ -2857,6 +2874,7 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
#if defined(MBEDTLS_SSL_PROTO_DTLS)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
{
if( ssl->in_msglen < ssl->in_hslen ||
@@ -2882,6 +2900,7 @@ static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl )
ssl->in_msg[8] );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
{
uint32_t msg_len, frag_off, frag_len;
@@ -2948,6 +2967,7 @@ static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
/*
* Check that bitmask is full
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_bitmask_check( unsigned char *mask, size_t len )
{
size_t i;
@@ -3147,6 +3167,7 @@ static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
( (uint64_t) buf[5] ) );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3229,8 +3250,8 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
/*
- * Without any SSL context, check if a datagram looks like a ClientHello with
- * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
+ * Check if a datagram looks like a ClientHello with a valid cookie,
+ * and if it doesn't, generate a HelloVerifyRequest message.
* Both input and output include full DTLS headers.
*
* - if cookie is valid, return 0
@@ -3239,10 +3260,10 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
* return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
* - otherwise return a specific error code
*/
-static int ssl_check_dtls_clihlo_cookie(
- mbedtls_ssl_cookie_write_t *f_cookie_write,
- mbedtls_ssl_cookie_check_t *f_cookie_check,
- void *p_cookie,
+MBEDTLS_CHECK_RETURN_CRITICAL
+MBEDTLS_STATIC_TESTABLE
+int mbedtls_ssl_check_dtls_clihlo_cookie(
+ mbedtls_ssl_context *ssl,
const unsigned char *cli_id, size_t cli_id_len,
const unsigned char *in, size_t in_len,
unsigned char *obuf, size_t buf_len, size_t *olen )
@@ -3276,26 +3297,53 @@ static int ssl_check_dtls_clihlo_cookie(
*
* Minimum length is 61 bytes.
*/
- if( in_len < 61 ||
- in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
+ MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: in_len=%u",
+ (unsigned) in_len ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "cli_id", cli_id, cli_id_len );
+ if( in_len < 61 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: record too short" ) );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+ if( in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
in[3] != 0 || in[4] != 0 ||
in[19] != 0 || in[20] != 0 || in[21] != 0 )
{
+ MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: not a good ClientHello" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 4, ( " type=%u epoch=%u fragment_offset=%u",
+ in[0],
+ (unsigned) in[3] << 8 | in[4],
+ (unsigned) in[19] << 16 | in[20] << 8 | in[21] ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
sid_len = in[59];
- if( sid_len > in_len - 61 )
+ if( 59 + 1 + sid_len + 1 > in_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: sid_len=%u > %u",
+ (unsigned) sid_len,
+ (unsigned) in_len - 61 ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 4, "sid received from network",
+ in + 60, sid_len );
cookie_len = in[60 + sid_len];
- if( cookie_len > in_len - 60 )
+ if( 59 + 1 + sid_len + 1 + cookie_len > in_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: cookie_len=%u > %u",
+ (unsigned) cookie_len,
+ (unsigned) ( in_len - sid_len - 61 ) ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
- if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
- cli_id, cli_id_len ) == 0 )
+ MBEDTLS_SSL_DEBUG_BUF( 4, "cookie received from network",
+ in + sid_len + 61, cookie_len );
+ if( ssl->conf->f_cookie_check( ssl->conf->p_cookie,
+ in + sid_len + 61, cookie_len,
+ cli_id, cli_id_len ) == 0 )
{
- /* Valid cookie */
+ MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: valid" ) );
return( 0 );
}
@@ -3330,8 +3378,9 @@ static int ssl_check_dtls_clihlo_cookie(
/* Generate and write actual cookie */
p = obuf + 28;
- if( f_cookie_write( p_cookie,
- &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
+ if( ssl->conf->f_cookie_write( ssl->conf->p_cookie,
+ &p, obuf + buf_len,
+ cli_id, cli_id_len ) != 0 )
{
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
@@ -3370,6 +3419,7 @@ static int ssl_check_dtls_clihlo_cookie(
* includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
* errors, and is the right thing to do in both cases).
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3385,15 +3435,13 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
return( 0 );
}
- ret = ssl_check_dtls_clihlo_cookie(
- ssl->conf->f_cookie_write,
- ssl->conf->f_cookie_check,
- ssl->conf->p_cookie,
+ ret = mbedtls_ssl_check_dtls_clihlo_cookie(
+ ssl,
ssl->cli_id, ssl->cli_id_len,
ssl->in_buf, ssl->in_left,
ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
+ MBEDTLS_SSL_DEBUG_RET( 2, "mbedtls_ssl_check_dtls_clihlo_cookie", ret );
if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
{
@@ -3427,6 +3475,7 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
}
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_record_type( uint8_t record_type )
{
if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
@@ -3459,6 +3508,7 @@ static int ssl_check_record_type( uint8_t record_type )
* Point 2 is needed when the peer is resending, and we have already received
* the first record from a datagram but are still waiting for the others.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
unsigned char *buf,
size_t len,
@@ -3571,7 +3621,6 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
/*
* Parse and validate record version
*/
-
rec->ver[0] = buf[ rec_hdr_version_offset + 0 ];
rec->ver[1] = buf[ rec_hdr_version_offset + 1 ];
mbedtls_ssl_read_version( &major_ver, &minor_ver,
@@ -3580,16 +3629,19 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
if( major_ver != ssl->major_ver )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch: got %u, expected %u",
+ (unsigned) major_ver,
+ (unsigned) ssl->major_ver ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
}
if( minor_ver > ssl->conf->max_minor_ver )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch: got %u, expected max %u",
+ (unsigned) minor_ver,
+ (unsigned) ssl->conf->max_minor_ver ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
}
-
/*
* Parse/Copy record sequence number.
*/
@@ -3692,6 +3744,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl )
{
unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
@@ -3721,6 +3774,7 @@ static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl )
/*
* If applicable, decrypt record content
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_prepare_record_content( mbedtls_ssl_context *ssl,
mbedtls_record *rec )
{
@@ -3854,7 +3908,7 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl,
/* Check actual (decrypted) record content length against
* configured maximum. */
- if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
+ if( rec->data_len > MBEDTLS_SSL_IN_CONTENT_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
@@ -3872,8 +3926,11 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl,
*/
/* Helper functions for mbedtls_ssl_read_record(). */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_next_record( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
@@ -3961,6 +4018,7 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
{
if( ssl->in_left > ssl->next_record_offset )
@@ -3969,6 +4027,7 @@ static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_handshake_params * const hs = ssl->handshake;
@@ -4066,6 +4125,7 @@ exit:
return( ret );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
size_t desired )
{
@@ -4108,6 +4168,7 @@ static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
return( -1 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_message( mbedtls_ssl_context *ssl )
{
int ret = 0;
@@ -4312,6 +4373,7 @@ exit:
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
{
/*
@@ -4399,6 +4461,7 @@ static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
{
if( ssl->in_msglen > 0 )
@@ -4425,6 +4488,7 @@ static void ssl_free_buffered_record( mbedtls_ssl_context *ssl )
}
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_handshake_params * const hs = ssl->handshake;
@@ -4482,6 +4546,7 @@ exit:
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
mbedtls_record const *rec )
{
@@ -4540,6 +4605,7 @@ static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_next_record( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -4918,6 +4984,9 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
if( ssl == NULL || ssl->conf == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ if( ssl->out_left != 0 )
+ return( mbedtls_ssl_flush_output( ssl ) );
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
@@ -5287,6 +5356,7 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
/*
* Check record counters and renegotiate if they're above the limit.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
{
size_t ep_len = mbedtls_ssl_ep_len( ssl );
@@ -5637,6 +5707,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
* Therefore, it is possible that the input message length is 0 and the
* corresponding return code is 0 on success.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_real( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
@@ -5708,6 +5779,7 @@ static int ssl_write_real( mbedtls_ssl_context *ssl,
* remember whether we already did the split or not.
*/
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_split( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
@@ -5790,9 +5862,6 @@ int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
- if( ssl->out_left != 0 )
- return( mbedtls_ssl_flush_output( ssl ) );
-
if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
{
if( ( ret = mbedtls_ssl_send_alert_message( ssl,
diff --git a/thirdparty/mbedtls/library/ssl_srv.c b/thirdparty/mbedtls/library/ssl_srv.c
index 1a63173204..2efb13cc33 100644
--- a/thirdparty/mbedtls/library/ssl_srv.c
+++ b/thirdparty/mbedtls/library/ssl_srv.c
@@ -78,6 +78,7 @@ void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf,
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -147,6 +148,7 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_conf_has_psk_or_cb( mbedtls_ssl_config const *conf )
{
if( conf->f_psk != NULL )
@@ -167,6 +169,7 @@ static int ssl_conf_has_psk_or_cb( mbedtls_ssl_config const *conf )
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
{
if( ssl->conf->f_psk != NULL )
@@ -188,6 +191,7 @@ static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -239,6 +243,7 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
* This needs to be done at a later stage.
*
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -317,6 +322,7 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -383,6 +389,7 @@ static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -425,6 +432,7 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -454,6 +462,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -473,6 +482,7 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -545,6 +555,7 @@ static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -567,6 +578,7 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -592,6 +604,7 @@ static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -617,6 +630,7 @@ static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t len )
@@ -691,6 +705,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_ALPN)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
@@ -779,6 +794,7 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_ALPN */
#if defined(MBEDTLS_SSL_DTLS_SRTP)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -907,6 +923,7 @@ static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
* Return 0 if the given key uses one of the acceptable curves, -1 otherwise
*/
#if defined(MBEDTLS_ECDSA_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_key_curve( mbedtls_pk_context *pk,
const mbedtls_ecp_curve_info **curves )
{
@@ -928,6 +945,7 @@ static int ssl_check_key_curve( mbedtls_pk_context *pk,
* Try picking a certificate for this ciphersuite,
* return 0 on success and -1 on failure.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_pick_cert( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t * ciphersuite_info )
{
@@ -1032,6 +1050,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
* Check if a given ciphersuite is suitable for use with our config/keys/etc
* Sets ciphersuite_info only if the suite matches.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
const mbedtls_ssl_ciphersuite_t **ciphersuite_info )
{
@@ -1147,6 +1166,7 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
}
#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
{
int ret, got_common_suite;
@@ -1410,6 +1430,7 @@ have_ciphersuite_v2:
/* This function doesn't alert on errors that happen early during
ClientHello parsing because they might indicate that the client is
not talking SSL/TLS at all and would not understand our alert. */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
{
int ret, got_common_suite;
@@ -1583,7 +1604,7 @@ read_record_header:
* Handshake layer:
* 0 . 0 handshake type
* 1 . 3 handshake length
- * 4 . 5 DTLS only: message seqence number
+ * 4 . 5 DTLS only: message sequence number
* 6 . 8 DTLS only: fragment offset
* 9 . 11 DTLS only: fragment length
*/
@@ -1604,11 +1625,19 @@ read_record_header:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d",
( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) );
+ if( buf[1] != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message: %u != 0",
+ (unsigned) buf[1] ) );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
/* We don't support fragmentation of ClientHello (yet?) */
- if( buf[1] != 0 ||
- msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) )
+ if( msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message: %u != %u + %u",
+ (unsigned) msg_len,
+ (unsigned) mbedtls_ssl_hs_hdr_len( ssl ),
+ (unsigned) ( buf[2] << 8 ) | buf[3] ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
@@ -1649,6 +1678,11 @@ read_record_header:
* For now we don't support fragmentation, so make sure
* fragment_offset == 0 and fragment_length == length
*/
+ MBEDTLS_SSL_DEBUG_MSG(
+ 4, ( "fragment_offset=%u fragment_length=%u length=%u",
+ (unsigned) ( ssl->in_msg[6] << 16 | ssl->in_msg[7] << 8 | ssl->in_msg[8] ),
+ (unsigned) ( ssl->in_msg[9] << 16 | ssl->in_msg[10] << 8 | ssl->in_msg[11] ),
+ (unsigned) ( ssl->in_msg[1] << 16 | ssl->in_msg[2] << 8 | ssl->in_msg[3] ) ) );
if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 ||
memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 )
{
@@ -2354,12 +2388,8 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t *suite = NULL;
const mbedtls_cipher_info_t *cipher = NULL;
- if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- *olen = 0;
- return;
- }
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
/*
* RFC 7366: "If a server receives an encrypt-then-MAC request extension
@@ -2372,6 +2402,11 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
( cipher = mbedtls_cipher_info_from_type( suite->cipher ) ) == NULL ||
cipher->mode != MBEDTLS_MODE_CBC )
{
+ ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
+ }
+
+ if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED )
+ {
*olen = 0;
return;
}
@@ -2685,6 +2720,7 @@ static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_DTLS_SRTP */
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -2805,6 +2841,7 @@ exit:
mbedtls_ssl_session_free( &session_tmp );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_HAVE_TIME)
@@ -3035,6 +3072,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
}
#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@@ -3053,6 +3091,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -3222,18 +3261,23 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_pk_context *own_key = mbedtls_ssl_own_key( ssl );
- if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) )
+ /* Check if the key is a transparent ECDH key.
+ * This also ensures that it is safe to call mbedtls_pk_ec(). */
+ if( mbedtls_pk_get_type( own_key ) != MBEDTLS_PK_ECKEY &&
+ mbedtls_pk_get_type( own_key ) != MBEDTLS_PK_ECKEY_DH )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx,
- mbedtls_pk_ec( *mbedtls_ssl_own_key( ssl ) ),
+ mbedtls_pk_ec( *own_key ),
MBEDTLS_ECDH_OURS ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
@@ -3247,6 +3291,7 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
size_t *signature_len )
{
@@ -3274,6 +3319,7 @@ static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
/* Prepare the ServerKeyExchange message, up to and including
* calculating the signature if any, but excluding formatting the
* signature and sending the message. */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
size_t *signature_len )
{
@@ -3643,6 +3689,7 @@ curve_matching_done:
* that do not include a ServerKeyExchange message, do nothing. Either
* way, if successful, move on to the next step in the SSL state
* machine. */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3664,7 +3711,12 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
{
- ssl_get_ecdh_params_from_cert( ssl );
+ ret = ssl_get_ecdh_params_from_cert( ssl );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
+ return( ret );
+ }
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
@@ -3740,6 +3792,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
return( 0 );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3779,6 +3832,7 @@ static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char **p,
const unsigned char *end )
{
@@ -3822,6 +3876,7 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char *
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl,
unsigned char *peer_pms,
size_t *peer_pmslen,
@@ -3839,6 +3894,7 @@ static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
const unsigned char *p,
const unsigned char *end,
@@ -3931,6 +3987,7 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
return( ret );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
const unsigned char *p,
const unsigned char *end,
@@ -4020,6 +4077,7 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p,
const unsigned char *end )
{
@@ -4080,6 +4138,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -4207,7 +4266,7 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- /* For opaque PSKs, we perform the PSK-to-MS derivation atomatically
+ /* For opaque PSKs, we perform the PSK-to-MS derivation automatically
* and skip the intermediate PMS. */
if( ssl_use_opaque_psk( ssl ) == 1 )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) );
@@ -4247,7 +4306,10 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only. */
if( ssl_use_opaque_psk( ssl ) == 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with RSA-PSK" ) );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
#endif
if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 )
@@ -4282,7 +4344,10 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only. */
if( ssl_use_opaque_psk( ssl ) == 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with DHE-PSK" ) );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
#endif
if( p != end )
@@ -4319,7 +4384,10 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only. */
if( ssl_use_opaque_psk( ssl ) == 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with ECDHE-PSK" ) );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
#endif
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
@@ -4386,6 +4454,7 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
}
#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@@ -4404,6 +4473,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -4597,6 +4667,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
diff --git a/thirdparty/mbedtls/library/ssl_ticket.c b/thirdparty/mbedtls/library/ssl_ticket.c
index 046ed1b2ff..e0126cc9d1 100644
--- a/thirdparty/mbedtls/library/ssl_ticket.c
+++ b/thirdparty/mbedtls/library/ssl_ticket.c
@@ -37,7 +37,7 @@
#include <string.h>
/*
- * Initialze context
+ * Initialize context
*/
void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx )
{
@@ -66,6 +66,7 @@ void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx )
/*
* Generate/update a key
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx,
unsigned char index )
{
@@ -96,6 +97,7 @@ static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx,
/*
* Rotate/generate keys if necessary
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx )
{
#if !defined(MBEDTLS_HAVE_TIME)
diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c
index 2e6469de83..7badec51ae 100644
--- a/thirdparty/mbedtls/library/ssl_tls.c
+++ b/thirdparty/mbedtls/library/ssl_tls.c
@@ -245,6 +245,7 @@ int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
}
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int resize_buffer( unsigned char **buffer, size_t len_new, size_t *len_old )
{
unsigned char* resized_buffer = mbedtls_calloc( 1, len_new );
@@ -337,6 +338,7 @@ static void handle_buffer_resizing( mbedtls_ssl_context *ssl, int downsizing,
* Key material generation
*/
#if defined(MBEDTLS_SSL_PROTO_SSL3)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl3_prf( const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
@@ -398,6 +400,7 @@ exit:
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int tls1_prf( const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
@@ -605,6 +608,7 @@ static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* de
return( PSA_SUCCESS );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_generic( mbedtls_md_type_t md_type,
const unsigned char *secret, size_t slen,
const char *label,
@@ -679,6 +683,7 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
#else /* MBEDTLS_USE_PSA_CRYPTO */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_generic( mbedtls_md_type_t md_type,
const unsigned char *secret, size_t slen,
const char *label,
@@ -770,6 +775,7 @@ exit:
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SHA256_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_sha256( const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
@@ -781,6 +787,7 @@ static int tls_prf_sha256( const unsigned char *secret, size_t slen,
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_sha384( const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
@@ -825,6 +832,7 @@ static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
{
if( ssl->conf->f_psk != NULL )
@@ -949,6 +957,7 @@ typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
* - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys
* - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_populate_transform( mbedtls_ssl_transform *transform,
int ciphersuite,
const unsigned char master[48],
@@ -990,6 +999,7 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform,
#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL) && \
!defined(MBEDTLS_SSL_EXPORT_KEYS) && \
+ !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
!defined(MBEDTLS_DEBUG_C)
ssl = NULL; /* make sure we don't use it except for those cases */
(void) ssl;
@@ -1361,7 +1371,7 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform,
* the structure field for the IV, which the PSA-based
* implementation currently doesn't. */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_enc,
cipher_info, transform->taglen );
@@ -1404,7 +1414,7 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform,
* the structure field for the IV, which the PSA-based
* implementation currently doesn't. */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_dec,
cipher_info, transform->taglen );
@@ -1511,6 +1521,7 @@ end:
* Outputs:
* - the tls_prf, calc_verify and calc_finished members of handshake structure
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake,
int minor_ver,
mbedtls_md_type_t hash )
@@ -1580,6 +1591,7 @@ static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake,
* EMS: passed to calc_verify (debug + (SSL3) session_negotiate)
* PSA-PSA: minor_ver, conf
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake,
unsigned char *master,
const mbedtls_ssl_context *ssl )
@@ -2108,6 +2120,7 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -2323,6 +2336,7 @@ write_msg:
#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
unsigned char *crt_buf,
size_t crt_buf_len )
@@ -2338,6 +2352,7 @@ static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
return( memcmp( peer_crt->raw.p, crt_buf, peer_crt->raw.len ) );
}
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
unsigned char *crt_buf,
size_t crt_buf_len )
@@ -2372,6 +2387,7 @@ static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
* Once the certificate message is read, parse it into a cert chain and
* perform basic checks, but leave actual verification to the caller
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl,
mbedtls_x509_crt *chain )
{
@@ -2521,6 +2537,7 @@ static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl,
}
#if defined(MBEDTLS_SSL_SRV_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl )
{
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
@@ -2570,6 +2587,7 @@ static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl )
*/
#define SSL_CERTIFICATE_EXPECTED 0
#define SSL_CERTIFICATE_SKIP 1
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl,
int authmode )
{
@@ -2599,6 +2617,7 @@ static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl,
return( SSL_CERTIFICATE_EXPECTED );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
int authmode,
mbedtls_x509_crt *chain,
@@ -2696,7 +2715,9 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
{
const mbedtls_pk_context *pk = &chain->pk;
- /* If certificate uses an EC key, make sure the curve is OK */
+ /* If certificate uses an EC key, make sure the curve is OK.
+ * This is a public key, so it can't be opaque, so can_do() is a good
+ * enough check to ensure pk_ec() is safe to use here. */
if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
{
@@ -2787,6 +2808,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
}
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl,
unsigned char *start, size_t len )
{
@@ -2818,6 +2840,7 @@ static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl,
return( ret );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl,
unsigned char *start, size_t len )
{
@@ -3428,7 +3451,7 @@ void mbedtls_ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
ssl->handshake = NULL;
/*
- * Free the previous transform and swith in the current one
+ * Free the previous transform and switch in the current one
*/
if( ssl->transform )
{
@@ -3796,6 +3819,7 @@ void mbedtls_ssl_session_init( mbedtls_ssl_session *session )
memset( session, 0, sizeof(mbedtls_ssl_session) );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_handshake_init( mbedtls_ssl_context *ssl )
{
/* Clear old handshake information if present */
@@ -3873,6 +3897,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
/* Dummy cookie callbacks for defaults */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_cookie_write_dummy( void *ctx,
unsigned char **p, unsigned char *end,
const unsigned char *cli_id, size_t cli_id_len )
@@ -3886,6 +3911,7 @@ static int ssl_cookie_write_dummy( void *ctx,
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_cookie_check_dummy( void *ctx,
const unsigned char *cookie, size_t cookie_len,
const unsigned char *cli_id, size_t cli_id_len )
@@ -4303,6 +4329,7 @@ void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
}
/* Append a new keycert entry to a (possibly empty) list */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_append_key_cert( mbedtls_ssl_key_cert **head,
mbedtls_x509_crt *cert,
mbedtls_pk_context *key )
@@ -4471,6 +4498,7 @@ static void ssl_conf_remove_psk( mbedtls_ssl_config *conf )
* It checks that the provided identity is well-formed and attempts
* to make a copy of it in the SSL config.
* On failure, the PSK identity in the config remains unset. */
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_conf_set_psk_identity( mbedtls_ssl_config *conf,
unsigned char const *psk_identity,
size_t psk_identity_len )
@@ -4632,6 +4660,9 @@ int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi_free( &conf->dhm_P );
+ mbedtls_mpi_free( &conf->dhm_G );
+
if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 ||
( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 )
{
@@ -4647,6 +4678,9 @@ int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi_free( &conf->dhm_P );
+ mbedtls_mpi_free( &conf->dhm_G );
+
if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
{
@@ -5384,6 +5418,7 @@ static unsigned char ssl_serialized_session_header[] = {
* verify_result is put before peer_cert so that all mandatory fields come
* together in one block.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_session_save( const mbedtls_ssl_session *session,
unsigned char omit_header,
unsigned char *buf,
@@ -5583,6 +5618,7 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
* This internal version is wrapped by a public function that cleans up in
* case of error, and has an extra option omit_header.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_session_load( mbedtls_ssl_session *session,
unsigned char omit_header,
const unsigned char *buf,
@@ -5886,6 +5922,7 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
/*
* Write HelloRequest to request renegotiation on server
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -6497,6 +6534,7 @@ static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id )
* This internal version is wrapped by a public function that cleans up in
* case of error.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_context_load( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -7320,6 +7358,18 @@ int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_i
return( -1 );
}
+
+/*
+ * Same as mbedtls_ssl_check_curve() but takes a TLS ID for the curve.
+ */
+int mbedtls_ssl_check_curve_tls_id( const mbedtls_ssl_context *ssl, uint16_t tls_id )
+{
+ const mbedtls_ecp_curve_info *curve_info =
+ mbedtls_ecp_curve_info_from_tls_id( tls_id );
+ if( curve_info == NULL )
+ return( -1 );
+ return( mbedtls_ssl_check_curve( ssl, curve_info->grp_id ) );
+}
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
diff --git a/thirdparty/mbedtls/library/threading.c b/thirdparty/mbedtls/library/threading.c
index 2de117f52a..5e0aaa4f21 100644
--- a/thirdparty/mbedtls/library/threading.c
+++ b/thirdparty/mbedtls/library/threading.c
@@ -113,7 +113,7 @@ int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_
int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread;
/*
- * With phtreads we can statically initialize mutexes
+ * With pthreads we can statically initialize mutexes
*/
#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 }
diff --git a/thirdparty/mbedtls/library/timing.c b/thirdparty/mbedtls/library/timing.c
index eb41461320..57bc9bcc12 100644
--- a/thirdparty/mbedtls/library/timing.c
+++ b/thirdparty/mbedtls/library/timing.c
@@ -56,15 +56,15 @@ struct _hr_time
#include <unistd.h>
#include <sys/types.h>
-#include <sys/time.h>
#include <signal.h>
+/* time.h should be included independently of MBEDTLS_HAVE_TIME. If the
+ * platform matches the ifdefs above, it will be used. */
#include <time.h>
-
+#include <sys/time.h>
struct _hr_time
{
struct timeval start;
};
-
#endif /* _WIN32 && !EFIX64 && !EFI32 */
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
@@ -364,7 +364,6 @@ int mbedtls_timing_get_delay( void *data )
return( 0 );
}
-#endif /* !MBEDTLS_TIMING_ALT */
#if defined(MBEDTLS_SELF_TEST)
@@ -526,5 +525,5 @@ hard_test_done:
}
#endif /* MBEDTLS_SELF_TEST */
-
+#endif /* !MBEDTLS_TIMING_ALT */
#endif /* MBEDTLS_TIMING_C */
diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c
index f21e9e6944..3997ebd1f3 100644
--- a/thirdparty/mbedtls/library/x509.c
+++ b/thirdparty/mbedtls/library/x509.c
@@ -741,7 +741,7 @@ int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t i, n;
+ size_t i, j, n;
unsigned char c, merge = 0;
const mbedtls_x509_name *name;
const char *short_name = NULL;
@@ -775,17 +775,24 @@ int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
ret = mbedtls_snprintf( p, n, "\?\?=" );
MBEDTLS_X509_SAFE_SNPRINTF;
- for( i = 0; i < name->val.len; i++ )
+ for( i = 0, j = 0; i < name->val.len; i++, j++ )
{
- if( i >= sizeof( s ) - 1 )
- break;
+ if( j >= sizeof( s ) - 1 )
+ return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
c = name->val.p[i];
+ // Special characters requiring escaping, RFC 1779
+ if( c && strchr( ",=+<>#;\"\\", c ) )
+ {
+ if( j + 1 >= sizeof( s ) - 1 )
+ return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+ s[j++] = '\\';
+ }
if( c < 32 || c >= 127 )
- s[i] = '?';
- else s[i] = c;
+ s[j] = '?';
+ else s[j] = c;
}
- s[i] = '\0';
+ s[j] = '\0';
ret = mbedtls_snprintf( p, n, "%s", s );
MBEDTLS_X509_SAFE_SNPRINTF;
diff --git a/thirdparty/mbedtls/library/x509_crl.c b/thirdparty/mbedtls/library/x509_crl.c
index ac4fc75de3..d2d8042029 100644
--- a/thirdparty/mbedtls/library/x509_crl.c
+++ b/thirdparty/mbedtls/library/x509_crl.c
@@ -52,11 +52,13 @@
#define mbedtls_snprintf snprintf
#endif
+#if defined(MBEDTLS_HAVE_TIME)
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
#include <windows.h>
#else
#include <time.h>
#endif
+#endif
#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
#include <stdio.h>
diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c
index 60312bf2f5..96477e4c9d 100644
--- a/thirdparty/mbedtls/library/x509_crt.c
+++ b/thirdparty/mbedtls/library/x509_crt.c
@@ -63,6 +63,7 @@
#include "mbedtls/threading.h"
#endif
+#if defined(MBEDTLS_HAVE_TIME)
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
#include <windows.h>
#if defined(_MSC_VER) && _MSC_VER <= 1600
@@ -81,6 +82,7 @@
#else
#include <time.h>
#endif
+#endif
#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
diff --git a/thirdparty/mbedtls/library/x509write_crt.c b/thirdparty/mbedtls/library/x509write_crt.c
index 184c90cd33..0c5e991834 100644
--- a/thirdparty/mbedtls/library/x509write_crt.c
+++ b/thirdparty/mbedtls/library/x509write_crt.c
@@ -299,7 +299,7 @@ static int x509_write_time( unsigned char **p, unsigned char *start,
/*
* write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
*/
- if( t[0] == '2' && t[1] == '0' && t[2] < '5' )
+ if( t[0] < '2' || ( t[0] == '2' && t[1] == '0' && t[2] < '5' ) )
{
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
(const unsigned char *) t + 2,
diff --git a/thirdparty/zstd/common/bitstream.h b/thirdparty/zstd/common/bitstream.h
index 2e5a933ad3..84b6062ff3 100644
--- a/thirdparty/zstd/common/bitstream.h
+++ b/thirdparty/zstd/common/bitstream.h
@@ -143,10 +143,16 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val)
{
# if defined(_MSC_VER) /* Visual */
# if STATIC_BMI2 == 1
- return _lzcnt_u32(val) ^ 31;
+ return _lzcnt_u32(val) ^ 31;
# else
- unsigned long r = 0;
- return _BitScanReverse(&r, val) ? (unsigned)r : 0;
+ if (val != 0) {
+ unsigned long r;
+ _BitScanReverse(&r, val);
+ return (unsigned)r;
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
# endif
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
return __builtin_clz (val) ^ 31;
@@ -293,22 +299,22 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
switch(srcSize)
{
case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
- /* fall-through */
+ ZSTD_FALLTHROUGH;
default: break;
}
@@ -332,7 +338,16 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 c
U32 const regMask = sizeof(bitContainer)*8 - 1;
/* if start > regMask, bitstream is corrupted, and result is undefined */
assert(nbBits < BIT_MASK_SIZE);
+ /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better
+ * than accessing memory. When bmi2 instruction is not present, we consider
+ * such cpus old (pre-Haswell, 2013) and their performance is not of that
+ * importance.
+ */
+#if defined(__x86_64__) || defined(_M_X86)
+ return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1);
+#else
return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
+#endif
}
MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
diff --git a/thirdparty/zstd/common/compiler.h b/thirdparty/zstd/common/compiler.h
index a951d0adea..516930c01e 100644
--- a/thirdparty/zstd/common/compiler.h
+++ b/thirdparty/zstd/common/compiler.h
@@ -11,6 +11,8 @@
#ifndef ZSTD_COMPILER_H
#define ZSTD_COMPILER_H
+#include "portability_macros.h"
+
/*-*******************************************************
* Compiler specifics
*********************************************************/
@@ -40,7 +42,7 @@
/**
On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC).
- This explictly marks such functions as __cdecl so that the code will still compile
+ This explicitly marks such functions as __cdecl so that the code will still compile
if a CC other than __cdecl has been made the default.
*/
#if defined(_MSC_VER)
@@ -92,29 +94,17 @@
/* target attribute */
-#ifndef __has_attribute
- #define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
-#endif
#if defined(__GNUC__) || defined(__ICCARM__)
# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
#else
# define TARGET_ATTRIBUTE(target)
#endif
-/* Enable runtime BMI2 dispatch based on the CPU.
- * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
+/* Target attribute for BMI2 dynamic dispatch.
+ * Enable lzcnt, bmi, and bmi2.
+ * We test for bmi1 & bmi2. lzcnt is included in bmi1.
*/
-#ifndef DYNAMIC_BMI2
- #if ((defined(__clang__) && __has_attribute(__target__)) \
- || (defined(__GNUC__) \
- && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
- && (defined(__x86_64__) || defined(_M_X86)) \
- && !defined(__BMI2__)
- # define DYNAMIC_BMI2 1
- #else
- # define DYNAMIC_BMI2 0
- #endif
-#endif
+#define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2")
/* prefetch
* can be disabled, by declaring NO_PREFETCH build macro */
@@ -150,8 +140,9 @@
}
/* vectorization
- * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */
-#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__)
+ * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax,
+ * and some compilers, like Intel ICC and MCST LCC, do not support it at all. */
+#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__)
# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
# else
@@ -197,25 +188,91 @@
#define STATIC_BMI2 0
#endif
-/* compat. with non-clang compilers */
-#ifndef __has_builtin
-# define __has_builtin(x) 0
+/* compile time determination of SIMD support */
+#if !defined(ZSTD_NO_INTRINSICS)
+# if defined(__SSE2__) || defined(_M_AMD64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
+# define ZSTD_ARCH_X86_SSE2
+# endif
+# if defined(__ARM_NEON) || defined(_M_ARM64)
+# define ZSTD_ARCH_ARM_NEON
+# endif
+#
+# if defined(ZSTD_ARCH_X86_SSE2)
+# include <emmintrin.h>
+# elif defined(ZSTD_ARCH_ARM_NEON)
+# include <arm_neon.h>
+# endif
#endif
-/* compat. with non-clang compilers */
-#ifndef __has_feature
-# define __has_feature(x) 0
+/* C-language Attributes are added in C23. */
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
+# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
+#else
+# define ZSTD_HAS_C_ATTRIBUTE(x) 0
#endif
-/* detects whether we are being compiled under msan */
-#ifndef ZSTD_MEMORY_SANITIZER
-# if __has_feature(memory_sanitizer)
-# define ZSTD_MEMORY_SANITIZER 1
-# else
-# define ZSTD_MEMORY_SANITIZER 0
-# endif
+/* Only use C++ attributes in C++. Some compilers report support for C++
+ * attributes when compiling with C.
+ */
+#if defined(__cplusplus) && defined(__has_cpp_attribute)
+# define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
+#else
+# define ZSTD_HAS_CPP_ATTRIBUTE(x) 0
#endif
+/* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute.
+ * - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough
+ * - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough
+ * - Else: __attribute__((__fallthrough__))
+ */
+#ifndef ZSTD_FALLTHROUGH
+# if ZSTD_HAS_C_ATTRIBUTE(fallthrough)
+# define ZSTD_FALLTHROUGH [[fallthrough]]
+# elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough)
+# define ZSTD_FALLTHROUGH [[fallthrough]]
+# elif __has_attribute(__fallthrough__)
+/* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon
+ * gcc complains about: a label can only be part of a statement and a declaration is not a statement.
+ */
+# define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__))
+# else
+# define ZSTD_FALLTHROUGH
+# endif
+#endif
+
+/*-**************************************************************
+* Alignment check
+*****************************************************************/
+
+/* this test was initially positioned in mem.h,
+ * but this file is removed (or replaced) for linux kernel
+ * so it's now hosted in compiler.h,
+ * which remains valid for both user & kernel spaces.
+ */
+
+#ifndef ZSTD_ALIGNOF
+# if defined(__GNUC__) || defined(_MSC_VER)
+/* covers gcc, clang & MSVC */
+/* note : this section must come first, before C11,
+ * due to a limitation in the kernel source generator */
+# define ZSTD_ALIGNOF(T) __alignof(T)
+
+# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+/* C11 support */
+# include <stdalign.h>
+# define ZSTD_ALIGNOF(T) alignof(T)
+
+# else
+/* No known support for alignof() - imperfect backup */
+# define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T))
+
+# endif
+#endif /* ZSTD_ALIGNOF */
+
+/*-**************************************************************
+* Sanitizer
+*****************************************************************/
+
#if ZSTD_MEMORY_SANITIZER
/* Not all platforms that support msan provide sanitizers/msan_interface.h.
* We therefore declare the functions we need ourselves, rather than trying to
@@ -237,17 +294,6 @@ void __msan_poison(const volatile void *a, size_t size);
intptr_t __msan_test_shadow(const volatile void *x, size_t size);
#endif
-/* detects whether we are being compiled under asan */
-#ifndef ZSTD_ADDRESS_SANITIZER
-# if __has_feature(address_sanitizer)
-# define ZSTD_ADDRESS_SANITIZER 1
-# elif defined(__SANITIZE_ADDRESS__)
-# define ZSTD_ADDRESS_SANITIZER 1
-# else
-# define ZSTD_ADDRESS_SANITIZER 0
-# endif
-#endif
-
#if ZSTD_ADDRESS_SANITIZER
/* Not all platforms that support asan provide sanitizers/asan_interface.h.
* We therefore declare the functions we need ourselves, rather than trying to
diff --git a/thirdparty/zstd/common/entropy_common.c b/thirdparty/zstd/common/entropy_common.c
index 41cd69566b..4229b40c5e 100644
--- a/thirdparty/zstd/common/entropy_common.c
+++ b/thirdparty/zstd/common/entropy_common.c
@@ -43,8 +43,14 @@ static U32 FSE_ctz(U32 val)
assert(val != 0);
{
# if defined(_MSC_VER) /* Visual */
- unsigned long r=0;
- return _BitScanForward(&r, val) ? (unsigned)r : 0;
+ if (val != 0) {
+ unsigned long r;
+ _BitScanForward(&r, val);
+ return (unsigned)r;
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
return __builtin_ctz(val);
# elif defined(__ICCARM__) /* IAR Intrinsic */
@@ -217,7 +223,7 @@ static size_t FSE_readNCount_body_default(
}
#if DYNAMIC_BMI2
-TARGET_ATTRIBUTE("bmi2") static size_t FSE_readNCount_body_bmi2(
+BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2(
short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
const void* headerBuffer, size_t hbSize)
{
@@ -299,7 +305,7 @@ HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats,
ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
weightTotal = 0;
{ U32 n; for (n=0; n<oSize; n++) {
- if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
+ if (huffWeight[n] > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
rankStats[huffWeight[n]]++;
weightTotal += (1 << huffWeight[n]) >> 1;
} }
@@ -337,7 +343,7 @@ static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* r
}
#if DYNAMIC_BMI2
-static TARGET_ATTRIBUTE("bmi2") size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats,
+static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats,
U32* nbSymbolsPtr, U32* tableLogPtr,
const void* src, size_t srcSize,
void* workSpace, size_t wkspSize)
diff --git a/thirdparty/zstd/common/error_private.h b/thirdparty/zstd/common/error_private.h
index 6d8b9f7763..007d81066a 100644
--- a/thirdparty/zstd/common/error_private.h
+++ b/thirdparty/zstd/common/error_private.h
@@ -22,6 +22,8 @@ extern "C" {
* Dependencies
******************************************/
#include "../zstd_errors.h" /* enum list */
+#include "compiler.h"
+#include "debug.h"
#include "zstd_deps.h" /* size_t */
@@ -73,6 +75,83 @@ ERR_STATIC const char* ERR_getErrorName(size_t code)
return ERR_getErrorString(ERR_getErrorCode(code));
}
+/**
+ * Ignore: this is an internal helper.
+ *
+ * This is a helper function to help force C99-correctness during compilation.
+ * Under strict compilation modes, variadic macro arguments can't be empty.
+ * However, variadic function arguments can be. Using a function therefore lets
+ * us statically check that at least one (string) argument was passed,
+ * independent of the compilation flags.
+ */
+static INLINE_KEYWORD UNUSED_ATTR
+void _force_has_format_string(const char *format, ...) {
+ (void)format;
+}
+
+/**
+ * Ignore: this is an internal helper.
+ *
+ * We want to force this function invocation to be syntactically correct, but
+ * we don't want to force runtime evaluation of its arguments.
+ */
+#define _FORCE_HAS_FORMAT_STRING(...) \
+ if (0) { \
+ _force_has_format_string(__VA_ARGS__); \
+ }
+
+#define ERR_QUOTE(str) #str
+
+/**
+ * Return the specified error if the condition evaluates to true.
+ *
+ * In debug modes, prints additional information.
+ * In order to do that (particularly, printing the conditional that failed),
+ * this can't just wrap RETURN_ERROR().
+ */
+#define RETURN_ERROR_IF(cond, err, ...) \
+ if (cond) { \
+ RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
+ __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
+ RAWLOG(3, ": " __VA_ARGS__); \
+ RAWLOG(3, "\n"); \
+ return ERROR(err); \
+ }
+
+/**
+ * Unconditionally return the specified error.
+ *
+ * In debug modes, prints additional information.
+ */
+#define RETURN_ERROR(err, ...) \
+ do { \
+ RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
+ __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
+ RAWLOG(3, ": " __VA_ARGS__); \
+ RAWLOG(3, "\n"); \
+ return ERROR(err); \
+ } while(0);
+
+/**
+ * If the provided expression evaluates to an error code, returns that error code.
+ *
+ * In debug modes, prints additional information.
+ */
+#define FORWARD_IF_ERROR(err, ...) \
+ do { \
+ size_t const err_code = (err); \
+ if (ERR_isError(err_code)) { \
+ RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
+ __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
+ RAWLOG(3, ": " __VA_ARGS__); \
+ RAWLOG(3, "\n"); \
+ return err_code; \
+ } \
+ } while(0);
+
#if defined (__cplusplus)
}
#endif
diff --git a/thirdparty/zstd/common/fse.h b/thirdparty/zstd/common/fse.h
index 19dd4febcd..714bfd3e7f 100644
--- a/thirdparty/zstd/common/fse.h
+++ b/thirdparty/zstd/common/fse.h
@@ -336,8 +336,9 @@ size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
/* FSE_buildCTable_wksp() :
* Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
* `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`.
+ * See FSE_buildCTable_wksp() for breakdown of workspace usage.
*/
-#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (maxSymbolValue + 2 + (1ull << (tableLog - 2)))
+#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (((maxSymbolValue + 2) + (1ull << (tableLog)))/2 + sizeof(U64)/sizeof(U32) /* additional 8 bytes for potential table overwrite */)
#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog))
size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
diff --git a/thirdparty/zstd/common/fse_decompress.c b/thirdparty/zstd/common/fse_decompress.c
index f4ff58fa0a..a5a358015f 100644
--- a/thirdparty/zstd/common/fse_decompress.c
+++ b/thirdparty/zstd/common/fse_decompress.c
@@ -365,7 +365,7 @@ static size_t FSE_decompress_wksp_body_default(void* dst, size_t dstCapacity, co
}
#if DYNAMIC_BMI2
-TARGET_ATTRIBUTE("bmi2") static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
+BMI2_TARGET_ATTRIBUTE static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
{
return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 1);
}
diff --git a/thirdparty/zstd/common/huf.h b/thirdparty/zstd/common/huf.h
index 3d47ced030..85518481ec 100644
--- a/thirdparty/zstd/common/huf.h
+++ b/thirdparty/zstd/common/huf.h
@@ -89,9 +89,9 @@ HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity,
/** HUF_compress4X_wksp() :
* Same as HUF_compress2(), but uses externally allocated `workSpace`.
- * `workspace` must have minimum alignment of 4, and be at least as large as HUF_WORKSPACE_SIZE */
-#define HUF_WORKSPACE_SIZE ((6 << 10) + 256)
-#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32))
+ * `workspace` must be at least as large as HUF_WORKSPACE_SIZE */
+#define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */)
+#define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64))
HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned tableLog,
@@ -116,11 +116,11 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
/* *** Constants *** */
-#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
+#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_TABLELOG_ABSOLUTEMAX */
#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */
#define HUF_SYMBOLVALUE_MAX 255
-#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
+#define HUF_TABLELOG_ABSOLUTEMAX 12 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
# error "HUF_TABLELOG_MAX is too large !"
#endif
@@ -136,15 +136,11 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
/* static allocation of HUF's Compression Table */
/* this is a private definition, just exposed for allocation and strict aliasing purpose. never EVER access its members directly */
-struct HUF_CElt_s {
- U16 val;
- BYTE nbBits;
-}; /* typedef'd to HUF_CElt */
-typedef struct HUF_CElt_s HUF_CElt; /* consider it an incomplete type */
-#define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */
-#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32))
+typedef size_t HUF_CElt; /* consider it an incomplete type */
+#define HUF_CTABLE_SIZE_ST(maxSymbolValue) ((maxSymbolValue)+2) /* Use tables of size_t, for proper alignment */
+#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_ST(maxSymbolValue) * sizeof(size_t))
#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
- HUF_CElt name[HUF_CTABLE_SIZE_U32(maxSymbolValue)] /* no final ; */
+ HUF_CElt name[HUF_CTABLE_SIZE_ST(maxSymbolValue)] /* no final ; */
/* static allocation of HUF's DTable */
typedef U32 HUF_DTable;
@@ -194,6 +190,7 @@ size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSym
size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize);
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
+size_t HUF_compress4X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2);
size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
@@ -206,12 +203,13 @@ typedef enum {
* Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
* If it uses hufTable it does not modify hufTable or repeat.
* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
- * If preferRepeat then the old table will always be used if valid. */
+ * If preferRepeat then the old table will always be used if valid.
+ * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */
size_t HUF_compress4X_repeat(void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned tableLog,
void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */
- HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2);
+ HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible);
/** HUF_buildCTable_wksp() :
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
@@ -249,11 +247,10 @@ size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize,
* Loading a CTable saved with HUF_writeCTable() */
size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights);
-/** HUF_getNbBits() :
+/** HUF_getNbBitsFromCTable() :
* Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX
- * Note 1 : is not inlined, as HUF_CElt definition is private
- * Note 2 : const void* used, so that it can provide a statically allocated table as argument (which uses type U32) */
-U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue);
+ * Note 1 : is not inlined, as HUF_CElt definition is private */
+U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue);
/*
* HUF_decompress() does the following:
@@ -305,18 +302,20 @@ size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* c
/* ====================== */
size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
-size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
+size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U64 U64 */
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
+size_t HUF_compress1X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2);
/** HUF_compress1X_repeat() :
* Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
* If it uses hufTable it does not modify hufTable or repeat.
* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
- * If preferRepeat then the old table will always be used if valid. */
+ * If preferRepeat then the old table will always be used if valid.
+ * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */
size_t HUF_compress1X_repeat(void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned tableLog,
void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */
- HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2);
+ HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible);
size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
#ifndef HUF_FORCE_DECOMPRESS_X1
@@ -354,6 +353,9 @@ size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t ds
#ifndef HUF_FORCE_DECOMPRESS_X2
size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2);
#endif
+#ifndef HUF_FORCE_DECOMPRESS_X1
+size_t HUF_readDTableX2_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2);
+#endif
#endif /* HUF_STATIC_LINKING_ONLY */
diff --git a/thirdparty/zstd/common/mem.h b/thirdparty/zstd/common/mem.h
index 9f3b81ab9d..85581c3847 100644
--- a/thirdparty/zstd/common/mem.h
+++ b/thirdparty/zstd/common/mem.h
@@ -51,6 +51,8 @@ extern "C" {
# include <stdint.h> /* intptr_t */
# endif
typedef uint8_t BYTE;
+ typedef uint8_t U8;
+ typedef int8_t S8;
typedef uint16_t U16;
typedef int16_t S16;
typedef uint32_t U32;
@@ -63,6 +65,8 @@ extern "C" {
# error "this implementation requires char to be exactly 8-bit type"
#endif
typedef unsigned char BYTE;
+ typedef unsigned char U8;
+ typedef signed char S8;
#if USHRT_MAX != 65535
# error "this implementation requires short to be exactly 16-bit type"
#endif
@@ -153,8 +157,22 @@ MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
MEM_STATIC unsigned MEM_isLittleEndian(void)
{
+#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+ return 1;
+#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+ return 0;
+#elif defined(__clang__) && __LITTLE_ENDIAN__
+ return 1;
+#elif defined(__clang__) && __BIG_ENDIAN__
+ return 0;
+#elif defined(_MSC_VER) && (_M_AMD64 || _M_IX86)
+ return 1;
+#elif defined(__DMC__) && defined(_M_IX86)
+ return 1;
+#else
const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
return one.c[0];
+#endif
}
#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)
diff --git a/thirdparty/zstd/common/pool.c b/thirdparty/zstd/common/pool.c
index ea70b8b65a..2e37cdd73c 100644
--- a/thirdparty/zstd/common/pool.c
+++ b/thirdparty/zstd/common/pool.c
@@ -86,7 +86,7 @@ static void* POOL_thread(void* opaque) {
{ POOL_job const job = ctx->queue[ctx->queueHead];
ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;
ctx->numThreadsBusy++;
- ctx->queueEmpty = ctx->queueHead == ctx->queueTail;
+ ctx->queueEmpty = (ctx->queueHead == ctx->queueTail);
/* Unlock the mutex, signal a pusher, and run the job */
ZSTD_pthread_cond_signal(&ctx->queuePushCond);
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
@@ -105,6 +105,7 @@ static void* POOL_thread(void* opaque) {
assert(0); /* Unreachable */
}
+/* ZSTD_createThreadPool() : public access point */
POOL_ctx* ZSTD_createThreadPool(size_t numThreads) {
return POOL_create (numThreads, 0);
}
@@ -114,7 +115,8 @@ POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
}
POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
- ZSTD_customMem customMem) {
+ ZSTD_customMem customMem)
+{
POOL_ctx* ctx;
/* Check parameters */
if (!numThreads) { return NULL; }
@@ -192,7 +194,7 @@ void ZSTD_freeThreadPool (ZSTD_threadPool* pool) {
POOL_free (pool);
}
-size_t POOL_sizeof(POOL_ctx *ctx) {
+size_t POOL_sizeof(const POOL_ctx* ctx) {
if (ctx==NULL) return 0; /* supports sizeof NULL */
return sizeof(*ctx)
+ ctx->queueSize * sizeof(POOL_job)
@@ -257,7 +259,8 @@ static int isQueueFull(POOL_ctx const* ctx) {
}
-static void POOL_add_internal(POOL_ctx* ctx, POOL_function function, void *opaque)
+static void
+POOL_add_internal(POOL_ctx* ctx, POOL_function function, void *opaque)
{
POOL_job const job = {function, opaque};
assert(ctx != NULL);
@@ -313,7 +316,9 @@ POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
}
-POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) {
+POOL_ctx*
+POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem)
+{
(void)numThreads;
(void)queueSize;
(void)customMem;
@@ -341,7 +346,7 @@ int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) {
return 1;
}
-size_t POOL_sizeof(POOL_ctx* ctx) {
+size_t POOL_sizeof(const POOL_ctx* ctx) {
if (ctx==NULL) return 0; /* supports sizeof NULL */
assert(ctx == &g_poolCtx);
return sizeof(*ctx);
diff --git a/thirdparty/zstd/common/pool.h b/thirdparty/zstd/common/pool.h
index e18aa0708f..0ebde1805d 100644
--- a/thirdparty/zstd/common/pool.h
+++ b/thirdparty/zstd/common/pool.h
@@ -53,7 +53,7 @@ int POOL_resize(POOL_ctx* ctx, size_t numThreads);
* @return threadpool memory usage
* note : compatible with NULL (returns 0 in this case)
*/
-size_t POOL_sizeof(POOL_ctx* ctx);
+size_t POOL_sizeof(const POOL_ctx* ctx);
/*! POOL_function :
* The function type that can be added to a thread pool.
@@ -70,7 +70,7 @@ void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque);
/*! POOL_tryAdd() :
- * Add the job `function(opaque)` to thread pool _if_ a worker is available.
+ * Add the job `function(opaque)` to thread pool _if_ a queue slot is available.
* Returns immediately even if not (does not block).
* @return : 1 if successful, 0 if not.
*/
diff --git a/thirdparty/zstd/common/portability_macros.h b/thirdparty/zstd/common/portability_macros.h
new file mode 100644
index 0000000000..2143817f57
--- /dev/null
+++ b/thirdparty/zstd/common/portability_macros.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+#ifndef ZSTD_PORTABILITY_MACROS_H
+#define ZSTD_PORTABILITY_MACROS_H
+
+/**
+ * This header file contains macro defintions to support portability.
+ * This header is shared between C and ASM code, so it MUST only
+ * contain macro definitions. It MUST not contain any C code.
+ *
+ * This header ONLY defines macros to detect platforms/feature support.
+ *
+ */
+
+
+/* compat. with non-clang compilers */
+#ifndef __has_attribute
+ #define __has_attribute(x) 0
+#endif
+
+/* compat. with non-clang compilers */
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/* compat. with non-clang compilers */
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+/* detects whether we are being compiled under msan */
+#ifndef ZSTD_MEMORY_SANITIZER
+# if __has_feature(memory_sanitizer)
+# define ZSTD_MEMORY_SANITIZER 1
+# else
+# define ZSTD_MEMORY_SANITIZER 0
+# endif
+#endif
+
+/* detects whether we are being compiled under asan */
+#ifndef ZSTD_ADDRESS_SANITIZER
+# if __has_feature(address_sanitizer)
+# define ZSTD_ADDRESS_SANITIZER 1
+# elif defined(__SANITIZE_ADDRESS__)
+# define ZSTD_ADDRESS_SANITIZER 1
+# else
+# define ZSTD_ADDRESS_SANITIZER 0
+# endif
+#endif
+
+/* detects whether we are being compiled under dfsan */
+#ifndef ZSTD_DATAFLOW_SANITIZER
+# if __has_feature(dataflow_sanitizer)
+# define ZSTD_DATAFLOW_SANITIZER 1
+# else
+# define ZSTD_DATAFLOW_SANITIZER 0
+# endif
+#endif
+
+/* Mark the internal assembly functions as hidden */
+#ifdef __ELF__
+# define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func
+#else
+# define ZSTD_HIDE_ASM_FUNCTION(func)
+#endif
+
+/* Enable runtime BMI2 dispatch based on the CPU.
+ * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
+ */
+#ifndef DYNAMIC_BMI2
+ #if ((defined(__clang__) && __has_attribute(__target__)) \
+ || (defined(__GNUC__) \
+ && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
+ && (defined(__x86_64__) || defined(_M_X64)) \
+ && !defined(__BMI2__)
+ # define DYNAMIC_BMI2 1
+ #else
+ # define DYNAMIC_BMI2 0
+ #endif
+#endif
+
+/**
+ * Only enable assembly for GNUC comptabile compilers,
+ * because other platforms may not support GAS assembly syntax.
+ *
+ * Only enable assembly for Linux / MacOS, other platforms may
+ * work, but they haven't been tested. This could likely be
+ * extended to BSD systems.
+ *
+ * Disable assembly when MSAN is enabled, because MSAN requires
+ * 100% of code to be instrumented to work.
+ */
+#if defined(__GNUC__)
+# if defined(__linux__) || defined(__linux) || defined(__APPLE__)
+# if ZSTD_MEMORY_SANITIZER
+# define ZSTD_ASM_SUPPORTED 0
+# elif ZSTD_DATAFLOW_SANITIZER
+# define ZSTD_ASM_SUPPORTED 0
+# else
+# define ZSTD_ASM_SUPPORTED 1
+# endif
+# else
+# define ZSTD_ASM_SUPPORTED 0
+# endif
+#else
+# define ZSTD_ASM_SUPPORTED 0
+#endif
+
+/**
+ * Determines whether we should enable assembly for x86-64
+ * with BMI2.
+ *
+ * Enable if all of the following conditions hold:
+ * - ASM hasn't been explicitly disabled by defining ZSTD_DISABLE_ASM
+ * - Assembly is supported
+ * - We are compiling for x86-64 and either:
+ * - DYNAMIC_BMI2 is enabled
+ * - BMI2 is supported at compile time
+ */
+#if !defined(ZSTD_DISABLE_ASM) && \
+ ZSTD_ASM_SUPPORTED && \
+ defined(__x86_64__) && \
+ (DYNAMIC_BMI2 || defined(__BMI2__))
+# define ZSTD_ENABLE_ASM_X86_64_BMI2 1
+#else
+# define ZSTD_ENABLE_ASM_X86_64_BMI2 0
+#endif
+
+#endif /* ZSTD_PORTABILITY_MACROS_H */
diff --git a/thirdparty/zstd/common/xxhash.c b/thirdparty/zstd/common/xxhash.c
index 926b33604e..d49497cf1c 100644
--- a/thirdparty/zstd/common/xxhash.c
+++ b/thirdparty/zstd/common/xxhash.c
@@ -5,7 +5,7 @@
* You can contact the author at :
* - xxHash homepage: http://www.xxhash.com
* - xxHash source repository : https://github.com/Cyan4973/xxHash
- *
+ *
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
@@ -13,812 +13,12 @@
*/
-/* *************************************
-* Tuning parameters
-***************************************/
-/*!XXH_FORCE_MEMORY_ACCESS :
- * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
- * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
- * The below switch allow to select different access method for improved performance.
- * Method 0 (default) : use `memcpy()`. Safe and portable.
- * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
- * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
- * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.
- * It can generate buggy code on targets which do not support unaligned memory accesses.
- * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
- * See http://stackoverflow.com/a/32095106/646947 for details.
- * Prefer these methods in priority order (0 > 1 > 2)
- */
-#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
-# if (defined(__INTEL_COMPILER) && !defined(WIN32)) || \
- (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) || \
- defined(__ICCARM__)
-# define XXH_FORCE_MEMORY_ACCESS 1
-# endif
-#endif
-
-/*!XXH_ACCEPT_NULL_INPUT_POINTER :
- * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
- * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
- * By default, this option is disabled. To enable it, uncomment below define :
- */
-/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */
-
-/*!XXH_FORCE_NATIVE_FORMAT :
- * By default, xxHash library provides endian-independent Hash values, based on little-endian convention.
- * Results are therefore identical for little-endian and big-endian CPU.
- * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
- * Should endian-independence be of no importance for your application, you may set the #define below to 1,
- * to improve speed for Big-endian CPU.
- * This option has no impact on Little_Endian CPU.
- */
-#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */
-# define XXH_FORCE_NATIVE_FORMAT 0
-#endif
-/*!XXH_FORCE_ALIGN_CHECK :
- * This is a minor performance trick, only useful with lots of very small keys.
- * It means : check for aligned/unaligned input.
- * The check costs one initial branch per hash; set to 0 when the input data
- * is guaranteed to be aligned.
+/*
+ * xxhash.c instantiates functions defined in xxhash.h
*/
-#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
-# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
-# define XXH_FORCE_ALIGN_CHECK 0
-# else
-# define XXH_FORCE_ALIGN_CHECK 1
-# endif
-#endif
-
-/* *************************************
-* Includes & Memory related functions
-***************************************/
-/* Modify the local functions below should you wish to use some other memory routines */
-/* for ZSTD_malloc(), ZSTD_free() */
-#define ZSTD_DEPS_NEED_MALLOC
-#include "zstd_deps.h" /* size_t, ZSTD_malloc, ZSTD_free, ZSTD_memcpy */
-static void* XXH_malloc(size_t s) { return ZSTD_malloc(s); }
-static void XXH_free (void* p) { ZSTD_free(p); }
-static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_memcpy(dest,src,size); }
+#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */
+#define XXH_IMPLEMENTATION /* access definitions */
-#ifndef XXH_STATIC_LINKING_ONLY
-# define XXH_STATIC_LINKING_ONLY
-#endif
#include "xxhash.h"
-
-
-/* *************************************
-* Compiler Specific Options
-***************************************/
-#include "compiler.h"
-
-
-/* *************************************
-* Basic Types
-***************************************/
-#include "mem.h" /* BYTE, U32, U64, size_t */
-
-#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
-
-/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
-static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
-static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
-
-#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
-
-/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
-/* currently only defined for gcc and icc */
-typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign;
-
-static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
-static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
-
-#else
-
-/* portable and safe solution. Generally efficient.
- * see : http://stackoverflow.com/a/32095106/646947
- */
-
-static U32 XXH_read32(const void* memPtr)
-{
- U32 val;
- ZSTD_memcpy(&val, memPtr, sizeof(val));
- return val;
-}
-
-static U64 XXH_read64(const void* memPtr)
-{
- U64 val;
- ZSTD_memcpy(&val, memPtr, sizeof(val));
- return val;
-}
-
-#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
-
-
-/* ****************************************
-* Compiler-specific Functions and Macros
-******************************************/
-#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
-
-/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
-#if defined(_MSC_VER)
-# define XXH_rotl32(x,r) _rotl(x,r)
-# define XXH_rotl64(x,r) _rotl64(x,r)
-#else
-#if defined(__ICCARM__)
-# include <intrinsics.h>
-# define XXH_rotl32(x,r) __ROR(x,(32 - r))
-#else
-# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
-#endif
-# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
-#endif
-
-#if defined(_MSC_VER) /* Visual Studio */
-# define XXH_swap32 _byteswap_ulong
-# define XXH_swap64 _byteswap_uint64
-#elif GCC_VERSION >= 403
-# define XXH_swap32 __builtin_bswap32
-# define XXH_swap64 __builtin_bswap64
-#else
-static U32 XXH_swap32 (U32 x)
-{
- return ((x << 24) & 0xff000000 ) |
- ((x << 8) & 0x00ff0000 ) |
- ((x >> 8) & 0x0000ff00 ) |
- ((x >> 24) & 0x000000ff );
-}
-static U64 XXH_swap64 (U64 x)
-{
- return ((x << 56) & 0xff00000000000000ULL) |
- ((x << 40) & 0x00ff000000000000ULL) |
- ((x << 24) & 0x0000ff0000000000ULL) |
- ((x << 8) & 0x000000ff00000000ULL) |
- ((x >> 8) & 0x00000000ff000000ULL) |
- ((x >> 24) & 0x0000000000ff0000ULL) |
- ((x >> 40) & 0x000000000000ff00ULL) |
- ((x >> 56) & 0x00000000000000ffULL);
-}
-#endif
-
-
-/* *************************************
-* Architecture Macros
-***************************************/
-typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
-
-/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
-#ifndef XXH_CPU_LITTLE_ENDIAN
- static const int g_one = 1;
-# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one))
-#endif
-
-
-/* ***************************
-* Memory reads
-*****************************/
-typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
-
-FORCE_INLINE_TEMPLATE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
-{
- if (align==XXH_unaligned)
- return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
- else
- return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
-}
-
-FORCE_INLINE_TEMPLATE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
-{
- return XXH_readLE32_align(ptr, endian, XXH_unaligned);
-}
-
-static U32 XXH_readBE32(const void* ptr)
-{
- return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
-}
-
-FORCE_INLINE_TEMPLATE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
-{
- if (align==XXH_unaligned)
- return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
- else
- return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
-}
-
-FORCE_INLINE_TEMPLATE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
-{
- return XXH_readLE64_align(ptr, endian, XXH_unaligned);
-}
-
-static U64 XXH_readBE64(const void* ptr)
-{
- return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
-}
-
-
-/* *************************************
-* Macros
-***************************************/
-#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
-
-
-/* *************************************
-* Constants
-***************************************/
-static const U32 PRIME32_1 = 2654435761U;
-static const U32 PRIME32_2 = 2246822519U;
-static const U32 PRIME32_3 = 3266489917U;
-static const U32 PRIME32_4 = 668265263U;
-static const U32 PRIME32_5 = 374761393U;
-
-static const U64 PRIME64_1 = 11400714785074694791ULL;
-static const U64 PRIME64_2 = 14029467366897019727ULL;
-static const U64 PRIME64_3 = 1609587929392839161ULL;
-static const U64 PRIME64_4 = 9650029242287828579ULL;
-static const U64 PRIME64_5 = 2870177450012600261ULL;
-
-XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
-
-
-/* **************************
-* Utils
-****************************/
-XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState)
-{
- ZSTD_memcpy(dstState, srcState, sizeof(*dstState));
-}
-
-XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState)
-{
- ZSTD_memcpy(dstState, srcState, sizeof(*dstState));
-}
-
-
-/* ***************************
-* Simple Hash Functions
-*****************************/
-
-static U32 XXH32_round(U32 seed, U32 input)
-{
- seed += input * PRIME32_2;
- seed = XXH_rotl32(seed, 13);
- seed *= PRIME32_1;
- return seed;
-}
-
-FORCE_INLINE_TEMPLATE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
-{
- const BYTE* p = (const BYTE*)input;
- const BYTE* bEnd = p + len;
- U32 h32;
-#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
-
-#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
- if (p==NULL) {
- len=0;
- bEnd=p=(const BYTE*)(size_t)16;
- }
-#endif
-
- if (len>=16) {
- const BYTE* const limit = bEnd - 16;
- U32 v1 = seed + PRIME32_1 + PRIME32_2;
- U32 v2 = seed + PRIME32_2;
- U32 v3 = seed + 0;
- U32 v4 = seed - PRIME32_1;
-
- do {
- v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;
- v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;
- v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;
- v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;
- } while (p<=limit);
-
- h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
- } else {
- h32 = seed + PRIME32_5;
- }
-
- h32 += (U32) len;
-
- while (p+4<=bEnd) {
- h32 += XXH_get32bits(p) * PRIME32_3;
- h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
- p+=4;
- }
-
- while (p<bEnd) {
- h32 += (*p) * PRIME32_5;
- h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
- p++;
- }
-
- h32 ^= h32 >> 15;
- h32 *= PRIME32_2;
- h32 ^= h32 >> 13;
- h32 *= PRIME32_3;
- h32 ^= h32 >> 16;
-
- return h32;
-}
-
-
-XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)
-{
-#if 0
- /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
- XXH32_CREATESTATE_STATIC(state);
- XXH32_reset(state, seed);
- XXH32_update(state, input, len);
- return XXH32_digest(state);
-#else
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
-
- if (XXH_FORCE_ALIGN_CHECK) {
- if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
- else
- return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
- } }
-
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
- else
- return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
-#endif
-}
-
-
-static U64 XXH64_round(U64 acc, U64 input)
-{
- acc += input * PRIME64_2;
- acc = XXH_rotl64(acc, 31);
- acc *= PRIME64_1;
- return acc;
-}
-
-static U64 XXH64_mergeRound(U64 acc, U64 val)
-{
- val = XXH64_round(0, val);
- acc ^= val;
- acc = acc * PRIME64_1 + PRIME64_4;
- return acc;
-}
-
-FORCE_INLINE_TEMPLATE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
-{
- const BYTE* p = (const BYTE*)input;
- const BYTE* const bEnd = p + len;
- U64 h64;
-#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
-
-#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
- if (p==NULL) {
- len=0;
- bEnd=p=(const BYTE*)(size_t)32;
- }
-#endif
-
- if (len>=32) {
- const BYTE* const limit = bEnd - 32;
- U64 v1 = seed + PRIME64_1 + PRIME64_2;
- U64 v2 = seed + PRIME64_2;
- U64 v3 = seed + 0;
- U64 v4 = seed - PRIME64_1;
-
- do {
- v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;
- v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;
- v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;
- v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;
- } while (p<=limit);
-
- h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
- h64 = XXH64_mergeRound(h64, v1);
- h64 = XXH64_mergeRound(h64, v2);
- h64 = XXH64_mergeRound(h64, v3);
- h64 = XXH64_mergeRound(h64, v4);
-
- } else {
- h64 = seed + PRIME64_5;
- }
-
- h64 += (U64) len;
-
- while (p+8<=bEnd) {
- U64 const k1 = XXH64_round(0, XXH_get64bits(p));
- h64 ^= k1;
- h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
- p+=8;
- }
-
- if (p+4<=bEnd) {
- h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
- h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
- p+=4;
- }
-
- while (p<bEnd) {
- h64 ^= (*p) * PRIME64_5;
- h64 = XXH_rotl64(h64, 11) * PRIME64_1;
- p++;
- }
-
- h64 ^= h64 >> 33;
- h64 *= PRIME64_2;
- h64 ^= h64 >> 29;
- h64 *= PRIME64_3;
- h64 ^= h64 >> 32;
-
- return h64;
-}
-
-
-XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
-{
-#if 0
- /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
- XXH64_CREATESTATE_STATIC(state);
- XXH64_reset(state, seed);
- XXH64_update(state, input, len);
- return XXH64_digest(state);
-#else
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
-
- if (XXH_FORCE_ALIGN_CHECK) {
- if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
- else
- return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
- } }
-
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
- else
- return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
-#endif
-}
-
-
-/* **************************************************
-* Advanced Hash Functions
-****************************************************/
-
-XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
-{
- return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
-}
-XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
-{
- XXH_free(statePtr);
- return XXH_OK;
-}
-
-XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
-{
- return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
-}
-XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
-{
- XXH_free(statePtr);
- return XXH_OK;
-}
-
-
-/*** Hash feed ***/
-
-XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)
-{
- XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
- ZSTD_memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */
- state.v1 = seed + PRIME32_1 + PRIME32_2;
- state.v2 = seed + PRIME32_2;
- state.v3 = seed + 0;
- state.v4 = seed - PRIME32_1;
- ZSTD_memcpy(statePtr, &state, sizeof(state));
- return XXH_OK;
-}
-
-
-XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)
-{
- XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
- ZSTD_memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */
- state.v1 = seed + PRIME64_1 + PRIME64_2;
- state.v2 = seed + PRIME64_2;
- state.v3 = seed + 0;
- state.v4 = seed - PRIME64_1;
- ZSTD_memcpy(statePtr, &state, sizeof(state));
- return XXH_OK;
-}
-
-
-FORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
-{
- const BYTE* p = (const BYTE*)input;
- const BYTE* const bEnd = p + len;
-
-#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
- if (input==NULL) return XXH_ERROR;
-#endif
-
- state->total_len_32 += (unsigned)len;
- state->large_len |= (len>=16) | (state->total_len_32>=16);
-
- if (state->memsize + len < 16) { /* fill in tmp buffer */
- XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
- state->memsize += (unsigned)len;
- return XXH_OK;
- }
-
- if (state->memsize) { /* some data left from previous update */
- XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
- { const U32* p32 = state->mem32;
- state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;
- state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;
- state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;
- state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++;
- }
- p += 16-state->memsize;
- state->memsize = 0;
- }
-
- if (p <= bEnd-16) {
- const BYTE* const limit = bEnd - 16;
- U32 v1 = state->v1;
- U32 v2 = state->v2;
- U32 v3 = state->v3;
- U32 v4 = state->v4;
-
- do {
- v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;
- v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;
- v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;
- v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;
- } while (p<=limit);
-
- state->v1 = v1;
- state->v2 = v2;
- state->v3 = v3;
- state->v4 = v4;
- }
-
- if (p < bEnd) {
- XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
- state->memsize = (unsigned)(bEnd-p);
- }
-
- return XXH_OK;
-}
-
-XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
-{
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
-
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
- else
- return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
-}
-
-
-
-FORCE_INLINE_TEMPLATE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
-{
- const BYTE * p = (const BYTE*)state->mem32;
- const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize;
- U32 h32;
-
- if (state->large_len) {
- h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
- } else {
- h32 = state->v3 /* == seed */ + PRIME32_5;
- }
-
- h32 += state->total_len_32;
-
- while (p+4<=bEnd) {
- h32 += XXH_readLE32(p, endian) * PRIME32_3;
- h32 = XXH_rotl32(h32, 17) * PRIME32_4;
- p+=4;
- }
-
- while (p<bEnd) {
- h32 += (*p) * PRIME32_5;
- h32 = XXH_rotl32(h32, 11) * PRIME32_1;
- p++;
- }
-
- h32 ^= h32 >> 15;
- h32 *= PRIME32_2;
- h32 ^= h32 >> 13;
- h32 *= PRIME32_3;
- h32 ^= h32 >> 16;
-
- return h32;
-}
-
-
-XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
-{
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
-
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH32_digest_endian(state_in, XXH_littleEndian);
- else
- return XXH32_digest_endian(state_in, XXH_bigEndian);
-}
-
-
-
-/* **** XXH64 **** */
-
-FORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
-{
- const BYTE* p = (const BYTE*)input;
- const BYTE* const bEnd = p + len;
-
-#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
- if (input==NULL) return XXH_ERROR;
-#endif
-
- state->total_len += len;
-
- if (state->memsize + len < 32) { /* fill in tmp buffer */
- if (input != NULL) {
- XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
- }
- state->memsize += (U32)len;
- return XXH_OK;
- }
-
- if (state->memsize) { /* tmp buffer is full */
- XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
- state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));
- state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));
- state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));
- state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));
- p += 32-state->memsize;
- state->memsize = 0;
- }
-
- if (p+32 <= bEnd) {
- const BYTE* const limit = bEnd - 32;
- U64 v1 = state->v1;
- U64 v2 = state->v2;
- U64 v3 = state->v3;
- U64 v4 = state->v4;
-
- do {
- v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;
- v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;
- v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;
- v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;
- } while (p<=limit);
-
- state->v1 = v1;
- state->v2 = v2;
- state->v3 = v3;
- state->v4 = v4;
- }
-
- if (p < bEnd) {
- XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
- state->memsize = (unsigned)(bEnd-p);
- }
-
- return XXH_OK;
-}
-
-XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
-{
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
-
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
- else
- return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
-}
-
-
-
-FORCE_INLINE_TEMPLATE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
-{
- const BYTE * p = (const BYTE*)state->mem64;
- const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize;
- U64 h64;
-
- if (state->total_len >= 32) {
- U64 const v1 = state->v1;
- U64 const v2 = state->v2;
- U64 const v3 = state->v3;
- U64 const v4 = state->v4;
-
- h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
- h64 = XXH64_mergeRound(h64, v1);
- h64 = XXH64_mergeRound(h64, v2);
- h64 = XXH64_mergeRound(h64, v3);
- h64 = XXH64_mergeRound(h64, v4);
- } else {
- h64 = state->v3 + PRIME64_5;
- }
-
- h64 += (U64) state->total_len;
-
- while (p+8<=bEnd) {
- U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian));
- h64 ^= k1;
- h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
- p+=8;
- }
-
- if (p+4<=bEnd) {
- h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
- h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
- p+=4;
- }
-
- while (p<bEnd) {
- h64 ^= (*p) * PRIME64_5;
- h64 = XXH_rotl64(h64, 11) * PRIME64_1;
- p++;
- }
-
- h64 ^= h64 >> 33;
- h64 *= PRIME64_2;
- h64 ^= h64 >> 29;
- h64 *= PRIME64_3;
- h64 ^= h64 >> 32;
-
- return h64;
-}
-
-
-XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
-{
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
-
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
- return XXH64_digest_endian(state_in, XXH_littleEndian);
- else
- return XXH64_digest_endian(state_in, XXH_bigEndian);
-}
-
-
-/* **************************
-* Canonical representation
-****************************/
-
-/*! Default XXH result types are basic unsigned 32 and 64 bits.
-* The canonical representation follows human-readable write convention, aka big-endian (large digits first).
-* These functions allow transformation of hash result into and from its canonical format.
-* This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs.
-*/
-
-XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
-{
- XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
- if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
- ZSTD_memcpy(dst, &hash, sizeof(*dst));
-}
-
-XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
-{
- XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
- if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
- ZSTD_memcpy(dst, &hash, sizeof(*dst));
-}
-
-XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
-{
- return XXH_readBE32(src);
-}
-
-XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
-{
- return XXH_readBE64(src);
-}
diff --git a/thirdparty/zstd/common/xxhash.h b/thirdparty/zstd/common/xxhash.h
index 16c1f1617b..8ebbfdd626 100644
--- a/thirdparty/zstd/common/xxhash.h
+++ b/thirdparty/zstd/common/xxhash.h
@@ -1,20 +1,36 @@
/*
- * xxHash - Extremely Fast Hash algorithm
- * Header File
- * Copyright (c) Yann Collet, Facebook, Inc.
+ * xxHash - Fast Hash algorithm
+ * Copyright (c) Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - xxHash homepage: http://www.xxhash.com
+ * - xxHash source repository : https://github.com/Cyan4973/xxHash
*
- * You can contact the author at :
- * - xxHash source repository : https://github.com/Cyan4973/xxHash
- *
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
* You may select, at your option, one of the above-listed licenses.
*/
-/* Notice extracted from xxHash homepage :
-xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
+#ifndef XXH_NO_XXH3
+# define XXH_NO_XXH3
+#endif
+
+#ifndef XXH_NAMESPACE
+# define XXH_NAMESPACE ZSTD_
+#endif
+
+/*!
+ * @mainpage xxHash
+ *
+ * @file xxhash.h
+ * xxHash prototypes and implementation
+ */
+/* TODO: update */
+/* Notice extracted from xxHash homepage:
+
+xxHash is an extremely fast hash algorithm, running at RAM speed limits.
It also successfully passes all tests from the SMHasher suite.
Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
@@ -22,7 +38,7 @@ Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo
Name Speed Q.Score Author
xxHash 5.4 GB/s 10
CrapWow 3.2 GB/s 2 Andrew
-MumurHash 3a 2.7 GB/s 10 Austin Appleby
+MurmurHash 3a 2.7 GB/s 10 Austin Appleby
SpookyHash 2.0 GB/s 10 Bob Jenkins
SBox 1.4 GB/s 9 Bret Mulvey
Lookup3 1.2 GB/s 9 Bob Jenkins
@@ -37,8 +53,13 @@ Q.Score is a measure of quality of the hash function.
It depends on successfully passing SMHasher test set.
10 is a perfect score.
-A 64-bits version, named XXH64, is available since r35.
-It offers much better speed, but for 64-bits applications only.
+Note: SMHasher's CRC32 implementation is not the fastest one.
+Other speed-oriented implementations can be faster,
+especially in combination with PCLMUL instruction:
+https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735
+
+A 64-bit version, named XXH64, is available since r35.
+It offers much better speed, but for 64-bit applications only.
Name Speed on 64 bits Speed on 32 bits
XXH64 13.8 GB/s 1.9 GB/s
XXH32 6.8 GB/s 6.0 GB/s
@@ -48,33 +69,34 @@ XXH32 6.8 GB/s 6.0 GB/s
extern "C" {
#endif
-#ifndef XXHASH_H_5627135585666179
-#define XXHASH_H_5627135585666179 1
-
-
-/* ****************************
-* Definitions
-******************************/
-#include "zstd_deps.h"
-typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
-
-
/* ****************************
-* API modifier
-******************************/
-/** XXH_PRIVATE_API
-* This is useful if you want to include xxhash functions in `static` mode
-* in order to inline them, and remove their symbol from the public list.
-* Methodology :
-* #define XXH_PRIVATE_API
-* #include "xxhash.h"
-* `xxhash.c` is automatically included.
-* It's not useful to compile and link it as a separate module anymore.
-*/
-#ifdef XXH_PRIVATE_API
-# ifndef XXH_STATIC_LINKING_ONLY
-# define XXH_STATIC_LINKING_ONLY
-# endif
+ * INLINE mode
+ ******************************/
+/*!
+ * XXH_INLINE_ALL (and XXH_PRIVATE_API)
+ * Use these build macros to inline xxhash into the target unit.
+ * Inlining improves performance on small inputs, especially when the length is
+ * expressed as a compile-time constant:
+ *
+ * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html
+ *
+ * It also keeps xxHash symbols private to the unit, so they are not exported.
+ *
+ * Usage:
+ * #define XXH_INLINE_ALL
+ * #include "xxhash.h"
+ *
+ * Do not compile and link xxhash.o as a separate object, as it is not useful.
+ */
+#if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \
+ && !defined(XXH_INLINE_ALL_31684351384)
+ /* this section should be traversed only once */
+# define XXH_INLINE_ALL_31684351384
+ /* give access to the advanced API, required to compile implementations */
+# undef XXH_STATIC_LINKING_ONLY /* avoid macro redef */
+# define XXH_STATIC_LINKING_ONLY
+ /* make all functions private */
+# undef XXH_PUBLIC_API
# if defined(__GNUC__)
# define XXH_PUBLIC_API static __inline __attribute__((unused))
# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
@@ -82,45 +104,205 @@ typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
# elif defined(_MSC_VER)
# define XXH_PUBLIC_API static __inline
# else
-# define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */
+ /* note: this version may generate warnings for unused static functions */
+# define XXH_PUBLIC_API static
# endif
-#else
-# define XXH_PUBLIC_API /* do nothing */
-#endif /* XXH_PRIVATE_API */
-/*!XXH_NAMESPACE, aka Namespace Emulation :
+ /*
+ * This part deals with the special case where a unit wants to inline xxHash,
+ * but "xxhash.h" has previously been included without XXH_INLINE_ALL,
+ * such as part of some previously included *.h header file.
+ * Without further action, the new include would just be ignored,
+ * and functions would effectively _not_ be inlined (silent failure).
+ * The following macros solve this situation by prefixing all inlined names,
+ * avoiding naming collision with previous inclusions.
+ */
+ /* Before that, we unconditionally #undef all symbols,
+ * in case they were already defined with XXH_NAMESPACE.
+ * They will then be redefined for XXH_INLINE_ALL
+ */
+# undef XXH_versionNumber
+ /* XXH32 */
+# undef XXH32
+# undef XXH32_createState
+# undef XXH32_freeState
+# undef XXH32_reset
+# undef XXH32_update
+# undef XXH32_digest
+# undef XXH32_copyState
+# undef XXH32_canonicalFromHash
+# undef XXH32_hashFromCanonical
+ /* XXH64 */
+# undef XXH64
+# undef XXH64_createState
+# undef XXH64_freeState
+# undef XXH64_reset
+# undef XXH64_update
+# undef XXH64_digest
+# undef XXH64_copyState
+# undef XXH64_canonicalFromHash
+# undef XXH64_hashFromCanonical
+ /* XXH3_64bits */
+# undef XXH3_64bits
+# undef XXH3_64bits_withSecret
+# undef XXH3_64bits_withSeed
+# undef XXH3_64bits_withSecretandSeed
+# undef XXH3_createState
+# undef XXH3_freeState
+# undef XXH3_copyState
+# undef XXH3_64bits_reset
+# undef XXH3_64bits_reset_withSeed
+# undef XXH3_64bits_reset_withSecret
+# undef XXH3_64bits_update
+# undef XXH3_64bits_digest
+# undef XXH3_generateSecret
+ /* XXH3_128bits */
+# undef XXH128
+# undef XXH3_128bits
+# undef XXH3_128bits_withSeed
+# undef XXH3_128bits_withSecret
+# undef XXH3_128bits_reset
+# undef XXH3_128bits_reset_withSeed
+# undef XXH3_128bits_reset_withSecret
+# undef XXH3_128bits_reset_withSecretandSeed
+# undef XXH3_128bits_update
+# undef XXH3_128bits_digest
+# undef XXH128_isEqual
+# undef XXH128_cmp
+# undef XXH128_canonicalFromHash
+# undef XXH128_hashFromCanonical
+ /* Finally, free the namespace itself */
+# undef XXH_NAMESPACE
-If you want to include _and expose_ xxHash functions from within your own library,
-but also want to avoid symbol collisions with another library which also includes xxHash,
+ /* employ the namespace for XXH_INLINE_ALL */
+# define XXH_NAMESPACE XXH_INLINE_
+ /*
+ * Some identifiers (enums, type names) are not symbols,
+ * but they must nonetheless be renamed to avoid redeclaration.
+ * Alternative solution: do not redeclare them.
+ * However, this requires some #ifdefs, and has a more dispersed impact.
+ * Meanwhile, renaming can be achieved in a single place.
+ */
+# define XXH_IPREF(Id) XXH_NAMESPACE ## Id
+# define XXH_OK XXH_IPREF(XXH_OK)
+# define XXH_ERROR XXH_IPREF(XXH_ERROR)
+# define XXH_errorcode XXH_IPREF(XXH_errorcode)
+# define XXH32_canonical_t XXH_IPREF(XXH32_canonical_t)
+# define XXH64_canonical_t XXH_IPREF(XXH64_canonical_t)
+# define XXH128_canonical_t XXH_IPREF(XXH128_canonical_t)
+# define XXH32_state_s XXH_IPREF(XXH32_state_s)
+# define XXH32_state_t XXH_IPREF(XXH32_state_t)
+# define XXH64_state_s XXH_IPREF(XXH64_state_s)
+# define XXH64_state_t XXH_IPREF(XXH64_state_t)
+# define XXH3_state_s XXH_IPREF(XXH3_state_s)
+# define XXH3_state_t XXH_IPREF(XXH3_state_t)
+# define XXH128_hash_t XXH_IPREF(XXH128_hash_t)
+ /* Ensure the header is parsed again, even if it was previously included */
+# undef XXHASH_H_5627135585666179
+# undef XXHASH_H_STATIC_13879238742
+#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */
-you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library
-with the value of XXH_NAMESPACE (so avoid to keep it NULL and avoid numeric values).
-Note that no change is required within the calling program as long as it includes `xxhash.h` :
-regular symbol name will be automatically translated by this header.
-*/
+
+/* ****************************************************************
+ * Stable API
+ *****************************************************************/
+#ifndef XXHASH_H_5627135585666179
+#define XXHASH_H_5627135585666179 1
+
+
+/*!
+ * @defgroup public Public API
+ * Contains details on the public xxHash functions.
+ * @{
+ */
+/* specific declaration modes for Windows */
+#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
+# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
+# ifdef XXH_EXPORT
+# define XXH_PUBLIC_API __declspec(dllexport)
+# elif XXH_IMPORT
+# define XXH_PUBLIC_API __declspec(dllimport)
+# endif
+# else
+# define XXH_PUBLIC_API /* do nothing */
+# endif
+#endif
+
+#ifdef XXH_DOXYGEN
+/*!
+ * @brief Emulate a namespace by transparently prefixing all symbols.
+ *
+ * If you want to include _and expose_ xxHash functions from within your own
+ * library, but also want to avoid symbol collisions with other libraries which
+ * may also include xxHash, you can use XXH_NAMESPACE to automatically prefix
+ * any public symbol from xxhash library with the value of XXH_NAMESPACE
+ * (therefore, avoid empty or numeric values).
+ *
+ * Note that no change is required within the calling program as long as it
+ * includes `xxhash.h`: Regular symbol names will be automatically translated
+ * by this header.
+ */
+# define XXH_NAMESPACE /* YOUR NAME HERE */
+# undef XXH_NAMESPACE
+#endif
+
#ifdef XXH_NAMESPACE
# define XXH_CAT(A,B) A##B
# define XXH_NAME2(A,B) XXH_CAT(A,B)
-# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
-# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
+/* XXH32 */
+# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
-# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
-# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
-# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
-# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
-# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
-# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
-# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
+/* XXH64 */
+# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
+# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
+# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
+# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
+# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
+# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
+# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
+# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
+/* XXH3_64bits */
+# define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits)
+# define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret)
+# define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed)
+# define XXH3_64bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecretandSeed)
+# define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState)
+# define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState)
+# define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState)
+# define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset)
+# define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed)
+# define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret)
+# define XXH3_64bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecretandSeed)
+# define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update)
+# define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest)
+# define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret)
+# define XXH3_generateSecret_fromSeed XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret_fromSeed)
+/* XXH3_128bits */
+# define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128)
+# define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits)
+# define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed)
+# define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret)
+# define XXH3_128bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecretandSeed)
+# define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset)
+# define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed)
+# define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret)
+# define XXH3_128bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecretandSeed)
+# define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update)
+# define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest)
+# define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual)
+# define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp)
+# define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash)
+# define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical)
#endif
@@ -128,156 +310,5375 @@ regular symbol name will be automatically translated by this header.
* Version
***************************************/
#define XXH_VERSION_MAJOR 0
-#define XXH_VERSION_MINOR 6
-#define XXH_VERSION_RELEASE 2
+#define XXH_VERSION_MINOR 8
+#define XXH_VERSION_RELEASE 1
#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
+
+/*!
+ * @brief Obtains the xxHash version.
+ *
+ * This is mostly useful when xxHash is compiled as a shared library,
+ * since the returned value comes from the library, as opposed to header file.
+ *
+ * @return `XXH_VERSION_NUMBER` of the invoked library.
+ */
XXH_PUBLIC_API unsigned XXH_versionNumber (void);
/* ****************************
-* Simple Hash Functions
+* Common basic types
******************************/
-typedef unsigned int XXH32_hash_t;
-typedef unsigned long long XXH64_hash_t;
-
-XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);
-XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);
-
-/*!
-XXH32() :
- Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
- The memory between input & input+length must be valid (allocated and read-accessible).
- "seed" can be used to alter the result predictably.
- Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
-XXH64() :
- Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
- "seed" can be used to alter the result predictably.
- This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark).
-*/
+#include <stddef.h> /* size_t */
+typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
-/* ****************************
-* Streaming Hash Functions
-******************************/
-typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */
-typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
+/*-**********************************************************************
+* 32-bit hash
+************************************************************************/
+#if defined(XXH_DOXYGEN) /* Don't show <stdint.h> include */
+/*!
+ * @brief An unsigned 32-bit integer.
+ *
+ * Not necessarily defined to `uint32_t` but functionally equivalent.
+ */
+typedef uint32_t XXH32_hash_t;
-/*! State allocation, compatible with dynamic libraries */
+#elif !defined (__VMS) \
+ && (defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+ typedef uint32_t XXH32_hash_t;
-XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
-XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
+#else
+# include <limits.h>
+# if UINT_MAX == 0xFFFFFFFFUL
+ typedef unsigned int XXH32_hash_t;
+# else
+# if ULONG_MAX == 0xFFFFFFFFUL
+ typedef unsigned long XXH32_hash_t;
+# else
+# error "unsupported platform: need a 32-bit type"
+# endif
+# endif
+#endif
-XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
-XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
+/*!
+ * @}
+ *
+ * @defgroup xxh32_family XXH32 family
+ * @ingroup public
+ * Contains functions used in the classic 32-bit xxHash algorithm.
+ *
+ * @note
+ * XXH32 is useful for older platforms, with no or poor 64-bit performance.
+ * Note that @ref xxh3_family provides competitive speed
+ * for both 32-bit and 64-bit systems, and offers true 64/128 bit hash results.
+ *
+ * @see @ref xxh64_family, @ref xxh3_family : Other xxHash families
+ * @see @ref xxh32_impl for implementation details
+ * @{
+ */
+
+/*!
+ * @brief Calculates the 32-bit hash of @p input using xxHash32.
+ *
+ * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s
+ *
+ * @param input The block of data to be hashed, at least @p length bytes in size.
+ * @param length The length of @p input, in bytes.
+ * @param seed The 32-bit seed to alter the hash's output predictably.
+ *
+ * @pre
+ * The memory between @p input and @p input + @p length must be valid,
+ * readable, contiguous memory. However, if @p length is `0`, @p input may be
+ * `NULL`. In C++, this also must be *TriviallyCopyable*.
+ *
+ * @return The calculated 32-bit hash value.
+ *
+ * @see
+ * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():
+ * Direct equivalents for the other variants of xxHash.
+ * @see
+ * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version.
+ */
+XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed);
+
+/*!
+ * Streaming functions generate the xxHash value from an incremental input.
+ * This method is slower than single-call functions, due to state management.
+ * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized.
+ *
+ * An XXH state must first be allocated using `XXH*_createState()`.
+ *
+ * Start a new hash by initializing the state with a seed using `XXH*_reset()`.
+ *
+ * Then, feed the hash state by calling `XXH*_update()` as many times as necessary.
+ *
+ * The function returns an error code, with 0 meaning OK, and any other value
+ * meaning there is an error.
+ *
+ * Finally, a hash value can be produced anytime, by using `XXH*_digest()`.
+ * This function returns the nn-bits hash as an int or long long.
+ *
+ * It's still possible to continue inserting input into the hash state after a
+ * digest, and generate new hash values later on by invoking `XXH*_digest()`.
+ *
+ * When done, release the state using `XXH*_freeState()`.
+ *
+ * Example code for incrementally hashing a file:
+ * @code{.c}
+ * #include <stdio.h>
+ * #include <xxhash.h>
+ * #define BUFFER_SIZE 256
+ *
+ * // Note: XXH64 and XXH3 use the same interface.
+ * XXH32_hash_t
+ * hashFile(FILE* stream)
+ * {
+ * XXH32_state_t* state;
+ * unsigned char buf[BUFFER_SIZE];
+ * size_t amt;
+ * XXH32_hash_t hash;
+ *
+ * state = XXH32_createState(); // Create a state
+ * assert(state != NULL); // Error check here
+ * XXH32_reset(state, 0xbaad5eed); // Reset state with our seed
+ * while ((amt = fread(buf, 1, sizeof(buf), stream)) != 0) {
+ * XXH32_update(state, buf, amt); // Hash the file in chunks
+ * }
+ * hash = XXH32_digest(state); // Finalize the hash
+ * XXH32_freeState(state); // Clean up
+ * return hash;
+ * }
+ * @endcode
+ */
+/*!
+ * @typedef struct XXH32_state_s XXH32_state_t
+ * @brief The opaque state struct for the XXH32 streaming API.
+ *
+ * @see XXH32_state_s for details.
+ */
+typedef struct XXH32_state_s XXH32_state_t;
+
+/*!
+ * @brief Allocates an @ref XXH32_state_t.
+ *
+ * Must be freed with XXH32_freeState().
+ * @return An allocated XXH32_state_t on success, `NULL` on failure.
+ */
+XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
+/*!
+ * @brief Frees an @ref XXH32_state_t.
+ *
+ * Must be allocated with XXH32_createState().
+ * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState().
+ * @return XXH_OK.
+ */
+XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
+/*!
+ * @brief Copies one @ref XXH32_state_t to another.
+ *
+ * @param dst_state The state to copy to.
+ * @param src_state The state to copy from.
+ * @pre
+ * @p dst_state and @p src_state must not be `NULL` and must not overlap.
+ */
+XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);
-/* hash streaming */
+/*!
+ * @brief Resets an @ref XXH32_state_t to begin a new hash.
+ *
+ * This function resets and seeds a state. Call it before @ref XXH32_update().
+ *
+ * @param statePtr The state struct to reset.
+ * @param seed The 32-bit seed to alter the hash result predictably.
+ *
+ * @pre
+ * @p statePtr must not be `NULL`.
+ *
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
+ */
+XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed);
-XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed);
+/*!
+ * @brief Consumes a block of @p input to an @ref XXH32_state_t.
+ *
+ * Call this to incrementally consume blocks of data.
+ *
+ * @param statePtr The state struct to update.
+ * @param input The block of data to be hashed, at least @p length bytes in size.
+ * @param length The length of @p input, in bytes.
+ *
+ * @pre
+ * @p statePtr must not be `NULL`.
+ * @pre
+ * The memory between @p input and @p input + @p length must be valid,
+ * readable, contiguous memory. However, if @p length is `0`, @p input may be
+ * `NULL`. In C++, this also must be *TriviallyCopyable*.
+ *
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
+ */
XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
+
+/*!
+ * @brief Returns the calculated hash value from an @ref XXH32_state_t.
+ *
+ * @note
+ * Calling XXH32_digest() will not affect @p statePtr, so you can update,
+ * digest, and update again.
+ *
+ * @param statePtr The state struct to calculate the hash from.
+ *
+ * @pre
+ * @p statePtr must not be `NULL`.
+ *
+ * @return The calculated xxHash32 value from that state.
+ */
XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
-XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
-XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
-XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
+/******* Canonical representation *******/
/*
-These functions generate the xxHash of an input provided in multiple segments.
-Note that, for small input, they are slower than single-call functions, due to state management.
-For small input, prefer `XXH32()` and `XXH64()` .
+ * The default return values from XXH functions are unsigned 32 and 64 bit
+ * integers.
+ * This the simplest and fastest format for further post-processing.
+ *
+ * However, this leaves open the question of what is the order on the byte level,
+ * since little and big endian conventions will store the same number differently.
+ *
+ * The canonical representation settles this issue by mandating big-endian
+ * convention, the same convention as human-readable numbers (large digits first).
+ *
+ * When writing hash values to storage, sending them over a network, or printing
+ * them, it's highly recommended to use the canonical representation to ensure
+ * portability across a wider range of systems, present and future.
+ *
+ * The following functions allow transformation of hash values to and from
+ * canonical format.
+ */
+
+/*!
+ * @brief Canonical (big endian) representation of @ref XXH32_hash_t.
+ */
+typedef struct {
+ unsigned char digest[4]; /*!< Hash bytes, big endian */
+} XXH32_canonical_t;
+
+/*!
+ * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t.
+ *
+ * @param dst The @ref XXH32_canonical_t pointer to be stored to.
+ * @param hash The @ref XXH32_hash_t to be converted.
+ *
+ * @pre
+ * @p dst must not be `NULL`.
+ */
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
-XXH state must first be allocated, using XXH*_createState() .
+/*!
+ * @brief Converts an @ref XXH32_canonical_t to a native @ref XXH32_hash_t.
+ *
+ * @param src The @ref XXH32_canonical_t to convert.
+ *
+ * @pre
+ * @p src must not be `NULL`.
+ *
+ * @return The converted hash.
+ */
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
-Start a new hash by initializing state with a seed, using XXH*_reset().
-Then, feed the hash state by calling XXH*_update() as many times as necessary.
-Obviously, input must be allocated and read accessible.
-The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
+#ifdef __has_attribute
+# define XXH_HAS_ATTRIBUTE(x) __has_attribute(x)
+#else
+# define XXH_HAS_ATTRIBUTE(x) 0
+#endif
-Finally, a hash value can be produced anytime, by using XXH*_digest().
-This function returns the nn-bits hash as an int or long long.
+/* C-language Attributes are added in C23. */
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
+# define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
+#else
+# define XXH_HAS_C_ATTRIBUTE(x) 0
+#endif
-It's still possible to continue inserting input into the hash state after a digest,
-and generate some new hashes later on, by calling again XXH*_digest().
+#if defined(__cplusplus) && defined(__has_cpp_attribute)
+# define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
+#else
+# define XXH_HAS_CPP_ATTRIBUTE(x) 0
+#endif
-When done, free XXH state space if it was allocated dynamically.
+/*
+Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute
+introduced in CPP17 and C23.
+CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough
+C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough
*/
+#if XXH_HAS_C_ATTRIBUTE(x)
+# define XXH_FALLTHROUGH [[fallthrough]]
+#elif XXH_HAS_CPP_ATTRIBUTE(x)
+# define XXH_FALLTHROUGH [[fallthrough]]
+#elif XXH_HAS_ATTRIBUTE(__fallthrough__)
+# define XXH_FALLTHROUGH __attribute__ ((fallthrough))
+#else
+# define XXH_FALLTHROUGH
+#endif
+/*!
+ * @}
+ * @ingroup public
+ * @{
+ */
-/* **************************
-* Utils
-****************************/
-#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* ! C99 */
-# define restrict /* disable restrict */
+#ifndef XXH_NO_LONG_LONG
+/*-**********************************************************************
+* 64-bit hash
+************************************************************************/
+#if defined(XXH_DOXYGEN) /* don't include <stdint.h> */
+/*!
+ * @brief An unsigned 64-bit integer.
+ *
+ * Not necessarily defined to `uint64_t` but functionally equivalent.
+ */
+typedef uint64_t XXH64_hash_t;
+#elif !defined (__VMS) \
+ && (defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+ typedef uint64_t XXH64_hash_t;
+#else
+# include <limits.h>
+# if defined(__LP64__) && ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL
+ /* LP64 ABI says uint64_t is unsigned long */
+ typedef unsigned long XXH64_hash_t;
+# else
+ /* the following type must have a width of 64-bit */
+ typedef unsigned long long XXH64_hash_t;
+# endif
#endif
-XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state);
-XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state);
+/*!
+ * @}
+ *
+ * @defgroup xxh64_family XXH64 family
+ * @ingroup public
+ * @{
+ * Contains functions used in the classic 64-bit xxHash algorithm.
+ *
+ * @note
+ * XXH3 provides competitive speed for both 32-bit and 64-bit systems,
+ * and offers true 64/128 bit hash results.
+ * It provides better speed for systems with vector processing capabilities.
+ */
-/* **************************
-* Canonical representation
-****************************/
-/* Default result type for XXH functions are primitive unsigned 32 and 64 bits.
-* The canonical representation uses human-readable write convention, aka big-endian (large digits first).
-* These functions allow transformation of hash result into and from its canonical format.
-* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
-*/
-typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
-typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
+/*!
+ * @brief Calculates the 64-bit hash of @p input using xxHash64.
+ *
+ * This function usually runs faster on 64-bit systems, but slower on 32-bit
+ * systems (see benchmark).
+ *
+ * @param input The block of data to be hashed, at least @p length bytes in size.
+ * @param length The length of @p input, in bytes.
+ * @param seed The 64-bit seed to alter the hash's output predictably.
+ *
+ * @pre
+ * The memory between @p input and @p input + @p length must be valid,
+ * readable, contiguous memory. However, if @p length is `0`, @p input may be
+ * `NULL`. In C++, this also must be *TriviallyCopyable*.
+ *
+ * @return The calculated 64-bit hash.
+ *
+ * @see
+ * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():
+ * Direct equivalents for the other variants of xxHash.
+ * @see
+ * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version.
+ */
+XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed);
-XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
-XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
+/******* Streaming *******/
+/*!
+ * @brief The opaque state struct for the XXH64 streaming API.
+ *
+ * @see XXH64_state_s for details.
+ */
+typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
+XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
+XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
+XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
-XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
+XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed);
+XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
+XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
+
+/******* Canonical representation *******/
+typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t;
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
+#ifndef XXH_NO_XXH3
+/*!
+ * @}
+ * ************************************************************************
+ * @defgroup xxh3_family XXH3 family
+ * @ingroup public
+ * @{
+ *
+ * XXH3 is a more recent hash algorithm featuring:
+ * - Improved speed for both small and large inputs
+ * - True 64-bit and 128-bit outputs
+ * - SIMD acceleration
+ * - Improved 32-bit viability
+ *
+ * Speed analysis methodology is explained here:
+ *
+ * https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html
+ *
+ * Compared to XXH64, expect XXH3 to run approximately
+ * ~2x faster on large inputs and >3x faster on small ones,
+ * exact differences vary depending on platform.
+ *
+ * XXH3's speed benefits greatly from SIMD and 64-bit arithmetic,
+ * but does not require it.
+ * Any 32-bit and 64-bit targets that can run XXH32 smoothly
+ * can run XXH3 at competitive speeds, even without vector support.
+ * Further details are explained in the implementation.
+ *
+ * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8,
+ * ZVector and scalar targets. This can be controlled via the XXH_VECTOR macro.
+ *
+ * XXH3 implementation is portable:
+ * it has a generic C90 formulation that can be compiled on any platform,
+ * all implementations generage exactly the same hash value on all platforms.
+ * Starting from v0.8.0, it's also labelled "stable", meaning that
+ * any future version will also generate the same hash value.
+ *
+ * XXH3 offers 2 variants, _64bits and _128bits.
+ *
+ * When only 64 bits are needed, prefer invoking the _64bits variant, as it
+ * reduces the amount of mixing, resulting in faster speed on small inputs.
+ * It's also generally simpler to manipulate a scalar return type than a struct.
+ *
+ * The API supports one-shot hashing, streaming mode, and custom secrets.
+ */
+
+/*-**********************************************************************
+* XXH3 64-bit variant
+************************************************************************/
+
+/* XXH3_64bits():
+ * default 64-bit variant, using default secret and default seed of 0.
+ * It's the fastest variant. */
+XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len);
+
+/*
+ * XXH3_64bits_withSeed():
+ * This variant generates a custom secret on the fly
+ * based on default secret altered using the `seed` value.
+ * While this operation is decently fast, note that it's not completely free.
+ * Note: seed==0 produces the same results as XXH3_64bits().
+ */
+XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
+
+/*!
+ * The bare minimum size for a custom secret.
+ *
+ * @see
+ * XXH3_64bits_withSecret(), XXH3_64bits_reset_withSecret(),
+ * XXH3_128bits_withSecret(), XXH3_128bits_reset_withSecret().
+ */
+#define XXH3_SECRET_SIZE_MIN 136
+
+/*
+ * XXH3_64bits_withSecret():
+ * It's possible to provide any blob of bytes as a "secret" to generate the hash.
+ * This makes it more difficult for an external actor to prepare an intentional collision.
+ * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN).
+ * However, the quality of the secret impacts the dispersion of the hash algorithm.
+ * Therefore, the secret _must_ look like a bunch of random bytes.
+ * Avoid "trivial" or structured data such as repeated sequences or a text document.
+ * Whenever in doubt about the "randomness" of the blob of bytes,
+ * consider employing "XXH3_generateSecret()" instead (see below).
+ * It will generate a proper high entropy secret derived from the blob of bytes.
+ * Another advantage of using XXH3_generateSecret() is that
+ * it guarantees that all bits within the initial blob of bytes
+ * will impact every bit of the output.
+ * This is not necessarily the case when using the blob of bytes directly
+ * because, when hashing _small_ inputs, only a portion of the secret is employed.
+ */
+XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
+
+
+/******* Streaming *******/
+/*
+ * Streaming requires state maintenance.
+ * This operation costs memory and CPU.
+ * As a consequence, streaming is slower than one-shot hashing.
+ * For better performance, prefer one-shot functions whenever applicable.
+ */
+
+/*!
+ * @brief The state struct for the XXH3 streaming API.
+ *
+ * @see XXH3_state_s for details.
+ */
+typedef struct XXH3_state_s XXH3_state_t;
+XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void);
+XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr);
+XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state);
+
+/*
+ * XXH3_64bits_reset():
+ * Initialize with default parameters.
+ * digest will be equivalent to `XXH3_64bits()`.
+ */
+XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr);
+/*
+ * XXH3_64bits_reset_withSeed():
+ * Generate a custom secret from `seed`, and store it into `statePtr`.
+ * digest will be equivalent to `XXH3_64bits_withSeed()`.
+ */
+XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
+/*
+ * XXH3_64bits_reset_withSecret():
+ * `secret` is referenced, it _must outlive_ the hash streaming session.
+ * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`,
+ * and the quality of produced hash values depends on secret's entropy
+ * (secret's content should look like a bunch of random bytes).
+ * When in doubt about the randomness of a candidate `secret`,
+ * consider employing `XXH3_generateSecret()` instead (see below).
+ */
+XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
+
+XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
+XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr);
+
+/* note : canonical representation of XXH3 is the same as XXH64
+ * since they both produce XXH64_hash_t values */
+
+
+/*-**********************************************************************
+* XXH3 128-bit variant
+************************************************************************/
+
+/*!
+ * @brief The return value from 128-bit hashes.
+ *
+ * Stored in little endian order, although the fields themselves are in native
+ * endianness.
+ */
+typedef struct {
+ XXH64_hash_t low64; /*!< `value & 0xFFFFFFFFFFFFFFFF` */
+ XXH64_hash_t high64; /*!< `value >> 64` */
+} XXH128_hash_t;
+
+XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len);
+XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
+XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
+
+/******* Streaming *******/
+/*
+ * Streaming requires state maintenance.
+ * This operation costs memory and CPU.
+ * As a consequence, streaming is slower than one-shot hashing.
+ * For better performance, prefer one-shot functions whenever applicable.
+ *
+ * XXH3_128bits uses the same XXH3_state_t as XXH3_64bits().
+ * Use already declared XXH3_createState() and XXH3_freeState().
+ *
+ * All reset and streaming functions have same meaning as their 64-bit counterpart.
+ */
+
+XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr);
+XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
+XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
+
+XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
+XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);
+
+/* Following helper functions make it possible to compare XXH128_hast_t values.
+ * Since XXH128_hash_t is a structure, this capability is not offered by the language.
+ * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */
+
+/*!
+ * XXH128_isEqual():
+ * Return: 1 if `h1` and `h2` are equal, 0 if they are not.
+ */
+XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2);
+
+/*!
+ * XXH128_cmp():
+ *
+ * This comparator is compatible with stdlib's `qsort()`/`bsearch()`.
+ *
+ * return: >0 if *h128_1 > *h128_2
+ * =0 if *h128_1 == *h128_2
+ * <0 if *h128_1 < *h128_2
+ */
+XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2);
+
+
+/******* Canonical representation *******/
+typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t;
+XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash);
+XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src);
+
+
+#endif /* !XXH_NO_XXH3 */
+#endif /* XXH_NO_LONG_LONG */
+
+/*!
+ * @}
+ */
#endif /* XXHASH_H_5627135585666179 */
-/* ================================================================================================
- This section contains definitions which are not guaranteed to remain stable.
- They may change in future versions, becoming incompatible with a different version of the library.
- They shall only be used with static linking.
- Never use these definitions in association with dynamic linking !
-=================================================================================================== */
-#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXH_STATIC_H_3543687687345)
-#define XXH_STATIC_H_3543687687345
-
-/* These definitions are only meant to allow allocation of XXH state
- statically, on stack, or in a struct for example.
- Do not use members directly. */
-
- struct XXH32_state_s {
- unsigned total_len_32;
- unsigned large_len;
- unsigned v1;
- unsigned v2;
- unsigned v3;
- unsigned v4;
- unsigned mem32[4]; /* buffer defined as U32 for alignment */
- unsigned memsize;
- unsigned reserved; /* never read nor write, will be removed in a future version */
- }; /* typedef'd to XXH32_state_t */
-
- struct XXH64_state_s {
- unsigned long long total_len;
- unsigned long long v1;
- unsigned long long v2;
- unsigned long long v3;
- unsigned long long v4;
- unsigned long long mem64[4]; /* buffer defined as U64 for alignment */
- unsigned memsize;
- unsigned reserved[2]; /* never read nor write, will be removed in a future version */
- }; /* typedef'd to XXH64_state_t */
-
-
-# ifdef XXH_PRIVATE_API
-# include "xxhash.c" /* include xxhash functions as `static`, for inlining */
+#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742)
+#define XXHASH_H_STATIC_13879238742
+/* ****************************************************************************
+ * This section contains declarations which are not guaranteed to remain stable.
+ * They may change in future versions, becoming incompatible with a different
+ * version of the library.
+ * These declarations should only be used with static linking.
+ * Never use them in association with dynamic linking!
+ ***************************************************************************** */
+
+/*
+ * These definitions are only present to allow static allocation
+ * of XXH states, on stack or in a struct, for example.
+ * Never **ever** access their members directly.
+ */
+
+/*!
+ * @internal
+ * @brief Structure for XXH32 streaming API.
+ *
+ * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
+ * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is
+ * an opaque type. This allows fields to safely be changed.
+ *
+ * Typedef'd to @ref XXH32_state_t.
+ * Do not access the members of this struct directly.
+ * @see XXH64_state_s, XXH3_state_s
+ */
+struct XXH32_state_s {
+ XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */
+ XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */
+ XXH32_hash_t v[4]; /*!< Accumulator lanes */
+ XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */
+ XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */
+ XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */
+}; /* typedef'd to XXH32_state_t */
+
+
+#ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */
+
+/*!
+ * @internal
+ * @brief Structure for XXH64 streaming API.
+ *
+ * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
+ * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is
+ * an opaque type. This allows fields to safely be changed.
+ *
+ * Typedef'd to @ref XXH64_state_t.
+ * Do not access the members of this struct directly.
+ * @see XXH32_state_s, XXH3_state_s
+ */
+struct XXH64_state_s {
+ XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */
+ XXH64_hash_t v[4]; /*!< Accumulator lanes */
+ XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */
+ XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */
+ XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/
+ XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */
+}; /* typedef'd to XXH64_state_t */
+
+
+#ifndef XXH_NO_XXH3
+
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */
+# include <stdalign.h>
+# define XXH_ALIGN(n) alignas(n)
+#elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */
+/* In C++ alignas() is a keyword */
+# define XXH_ALIGN(n) alignas(n)
+#elif defined(__GNUC__)
+# define XXH_ALIGN(n) __attribute__ ((aligned(n)))
+#elif defined(_MSC_VER)
+# define XXH_ALIGN(n) __declspec(align(n))
+#else
+# define XXH_ALIGN(n) /* disabled */
+#endif
+
+/* Old GCC versions only accept the attribute after the type in structures. */
+#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \
+ && ! (defined(__cplusplus) && (__cplusplus >= 201103L)) /* >= C++11 */ \
+ && defined(__GNUC__)
+# define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align)
+#else
+# define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type
+#endif
+
+/*!
+ * @brief The size of the internal XXH3 buffer.
+ *
+ * This is the optimal update size for incremental hashing.
+ *
+ * @see XXH3_64b_update(), XXH3_128b_update().
+ */
+#define XXH3_INTERNALBUFFER_SIZE 256
+
+/*!
+ * @brief Default size of the secret buffer (and @ref XXH3_kSecret).
+ *
+ * This is the size used in @ref XXH3_kSecret and the seeded functions.
+ *
+ * Not to be confused with @ref XXH3_SECRET_SIZE_MIN.
+ */
+#define XXH3_SECRET_DEFAULT_SIZE 192
+
+/*!
+ * @internal
+ * @brief Structure for XXH3 streaming API.
+ *
+ * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
+ * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined.
+ * Otherwise it is an opaque type.
+ * Never use this definition in combination with dynamic library.
+ * This allows fields to safely be changed in the future.
+ *
+ * @note ** This structure has a strict alignment requirement of 64 bytes!! **
+ * Do not allocate this with `malloc()` or `new`,
+ * it will not be sufficiently aligned.
+ * Use @ref XXH3_createState() and @ref XXH3_freeState(), or stack allocation.
+ *
+ * Typedef'd to @ref XXH3_state_t.
+ * Do never access the members of this struct directly.
+ *
+ * @see XXH3_INITSTATE() for stack initialization.
+ * @see XXH3_createState(), XXH3_freeState().
+ * @see XXH32_state_s, XXH64_state_s
+ */
+struct XXH3_state_s {
+ XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]);
+ /*!< The 8 accumulators. Similar to `vN` in @ref XXH32_state_s::v1 and @ref XXH64_state_s */
+ XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]);
+ /*!< Used to store a custom secret generated from a seed. */
+ XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]);
+ /*!< The internal buffer. @see XXH32_state_s::mem32 */
+ XXH32_hash_t bufferedSize;
+ /*!< The amount of memory in @ref buffer, @see XXH32_state_s::memsize */
+ XXH32_hash_t useSeed;
+ /*!< Reserved field. Needed for padding on 64-bit. */
+ size_t nbStripesSoFar;
+ /*!< Number or stripes processed. */
+ XXH64_hash_t totalLen;
+ /*!< Total length hashed. 64-bit even on 32-bit targets. */
+ size_t nbStripesPerBlock;
+ /*!< Number of stripes per block. */
+ size_t secretLimit;
+ /*!< Size of @ref customSecret or @ref extSecret */
+ XXH64_hash_t seed;
+ /*!< Seed for _withSeed variants. Must be zero otherwise, @see XXH3_INITSTATE() */
+ XXH64_hash_t reserved64;
+ /*!< Reserved field. */
+ const unsigned char* extSecret;
+ /*!< Reference to an external secret for the _withSecret variants, NULL
+ * for other variants. */
+ /* note: there may be some padding at the end due to alignment on 64 bytes */
+}; /* typedef'd to XXH3_state_t */
+
+#undef XXH_ALIGN_MEMBER
+
+/*!
+ * @brief Initializes a stack-allocated `XXH3_state_s`.
+ *
+ * When the @ref XXH3_state_t structure is merely emplaced on stack,
+ * it should be initialized with XXH3_INITSTATE() or a memset()
+ * in case its first reset uses XXH3_NNbits_reset_withSeed().
+ * This init can be omitted if the first reset uses default or _withSecret mode.
+ * This operation isn't necessary when the state is created with XXH3_createState().
+ * Note that this doesn't prepare the state for a streaming operation,
+ * it's still necessary to use XXH3_NNbits_reset*() afterwards.
+ */
+#define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; }
+
+
+/* XXH128() :
+ * simple alias to pre-selected XXH3_128bits variant
+ */
+XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
+
+
+/* === Experimental API === */
+/* Symbols defined below must be considered tied to a specific library version. */
+
+/*
+ * XXH3_generateSecret():
+ *
+ * Derive a high-entropy secret from any user-defined content, named customSeed.
+ * The generated secret can be used in combination with `*_withSecret()` functions.
+ * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed,
+ * as it becomes much more difficult for an external actor to guess how to impact the calculation logic.
+ *
+ * The function accepts as input a custom seed of any length and any content,
+ * and derives from it a high-entropy secret of length @secretSize
+ * into an already allocated buffer @secretBuffer.
+ * @secretSize must be >= XXH3_SECRET_SIZE_MIN
+ *
+ * The generated secret can then be used with any `*_withSecret()` variant.
+ * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`,
+ * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()`
+ * are part of this list. They all accept a `secret` parameter
+ * which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN)
+ * _and_ feature very high entropy (consist of random-looking bytes).
+ * These conditions can be a high bar to meet, so
+ * XXH3_generateSecret() can be employed to ensure proper quality.
+ *
+ * customSeed can be anything. It can have any size, even small ones,
+ * and its content can be anything, even "poor entropy" sources such as a bunch of zeroes.
+ * The resulting `secret` will nonetheless provide all required qualities.
+ *
+ * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior.
+ */
+XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize);
+
+
+/*
+ * XXH3_generateSecret_fromSeed():
+ *
+ * Generate the same secret as the _withSeed() variants.
+ *
+ * The resulting secret has a length of XXH3_SECRET_DEFAULT_SIZE (necessarily).
+ * @secretBuffer must be already allocated, of size at least XXH3_SECRET_DEFAULT_SIZE bytes.
+ *
+ * The generated secret can be used in combination with
+ *`*_withSecret()` and `_withSecretandSeed()` variants.
+ * This generator is notably useful in combination with `_withSecretandSeed()`,
+ * as a way to emulate a faster `_withSeed()` variant.
+ */
+XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed);
+
+/*
+ * *_withSecretandSeed() :
+ * These variants generate hash values using either
+ * @seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes)
+ * or @secret for "large" keys (>= XXH3_MIDSIZE_MAX).
+ *
+ * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`.
+ * `_withSeed()` has to generate the secret on the fly for "large" keys.
+ * It's fast, but can be perceptible for "not so large" keys (< 1 KB).
+ * `_withSecret()` has to generate the masks on the fly for "small" keys,
+ * which requires more instructions than _withSeed() variants.
+ * Therefore, _withSecretandSeed variant combines the best of both worlds.
+ *
+ * When @secret has been generated by XXH3_generateSecret_fromSeed(),
+ * this variant produces *exactly* the same results as `_withSeed()` variant,
+ * hence offering only a pure speed benefit on "large" input,
+ * by skipping the need to regenerate the secret for every large input.
+ *
+ * Another usage scenario is to hash the secret to a 64-bit hash value,
+ * for example with XXH3_64bits(), which then becomes the seed,
+ * and then employ both the seed and the secret in _withSecretandSeed().
+ * On top of speed, an added benefit is that each bit in the secret
+ * has a 50% chance to swap each bit in the output,
+ * via its impact to the seed.
+ * This is not guaranteed when using the secret directly in "small data" scenarios,
+ * because only portions of the secret are employed for small data.
+ */
+XXH_PUBLIC_API XXH64_hash_t
+XXH3_64bits_withSecretandSeed(const void* data, size_t len,
+ const void* secret, size_t secretSize,
+ XXH64_hash_t seed);
+
+XXH_PUBLIC_API XXH128_hash_t
+XXH3_128bits_withSecretandSeed(const void* data, size_t len,
+ const void* secret, size_t secretSize,
+ XXH64_hash_t seed64);
+
+XXH_PUBLIC_API XXH_errorcode
+XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
+ const void* secret, size_t secretSize,
+ XXH64_hash_t seed64);
+
+XXH_PUBLIC_API XXH_errorcode
+XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
+ const void* secret, size_t secretSize,
+ XXH64_hash_t seed64);
+
+
+#endif /* XXH_NO_XXH3 */
+#endif /* XXH_NO_LONG_LONG */
+#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
+# define XXH_IMPLEMENTATION
+#endif
+
+#endif /* defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) */
+
+
+/* ======================================================================== */
+/* ======================================================================== */
+/* ======================================================================== */
+
+
+/*-**********************************************************************
+ * xxHash implementation
+ *-**********************************************************************
+ * xxHash's implementation used to be hosted inside xxhash.c.
+ *
+ * However, inlining requires implementation to be visible to the compiler,
+ * hence be included alongside the header.
+ * Previously, implementation was hosted inside xxhash.c,
+ * which was then #included when inlining was activated.
+ * This construction created issues with a few build and install systems,
+ * as it required xxhash.c to be stored in /include directory.
+ *
+ * xxHash implementation is now directly integrated within xxhash.h.
+ * As a consequence, xxhash.c is no longer needed in /include.
+ *
+ * xxhash.c is still available and is still useful.
+ * In a "normal" setup, when xxhash is not inlined,
+ * xxhash.h only exposes the prototypes and public symbols,
+ * while xxhash.c can be built into an object file xxhash.o
+ * which can then be linked into the final binary.
+ ************************************************************************/
+
+#if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \
+ || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387)
+# define XXH_IMPLEM_13a8737387
+
+/* *************************************
+* Tuning parameters
+***************************************/
+
+/*!
+ * @defgroup tuning Tuning parameters
+ * @{
+ *
+ * Various macros to control xxHash's behavior.
+ */
+#ifdef XXH_DOXYGEN
+/*!
+ * @brief Define this to disable 64-bit code.
+ *
+ * Useful if only using the @ref xxh32_family and you have a strict C90 compiler.
+ */
+# define XXH_NO_LONG_LONG
+# undef XXH_NO_LONG_LONG /* don't actually */
+/*!
+ * @brief Controls how unaligned memory is accessed.
+ *
+ * By default, access to unaligned memory is controlled by `memcpy()`, which is
+ * safe and portable.
+ *
+ * Unfortunately, on some target/compiler combinations, the generated assembly
+ * is sub-optimal.
+ *
+ * The below switch allow selection of a different access method
+ * in the search for improved performance.
+ *
+ * @par Possible options:
+ *
+ * - `XXH_FORCE_MEMORY_ACCESS=0` (default): `memcpy`
+ * @par
+ * Use `memcpy()`. Safe and portable. Note that most modern compilers will
+ * eliminate the function call and treat it as an unaligned access.
+ *
+ * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((packed))`
+ * @par
+ * Depends on compiler extensions and is therefore not portable.
+ * This method is safe _if_ your compiler supports it,
+ * and *generally* as fast or faster than `memcpy`.
+ *
+ * - `XXH_FORCE_MEMORY_ACCESS=2`: Direct cast
+ * @par
+ * Casts directly and dereferences. This method doesn't depend on the
+ * compiler, but it violates the C standard as it directly dereferences an
+ * unaligned pointer. It can generate buggy code on targets which do not
+ * support unaligned memory accesses, but in some circumstances, it's the
+ * only known way to get the most performance.
+ *
+ * - `XXH_FORCE_MEMORY_ACCESS=3`: Byteshift
+ * @par
+ * Also portable. This can generate the best code on old compilers which don't
+ * inline small `memcpy()` calls, and it might also be faster on big-endian
+ * systems which lack a native byteswap instruction. However, some compilers
+ * will emit literal byteshifts even if the target supports unaligned access.
+ * .
+ *
+ * @warning
+ * Methods 1 and 2 rely on implementation-defined behavior. Use these with
+ * care, as what works on one compiler/platform/optimization level may cause
+ * another to read garbage data or even crash.
+ *
+ * See http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html for details.
+ *
+ * Prefer these methods in priority order (0 > 3 > 1 > 2)
+ */
+# define XXH_FORCE_MEMORY_ACCESS 0
+
+/*!
+ * @def XXH_FORCE_ALIGN_CHECK
+ * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32()
+ * and XXH64() only).
+ *
+ * This is an important performance trick for architectures without decent
+ * unaligned memory access performance.
+ *
+ * It checks for input alignment, and when conditions are met, uses a "fast
+ * path" employing direct 32-bit/64-bit reads, resulting in _dramatically
+ * faster_ read speed.
+ *
+ * The check costs one initial branch per hash, which is generally negligible,
+ * but not zero.
+ *
+ * Moreover, it's not useful to generate an additional code path if memory
+ * access uses the same instruction for both aligned and unaligned
+ * addresses (e.g. x86 and aarch64).
+ *
+ * In these cases, the alignment check can be removed by setting this macro to 0.
+ * Then the code will always use unaligned memory access.
+ * Align check is automatically disabled on x86, x64 & arm64,
+ * which are platforms known to offer good unaligned memory accesses performance.
+ *
+ * This option does not affect XXH3 (only XXH32 and XXH64).
+ */
+# define XXH_FORCE_ALIGN_CHECK 0
+
+/*!
+ * @def XXH_NO_INLINE_HINTS
+ * @brief When non-zero, sets all functions to `static`.
+ *
+ * By default, xxHash tries to force the compiler to inline almost all internal
+ * functions.
+ *
+ * This can usually improve performance due to reduced jumping and improved
+ * constant folding, but significantly increases the size of the binary which
+ * might not be favorable.
+ *
+ * Additionally, sometimes the forced inlining can be detrimental to performance,
+ * depending on the architecture.
+ *
+ * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the
+ * compiler full control on whether to inline or not.
+ *
+ * When not optimizing (-O0), optimizing for size (-Os, -Oz), or using
+ * -fno-inline with GCC or Clang, this will automatically be defined.
+ */
+# define XXH_NO_INLINE_HINTS 0
+
+/*!
+ * @def XXH32_ENDJMP
+ * @brief Whether to use a jump for `XXH32_finalize`.
+ *
+ * For performance, `XXH32_finalize` uses multiple branches in the finalizer.
+ * This is generally preferable for performance,
+ * but depending on exact architecture, a jmp may be preferable.
+ *
+ * This setting is only possibly making a difference for very small inputs.
+ */
+# define XXH32_ENDJMP 0
+
+/*!
+ * @internal
+ * @brief Redefines old internal names.
+ *
+ * For compatibility with code that uses xxHash's internals before the names
+ * were changed to improve namespacing. There is no other reason to use this.
+ */
+# define XXH_OLD_NAMES
+# undef XXH_OLD_NAMES /* don't actually use, it is ugly. */
+#endif /* XXH_DOXYGEN */
+/*!
+ * @}
+ */
+
+#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
+ /* prefer __packed__ structures (method 1) for gcc on armv7+ and mips */
+# if !defined(__clang__) && \
+( \
+ (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \
+ ( \
+ defined(__GNUC__) && ( \
+ (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \
+ ( \
+ defined(__mips__) && \
+ (__mips <= 5 || __mips_isa_rev < 6) && \
+ (!defined(__mips16) || defined(__mips_mips16e2)) \
+ ) \
+ ) \
+ ) \
+)
+# define XXH_FORCE_MEMORY_ACCESS 1
+# endif
+#endif
+
+#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
+# if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \
+ || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */
+# define XXH_FORCE_ALIGN_CHECK 0
+# else
+# define XXH_FORCE_ALIGN_CHECK 1
+# endif
+#endif
+
+#ifndef XXH_NO_INLINE_HINTS
+# if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \
+ || defined(__NO_INLINE__) /* -O0, -fno-inline */
+# define XXH_NO_INLINE_HINTS 1
+# else
+# define XXH_NO_INLINE_HINTS 0
+# endif
+#endif
+
+#ifndef XXH32_ENDJMP
+/* generally preferable for performance */
+# define XXH32_ENDJMP 0
+#endif
+
+/*!
+ * @defgroup impl Implementation
+ * @{
+ */
+
+
+/* *************************************
+* Includes & Memory related functions
+***************************************/
+/* Modify the local functions below should you wish to use some other memory routines */
+/* for ZSTD_malloc(), ZSTD_free() */
+#define ZSTD_DEPS_NEED_MALLOC
+#include "zstd_deps.h" /* size_t, ZSTD_malloc, ZSTD_free, ZSTD_memcpy */
+static void* XXH_malloc(size_t s) { return ZSTD_malloc(s); }
+static void XXH_free (void* p) { ZSTD_free(p); }
+static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_memcpy(dest,src,size); }
+
+
+/* *************************************
+* Compiler Specific Options
+***************************************/
+#ifdef _MSC_VER /* Visual Studio warning fix */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+#endif
+
+#if XXH_NO_INLINE_HINTS /* disable inlining hints */
+# if defined(__GNUC__) || defined(__clang__)
+# define XXH_FORCE_INLINE static __attribute__((unused))
+# else
+# define XXH_FORCE_INLINE static
+# endif
+# define XXH_NO_INLINE static
+/* enable inlining hints */
+#elif defined(__GNUC__) || defined(__clang__)
+# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused))
+# define XXH_NO_INLINE static __attribute__((noinline))
+#elif defined(_MSC_VER) /* Visual Studio */
+# define XXH_FORCE_INLINE static __forceinline
+# define XXH_NO_INLINE static __declspec(noinline)
+#elif defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */
+# define XXH_FORCE_INLINE static inline
+# define XXH_NO_INLINE static
+#else
+# define XXH_FORCE_INLINE static
+# define XXH_NO_INLINE static
+#endif
+
+
+
+/* *************************************
+* Debug
+***************************************/
+/*!
+ * @ingroup tuning
+ * @def XXH_DEBUGLEVEL
+ * @brief Sets the debugging level.
+ *
+ * XXH_DEBUGLEVEL is expected to be defined externally, typically via the
+ * compiler's command line options. The value must be a number.
+ */
+#ifndef XXH_DEBUGLEVEL
+# ifdef DEBUGLEVEL /* backwards compat */
+# define XXH_DEBUGLEVEL DEBUGLEVEL
+# else
+# define XXH_DEBUGLEVEL 0
+# endif
+#endif
+
+#if (XXH_DEBUGLEVEL>=1)
+# include <assert.h> /* note: can still be disabled with NDEBUG */
+# define XXH_ASSERT(c) assert(c)
+#else
+# define XXH_ASSERT(c) ((void)0)
+#endif
+
+/* note: use after variable declarations */
+#ifndef XXH_STATIC_ASSERT
+# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */
+# include <assert.h>
+# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
+# elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */
+# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
+# else
+# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { struct xxh_sa { char x[(c) ? 1 : -1]; }; } while(0)
+# endif
+# define XXH_STATIC_ASSERT(c) XXH_STATIC_ASSERT_WITH_MESSAGE((c),#c)
+#endif
+
+/*!
+ * @internal
+ * @def XXH_COMPILER_GUARD(var)
+ * @brief Used to prevent unwanted optimizations for @p var.
+ *
+ * It uses an empty GCC inline assembly statement with a register constraint
+ * which forces @p var into a general purpose register (eg eax, ebx, ecx
+ * on x86) and marks it as modified.
+ *
+ * This is used in a few places to avoid unwanted autovectorization (e.g.
+ * XXH32_round()). All vectorization we want is explicit via intrinsics,
+ * and _usually_ isn't wanted elsewhere.
+ *
+ * We also use it to prevent unwanted constant folding for AArch64 in
+ * XXH3_initCustomSecret_scalar().
+ */
+#if defined(__GNUC__) || defined(__clang__)
+# define XXH_COMPILER_GUARD(var) __asm__ __volatile__("" : "+r" (var))
+#else
+# define XXH_COMPILER_GUARD(var) ((void)0)
+#endif
+
+/* *************************************
+* Basic Types
+***************************************/
+#if !defined (__VMS) \
+ && (defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+ typedef uint8_t xxh_u8;
+#else
+ typedef unsigned char xxh_u8;
+#endif
+typedef XXH32_hash_t xxh_u32;
+
+#ifdef XXH_OLD_NAMES
+# define BYTE xxh_u8
+# define U8 xxh_u8
+# define U32 xxh_u32
+#endif
+
+/* *** Memory access *** */
+
+/*!
+ * @internal
+ * @fn xxh_u32 XXH_read32(const void* ptr)
+ * @brief Reads an unaligned 32-bit integer from @p ptr in native endianness.
+ *
+ * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
+ *
+ * @param ptr The pointer to read from.
+ * @return The 32-bit native endian integer from the bytes at @p ptr.
+ */
+
+/*!
+ * @internal
+ * @fn xxh_u32 XXH_readLE32(const void* ptr)
+ * @brief Reads an unaligned 32-bit little endian integer from @p ptr.
+ *
+ * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
+ *
+ * @param ptr The pointer to read from.
+ * @return The 32-bit little endian integer from the bytes at @p ptr.
+ */
+
+/*!
+ * @internal
+ * @fn xxh_u32 XXH_readBE32(const void* ptr)
+ * @brief Reads an unaligned 32-bit big endian integer from @p ptr.
+ *
+ * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
+ *
+ * @param ptr The pointer to read from.
+ * @return The 32-bit big endian integer from the bytes at @p ptr.
+ */
+
+/*!
+ * @internal
+ * @fn xxh_u32 XXH_readLE32_align(const void* ptr, XXH_alignment align)
+ * @brief Like @ref XXH_readLE32(), but has an option for aligned reads.
+ *
+ * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
+ * Note that when @ref XXH_FORCE_ALIGN_CHECK == 0, the @p align parameter is
+ * always @ref XXH_alignment::XXH_unaligned.
+ *
+ * @param ptr The pointer to read from.
+ * @param align Whether @p ptr is aligned.
+ * @pre
+ * If @p align == @ref XXH_alignment::XXH_aligned, @p ptr must be 4 byte
+ * aligned.
+ * @return The 32-bit little endian integer from the bytes at @p ptr.
+ */
+
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
+/*
+ * Manual byteshift. Best for old compilers which don't inline memcpy.
+ * We actually directly use XXH_readLE32 and XXH_readBE32.
+ */
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
+
+/*
+ * Force direct memory access. Only works on CPU which support unaligned memory
+ * access in hardware.
+ */
+static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; }
+
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
+
+/*
+ * __pack instructions are safer but compiler specific, hence potentially
+ * problematic for some compilers.
+ *
+ * Currently only defined for GCC and ICC.
+ */
+#ifdef XXH_OLD_NAMES
+typedef union { xxh_u32 u32; } __attribute__((packed)) unalign;
+#endif
+static xxh_u32 XXH_read32(const void* ptr)
+{
+ typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign;
+ return ((const xxh_unalign*)ptr)->u32;
+}
+
+#else
+
+/*
+ * Portable and safe solution. Generally efficient.
+ * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
+ */
+static xxh_u32 XXH_read32(const void* memPtr)
+{
+ xxh_u32 val;
+ XXH_memcpy(&val, memPtr, sizeof(val));
+ return val;
+}
+
+#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
+
+
+/* *** Endianness *** */
+
+/*!
+ * @ingroup tuning
+ * @def XXH_CPU_LITTLE_ENDIAN
+ * @brief Whether the target is little endian.
+ *
+ * Defined to 1 if the target is little endian, or 0 if it is big endian.
+ * It can be defined externally, for example on the compiler command line.
+ *
+ * If it is not defined,
+ * a runtime check (which is usually constant folded) is used instead.
+ *
+ * @note
+ * This is not necessarily defined to an integer constant.
+ *
+ * @see XXH_isLittleEndian() for the runtime check.
+ */
+#ifndef XXH_CPU_LITTLE_ENDIAN
+/*
+ * Try to detect endianness automatically, to avoid the nonstandard behavior
+ * in `XXH_isLittleEndian()`
+ */
+# if defined(_WIN32) /* Windows is always little endian */ \
+ || defined(__LITTLE_ENDIAN__) \
+ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+# define XXH_CPU_LITTLE_ENDIAN 1
+# elif defined(__BIG_ENDIAN__) \
+ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+# define XXH_CPU_LITTLE_ENDIAN 0
+# else
+/*!
+ * @internal
+ * @brief Runtime check for @ref XXH_CPU_LITTLE_ENDIAN.
+ *
+ * Most compilers will constant fold this.
+ */
+static int XXH_isLittleEndian(void)
+{
+ /*
+ * Portable and well-defined behavior.
+ * Don't use static: it is detrimental to performance.
+ */
+ const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 };
+ return one.c[0];
+}
+# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian()
+# endif
+#endif
+
+
+
+
+/* ****************************************
+* Compiler-specific Functions and Macros
+******************************************/
+#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+#ifdef __has_builtin
+# define XXH_HAS_BUILTIN(x) __has_builtin(x)
+#else
+# define XXH_HAS_BUILTIN(x) 0
+#endif
+
+/*!
+ * @internal
+ * @def XXH_rotl32(x,r)
+ * @brief 32-bit rotate left.
+ *
+ * @param x The 32-bit integer to be rotated.
+ * @param r The number of bits to rotate.
+ * @pre
+ * @p r > 0 && @p r < 32
+ * @note
+ * @p x and @p r may be evaluated multiple times.
+ * @return The rotated result.
+ */
+#if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \
+ && XXH_HAS_BUILTIN(__builtin_rotateleft64)
+# define XXH_rotl32 __builtin_rotateleft32
+# define XXH_rotl64 __builtin_rotateleft64
+/* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */
+#elif defined(_MSC_VER)
+# define XXH_rotl32(x,r) _rotl(x,r)
+# define XXH_rotl64(x,r) _rotl64(x,r)
+#else
+# define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
+# define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r))))
+#endif
+
+/*!
+ * @internal
+ * @fn xxh_u32 XXH_swap32(xxh_u32 x)
+ * @brief A 32-bit byteswap.
+ *
+ * @param x The 32-bit integer to byteswap.
+ * @return @p x, byteswapped.
+ */
+#if defined(_MSC_VER) /* Visual Studio */
+# define XXH_swap32 _byteswap_ulong
+#elif XXH_GCC_VERSION >= 403
+# define XXH_swap32 __builtin_bswap32
+#else
+static xxh_u32 XXH_swap32 (xxh_u32 x)
+{
+ return ((x << 24) & 0xff000000 ) |
+ ((x << 8) & 0x00ff0000 ) |
+ ((x >> 8) & 0x0000ff00 ) |
+ ((x >> 24) & 0x000000ff );
+}
+#endif
+
+
+/* ***************************
+* Memory reads
+*****************************/
+
+/*!
+ * @internal
+ * @brief Enum to indicate whether a pointer is aligned.
+ */
+typedef enum {
+ XXH_aligned, /*!< Aligned */
+ XXH_unaligned /*!< Possibly unaligned */
+} XXH_alignment;
+
+/*
+ * XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load.
+ *
+ * This is ideal for older compilers which don't inline memcpy.
+ */
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
+
+XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* memPtr)
+{
+ const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
+ return bytePtr[0]
+ | ((xxh_u32)bytePtr[1] << 8)
+ | ((xxh_u32)bytePtr[2] << 16)
+ | ((xxh_u32)bytePtr[3] << 24);
+}
+
+XXH_FORCE_INLINE xxh_u32 XXH_readBE32(const void* memPtr)
+{
+ const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
+ return bytePtr[3]
+ | ((xxh_u32)bytePtr[2] << 8)
+ | ((xxh_u32)bytePtr[1] << 16)
+ | ((xxh_u32)bytePtr[0] << 24);
+}
+
+#else
+XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
+}
+
+static xxh_u32 XXH_readBE32(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
+}
+#endif
+
+XXH_FORCE_INLINE xxh_u32
+XXH_readLE32_align(const void* ptr, XXH_alignment align)
+{
+ if (align==XXH_unaligned) {
+ return XXH_readLE32(ptr);
+ } else {
+ return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr);
+ }
+}
+
+
+/* *************************************
+* Misc
+***************************************/
+/*! @ingroup public */
+XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
+
+
+/* *******************************************************************
+* 32-bit hash functions
+*********************************************************************/
+/*!
+ * @}
+ * @defgroup xxh32_impl XXH32 implementation
+ * @ingroup impl
+ * @{
+ */
+ /* #define instead of static const, to be used as initializers */
+#define XXH_PRIME32_1 0x9E3779B1U /*!< 0b10011110001101110111100110110001 */
+#define XXH_PRIME32_2 0x85EBCA77U /*!< 0b10000101111010111100101001110111 */
+#define XXH_PRIME32_3 0xC2B2AE3DU /*!< 0b11000010101100101010111000111101 */
+#define XXH_PRIME32_4 0x27D4EB2FU /*!< 0b00100111110101001110101100101111 */
+#define XXH_PRIME32_5 0x165667B1U /*!< 0b00010110010101100110011110110001 */
+
+#ifdef XXH_OLD_NAMES
+# define PRIME32_1 XXH_PRIME32_1
+# define PRIME32_2 XXH_PRIME32_2
+# define PRIME32_3 XXH_PRIME32_3
+# define PRIME32_4 XXH_PRIME32_4
+# define PRIME32_5 XXH_PRIME32_5
+#endif
+
+/*!
+ * @internal
+ * @brief Normal stripe processing routine.
+ *
+ * This shuffles the bits so that any bit from @p input impacts several bits in
+ * @p acc.
+ *
+ * @param acc The accumulator lane.
+ * @param input The stripe of input to mix.
+ * @return The mixed accumulator lane.
+ */
+static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
+{
+ acc += input * XXH_PRIME32_2;
+ acc = XXH_rotl32(acc, 13);
+ acc *= XXH_PRIME32_1;
+#if (defined(__SSE4_1__) || defined(__aarch64__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
+ /*
+ * UGLY HACK:
+ * A compiler fence is the only thing that prevents GCC and Clang from
+ * autovectorizing the XXH32 loop (pragmas and attributes don't work for some
+ * reason) without globally disabling SSE4.1.
+ *
+ * The reason we want to avoid vectorization is because despite working on
+ * 4 integers at a time, there are multiple factors slowing XXH32 down on
+ * SSE4:
+ * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on
+ * newer chips!) making it slightly slower to multiply four integers at
+ * once compared to four integers independently. Even when pmulld was
+ * fastest, Sandy/Ivy Bridge, it is still not worth it to go into SSE
+ * just to multiply unless doing a long operation.
+ *
+ * - Four instructions are required to rotate,
+ * movqda tmp, v // not required with VEX encoding
+ * pslld tmp, 13 // tmp <<= 13
+ * psrld v, 19 // x >>= 19
+ * por v, tmp // x |= tmp
+ * compared to one for scalar:
+ * roll v, 13 // reliably fast across the board
+ * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason
+ *
+ * - Instruction level parallelism is actually more beneficial here because
+ * the SIMD actually serializes this operation: While v1 is rotating, v2
+ * can load data, while v3 can multiply. SSE forces them to operate
+ * together.
+ *
+ * This is also enabled on AArch64, as Clang autovectorizes it incorrectly
+ * and it is pointless writing a NEON implementation that is basically the
+ * same speed as scalar for XXH32.
+ */
+ XXH_COMPILER_GUARD(acc);
+#endif
+ return acc;
+}
+
+/*!
+ * @internal
+ * @brief Mixes all bits to finalize the hash.
+ *
+ * The final mix ensures that all input bits have a chance to impact any bit in
+ * the output digest, resulting in an unbiased distribution.
+ *
+ * @param h32 The hash to avalanche.
+ * @return The avalanched hash.
+ */
+static xxh_u32 XXH32_avalanche(xxh_u32 h32)
+{
+ h32 ^= h32 >> 15;
+ h32 *= XXH_PRIME32_2;
+ h32 ^= h32 >> 13;
+ h32 *= XXH_PRIME32_3;
+ h32 ^= h32 >> 16;
+ return(h32);
+}
+
+#define XXH_get32bits(p) XXH_readLE32_align(p, align)
+
+/*!
+ * @internal
+ * @brief Processes the last 0-15 bytes of @p ptr.
+ *
+ * There may be up to 15 bytes remaining to consume from the input.
+ * This final stage will digest them to ensure that all input bytes are present
+ * in the final mix.
+ *
+ * @param h32 The hash to finalize.
+ * @param ptr The pointer to the remaining input.
+ * @param len The remaining length, modulo 16.
+ * @param align Whether @p ptr is aligned.
+ * @return The finalized hash.
+ */
+static xxh_u32
+XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
+{
+#define XXH_PROCESS1 do { \
+ h32 += (*ptr++) * XXH_PRIME32_5; \
+ h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \
+} while (0)
+
+#define XXH_PROCESS4 do { \
+ h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \
+ ptr += 4; \
+ h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \
+} while (0)
+
+ if (ptr==NULL) XXH_ASSERT(len == 0);
+
+ /* Compact rerolled version; generally faster */
+ if (!XXH32_ENDJMP) {
+ len &= 15;
+ while (len >= 4) {
+ XXH_PROCESS4;
+ len -= 4;
+ }
+ while (len > 0) {
+ XXH_PROCESS1;
+ --len;
+ }
+ return XXH32_avalanche(h32);
+ } else {
+ switch(len&15) /* or switch(bEnd - p) */ {
+ case 12: XXH_PROCESS4;
+ XXH_FALLTHROUGH;
+ case 8: XXH_PROCESS4;
+ XXH_FALLTHROUGH;
+ case 4: XXH_PROCESS4;
+ return XXH32_avalanche(h32);
+
+ case 13: XXH_PROCESS4;
+ XXH_FALLTHROUGH;
+ case 9: XXH_PROCESS4;
+ XXH_FALLTHROUGH;
+ case 5: XXH_PROCESS4;
+ XXH_PROCESS1;
+ return XXH32_avalanche(h32);
+
+ case 14: XXH_PROCESS4;
+ XXH_FALLTHROUGH;
+ case 10: XXH_PROCESS4;
+ XXH_FALLTHROUGH;
+ case 6: XXH_PROCESS4;
+ XXH_PROCESS1;
+ XXH_PROCESS1;
+ return XXH32_avalanche(h32);
+
+ case 15: XXH_PROCESS4;
+ XXH_FALLTHROUGH;
+ case 11: XXH_PROCESS4;
+ XXH_FALLTHROUGH;
+ case 7: XXH_PROCESS4;
+ XXH_FALLTHROUGH;
+ case 3: XXH_PROCESS1;
+ XXH_FALLTHROUGH;
+ case 2: XXH_PROCESS1;
+ XXH_FALLTHROUGH;
+ case 1: XXH_PROCESS1;
+ XXH_FALLTHROUGH;
+ case 0: return XXH32_avalanche(h32);
+ }
+ XXH_ASSERT(0);
+ return h32; /* reaching this point is deemed impossible */
+ }
+}
+
+#ifdef XXH_OLD_NAMES
+# define PROCESS1 XXH_PROCESS1
+# define PROCESS4 XXH_PROCESS4
+#else
+# undef XXH_PROCESS1
+# undef XXH_PROCESS4
+#endif
+
+/*!
+ * @internal
+ * @brief The implementation for @ref XXH32().
+ *
+ * @param input , len , seed Directly passed from @ref XXH32().
+ * @param align Whether @p input is aligned.
+ * @return The calculated hash.
+ */
+XXH_FORCE_INLINE xxh_u32
+XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align)
+{
+ xxh_u32 h32;
+
+ if (input==NULL) XXH_ASSERT(len == 0);
+
+ if (len>=16) {
+ const xxh_u8* const bEnd = input + len;
+ const xxh_u8* const limit = bEnd - 15;
+ xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
+ xxh_u32 v2 = seed + XXH_PRIME32_2;
+ xxh_u32 v3 = seed + 0;
+ xxh_u32 v4 = seed - XXH_PRIME32_1;
+
+ do {
+ v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4;
+ v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4;
+ v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4;
+ v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4;
+ } while (input < limit);
+
+ h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7)
+ + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
+ } else {
+ h32 = seed + XXH_PRIME32_5;
+ }
+
+ h32 += (xxh_u32)len;
+
+ return XXH32_finalize(h32, input, len&15, align);
+}
+
+/*! @ingroup xxh32_family */
+XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed)
+{
+#if 0
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+ XXH32_state_t state;
+ XXH32_reset(&state, seed);
+ XXH32_update(&state, (const xxh_u8*)input, len);
+ return XXH32_digest(&state);
+#else
+ if (XXH_FORCE_ALIGN_CHECK) {
+ if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
+ return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
+ } }
+
+ return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
+#endif
+}
+
+
+
+/******* Hash streaming *******/
+/*!
+ * @ingroup xxh32_family
+ */
+XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
+{
+ return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
+}
+/*! @ingroup xxh32_family */
+XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
+{
+ XXH_free(statePtr);
+ return XXH_OK;
+}
+
+/*! @ingroup xxh32_family */
+XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
+{
+ XXH_memcpy(dstState, srcState, sizeof(*dstState));
+}
+
+/*! @ingroup xxh32_family */
+XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed)
+{
+ XXH_ASSERT(statePtr != NULL);
+ memset(statePtr, 0, sizeof(*statePtr));
+ statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
+ statePtr->v[1] = seed + XXH_PRIME32_2;
+ statePtr->v[2] = seed + 0;
+ statePtr->v[3] = seed - XXH_PRIME32_1;
+ return XXH_OK;
+}
+
+
+/*! @ingroup xxh32_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH32_update(XXH32_state_t* state, const void* input, size_t len)
+{
+ if (input==NULL) {
+ XXH_ASSERT(len == 0);
+ return XXH_OK;
+ }
+
+ { const xxh_u8* p = (const xxh_u8*)input;
+ const xxh_u8* const bEnd = p + len;
+
+ state->total_len_32 += (XXH32_hash_t)len;
+ state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16));
+
+ if (state->memsize + len < 16) { /* fill in tmp buffer */
+ XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len);
+ state->memsize += (XXH32_hash_t)len;
+ return XXH_OK;
+ }
+
+ if (state->memsize) { /* some data left from previous update */
+ XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize);
+ { const xxh_u32* p32 = state->mem32;
+ state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++;
+ state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++;
+ state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++;
+ state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32));
+ }
+ p += 16-state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p <= bEnd-16) {
+ const xxh_u8* const limit = bEnd - 16;
+
+ do {
+ state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4;
+ state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4;
+ state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4;
+ state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4;
+ } while (p<=limit);
+
+ }
+
+ if (p < bEnd) {
+ XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
+ state->memsize = (unsigned)(bEnd-p);
+ }
+ }
+
+ return XXH_OK;
+}
+
+
+/*! @ingroup xxh32_family */
+XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
+{
+ xxh_u32 h32;
+
+ if (state->large_len) {
+ h32 = XXH_rotl32(state->v[0], 1)
+ + XXH_rotl32(state->v[1], 7)
+ + XXH_rotl32(state->v[2], 12)
+ + XXH_rotl32(state->v[3], 18);
+ } else {
+ h32 = state->v[2] /* == seed */ + XXH_PRIME32_5;
+ }
+
+ h32 += state->total_len_32;
+
+ return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned);
+}
+
+
+/******* Canonical representation *******/
+
+/*!
+ * @ingroup xxh32_family
+ * The default return values from XXH functions are unsigned 32 and 64 bit
+ * integers.
+ *
+ * The canonical representation uses big endian convention, the same convention
+ * as human-readable numbers (large digits first).
+ *
+ * This way, hash values can be written into a file or buffer, remaining
+ * comparable across different systems.
+ *
+ * The following functions allow transformation of hash values to and from their
+ * canonical format.
+ */
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
+{
+ /* XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); */
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
+ XXH_memcpy(dst, &hash, sizeof(*dst));
+}
+/*! @ingroup xxh32_family */
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
+{
+ return XXH_readBE32(src);
+}
+
+
+#ifndef XXH_NO_LONG_LONG
+
+/* *******************************************************************
+* 64-bit hash functions
+*********************************************************************/
+/*!
+ * @}
+ * @ingroup impl
+ * @{
+ */
+/******* Memory access *******/
+
+typedef XXH64_hash_t xxh_u64;
+
+#ifdef XXH_OLD_NAMES
+# define U64 xxh_u64
+#endif
+
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
+/*
+ * Manual byteshift. Best for old compilers which don't inline memcpy.
+ * We actually directly use XXH_readLE64 and XXH_readBE64.
+ */
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
+
+/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
+static xxh_u64 XXH_read64(const void* memPtr)
+{
+ return *(const xxh_u64*) memPtr;
+}
+
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
+
+/*
+ * __pack instructions are safer, but compiler specific, hence potentially
+ * problematic for some compilers.
+ *
+ * Currently only defined for GCC and ICC.
+ */
+#ifdef XXH_OLD_NAMES
+typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64;
+#endif
+static xxh_u64 XXH_read64(const void* ptr)
+{
+ typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) xxh_unalign64;
+ return ((const xxh_unalign64*)ptr)->u64;
+}
+
+#else
+
+/*
+ * Portable and safe solution. Generally efficient.
+ * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
+ */
+static xxh_u64 XXH_read64(const void* memPtr)
+{
+ xxh_u64 val;
+ XXH_memcpy(&val, memPtr, sizeof(val));
+ return val;
+}
+
+#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
+
+#if defined(_MSC_VER) /* Visual Studio */
+# define XXH_swap64 _byteswap_uint64
+#elif XXH_GCC_VERSION >= 403
+# define XXH_swap64 __builtin_bswap64
+#else
+static xxh_u64 XXH_swap64(xxh_u64 x)
+{
+ return ((x << 56) & 0xff00000000000000ULL) |
+ ((x << 40) & 0x00ff000000000000ULL) |
+ ((x << 24) & 0x0000ff0000000000ULL) |
+ ((x << 8) & 0x000000ff00000000ULL) |
+ ((x >> 8) & 0x00000000ff000000ULL) |
+ ((x >> 24) & 0x0000000000ff0000ULL) |
+ ((x >> 40) & 0x000000000000ff00ULL) |
+ ((x >> 56) & 0x00000000000000ffULL);
+}
+#endif
+
+
+/* XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. */
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
+
+XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* memPtr)
+{
+ const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
+ return bytePtr[0]
+ | ((xxh_u64)bytePtr[1] << 8)
+ | ((xxh_u64)bytePtr[2] << 16)
+ | ((xxh_u64)bytePtr[3] << 24)
+ | ((xxh_u64)bytePtr[4] << 32)
+ | ((xxh_u64)bytePtr[5] << 40)
+ | ((xxh_u64)bytePtr[6] << 48)
+ | ((xxh_u64)bytePtr[7] << 56);
+}
+
+XXH_FORCE_INLINE xxh_u64 XXH_readBE64(const void* memPtr)
+{
+ const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
+ return bytePtr[7]
+ | ((xxh_u64)bytePtr[6] << 8)
+ | ((xxh_u64)bytePtr[5] << 16)
+ | ((xxh_u64)bytePtr[4] << 24)
+ | ((xxh_u64)bytePtr[3] << 32)
+ | ((xxh_u64)bytePtr[2] << 40)
+ | ((xxh_u64)bytePtr[1] << 48)
+ | ((xxh_u64)bytePtr[0] << 56);
+}
+
+#else
+XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
+}
+
+static xxh_u64 XXH_readBE64(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
+}
+#endif
+
+XXH_FORCE_INLINE xxh_u64
+XXH_readLE64_align(const void* ptr, XXH_alignment align)
+{
+ if (align==XXH_unaligned)
+ return XXH_readLE64(ptr);
+ else
+ return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr);
+}
+
+
+/******* xxh64 *******/
+/*!
+ * @}
+ * @defgroup xxh64_impl XXH64 implementation
+ * @ingroup impl
+ * @{
+ */
+/* #define rather that static const, to be used as initializers */
+#define XXH_PRIME64_1 0x9E3779B185EBCA87ULL /*!< 0b1001111000110111011110011011000110000101111010111100101010000111 */
+#define XXH_PRIME64_2 0xC2B2AE3D27D4EB4FULL /*!< 0b1100001010110010101011100011110100100111110101001110101101001111 */
+#define XXH_PRIME64_3 0x165667B19E3779F9ULL /*!< 0b0001011001010110011001111011000110011110001101110111100111111001 */
+#define XXH_PRIME64_4 0x85EBCA77C2B2AE63ULL /*!< 0b1000010111101011110010100111011111000010101100101010111001100011 */
+#define XXH_PRIME64_5 0x27D4EB2F165667C5ULL /*!< 0b0010011111010100111010110010111100010110010101100110011111000101 */
+
+#ifdef XXH_OLD_NAMES
+# define PRIME64_1 XXH_PRIME64_1
+# define PRIME64_2 XXH_PRIME64_2
+# define PRIME64_3 XXH_PRIME64_3
+# define PRIME64_4 XXH_PRIME64_4
+# define PRIME64_5 XXH_PRIME64_5
+#endif
+
+static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input)
+{
+ acc += input * XXH_PRIME64_2;
+ acc = XXH_rotl64(acc, 31);
+ acc *= XXH_PRIME64_1;
+ return acc;
+}
+
+static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val)
+{
+ val = XXH64_round(0, val);
+ acc ^= val;
+ acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4;
+ return acc;
+}
+
+static xxh_u64 XXH64_avalanche(xxh_u64 h64)
+{
+ h64 ^= h64 >> 33;
+ h64 *= XXH_PRIME64_2;
+ h64 ^= h64 >> 29;
+ h64 *= XXH_PRIME64_3;
+ h64 ^= h64 >> 32;
+ return h64;
+}
+
+
+#define XXH_get64bits(p) XXH_readLE64_align(p, align)
+
+static xxh_u64
+XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align)
+{
+ if (ptr==NULL) XXH_ASSERT(len == 0);
+ len &= 31;
+ while (len >= 8) {
+ xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr));
+ ptr += 8;
+ h64 ^= k1;
+ h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4;
+ len -= 8;
+ }
+ if (len >= 4) {
+ h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1;
+ ptr += 4;
+ h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
+ len -= 4;
+ }
+ while (len > 0) {
+ h64 ^= (*ptr++) * XXH_PRIME64_5;
+ h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1;
+ --len;
+ }
+ return XXH64_avalanche(h64);
+}
+
+#ifdef XXH_OLD_NAMES
+# define PROCESS1_64 XXH_PROCESS1_64
+# define PROCESS4_64 XXH_PROCESS4_64
+# define PROCESS8_64 XXH_PROCESS8_64
+#else
+# undef XXH_PROCESS1_64
+# undef XXH_PROCESS4_64
+# undef XXH_PROCESS8_64
+#endif
+
+XXH_FORCE_INLINE xxh_u64
+XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align)
+{
+ xxh_u64 h64;
+ if (input==NULL) XXH_ASSERT(len == 0);
+
+ if (len>=32) {
+ const xxh_u8* const bEnd = input + len;
+ const xxh_u8* const limit = bEnd - 31;
+ xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
+ xxh_u64 v2 = seed + XXH_PRIME64_2;
+ xxh_u64 v3 = seed + 0;
+ xxh_u64 v4 = seed - XXH_PRIME64_1;
+
+ do {
+ v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8;
+ v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8;
+ v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8;
+ v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8;
+ } while (input<limit);
+
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+ h64 = XXH64_mergeRound(h64, v1);
+ h64 = XXH64_mergeRound(h64, v2);
+ h64 = XXH64_mergeRound(h64, v3);
+ h64 = XXH64_mergeRound(h64, v4);
+
+ } else {
+ h64 = seed + XXH_PRIME64_5;
+ }
+
+ h64 += (xxh_u64) len;
+
+ return XXH64_finalize(h64, input, len, align);
+}
+
+
+/*! @ingroup xxh64_family */
+XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed)
+{
+#if 0
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+ XXH64_state_t state;
+ XXH64_reset(&state, seed);
+ XXH64_update(&state, (const xxh_u8*)input, len);
+ return XXH64_digest(&state);
+#else
+ if (XXH_FORCE_ALIGN_CHECK) {
+ if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
+ return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
+ } }
+
+ return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
+
+#endif
+}
+
+/******* Hash Streaming *******/
+
+/*! @ingroup xxh64_family*/
+XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
+{
+ return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
+}
+/*! @ingroup xxh64_family */
+XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
+{
+ XXH_free(statePtr);
+ return XXH_OK;
+}
+
+/*! @ingroup xxh64_family */
+XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
+{
+ XXH_memcpy(dstState, srcState, sizeof(*dstState));
+}
+
+/*! @ingroup xxh64_family */
+XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed)
+{
+ XXH_ASSERT(statePtr != NULL);
+ memset(statePtr, 0, sizeof(*statePtr));
+ statePtr->v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
+ statePtr->v[1] = seed + XXH_PRIME64_2;
+ statePtr->v[2] = seed + 0;
+ statePtr->v[3] = seed - XXH_PRIME64_1;
+ return XXH_OK;
+}
+
+/*! @ingroup xxh64_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH64_update (XXH64_state_t* state, const void* input, size_t len)
+{
+ if (input==NULL) {
+ XXH_ASSERT(len == 0);
+ return XXH_OK;
+ }
+
+ { const xxh_u8* p = (const xxh_u8*)input;
+ const xxh_u8* const bEnd = p + len;
+
+ state->total_len += len;
+
+ if (state->memsize + len < 32) { /* fill in tmp buffer */
+ XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len);
+ state->memsize += (xxh_u32)len;
+ return XXH_OK;
+ }
+
+ if (state->memsize) { /* tmp buffer is full */
+ XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize);
+ state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0));
+ state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1));
+ state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2));
+ state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3));
+ p += 32 - state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p+32 <= bEnd) {
+ const xxh_u8* const limit = bEnd - 32;
+
+ do {
+ state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8;
+ state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8;
+ state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8;
+ state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8;
+ } while (p<=limit);
+
+ }
+
+ if (p < bEnd) {
+ XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
+ state->memsize = (unsigned)(bEnd-p);
+ }
+ }
+
+ return XXH_OK;
+}
+
+
+/*! @ingroup xxh64_family */
+XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state)
+{
+ xxh_u64 h64;
+
+ if (state->total_len >= 32) {
+ h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18);
+ h64 = XXH64_mergeRound(h64, state->v[0]);
+ h64 = XXH64_mergeRound(h64, state->v[1]);
+ h64 = XXH64_mergeRound(h64, state->v[2]);
+ h64 = XXH64_mergeRound(h64, state->v[3]);
+ } else {
+ h64 = state->v[2] /*seed*/ + XXH_PRIME64_5;
+ }
+
+ h64 += (xxh_u64) state->total_len;
+
+ return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned);
+}
+
+
+/******* Canonical representation *******/
+
+/*! @ingroup xxh64_family */
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
+{
+ /* XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); */
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
+ XXH_memcpy(dst, &hash, sizeof(*dst));
+}
+
+/*! @ingroup xxh64_family */
+XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
+{
+ return XXH_readBE64(src);
+}
+
+#ifndef XXH_NO_XXH3
+
+/* *********************************************************************
+* XXH3
+* New generation hash designed for speed on small keys and vectorization
+************************************************************************ */
+/*!
+ * @}
+ * @defgroup xxh3_impl XXH3 implementation
+ * @ingroup impl
+ * @{
+ */
+
+/* === Compiler specifics === */
+
+#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */
+# define XXH_RESTRICT /* disable */
+#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */
+# define XXH_RESTRICT restrict
+#else
+/* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */
+# define XXH_RESTRICT /* disable */
+#endif
+
+#if (defined(__GNUC__) && (__GNUC__ >= 3)) \
+ || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \
+ || defined(__clang__)
+# define XXH_likely(x) __builtin_expect(x, 1)
+# define XXH_unlikely(x) __builtin_expect(x, 0)
+#else
+# define XXH_likely(x) (x)
+# define XXH_unlikely(x) (x)
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+# if defined(__ARM_NEON__) || defined(__ARM_NEON) \
+ || defined(__aarch64__) || defined(_M_ARM) \
+ || defined(_M_ARM64) || defined(_M_ARM64EC)
+# define inline __inline__ /* circumvent a clang bug */
+# include <arm_neon.h>
+# undef inline
+# elif defined(__AVX2__)
+# include <immintrin.h>
+# elif defined(__SSE2__)
+# include <emmintrin.h>
# endif
+#endif
+
+#if defined(_MSC_VER)
+# include <intrin.h>
+#endif
+
+/*
+ * One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while
+ * remaining a true 64-bit/128-bit hash function.
+ *
+ * This is done by prioritizing a subset of 64-bit operations that can be
+ * emulated without too many steps on the average 32-bit machine.
+ *
+ * For example, these two lines seem similar, and run equally fast on 64-bit:
+ *
+ * xxh_u64 x;
+ * x ^= (x >> 47); // good
+ * x ^= (x >> 13); // bad
+ *
+ * However, to a 32-bit machine, there is a major difference.
+ *
+ * x ^= (x >> 47) looks like this:
+ *
+ * x.lo ^= (x.hi >> (47 - 32));
+ *
+ * while x ^= (x >> 13) looks like this:
+ *
+ * // note: funnel shifts are not usually cheap.
+ * x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13));
+ * x.hi ^= (x.hi >> 13);
+ *
+ * The first one is significantly faster than the second, simply because the
+ * shift is larger than 32. This means:
+ * - All the bits we need are in the upper 32 bits, so we can ignore the lower
+ * 32 bits in the shift.
+ * - The shift result will always fit in the lower 32 bits, and therefore,
+ * we can ignore the upper 32 bits in the xor.
+ *
+ * Thanks to this optimization, XXH3 only requires these features to be efficient:
+ *
+ * - Usable unaligned access
+ * - A 32-bit or 64-bit ALU
+ * - If 32-bit, a decent ADC instruction
+ * - A 32 or 64-bit multiply with a 64-bit result
+ * - For the 128-bit variant, a decent byteswap helps short inputs.
+ *
+ * The first two are already required by XXH32, and almost all 32-bit and 64-bit
+ * platforms which can run XXH32 can run XXH3 efficiently.
+ *
+ * Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one
+ * notable exception.
+ *
+ * First of all, Thumb-1 lacks support for the UMULL instruction which
+ * performs the important long multiply. This means numerous __aeabi_lmul
+ * calls.
+ *
+ * Second of all, the 8 functional registers are just not enough.
+ * Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need
+ * Lo registers, and this shuffling results in thousands more MOVs than A32.
+ *
+ * A32 and T32 don't have this limitation. They can access all 14 registers,
+ * do a 32->64 multiply with UMULL, and the flexible operand allowing free
+ * shifts is helpful, too.
+ *
+ * Therefore, we do a quick sanity check.
+ *
+ * If compiling Thumb-1 for a target which supports ARM instructions, we will
+ * emit a warning, as it is not a "sane" platform to compile for.
+ *
+ * Usually, if this happens, it is because of an accident and you probably need
+ * to specify -march, as you likely meant to compile for a newer architecture.
+ *
+ * Credit: large sections of the vectorial and asm source code paths
+ * have been contributed by @easyaspi314
+ */
+#if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM)
+# warning "XXH3 is highly inefficient without ARM or Thumb-2."
+#endif
+
+/* ==========================================
+ * Vectorization detection
+ * ========================================== */
+
+#ifdef XXH_DOXYGEN
+/*!
+ * @ingroup tuning
+ * @brief Overrides the vectorization implementation chosen for XXH3.
+ *
+ * Can be defined to 0 to disable SIMD or any of the values mentioned in
+ * @ref XXH_VECTOR_TYPE.
+ *
+ * If this is not defined, it uses predefined macros to determine the best
+ * implementation.
+ */
+# define XXH_VECTOR XXH_SCALAR
+/*!
+ * @ingroup tuning
+ * @brief Possible values for @ref XXH_VECTOR.
+ *
+ * Note that these are actually implemented as macros.
+ *
+ * If this is not defined, it is detected automatically.
+ * @ref XXH_X86DISPATCH overrides this.
+ */
+enum XXH_VECTOR_TYPE /* fake enum */ {
+ XXH_SCALAR = 0, /*!< Portable scalar version */
+ XXH_SSE2 = 1, /*!<
+ * SSE2 for Pentium 4, Opteron, all x86_64.
+ *
+ * @note SSE2 is also guaranteed on Windows 10, macOS, and
+ * Android x86.
+ */
+ XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */
+ XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */
+ XXH_NEON = 4, /*!< NEON for most ARMv7-A and all AArch64 */
+ XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */
+};
+/*!
+ * @ingroup tuning
+ * @brief Selects the minimum alignment for XXH3's accumulators.
+ *
+ * When using SIMD, this should match the alignment reqired for said vector
+ * type, so, for example, 32 for AVX2.
+ *
+ * Default: Auto detected.
+ */
+# define XXH_ACC_ALIGN 8
+#endif
+
+/* Actual definition */
+#ifndef XXH_DOXYGEN
+# define XXH_SCALAR 0
+# define XXH_SSE2 1
+# define XXH_AVX2 2
+# define XXH_AVX512 3
+# define XXH_NEON 4
+# define XXH_VSX 5
+#endif
+
+#ifndef XXH_VECTOR /* can be defined on command line */
+# if ( \
+ defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \
+ || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) /* msvc */ \
+ ) && ( \
+ defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \
+ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
+ )
+# define XXH_VECTOR XXH_NEON
+# elif defined(__AVX512F__)
+# define XXH_VECTOR XXH_AVX512
+# elif defined(__AVX2__)
+# define XXH_VECTOR XXH_AVX2
+# elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2))
+# define XXH_VECTOR XXH_SSE2
+# elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \
+ || (defined(__s390x__) && defined(__VEC__)) \
+ && defined(__GNUC__) /* TODO: IBM XL */
+# define XXH_VECTOR XXH_VSX
+# else
+# define XXH_VECTOR XXH_SCALAR
+# endif
+#endif
+
+/*
+ * Controls the alignment of the accumulator,
+ * for compatibility with aligned vector loads, which are usually faster.
+ */
+#ifndef XXH_ACC_ALIGN
+# if defined(XXH_X86DISPATCH)
+# define XXH_ACC_ALIGN 64 /* for compatibility with avx512 */
+# elif XXH_VECTOR == XXH_SCALAR /* scalar */
+# define XXH_ACC_ALIGN 8
+# elif XXH_VECTOR == XXH_SSE2 /* sse2 */
+# define XXH_ACC_ALIGN 16
+# elif XXH_VECTOR == XXH_AVX2 /* avx2 */
+# define XXH_ACC_ALIGN 32
+# elif XXH_VECTOR == XXH_NEON /* neon */
+# define XXH_ACC_ALIGN 16
+# elif XXH_VECTOR == XXH_VSX /* vsx */
+# define XXH_ACC_ALIGN 16
+# elif XXH_VECTOR == XXH_AVX512 /* avx512 */
+# define XXH_ACC_ALIGN 64
+# endif
+#endif
+
+#if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \
+ || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512
+# define XXH_SEC_ALIGN XXH_ACC_ALIGN
+#else
+# define XXH_SEC_ALIGN 8
+#endif
+
+/*
+ * UGLY HACK:
+ * GCC usually generates the best code with -O3 for xxHash.
+ *
+ * However, when targeting AVX2, it is overzealous in its unrolling resulting
+ * in code roughly 3/4 the speed of Clang.
+ *
+ * There are other issues, such as GCC splitting _mm256_loadu_si256 into
+ * _mm_loadu_si128 + _mm256_inserti128_si256. This is an optimization which
+ * only applies to Sandy and Ivy Bridge... which don't even support AVX2.
+ *
+ * That is why when compiling the AVX2 version, it is recommended to use either
+ * -O2 -mavx2 -march=haswell
+ * or
+ * -O2 -mavx2 -mno-avx256-split-unaligned-load
+ * for decent performance, or to use Clang instead.
+ *
+ * Fortunately, we can control the first one with a pragma that forces GCC into
+ * -O2, but the other one we can't control without "failed to inline always
+ * inline function due to target mismatch" warnings.
+ */
+#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
+ && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
+ && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
+# pragma GCC push_options
+# pragma GCC optimize("-O2")
+#endif
+
+
+#if XXH_VECTOR == XXH_NEON
+/*
+ * NEON's setup for vmlal_u32 is a little more complicated than it is on
+ * SSE2, AVX2, and VSX.
+ *
+ * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast.
+ *
+ * To do the same operation, the 128-bit 'Q' register needs to be split into
+ * two 64-bit 'D' registers, performing this operation::
+ *
+ * [ a | b ]
+ * | '---------. .--------' |
+ * | x |
+ * | .---------' '--------. |
+ * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ]
+ *
+ * Due to significant changes in aarch64, the fastest method for aarch64 is
+ * completely different than the fastest method for ARMv7-A.
+ *
+ * ARMv7-A treats D registers as unions overlaying Q registers, so modifying
+ * D11 will modify the high half of Q5. This is similar to how modifying AH
+ * will only affect bits 8-15 of AX on x86.
+ *
+ * VZIP takes two registers, and puts even lanes in one register and odd lanes
+ * in the other.
+ *
+ * On ARMv7-A, this strangely modifies both parameters in place instead of
+ * taking the usual 3-operand form.
+ *
+ * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the
+ * lower and upper halves of the Q register to end up with the high and low
+ * halves where we want - all in one instruction.
+ *
+ * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] }
+ *
+ * Unfortunately we need inline assembly for this: Instructions modifying two
+ * registers at once is not possible in GCC or Clang's IR, and they have to
+ * create a copy.
+ *
+ * aarch64 requires a different approach.
+ *
+ * In order to make it easier to write a decent compiler for aarch64, many
+ * quirks were removed, such as conditional execution.
+ *
+ * NEON was also affected by this.
+ *
+ * aarch64 cannot access the high bits of a Q-form register, and writes to a
+ * D-form register zero the high bits, similar to how writes to W-form scalar
+ * registers (or DWORD registers on x86_64) work.
+ *
+ * The formerly free vget_high intrinsics now require a vext (with a few
+ * exceptions)
+ *
+ * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent
+ * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one
+ * operand.
+ *
+ * The equivalent of the VZIP.32 on the lower and upper halves would be this
+ * mess:
+ *
+ * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] }
+ * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] }
+ * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] }
+ *
+ * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN):
+ *
+ * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32);
+ * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF);
+ *
+ * This is available on ARMv7-A, but is less efficient than a single VZIP.32.
+ */
+
+/*!
+ * Function-like macro:
+ * void XXH_SPLIT_IN_PLACE(uint64x2_t &in, uint32x2_t &outLo, uint32x2_t &outHi)
+ * {
+ * outLo = (uint32x2_t)(in & 0xFFFFFFFF);
+ * outHi = (uint32x2_t)(in >> 32);
+ * in = UNDEFINED;
+ * }
+ */
+# if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \
+ && (defined(__GNUC__) || defined(__clang__)) \
+ && (defined(__arm__) || defined(__thumb__) || defined(_M_ARM))
+# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
+ do { \
+ /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \
+ /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \
+ /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \
+ __asm__("vzip.32 %e0, %f0" : "+w" (in)); \
+ (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \
+ (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \
+ } while (0)
+# else
+# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
+ do { \
+ (outLo) = vmovn_u64 (in); \
+ (outHi) = vshrn_n_u64 ((in), 32); \
+ } while (0)
+# endif
+
+/*!
+ * @ingroup tuning
+ * @brief Controls the NEON to scalar ratio for XXH3
+ *
+ * On AArch64 when not optimizing for size, XXH3 will run 6 lanes using NEON and
+ * 2 lanes on scalar by default.
+ *
+ * This can be set to 2, 4, 6, or 8. ARMv7 will default to all 8 NEON lanes, as the
+ * emulated 64-bit arithmetic is too slow.
+ *
+ * Modern ARM CPUs are _very_ sensitive to how their pipelines are used.
+ *
+ * For example, the Cortex-A73 can dispatch 3 micro-ops per cycle, but it can't
+ * have more than 2 NEON (F0/F1) micro-ops. If you are only using NEON instructions,
+ * you are only using 2/3 of the CPU bandwidth.
+ *
+ * This is even more noticable on the more advanced cores like the A76 which
+ * can dispatch 8 micro-ops per cycle, but still only 2 NEON micro-ops at once.
+ *
+ * Therefore, @ref XXH3_NEON_LANES lanes will be processed using NEON, and the
+ * remaining lanes will use scalar instructions. This improves the bandwidth
+ * and also gives the integer pipelines something to do besides twiddling loop
+ * counters and pointers.
+ *
+ * This change benefits CPUs with large micro-op buffers without negatively affecting
+ * other CPUs:
+ *
+ * | Chipset | Dispatch type | NEON only | 6:2 hybrid | Diff. |
+ * |:----------------------|:--------------------|----------:|-----------:|------:|
+ * | Snapdragon 730 (A76) | 2 NEON/8 micro-ops | 8.8 GB/s | 10.1 GB/s | ~16% |
+ * | Snapdragon 835 (A73) | 2 NEON/3 micro-ops | 5.1 GB/s | 5.3 GB/s | ~5% |
+ * | Marvell PXA1928 (A53) | In-order dual-issue | 1.9 GB/s | 1.9 GB/s | 0% |
+ *
+ * It also seems to fix some bad codegen on GCC, making it almost as fast as clang.
+ *
+ * @see XXH3_accumulate_512_neon()
+ */
+# ifndef XXH3_NEON_LANES
+# if (defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) \
+ && !defined(__OPTIMIZE_SIZE__)
+# define XXH3_NEON_LANES 6
+# else
+# define XXH3_NEON_LANES XXH_ACC_NB
+# endif
+# endif
+#endif /* XXH_VECTOR == XXH_NEON */
+
+/*
+ * VSX and Z Vector helpers.
+ *
+ * This is very messy, and any pull requests to clean this up are welcome.
+ *
+ * There are a lot of problems with supporting VSX and s390x, due to
+ * inconsistent intrinsics, spotty coverage, and multiple endiannesses.
+ */
+#if XXH_VECTOR == XXH_VSX
+# if defined(__s390x__)
+# include <s390intrin.h>
+# else
+/* gcc's altivec.h can have the unwanted consequence to unconditionally
+ * #define bool, vector, and pixel keywords,
+ * with bad consequences for programs already using these keywords for other purposes.
+ * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined.
+ * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler,
+ * but it seems that, in some cases, it isn't.
+ * Force the build macro to be defined, so that keywords are not altered.
+ */
+# if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__)
+# define __APPLE_ALTIVEC__
+# endif
+# include <altivec.h>
+# endif
+
+typedef __vector unsigned long long xxh_u64x2;
+typedef __vector unsigned char xxh_u8x16;
+typedef __vector unsigned xxh_u32x4;
+
+# ifndef XXH_VSX_BE
+# if defined(__BIG_ENDIAN__) \
+ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+# define XXH_VSX_BE 1
+# elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__
+# warning "-maltivec=be is not recommended. Please use native endianness."
+# define XXH_VSX_BE 1
+# else
+# define XXH_VSX_BE 0
+# endif
+# endif /* !defined(XXH_VSX_BE) */
+
+# if XXH_VSX_BE
+# if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__))
+# define XXH_vec_revb vec_revb
+# else
+/*!
+ * A polyfill for POWER9's vec_revb().
+ */
+XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val)
+{
+ xxh_u8x16 const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+ 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 };
+ return vec_perm(val, val, vByteSwap);
+}
+# endif
+# endif /* XXH_VSX_BE */
+
+/*!
+ * Performs an unaligned vector load and byte swaps it on big endian.
+ */
+XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr)
+{
+ xxh_u64x2 ret;
+ XXH_memcpy(&ret, ptr, sizeof(xxh_u64x2));
+# if XXH_VSX_BE
+ ret = XXH_vec_revb(ret);
+# endif
+ return ret;
+}
+
+/*
+ * vec_mulo and vec_mule are very problematic intrinsics on PowerPC
+ *
+ * These intrinsics weren't added until GCC 8, despite existing for a while,
+ * and they are endian dependent. Also, their meaning swap depending on version.
+ * */
+# if defined(__s390x__)
+ /* s390x is always big endian, no issue on this platform */
+# define XXH_vec_mulo vec_mulo
+# define XXH_vec_mule vec_mule
+# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw)
+/* Clang has a better way to control this, we can just use the builtin which doesn't swap. */
+# define XXH_vec_mulo __builtin_altivec_vmulouw
+# define XXH_vec_mule __builtin_altivec_vmuleuw
+# else
+/* gcc needs inline assembly */
+/* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */
+XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b)
+{
+ xxh_u64x2 result;
+ __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b));
+ return result;
+}
+XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b)
+{
+ xxh_u64x2 result;
+ __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b));
+ return result;
+}
+# endif /* XXH_vec_mulo, XXH_vec_mule */
+#endif /* XXH_VECTOR == XXH_VSX */
+
+
+/* prefetch
+ * can be disabled, by declaring XXH_NO_PREFETCH build macro */
+#if defined(XXH_NO_PREFETCH)
+# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */
+#else
+# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */
+# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
+# define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
+# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
+# define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
+# else
+# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */
+# endif
+#endif /* XXH_NO_PREFETCH */
+
+
+/* ==========================================
+ * XXH3 default settings
+ * ========================================== */
+
+#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */
+
+#if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN)
+# error "default keyset is not large enough"
+#endif
+
+/*! Pseudorandom secret taken directly from FARSH. */
+XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = {
+ 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
+ 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
+ 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
+ 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c,
+ 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3,
+ 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8,
+ 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d,
+ 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64,
+ 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb,
+ 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e,
+ 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce,
+ 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
+};
+
+
+#ifdef XXH_OLD_NAMES
+# define kSecret XXH3_kSecret
+#endif
+
+#ifdef XXH_DOXYGEN
+/*!
+ * @brief Calculates a 32-bit to 64-bit long multiply.
+ *
+ * Implemented as a macro.
+ *
+ * Wraps `__emulu` on MSVC x86 because it tends to call `__allmul` when it doesn't
+ * need to (but it shouldn't need to anyways, it is about 7 instructions to do
+ * a 64x64 multiply...). Since we know that this will _always_ emit `MULL`, we
+ * use that instead of the normal method.
+ *
+ * If you are compiling for platforms like Thumb-1 and don't have a better option,
+ * you may also want to write your own long multiply routine here.
+ *
+ * @param x, y Numbers to be multiplied
+ * @return 64-bit product of the low 32 bits of @p x and @p y.
+ */
+XXH_FORCE_INLINE xxh_u64
+XXH_mult32to64(xxh_u64 x, xxh_u64 y)
+{
+ return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF);
+}
+#elif defined(_MSC_VER) && defined(_M_IX86)
+# define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y))
+#else
+/*
+ * Downcast + upcast is usually better than masking on older compilers like
+ * GCC 4.2 (especially 32-bit ones), all without affecting newer compilers.
+ *
+ * The other method, (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF), will AND both operands
+ * and perform a full 64x64 multiply -- entirely redundant on 32-bit.
+ */
+# define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y))
+#endif
+
+/*!
+ * @brief Calculates a 64->128-bit long multiply.
+ *
+ * Uses `__uint128_t` and `_umul128` if available, otherwise uses a scalar
+ * version.
+ *
+ * @param lhs , rhs The 64-bit integers to be multiplied
+ * @return The 128-bit result represented in an @ref XXH128_hash_t.
+ */
+static XXH128_hash_t
+XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs)
+{
+ /*
+ * GCC/Clang __uint128_t method.
+ *
+ * On most 64-bit targets, GCC and Clang define a __uint128_t type.
+ * This is usually the best way as it usually uses a native long 64-bit
+ * multiply, such as MULQ on x86_64 or MUL + UMULH on aarch64.
+ *
+ * Usually.
+ *
+ * Despite being a 32-bit platform, Clang (and emscripten) define this type
+ * despite not having the arithmetic for it. This results in a laggy
+ * compiler builtin call which calculates a full 128-bit multiply.
+ * In that case it is best to use the portable one.
+ * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677
+ */
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(__wasm__) \
+ && defined(__SIZEOF_INT128__) \
+ || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128)
+
+ __uint128_t const product = (__uint128_t)lhs * (__uint128_t)rhs;
+ XXH128_hash_t r128;
+ r128.low64 = (xxh_u64)(product);
+ r128.high64 = (xxh_u64)(product >> 64);
+ return r128;
+
+ /*
+ * MSVC for x64's _umul128 method.
+ *
+ * xxh_u64 _umul128(xxh_u64 Multiplier, xxh_u64 Multiplicand, xxh_u64 *HighProduct);
+ *
+ * This compiles to single operand MUL on x64.
+ */
+#elif (defined(_M_X64) || defined(_M_IA64)) && !defined(_M_ARM64EC)
+
+#ifndef _MSC_VER
+# pragma intrinsic(_umul128)
+#endif
+ xxh_u64 product_high;
+ xxh_u64 const product_low = _umul128(lhs, rhs, &product_high);
+ XXH128_hash_t r128;
+ r128.low64 = product_low;
+ r128.high64 = product_high;
+ return r128;
+
+ /*
+ * MSVC for ARM64's __umulh method.
+ *
+ * This compiles to the same MUL + UMULH as GCC/Clang's __uint128_t method.
+ */
+#elif defined(_M_ARM64) || defined(_M_ARM64EC)
+
+#ifndef _MSC_VER
+# pragma intrinsic(__umulh)
+#endif
+ XXH128_hash_t r128;
+ r128.low64 = lhs * rhs;
+ r128.high64 = __umulh(lhs, rhs);
+ return r128;
+
+#else
+ /*
+ * Portable scalar method. Optimized for 32-bit and 64-bit ALUs.
+ *
+ * This is a fast and simple grade school multiply, which is shown below
+ * with base 10 arithmetic instead of base 0x100000000.
+ *
+ * 9 3 // D2 lhs = 93
+ * x 7 5 // D2 rhs = 75
+ * ----------
+ * 1 5 // D2 lo_lo = (93 % 10) * (75 % 10) = 15
+ * 4 5 | // D2 hi_lo = (93 / 10) * (75 % 10) = 45
+ * 2 1 | // D2 lo_hi = (93 % 10) * (75 / 10) = 21
+ * + 6 3 | | // D2 hi_hi = (93 / 10) * (75 / 10) = 63
+ * ---------
+ * 2 7 | // D2 cross = (15 / 10) + (45 % 10) + 21 = 27
+ * + 6 7 | | // D2 upper = (27 / 10) + (45 / 10) + 63 = 67
+ * ---------
+ * 6 9 7 5 // D4 res = (27 * 10) + (15 % 10) + (67 * 100) = 6975
+ *
+ * The reasons for adding the products like this are:
+ * 1. It avoids manual carry tracking. Just like how
+ * (9 * 9) + 9 + 9 = 99, the same applies with this for UINT64_MAX.
+ * This avoids a lot of complexity.
+ *
+ * 2. It hints for, and on Clang, compiles to, the powerful UMAAL
+ * instruction available in ARM's Digital Signal Processing extension
+ * in 32-bit ARMv6 and later, which is shown below:
+ *
+ * void UMAAL(xxh_u32 *RdLo, xxh_u32 *RdHi, xxh_u32 Rn, xxh_u32 Rm)
+ * {
+ * xxh_u64 product = (xxh_u64)*RdLo * (xxh_u64)*RdHi + Rn + Rm;
+ * *RdLo = (xxh_u32)(product & 0xFFFFFFFF);
+ * *RdHi = (xxh_u32)(product >> 32);
+ * }
+ *
+ * This instruction was designed for efficient long multiplication, and
+ * allows this to be calculated in only 4 instructions at speeds
+ * comparable to some 64-bit ALUs.
+ *
+ * 3. It isn't terrible on other platforms. Usually this will be a couple
+ * of 32-bit ADD/ADCs.
+ */
+
+ /* First calculate all of the cross products. */
+ xxh_u64 const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF);
+ xxh_u64 const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF);
+ xxh_u64 const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32);
+ xxh_u64 const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32);
+
+ /* Now add the products together. These will never overflow. */
+ xxh_u64 const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi;
+ xxh_u64 const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi;
+ xxh_u64 const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF);
+
+ XXH128_hash_t r128;
+ r128.low64 = lower;
+ r128.high64 = upper;
+ return r128;
+#endif
+}
+
+/*!
+ * @brief Calculates a 64-bit to 128-bit multiply, then XOR folds it.
+ *
+ * The reason for the separate function is to prevent passing too many structs
+ * around by value. This will hopefully inline the multiply, but we don't force it.
+ *
+ * @param lhs , rhs The 64-bit integers to multiply
+ * @return The low 64 bits of the product XOR'd by the high 64 bits.
+ * @see XXH_mult64to128()
+ */
+static xxh_u64
+XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs)
+{
+ XXH128_hash_t product = XXH_mult64to128(lhs, rhs);
+ return product.low64 ^ product.high64;
+}
+
+/*! Seems to produce slightly better code on GCC for some reason. */
+XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
+{
+ XXH_ASSERT(0 <= shift && shift < 64);
+ return v64 ^ (v64 >> shift);
+}
+
+/*
+ * This is a fast avalanche stage,
+ * suitable when input bits are already partially mixed
+ */
+static XXH64_hash_t XXH3_avalanche(xxh_u64 h64)
+{
+ h64 = XXH_xorshift64(h64, 37);
+ h64 *= 0x165667919E3779F9ULL;
+ h64 = XXH_xorshift64(h64, 32);
+ return h64;
+}
+
+/*
+ * This is a stronger avalanche,
+ * inspired by Pelle Evensen's rrmxmx
+ * preferable when input has not been previously mixed
+ */
+static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len)
+{
+ /* this mix is inspired by Pelle Evensen's rrmxmx */
+ h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24);
+ h64 *= 0x9FB21C651E98DF25ULL;
+ h64 ^= (h64 >> 35) + len ;
+ h64 *= 0x9FB21C651E98DF25ULL;
+ return XXH_xorshift64(h64, 28);
+}
+
+
+/* ==========================================
+ * Short keys
+ * ==========================================
+ * One of the shortcomings of XXH32 and XXH64 was that their performance was
+ * sub-optimal on short lengths. It used an iterative algorithm which strongly
+ * favored lengths that were a multiple of 4 or 8.
+ *
+ * Instead of iterating over individual inputs, we use a set of single shot
+ * functions which piece together a range of lengths and operate in constant time.
+ *
+ * Additionally, the number of multiplies has been significantly reduced. This
+ * reduces latency, especially when emulating 64-bit multiplies on 32-bit.
+ *
+ * Depending on the platform, this may or may not be faster than XXH32, but it
+ * is almost guaranteed to be faster than XXH64.
+ */
+
+/*
+ * At very short lengths, there isn't enough input to fully hide secrets, or use
+ * the entire secret.
+ *
+ * There is also only a limited amount of mixing we can do before significantly
+ * impacting performance.
+ *
+ * Therefore, we use different sections of the secret and always mix two secret
+ * samples with an XOR. This should have no effect on performance on the
+ * seedless or withSeed variants because everything _should_ be constant folded
+ * by modern compilers.
+ *
+ * The XOR mixing hides individual parts of the secret and increases entropy.
+ *
+ * This adds an extra layer of strength for custom secrets.
+ */
+XXH_FORCE_INLINE XXH64_hash_t
+XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
+{
+ XXH_ASSERT(input != NULL);
+ XXH_ASSERT(1 <= len && len <= 3);
+ XXH_ASSERT(secret != NULL);
+ /*
+ * len = 1: combined = { input[0], 0x01, input[0], input[0] }
+ * len = 2: combined = { input[1], 0x02, input[0], input[1] }
+ * len = 3: combined = { input[2], 0x03, input[0], input[1] }
+ */
+ { xxh_u8 const c1 = input[0];
+ xxh_u8 const c2 = input[len >> 1];
+ xxh_u8 const c3 = input[len - 1];
+ xxh_u32 const combined = ((xxh_u32)c1 << 16) | ((xxh_u32)c2 << 24)
+ | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
+ xxh_u64 const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
+ xxh_u64 const keyed = (xxh_u64)combined ^ bitflip;
+ return XXH64_avalanche(keyed);
+ }
+}
+
+XXH_FORCE_INLINE XXH64_hash_t
+XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
+{
+ XXH_ASSERT(input != NULL);
+ XXH_ASSERT(secret != NULL);
+ XXH_ASSERT(4 <= len && len <= 8);
+ seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
+ { xxh_u32 const input1 = XXH_readLE32(input);
+ xxh_u32 const input2 = XXH_readLE32(input + len - 4);
+ xxh_u64 const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed;
+ xxh_u64 const input64 = input2 + (((xxh_u64)input1) << 32);
+ xxh_u64 const keyed = input64 ^ bitflip;
+ return XXH3_rrmxmx(keyed, len);
+ }
+}
+
+XXH_FORCE_INLINE XXH64_hash_t
+XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
+{
+ XXH_ASSERT(input != NULL);
+ XXH_ASSERT(secret != NULL);
+ XXH_ASSERT(9 <= len && len <= 16);
+ { xxh_u64 const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed;
+ xxh_u64 const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed;
+ xxh_u64 const input_lo = XXH_readLE64(input) ^ bitflip1;
+ xxh_u64 const input_hi = XXH_readLE64(input + len - 8) ^ bitflip2;
+ xxh_u64 const acc = len
+ + XXH_swap64(input_lo) + input_hi
+ + XXH3_mul128_fold64(input_lo, input_hi);
+ return XXH3_avalanche(acc);
+ }
+}
+
+XXH_FORCE_INLINE XXH64_hash_t
+XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
+{
+ XXH_ASSERT(len <= 16);
+ { if (XXH_likely(len > 8)) return XXH3_len_9to16_64b(input, len, secret, seed);
+ if (XXH_likely(len >= 4)) return XXH3_len_4to8_64b(input, len, secret, seed);
+ if (len) return XXH3_len_1to3_64b(input, len, secret, seed);
+ return XXH64_avalanche(seed ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64)));
+ }
+}
+
+/*
+ * DISCLAIMER: There are known *seed-dependent* multicollisions here due to
+ * multiplication by zero, affecting hashes of lengths 17 to 240.
+ *
+ * However, they are very unlikely.
+ *
+ * Keep this in mind when using the unseeded XXH3_64bits() variant: As with all
+ * unseeded non-cryptographic hashes, it does not attempt to defend itself
+ * against specially crafted inputs, only random inputs.
+ *
+ * Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes
+ * cancelling out the secret is taken an arbitrary number of times (addressed
+ * in XXH3_accumulate_512), this collision is very unlikely with random inputs
+ * and/or proper seeding:
+ *
+ * This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a
+ * function that is only called up to 16 times per hash with up to 240 bytes of
+ * input.
+ *
+ * This is not too bad for a non-cryptographic hash function, especially with
+ * only 64 bit outputs.
+ *
+ * The 128-bit variant (which trades some speed for strength) is NOT affected
+ * by this, although it is always a good idea to use a proper seed if you care
+ * about strength.
+ */
+XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input,
+ const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64)
+{
+#if defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
+ && defined(__i386__) && defined(__SSE2__) /* x86 + SSE2 */ \
+ && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable like XXH32 hack */
+ /*
+ * UGLY HACK:
+ * GCC for x86 tends to autovectorize the 128-bit multiply, resulting in
+ * slower code.
+ *
+ * By forcing seed64 into a register, we disrupt the cost model and
+ * cause it to scalarize. See `XXH32_round()`
+ *
+ * FIXME: Clang's output is still _much_ faster -- On an AMD Ryzen 3600,
+ * XXH3_64bits @ len=240 runs at 4.6 GB/s with Clang 9, but 3.3 GB/s on
+ * GCC 9.2, despite both emitting scalar code.
+ *
+ * GCC generates much better scalar code than Clang for the rest of XXH3,
+ * which is why finding a more optimal codepath is an interest.
+ */
+ XXH_COMPILER_GUARD(seed64);
+#endif
+ { xxh_u64 const input_lo = XXH_readLE64(input);
+ xxh_u64 const input_hi = XXH_readLE64(input+8);
+ return XXH3_mul128_fold64(
+ input_lo ^ (XXH_readLE64(secret) + seed64),
+ input_hi ^ (XXH_readLE64(secret+8) - seed64)
+ );
+ }
+}
+
+/* For mid range keys, XXH3 uses a Mum-hash variant. */
+XXH_FORCE_INLINE XXH64_hash_t
+XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
+ const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
+ XXH64_hash_t seed)
+{
+ XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
+ XXH_ASSERT(16 < len && len <= 128);
+
+ { xxh_u64 acc = len * XXH_PRIME64_1;
+ if (len > 32) {
+ if (len > 64) {
+ if (len > 96) {
+ acc += XXH3_mix16B(input+48, secret+96, seed);
+ acc += XXH3_mix16B(input+len-64, secret+112, seed);
+ }
+ acc += XXH3_mix16B(input+32, secret+64, seed);
+ acc += XXH3_mix16B(input+len-48, secret+80, seed);
+ }
+ acc += XXH3_mix16B(input+16, secret+32, seed);
+ acc += XXH3_mix16B(input+len-32, secret+48, seed);
+ }
+ acc += XXH3_mix16B(input+0, secret+0, seed);
+ acc += XXH3_mix16B(input+len-16, secret+16, seed);
+
+ return XXH3_avalanche(acc);
+ }
+}
+
+#define XXH3_MIDSIZE_MAX 240
+
+XXH_NO_INLINE XXH64_hash_t
+XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
+ const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
+ XXH64_hash_t seed)
+{
+ XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
+ XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
+
+ #define XXH3_MIDSIZE_STARTOFFSET 3
+ #define XXH3_MIDSIZE_LASTOFFSET 17
+
+ { xxh_u64 acc = len * XXH_PRIME64_1;
+ int const nbRounds = (int)len / 16;
+ int i;
+ for (i=0; i<8; i++) {
+ acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed);
+ }
+ acc = XXH3_avalanche(acc);
+ XXH_ASSERT(nbRounds >= 8);
+#if defined(__clang__) /* Clang */ \
+ && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \
+ && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */
+ /*
+ * UGLY HACK:
+ * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86.
+ * In everywhere else, it uses scalar code.
+ *
+ * For 64->128-bit multiplies, even if the NEON was 100% optimal, it
+ * would still be slower than UMAAL (see XXH_mult64to128).
+ *
+ * Unfortunately, Clang doesn't handle the long multiplies properly and
+ * converts them to the nonexistent "vmulq_u64" intrinsic, which is then
+ * scalarized into an ugly mess of VMOV.32 instructions.
+ *
+ * This mess is difficult to avoid without turning autovectorization
+ * off completely, but they are usually relatively minor and/or not
+ * worth it to fix.
+ *
+ * This loop is the easiest to fix, as unlike XXH32, this pragma
+ * _actually works_ because it is a loop vectorization instead of an
+ * SLP vectorization.
+ */
+ #pragma clang loop vectorize(disable)
+#endif
+ for (i=8 ; i < nbRounds; i++) {
+ acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed);
+ }
+ /* last bytes */
+ acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed);
+ return XXH3_avalanche(acc);
+ }
+}
+
+
+/* ======= Long Keys ======= */
+
+#define XXH_STRIPE_LEN 64
+#define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */
+#define XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64))
+
+#ifdef XXH_OLD_NAMES
+# define STRIPE_LEN XXH_STRIPE_LEN
+# define ACC_NB XXH_ACC_NB
+#endif
+
+XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64)
+{
+ if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64);
+ XXH_memcpy(dst, &v64, sizeof(v64));
+}
+
+/* Several intrinsic functions below are supposed to accept __int64 as argument,
+ * as documented in https://software.intel.com/sites/landingpage/IntrinsicsGuide/ .
+ * However, several environments do not define __int64 type,
+ * requiring a workaround.
+ */
+#if !defined (__VMS) \
+ && (defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+ typedef int64_t xxh_i64;
+#else
+ /* the following type must have a width of 64-bit */
+ typedef long long xxh_i64;
+#endif
+
+
+/*
+ * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized.
+ *
+ * It is a hardened version of UMAC, based off of FARSH's implementation.
+ *
+ * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD
+ * implementations, and it is ridiculously fast.
+ *
+ * We harden it by mixing the original input to the accumulators as well as the product.
+ *
+ * This means that in the (relatively likely) case of a multiply by zero, the
+ * original input is preserved.
+ *
+ * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve
+ * cross-pollination, as otherwise the upper and lower halves would be
+ * essentially independent.
+ *
+ * This doesn't matter on 64-bit hashes since they all get merged together in
+ * the end, so we skip the extra step.
+ *
+ * Both XXH3_64bits and XXH3_128bits use this subroutine.
+ */
+
+#if (XXH_VECTOR == XXH_AVX512) \
+ || (defined(XXH_DISPATCH_AVX512) && XXH_DISPATCH_AVX512 != 0)
+
+#ifndef XXH_TARGET_AVX512
+# define XXH_TARGET_AVX512 /* disable attribute target */
+#endif
+
+XXH_FORCE_INLINE XXH_TARGET_AVX512 void
+XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc,
+ const void* XXH_RESTRICT input,
+ const void* XXH_RESTRICT secret)
+{
+ __m512i* const xacc = (__m512i *) acc;
+ XXH_ASSERT((((size_t)acc) & 63) == 0);
+ XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
+
+ {
+ /* data_vec = input[0]; */
+ __m512i const data_vec = _mm512_loadu_si512 (input);
+ /* key_vec = secret[0]; */
+ __m512i const key_vec = _mm512_loadu_si512 (secret);
+ /* data_key = data_vec ^ key_vec; */
+ __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec);
+ /* data_key_lo = data_key >> 32; */
+ __m512i const data_key_lo = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1));
+ /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
+ __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo);
+ /* xacc[0] += swap(data_vec); */
+ __m512i const data_swap = _mm512_shuffle_epi32(data_vec, (_MM_PERM_ENUM)_MM_SHUFFLE(1, 0, 3, 2));
+ __m512i const sum = _mm512_add_epi64(*xacc, data_swap);
+ /* xacc[0] += product; */
+ *xacc = _mm512_add_epi64(product, sum);
+ }
+}
+
+/*
+ * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing.
+ *
+ * Multiplication isn't perfect, as explained by Google in HighwayHash:
+ *
+ * // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to
+ * // varying degrees. In descending order of goodness, bytes
+ * // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32.
+ * // As expected, the upper and lower bytes are much worse.
+ *
+ * Source: https://github.com/google/highwayhash/blob/0aaf66b/highwayhash/hh_avx2.h#L291
+ *
+ * Since our algorithm uses a pseudorandom secret to add some variance into the
+ * mix, we don't need to (or want to) mix as often or as much as HighwayHash does.
+ *
+ * This isn't as tight as XXH3_accumulate, but still written in SIMD to avoid
+ * extraction.
+ *
+ * Both XXH3_64bits and XXH3_128bits use this subroutine.
+ */
+
+XXH_FORCE_INLINE XXH_TARGET_AVX512 void
+XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
+{
+ XXH_ASSERT((((size_t)acc) & 63) == 0);
+ XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
+ { __m512i* const xacc = (__m512i*) acc;
+ const __m512i prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1);
+
+ /* xacc[0] ^= (xacc[0] >> 47) */
+ __m512i const acc_vec = *xacc;
+ __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47);
+ __m512i const data_vec = _mm512_xor_si512 (acc_vec, shifted);
+ /* xacc[0] ^= secret; */
+ __m512i const key_vec = _mm512_loadu_si512 (secret);
+ __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec);
+
+ /* xacc[0] *= XXH_PRIME32_1; */
+ __m512i const data_key_hi = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1));
+ __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32);
+ __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32);
+ *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32));
+ }
+}
+
+XXH_FORCE_INLINE XXH_TARGET_AVX512 void
+XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
+{
+ XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 63) == 0);
+ XXH_STATIC_ASSERT(XXH_SEC_ALIGN == 64);
+ XXH_ASSERT(((size_t)customSecret & 63) == 0);
+ (void)(&XXH_writeLE64);
+ { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i);
+ __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, (xxh_i64)(0U - seed64));
+
+ const __m512i* const src = (const __m512i*) ((const void*) XXH3_kSecret);
+ __m512i* const dest = ( __m512i*) customSecret;
+ int i;
+ XXH_ASSERT(((size_t)src & 63) == 0); /* control alignment */
+ XXH_ASSERT(((size_t)dest & 63) == 0);
+ for (i=0; i < nbRounds; ++i) {
+ /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*',
+ * this will warn "discards 'const' qualifier". */
+ union {
+ const __m512i* cp;
+ void* p;
+ } remote_const_void;
+ remote_const_void.cp = src + i;
+ dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed);
+ } }
+}
+
+#endif
+
+#if (XXH_VECTOR == XXH_AVX2) \
+ || (defined(XXH_DISPATCH_AVX2) && XXH_DISPATCH_AVX2 != 0)
+
+#ifndef XXH_TARGET_AVX2
+# define XXH_TARGET_AVX2 /* disable attribute target */
+#endif
+
+XXH_FORCE_INLINE XXH_TARGET_AVX2 void
+XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc,
+ const void* XXH_RESTRICT input,
+ const void* XXH_RESTRICT secret)
+{
+ XXH_ASSERT((((size_t)acc) & 31) == 0);
+ { __m256i* const xacc = (__m256i *) acc;
+ /* Unaligned. This is mainly for pointer arithmetic, and because
+ * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
+ const __m256i* const xinput = (const __m256i *) input;
+ /* Unaligned. This is mainly for pointer arithmetic, and because
+ * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
+ const __m256i* const xsecret = (const __m256i *) secret;
+
+ size_t i;
+ for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) {
+ /* data_vec = xinput[i]; */
+ __m256i const data_vec = _mm256_loadu_si256 (xinput+i);
+ /* key_vec = xsecret[i]; */
+ __m256i const key_vec = _mm256_loadu_si256 (xsecret+i);
+ /* data_key = data_vec ^ key_vec; */
+ __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec);
+ /* data_key_lo = data_key >> 32; */
+ __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
+ /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
+ __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo);
+ /* xacc[i] += swap(data_vec); */
+ __m256i const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2));
+ __m256i const sum = _mm256_add_epi64(xacc[i], data_swap);
+ /* xacc[i] += product; */
+ xacc[i] = _mm256_add_epi64(product, sum);
+ } }
+}
+
+XXH_FORCE_INLINE XXH_TARGET_AVX2 void
+XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
+{
+ XXH_ASSERT((((size_t)acc) & 31) == 0);
+ { __m256i* const xacc = (__m256i*) acc;
+ /* Unaligned. This is mainly for pointer arithmetic, and because
+ * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
+ const __m256i* const xsecret = (const __m256i *) secret;
+ const __m256i prime32 = _mm256_set1_epi32((int)XXH_PRIME32_1);
+
+ size_t i;
+ for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) {
+ /* xacc[i] ^= (xacc[i] >> 47) */
+ __m256i const acc_vec = xacc[i];
+ __m256i const shifted = _mm256_srli_epi64 (acc_vec, 47);
+ __m256i const data_vec = _mm256_xor_si256 (acc_vec, shifted);
+ /* xacc[i] ^= xsecret; */
+ __m256i const key_vec = _mm256_loadu_si256 (xsecret+i);
+ __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec);
+
+ /* xacc[i] *= XXH_PRIME32_1; */
+ __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
+ __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32);
+ __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32);
+ xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32));
+ }
+ }
+}
+
+XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
+{
+ XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 31) == 0);
+ XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE / sizeof(__m256i)) == 6);
+ XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64);
+ (void)(&XXH_writeLE64);
+ XXH_PREFETCH(customSecret);
+ { __m256i const seed = _mm256_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64, (xxh_i64)(0U - seed64), (xxh_i64)seed64);
+
+ const __m256i* const src = (const __m256i*) ((const void*) XXH3_kSecret);
+ __m256i* dest = ( __m256i*) customSecret;
+
+# if defined(__GNUC__) || defined(__clang__)
+ /*
+ * On GCC & Clang, marking 'dest' as modified will cause the compiler:
+ * - do not extract the secret from sse registers in the internal loop
+ * - use less common registers, and avoid pushing these reg into stack
+ */
+ XXH_COMPILER_GUARD(dest);
+# endif
+ XXH_ASSERT(((size_t)src & 31) == 0); /* control alignment */
+ XXH_ASSERT(((size_t)dest & 31) == 0);
+
+ /* GCC -O2 need unroll loop manually */
+ dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed);
+ dest[1] = _mm256_add_epi64(_mm256_stream_load_si256(src+1), seed);
+ dest[2] = _mm256_add_epi64(_mm256_stream_load_si256(src+2), seed);
+ dest[3] = _mm256_add_epi64(_mm256_stream_load_si256(src+3), seed);
+ dest[4] = _mm256_add_epi64(_mm256_stream_load_si256(src+4), seed);
+ dest[5] = _mm256_add_epi64(_mm256_stream_load_si256(src+5), seed);
+ }
+}
+
+#endif
+
+/* x86dispatch always generates SSE2 */
+#if (XXH_VECTOR == XXH_SSE2) || defined(XXH_X86DISPATCH)
+
+#ifndef XXH_TARGET_SSE2
+# define XXH_TARGET_SSE2 /* disable attribute target */
+#endif
+
+XXH_FORCE_INLINE XXH_TARGET_SSE2 void
+XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc,
+ const void* XXH_RESTRICT input,
+ const void* XXH_RESTRICT secret)
+{
+ /* SSE2 is just a half-scale version of the AVX2 version. */
+ XXH_ASSERT((((size_t)acc) & 15) == 0);
+ { __m128i* const xacc = (__m128i *) acc;
+ /* Unaligned. This is mainly for pointer arithmetic, and because
+ * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
+ const __m128i* const xinput = (const __m128i *) input;
+ /* Unaligned. This is mainly for pointer arithmetic, and because
+ * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
+ const __m128i* const xsecret = (const __m128i *) secret;
+
+ size_t i;
+ for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) {
+ /* data_vec = xinput[i]; */
+ __m128i const data_vec = _mm_loadu_si128 (xinput+i);
+ /* key_vec = xsecret[i]; */
+ __m128i const key_vec = _mm_loadu_si128 (xsecret+i);
+ /* data_key = data_vec ^ key_vec; */
+ __m128i const data_key = _mm_xor_si128 (data_vec, key_vec);
+ /* data_key_lo = data_key >> 32; */
+ __m128i const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
+ /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
+ __m128i const product = _mm_mul_epu32 (data_key, data_key_lo);
+ /* xacc[i] += swap(data_vec); */
+ __m128i const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2));
+ __m128i const sum = _mm_add_epi64(xacc[i], data_swap);
+ /* xacc[i] += product; */
+ xacc[i] = _mm_add_epi64(product, sum);
+ } }
+}
+
+XXH_FORCE_INLINE XXH_TARGET_SSE2 void
+XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
+{
+ XXH_ASSERT((((size_t)acc) & 15) == 0);
+ { __m128i* const xacc = (__m128i*) acc;
+ /* Unaligned. This is mainly for pointer arithmetic, and because
+ * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
+ const __m128i* const xsecret = (const __m128i *) secret;
+ const __m128i prime32 = _mm_set1_epi32((int)XXH_PRIME32_1);
+
+ size_t i;
+ for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) {
+ /* xacc[i] ^= (xacc[i] >> 47) */
+ __m128i const acc_vec = xacc[i];
+ __m128i const shifted = _mm_srli_epi64 (acc_vec, 47);
+ __m128i const data_vec = _mm_xor_si128 (acc_vec, shifted);
+ /* xacc[i] ^= xsecret[i]; */
+ __m128i const key_vec = _mm_loadu_si128 (xsecret+i);
+ __m128i const data_key = _mm_xor_si128 (data_vec, key_vec);
+
+ /* xacc[i] *= XXH_PRIME32_1; */
+ __m128i const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
+ __m128i const prod_lo = _mm_mul_epu32 (data_key, prime32);
+ __m128i const prod_hi = _mm_mul_epu32 (data_key_hi, prime32);
+ xacc[i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32));
+ }
+ }
+}
+
+XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
+{
+ XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
+ (void)(&XXH_writeLE64);
+ { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m128i);
+
+# if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900
+ /* MSVC 32bit mode does not support _mm_set_epi64x before 2015 */
+ XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, (xxh_i64)(0U - seed64) };
+ __m128i const seed = _mm_load_si128((__m128i const*)seed64x2);
+# else
+ __m128i const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64);
+# endif
+ int i;
+
+ const void* const src16 = XXH3_kSecret;
+ __m128i* dst16 = (__m128i*) customSecret;
+# if defined(__GNUC__) || defined(__clang__)
+ /*
+ * On GCC & Clang, marking 'dest' as modified will cause the compiler:
+ * - do not extract the secret from sse registers in the internal loop
+ * - use less common registers, and avoid pushing these reg into stack
+ */
+ XXH_COMPILER_GUARD(dst16);
+# endif
+ XXH_ASSERT(((size_t)src16 & 15) == 0); /* control alignment */
+ XXH_ASSERT(((size_t)dst16 & 15) == 0);
+
+ for (i=0; i < nbRounds; ++i) {
+ dst16[i] = _mm_add_epi64(_mm_load_si128((const __m128i *)src16+i), seed);
+ } }
+}
+
+#endif
+
+#if (XXH_VECTOR == XXH_NEON)
+
+/* forward declarations for the scalar routines */
+XXH_FORCE_INLINE void
+XXH3_scalarRound(void* XXH_RESTRICT acc, void const* XXH_RESTRICT input,
+ void const* XXH_RESTRICT secret, size_t lane);
+
+XXH_FORCE_INLINE void
+XXH3_scalarScrambleRound(void* XXH_RESTRICT acc,
+ void const* XXH_RESTRICT secret, size_t lane);
+
+/*!
+ * @internal
+ * @brief The bulk processing loop for NEON.
+ *
+ * The NEON code path is actually partially scalar when running on AArch64. This
+ * is to optimize the pipelining and can have up to 15% speedup depending on the
+ * CPU, and it also mitigates some GCC codegen issues.
+ *
+ * @see XXH3_NEON_LANES for configuring this and details about this optimization.
+ */
+XXH_FORCE_INLINE void
+XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
+ const void* XXH_RESTRICT input,
+ const void* XXH_RESTRICT secret)
+{
+ XXH_ASSERT((((size_t)acc) & 15) == 0);
+ XXH_STATIC_ASSERT(XXH3_NEON_LANES > 0 && XXH3_NEON_LANES <= XXH_ACC_NB && XXH3_NEON_LANES % 2 == 0);
+ {
+ uint64x2_t* const xacc = (uint64x2_t *) acc;
+ /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */
+ uint8_t const* const xinput = (const uint8_t *) input;
+ uint8_t const* const xsecret = (const uint8_t *) secret;
+
+ size_t i;
+ /* NEON for the first few lanes (these loops are normally interleaved) */
+ for (i=0; i < XXH3_NEON_LANES / 2; i++) {
+ /* data_vec = xinput[i]; */
+ uint8x16_t data_vec = vld1q_u8(xinput + (i * 16));
+ /* key_vec = xsecret[i]; */
+ uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16));
+ uint64x2_t data_key;
+ uint32x2_t data_key_lo, data_key_hi;
+ /* xacc[i] += swap(data_vec); */
+ uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec);
+ uint64x2_t const swapped = vextq_u64(data64, data64, 1);
+ xacc[i] = vaddq_u64 (xacc[i], swapped);
+ /* data_key = data_vec ^ key_vec; */
+ data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec));
+ /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF);
+ * data_key_hi = (uint32x2_t) (data_key >> 32);
+ * data_key = UNDEFINED; */
+ XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi);
+ /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */
+ xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi);
+
+ }
+ /* Scalar for the remainder. This may be a zero iteration loop. */
+ for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) {
+ XXH3_scalarRound(acc, input, secret, i);
+ }
+ }
+}
+
+XXH_FORCE_INLINE void
+XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
+{
+ XXH_ASSERT((((size_t)acc) & 15) == 0);
+
+ { uint64x2_t* xacc = (uint64x2_t*) acc;
+ uint8_t const* xsecret = (uint8_t const*) secret;
+ uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1);
+
+ size_t i;
+ /* NEON for the first few lanes (these loops are normally interleaved) */
+ for (i=0; i < XXH3_NEON_LANES / 2; i++) {
+ /* xacc[i] ^= (xacc[i] >> 47); */
+ uint64x2_t acc_vec = xacc[i];
+ uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47);
+ uint64x2_t data_vec = veorq_u64 (acc_vec, shifted);
+
+ /* xacc[i] ^= xsecret[i]; */
+ uint8x16_t key_vec = vld1q_u8 (xsecret + (i * 16));
+ uint64x2_t data_key = veorq_u64 (data_vec, vreinterpretq_u64_u8(key_vec));
+
+ /* xacc[i] *= XXH_PRIME32_1 */
+ uint32x2_t data_key_lo, data_key_hi;
+ /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF);
+ * data_key_hi = (uint32x2_t) (xacc[i] >> 32);
+ * xacc[i] = UNDEFINED; */
+ XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi);
+ { /*
+ * prod_hi = (data_key >> 32) * XXH_PRIME32_1;
+ *
+ * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will
+ * incorrectly "optimize" this:
+ * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b));
+ * shifted = vshll_n_u32(tmp, 32);
+ * to this:
+ * tmp = "vmulq_u64"(a, b); // no such thing!
+ * shifted = vshlq_n_u64(tmp, 32);
+ *
+ * However, unlike SSE, Clang lacks a 64-bit multiply routine
+ * for NEON, and it scalarizes two 64-bit multiplies instead.
+ *
+ * vmull_u32 has the same timing as vmul_u32, and it avoids
+ * this bug completely.
+ * See https://bugs.llvm.org/show_bug.cgi?id=39967
+ */
+ uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime);
+ /* xacc[i] = prod_hi << 32; */
+ xacc[i] = vshlq_n_u64(prod_hi, 32);
+ /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */
+ xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime);
+ }
+ }
+ /* Scalar for the remainder. This may be a zero iteration loop. */
+ for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) {
+ XXH3_scalarScrambleRound(acc, secret, i);
+ }
+ }
+}
+
+#endif
+
+#if (XXH_VECTOR == XXH_VSX)
+
+XXH_FORCE_INLINE void
+XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc,
+ const void* XXH_RESTRICT input,
+ const void* XXH_RESTRICT secret)
+{
+ /* presumed aligned */
+ unsigned int* const xacc = (unsigned int*) acc;
+ xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */
+ xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */
+ xxh_u64x2 const v32 = { 32, 32 };
+ size_t i;
+ for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) {
+ /* data_vec = xinput[i]; */
+ xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i);
+ /* key_vec = xsecret[i]; */
+ xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i);
+ xxh_u64x2 const data_key = data_vec ^ key_vec;
+ /* shuffled = (data_key << 32) | (data_key >> 32); */
+ xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32);
+ /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */
+ xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled);
+ /* acc_vec = xacc[i]; */
+ xxh_u64x2 acc_vec = (xxh_u64x2)vec_xl(0, xacc + 4 * i);
+ acc_vec += product;
+
+ /* swap high and low halves */
+#ifdef __s390x__
+ acc_vec += vec_permi(data_vec, data_vec, 2);
+#else
+ acc_vec += vec_xxpermdi(data_vec, data_vec, 2);
+#endif
+ /* xacc[i] = acc_vec; */
+ vec_xst((xxh_u32x4)acc_vec, 0, xacc + 4 * i);
+ }
+}
+
+XXH_FORCE_INLINE void
+XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
+{
+ XXH_ASSERT((((size_t)acc) & 15) == 0);
+
+ { xxh_u64x2* const xacc = (xxh_u64x2*) acc;
+ const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret;
+ /* constants */
+ xxh_u64x2 const v32 = { 32, 32 };
+ xxh_u64x2 const v47 = { 47, 47 };
+ xxh_u32x4 const prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 };
+ size_t i;
+ for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) {
+ /* xacc[i] ^= (xacc[i] >> 47); */
+ xxh_u64x2 const acc_vec = xacc[i];
+ xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47);
+
+ /* xacc[i] ^= xsecret[i]; */
+ xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i);
+ xxh_u64x2 const data_key = data_vec ^ key_vec;
+
+ /* xacc[i] *= XXH_PRIME32_1 */
+ /* prod_lo = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)prime & 0xFFFFFFFF); */
+ xxh_u64x2 const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime);
+ /* prod_hi = ((xxh_u64x2)data_key >> 32) * ((xxh_u64x2)prime >> 32); */
+ xxh_u64x2 const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime);
+ xacc[i] = prod_odd + (prod_even << v32);
+ } }
+}
+
+#endif
+
+/* scalar variants - universal */
+
+/*!
+ * @internal
+ * @brief Scalar round for @ref XXH3_accumulate_512_scalar().
+ *
+ * This is extracted to its own function because the NEON path uses a combination
+ * of NEON and scalar.
+ */
+XXH_FORCE_INLINE void
+XXH3_scalarRound(void* XXH_RESTRICT acc,
+ void const* XXH_RESTRICT input,
+ void const* XXH_RESTRICT secret,
+ size_t lane)
+{
+ xxh_u64* xacc = (xxh_u64*) acc;
+ xxh_u8 const* xinput = (xxh_u8 const*) input;
+ xxh_u8 const* xsecret = (xxh_u8 const*) secret;
+ XXH_ASSERT(lane < XXH_ACC_NB);
+ XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0);
+ {
+ xxh_u64 const data_val = XXH_readLE64(xinput + lane * 8);
+ xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + lane * 8);
+ xacc[lane ^ 1] += data_val; /* swap adjacent lanes */
+ xacc[lane] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32);
+ }
+}
+
+/*!
+ * @internal
+ * @brief Processes a 64 byte block of data using the scalar path.
+ */
+XXH_FORCE_INLINE void
+XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc,
+ const void* XXH_RESTRICT input,
+ const void* XXH_RESTRICT secret)
+{
+ size_t i;
+ for (i=0; i < XXH_ACC_NB; i++) {
+ XXH3_scalarRound(acc, input, secret, i);
+ }
+}
+
+/*!
+ * @internal
+ * @brief Scalar scramble step for @ref XXH3_scrambleAcc_scalar().
+ *
+ * This is extracted to its own function because the NEON path uses a combination
+ * of NEON and scalar.
+ */
+XXH_FORCE_INLINE void
+XXH3_scalarScrambleRound(void* XXH_RESTRICT acc,
+ void const* XXH_RESTRICT secret,
+ size_t lane)
+{
+ xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */
+ const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */
+ XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0);
+ XXH_ASSERT(lane < XXH_ACC_NB);
+ {
+ xxh_u64 const key64 = XXH_readLE64(xsecret + lane * 8);
+ xxh_u64 acc64 = xacc[lane];
+ acc64 = XXH_xorshift64(acc64, 47);
+ acc64 ^= key64;
+ acc64 *= XXH_PRIME32_1;
+ xacc[lane] = acc64;
+ }
+}
+
+/*!
+ * @internal
+ * @brief Scrambles the accumulators after a large chunk has been read
+ */
+XXH_FORCE_INLINE void
+XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
+{
+ size_t i;
+ for (i=0; i < XXH_ACC_NB; i++) {
+ XXH3_scalarScrambleRound(acc, secret, i);
+ }
+}
-#endif /* XXH_STATIC_LINKING_ONLY && XXH_STATIC_H_3543687687345 */
+XXH_FORCE_INLINE void
+XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
+{
+ /*
+ * We need a separate pointer for the hack below,
+ * which requires a non-const pointer.
+ * Any decent compiler will optimize this out otherwise.
+ */
+ const xxh_u8* kSecretPtr = XXH3_kSecret;
+ XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
+
+#if defined(__clang__) && defined(__aarch64__)
+ /*
+ * UGLY HACK:
+ * Clang generates a bunch of MOV/MOVK pairs for aarch64, and they are
+ * placed sequentially, in order, at the top of the unrolled loop.
+ *
+ * While MOVK is great for generating constants (2 cycles for a 64-bit
+ * constant compared to 4 cycles for LDR), it fights for bandwidth with
+ * the arithmetic instructions.
+ *
+ * I L S
+ * MOVK
+ * MOVK
+ * MOVK
+ * MOVK
+ * ADD
+ * SUB STR
+ * STR
+ * By forcing loads from memory (as the asm line causes Clang to assume
+ * that XXH3_kSecretPtr has been changed), the pipelines are used more
+ * efficiently:
+ * I L S
+ * LDR
+ * ADD LDR
+ * SUB STR
+ * STR
+ *
+ * See XXH3_NEON_LANES for details on the pipsline.
+ *
+ * XXH3_64bits_withSeed, len == 256, Snapdragon 835
+ * without hack: 2654.4 MB/s
+ * with hack: 3202.9 MB/s
+ */
+ XXH_COMPILER_GUARD(kSecretPtr);
+#endif
+ /*
+ * Note: in debug mode, this overrides the asm optimization
+ * and Clang will emit MOVK chains again.
+ */
+ XXH_ASSERT(kSecretPtr == XXH3_kSecret);
+
+ { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16;
+ int i;
+ for (i=0; i < nbRounds; i++) {
+ /*
+ * The asm hack causes Clang to assume that kSecretPtr aliases with
+ * customSecret, and on aarch64, this prevented LDP from merging two
+ * loads together for free. Putting the loads together before the stores
+ * properly generates LDP.
+ */
+ xxh_u64 lo = XXH_readLE64(kSecretPtr + 16*i) + seed64;
+ xxh_u64 hi = XXH_readLE64(kSecretPtr + 16*i + 8) - seed64;
+ XXH_writeLE64((xxh_u8*)customSecret + 16*i, lo);
+ XXH_writeLE64((xxh_u8*)customSecret + 16*i + 8, hi);
+ } }
+}
+
+
+typedef void (*XXH3_f_accumulate_512)(void* XXH_RESTRICT, const void*, const void*);
+typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*);
+typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64);
+
+
+#if (XXH_VECTOR == XXH_AVX512)
+
+#define XXH3_accumulate_512 XXH3_accumulate_512_avx512
+#define XXH3_scrambleAcc XXH3_scrambleAcc_avx512
+#define XXH3_initCustomSecret XXH3_initCustomSecret_avx512
+
+#elif (XXH_VECTOR == XXH_AVX2)
+
+#define XXH3_accumulate_512 XXH3_accumulate_512_avx2
+#define XXH3_scrambleAcc XXH3_scrambleAcc_avx2
+#define XXH3_initCustomSecret XXH3_initCustomSecret_avx2
+
+#elif (XXH_VECTOR == XXH_SSE2)
+
+#define XXH3_accumulate_512 XXH3_accumulate_512_sse2
+#define XXH3_scrambleAcc XXH3_scrambleAcc_sse2
+#define XXH3_initCustomSecret XXH3_initCustomSecret_sse2
+
+#elif (XXH_VECTOR == XXH_NEON)
+
+#define XXH3_accumulate_512 XXH3_accumulate_512_neon
+#define XXH3_scrambleAcc XXH3_scrambleAcc_neon
+#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
+
+#elif (XXH_VECTOR == XXH_VSX)
+
+#define XXH3_accumulate_512 XXH3_accumulate_512_vsx
+#define XXH3_scrambleAcc XXH3_scrambleAcc_vsx
+#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
+
+#else /* scalar */
+
+#define XXH3_accumulate_512 XXH3_accumulate_512_scalar
+#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar
+#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
+
+#endif
+
+
+
+#ifndef XXH_PREFETCH_DIST
+# ifdef __clang__
+# define XXH_PREFETCH_DIST 320
+# else
+# if (XXH_VECTOR == XXH_AVX512)
+# define XXH_PREFETCH_DIST 512
+# else
+# define XXH_PREFETCH_DIST 384
+# endif
+# endif /* __clang__ */
+#endif /* XXH_PREFETCH_DIST */
+
+/*
+ * XXH3_accumulate()
+ * Loops over XXH3_accumulate_512().
+ * Assumption: nbStripes will not overflow the secret size
+ */
+XXH_FORCE_INLINE void
+XXH3_accumulate( xxh_u64* XXH_RESTRICT acc,
+ const xxh_u8* XXH_RESTRICT input,
+ const xxh_u8* XXH_RESTRICT secret,
+ size_t nbStripes,
+ XXH3_f_accumulate_512 f_acc512)
+{
+ size_t n;
+ for (n = 0; n < nbStripes; n++ ) {
+ const xxh_u8* const in = input + n*XXH_STRIPE_LEN;
+ XXH_PREFETCH(in + XXH_PREFETCH_DIST);
+ f_acc512(acc,
+ in,
+ secret + n*XXH_SECRET_CONSUME_RATE);
+ }
+}
+
+XXH_FORCE_INLINE void
+XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc,
+ const xxh_u8* XXH_RESTRICT input, size_t len,
+ const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
+ XXH3_f_accumulate_512 f_acc512,
+ XXH3_f_scrambleAcc f_scramble)
+{
+ size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE;
+ size_t const block_len = XXH_STRIPE_LEN * nbStripesPerBlock;
+ size_t const nb_blocks = (len - 1) / block_len;
+
+ size_t n;
+
+ XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
+
+ for (n = 0; n < nb_blocks; n++) {
+ XXH3_accumulate(acc, input + n*block_len, secret, nbStripesPerBlock, f_acc512);
+ f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN);
+ }
+
+ /* last partial block */
+ XXH_ASSERT(len > XXH_STRIPE_LEN);
+ { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN;
+ XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE));
+ XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, f_acc512);
+
+ /* last stripe */
+ { const xxh_u8* const p = input + len - XXH_STRIPE_LEN;
+#define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */
+ f_acc512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START);
+ } }
+}
+
+XXH_FORCE_INLINE xxh_u64
+XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret)
+{
+ return XXH3_mul128_fold64(
+ acc[0] ^ XXH_readLE64(secret),
+ acc[1] ^ XXH_readLE64(secret+8) );
+}
+
+static XXH64_hash_t
+XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start)
+{
+ xxh_u64 result64 = start;
+ size_t i = 0;
+
+ for (i = 0; i < 4; i++) {
+ result64 += XXH3_mix2Accs(acc+2*i, secret + 16*i);
+#if defined(__clang__) /* Clang */ \
+ && (defined(__arm__) || defined(__thumb__)) /* ARMv7 */ \
+ && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \
+ && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */
+ /*
+ * UGLY HACK:
+ * Prevent autovectorization on Clang ARMv7-a. Exact same problem as
+ * the one in XXH3_len_129to240_64b. Speeds up shorter keys > 240b.
+ * XXH3_64bits, len == 256, Snapdragon 835:
+ * without hack: 2063.7 MB/s
+ * with hack: 2560.7 MB/s
+ */
+ XXH_COMPILER_GUARD(result64);
+#endif
+ }
+
+ return XXH3_avalanche(result64);
+}
+
+#define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \
+ XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 }
+
+XXH_FORCE_INLINE XXH64_hash_t
+XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len,
+ const void* XXH_RESTRICT secret, size_t secretSize,
+ XXH3_f_accumulate_512 f_acc512,
+ XXH3_f_scrambleAcc f_scramble)
+{
+ XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
+
+ XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc512, f_scramble);
+
+ /* converge into final hash */
+ XXH_STATIC_ASSERT(sizeof(acc) == 64);
+ /* do not align on 8, so that the secret is different from the accumulator */
+#define XXH_SECRET_MERGEACCS_START 11
+ XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
+ return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1);
+}
+
+/*
+ * It's important for performance to transmit secret's size (when it's static)
+ * so that the compiler can properly optimize the vectorized loop.
+ * This makes a big performance difference for "medium" keys (<1 KB) when using AVX instruction set.
+ */
+XXH_FORCE_INLINE XXH64_hash_t
+XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len,
+ XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
+{
+ (void)seed64;
+ return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate_512, XXH3_scrambleAcc);
+}
+
+/*
+ * It's preferable for performance that XXH3_hashLong is not inlined,
+ * as it results in a smaller function for small data, easier to the instruction cache.
+ * Note that inside this no_inline function, we do inline the internal loop,
+ * and provide a statically defined secret size to allow optimization of vector loop.
+ */
+XXH_NO_INLINE XXH64_hash_t
+XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len,
+ XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
+{
+ (void)seed64; (void)secret; (void)secretLen;
+ return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate_512, XXH3_scrambleAcc);
+}
+
+/*
+ * XXH3_hashLong_64b_withSeed():
+ * Generate a custom key based on alteration of default XXH3_kSecret with the seed,
+ * and then use this key for long mode hashing.
+ *
+ * This operation is decently fast but nonetheless costs a little bit of time.
+ * Try to avoid it whenever possible (typically when seed==0).
+ *
+ * It's important for performance that XXH3_hashLong is not inlined. Not sure
+ * why (uop cache maybe?), but the difference is large and easily measurable.
+ */
+XXH_FORCE_INLINE XXH64_hash_t
+XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len,
+ XXH64_hash_t seed,
+ XXH3_f_accumulate_512 f_acc512,
+ XXH3_f_scrambleAcc f_scramble,
+ XXH3_f_initCustomSecret f_initSec)
+{
+ if (seed == 0)
+ return XXH3_hashLong_64b_internal(input, len,
+ XXH3_kSecret, sizeof(XXH3_kSecret),
+ f_acc512, f_scramble);
+ { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
+ f_initSec(secret, seed);
+ return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret),
+ f_acc512, f_scramble);
+ }
+}
+
+/*
+ * It's important for performance that XXH3_hashLong is not inlined.
+ */
+XXH_NO_INLINE XXH64_hash_t
+XXH3_hashLong_64b_withSeed(const void* input, size_t len,
+ XXH64_hash_t seed, const xxh_u8* secret, size_t secretLen)
+{
+ (void)secret; (void)secretLen;
+ return XXH3_hashLong_64b_withSeed_internal(input, len, seed,
+ XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret);
+}
+
+
+typedef XXH64_hash_t (*XXH3_hashLong64_f)(const void* XXH_RESTRICT, size_t,
+ XXH64_hash_t, const xxh_u8* XXH_RESTRICT, size_t);
+
+XXH_FORCE_INLINE XXH64_hash_t
+XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len,
+ XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen,
+ XXH3_hashLong64_f f_hashLong)
+{
+ XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN);
+ /*
+ * If an action is to be taken if `secretLen` condition is not respected,
+ * it should be done here.
+ * For now, it's a contract pre-condition.
+ * Adding a check and a branch here would cost performance at every hash.
+ * Also, note that function signature doesn't offer room to return an error.
+ */
+ if (len <= 16)
+ return XXH3_len_0to16_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64);
+ if (len <= 128)
+ return XXH3_len_17to128_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
+ if (len <= XXH3_MIDSIZE_MAX)
+ return XXH3_len_129to240_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
+ return f_hashLong(input, len, seed64, (const xxh_u8*)secret, secretLen);
+}
+
+
+/* === Public entry point === */
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len)
+{
+ return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH64_hash_t
+XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
+{
+ return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH64_hash_t
+XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
+{
+ return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed);
+}
+
+XXH_PUBLIC_API XXH64_hash_t
+XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
+{
+ if (len <= XXH3_MIDSIZE_MAX)
+ return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
+ return XXH3_hashLong_64b_withSecret(input, len, seed, (const xxh_u8*)secret, secretSize);
+}
+
+
+/* === XXH3 streaming === */
+
+/*
+ * Malloc's a pointer that is always aligned to align.
+ *
+ * This must be freed with `XXH_alignedFree()`.
+ *
+ * malloc typically guarantees 16 byte alignment on 64-bit systems and 8 byte
+ * alignment on 32-bit. This isn't enough for the 32 byte aligned loads in AVX2
+ * or on 32-bit, the 16 byte aligned loads in SSE2 and NEON.
+ *
+ * This underalignment previously caused a rather obvious crash which went
+ * completely unnoticed due to XXH3_createState() not actually being tested.
+ * Credit to RedSpah for noticing this bug.
+ *
+ * The alignment is done manually: Functions like posix_memalign or _mm_malloc
+ * are avoided: To maintain portability, we would have to write a fallback
+ * like this anyways, and besides, testing for the existence of library
+ * functions without relying on external build tools is impossible.
+ *
+ * The method is simple: Overallocate, manually align, and store the offset
+ * to the original behind the returned pointer.
+ *
+ * Align must be a power of 2 and 8 <= align <= 128.
+ */
+static void* XXH_alignedMalloc(size_t s, size_t align)
+{
+ XXH_ASSERT(align <= 128 && align >= 8); /* range check */
+ XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */
+ XXH_ASSERT(s != 0 && s < (s + align)); /* empty/overflow */
+ { /* Overallocate to make room for manual realignment and an offset byte */
+ xxh_u8* base = (xxh_u8*)XXH_malloc(s + align);
+ if (base != NULL) {
+ /*
+ * Get the offset needed to align this pointer.
+ *
+ * Even if the returned pointer is aligned, there will always be
+ * at least one byte to store the offset to the original pointer.
+ */
+ size_t offset = align - ((size_t)base & (align - 1)); /* base % align */
+ /* Add the offset for the now-aligned pointer */
+ xxh_u8* ptr = base + offset;
+
+ XXH_ASSERT((size_t)ptr % align == 0);
+
+ /* Store the offset immediately before the returned pointer. */
+ ptr[-1] = (xxh_u8)offset;
+ return ptr;
+ }
+ return NULL;
+ }
+}
+/*
+ * Frees an aligned pointer allocated by XXH_alignedMalloc(). Don't pass
+ * normal malloc'd pointers, XXH_alignedMalloc has a specific data layout.
+ */
+static void XXH_alignedFree(void* p)
+{
+ if (p != NULL) {
+ xxh_u8* ptr = (xxh_u8*)p;
+ /* Get the offset byte we added in XXH_malloc. */
+ xxh_u8 offset = ptr[-1];
+ /* Free the original malloc'd pointer */
+ xxh_u8* base = ptr - offset;
+ XXH_free(base);
+ }
+}
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
+{
+ XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64);
+ if (state==NULL) return NULL;
+ XXH3_INITSTATE(state);
+ return state;
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr)
+{
+ XXH_alignedFree(statePtr);
+ return XXH_OK;
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API void
+XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state)
+{
+ XXH_memcpy(dst_state, src_state, sizeof(*dst_state));
+}
+
+static void
+XXH3_reset_internal(XXH3_state_t* statePtr,
+ XXH64_hash_t seed,
+ const void* secret, size_t secretSize)
+{
+ size_t const initStart = offsetof(XXH3_state_t, bufferedSize);
+ size_t const initLength = offsetof(XXH3_state_t, nbStripesPerBlock) - initStart;
+ XXH_ASSERT(offsetof(XXH3_state_t, nbStripesPerBlock) > initStart);
+ XXH_ASSERT(statePtr != NULL);
+ /* set members from bufferedSize to nbStripesPerBlock (excluded) to 0 */
+ memset((char*)statePtr + initStart, 0, initLength);
+ statePtr->acc[0] = XXH_PRIME32_3;
+ statePtr->acc[1] = XXH_PRIME64_1;
+ statePtr->acc[2] = XXH_PRIME64_2;
+ statePtr->acc[3] = XXH_PRIME64_3;
+ statePtr->acc[4] = XXH_PRIME64_4;
+ statePtr->acc[5] = XXH_PRIME32_2;
+ statePtr->acc[6] = XXH_PRIME64_5;
+ statePtr->acc[7] = XXH_PRIME32_1;
+ statePtr->seed = seed;
+ statePtr->useSeed = (seed != 0);
+ statePtr->extSecret = (const unsigned char*)secret;
+ XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
+ statePtr->secretLimit = secretSize - XXH_STRIPE_LEN;
+ statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE;
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_64bits_reset(XXH3_state_t* statePtr)
+{
+ if (statePtr == NULL) return XXH_ERROR;
+ XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE);
+ return XXH_OK;
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
+{
+ if (statePtr == NULL) return XXH_ERROR;
+ XXH3_reset_internal(statePtr, 0, secret, secretSize);
+ if (secret == NULL) return XXH_ERROR;
+ if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
+ return XXH_OK;
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
+{
+ if (statePtr == NULL) return XXH_ERROR;
+ if (seed==0) return XXH3_64bits_reset(statePtr);
+ if ((seed != statePtr->seed) || (statePtr->extSecret != NULL))
+ XXH3_initCustomSecret(statePtr->customSecret, seed);
+ XXH3_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE);
+ return XXH_OK;
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64)
+{
+ if (statePtr == NULL) return XXH_ERROR;
+ if (secret == NULL) return XXH_ERROR;
+ if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
+ XXH3_reset_internal(statePtr, seed64, secret, secretSize);
+ statePtr->useSeed = 1; /* always, even if seed64==0 */
+ return XXH_OK;
+}
+
+/* Note : when XXH3_consumeStripes() is invoked,
+ * there must be a guarantee that at least one more byte must be consumed from input
+ * so that the function can blindly consume all stripes using the "normal" secret segment */
+XXH_FORCE_INLINE void
+XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc,
+ size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock,
+ const xxh_u8* XXH_RESTRICT input, size_t nbStripes,
+ const xxh_u8* XXH_RESTRICT secret, size_t secretLimit,
+ XXH3_f_accumulate_512 f_acc512,
+ XXH3_f_scrambleAcc f_scramble)
+{
+ XXH_ASSERT(nbStripes <= nbStripesPerBlock); /* can handle max 1 scramble per invocation */
+ XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock);
+ if (nbStripesPerBlock - *nbStripesSoFarPtr <= nbStripes) {
+ /* need a scrambling operation */
+ size_t const nbStripesToEndofBlock = nbStripesPerBlock - *nbStripesSoFarPtr;
+ size_t const nbStripesAfterBlock = nbStripes - nbStripesToEndofBlock;
+ XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripesToEndofBlock, f_acc512);
+ f_scramble(acc, secret + secretLimit);
+ XXH3_accumulate(acc, input + nbStripesToEndofBlock * XXH_STRIPE_LEN, secret, nbStripesAfterBlock, f_acc512);
+ *nbStripesSoFarPtr = nbStripesAfterBlock;
+ } else {
+ XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, f_acc512);
+ *nbStripesSoFarPtr += nbStripes;
+ }
+}
+
+#ifndef XXH3_STREAM_USE_STACK
+# ifndef __clang__ /* clang doesn't need additional stack space */
+# define XXH3_STREAM_USE_STACK 1
+# endif
+#endif
+/*
+ * Both XXH3_64bits_update and XXH3_128bits_update use this routine.
+ */
+XXH_FORCE_INLINE XXH_errorcode
+XXH3_update(XXH3_state_t* XXH_RESTRICT const state,
+ const xxh_u8* XXH_RESTRICT input, size_t len,
+ XXH3_f_accumulate_512 f_acc512,
+ XXH3_f_scrambleAcc f_scramble)
+{
+ if (input==NULL) {
+ XXH_ASSERT(len == 0);
+ return XXH_OK;
+ }
+
+ XXH_ASSERT(state != NULL);
+ { const xxh_u8* const bEnd = input + len;
+ const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
+#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
+ /* For some reason, gcc and MSVC seem to suffer greatly
+ * when operating accumulators directly into state.
+ * Operating into stack space seems to enable proper optimization.
+ * clang, on the other hand, doesn't seem to need this trick */
+ XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; memcpy(acc, state->acc, sizeof(acc));
+#else
+ xxh_u64* XXH_RESTRICT const acc = state->acc;
+#endif
+ state->totalLen += len;
+ XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE);
+
+ /* small input : just fill in tmp buffer */
+ if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) {
+ XXH_memcpy(state->buffer + state->bufferedSize, input, len);
+ state->bufferedSize += (XXH32_hash_t)len;
+ return XXH_OK;
+ }
+
+ /* total input is now > XXH3_INTERNALBUFFER_SIZE */
+ #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN)
+ XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0); /* clean multiple */
+
+ /*
+ * Internal buffer is partially filled (always, except at beginning)
+ * Complete it, then consume it.
+ */
+ if (state->bufferedSize) {
+ size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize;
+ XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize);
+ input += loadSize;
+ XXH3_consumeStripes(acc,
+ &state->nbStripesSoFar, state->nbStripesPerBlock,
+ state->buffer, XXH3_INTERNALBUFFER_STRIPES,
+ secret, state->secretLimit,
+ f_acc512, f_scramble);
+ state->bufferedSize = 0;
+ }
+ XXH_ASSERT(input < bEnd);
+
+ /* large input to consume : ingest per full block */
+ if ((size_t)(bEnd - input) > state->nbStripesPerBlock * XXH_STRIPE_LEN) {
+ size_t nbStripes = (size_t)(bEnd - 1 - input) / XXH_STRIPE_LEN;
+ XXH_ASSERT(state->nbStripesPerBlock >= state->nbStripesSoFar);
+ /* join to current block's end */
+ { size_t const nbStripesToEnd = state->nbStripesPerBlock - state->nbStripesSoFar;
+ XXH_ASSERT(nbStripesToEnd <= nbStripes);
+ XXH3_accumulate(acc, input, secret + state->nbStripesSoFar * XXH_SECRET_CONSUME_RATE, nbStripesToEnd, f_acc512);
+ f_scramble(acc, secret + state->secretLimit);
+ state->nbStripesSoFar = 0;
+ input += nbStripesToEnd * XXH_STRIPE_LEN;
+ nbStripes -= nbStripesToEnd;
+ }
+ /* consume per entire blocks */
+ while(nbStripes >= state->nbStripesPerBlock) {
+ XXH3_accumulate(acc, input, secret, state->nbStripesPerBlock, f_acc512);
+ f_scramble(acc, secret + state->secretLimit);
+ input += state->nbStripesPerBlock * XXH_STRIPE_LEN;
+ nbStripes -= state->nbStripesPerBlock;
+ }
+ /* consume last partial block */
+ XXH3_accumulate(acc, input, secret, nbStripes, f_acc512);
+ input += nbStripes * XXH_STRIPE_LEN;
+ XXH_ASSERT(input < bEnd); /* at least some bytes left */
+ state->nbStripesSoFar = nbStripes;
+ /* buffer predecessor of last partial stripe */
+ XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
+ XXH_ASSERT(bEnd - input <= XXH_STRIPE_LEN);
+ } else {
+ /* content to consume <= block size */
+ /* Consume input by a multiple of internal buffer size */
+ if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) {
+ const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE;
+ do {
+ XXH3_consumeStripes(acc,
+ &state->nbStripesSoFar, state->nbStripesPerBlock,
+ input, XXH3_INTERNALBUFFER_STRIPES,
+ secret, state->secretLimit,
+ f_acc512, f_scramble);
+ input += XXH3_INTERNALBUFFER_SIZE;
+ } while (input<limit);
+ /* buffer predecessor of last partial stripe */
+ XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
+ }
+ }
+
+ /* Some remaining input (always) : buffer it */
+ XXH_ASSERT(input < bEnd);
+ XXH_ASSERT(bEnd - input <= XXH3_INTERNALBUFFER_SIZE);
+ XXH_ASSERT(state->bufferedSize == 0);
+ XXH_memcpy(state->buffer, input, (size_t)(bEnd-input));
+ state->bufferedSize = (XXH32_hash_t)(bEnd-input);
+#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
+ /* save stack accumulators into state */
+ memcpy(state->acc, acc, sizeof(acc));
+#endif
+ }
+
+ return XXH_OK;
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len)
+{
+ return XXH3_update(state, (const xxh_u8*)input, len,
+ XXH3_accumulate_512, XXH3_scrambleAcc);
+}
+
+
+XXH_FORCE_INLINE void
+XXH3_digest_long (XXH64_hash_t* acc,
+ const XXH3_state_t* state,
+ const unsigned char* secret)
+{
+ /*
+ * Digest on a local copy. This way, the state remains unaltered, and it can
+ * continue ingesting more input afterwards.
+ */
+ XXH_memcpy(acc, state->acc, sizeof(state->acc));
+ if (state->bufferedSize >= XXH_STRIPE_LEN) {
+ size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN;
+ size_t nbStripesSoFar = state->nbStripesSoFar;
+ XXH3_consumeStripes(acc,
+ &nbStripesSoFar, state->nbStripesPerBlock,
+ state->buffer, nbStripes,
+ secret, state->secretLimit,
+ XXH3_accumulate_512, XXH3_scrambleAcc);
+ /* last stripe */
+ XXH3_accumulate_512(acc,
+ state->buffer + state->bufferedSize - XXH_STRIPE_LEN,
+ secret + state->secretLimit - XXH_SECRET_LASTACC_START);
+ } else { /* bufferedSize < XXH_STRIPE_LEN */
+ xxh_u8 lastStripe[XXH_STRIPE_LEN];
+ size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize;
+ XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */
+ XXH_memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize);
+ XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize);
+ XXH3_accumulate_512(acc,
+ lastStripe,
+ secret + state->secretLimit - XXH_SECRET_LASTACC_START);
+ }
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
+{
+ const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
+ if (state->totalLen > XXH3_MIDSIZE_MAX) {
+ XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
+ XXH3_digest_long(acc, state, secret);
+ return XXH3_mergeAccs(acc,
+ secret + XXH_SECRET_MERGEACCS_START,
+ (xxh_u64)state->totalLen * XXH_PRIME64_1);
+ }
+ /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */
+ if (state->useSeed)
+ return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
+ return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen),
+ secret, state->secretLimit + XXH_STRIPE_LEN);
+}
+
+
+
+/* ==========================================
+ * XXH3 128 bits (a.k.a XXH128)
+ * ==========================================
+ * XXH3's 128-bit variant has better mixing and strength than the 64-bit variant,
+ * even without counting the significantly larger output size.
+ *
+ * For example, extra steps are taken to avoid the seed-dependent collisions
+ * in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B).
+ *
+ * This strength naturally comes at the cost of some speed, especially on short
+ * lengths. Note that longer hashes are about as fast as the 64-bit version
+ * due to it using only a slight modification of the 64-bit loop.
+ *
+ * XXH128 is also more oriented towards 64-bit machines. It is still extremely
+ * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64).
+ */
+
+XXH_FORCE_INLINE XXH128_hash_t
+XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
+{
+ /* A doubled version of 1to3_64b with different constants. */
+ XXH_ASSERT(input != NULL);
+ XXH_ASSERT(1 <= len && len <= 3);
+ XXH_ASSERT(secret != NULL);
+ /*
+ * len = 1: combinedl = { input[0], 0x01, input[0], input[0] }
+ * len = 2: combinedl = { input[1], 0x02, input[0], input[1] }
+ * len = 3: combinedl = { input[2], 0x03, input[0], input[1] }
+ */
+ { xxh_u8 const c1 = input[0];
+ xxh_u8 const c2 = input[len >> 1];
+ xxh_u8 const c3 = input[len - 1];
+ xxh_u32 const combinedl = ((xxh_u32)c1 <<16) | ((xxh_u32)c2 << 24)
+ | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
+ xxh_u32 const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13);
+ xxh_u64 const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
+ xxh_u64 const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed;
+ xxh_u64 const keyed_lo = (xxh_u64)combinedl ^ bitflipl;
+ xxh_u64 const keyed_hi = (xxh_u64)combinedh ^ bitfliph;
+ XXH128_hash_t h128;
+ h128.low64 = XXH64_avalanche(keyed_lo);
+ h128.high64 = XXH64_avalanche(keyed_hi);
+ return h128;
+ }
+}
+
+XXH_FORCE_INLINE XXH128_hash_t
+XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
+{
+ XXH_ASSERT(input != NULL);
+ XXH_ASSERT(secret != NULL);
+ XXH_ASSERT(4 <= len && len <= 8);
+ seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
+ { xxh_u32 const input_lo = XXH_readLE32(input);
+ xxh_u32 const input_hi = XXH_readLE32(input + len - 4);
+ xxh_u64 const input_64 = input_lo + ((xxh_u64)input_hi << 32);
+ xxh_u64 const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed;
+ xxh_u64 const keyed = input_64 ^ bitflip;
+
+ /* Shift len to the left to ensure it is even, this avoids even multiplies. */
+ XXH128_hash_t m128 = XXH_mult64to128(keyed, XXH_PRIME64_1 + (len << 2));
+
+ m128.high64 += (m128.low64 << 1);
+ m128.low64 ^= (m128.high64 >> 3);
+
+ m128.low64 = XXH_xorshift64(m128.low64, 35);
+ m128.low64 *= 0x9FB21C651E98DF25ULL;
+ m128.low64 = XXH_xorshift64(m128.low64, 28);
+ m128.high64 = XXH3_avalanche(m128.high64);
+ return m128;
+ }
+}
+
+XXH_FORCE_INLINE XXH128_hash_t
+XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
+{
+ XXH_ASSERT(input != NULL);
+ XXH_ASSERT(secret != NULL);
+ XXH_ASSERT(9 <= len && len <= 16);
+ { xxh_u64 const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed;
+ xxh_u64 const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed;
+ xxh_u64 const input_lo = XXH_readLE64(input);
+ xxh_u64 input_hi = XXH_readLE64(input + len - 8);
+ XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, XXH_PRIME64_1);
+ /*
+ * Put len in the middle of m128 to ensure that the length gets mixed to
+ * both the low and high bits in the 128x64 multiply below.
+ */
+ m128.low64 += (xxh_u64)(len - 1) << 54;
+ input_hi ^= bitfliph;
+ /*
+ * Add the high 32 bits of input_hi to the high 32 bits of m128, then
+ * add the long product of the low 32 bits of input_hi and XXH_PRIME32_2 to
+ * the high 64 bits of m128.
+ *
+ * The best approach to this operation is different on 32-bit and 64-bit.
+ */
+ if (sizeof(void *) < sizeof(xxh_u64)) { /* 32-bit */
+ /*
+ * 32-bit optimized version, which is more readable.
+ *
+ * On 32-bit, it removes an ADC and delays a dependency between the two
+ * halves of m128.high64, but it generates an extra mask on 64-bit.
+ */
+ m128.high64 += (input_hi & 0xFFFFFFFF00000000ULL) + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2);
+ } else {
+ /*
+ * 64-bit optimized (albeit more confusing) version.
+ *
+ * Uses some properties of addition and multiplication to remove the mask:
+ *
+ * Let:
+ * a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF)
+ * b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000)
+ * c = XXH_PRIME32_2
+ *
+ * a + (b * c)
+ * Inverse Property: x + y - x == y
+ * a + (b * (1 + c - 1))
+ * Distributive Property: x * (y + z) == (x * y) + (x * z)
+ * a + (b * 1) + (b * (c - 1))
+ * Identity Property: x * 1 == x
+ * a + b + (b * (c - 1))
+ *
+ * Substitute a, b, and c:
+ * input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1))
+ *
+ * Since input_hi.hi + input_hi.lo == input_hi, we get this:
+ * input_hi + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1))
+ */
+ m128.high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2 - 1);
+ }
+ /* m128 ^= XXH_swap64(m128 >> 64); */
+ m128.low64 ^= XXH_swap64(m128.high64);
+
+ { /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */
+ XXH128_hash_t h128 = XXH_mult64to128(m128.low64, XXH_PRIME64_2);
+ h128.high64 += m128.high64 * XXH_PRIME64_2;
+
+ h128.low64 = XXH3_avalanche(h128.low64);
+ h128.high64 = XXH3_avalanche(h128.high64);
+ return h128;
+ } }
+}
+
+/*
+ * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN
+ */
+XXH_FORCE_INLINE XXH128_hash_t
+XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
+{
+ XXH_ASSERT(len <= 16);
+ { if (len > 8) return XXH3_len_9to16_128b(input, len, secret, seed);
+ if (len >= 4) return XXH3_len_4to8_128b(input, len, secret, seed);
+ if (len) return XXH3_len_1to3_128b(input, len, secret, seed);
+ { XXH128_hash_t h128;
+ xxh_u64 const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72);
+ xxh_u64 const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88);
+ h128.low64 = XXH64_avalanche(seed ^ bitflipl);
+ h128.high64 = XXH64_avalanche( seed ^ bitfliph);
+ return h128;
+ } }
+}
+
+/*
+ * A bit slower than XXH3_mix16B, but handles multiply by zero better.
+ */
+XXH_FORCE_INLINE XXH128_hash_t
+XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2,
+ const xxh_u8* secret, XXH64_hash_t seed)
+{
+ acc.low64 += XXH3_mix16B (input_1, secret+0, seed);
+ acc.low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8);
+ acc.high64 += XXH3_mix16B (input_2, secret+16, seed);
+ acc.high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8);
+ return acc;
+}
+
+
+XXH_FORCE_INLINE XXH128_hash_t
+XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
+ const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
+ XXH64_hash_t seed)
+{
+ XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
+ XXH_ASSERT(16 < len && len <= 128);
+
+ { XXH128_hash_t acc;
+ acc.low64 = len * XXH_PRIME64_1;
+ acc.high64 = 0;
+ if (len > 32) {
+ if (len > 64) {
+ if (len > 96) {
+ acc = XXH128_mix32B(acc, input+48, input+len-64, secret+96, seed);
+ }
+ acc = XXH128_mix32B(acc, input+32, input+len-48, secret+64, seed);
+ }
+ acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed);
+ }
+ acc = XXH128_mix32B(acc, input, input+len-16, secret, seed);
+ { XXH128_hash_t h128;
+ h128.low64 = acc.low64 + acc.high64;
+ h128.high64 = (acc.low64 * XXH_PRIME64_1)
+ + (acc.high64 * XXH_PRIME64_4)
+ + ((len - seed) * XXH_PRIME64_2);
+ h128.low64 = XXH3_avalanche(h128.low64);
+ h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64);
+ return h128;
+ }
+ }
+}
+
+XXH_NO_INLINE XXH128_hash_t
+XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
+ const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
+ XXH64_hash_t seed)
+{
+ XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
+ XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
+
+ { XXH128_hash_t acc;
+ int const nbRounds = (int)len / 32;
+ int i;
+ acc.low64 = len * XXH_PRIME64_1;
+ acc.high64 = 0;
+ for (i=0; i<4; i++) {
+ acc = XXH128_mix32B(acc,
+ input + (32 * i),
+ input + (32 * i) + 16,
+ secret + (32 * i),
+ seed);
+ }
+ acc.low64 = XXH3_avalanche(acc.low64);
+ acc.high64 = XXH3_avalanche(acc.high64);
+ XXH_ASSERT(nbRounds >= 4);
+ for (i=4 ; i < nbRounds; i++) {
+ acc = XXH128_mix32B(acc,
+ input + (32 * i),
+ input + (32 * i) + 16,
+ secret + XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)),
+ seed);
+ }
+ /* last bytes */
+ acc = XXH128_mix32B(acc,
+ input + len - 16,
+ input + len - 32,
+ secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16,
+ 0ULL - seed);
+
+ { XXH128_hash_t h128;
+ h128.low64 = acc.low64 + acc.high64;
+ h128.high64 = (acc.low64 * XXH_PRIME64_1)
+ + (acc.high64 * XXH_PRIME64_4)
+ + ((len - seed) * XXH_PRIME64_2);
+ h128.low64 = XXH3_avalanche(h128.low64);
+ h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64);
+ return h128;
+ }
+ }
+}
+
+XXH_FORCE_INLINE XXH128_hash_t
+XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len,
+ const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
+ XXH3_f_accumulate_512 f_acc512,
+ XXH3_f_scrambleAcc f_scramble)
+{
+ XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
+
+ XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc512, f_scramble);
+
+ /* converge into final hash */
+ XXH_STATIC_ASSERT(sizeof(acc) == 64);
+ XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
+ { XXH128_hash_t h128;
+ h128.low64 = XXH3_mergeAccs(acc,
+ secret + XXH_SECRET_MERGEACCS_START,
+ (xxh_u64)len * XXH_PRIME64_1);
+ h128.high64 = XXH3_mergeAccs(acc,
+ secret + secretSize
+ - sizeof(acc) - XXH_SECRET_MERGEACCS_START,
+ ~((xxh_u64)len * XXH_PRIME64_2));
+ return h128;
+ }
+}
+
+/*
+ * It's important for performance that XXH3_hashLong is not inlined.
+ */
+XXH_NO_INLINE XXH128_hash_t
+XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len,
+ XXH64_hash_t seed64,
+ const void* XXH_RESTRICT secret, size_t secretLen)
+{
+ (void)seed64; (void)secret; (void)secretLen;
+ return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret),
+ XXH3_accumulate_512, XXH3_scrambleAcc);
+}
+
+/*
+ * It's important for performance to pass @secretLen (when it's static)
+ * to the compiler, so that it can properly optimize the vectorized loop.
+ */
+XXH_FORCE_INLINE XXH128_hash_t
+XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len,
+ XXH64_hash_t seed64,
+ const void* XXH_RESTRICT secret, size_t secretLen)
+{
+ (void)seed64;
+ return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen,
+ XXH3_accumulate_512, XXH3_scrambleAcc);
+}
+
+XXH_FORCE_INLINE XXH128_hash_t
+XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len,
+ XXH64_hash_t seed64,
+ XXH3_f_accumulate_512 f_acc512,
+ XXH3_f_scrambleAcc f_scramble,
+ XXH3_f_initCustomSecret f_initSec)
+{
+ if (seed64 == 0)
+ return XXH3_hashLong_128b_internal(input, len,
+ XXH3_kSecret, sizeof(XXH3_kSecret),
+ f_acc512, f_scramble);
+ { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
+ f_initSec(secret, seed64);
+ return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret),
+ f_acc512, f_scramble);
+ }
+}
+
+/*
+ * It's important for performance that XXH3_hashLong is not inlined.
+ */
+XXH_NO_INLINE XXH128_hash_t
+XXH3_hashLong_128b_withSeed(const void* input, size_t len,
+ XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen)
+{
+ (void)secret; (void)secretLen;
+ return XXH3_hashLong_128b_withSeed_internal(input, len, seed64,
+ XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret);
+}
+
+typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t,
+ XXH64_hash_t, const void* XXH_RESTRICT, size_t);
+
+XXH_FORCE_INLINE XXH128_hash_t
+XXH3_128bits_internal(const void* input, size_t len,
+ XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen,
+ XXH3_hashLong128_f f_hl128)
+{
+ XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN);
+ /*
+ * If an action is to be taken if `secret` conditions are not respected,
+ * it should be done here.
+ * For now, it's a contract pre-condition.
+ * Adding a check and a branch here would cost performance at every hash.
+ */
+ if (len <= 16)
+ return XXH3_len_0to16_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64);
+ if (len <= 128)
+ return XXH3_len_17to128_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
+ if (len <= XXH3_MIDSIZE_MAX)
+ return XXH3_len_129to240_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
+ return f_hl128(input, len, seed64, secret, secretLen);
+}
+
+
+/* === Public XXH128 API === */
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len)
+{
+ return XXH3_128bits_internal(input, len, 0,
+ XXH3_kSecret, sizeof(XXH3_kSecret),
+ XXH3_hashLong_128b_default);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH128_hash_t
+XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
+{
+ return XXH3_128bits_internal(input, len, 0,
+ (const xxh_u8*)secret, secretSize,
+ XXH3_hashLong_128b_withSecret);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH128_hash_t
+XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
+{
+ return XXH3_128bits_internal(input, len, seed,
+ XXH3_kSecret, sizeof(XXH3_kSecret),
+ XXH3_hashLong_128b_withSeed);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH128_hash_t
+XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
+{
+ if (len <= XXH3_MIDSIZE_MAX)
+ return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
+ return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH128_hash_t
+XXH128(const void* input, size_t len, XXH64_hash_t seed)
+{
+ return XXH3_128bits_withSeed(input, len, seed);
+}
+
+
+/* === XXH3 128-bit streaming === */
+
+/*
+ * All initialization and update functions are identical to 64-bit streaming variant.
+ * The only difference is the finalization routine.
+ */
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_128bits_reset(XXH3_state_t* statePtr)
+{
+ return XXH3_64bits_reset(statePtr);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
+{
+ return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
+{
+ return XXH3_64bits_reset_withSeed(statePtr, seed);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed)
+{
+ return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len)
+{
+ return XXH3_update(state, (const xxh_u8*)input, len,
+ XXH3_accumulate_512, XXH3_scrambleAcc);
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state)
+{
+ const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
+ if (state->totalLen > XXH3_MIDSIZE_MAX) {
+ XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
+ XXH3_digest_long(acc, state, secret);
+ XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
+ { XXH128_hash_t h128;
+ h128.low64 = XXH3_mergeAccs(acc,
+ secret + XXH_SECRET_MERGEACCS_START,
+ (xxh_u64)state->totalLen * XXH_PRIME64_1);
+ h128.high64 = XXH3_mergeAccs(acc,
+ secret + state->secretLimit + XXH_STRIPE_LEN
+ - sizeof(acc) - XXH_SECRET_MERGEACCS_START,
+ ~((xxh_u64)state->totalLen * XXH_PRIME64_2));
+ return h128;
+ }
+ }
+ /* len <= XXH3_MIDSIZE_MAX : short code */
+ if (state->seed)
+ return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
+ return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen),
+ secret, state->secretLimit + XXH_STRIPE_LEN);
+}
+
+/* 128-bit utility functions */
+
+#include <string.h> /* memcmp, memcpy */
+
+/* return : 1 is equal, 0 if different */
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
+{
+ /* note : XXH128_hash_t is compact, it has no padding byte */
+ return !(memcmp(&h1, &h2, sizeof(h1)));
+}
+
+/* This prototype is compatible with stdlib's qsort().
+ * return : >0 if *h128_1 > *h128_2
+ * <0 if *h128_1 < *h128_2
+ * =0 if *h128_1 == *h128_2 */
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2)
+{
+ XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1;
+ XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2;
+ int const hcmp = (h1.high64 > h2.high64) - (h2.high64 > h1.high64);
+ /* note : bets that, in most cases, hash values are different */
+ if (hcmp) return hcmp;
+ return (h1.low64 > h2.low64) - (h2.low64 > h1.low64);
+}
+
+
+/*====== Canonical representation ======*/
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API void
+XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash)
+{
+ XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t));
+ if (XXH_CPU_LITTLE_ENDIAN) {
+ hash.high64 = XXH_swap64(hash.high64);
+ hash.low64 = XXH_swap64(hash.low64);
+ }
+ XXH_memcpy(dst, &hash.high64, sizeof(hash.high64));
+ XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64));
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH128_hash_t
+XXH128_hashFromCanonical(const XXH128_canonical_t* src)
+{
+ XXH128_hash_t h;
+ h.high64 = XXH_readBE64(src);
+ h.low64 = XXH_readBE64(src->digest + 8);
+ return h;
+}
+
+
+
+/* ==========================================
+ * Secret generators
+ * ==========================================
+ */
+#define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x))
+
+XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128)
+{
+ XXH_writeLE64( dst, XXH_readLE64(dst) ^ h128.low64 );
+ XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 );
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API XXH_errorcode
+XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize)
+{
+#if (XXH_DEBUGLEVEL >= 1)
+ XXH_ASSERT(secretBuffer != NULL);
+ XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
+#else
+ /* production mode, assert() are disabled */
+ if (secretBuffer == NULL) return XXH_ERROR;
+ if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
+#endif
+
+ if (customSeedSize == 0) {
+ customSeed = XXH3_kSecret;
+ customSeedSize = XXH_SECRET_DEFAULT_SIZE;
+ }
+#if (XXH_DEBUGLEVEL >= 1)
+ XXH_ASSERT(customSeed != NULL);
+#else
+ if (customSeed == NULL) return XXH_ERROR;
+#endif
+
+ /* Fill secretBuffer with a copy of customSeed - repeat as needed */
+ { size_t pos = 0;
+ while (pos < secretSize) {
+ size_t const toCopy = XXH_MIN((secretSize - pos), customSeedSize);
+ memcpy((char*)secretBuffer + pos, customSeed, toCopy);
+ pos += toCopy;
+ } }
+
+ { size_t const nbSeg16 = secretSize / 16;
+ size_t n;
+ XXH128_canonical_t scrambler;
+ XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0));
+ for (n=0; n<nbSeg16; n++) {
+ XXH128_hash_t const h128 = XXH128(&scrambler, sizeof(scrambler), n);
+ XXH3_combine16((char*)secretBuffer + n*16, h128);
+ }
+ /* last segment */
+ XXH3_combine16((char*)secretBuffer + secretSize - 16, XXH128_hashFromCanonical(&scrambler));
+ }
+ return XXH_OK;
+}
+
+/*! @ingroup xxh3_family */
+XXH_PUBLIC_API void
+XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed)
+{
+ XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
+ XXH3_initCustomSecret(secret, seed);
+ XXH_ASSERT(secretBuffer != NULL);
+ memcpy(secretBuffer, secret, XXH_SECRET_DEFAULT_SIZE);
+}
+
+
+
+/* Pop our optimization override from above */
+#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
+ && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
+ && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
+# pragma GCC pop_options
+#endif
+
+#endif /* XXH_NO_LONG_LONG */
+
+#endif /* XXH_NO_XXH3 */
+
+/*!
+ * @}
+ */
+#endif /* XXH_IMPLEMENTATION */
#if defined (__cplusplus)
diff --git a/thirdparty/zstd/common/zstd_internal.h b/thirdparty/zstd/common/zstd_internal.h
index 68252e987e..e4d36ce090 100644
--- a/thirdparty/zstd/common/zstd_internal.h
+++ b/thirdparty/zstd/common/zstd_internal.h
@@ -19,10 +19,8 @@
/*-*************************************
* Dependencies
***************************************/
-#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON)
-#include <arm_neon.h>
-#endif
#include "compiler.h"
+#include "cpu.h"
#include "mem.h"
#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */
#include "error_private.h"
@@ -60,81 +58,7 @@ extern "C" {
#undef MAX
#define MIN(a,b) ((a)<(b) ? (a) : (b))
#define MAX(a,b) ((a)>(b) ? (a) : (b))
-
-/**
- * Ignore: this is an internal helper.
- *
- * This is a helper function to help force C99-correctness during compilation.
- * Under strict compilation modes, variadic macro arguments can't be empty.
- * However, variadic function arguments can be. Using a function therefore lets
- * us statically check that at least one (string) argument was passed,
- * independent of the compilation flags.
- */
-static INLINE_KEYWORD UNUSED_ATTR
-void _force_has_format_string(const char *format, ...) {
- (void)format;
-}
-
-/**
- * Ignore: this is an internal helper.
- *
- * We want to force this function invocation to be syntactically correct, but
- * we don't want to force runtime evaluation of its arguments.
- */
-#define _FORCE_HAS_FORMAT_STRING(...) \
- if (0) { \
- _force_has_format_string(__VA_ARGS__); \
- }
-
-/**
- * Return the specified error if the condition evaluates to true.
- *
- * In debug modes, prints additional information.
- * In order to do that (particularly, printing the conditional that failed),
- * this can't just wrap RETURN_ERROR().
- */
-#define RETURN_ERROR_IF(cond, err, ...) \
- if (cond) { \
- RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
- __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \
- _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
- RAWLOG(3, ": " __VA_ARGS__); \
- RAWLOG(3, "\n"); \
- return ERROR(err); \
- }
-
-/**
- * Unconditionally return the specified error.
- *
- * In debug modes, prints additional information.
- */
-#define RETURN_ERROR(err, ...) \
- do { \
- RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
- __FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \
- _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
- RAWLOG(3, ": " __VA_ARGS__); \
- RAWLOG(3, "\n"); \
- return ERROR(err); \
- } while(0);
-
-/**
- * If the provided expression evaluates to an error code, returns that error code.
- *
- * In debug modes, prints additional information.
- */
-#define FORWARD_IF_ERROR(err, ...) \
- do { \
- size_t const err_code = (err); \
- if (ERR_isError(err_code)) { \
- RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
- __FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \
- _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
- RAWLOG(3, ": " __VA_ARGS__); \
- RAWLOG(3, "\n"); \
- return err_code; \
- } \
- } while(0);
+#define BOUNDED(min,val,max) (MAX(min,MIN(val,max)))
/*-*************************************
@@ -143,7 +67,6 @@ void _force_has_format_string(const char *format, ...) {
#define ZSTD_OPT_NUM (1<<12)
#define ZSTD_REP_NUM 3 /* number of repcodes */
-#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
static UNUSED_ATTR const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
#define KB *(1 <<10)
@@ -195,7 +118,7 @@ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingTy
/* Each table cannot take more than #symbols * FSELog bits */
#define ZSTD_MAX_FSE_HEADERS_SIZE (((MaxML + 1) * MLFSELog + (MaxLL + 1) * LLFSELog + (MaxOff + 1) * OffFSELog + 7) / 8)
-static UNUSED_ATTR const U32 LL_bits[MaxLL+1] = {
+static UNUSED_ATTR const U8 LL_bits[MaxLL+1] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 3, 3,
@@ -212,7 +135,7 @@ static UNUSED_ATTR const S16 LL_defaultNorm[MaxLL+1] = {
#define LL_DEFAULTNORMLOG 6 /* for static allocation */
static UNUSED_ATTR const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
-static UNUSED_ATTR const U32 ML_bits[MaxML+1] = {
+static UNUSED_ATTR const U8 ML_bits[MaxML+1] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -247,19 +170,30 @@ static UNUSED_ATTR const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
* Shared functions to include for inlining
*********************************************/
static void ZSTD_copy8(void* dst, const void* src) {
-#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON)
+#if defined(ZSTD_ARCH_ARM_NEON)
vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
#else
ZSTD_memcpy(dst, src, 8);
#endif
}
-
#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
+
+/* Need to use memmove here since the literal buffer can now be located within
+ the dst buffer. In circumstances where the op "catches up" to where the
+ literal buffer is, there can be partial overlaps in this call on the final
+ copy if the literal is being shifted by less than 16 bytes. */
static void ZSTD_copy16(void* dst, const void* src) {
-#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON)
+#if defined(ZSTD_ARCH_ARM_NEON)
vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
+#elif defined(ZSTD_ARCH_X86_SSE2)
+ _mm_storeu_si128((__m128i*)dst, _mm_loadu_si128((const __m128i*)src));
+#elif defined(__clang__)
+ ZSTD_memmove(dst, src, 16);
#else
- ZSTD_memcpy(dst, src, 16);
+ /* ZSTD_memmove is not inlined properly by gcc */
+ BYTE copy16_buf[16];
+ ZSTD_memcpy(copy16_buf, src, 16);
+ ZSTD_memcpy(dst, copy16_buf, 16);
#endif
}
#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
@@ -288,8 +222,6 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e
BYTE* op = (BYTE*)dst;
BYTE* const oend = op + length;
- assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff <= -WILDCOPY_VECLEN));
-
if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {
/* Handle short offset copies. */
do {
@@ -352,9 +284,9 @@ typedef enum {
* Private declarations
*********************************************/
typedef struct seqDef_s {
- U32 offset; /* offset == rawOffset + ZSTD_REP_NUM, or equivalently, offCode + 1 */
+ U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */
U16 litLength;
- U16 matchLength;
+ U16 mlBase; /* mlBase == matchLength - MINMATCH */
} seqDef;
/* Controls whether seqStore has a single "long" litLength or matchLength. See seqStore_t. */
@@ -396,7 +328,7 @@ MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore
{
ZSTD_sequenceLength seqLen;
seqLen.litLength = seq->litLength;
- seqLen.matchLength = seq->matchLength + MINMATCH;
+ seqLen.matchLength = seq->mlBase + MINMATCH;
if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
if (seqStore->longLengthType == ZSTD_llt_literalLength) {
seqLen.litLength += 0xFFFF;
@@ -436,8 +368,14 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus
# if STATIC_BMI2 == 1
return _lzcnt_u32(val)^31;
# else
- unsigned long r=0;
- return _BitScanReverse(&r, val) ? (unsigned)r : 0;
+ if (val != 0) {
+ unsigned long r;
+ _BitScanReverse(&r, val);
+ return (unsigned)r;
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
# endif
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
return __builtin_clz (val) ^ 31;
@@ -456,6 +394,63 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus
}
}
+/**
+ * Counts the number of trailing zeros of a `size_t`.
+ * Most compilers should support CTZ as a builtin. A backup
+ * implementation is provided if the builtin isn't supported, but
+ * it may not be terribly efficient.
+ */
+MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val)
+{
+ if (MEM_64bits()) {
+# if defined(_MSC_VER) && defined(_WIN64)
+# if STATIC_BMI2
+ return _tzcnt_u64(val);
+# else
+ if (val != 0) {
+ unsigned long r;
+ _BitScanForward64(&r, (U64)val);
+ return (unsigned)r;
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
+# endif
+# elif defined(__GNUC__) && (__GNUC__ >= 4)
+ return __builtin_ctzll((U64)val);
+# else
+ static const int DeBruijnBytePos[64] = { 0, 1, 2, 7, 3, 13, 8, 19,
+ 4, 25, 14, 28, 9, 34, 20, 56,
+ 5, 17, 26, 54, 15, 41, 29, 43,
+ 10, 31, 38, 35, 21, 45, 49, 57,
+ 63, 6, 12, 18, 24, 27, 33, 55,
+ 16, 53, 40, 42, 30, 37, 44, 48,
+ 62, 11, 23, 32, 52, 39, 36, 47,
+ 61, 22, 51, 46, 60, 50, 59, 58 };
+ return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
+# endif
+ } else { /* 32 bits */
+# if defined(_MSC_VER)
+ if (val != 0) {
+ unsigned long r;
+ _BitScanForward(&r, (U32)val);
+ return (unsigned)r;
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
+# elif defined(__GNUC__) && (__GNUC__ >= 3)
+ return __builtin_ctz((U32)val);
+# else
+ static const int DeBruijnBytePos[32] = { 0, 1, 28, 2, 29, 14, 24, 3,
+ 30, 22, 20, 15, 25, 17, 4, 8,
+ 31, 27, 13, 23, 21, 19, 16, 7,
+ 26, 12, 18, 6, 11, 5, 10, 9 };
+ return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
+# endif
+ }
+}
+
/* ZSTD_invalidateRepCodes() :
* ensures next compression will not use repcodes from previous block.
@@ -482,6 +477,14 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
const void* src, size_t srcSize);
+/**
+ * @returns true iff the CPU supports dynamic BMI2 dispatch.
+ */
+MEM_STATIC int ZSTD_cpuSupportsBmi2(void)
+{
+ ZSTD_cpuid_t cpuid = ZSTD_cpuid();
+ return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid);
+}
#if defined (__cplusplus)
}
diff --git a/thirdparty/zstd/common/zstd_trace.h b/thirdparty/zstd/common/zstd_trace.h
index 2da5640771..f9121f7d8e 100644
--- a/thirdparty/zstd/common/zstd_trace.h
+++ b/thirdparty/zstd/common/zstd_trace.h
@@ -17,10 +17,19 @@ extern "C" {
#include <stddef.h>
-/* weak symbol support */
-#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && defined(__GNUC__) && \
+/* weak symbol support
+ * For now, enable conservatively:
+ * - Only GNUC
+ * - Only ELF
+ * - Only x86-64 and i386
+ * Also, explicitly disable on platforms known not to work so they aren't
+ * forgotten in the future.
+ */
+#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && \
+ defined(__GNUC__) && defined(__ELF__) && \
+ (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \
- !defined(__CYGWIN__)
+ !defined(__CYGWIN__) && !defined(_AIX)
# define ZSTD_HAVE_WEAK_SYMBOLS 1
#else
# define ZSTD_HAVE_WEAK_SYMBOLS 0
diff --git a/thirdparty/zstd/compress/clevels.h b/thirdparty/zstd/compress/clevels.h
new file mode 100644
index 0000000000..7ed2e00490
--- /dev/null
+++ b/thirdparty/zstd/compress/clevels.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+#ifndef ZSTD_CLEVELS_H
+#define ZSTD_CLEVELS_H
+
+#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */
+#include "../zstd.h"
+
+/*-===== Pre-defined compression levels =====-*/
+
+#define ZSTD_MAX_CLEVEL 22
+
+#ifdef __GNUC__
+__attribute__((__unused__))
+#endif
+
+static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
+{ /* "default" - for any srcSize > 256 KB */
+ /* W, C, H, S, L, TL, strat */
+ { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */
+ { 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */
+ { 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */
+ { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */
+ { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */
+ { 21, 18, 19, 3, 5, 2, ZSTD_greedy }, /* level 5 */
+ { 21, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6 */
+ { 21, 19, 20, 4, 5, 8, ZSTD_lazy }, /* level 7 */
+ { 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 8 */
+ { 22, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */
+ { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 10 */
+ { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 11 */
+ { 22, 22, 23, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */
+ { 22, 22, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */
+ { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */
+ { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */
+ { 22, 22, 22, 5, 5, 48, ZSTD_btopt }, /* level 16 */
+ { 23, 23, 22, 5, 4, 64, ZSTD_btopt }, /* level 17 */
+ { 23, 23, 22, 6, 3, 64, ZSTD_btultra }, /* level 18 */
+ { 23, 24, 22, 7, 3,256, ZSTD_btultra2}, /* level 19 */
+ { 25, 25, 23, 7, 3,256, ZSTD_btultra2}, /* level 20 */
+ { 26, 26, 24, 7, 3,512, ZSTD_btultra2}, /* level 21 */
+ { 27, 27, 25, 9, 3,999, ZSTD_btultra2}, /* level 22 */
+},
+{ /* for srcSize <= 256 KB */
+ /* W, C, H, S, L, T, strat */
+ { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
+ { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */
+ { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */
+ { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */
+ { 18, 16, 17, 3, 5, 2, ZSTD_greedy }, /* level 4.*/
+ { 18, 17, 18, 5, 5, 2, ZSTD_greedy }, /* level 5.*/
+ { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/
+ { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */
+ { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
+ { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
+ { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
+ { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/
+ { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/
+ { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */
+ { 18, 18, 19, 4, 3, 32, ZSTD_btopt }, /* level 14.*/
+ { 18, 18, 19, 6, 3,128, ZSTD_btopt }, /* level 15.*/
+ { 18, 19, 19, 6, 3,128, ZSTD_btultra }, /* level 16.*/
+ { 18, 19, 19, 8, 3,256, ZSTD_btultra }, /* level 17.*/
+ { 18, 19, 19, 6, 3,128, ZSTD_btultra2}, /* level 18.*/
+ { 18, 19, 19, 8, 3,256, ZSTD_btultra2}, /* level 19.*/
+ { 18, 19, 19, 10, 3,512, ZSTD_btultra2}, /* level 20.*/
+ { 18, 19, 19, 12, 3,512, ZSTD_btultra2}, /* level 21.*/
+ { 18, 19, 19, 13, 3,999, ZSTD_btultra2}, /* level 22.*/
+},
+{ /* for srcSize <= 128 KB */
+ /* W, C, H, S, L, T, strat */
+ { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
+ { 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */
+ { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */
+ { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */
+ { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */
+ { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */
+ { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */
+ { 17, 16, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */
+ { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
+ { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
+ { 17, 16, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
+ { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */
+ { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */
+ { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/
+ { 17, 18, 17, 4, 3, 32, ZSTD_btopt }, /* level 14.*/
+ { 17, 18, 17, 6, 3,256, ZSTD_btopt }, /* level 15.*/
+ { 17, 18, 17, 6, 3,128, ZSTD_btultra }, /* level 16.*/
+ { 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 17.*/
+ { 17, 18, 17, 10, 3,512, ZSTD_btultra }, /* level 18.*/
+ { 17, 18, 17, 5, 3,256, ZSTD_btultra2}, /* level 19.*/
+ { 17, 18, 17, 7, 3,512, ZSTD_btultra2}, /* level 20.*/
+ { 17, 18, 17, 9, 3,512, ZSTD_btultra2}, /* level 21.*/
+ { 17, 18, 17, 11, 3,999, ZSTD_btultra2}, /* level 22.*/
+},
+{ /* for srcSize <= 16 KB */
+ /* W, C, H, S, L, T, strat */
+ { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
+ { 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */
+ { 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */
+ { 14, 14, 15, 2, 4, 0, ZSTD_dfast }, /* level 3 */
+ { 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4 */
+ { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/
+ { 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */
+ { 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */
+ { 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/
+ { 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/
+ { 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/
+ { 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/
+ { 14, 15, 14, 4, 3, 24, ZSTD_btopt }, /* level 12.*/
+ { 14, 15, 14, 5, 3, 32, ZSTD_btultra }, /* level 13.*/
+ { 14, 15, 15, 6, 3, 64, ZSTD_btultra }, /* level 14.*/
+ { 14, 15, 15, 7, 3,256, ZSTD_btultra }, /* level 15.*/
+ { 14, 15, 15, 5, 3, 48, ZSTD_btultra2}, /* level 16.*/
+ { 14, 15, 15, 6, 3,128, ZSTD_btultra2}, /* level 17.*/
+ { 14, 15, 15, 7, 3,256, ZSTD_btultra2}, /* level 18.*/
+ { 14, 15, 15, 8, 3,256, ZSTD_btultra2}, /* level 19.*/
+ { 14, 15, 15, 8, 3,512, ZSTD_btultra2}, /* level 20.*/
+ { 14, 15, 15, 9, 3,512, ZSTD_btultra2}, /* level 21.*/
+ { 14, 15, 15, 10, 3,999, ZSTD_btultra2}, /* level 22.*/
+},
+};
+
+
+
+#endif /* ZSTD_CLEVELS_H */
diff --git a/thirdparty/zstd/compress/fse_compress.c b/thirdparty/zstd/compress/fse_compress.c
index b4297ec88a..5547b4ac09 100644
--- a/thirdparty/zstd/compress/fse_compress.c
+++ b/thirdparty/zstd/compress/fse_compress.c
@@ -75,13 +75,14 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
U32 const step = FSE_TABLESTEP(tableSize);
+ U32 const maxSV1 = maxSymbolValue+1;
- U32* cumul = (U32*)workSpace;
- FSE_FUNCTION_TYPE* tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSymbolValue + 2));
+ U16* cumul = (U16*)workSpace; /* size = maxSV1 */
+ FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSV1+1)); /* size = tableSize */
U32 highThreshold = tableSize-1;
- if ((size_t)workSpace & 3) return ERROR(GENERIC); /* Must be 4 byte aligned */
+ assert(((size_t)workSpace & 1) == 0); /* Must be 2 bytes-aligned */
if (FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) > wkspSize) return ERROR(tableLog_tooLarge);
/* CTable header */
tableU16[-2] = (U16) tableLog;
@@ -98,20 +99,61 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
/* symbol start positions */
{ U32 u;
cumul[0] = 0;
- for (u=1; u <= maxSymbolValue+1; u++) {
+ for (u=1; u <= maxSV1; u++) {
if (normalizedCounter[u-1]==-1) { /* Low proba symbol */
cumul[u] = cumul[u-1] + 1;
tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
} else {
- cumul[u] = cumul[u-1] + normalizedCounter[u-1];
+ assert(normalizedCounter[u-1] >= 0);
+ cumul[u] = cumul[u-1] + (U16)normalizedCounter[u-1];
+ assert(cumul[u] >= cumul[u-1]); /* no overflow */
} }
- cumul[maxSymbolValue+1] = tableSize+1;
+ cumul[maxSV1] = (U16)(tableSize+1);
}
/* Spread symbols */
- { U32 position = 0;
+ if (highThreshold == tableSize - 1) {
+ /* Case for no low prob count symbols. Lay down 8 bytes at a time
+ * to reduce branch misses since we are operating on a small block
+ */
+ BYTE* const spread = tableSymbol + tableSize; /* size = tableSize + 8 (may write beyond tableSize) */
+ { U64 const add = 0x0101010101010101ull;
+ size_t pos = 0;
+ U64 sv = 0;
+ U32 s;
+ for (s=0; s<maxSV1; ++s, sv += add) {
+ int i;
+ int const n = normalizedCounter[s];
+ MEM_write64(spread + pos, sv);
+ for (i = 8; i < n; i += 8) {
+ MEM_write64(spread + pos + i, sv);
+ }
+ assert(n>=0);
+ pos += (size_t)n;
+ }
+ }
+ /* Spread symbols across the table. Lack of lowprob symbols means that
+ * we don't need variable sized inner loop, so we can unroll the loop and
+ * reduce branch misses.
+ */
+ { size_t position = 0;
+ size_t s;
+ size_t const unroll = 2; /* Experimentally determined optimal unroll */
+ assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */
+ for (s = 0; s < (size_t)tableSize; s += unroll) {
+ size_t u;
+ for (u = 0; u < unroll; ++u) {
+ size_t const uPosition = (position + (u * step)) & tableMask;
+ tableSymbol[uPosition] = spread[s + u];
+ }
+ position = (position + (unroll * step)) & tableMask;
+ }
+ assert(position == 0); /* Must have initialized all positions */
+ }
+ } else {
+ U32 position = 0;
U32 symbol;
- for (symbol=0; symbol<=maxSymbolValue; symbol++) {
+ for (symbol=0; symbol<maxSV1; symbol++) {
int nbOccurrences;
int const freq = normalizedCounter[symbol];
for (nbOccurrences=0; nbOccurrences<freq; nbOccurrences++) {
@@ -120,7 +162,6 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
while (position > highThreshold)
position = (position + step) & tableMask; /* Low proba area */
} }
-
assert(position==0); /* Must have initialized all positions */
}
@@ -144,16 +185,17 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
case -1:
case 1:
symbolTT[s].deltaNbBits = (tableLog << 16) - (1<<tableLog);
- symbolTT[s].deltaFindState = total - 1;
+ assert(total <= INT_MAX);
+ symbolTT[s].deltaFindState = (int)(total - 1);
total ++;
break;
default :
- {
- U32 const maxBitsOut = tableLog - BIT_highbit32 (normalizedCounter[s]-1);
- U32 const minStatePlus = normalizedCounter[s] << maxBitsOut;
+ assert(normalizedCounter[s] > 1);
+ { U32 const maxBitsOut = tableLog - BIT_highbit32 ((U32)normalizedCounter[s]-1);
+ U32 const minStatePlus = (U32)normalizedCounter[s] << maxBitsOut;
symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;
- symbolTT[s].deltaFindState = total - normalizedCounter[s];
- total += normalizedCounter[s];
+ symbolTT[s].deltaFindState = (int)(total - (unsigned)normalizedCounter[s]);
+ total += (unsigned)normalizedCounter[s];
} } } }
#if 0 /* debug : symbol costs */
@@ -164,32 +206,26 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
symbol, normalizedCounter[symbol],
FSE_getMaxNbBits(symbolTT, symbol),
(double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256);
- }
- }
+ } }
#endif
return 0;
}
-#ifndef ZSTD_NO_UNUSED_FUNCTIONS
-size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
-{
- FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
- return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol));
-}
-#endif
-
#ifndef FSE_COMMONDEFS_ONLY
-
/*-**************************************************************
* FSE NCount encoding
****************************************************************/
size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
{
- size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
+ size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog
+ + 4 /* bitCount initialized at 4 */
+ + 2 /* first two symbols may use one additional bit each */) / 8)
+ + 1 /* round up to whole nb bytes */
+ + 2 /* additional two bytes for bitstream flush */;
return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
}
diff --git a/thirdparty/zstd/compress/huf_compress.c b/thirdparty/zstd/compress/huf_compress.c
index 485906e678..2b3d6adc2a 100644
--- a/thirdparty/zstd/compress/huf_compress.c
+++ b/thirdparty/zstd/compress/huf_compress.c
@@ -53,6 +53,28 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
/* *******************************************************
* HUF : Huffman block compression
*********************************************************/
+#define HUF_WORKSPACE_MAX_ALIGNMENT 8
+
+static void* HUF_alignUpWorkspace(void* workspace, size_t* workspaceSizePtr, size_t align)
+{
+ size_t const mask = align - 1;
+ size_t const rem = (size_t)workspace & mask;
+ size_t const add = (align - rem) & mask;
+ BYTE* const aligned = (BYTE*)workspace + add;
+ assert((align & (align - 1)) == 0); /* pow 2 */
+ assert(align <= HUF_WORKSPACE_MAX_ALIGNMENT);
+ if (*workspaceSizePtr >= add) {
+ assert(add < align);
+ assert(((size_t)aligned & mask) == 0);
+ *workspaceSizePtr -= add;
+ return aligned;
+ } else {
+ *workspaceSizePtr = 0;
+ return NULL;
+ }
+}
+
+
/* HUF_compressWeights() :
* Same as FSE_compress(), but dedicated to huff0's weights compression.
* The use case needs much less stack memory.
@@ -75,7 +97,7 @@ static size_t HUF_compressWeights(void* dst, size_t dstSize, const void* weightT
unsigned maxSymbolValue = HUF_TABLELOG_MAX;
U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
- HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)workspace;
+ HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32));
if (workspaceSize < sizeof(HUF_CompressWeightsWksp)) return ERROR(GENERIC);
@@ -106,6 +128,40 @@ static size_t HUF_compressWeights(void* dst, size_t dstSize, const void* weightT
return (size_t)(op-ostart);
}
+static size_t HUF_getNbBits(HUF_CElt elt)
+{
+ return elt & 0xFF;
+}
+
+static size_t HUF_getNbBitsFast(HUF_CElt elt)
+{
+ return elt;
+}
+
+static size_t HUF_getValue(HUF_CElt elt)
+{
+ return elt & ~0xFF;
+}
+
+static size_t HUF_getValueFast(HUF_CElt elt)
+{
+ return elt;
+}
+
+static void HUF_setNbBits(HUF_CElt* elt, size_t nbBits)
+{
+ assert(nbBits <= HUF_TABLELOG_ABSOLUTEMAX);
+ *elt = nbBits;
+}
+
+static void HUF_setValue(HUF_CElt* elt, size_t value)
+{
+ size_t const nbBits = HUF_getNbBits(*elt);
+ if (nbBits > 0) {
+ assert((value >> nbBits) == 0);
+ *elt |= value << (sizeof(HUF_CElt) * 8 - nbBits);
+ }
+}
typedef struct {
HUF_CompressWeightsWksp wksp;
@@ -117,9 +173,10 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize,
const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog,
void* workspace, size_t workspaceSize)
{
+ HUF_CElt const* const ct = CTable + 1;
BYTE* op = (BYTE*)dst;
U32 n;
- HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)workspace;
+ HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32));
/* check conditions */
if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC);
@@ -130,9 +187,10 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize,
for (n=1; n<huffLog+1; n++)
wksp->bitsToWeight[n] = (BYTE)(huffLog + 1 - n);
for (n=0; n<maxSymbolValue; n++)
- wksp->huffWeight[n] = wksp->bitsToWeight[CTable[n].nbBits];
+ wksp->huffWeight[n] = wksp->bitsToWeight[HUF_getNbBits(ct[n])];
/* attempt weights compression by FSE */
+ if (maxDstSize < 1) return ERROR(dstSize_tooSmall);
{ CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, wksp->huffWeight, maxSymbolValue, &wksp->wksp, sizeof(wksp->wksp)) );
if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */
op[0] = (BYTE)hSize;
@@ -166,6 +224,7 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
U32 tableLog = 0;
U32 nbSymbols = 0;
+ HUF_CElt* const ct = CTable + 1;
/* get symbol weights */
CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize));
@@ -175,6 +234,8 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
if (nbSymbols > *maxSymbolValuePtr+1) return ERROR(maxSymbolValue_tooSmall);
+ CTable[0] = tableLog;
+
/* Prepare base value per rank */
{ U32 n, nextRankStart = 0;
for (n=1; n<=tableLog; n++) {
@@ -186,13 +247,13 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
/* fill nbBits */
{ U32 n; for (n=0; n<nbSymbols; n++) {
const U32 w = huffWeight[n];
- CTable[n].nbBits = (BYTE)(tableLog + 1 - w) & -(w != 0);
+ HUF_setNbBits(ct + n, (BYTE)(tableLog + 1 - w) & -(w != 0));
} }
/* fill val */
{ U16 nbPerRank[HUF_TABLELOG_MAX+2] = {0}; /* support w=0=>n=tableLog+1 */
U16 valPerRank[HUF_TABLELOG_MAX+2] = {0};
- { U32 n; for (n=0; n<nbSymbols; n++) nbPerRank[CTable[n].nbBits]++; }
+ { U32 n; for (n=0; n<nbSymbols; n++) nbPerRank[HUF_getNbBits(ct[n])]++; }
/* determine stating value per rank */
valPerRank[tableLog+1] = 0; /* for w==0 */
{ U16 min = 0;
@@ -202,18 +263,18 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
min >>= 1;
} }
/* assign value within rank, symbol order */
- { U32 n; for (n=0; n<nbSymbols; n++) CTable[n].val = valPerRank[CTable[n].nbBits]++; }
+ { U32 n; for (n=0; n<nbSymbols; n++) HUF_setValue(ct + n, valPerRank[HUF_getNbBits(ct[n])]++); }
}
*maxSymbolValuePtr = nbSymbols - 1;
return readSize;
}
-U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue)
+U32 HUF_getNbBitsFromCTable(HUF_CElt const* CTable, U32 symbolValue)
{
- const HUF_CElt* table = (const HUF_CElt*)symbolTable;
+ const HUF_CElt* ct = CTable + 1;
assert(symbolValue <= HUF_SYMBOLVALUE_MAX);
- return table[symbolValue].nbBits;
+ return (U32)HUF_getNbBits(ct[symbolValue]);
}
@@ -367,22 +428,118 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
}
typedef struct {
- U32 base;
- U32 curr;
+ U16 base;
+ U16 curr;
} rankPos;
typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32];
-#define RANK_POSITION_TABLE_SIZE 32
+/* Number of buckets available for HUF_sort() */
+#define RANK_POSITION_TABLE_SIZE 192
typedef struct {
huffNodeTable huffNodeTbl;
rankPos rankPosition[RANK_POSITION_TABLE_SIZE];
} HUF_buildCTable_wksp_tables;
+/* RANK_POSITION_DISTINCT_COUNT_CUTOFF == Cutoff point in HUF_sort() buckets for which we use log2 bucketing.
+ * Strategy is to use as many buckets as possible for representing distinct
+ * counts while using the remainder to represent all "large" counts.
+ *
+ * To satisfy this requirement for 192 buckets, we can do the following:
+ * Let buckets 0-166 represent distinct counts of [0, 166]
+ * Let buckets 166 to 192 represent all remaining counts up to RANK_POSITION_MAX_COUNT_LOG using log2 bucketing.
+ */
+#define RANK_POSITION_MAX_COUNT_LOG 32
+#define RANK_POSITION_LOG_BUCKETS_BEGIN (RANK_POSITION_TABLE_SIZE - 1) - RANK_POSITION_MAX_COUNT_LOG - 1 /* == 158 */
+#define RANK_POSITION_DISTINCT_COUNT_CUTOFF RANK_POSITION_LOG_BUCKETS_BEGIN + BIT_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN) /* == 166 */
+
+/* Return the appropriate bucket index for a given count. See definition of
+ * RANK_POSITION_DISTINCT_COUNT_CUTOFF for explanation of bucketing strategy.
+ */
+static U32 HUF_getIndex(U32 const count) {
+ return (count < RANK_POSITION_DISTINCT_COUNT_CUTOFF)
+ ? count
+ : BIT_highbit32(count) + RANK_POSITION_LOG_BUCKETS_BEGIN;
+}
+
+/* Helper swap function for HUF_quickSortPartition() */
+static void HUF_swapNodes(nodeElt* a, nodeElt* b) {
+ nodeElt tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+/* Returns 0 if the huffNode array is not sorted by descending count */
+MEM_STATIC int HUF_isSorted(nodeElt huffNode[], U32 const maxSymbolValue1) {
+ U32 i;
+ for (i = 1; i < maxSymbolValue1; ++i) {
+ if (huffNode[i].count > huffNode[i-1].count) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* Insertion sort by descending order */
+HINT_INLINE void HUF_insertionSort(nodeElt huffNode[], int const low, int const high) {
+ int i;
+ int const size = high-low+1;
+ huffNode += low;
+ for (i = 1; i < size; ++i) {
+ nodeElt const key = huffNode[i];
+ int j = i - 1;
+ while (j >= 0 && huffNode[j].count < key.count) {
+ huffNode[j + 1] = huffNode[j];
+ j--;
+ }
+ huffNode[j + 1] = key;
+ }
+}
+
+/* Pivot helper function for quicksort. */
+static int HUF_quickSortPartition(nodeElt arr[], int const low, int const high) {
+ /* Simply select rightmost element as pivot. "Better" selectors like
+ * median-of-three don't experimentally appear to have any benefit.
+ */
+ U32 const pivot = arr[high].count;
+ int i = low - 1;
+ int j = low;
+ for ( ; j < high; j++) {
+ if (arr[j].count > pivot) {
+ i++;
+ HUF_swapNodes(&arr[i], &arr[j]);
+ }
+ }
+ HUF_swapNodes(&arr[i + 1], &arr[high]);
+ return i + 1;
+}
+
+/* Classic quicksort by descending with partially iterative calls
+ * to reduce worst case callstack size.
+ */
+static void HUF_simpleQuickSort(nodeElt arr[], int low, int high) {
+ int const kInsertionSortThreshold = 8;
+ if (high - low < kInsertionSortThreshold) {
+ HUF_insertionSort(arr, low, high);
+ return;
+ }
+ while (low < high) {
+ int const idx = HUF_quickSortPartition(arr, low, high);
+ if (idx - low < high - idx) {
+ HUF_simpleQuickSort(arr, low, idx - 1);
+ low = idx + 1;
+ } else {
+ HUF_simpleQuickSort(arr, idx + 1, high);
+ high = idx - 1;
+ }
+ }
+}
+
/**
* HUF_sort():
* Sorts the symbols [0, maxSymbolValue] by count[symbol] in decreasing order.
+ * This is a typical bucket sorting strategy that uses either quicksort or insertion sort to sort each bucket.
*
* @param[out] huffNode Sorted symbols by decreasing count. Only members `.count` and `.byte` are filled.
* Must have (maxSymbolValue + 1) entries.
@@ -390,44 +547,52 @@ typedef struct {
* @param[in] maxSymbolValue Maximum symbol value.
* @param rankPosition This is a scratch workspace. Must have RANK_POSITION_TABLE_SIZE entries.
*/
-static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue, rankPos* rankPosition)
-{
- int n;
- int const maxSymbolValue1 = (int)maxSymbolValue + 1;
+static void HUF_sort(nodeElt huffNode[], const unsigned count[], U32 const maxSymbolValue, rankPos rankPosition[]) {
+ U32 n;
+ U32 const maxSymbolValue1 = maxSymbolValue+1;
/* Compute base and set curr to base.
- * For symbol s let lowerRank = BIT_highbit32(count[n]+1) and rank = lowerRank + 1.
- * Then 2^lowerRank <= count[n]+1 <= 2^rank.
+ * For symbol s let lowerRank = HUF_getIndex(count[n]) and rank = lowerRank + 1.
+ * See HUF_getIndex to see bucketing strategy.
* We attribute each symbol to lowerRank's base value, because we want to know where
* each rank begins in the output, so for rank R we want to count ranks R+1 and above.
*/
ZSTD_memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE);
for (n = 0; n < maxSymbolValue1; ++n) {
- U32 lowerRank = BIT_highbit32(count[n] + 1);
+ U32 lowerRank = HUF_getIndex(count[n]);
+ assert(lowerRank < RANK_POSITION_TABLE_SIZE - 1);
rankPosition[lowerRank].base++;
}
+
assert(rankPosition[RANK_POSITION_TABLE_SIZE - 1].base == 0);
+ /* Set up the rankPosition table */
for (n = RANK_POSITION_TABLE_SIZE - 1; n > 0; --n) {
rankPosition[n-1].base += rankPosition[n].base;
rankPosition[n-1].curr = rankPosition[n-1].base;
}
- /* Sort */
+
+ /* Insert each symbol into their appropriate bucket, setting up rankPosition table. */
for (n = 0; n < maxSymbolValue1; ++n) {
U32 const c = count[n];
- U32 const r = BIT_highbit32(c+1) + 1;
- U32 pos = rankPosition[r].curr++;
- /* Insert into the correct position in the rank.
- * We have at most 256 symbols, so this insertion should be fine.
- */
- while ((pos > rankPosition[r].base) && (c > huffNode[pos-1].count)) {
- huffNode[pos] = huffNode[pos-1];
- pos--;
- }
+ U32 const r = HUF_getIndex(c) + 1;
+ U32 const pos = rankPosition[r].curr++;
+ assert(pos < maxSymbolValue1);
huffNode[pos].count = c;
huffNode[pos].byte = (BYTE)n;
}
-}
+ /* Sort each bucket. */
+ for (n = RANK_POSITION_DISTINCT_COUNT_CUTOFF; n < RANK_POSITION_TABLE_SIZE - 1; ++n) {
+ U32 const bucketSize = rankPosition[n].curr-rankPosition[n].base;
+ U32 const bucketStartIdx = rankPosition[n].base;
+ if (bucketSize > 1) {
+ assert(bucketStartIdx < maxSymbolValue1);
+ HUF_simpleQuickSort(huffNode + bucketStartIdx, 0, bucketSize-1);
+ }
+ }
+
+ assert(HUF_isSorted(huffNode, maxSymbolValue1));
+}
/** HUF_buildCTable_wksp() :
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
@@ -490,6 +655,7 @@ static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue)
*/
static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, int nonNullRank, U32 maxSymbolValue, U32 maxNbBits)
{
+ HUF_CElt* const ct = CTable + 1;
/* fill result into ctable (val, nbBits) */
int n;
U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
@@ -505,20 +671,20 @@ static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, i
min >>= 1;
} }
for (n=0; n<alphabetSize; n++)
- CTable[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */
+ HUF_setNbBits(ct + huffNode[n].byte, huffNode[n].nbBits); /* push nbBits per symbol, symbol order */
for (n=0; n<alphabetSize; n++)
- CTable[n].val = valPerRank[CTable[n].nbBits]++; /* assign value within rank, symbol order */
+ HUF_setValue(ct + n, valPerRank[HUF_getNbBits(ct[n])]++); /* assign value within rank, symbol order */
+ CTable[0] = maxNbBits;
}
-size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
+size_t HUF_buildCTable_wksp (HUF_CElt* CTable, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
{
- HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)workSpace;
+ HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(U32));
nodeElt* const huffNode0 = wksp_tables->huffNodeTbl;
nodeElt* const huffNode = huffNode0+1;
int nonNullRank;
/* safety checks */
- if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
if (wkspSize < sizeof(HUF_buildCTable_wksp_tables))
return ERROR(workSpace_tooSmall);
if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
@@ -536,96 +702,334 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbo
maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits);
if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
- HUF_buildCTableFromTree(tree, huffNode, nonNullRank, maxSymbolValue, maxNbBits);
+ HUF_buildCTableFromTree(CTable, huffNode, nonNullRank, maxSymbolValue, maxNbBits);
return maxNbBits;
}
size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)
{
+ HUF_CElt const* ct = CTable + 1;
size_t nbBits = 0;
int s;
for (s = 0; s <= (int)maxSymbolValue; ++s) {
- nbBits += CTable[s].nbBits * count[s];
+ nbBits += HUF_getNbBits(ct[s]) * count[s];
}
return nbBits >> 3;
}
int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) {
+ HUF_CElt const* ct = CTable + 1;
int bad = 0;
int s;
for (s = 0; s <= (int)maxSymbolValue; ++s) {
- bad |= (count[s] != 0) & (CTable[s].nbBits == 0);
+ bad |= (count[s] != 0) & (HUF_getNbBits(ct[s]) == 0);
}
return !bad;
}
size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }
+/** HUF_CStream_t:
+ * Huffman uses its own BIT_CStream_t implementation.
+ * There are three major differences from BIT_CStream_t:
+ * 1. HUF_addBits() takes a HUF_CElt (size_t) which is
+ * the pair (nbBits, value) in the format:
+ * format:
+ * - Bits [0, 4) = nbBits
+ * - Bits [4, 64 - nbBits) = 0
+ * - Bits [64 - nbBits, 64) = value
+ * 2. The bitContainer is built from the upper bits and
+ * right shifted. E.g. to add a new value of N bits
+ * you right shift the bitContainer by N, then or in
+ * the new value into the N upper bits.
+ * 3. The bitstream has two bit containers. You can add
+ * bits to the second container and merge them into
+ * the first container.
+ */
+
+#define HUF_BITS_IN_CONTAINER (sizeof(size_t) * 8)
+
+typedef struct {
+ size_t bitContainer[2];
+ size_t bitPos[2];
+
+ BYTE* startPtr;
+ BYTE* ptr;
+ BYTE* endPtr;
+} HUF_CStream_t;
+
+/**! HUF_initCStream():
+ * Initializes the bitstream.
+ * @returns 0 or an error code.
+ */
+static size_t HUF_initCStream(HUF_CStream_t* bitC,
+ void* startPtr, size_t dstCapacity)
+{
+ ZSTD_memset(bitC, 0, sizeof(*bitC));
+ bitC->startPtr = (BYTE*)startPtr;
+ bitC->ptr = bitC->startPtr;
+ bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer[0]);
+ if (dstCapacity <= sizeof(bitC->bitContainer[0])) return ERROR(dstSize_tooSmall);
+ return 0;
+}
+
+/*! HUF_addBits():
+ * Adds the symbol stored in HUF_CElt elt to the bitstream.
+ *
+ * @param elt The element we're adding. This is a (nbBits, value) pair.
+ * See the HUF_CStream_t docs for the format.
+ * @param idx Insert into the bitstream at this idx.
+ * @param kFast This is a template parameter. If the bitstream is guaranteed
+ * to have at least 4 unused bits after this call it may be 1,
+ * otherwise it must be 0. HUF_addBits() is faster when fast is set.
+ */
+FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t* bitC, HUF_CElt elt, int idx, int kFast)
+{
+ assert(idx <= 1);
+ assert(HUF_getNbBits(elt) <= HUF_TABLELOG_ABSOLUTEMAX);
+ /* This is efficient on x86-64 with BMI2 because shrx
+ * only reads the low 6 bits of the register. The compiler
+ * knows this and elides the mask. When fast is set,
+ * every operation can use the same value loaded from elt.
+ */
+ bitC->bitContainer[idx] >>= HUF_getNbBits(elt);
+ bitC->bitContainer[idx] |= kFast ? HUF_getValueFast(elt) : HUF_getValue(elt);
+ /* We only read the low 8 bits of bitC->bitPos[idx] so it
+ * doesn't matter that the high bits have noise from the value.
+ */
+ bitC->bitPos[idx] += HUF_getNbBitsFast(elt);
+ assert((bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER);
+ /* The last 4-bits of elt are dirty if fast is set,
+ * so we must not be overwriting bits that have already been
+ * inserted into the bit container.
+ */
+#if DEBUGLEVEL >= 1
+ {
+ size_t const nbBits = HUF_getNbBits(elt);
+ size_t const dirtyBits = nbBits == 0 ? 0 : BIT_highbit32((U32)nbBits) + 1;
+ (void)dirtyBits;
+ /* Middle bits are 0. */
+ assert(((elt >> dirtyBits) << (dirtyBits + nbBits)) == 0);
+ /* We didn't overwrite any bits in the bit container. */
+ assert(!kFast || (bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER);
+ (void)dirtyBits;
+ }
+#endif
+}
+
+FORCE_INLINE_TEMPLATE void HUF_zeroIndex1(HUF_CStream_t* bitC)
+{
+ bitC->bitContainer[1] = 0;
+ bitC->bitPos[1] = 0;
+}
+
+/*! HUF_mergeIndex1() :
+ * Merges the bit container @ index 1 into the bit container @ index 0
+ * and zeros the bit container @ index 1.
+ */
+FORCE_INLINE_TEMPLATE void HUF_mergeIndex1(HUF_CStream_t* bitC)
+{
+ assert((bitC->bitPos[1] & 0xFF) < HUF_BITS_IN_CONTAINER);
+ bitC->bitContainer[0] >>= (bitC->bitPos[1] & 0xFF);
+ bitC->bitContainer[0] |= bitC->bitContainer[1];
+ bitC->bitPos[0] += bitC->bitPos[1];
+ assert((bitC->bitPos[0] & 0xFF) <= HUF_BITS_IN_CONTAINER);
+}
+
+/*! HUF_flushBits() :
+* Flushes the bits in the bit container @ index 0.
+*
+* @post bitPos will be < 8.
+* @param kFast If kFast is set then we must know a-priori that
+* the bit container will not overflow.
+*/
+FORCE_INLINE_TEMPLATE void HUF_flushBits(HUF_CStream_t* bitC, int kFast)
+{
+ /* The upper bits of bitPos are noisy, so we must mask by 0xFF. */
+ size_t const nbBits = bitC->bitPos[0] & 0xFF;
+ size_t const nbBytes = nbBits >> 3;
+ /* The top nbBits bits of bitContainer are the ones we need. */
+ size_t const bitContainer = bitC->bitContainer[0] >> (HUF_BITS_IN_CONTAINER - nbBits);
+ /* Mask bitPos to account for the bytes we consumed. */
+ bitC->bitPos[0] &= 7;
+ assert(nbBits > 0);
+ assert(nbBits <= sizeof(bitC->bitContainer[0]) * 8);
+ assert(bitC->ptr <= bitC->endPtr);
+ MEM_writeLEST(bitC->ptr, bitContainer);
+ bitC->ptr += nbBytes;
+ assert(!kFast || bitC->ptr <= bitC->endPtr);
+ if (!kFast && bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
+ /* bitContainer doesn't need to be modified because the leftover
+ * bits are already the top bitPos bits. And we don't care about
+ * noise in the lower values.
+ */
+}
+
+/*! HUF_endMark()
+ * @returns The Huffman stream end mark: A 1-bit value = 1.
+ */
+static HUF_CElt HUF_endMark(void)
+{
+ HUF_CElt endMark;
+ HUF_setNbBits(&endMark, 1);
+ HUF_setValue(&endMark, 1);
+ return endMark;
+}
+
+/*! HUF_closeCStream() :
+ * @return Size of CStream, in bytes,
+ * or 0 if it could not fit into dstBuffer */
+static size_t HUF_closeCStream(HUF_CStream_t* bitC)
+{
+ HUF_addBits(bitC, HUF_endMark(), /* idx */ 0, /* kFast */ 0);
+ HUF_flushBits(bitC, /* kFast */ 0);
+ {
+ size_t const nbBits = bitC->bitPos[0] & 0xFF;
+ if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
+ return (bitC->ptr - bitC->startPtr) + (nbBits > 0);
+ }
+}
+
FORCE_INLINE_TEMPLATE void
-HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)
+HUF_encodeSymbol(HUF_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable, int idx, int fast)
{
- BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);
+ HUF_addBits(bitCPtr, CTable[symbol], idx, fast);
}
-#define HUF_FLUSHBITS(s) BIT_flushBits(s)
+FORCE_INLINE_TEMPLATE void
+HUF_compress1X_usingCTable_internal_body_loop(HUF_CStream_t* bitC,
+ const BYTE* ip, size_t srcSize,
+ const HUF_CElt* ct,
+ int kUnroll, int kFastFlush, int kLastFast)
+{
+ /* Join to kUnroll */
+ int n = (int)srcSize;
+ int rem = n % kUnroll;
+ if (rem > 0) {
+ for (; rem > 0; --rem) {
+ HUF_encodeSymbol(bitC, ip[--n], ct, 0, /* fast */ 0);
+ }
+ HUF_flushBits(bitC, kFastFlush);
+ }
+ assert(n % kUnroll == 0);
+
+ /* Join to 2 * kUnroll */
+ if (n % (2 * kUnroll)) {
+ int u;
+ for (u = 1; u < kUnroll; ++u) {
+ HUF_encodeSymbol(bitC, ip[n - u], ct, 0, 1);
+ }
+ HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, 0, kLastFast);
+ HUF_flushBits(bitC, kFastFlush);
+ n -= kUnroll;
+ }
+ assert(n % (2 * kUnroll) == 0);
+
+ for (; n>0; n-= 2 * kUnroll) {
+ /* Encode kUnroll symbols into the bitstream @ index 0. */
+ int u;
+ for (u = 1; u < kUnroll; ++u) {
+ HUF_encodeSymbol(bitC, ip[n - u], ct, /* idx */ 0, /* fast */ 1);
+ }
+ HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, /* idx */ 0, /* fast */ kLastFast);
+ HUF_flushBits(bitC, kFastFlush);
+ /* Encode kUnroll symbols into the bitstream @ index 1.
+ * This allows us to start filling the bit container
+ * without any data dependencies.
+ */
+ HUF_zeroIndex1(bitC);
+ for (u = 1; u < kUnroll; ++u) {
+ HUF_encodeSymbol(bitC, ip[n - kUnroll - u], ct, /* idx */ 1, /* fast */ 1);
+ }
+ HUF_encodeSymbol(bitC, ip[n - kUnroll - kUnroll], ct, /* idx */ 1, /* fast */ kLastFast);
+ /* Merge bitstream @ index 1 into the bitstream @ index 0 */
+ HUF_mergeIndex1(bitC);
+ HUF_flushBits(bitC, kFastFlush);
+ }
+ assert(n == 0);
+
+}
-#define HUF_FLUSHBITS_1(stream) \
- if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*2+7) HUF_FLUSHBITS(stream)
+/**
+ * Returns a tight upper bound on the output space needed by Huffman
+ * with 8 bytes buffer to handle over-writes. If the output is at least
+ * this large we don't need to do bounds checks during Huffman encoding.
+ */
+static size_t HUF_tightCompressBound(size_t srcSize, size_t tableLog)
+{
+ return ((srcSize * tableLog) >> 3) + 8;
+}
-#define HUF_FLUSHBITS_2(stream) \
- if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*4+7) HUF_FLUSHBITS(stream)
FORCE_INLINE_TEMPLATE size_t
HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,
const void* src, size_t srcSize,
const HUF_CElt* CTable)
{
+ U32 const tableLog = (U32)CTable[0];
+ HUF_CElt const* ct = CTable + 1;
const BYTE* ip = (const BYTE*) src;
BYTE* const ostart = (BYTE*)dst;
BYTE* const oend = ostart + dstSize;
BYTE* op = ostart;
- size_t n;
- BIT_CStream_t bitC;
+ HUF_CStream_t bitC;
/* init */
if (dstSize < 8) return 0; /* not enough space to compress */
- { size_t const initErr = BIT_initCStream(&bitC, op, (size_t)(oend-op));
+ { size_t const initErr = HUF_initCStream(&bitC, op, (size_t)(oend-op));
if (HUF_isError(initErr)) return 0; }
- n = srcSize & ~3; /* join to mod 4 */
- switch (srcSize & 3)
- {
- case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);
- HUF_FLUSHBITS_2(&bitC);
- /* fall-through */
- case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
- HUF_FLUSHBITS_1(&bitC);
- /* fall-through */
- case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);
- HUF_FLUSHBITS(&bitC);
- /* fall-through */
- case 0 : /* fall-through */
- default: break;
- }
-
- for (; n>0; n-=4) { /* note : n&3==0 at this stage */
- HUF_encodeSymbol(&bitC, ip[n- 1], CTable);
- HUF_FLUSHBITS_1(&bitC);
- HUF_encodeSymbol(&bitC, ip[n- 2], CTable);
- HUF_FLUSHBITS_2(&bitC);
- HUF_encodeSymbol(&bitC, ip[n- 3], CTable);
- HUF_FLUSHBITS_1(&bitC);
- HUF_encodeSymbol(&bitC, ip[n- 4], CTable);
- HUF_FLUSHBITS(&bitC);
+ if (dstSize < HUF_tightCompressBound(srcSize, (size_t)tableLog) || tableLog > 11)
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ MEM_32bits() ? 2 : 4, /* kFast */ 0, /* kLastFast */ 0);
+ else {
+ if (MEM_32bits()) {
+ switch (tableLog) {
+ case 11:
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 0);
+ break;
+ case 10: ZSTD_FALLTHROUGH;
+ case 9: ZSTD_FALLTHROUGH;
+ case 8:
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 1);
+ break;
+ case 7: ZSTD_FALLTHROUGH;
+ default:
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 3, /* kFastFlush */ 1, /* kLastFast */ 1);
+ break;
+ }
+ } else {
+ switch (tableLog) {
+ case 11:
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 0);
+ break;
+ case 10:
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 1);
+ break;
+ case 9:
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 6, /* kFastFlush */ 1, /* kLastFast */ 0);
+ break;
+ case 8:
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 7, /* kFastFlush */ 1, /* kLastFast */ 0);
+ break;
+ case 7:
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 8, /* kFastFlush */ 1, /* kLastFast */ 0);
+ break;
+ case 6: ZSTD_FALLTHROUGH;
+ default:
+ HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 9, /* kFastFlush */ 1, /* kLastFast */ 1);
+ break;
+ }
+ }
}
+ assert(bitC.ptr <= bitC.endPtr);
- return BIT_closeCStream(&bitC);
+ return HUF_closeCStream(&bitC);
}
#if DYNAMIC_BMI2
-static TARGET_ATTRIBUTE("bmi2") size_t
+static BMI2_TARGET_ATTRIBUTE size_t
HUF_compress1X_usingCTable_internal_bmi2(void* dst, size_t dstSize,
const void* src, size_t srcSize,
const HUF_CElt* CTable)
@@ -667,9 +1071,13 @@ HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
{
- return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);
+ return HUF_compress1X_usingCTable_bmi2(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);
}
+size_t HUF_compress1X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2)
+{
+ return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, bmi2);
+}
static size_t
HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
@@ -689,8 +1097,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
assert(op <= oend);
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) );
- if (cSize==0) return 0;
- assert(cSize <= 65535);
+ if (cSize == 0 || cSize > 65535) return 0;
MEM_writeLE16(ostart, (U16)cSize);
op += cSize;
}
@@ -698,8 +1105,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
ip += segmentSize;
assert(op <= oend);
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) );
- if (cSize==0) return 0;
- assert(cSize <= 65535);
+ if (cSize == 0 || cSize > 65535) return 0;
MEM_writeLE16(ostart+2, (U16)cSize);
op += cSize;
}
@@ -707,8 +1113,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
ip += segmentSize;
assert(op <= oend);
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) );
- if (cSize==0) return 0;
- assert(cSize <= 65535);
+ if (cSize == 0 || cSize > 65535) return 0;
MEM_writeLE16(ostart+4, (U16)cSize);
op += cSize;
}
@@ -717,7 +1122,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
assert(op <= oend);
assert(ip <= iend);
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, bmi2) );
- if (cSize==0) return 0;
+ if (cSize == 0 || cSize > 65535) return 0;
op += cSize;
}
@@ -726,7 +1131,12 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
{
- return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);
+ return HUF_compress4X_usingCTable_bmi2(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);
+}
+
+size_t HUF_compress4X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2)
+{
+ return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, bmi2);
}
typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e;
@@ -750,35 +1160,38 @@ static size_t HUF_compressCTable_internal(
typedef struct {
unsigned count[HUF_SYMBOLVALUE_MAX + 1];
- HUF_CElt CTable[HUF_SYMBOLVALUE_MAX + 1];
+ HUF_CElt CTable[HUF_CTABLE_SIZE_ST(HUF_SYMBOLVALUE_MAX)];
union {
HUF_buildCTable_wksp_tables buildCTable_wksp;
HUF_WriteCTableWksp writeCTable_wksp;
+ U32 hist_wksp[HIST_WKSP_SIZE_U32];
} wksps;
} HUF_compress_tables_t;
+#define SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE 4096
+#define SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO 10 /* Must be >= 2 */
+
/* HUF_compress_internal() :
* `workSpace_align4` must be aligned on 4-bytes boundaries,
- * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U32 unsigned */
+ * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U64 unsigned */
static size_t
HUF_compress_internal (void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog,
HUF_nbStreams_e nbStreams,
- void* workSpace_align4, size_t wkspSize,
+ void* workSpace, size_t wkspSize,
HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,
- const int bmi2)
+ const int bmi2, unsigned suspectUncompressible)
{
- HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace_align4;
+ HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(size_t));
BYTE* const ostart = (BYTE*)dst;
BYTE* const oend = ostart + dstSize;
BYTE* op = ostart;
- HUF_STATIC_ASSERT(sizeof(*table) <= HUF_WORKSPACE_SIZE);
- assert(((size_t)workSpace_align4 & 3) == 0); /* must be aligned on 4-bytes boundaries */
+ HUF_STATIC_ASSERT(sizeof(*table) + HUF_WORKSPACE_MAX_ALIGNMENT <= HUF_WORKSPACE_SIZE);
/* checks & inits */
- if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall);
+ if (wkspSize < sizeof(*table)) return ERROR(workSpace_tooSmall);
if (!srcSize) return 0; /* Uncompressed */
if (!dstSize) return 0; /* cannot fit anything within dst budget */
if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */
@@ -794,8 +1207,23 @@ HUF_compress_internal (void* dst, size_t dstSize,
nbStreams, oldHufTable, bmi2);
}
+ /* If uncompressible data is suspected, do a smaller sampling first */
+ DEBUG_STATIC_ASSERT(SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO >= 2);
+ if (suspectUncompressible && srcSize >= (SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE * SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO)) {
+ size_t largestTotal = 0;
+ { unsigned maxSymbolValueBegin = maxSymbolValue;
+ CHECK_V_F(largestBegin, HIST_count_simple (table->count, &maxSymbolValueBegin, (const BYTE*)src, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) );
+ largestTotal += largestBegin;
+ }
+ { unsigned maxSymbolValueEnd = maxSymbolValue;
+ CHECK_V_F(largestEnd, HIST_count_simple (table->count, &maxSymbolValueEnd, (const BYTE*)src + srcSize - SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) );
+ largestTotal += largestEnd;
+ }
+ if (largestTotal <= ((2 * SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) >> 7)+4) return 0; /* heuristic : probably not compressible enough */
+ }
+
/* Scan input and build symbol stats */
- { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace_align4, wkspSize) );
+ { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, table->wksps.hist_wksp, sizeof(table->wksps.hist_wksp)) );
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */
}
@@ -820,9 +1248,12 @@ HUF_compress_internal (void* dst, size_t dstSize,
&table->wksps.buildCTable_wksp, sizeof(table->wksps.buildCTable_wksp));
CHECK_F(maxBits);
huffLog = (U32)maxBits;
- /* Zero unused symbols in CTable, so we can check it for validity */
- ZSTD_memset(table->CTable + (maxSymbolValue + 1), 0,
- sizeof(table->CTable) - ((maxSymbolValue + 1) * sizeof(HUF_CElt)));
+ }
+ /* Zero unused symbols in CTable, so we can check it for validity */
+ {
+ size_t const ctableSize = HUF_CTABLE_SIZE_ST(maxSymbolValue);
+ size_t const unusedSize = sizeof(table->CTable) - ctableSize * sizeof(HUF_CElt);
+ ZSTD_memset(table->CTable + ctableSize, 0, unusedSize);
}
/* Write table description header */
@@ -859,19 +1290,20 @@ size_t HUF_compress1X_wksp (void* dst, size_t dstSize,
return HUF_compress_internal(dst, dstSize, src, srcSize,
maxSymbolValue, huffLog, HUF_singleStream,
workSpace, wkspSize,
- NULL, NULL, 0, 0 /*bmi2*/);
+ NULL, NULL, 0, 0 /*bmi2*/, 0);
}
size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog,
void* workSpace, size_t wkspSize,
- HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2)
+ HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat,
+ int bmi2, unsigned suspectUncompressible)
{
return HUF_compress_internal(dst, dstSize, src, srcSize,
maxSymbolValue, huffLog, HUF_singleStream,
workSpace, wkspSize, hufTable,
- repeat, preferRepeat, bmi2);
+ repeat, preferRepeat, bmi2, suspectUncompressible);
}
/* HUF_compress4X_repeat():
@@ -885,22 +1317,23 @@ size_t HUF_compress4X_wksp (void* dst, size_t dstSize,
return HUF_compress_internal(dst, dstSize, src, srcSize,
maxSymbolValue, huffLog, HUF_fourStreams,
workSpace, wkspSize,
- NULL, NULL, 0, 0 /*bmi2*/);
+ NULL, NULL, 0, 0 /*bmi2*/, 0);
}
/* HUF_compress4X_repeat():
* compress input using 4 streams.
+ * consider skipping quickly
* re-use an existing huffman compression table */
size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog,
void* workSpace, size_t wkspSize,
- HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2)
+ HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible)
{
return HUF_compress_internal(dst, dstSize, src, srcSize,
maxSymbolValue, huffLog, HUF_fourStreams,
workSpace, wkspSize,
- hufTable, repeat, preferRepeat, bmi2);
+ hufTable, repeat, preferRepeat, bmi2, suspectUncompressible);
}
#ifndef ZSTD_NO_UNUSED_FUNCTIONS
@@ -918,7 +1351,7 @@ size_t HUF_compress1X (void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog)
{
- unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
+ U64 workSpace[HUF_WORKSPACE_SIZE_U64];
return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
}
@@ -926,7 +1359,7 @@ size_t HUF_compress2 (void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog)
{
- unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
+ U64 workSpace[HUF_WORKSPACE_SIZE_U64];
return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
}
diff --git a/thirdparty/zstd/compress/zstd_compress.c b/thirdparty/zstd/compress/zstd_compress.c
index b7ee2980a7..f06456af92 100644
--- a/thirdparty/zstd/compress/zstd_compress.c
+++ b/thirdparty/zstd/compress/zstd_compress.c
@@ -12,7 +12,6 @@
* Dependencies
***************************************/
#include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */
-#include "../common/cpu.h"
#include "../common/mem.h"
#include "hist.h" /* HIST_countFast_wksp */
#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
@@ -42,6 +41,18 @@
# define ZSTD_COMPRESS_HEAPMODE 0
#endif
+/*!
+ * ZSTD_HASHLOG3_MAX :
+ * Maximum size of the hash table dedicated to find 3-bytes matches,
+ * in log format, aka 17 => 1 << 17 == 128Ki positions.
+ * This structure is only used in zstd_opt.
+ * Since allocation is centralized for all strategies, it has to be known here.
+ * The actual (selected) size of the hash table is then stored in ZSTD_matchState_t.hashLog3,
+ * so that zstd_opt.c doesn't need to know about this constant.
+ */
+#ifndef ZSTD_HASHLOG3_MAX
+# define ZSTD_HASHLOG3_MAX 17
+#endif
/*-*************************************
* Helper functions
@@ -72,10 +83,10 @@ struct ZSTD_CDict_s {
ZSTD_customMem customMem;
U32 dictID;
int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */
- ZSTD_useRowMatchFinderMode_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use
- * row-based matchfinder. Unless the cdict is reloaded, we will use
- * the same greedy/lazy matchfinder at compression time.
- */
+ ZSTD_paramSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use
+ * row-based matchfinder. Unless the cdict is reloaded, we will use
+ * the same greedy/lazy matchfinder at compression time.
+ */
}; /* typedef'd to ZSTD_CDict within "zstd.h" */
ZSTD_CCtx* ZSTD_createCCtx(void)
@@ -88,7 +99,7 @@ static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager)
assert(cctx != NULL);
ZSTD_memset(cctx, 0, sizeof(*cctx));
cctx->customMem = memManager;
- cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
+ cctx->bmi2 = ZSTD_cpuSupportsBmi2();
{ size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters);
assert(!ZSTD_isError(err));
(void)err;
@@ -214,35 +225,42 @@ static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) {
/* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder
* for this compression.
*/
-static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_useRowMatchFinderMode_e mode) {
- assert(mode != ZSTD_urm_auto);
- return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_urm_enableRowMatchFinder);
+static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_paramSwitch_e mode) {
+ assert(mode != ZSTD_ps_auto);
+ return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_ps_enable);
}
-/* Returns row matchfinder usage enum given an initial mode and cParams */
-static ZSTD_useRowMatchFinderMode_e ZSTD_resolveRowMatchFinderMode(ZSTD_useRowMatchFinderMode_e mode,
- const ZSTD_compressionParameters* const cParams) {
-#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(__ARM_NEON))
+/* Returns row matchfinder usage given an initial mode and cParams */
+static ZSTD_paramSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_paramSwitch_e mode,
+ const ZSTD_compressionParameters* const cParams) {
+#if defined(ZSTD_ARCH_X86_SSE2) || defined(ZSTD_ARCH_ARM_NEON)
int const kHasSIMD128 = 1;
#else
int const kHasSIMD128 = 0;
#endif
- if (mode != ZSTD_urm_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */
- mode = ZSTD_urm_disableRowMatchFinder;
+ if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */
+ mode = ZSTD_ps_disable;
if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode;
if (kHasSIMD128) {
- if (cParams->windowLog > 14) mode = ZSTD_urm_enableRowMatchFinder;
+ if (cParams->windowLog > 14) mode = ZSTD_ps_enable;
} else {
- if (cParams->windowLog > 17) mode = ZSTD_urm_enableRowMatchFinder;
+ if (cParams->windowLog > 17) mode = ZSTD_ps_enable;
}
return mode;
}
+/* Returns block splitter usage (generally speaking, when using slower/stronger compression modes) */
+static ZSTD_paramSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_paramSwitch_e mode,
+ const ZSTD_compressionParameters* const cParams) {
+ if (mode != ZSTD_ps_auto) return mode;
+ return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17) ? ZSTD_ps_enable : ZSTD_ps_disable;
+}
+
/* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */
static int ZSTD_allocateChainTable(const ZSTD_strategy strategy,
- const ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
+ const ZSTD_paramSwitch_e useRowMatchFinder,
const U32 forDDSDict) {
- assert(useRowMatchFinder != ZSTD_urm_auto);
+ assert(useRowMatchFinder != ZSTD_ps_auto);
/* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate.
* We do not allocate a chaintable if we are using ZSTD_fast, or are using the row-based matchfinder.
*/
@@ -253,16 +271,10 @@ static int ZSTD_allocateChainTable(const ZSTD_strategy strategy,
* enable long distance matching (wlog >= 27, strategy >= btopt).
* Returns 0 otherwise.
*/
-static U32 ZSTD_CParams_shouldEnableLdm(const ZSTD_compressionParameters* const cParams) {
- return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27;
-}
-
-/* Returns 1 if compression parameters are such that we should
- * enable blockSplitter (wlog >= 17, strategy >= btopt).
- * Returns 0 otherwise.
- */
-static U32 ZSTD_CParams_useBlockSplitter(const ZSTD_compressionParameters* const cParams) {
- return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17;
+static ZSTD_paramSwitch_e ZSTD_resolveEnableLdm(ZSTD_paramSwitch_e mode,
+ const ZSTD_compressionParameters* const cParams) {
+ if (mode != ZSTD_ps_auto) return mode;
+ return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable;
}
static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
@@ -274,20 +286,13 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
cctxParams.cParams = cParams;
/* Adjust advanced params according to cParams */
- if (ZSTD_CParams_shouldEnableLdm(&cParams)) {
- DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including LDM into cctx params");
- cctxParams.ldmParams.enableLdm = 1;
- /* LDM is enabled by default for optimal parser and window size >= 128MB */
+ cctxParams.ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams.ldmParams.enableLdm, &cParams);
+ if (cctxParams.ldmParams.enableLdm == ZSTD_ps_enable) {
ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams);
assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog);
assert(cctxParams.ldmParams.hashRateLog < 32);
}
-
- if (ZSTD_CParams_useBlockSplitter(&cParams)) {
- DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including block splitting into cctx params");
- cctxParams.splitBlocks = 1;
- }
-
+ cctxParams.useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.useBlockSplitter, &cParams);
cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
assert(!ZSTD_checkCParams(cParams));
return cctxParams;
@@ -348,7 +353,10 @@ static void ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, ZSTD_par
*/
cctxParams->compressionLevel = compressionLevel;
cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, &params->cParams);
- DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d", cctxParams->useRowMatchFinder);
+ cctxParams->useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->useBlockSplitter, &params->cParams);
+ cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, &params->cParams);
+ DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d",
+ cctxParams->useRowMatchFinder, cctxParams->useBlockSplitter, cctxParams->ldmParams.enableLdm);
}
size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
@@ -518,9 +526,9 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
return bounds;
case ZSTD_c_literalCompressionMode:
- ZSTD_STATIC_ASSERT(ZSTD_lcm_auto < ZSTD_lcm_huffman && ZSTD_lcm_huffman < ZSTD_lcm_uncompressed);
- bounds.lowerBound = ZSTD_lcm_auto;
- bounds.upperBound = ZSTD_lcm_uncompressed;
+ ZSTD_STATIC_ASSERT(ZSTD_ps_auto < ZSTD_ps_enable && ZSTD_ps_enable < ZSTD_ps_disable);
+ bounds.lowerBound = (int)ZSTD_ps_auto;
+ bounds.upperBound = (int)ZSTD_ps_disable;
return bounds;
case ZSTD_c_targetCBlockSize:
@@ -549,14 +557,14 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
bounds.upperBound = 1;
return bounds;
- case ZSTD_c_splitBlocks:
- bounds.lowerBound = 0;
- bounds.upperBound = 1;
+ case ZSTD_c_useBlockSplitter:
+ bounds.lowerBound = (int)ZSTD_ps_auto;
+ bounds.upperBound = (int)ZSTD_ps_disable;
return bounds;
case ZSTD_c_useRowMatchFinder:
- bounds.lowerBound = (int)ZSTD_urm_auto;
- bounds.upperBound = (int)ZSTD_urm_enableRowMatchFinder;
+ bounds.lowerBound = (int)ZSTD_ps_auto;
+ bounds.upperBound = (int)ZSTD_ps_disable;
return bounds;
case ZSTD_c_deterministicRefPrefix:
@@ -625,7 +633,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
case ZSTD_c_stableOutBuffer:
case ZSTD_c_blockDelimiters:
case ZSTD_c_validateSequences:
- case ZSTD_c_splitBlocks:
+ case ZSTD_c_useBlockSplitter:
case ZSTD_c_useRowMatchFinder:
case ZSTD_c_deterministicRefPrefix:
default:
@@ -680,7 +688,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
case ZSTD_c_stableOutBuffer:
case ZSTD_c_blockDelimiters:
case ZSTD_c_validateSequences:
- case ZSTD_c_splitBlocks:
+ case ZSTD_c_useBlockSplitter:
case ZSTD_c_useRowMatchFinder:
case ZSTD_c_deterministicRefPrefix:
break;
@@ -780,7 +788,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
}
case ZSTD_c_literalCompressionMode : {
- const ZSTD_literalCompressionMode_e lcm = (ZSTD_literalCompressionMode_e)value;
+ const ZSTD_paramSwitch_e lcm = (ZSTD_paramSwitch_e)value;
BOUNDCHECK(ZSTD_c_literalCompressionMode, lcm);
CCtxParams->literalCompressionMode = lcm;
return CCtxParams->literalCompressionMode;
@@ -835,7 +843,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
return CCtxParams->enableDedicatedDictSearch;
case ZSTD_c_enableLongDistanceMatching :
- CCtxParams->ldmParams.enableLdm = (value!=0);
+ CCtxParams->ldmParams.enableLdm = (ZSTD_paramSwitch_e)value;
return CCtxParams->ldmParams.enableLdm;
case ZSTD_c_ldmHashLog :
@@ -857,8 +865,8 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
return CCtxParams->ldmParams.bucketSizeLog;
case ZSTD_c_ldmHashRateLog :
- RETURN_ERROR_IF(value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN,
- parameter_outOfBound, "Param out of bounds!");
+ if (value!=0) /* 0 ==> default */
+ BOUNDCHECK(ZSTD_c_ldmHashRateLog, value);
CCtxParams->ldmParams.hashRateLog = value;
return CCtxParams->ldmParams.hashRateLog;
@@ -894,14 +902,14 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
CCtxParams->validateSequences = value;
return CCtxParams->validateSequences;
- case ZSTD_c_splitBlocks:
- BOUNDCHECK(ZSTD_c_splitBlocks, value);
- CCtxParams->splitBlocks = value;
- return CCtxParams->splitBlocks;
+ case ZSTD_c_useBlockSplitter:
+ BOUNDCHECK(ZSTD_c_useBlockSplitter, value);
+ CCtxParams->useBlockSplitter = (ZSTD_paramSwitch_e)value;
+ return CCtxParams->useBlockSplitter;
case ZSTD_c_useRowMatchFinder:
BOUNDCHECK(ZSTD_c_useRowMatchFinder, value);
- CCtxParams->useRowMatchFinder = (ZSTD_useRowMatchFinderMode_e)value;
+ CCtxParams->useRowMatchFinder = (ZSTD_paramSwitch_e)value;
return CCtxParams->useRowMatchFinder;
case ZSTD_c_deterministicRefPrefix:
@@ -1032,8 +1040,8 @@ size_t ZSTD_CCtxParams_getParameter(
case ZSTD_c_validateSequences :
*value = (int)CCtxParams->validateSequences;
break;
- case ZSTD_c_splitBlocks :
- *value = (int)CCtxParams->splitBlocks;
+ case ZSTD_c_useBlockSplitter :
+ *value = (int)CCtxParams->useBlockSplitter;
break;
case ZSTD_c_useRowMatchFinder :
*value = (int)CCtxParams->useRowMatchFinder;
@@ -1067,7 +1075,7 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
return 0;
}
-ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
+size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
{
DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %u bytes", (U32)pledgedSrcSize);
RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
@@ -1147,14 +1155,14 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
return 0;
}
-ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(
+size_t ZSTD_CCtx_loadDictionary_byReference(
ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
{
return ZSTD_CCtx_loadDictionary_advanced(
cctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto);
}
-ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
+size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
{
return ZSTD_CCtx_loadDictionary_advanced(
cctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);
@@ -1324,7 +1332,7 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
break;
case ZSTD_cpm_createCDict:
/* Assume a small source size when creating a dictionary
- * with an unkown source size.
+ * with an unknown source size.
*/
if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN)
srcSize = minSrcSize;
@@ -1398,7 +1406,7 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
srcSizeHint = CCtxParams->srcSizeHint;
}
cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode);
- if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
+ if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
ZSTD_overrideCParams(&cParams, &CCtxParams->cParams);
assert(!ZSTD_checkCParams(cParams));
/* srcSizeHint == 0 means 0 */
@@ -1407,7 +1415,7 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
static size_t
ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
- const ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
+ const ZSTD_paramSwitch_e useRowMatchFinder,
const U32 enableDedicatedDictSearch,
const U32 forCCtx)
{
@@ -1440,7 +1448,7 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
/* tables are guaranteed to be sized in multiples of 64 bytes (or 16 uint32_t) */
ZSTD_STATIC_ASSERT(ZSTD_HASHLOG_MIN >= 4 && ZSTD_WINDOWLOG_MIN >= 4 && ZSTD_CHAINLOG_MIN >= 4);
- assert(useRowMatchFinder != ZSTD_urm_auto);
+ assert(useRowMatchFinder != ZSTD_ps_auto);
DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u",
(U32)chainSize, (U32)hSize, (U32)h3Size);
@@ -1451,12 +1459,12 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
const ZSTD_compressionParameters* cParams,
const ldmParams_t* ldmParams,
const int isStatic,
- const ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
+ const ZSTD_paramSwitch_e useRowMatchFinder,
const size_t buffInSize,
const size_t buffOutSize,
const U64 pledgedSrcSize)
{
- size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << cParams->windowLog), pledgedSrcSize));
+ size_t const windowSize = (size_t) BOUNDED(1ULL, 1ULL << cParams->windowLog, pledgedSrcSize);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
U32 const divider = (cParams->minMatch==3) ? 3 : 4;
size_t const maxNbSeq = blockSize / divider;
@@ -1469,7 +1477,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams);
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize);
- size_t const ldmSeqSpace = ldmParams->enableLdm ?
+ size_t const ldmSeqSpace = ldmParams->enableLdm == ZSTD_ps_enable ?
ZSTD_cwksp_aligned_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
@@ -1496,8 +1504,8 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
{
ZSTD_compressionParameters const cParams =
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
- ZSTD_useRowMatchFinderMode_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
- &cParams);
+ ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
+ &cParams);
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
/* estimateCCtxSize is for one-shot compression. So no buffers should
@@ -1514,9 +1522,9 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
/* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */
size_t noRowCCtxSize;
size_t rowCCtxSize;
- initialParams.useRowMatchFinder = ZSTD_urm_disableRowMatchFinder;
+ initialParams.useRowMatchFinder = ZSTD_ps_disable;
noRowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams);
- initialParams.useRowMatchFinder = ZSTD_urm_enableRowMatchFinder;
+ initialParams.useRowMatchFinder = ZSTD_ps_enable;
rowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams);
return MAX(noRowCCtxSize, rowCCtxSize);
} else {
@@ -1561,7 +1569,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered)
? ZSTD_compressBound(blockSize) + 1
: 0;
- ZSTD_useRowMatchFinderMode_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, &params->cParams);
+ ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, &params->cParams);
return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
&cParams, &params->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
@@ -1576,9 +1584,9 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)
/* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */
size_t noRowCCtxSize;
size_t rowCCtxSize;
- initialParams.useRowMatchFinder = ZSTD_urm_disableRowMatchFinder;
+ initialParams.useRowMatchFinder = ZSTD_ps_disable;
noRowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams);
- initialParams.useRowMatchFinder = ZSTD_urm_enableRowMatchFinder;
+ initialParams.useRowMatchFinder = ZSTD_ps_enable;
rowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams);
return MAX(noRowCCtxSize, rowCCtxSize);
} else {
@@ -1713,7 +1721,7 @@ static size_t
ZSTD_reset_matchState(ZSTD_matchState_t* ms,
ZSTD_cwksp* ws,
const ZSTD_compressionParameters* cParams,
- const ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
+ const ZSTD_paramSwitch_e useRowMatchFinder,
const ZSTD_compResetPolicy_e crp,
const ZSTD_indexResetPolicy_e forceResetIndex,
const ZSTD_resetTarget_e forWho)
@@ -1728,7 +1736,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;
DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset);
- assert(useRowMatchFinder != ZSTD_urm_auto);
+ assert(useRowMatchFinder != ZSTD_ps_auto);
if (forceResetIndex == ZSTDirp_reset) {
ZSTD_window_init(&ms->window);
ZSTD_cwksp_mark_tables_dirty(ws);
@@ -1774,8 +1782,8 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
if (ms->tagTable) ZSTD_memset(ms->tagTable, 0, tagTableSize);
}
{ /* Switch to 32-entry rows if searchLog is 5 (or more) */
- U32 const rowLog = cParams->searchLog < 5 ? 4 : 5;
- assert(cParams->hashLog > rowLog);
+ U32 const rowLog = BOUNDED(4, cParams->searchLog, 6);
+ assert(cParams->hashLog >= rowLog);
ms->rowHashLog = cParams->hashLog - rowLog;
}
}
@@ -1824,8 +1832,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
ZSTD_buffered_policy_e const zbuff)
{
ZSTD_cwksp* const ws = &zc->workspace;
- DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d",
- (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder);
+ DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d useBlockSplitter=%d",
+ (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->useBlockSplitter);
assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
zc->isFirstBlock = 1;
@@ -1836,8 +1844,10 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->appliedParams = *params;
params = &zc->appliedParams;
- assert(params->useRowMatchFinder != ZSTD_urm_auto);
- if (params->ldmParams.enableLdm) {
+ assert(params->useRowMatchFinder != ZSTD_ps_auto);
+ assert(params->useBlockSplitter != ZSTD_ps_auto);
+ assert(params->ldmParams.enableLdm != ZSTD_ps_auto);
+ if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
/* Adjust long distance matching parameters */
ZSTD_ldm_adjustParameters(&zc->appliedParams.ldmParams, &params->cParams);
assert(params->ldmParams.hashLog >= params->ldmParams.bucketSizeLog);
@@ -1900,7 +1910,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock");
zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, ENTROPY_WORKSPACE_SIZE);
- RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate entropyWorkspace");
+ RETURN_ERROR_IF(zc->entropyWorkspace == NULL, memory_allocation, "couldn't allocate entropyWorkspace");
} }
ZSTD_cwksp_clear(ws);
@@ -1937,7 +1947,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize);
/* ldm bucketOffsets table */
- if (params->ldmParams.enableLdm) {
+ if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
/* TODO: avoid memset? */
size_t const numBuckets =
((size_t)1) << (params->ldmParams.hashLog -
@@ -1964,7 +1974,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
ZSTD_resetTarget_CCtx), "");
/* ldm hash table */
- if (params->ldmParams.enableLdm) {
+ if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
/* TODO: avoid memset? */
size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog;
zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t));
@@ -1976,8 +1986,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->ldmState.loadedDictEnd = 0;
}
- assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace, resizeWorkspace));
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
+ assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace, resizeWorkspace));
zc->initialized = 1;
@@ -2115,7 +2125,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
}
ZSTD_cwksp_mark_tables_dirty(&cctx->workspace);
- assert(params.useRowMatchFinder != ZSTD_urm_auto);
+ assert(params.useRowMatchFinder != ZSTD_ps_auto);
/* copy tables */
{ size_t const chainSize = ZSTD_allocateChainTable(cdict_cParams->strategy, cdict->useRowMatchFinder, 0 /* DDS guaranteed disabled */)
@@ -2209,8 +2219,12 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
{ ZSTD_CCtx_params params = dstCCtx->requestedParams;
/* Copy only compression parameters related to tables. */
params.cParams = srcCCtx->appliedParams.cParams;
- assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_urm_auto);
+ assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto);
+ assert(srcCCtx->appliedParams.useBlockSplitter != ZSTD_ps_auto);
+ assert(srcCCtx->appliedParams.ldmParams.enableLdm != ZSTD_ps_auto);
params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder;
+ params.useBlockSplitter = srcCCtx->appliedParams.useBlockSplitter;
+ params.ldmParams = srcCCtx->appliedParams.ldmParams;
params.fParams = fParams;
ZSTD_resetCCtx_internal(dstCCtx, &params, pledgedSrcSize,
/* loadedDictSize */ 0,
@@ -2296,6 +2310,8 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
int const nbRows = (int)size / ZSTD_ROWSIZE;
int cellNb = 0;
int rowNb;
+ /* Protect special index values < ZSTD_WINDOW_START_INDEX. */
+ U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX;
assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
assert(size < (1U<<31)); /* can be casted to int */
@@ -2315,12 +2331,17 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
for (rowNb=0 ; rowNb < nbRows ; rowNb++) {
int column;
for (column=0; column<ZSTD_ROWSIZE; column++) {
- if (preserveMark) {
- U32 const adder = (table[cellNb] == ZSTD_DUBT_UNSORTED_MARK) ? reducerValue : 0;
- table[cellNb] += adder;
+ U32 newVal;
+ if (preserveMark && table[cellNb] == ZSTD_DUBT_UNSORTED_MARK) {
+ /* This write is pointless, but is required(?) for the compiler
+ * to auto-vectorize the loop. */
+ newVal = ZSTD_DUBT_UNSORTED_MARK;
+ } else if (table[cellNb] < reducerThreshold) {
+ newVal = 0;
+ } else {
+ newVal = table[cellNb] - reducerValue;
}
- if (table[cellNb] < reducerValue) table[cellNb] = 0;
- else table[cellNb] -= reducerValue;
+ table[cellNb] = newVal;
cellNb++;
} }
}
@@ -2375,9 +2396,9 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
assert(nbSeq <= seqStorePtr->maxNbSeq);
for (u=0; u<nbSeq; u++) {
U32 const llv = sequences[u].litLength;
- U32 const mlv = sequences[u].matchLength;
+ U32 const mlv = sequences[u].mlBase;
llCodeTable[u] = (BYTE)ZSTD_LLcode(llv);
- ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
+ ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offBase);
mlCodeTable[u] = (BYTE)ZSTD_MLcode(mlv);
}
if (seqStorePtr->longLengthType==ZSTD_llt_literalLength)
@@ -2399,11 +2420,13 @@ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams)
/* ZSTD_blockSplitterEnabled():
* Returns if block splitting param is being used
* If used, compression will do best effort to split a block in order to improve compression ratio.
+ * At the time this function is called, the parameter must be finalized.
* Returns 1 if true, 0 otherwise. */
static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams)
{
- DEBUGLOG(5, "ZSTD_blockSplitterEnabled(splitBlocks=%d)", cctxParams->splitBlocks);
- return (cctxParams->splitBlocks != 0);
+ DEBUGLOG(5, "ZSTD_blockSplitterEnabled (useBlockSplitter=%d)", cctxParams->useBlockSplitter);
+ assert(cctxParams->useBlockSplitter != ZSTD_ps_auto);
+ return (cctxParams->useBlockSplitter == ZSTD_ps_enable);
}
/* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types
@@ -2546,6 +2569,7 @@ ZSTD_buildSequencesStatistics(seqStore_t* seqStorePtr, size_t nbSeq,
* compresses both literals and sequences
* Returns compressed size of block, or a zstd error.
*/
+#define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20
MEM_STATIC size_t
ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr,
const ZSTD_entropyCTables_t* prevEntropy,
@@ -2580,15 +2604,19 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr,
/* Compress literals */
{ const BYTE* const literals = seqStorePtr->litStart;
+ size_t const numSequences = seqStorePtr->sequences - seqStorePtr->sequencesStart;
+ size_t const numLiterals = seqStorePtr->lit - seqStorePtr->litStart;
+ /* Base suspicion of uncompressibility on ratio of literals to sequences */
+ unsigned const suspectUncompressible = (numSequences == 0) || (numLiterals / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO);
size_t const litSize = (size_t)(seqStorePtr->lit - literals);
size_t const cSize = ZSTD_compressLiterals(
&prevEntropy->huf, &nextEntropy->huf,
cctxParams->cParams.strategy,
- ZSTD_disableLiteralsCompression(cctxParams),
+ ZSTD_literalsCompressionIsDisabled(cctxParams),
op, dstCapacity,
literals, litSize,
entropyWorkspace, entropyWkspSize,
- bmi2);
+ bmi2, suspectUncompressible);
FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed");
assert(cSize <= dstCapacity);
op += cSize;
@@ -2693,7 +2721,7 @@ ZSTD_entropyCompressSeqStore(seqStore_t* seqStorePtr,
/* ZSTD_selectBlockCompressor() :
* Not static, but internal use only (used by long distance matcher)
* assumption : strat is a valid strategy */
-ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRowMatchFinderMode_e useRowMatchFinder, ZSTD_dictMode_e dictMode)
+ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode)
{
static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = {
{ ZSTD_compressBlock_fast /* default for 0 */,
@@ -2758,7 +2786,7 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRow
ZSTD_compressBlock_lazy2_dedicatedDictSearch_row }
};
DEBUGLOG(4, "Selecting a row-based matchfinder");
- assert(useRowMatchFinder != ZSTD_urm_auto);
+ assert(useRowMatchFinder != ZSTD_ps_auto);
selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy];
} else {
selectedCompressor = blockCompressor[(int)dictMode][(int)strat];
@@ -2825,7 +2853,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i];
}
if (zc->externSeqStore.pos < zc->externSeqStore.size) {
- assert(!zc->appliedParams.ldmParams.enableLdm);
+ assert(zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_disable);
/* Updates ldmSeqStore.pos */
lastLLSize =
ZSTD_ldm_blockCompress(&zc->externSeqStore,
@@ -2834,7 +2862,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
zc->appliedParams.useRowMatchFinder,
src, srcSize);
assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
- } else if (zc->appliedParams.ldmParams.enableLdm) {
+ } else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) {
rawSeqStore_t ldmSeqStore = kNullRawSeqStore;
ldmSeqStore.seq = zc->ldmSequences;
@@ -2882,9 +2910,9 @@ static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
assert(zc->seqCollector.maxSequences >= seqStoreSeqSize + 1);
ZSTD_memcpy(updatedRepcodes.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
for (i = 0; i < seqStoreSeqSize; ++i) {
- U32 rawOffset = seqStoreSeqs[i].offset - ZSTD_REP_NUM;
+ U32 rawOffset = seqStoreSeqs[i].offBase - ZSTD_REP_NUM;
outSeqs[i].litLength = seqStoreSeqs[i].litLength;
- outSeqs[i].matchLength = seqStoreSeqs[i].matchLength + MINMATCH;
+ outSeqs[i].matchLength = seqStoreSeqs[i].mlBase + MINMATCH;
outSeqs[i].rep = 0;
if (i == seqStore->longLengthPos) {
@@ -2895,9 +2923,9 @@ static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
}
}
- if (seqStoreSeqs[i].offset <= ZSTD_REP_NUM) {
+ if (seqStoreSeqs[i].offBase <= ZSTD_REP_NUM) {
/* Derive the correct offset corresponding to a repcode */
- outSeqs[i].rep = seqStoreSeqs[i].offset;
+ outSeqs[i].rep = seqStoreSeqs[i].offBase;
if (outSeqs[i].litLength != 0) {
rawOffset = updatedRepcodes.rep[outSeqs[i].rep - 1];
} else {
@@ -2911,9 +2939,9 @@ static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
outSeqs[i].offset = rawOffset;
/* seqStoreSeqs[i].offset == offCode+1, and ZSTD_updateRep() expects offCode
so we provide seqStoreSeqs[i].offset - 1 */
- updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep,
- seqStoreSeqs[i].offset - 1,
- seqStoreSeqs[i].litLength == 0);
+ ZSTD_updateRep(updatedRepcodes.rep,
+ seqStoreSeqs[i].offBase - 1,
+ seqStoreSeqs[i].litLength == 0);
literalsRead += outSeqs[i].litLength;
}
/* Insert last literals (if any exist) in the block as a sequence with ml == off == 0.
@@ -3027,7 +3055,7 @@ static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSi
const ZSTD_hufCTables_t* prevHuf,
ZSTD_hufCTables_t* nextHuf,
ZSTD_hufCTablesMetadata_t* hufMetadata,
- const int disableLiteralsCompression,
+ const int literalsCompressionIsDisabled,
void* workspace, size_t wkspSize)
{
BYTE* const wkspStart = (BYTE*)workspace;
@@ -3045,7 +3073,7 @@ static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSi
/* Prepare nextEntropy assuming reusing the existing table */
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
- if (disableLiteralsCompression) {
+ if (literalsCompressionIsDisabled) {
DEBUGLOG(5, "set_basic - disabled");
hufMetadata->hType = set_basic;
return 0;
@@ -3192,7 +3220,7 @@ size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr,
ZSTD_buildBlockEntropyStats_literals(seqStorePtr->litStart, litSize,
&prevEntropy->huf, &nextEntropy->huf,
&entropyMetadata->hufMetadata,
- ZSTD_disableLiteralsCompression(cctxParams),
+ ZSTD_literalsCompressionIsDisabled(cctxParams),
workspace, wkspSize);
FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildBlockEntropyStats_literals failed");
entropyMetadata->fseMetadata.fseTablesSize =
@@ -3235,7 +3263,7 @@ static size_t ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSiz
static size_t ZSTD_estimateBlockSize_symbolType(symbolEncodingType_e type,
const BYTE* codeTable, size_t nbSeq, unsigned maxCode,
const FSE_CTable* fseCTable,
- const U32* additionalBits,
+ const U8* additionalBits,
short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
void* workspace, size_t wkspSize)
{
@@ -3319,19 +3347,20 @@ static size_t ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize,
*
* Returns the estimated compressed size of the seqStore, or a zstd error.
*/
-static size_t ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, const ZSTD_CCtx* zc) {
- ZSTD_entropyCTablesMetadata_t entropyMetadata;
+static size_t ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, ZSTD_CCtx* zc) {
+ ZSTD_entropyCTablesMetadata_t* entropyMetadata = &zc->blockSplitCtx.entropyMetadata;
+ DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()");
FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(seqStore,
&zc->blockState.prevCBlock->entropy,
&zc->blockState.nextCBlock->entropy,
&zc->appliedParams,
- &entropyMetadata,
+ entropyMetadata,
zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
return ZSTD_estimateBlockSize(seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart),
seqStore->ofCode, seqStore->llCode, seqStore->mlCode,
(size_t)(seqStore->sequences - seqStore->sequencesStart),
- &zc->blockState.nextCBlock->entropy, &entropyMetadata, zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE,
- (int)(entropyMetadata.hufMetadata.hType == set_compressed), 1);
+ &zc->blockState.nextCBlock->entropy, entropyMetadata, zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE,
+ (int)(entropyMetadata->hufMetadata.hType == set_compressed), 1);
}
/* Returns literals bytes represented in a seqStore */
@@ -3356,7 +3385,7 @@ static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t* const seqStore) {
size_t i;
for (i = 0; i < nbSeqs; ++i) {
seqDef seq = seqStore->sequencesStart[i];
- matchBytes += seq.matchLength + MINMATCH;
+ matchBytes += seq.mlBase + MINMATCH;
if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) {
matchBytes += 0x10000;
}
@@ -3405,11 +3434,13 @@ static void ZSTD_deriveSeqStoreChunk(seqStore_t* resultSeqStore,
/**
* Returns the raw offset represented by the combination of offCode, ll0, and repcode history.
- * offCode must be an offCode representing a repcode, therefore in the range of [0, 2].
+ * offCode must represent a repcode in the numeric representation of ZSTD_storeSeq().
*/
-static U32 ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offCode, const U32 ll0) {
- U32 const adjustedOffCode = offCode + ll0;
- assert(offCode < ZSTD_REP_NUM);
+static U32
+ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offCode, const U32 ll0)
+{
+ U32 const adjustedOffCode = STORED_REPCODE(offCode) - 1 + ll0; /* [ 0 - 3 ] */
+ assert(STORED_IS_REPCODE(offCode));
if (adjustedOffCode == ZSTD_REP_NUM) {
/* litlength == 0 and offCode == 2 implies selection of first repcode - 1 */
assert(rep[0] > 0);
@@ -3420,11 +3451,16 @@ static U32 ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32
/**
* ZSTD_seqStore_resolveOffCodes() reconciles any possible divergences in offset history that may arise
- * due to emission of RLE/raw blocks that disturb the offset history, and replaces any repcodes within
- * the seqStore that may be invalid.
+ * due to emission of RLE/raw blocks that disturb the offset history,
+ * and replaces any repcodes within the seqStore that may be invalid.
+ *
+ * dRepcodes are updated as would be on the decompression side.
+ * cRepcodes are updated exactly in accordance with the seqStore.
*
- * dRepcodes are updated as would be on the decompression side. cRepcodes are updated exactly in
- * accordance with the seqStore.
+ * Note : this function assumes seq->offBase respects the following numbering scheme :
+ * 0 : invalid
+ * 1-3 : repcode 1-3
+ * 4+ : real_offset+3
*/
static void ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRepcodes,
seqStore_t* const seqStore, U32 const nbSeq) {
@@ -3432,9 +3468,9 @@ static void ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_
for (; idx < nbSeq; ++idx) {
seqDef* const seq = seqStore->sequencesStart + idx;
U32 const ll0 = (seq->litLength == 0);
- U32 offCode = seq->offset - 1;
- assert(seq->offset > 0);
- if (offCode <= ZSTD_REP_MOVE) {
+ U32 const offCode = OFFBASE_TO_STORED(seq->offBase);
+ assert(seq->offBase > 0);
+ if (STORED_IS_REPCODE(offCode)) {
U32 const dRawOffset = ZSTD_resolveRepcodeToRawOffset(dRepcodes->rep, offCode, ll0);
U32 const cRawOffset = ZSTD_resolveRepcodeToRawOffset(cRepcodes->rep, offCode, ll0);
/* Adjust simulated decompression repcode history if we come across a mismatch. Replace
@@ -3442,14 +3478,14 @@ static void ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_
* repcode history.
*/
if (dRawOffset != cRawOffset) {
- seq->offset = cRawOffset + ZSTD_REP_NUM;
+ seq->offBase = cRawOffset + ZSTD_REP_NUM;
}
}
/* Compression repcode history is always updated with values directly from the unmodified seqStore.
* Decompression repcode history may use modified seq->offset value taken from compression repcode history.
*/
- *dRepcodes = ZSTD_updateRep(dRepcodes->rep, seq->offset - 1, ll0);
- *cRepcodes = ZSTD_updateRep(cRepcodes->rep, offCode, ll0);
+ ZSTD_updateRep(dRepcodes->rep, OFFBASE_TO_STORED(seq->offBase), ll0);
+ ZSTD_updateRep(cRepcodes->rep, offCode, ll0);
}
}
@@ -3458,11 +3494,13 @@ static void ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_
*
* Returns the total size of that block (including header) or a ZSTD error code.
*/
-static size_t ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const seqStore,
- repcodes_t* const dRep, repcodes_t* const cRep,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- U32 lastBlock, U32 isPartition) {
+static size_t
+ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const seqStore,
+ repcodes_t* const dRep, repcodes_t* const cRep,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ U32 lastBlock, U32 isPartition)
+{
const U32 rleMaxLength = 25;
BYTE* op = (BYTE*)dst;
const BYTE* ip = (const BYTE*)src;
@@ -3471,9 +3509,11 @@ static size_t ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const
/* In case of an RLE or raw block, the simulated decompression repcode history must be reset */
repcodes_t const dRepOriginal = *dRep;
+ DEBUGLOG(5, "ZSTD_compressSeqStore_singleBlock");
if (isPartition)
ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart));
+ RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "Block header doesn't fit");
cSeqsSize = ZSTD_entropyCompressSeqStore(seqStore,
&zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
&zc->appliedParams,
@@ -3499,9 +3539,6 @@ static size_t ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const
return 0;
}
- if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
- zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
-
if (cSeqsSize == 0) {
cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock);
FORWARD_IF_ERROR(cSize, "Nocompress block failed");
@@ -3518,6 +3555,10 @@ static size_t ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const
cSize = ZSTD_blockHeaderSize + cSeqsSize;
DEBUGLOG(4, "Writing out compressed block, size: %zu", cSize);
}
+
+ if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
+ zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
+
return cSize;
}
@@ -3528,7 +3569,6 @@ typedef struct {
} seqStoreSplits;
#define MIN_SEQUENCES_BLOCK_SPLITTING 300
-#define MAX_NB_SPLITS 196
/* Helper function to perform the recursive search for block splits.
* Estimates the cost of seqStore prior to split, and estimates the cost of splitting the sequences in half.
@@ -3539,29 +3579,33 @@ typedef struct {
* In theory, this means the absolute largest recursion depth is 10 == log2(maxNbSeqInBlock/MIN_SEQUENCES_BLOCK_SPLITTING).
* In practice, recursion depth usually doesn't go beyond 4.
*
- * Furthermore, the number of splits is capped by MAX_NB_SPLITS. At MAX_NB_SPLITS == 196 with the current existing blockSize
+ * Furthermore, the number of splits is capped by ZSTD_MAX_NB_BLOCK_SPLITS. At ZSTD_MAX_NB_BLOCK_SPLITS == 196 with the current existing blockSize
* maximum of 128 KB, this value is actually impossible to reach.
*/
-static void ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx,
- const ZSTD_CCtx* zc, const seqStore_t* origSeqStore) {
- seqStore_t fullSeqStoreChunk;
- seqStore_t firstHalfSeqStore;
- seqStore_t secondHalfSeqStore;
+static void
+ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx,
+ ZSTD_CCtx* zc, const seqStore_t* origSeqStore)
+{
+ seqStore_t* fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk;
+ seqStore_t* firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore;
+ seqStore_t* secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore;
size_t estimatedOriginalSize;
size_t estimatedFirstHalfSize;
size_t estimatedSecondHalfSize;
size_t midIdx = (startIdx + endIdx)/2;
- if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= MAX_NB_SPLITS) {
+ if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= ZSTD_MAX_NB_BLOCK_SPLITS) {
+ DEBUGLOG(6, "ZSTD_deriveBlockSplitsHelper: Too few sequences");
return;
}
- ZSTD_deriveSeqStoreChunk(&fullSeqStoreChunk, origSeqStore, startIdx, endIdx);
- ZSTD_deriveSeqStoreChunk(&firstHalfSeqStore, origSeqStore, startIdx, midIdx);
- ZSTD_deriveSeqStoreChunk(&secondHalfSeqStore, origSeqStore, midIdx, endIdx);
- estimatedOriginalSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&fullSeqStoreChunk, zc);
- estimatedFirstHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&firstHalfSeqStore, zc);
- estimatedSecondHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&secondHalfSeqStore, zc);
- DEBUGLOG(5, "Estimated original block size: %zu -- First half split: %zu -- Second half split: %zu",
+ DEBUGLOG(4, "ZSTD_deriveBlockSplitsHelper: startIdx=%zu endIdx=%zu", startIdx, endIdx);
+ ZSTD_deriveSeqStoreChunk(fullSeqStoreChunk, origSeqStore, startIdx, endIdx);
+ ZSTD_deriveSeqStoreChunk(firstHalfSeqStore, origSeqStore, startIdx, midIdx);
+ ZSTD_deriveSeqStoreChunk(secondHalfSeqStore, origSeqStore, midIdx, endIdx);
+ estimatedOriginalSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(fullSeqStoreChunk, zc);
+ estimatedFirstHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(firstHalfSeqStore, zc);
+ estimatedSecondHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(secondHalfSeqStore, zc);
+ DEBUGLOG(4, "Estimated original block size: %zu -- First half split: %zu -- Second half split: %zu",
estimatedOriginalSize, estimatedFirstHalfSize, estimatedSecondHalfSize);
if (ZSTD_isError(estimatedOriginalSize) || ZSTD_isError(estimatedFirstHalfSize) || ZSTD_isError(estimatedSecondHalfSize)) {
return;
@@ -3596,17 +3640,19 @@ static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx* zc, U32 partitions[], U32 nbSeq)
*
* Returns combined size of all blocks (which includes headers), or a ZSTD error code.
*/
-static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity,
- const void* src, size_t blockSize, U32 lastBlock, U32 nbSeq) {
+static size_t
+ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity,
+ const void* src, size_t blockSize, U32 lastBlock, U32 nbSeq)
+{
size_t cSize = 0;
const BYTE* ip = (const BYTE*)src;
BYTE* op = (BYTE*)dst;
- U32 partitions[MAX_NB_SPLITS];
size_t i = 0;
size_t srcBytesTotal = 0;
+ U32* partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */
+ seqStore_t* nextSeqStore = &zc->blockSplitCtx.nextSeqStore;
+ seqStore_t* currSeqStore = &zc->blockSplitCtx.currSeqStore;
size_t numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq);
- seqStore_t nextSeqStore;
- seqStore_t currSeqStore;
/* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history
* may become invalid. In order to reconcile potentially invalid repcodes, we keep track of two
@@ -3626,6 +3672,7 @@ static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, s
repcodes_t cRep;
ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
+ ZSTD_memset(nextSeqStore, 0, sizeof(seqStore_t));
DEBUGLOG(4, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
(unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
@@ -3643,36 +3690,36 @@ static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, s
return cSizeSingleBlock;
}
- ZSTD_deriveSeqStoreChunk(&currSeqStore, &zc->seqStore, 0, partitions[0]);
+ ZSTD_deriveSeqStoreChunk(currSeqStore, &zc->seqStore, 0, partitions[0]);
for (i = 0; i <= numSplits; ++i) {
size_t srcBytes;
size_t cSizeChunk;
U32 const lastPartition = (i == numSplits);
U32 lastBlockEntireSrc = 0;
- srcBytes = ZSTD_countSeqStoreLiteralsBytes(&currSeqStore) + ZSTD_countSeqStoreMatchBytes(&currSeqStore);
+ srcBytes = ZSTD_countSeqStoreLiteralsBytes(currSeqStore) + ZSTD_countSeqStoreMatchBytes(currSeqStore);
srcBytesTotal += srcBytes;
if (lastPartition) {
/* This is the final partition, need to account for possible last literals */
srcBytes += blockSize - srcBytesTotal;
lastBlockEntireSrc = lastBlock;
} else {
- ZSTD_deriveSeqStoreChunk(&nextSeqStore, &zc->seqStore, partitions[i], partitions[i+1]);
+ ZSTD_deriveSeqStoreChunk(nextSeqStore, &zc->seqStore, partitions[i], partitions[i+1]);
}
- cSizeChunk = ZSTD_compressSeqStore_singleBlock(zc, &currSeqStore,
+ cSizeChunk = ZSTD_compressSeqStore_singleBlock(zc, currSeqStore,
&dRep, &cRep,
op, dstCapacity,
ip, srcBytes,
lastBlockEntireSrc, 1 /* isPartition */);
- DEBUGLOG(5, "Estimated size: %zu actual size: %zu", ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&currSeqStore, zc), cSizeChunk);
+ DEBUGLOG(5, "Estimated size: %zu actual size: %zu", ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(currSeqStore, zc), cSizeChunk);
FORWARD_IF_ERROR(cSizeChunk, "Compressing chunk failed!");
ip += srcBytes;
op += cSizeChunk;
dstCapacity -= cSizeChunk;
cSize += cSizeChunk;
- currSeqStore = nextSeqStore;
+ *currSeqStore = *nextSeqStore;
assert(cSizeChunk <= ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize);
}
/* cRep and dRep may have diverged during the compression. If so, we use the dRep repcodes
@@ -3682,14 +3729,17 @@ static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, s
return cSize;
}
-static size_t ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize, U32 lastBlock) {
+static size_t
+ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize, U32 lastBlock)
+{
const BYTE* ip = (const BYTE*)src;
BYTE* op = (BYTE*)dst;
U32 nbSeq;
size_t cSize;
DEBUGLOG(4, "ZSTD_compressBlock_splitBlock");
+ assert(zc->appliedParams.useBlockSplitter == ZSTD_ps_enable);
{ const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
@@ -3704,15 +3754,15 @@ static size_t ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart);
}
- assert(zc->appliedParams.splitBlocks == 1);
cSize = ZSTD_compressBlock_splitBlock_internal(zc, dst, dstCapacity, src, srcSize, lastBlock, nbSeq);
FORWARD_IF_ERROR(cSize, "Splitting blocks failed!");
return cSize;
}
-static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize, U32 frame)
+static size_t
+ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize, U32 frame)
{
/* This the upper bound for the length of an rle block.
* This isn't the actual upper bound. Finding the real threshold
@@ -3746,12 +3796,6 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
zc->bmi2);
- if (zc->seqCollector.collectSequences) {
- ZSTD_copyBlockSequences(zc);
- return 0;
- }
-
-
if (frame &&
/* We don't want to emit our first block as a RLE even if it qualifies because
* doing so will cause the decoder (cli only) to throw a "should consume all input error."
@@ -3915,6 +3959,7 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
ZSTD_overflowCorrectIfNeeded(
ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize);
ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
+ ZSTD_window_enforceMaxDist(&ms->window, ip, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
/* Ensure hash/chain table insertion resumes no sooner than lowlimit */
if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
@@ -3991,7 +4036,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
if (!singleSegment) op[pos++] = windowLogByte;
switch(dictIDSizeCode)
{
- default: assert(0); /* impossible */
+ default:
+ assert(0); /* impossible */
+ ZSTD_FALLTHROUGH;
case 0 : break;
case 1 : op[pos] = (BYTE)(dictID); pos++; break;
case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
@@ -3999,7 +4046,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
}
switch(fcsCode)
{
- default: assert(0); /* impossible */
+ default:
+ assert(0); /* impossible */
+ ZSTD_FALLTHROUGH;
case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
@@ -4047,7 +4096,7 @@ size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSe
{
RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong,
"wrong cctx stage");
- RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm,
+ RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable,
parameter_unsupported,
"incompatible with ldm");
cctx->externSeqStore.seq = seq;
@@ -4088,7 +4137,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
ms->forceNonContiguous = 0;
ms->nextToUpdate = ms->window.dictLimit;
}
- if (cctx->appliedParams.ldmParams.enableLdm) {
+ if (cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) {
ZSTD_window_update(&cctx->ldmState.window, src, srcSize, /* forceNonContiguous */ 0);
}
@@ -4157,7 +4206,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
{
const BYTE* ip = (const BYTE*) src;
const BYTE* const iend = ip + srcSize;
- int const loadLdmDict = params->ldmParams.enableLdm && ls != NULL;
+ int const loadLdmDict = params->ldmParams.enableLdm == ZSTD_ps_enable && ls != NULL;
/* Assert that we the ms params match the params we're being given */
ZSTD_assertEqualCParams(params->cParams, ms->cParams);
@@ -4214,8 +4263,8 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
assert(ms->chainTable != NULL);
ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, iend-HASH_READ_SIZE);
} else {
- assert(params->useRowMatchFinder != ZSTD_urm_auto);
- if (params->useRowMatchFinder == ZSTD_urm_enableRowMatchFinder) {
+ assert(params->useRowMatchFinder != ZSTD_ps_auto);
+ if (params->useRowMatchFinder == ZSTD_ps_enable) {
size_t const tagTableSize = ((size_t)1 << params->cParams.hashLog) * sizeof(U16);
ZSTD_memset(ms->tagTable, 0, tagTableSize);
ZSTD_row_update(ms, iend-HASH_READ_SIZE);
@@ -4715,7 +4764,7 @@ size_t ZSTD_estimateCDictSize_advanced(
+ ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE)
/* enableDedicatedDictSearch == 1 ensures that CDict estimation will not be too small
* in case we are using DDS with row-hash. */
- + ZSTD_sizeof_matchState(&cParams, ZSTD_resolveRowMatchFinderMode(ZSTD_urm_auto, &cParams),
+ + ZSTD_sizeof_matchState(&cParams, ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams),
/* enableDedicatedDictSearch */ 1, /* forCCtx */ 0)
+ (dictLoadMethod == ZSTD_dlm_byRef ? 0
: ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *))));
@@ -4792,7 +4841,7 @@ static size_t ZSTD_initCDict_internal(
static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_compressionParameters cParams,
- ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
+ ZSTD_paramSwitch_e useRowMatchFinder,
U32 enableDedicatedDictSearch,
ZSTD_customMem customMem)
{
@@ -4842,7 +4891,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
&cctxParams, customMem);
}
-ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2(
+ZSTD_CDict* ZSTD_createCDict_advanced2(
const void* dict, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType,
@@ -4947,7 +4996,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
ZSTD_dictContentType_e dictContentType,
ZSTD_compressionParameters cParams)
{
- ZSTD_useRowMatchFinderMode_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_urm_auto, &cParams);
+ ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams);
/* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0);
size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
@@ -5403,7 +5452,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
zcs->outBuffFlushedSize = 0;
zcs->streamStage = zcss_flush; /* pass-through to flush stage */
}
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case zcss_flush:
DEBUGLOG(5, "flush stage");
assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered);
@@ -5524,17 +5573,8 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
dictSize, mode);
}
- if (ZSTD_CParams_shouldEnableLdm(&params.cParams)) {
- /* Enable LDM by default for optimal parser and window size >= 128MB */
- DEBUGLOG(4, "LDM enabled by default (window size >= 128MB, strategy >= btopt)");
- params.ldmParams.enableLdm = 1;
- }
-
- if (ZSTD_CParams_useBlockSplitter(&params.cParams)) {
- DEBUGLOG(4, "Block splitter enabled by default (window size >= 128K, strategy >= btopt)");
- params.splitBlocks = 1;
- }
-
+ params.useBlockSplitter = ZSTD_resolveBlockSplitterMode(params.useBlockSplitter, &params.cParams);
+ params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, &params.cParams);
params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, &params.cParams);
#ifdef ZSTD_MULTITHREAD
@@ -5715,39 +5755,39 @@ typedef struct {
size_t posInSrc; /* Number of bytes given by sequences provided so far */
} ZSTD_sequencePosition;
-/* Returns a ZSTD error code if sequence is not valid */
-static size_t ZSTD_validateSequence(U32 offCode, U32 matchLength,
- size_t posInSrc, U32 windowLog, size_t dictSize, U32 minMatch) {
- size_t offsetBound;
- U32 windowSize = 1 << windowLog;
+/* ZSTD_validateSequence() :
+ * @offCode : is presumed to follow format required by ZSTD_storeSeq()
+ * @returns a ZSTD error code if sequence is not valid
+ */
+static size_t
+ZSTD_validateSequence(U32 offCode, U32 matchLength,
+ size_t posInSrc, U32 windowLog, size_t dictSize)
+{
+ U32 const windowSize = 1 << windowLog;
/* posInSrc represents the amount of data the the decoder would decode up to this point.
* As long as the amount of data decoded is less than or equal to window size, offsets may be
* larger than the total length of output decoded in order to reference the dict, even larger than
* window size. After output surpasses windowSize, we're limited to windowSize offsets again.
*/
- offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize;
- RETURN_ERROR_IF(offCode > offsetBound + ZSTD_REP_MOVE, corruption_detected, "Offset too large!");
- RETURN_ERROR_IF(matchLength < minMatch, corruption_detected, "Matchlength too small");
+ size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize;
+ RETURN_ERROR_IF(offCode > STORE_OFFSET(offsetBound), corruption_detected, "Offset too large!");
+ RETURN_ERROR_IF(matchLength < MINMATCH, corruption_detected, "Matchlength too small");
return 0;
}
/* Returns an offset code, given a sequence's raw offset, the ongoing repcode array, and whether litLength == 0 */
-static U32 ZSTD_finalizeOffCode(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0) {
- U32 offCode = rawOffset + ZSTD_REP_MOVE;
- U32 repCode = 0;
+static U32 ZSTD_finalizeOffCode(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0)
+{
+ U32 offCode = STORE_OFFSET(rawOffset);
if (!ll0 && rawOffset == rep[0]) {
- repCode = 1;
+ offCode = STORE_REPCODE_1;
} else if (rawOffset == rep[1]) {
- repCode = 2 - ll0;
+ offCode = STORE_REPCODE(2 - ll0);
} else if (rawOffset == rep[2]) {
- repCode = 3 - ll0;
+ offCode = STORE_REPCODE(3 - ll0);
} else if (ll0 && rawOffset == rep[0] - 1) {
- repCode = 3;
- }
- if (repCode) {
- /* ZSTD_storeSeq expects a number in the range [0, 2] to represent a repcode */
- offCode = repCode - 1;
+ offCode = STORE_REPCODE_3;
}
return offCode;
}
@@ -5755,18 +5795,17 @@ static U32 ZSTD_finalizeOffCode(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32
/* Returns 0 on success, and a ZSTD_error otherwise. This function scans through an array of
* ZSTD_Sequence, storing the sequences it finds, until it reaches a block delimiter.
*/
-static size_t ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
- const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
- const void* src, size_t blockSize) {
+static size_t
+ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
+ ZSTD_sequencePosition* seqPos,
+ const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
+ const void* src, size_t blockSize)
+{
U32 idx = seqPos->idx;
BYTE const* ip = (BYTE const*)(src);
const BYTE* const iend = ip + blockSize;
repcodes_t updatedRepcodes;
U32 dictSize;
- U32 litLength;
- U32 matchLength;
- U32 ll0;
- U32 offCode;
if (cctx->cdict) {
dictSize = (U32)cctx->cdict->dictContentSize;
@@ -5777,23 +5816,22 @@ static size_t ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, ZS
}
ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
for (; (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0) && idx < inSeqsSize; ++idx) {
- litLength = inSeqs[idx].litLength;
- matchLength = inSeqs[idx].matchLength;
- ll0 = litLength == 0;
- offCode = ZSTD_finalizeOffCode(inSeqs[idx].offset, updatedRepcodes.rep, ll0);
- updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0);
+ U32 const litLength = inSeqs[idx].litLength;
+ U32 const ll0 = (litLength == 0);
+ U32 const matchLength = inSeqs[idx].matchLength;
+ U32 const offCode = ZSTD_finalizeOffCode(inSeqs[idx].offset, updatedRepcodes.rep, ll0);
+ ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0);
DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offCode, matchLength, litLength);
if (cctx->appliedParams.validateSequences) {
seqPos->posInSrc += litLength + matchLength;
FORWARD_IF_ERROR(ZSTD_validateSequence(offCode, matchLength, seqPos->posInSrc,
- cctx->appliedParams.cParams.windowLog, dictSize,
- cctx->appliedParams.cParams.minMatch),
+ cctx->appliedParams.cParams.windowLog, dictSize),
"Sequence validation failed");
}
RETURN_ERROR_IF(idx - seqPos->idx > cctx->seqStore.maxNbSeq, memory_allocation,
"Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
- ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength - MINMATCH);
+ ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength);
ip += matchLength + litLength;
}
ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t));
@@ -5820,9 +5858,11 @@ static size_t ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, ZS
* avoid splitting a match, or to avoid splitting a match such that it would produce a match
* smaller than MINMATCH. In this case, we return the number of bytes that we didn't read from this block.
*/
-static size_t ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
- const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
- const void* src, size_t blockSize) {
+static size_t
+ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
+ const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
+ const void* src, size_t blockSize)
+{
U32 idx = seqPos->idx;
U32 startPosInSequence = seqPos->posInSequence;
U32 endPosInSequence = seqPos->posInSequence + (U32)blockSize;
@@ -5832,10 +5872,6 @@ static size_t ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_seq
repcodes_t updatedRepcodes;
U32 bytesAdjustment = 0;
U32 finalMatchSplit = 0;
- U32 litLength;
- U32 matchLength;
- U32 rawOffset;
- U32 offCode;
if (cctx->cdict) {
dictSize = cctx->cdict->dictContentSize;
@@ -5849,9 +5885,10 @@ static size_t ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_seq
ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
while (endPosInSequence && idx < inSeqsSize && !finalMatchSplit) {
const ZSTD_Sequence currSeq = inSeqs[idx];
- litLength = currSeq.litLength;
- matchLength = currSeq.matchLength;
- rawOffset = currSeq.offset;
+ U32 litLength = currSeq.litLength;
+ U32 matchLength = currSeq.matchLength;
+ U32 const rawOffset = currSeq.offset;
+ U32 offCode;
/* Modify the sequence depending on where endPosInSequence lies */
if (endPosInSequence >= currSeq.litLength + currSeq.matchLength) {
@@ -5904,22 +5941,21 @@ static size_t ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_seq
}
}
/* Check if this offset can be represented with a repcode */
- { U32 ll0 = (litLength == 0);
+ { U32 const ll0 = (litLength == 0);
offCode = ZSTD_finalizeOffCode(rawOffset, updatedRepcodes.rep, ll0);
- updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0);
+ ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0);
}
if (cctx->appliedParams.validateSequences) {
seqPos->posInSrc += litLength + matchLength;
FORWARD_IF_ERROR(ZSTD_validateSequence(offCode, matchLength, seqPos->posInSrc,
- cctx->appliedParams.cParams.windowLog, dictSize,
- cctx->appliedParams.cParams.minMatch),
+ cctx->appliedParams.cParams.windowLog, dictSize),
"Sequence validation failed");
}
DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offCode, matchLength, litLength);
RETURN_ERROR_IF(idx - seqPos->idx > cctx->seqStore.maxNbSeq, memory_allocation,
"Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
- ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength - MINMATCH);
+ ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength);
ip += matchLength + litLength;
}
DEBUGLOG(5, "Ending seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
@@ -5944,7 +5980,8 @@ static size_t ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_seq
typedef size_t (*ZSTD_sequenceCopier) (ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
const void* src, size_t blockSize);
-static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode) {
+static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode)
+{
ZSTD_sequenceCopier sequenceCopier = NULL;
assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, mode));
if (mode == ZSTD_sf_explicitBlockDelimiters) {
@@ -5958,12 +5995,15 @@ static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode)
/* Compress, block-by-block, all of the sequences given.
*
- * Returns the cumulative size of all compressed blocks (including their headers), otherwise a ZSTD error.
+ * Returns the cumulative size of all compressed blocks (including their headers),
+ * otherwise a ZSTD error.
*/
-static size_t ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
- void* dst, size_t dstCapacity,
- const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
- const void* src, size_t srcSize) {
+static size_t
+ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
+ const void* src, size_t srcSize)
+{
size_t cSize = 0;
U32 lastBlock;
size_t blockSize;
@@ -5973,7 +6013,7 @@ static size_t ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
BYTE const* ip = (BYTE const*)src;
BYTE* op = (BYTE*)dst;
- ZSTD_sequenceCopier sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters);
+ ZSTD_sequenceCopier const sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters);
DEBUGLOG(4, "ZSTD_compressSequences_internal srcSize: %zu, inSeqsSize: %zu", srcSize, inSeqsSize);
/* Special case: empty frame */
@@ -6073,7 +6113,8 @@ static size_t ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstCapacity,
const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
- const void* src, size_t srcSize) {
+ const void* src, size_t srcSize)
+{
BYTE* op = (BYTE*)dst;
size_t cSize = 0;
size_t compressedBlocksSize = 0;
@@ -6140,119 +6181,12 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
/*-===== Pre-defined compression levels =====-*/
+#include "clevels.h"
-#define ZSTD_MAX_CLEVEL 22
int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; }
int ZSTD_defaultCLevel(void) { return ZSTD_CLEVEL_DEFAULT; }
-static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
-{ /* "default" - for any srcSize > 256 KB */
- /* W, C, H, S, L, TL, strat */
- { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */
- { 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */
- { 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */
- { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */
- { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */
- { 21, 18, 19, 2, 5, 2, ZSTD_greedy }, /* level 5 */
- { 21, 19, 19, 3, 5, 4, ZSTD_greedy }, /* level 6 */
- { 21, 19, 19, 3, 5, 8, ZSTD_lazy }, /* level 7 */
- { 21, 19, 19, 3, 5, 16, ZSTD_lazy2 }, /* level 8 */
- { 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */
- { 22, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */
- { 22, 21, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */
- { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 12 */
- { 22, 21, 22, 5, 5, 32, ZSTD_btlazy2 }, /* level 13 */
- { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */
- { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */
- { 22, 22, 22, 5, 5, 48, ZSTD_btopt }, /* level 16 */
- { 23, 23, 22, 5, 4, 64, ZSTD_btopt }, /* level 17 */
- { 23, 23, 22, 6, 3, 64, ZSTD_btultra }, /* level 18 */
- { 23, 24, 22, 7, 3,256, ZSTD_btultra2}, /* level 19 */
- { 25, 25, 23, 7, 3,256, ZSTD_btultra2}, /* level 20 */
- { 26, 26, 24, 7, 3,512, ZSTD_btultra2}, /* level 21 */
- { 27, 27, 25, 9, 3,999, ZSTD_btultra2}, /* level 22 */
-},
-{ /* for srcSize <= 256 KB */
- /* W, C, H, S, L, T, strat */
- { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
- { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */
- { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */
- { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */
- { 18, 16, 17, 2, 5, 2, ZSTD_greedy }, /* level 4.*/
- { 18, 18, 18, 3, 5, 2, ZSTD_greedy }, /* level 5.*/
- { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/
- { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */
- { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
- { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
- { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
- { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/
- { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/
- { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */
- { 18, 18, 19, 4, 3, 32, ZSTD_btopt }, /* level 14.*/
- { 18, 18, 19, 6, 3,128, ZSTD_btopt }, /* level 15.*/
- { 18, 19, 19, 6, 3,128, ZSTD_btultra }, /* level 16.*/
- { 18, 19, 19, 8, 3,256, ZSTD_btultra }, /* level 17.*/
- { 18, 19, 19, 6, 3,128, ZSTD_btultra2}, /* level 18.*/
- { 18, 19, 19, 8, 3,256, ZSTD_btultra2}, /* level 19.*/
- { 18, 19, 19, 10, 3,512, ZSTD_btultra2}, /* level 20.*/
- { 18, 19, 19, 12, 3,512, ZSTD_btultra2}, /* level 21.*/
- { 18, 19, 19, 13, 3,999, ZSTD_btultra2}, /* level 22.*/
-},
-{ /* for srcSize <= 128 KB */
- /* W, C, H, S, L, T, strat */
- { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
- { 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */
- { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */
- { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */
- { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */
- { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */
- { 17, 17, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */
- { 17, 17, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */
- { 17, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
- { 17, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
- { 17, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
- { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */
- { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */
- { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/
- { 17, 18, 17, 4, 3, 32, ZSTD_btopt }, /* level 14.*/
- { 17, 18, 17, 6, 3,256, ZSTD_btopt }, /* level 15.*/
- { 17, 18, 17, 6, 3,128, ZSTD_btultra }, /* level 16.*/
- { 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 17.*/
- { 17, 18, 17, 10, 3,512, ZSTD_btultra }, /* level 18.*/
- { 17, 18, 17, 5, 3,256, ZSTD_btultra2}, /* level 19.*/
- { 17, 18, 17, 7, 3,512, ZSTD_btultra2}, /* level 20.*/
- { 17, 18, 17, 9, 3,512, ZSTD_btultra2}, /* level 21.*/
- { 17, 18, 17, 11, 3,999, ZSTD_btultra2}, /* level 22.*/
-},
-{ /* for srcSize <= 16 KB */
- /* W, C, H, S, L, T, strat */
- { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
- { 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */
- { 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */
- { 14, 14, 15, 2, 4, 0, ZSTD_dfast }, /* level 3 */
- { 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4 */
- { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/
- { 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */
- { 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */
- { 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/
- { 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/
- { 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/
- { 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/
- { 14, 15, 14, 4, 3, 24, ZSTD_btopt }, /* level 12.*/
- { 14, 15, 14, 5, 3, 32, ZSTD_btultra }, /* level 13.*/
- { 14, 15, 15, 6, 3, 64, ZSTD_btultra }, /* level 14.*/
- { 14, 15, 15, 7, 3,256, ZSTD_btultra }, /* level 15.*/
- { 14, 15, 15, 5, 3, 48, ZSTD_btultra2}, /* level 16.*/
- { 14, 15, 15, 6, 3,128, ZSTD_btultra2}, /* level 17.*/
- { 14, 15, 15, 7, 3,256, ZSTD_btultra2}, /* level 18.*/
- { 14, 15, 15, 8, 3,256, ZSTD_btultra2}, /* level 19.*/
- { 14, 15, 15, 8, 3,512, ZSTD_btultra2}, /* level 20.*/
- { 14, 15, 15, 9, 3,512, ZSTD_btultra2}, /* level 21.*/
- { 14, 15, 15, 10, 3,999, ZSTD_btultra2}, /* level 22.*/
-},
-};
-
static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize)
{
ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, 0, dictSize, ZSTD_cpm_createCDict);
diff --git a/thirdparty/zstd/compress/zstd_compress_internal.h b/thirdparty/zstd/compress/zstd_compress_internal.h
index 3b04fd09f6..c406e794bd 100644
--- a/thirdparty/zstd/compress/zstd_compress_internal.h
+++ b/thirdparty/zstd/compress/zstd_compress_internal.h
@@ -63,7 +63,7 @@ typedef struct {
} ZSTD_localDict;
typedef struct {
- HUF_CElt CTable[HUF_CTABLE_SIZE_U32(255)];
+ HUF_CElt CTable[HUF_CTABLE_SIZE_ST(255)];
HUF_repeat repeatMode;
} ZSTD_hufCTables_t;
@@ -129,7 +129,7 @@ size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr,
*********************************/
typedef struct {
- U32 off; /* Offset code (offset + ZSTD_REP_MOVE) for the match */
+ U32 off; /* Offset sumtype code for the match, using ZSTD_storeSeq() format */
U32 len; /* Raw length of match */
} ZSTD_match_t;
@@ -179,7 +179,7 @@ typedef struct {
U32 offCodeSumBasePrice; /* to compare to log2(offreq) */
ZSTD_OptPrice_e priceType; /* prices can be determined dynamically, or follow a pre-defined cost structure */
const ZSTD_entropyCTables_t* symbolCosts; /* pre-calculated dictionary statistics */
- ZSTD_literalCompressionMode_e literalCompressionMode;
+ ZSTD_paramSwitch_e literalCompressionMode;
} optState_t;
typedef struct {
@@ -199,6 +199,8 @@ typedef struct {
*/
} ZSTD_window_t;
+#define ZSTD_WINDOW_START_INDEX 2
+
typedef struct ZSTD_matchState_t ZSTD_matchState_t;
#define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */
@@ -264,7 +266,7 @@ typedef struct {
} ldmState_t;
typedef struct {
- U32 enableLdm; /* 1 if enable long distance matching */
+ ZSTD_paramSwitch_e enableLdm; /* ZSTD_ps_enable to enable LDM. ZSTD_ps_auto by default */
U32 hashLog; /* Log size of hashTable */
U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */
U32 minMatchLength; /* Minimum match length */
@@ -295,7 +297,7 @@ struct ZSTD_CCtx_params_s {
* There is no guarantee that hint is close to actual source size */
ZSTD_dictAttachPref_e attachDictPref;
- ZSTD_literalCompressionMode_e literalCompressionMode;
+ ZSTD_paramSwitch_e literalCompressionMode;
/* Multithreading: used to pass parameters to mtctx */
int nbWorkers;
@@ -318,10 +320,10 @@ struct ZSTD_CCtx_params_s {
int validateSequences;
/* Block splitting */
- int splitBlocks;
+ ZSTD_paramSwitch_e useBlockSplitter;
/* Param for deciding whether to use row-based matchfinder */
- ZSTD_useRowMatchFinderMode_e useRowMatchFinder;
+ ZSTD_paramSwitch_e useRowMatchFinder;
/* Always load a dictionary in ext-dict mode (not prefix mode)? */
int deterministicRefPrefix;
@@ -343,6 +345,22 @@ typedef enum {
ZSTDb_buffered
} ZSTD_buffered_policy_e;
+/**
+ * Struct that contains all elements of block splitter that should be allocated
+ * in a wksp.
+ */
+#define ZSTD_MAX_NB_BLOCK_SPLITS 196
+typedef struct {
+ seqStore_t fullSeqStoreChunk;
+ seqStore_t firstHalfSeqStore;
+ seqStore_t secondHalfSeqStore;
+ seqStore_t currSeqStore;
+ seqStore_t nextSeqStore;
+
+ U32 partitions[ZSTD_MAX_NB_BLOCK_SPLITS];
+ ZSTD_entropyCTablesMetadata_t entropyMetadata;
+} ZSTD_blockSplitCtx;
+
struct ZSTD_CCtx_s {
ZSTD_compressionStage_e stage;
int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */
@@ -374,7 +392,7 @@ struct ZSTD_CCtx_s {
ZSTD_blockState_t blockState;
U32* entropyWorkspace; /* entropy workspace of ENTROPY_WORKSPACE_SIZE bytes */
- /* Wether we are streaming or not */
+ /* Whether we are streaming or not */
ZSTD_buffered_policy_e bufferedPolicy;
/* streaming */
@@ -408,6 +426,9 @@ struct ZSTD_CCtx_s {
#if ZSTD_TRACE
ZSTD_TraceCtx traceCtx;
#endif
+
+ /* Workspace for block splitter */
+ ZSTD_blockSplitCtx blockSplitCtx;
};
typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e;
@@ -442,7 +463,7 @@ typedef enum {
typedef size_t (*ZSTD_blockCompressor) (
ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
-ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRowMatchFinderMode_e rowMatchfinderMode, ZSTD_dictMode_e dictMode);
+ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramSwitch_e rowMatchfinderMode, ZSTD_dictMode_e dictMode);
MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
@@ -476,31 +497,6 @@ MEM_STATIC U32 ZSTD_MLcode(U32 mlBase)
return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase];
}
-typedef struct repcodes_s {
- U32 rep[3];
-} repcodes_t;
-
-MEM_STATIC repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 const ll0)
-{
- repcodes_t newReps;
- if (offset >= ZSTD_REP_NUM) { /* full offset */
- newReps.rep[2] = rep[1];
- newReps.rep[1] = rep[0];
- newReps.rep[0] = offset - ZSTD_REP_MOVE;
- } else { /* repcode */
- U32 const repCode = offset + ll0;
- if (repCode > 0) { /* note : if repCode==0, no change */
- U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
- newReps.rep[2] = (repCode >= 2) ? rep[1] : rep[2];
- newReps.rep[1] = rep[0];
- newReps.rep[0] = currentOffset;
- } else { /* repCode == 0 */
- ZSTD_memcpy(&newReps, rep, sizeof(newReps));
- }
- }
- return newReps;
-}
-
/* ZSTD_cParam_withinBounds:
* @return 1 if value is within cParam bounds,
* 0 otherwise */
@@ -549,17 +545,17 @@ MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
return (srcSize >> minlog) + 2;
}
-MEM_STATIC int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParams)
+MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params* cctxParams)
{
switch (cctxParams->literalCompressionMode) {
- case ZSTD_lcm_huffman:
+ case ZSTD_ps_enable:
return 0;
- case ZSTD_lcm_uncompressed:
+ case ZSTD_ps_disable:
return 1;
default:
assert(0 /* impossible: pre-validated */);
- /* fall-through */
- case ZSTD_lcm_auto:
+ ZSTD_FALLTHROUGH;
+ case ZSTD_ps_auto:
return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
}
}
@@ -569,7 +565,9 @@ MEM_STATIC int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParam
* Only called when the sequence ends past ilimit_w, so it only needs to be optimized for single
* large copies.
*/
-static void ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE const* ilimit_w) {
+static void
+ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE const* ilimit_w)
+{
assert(iend > ilimit_w);
if (ip <= ilimit_w) {
ZSTD_wildcopy(op, ip, ilimit_w - ip, ZSTD_no_overlap);
@@ -579,14 +577,30 @@ static void ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const ie
while (ip < iend) *op++ = *ip++;
}
+#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
+#define STORE_REPCODE_1 STORE_REPCODE(1)
+#define STORE_REPCODE_2 STORE_REPCODE(2)
+#define STORE_REPCODE_3 STORE_REPCODE(3)
+#define STORE_REPCODE(r) (assert((r)>=1), assert((r)<=3), (r)-1)
+#define STORE_OFFSET(o) (assert((o)>0), o + ZSTD_REP_MOVE)
+#define STORED_IS_OFFSET(o) ((o) > ZSTD_REP_MOVE)
+#define STORED_IS_REPCODE(o) ((o) <= ZSTD_REP_MOVE)
+#define STORED_OFFSET(o) (assert(STORED_IS_OFFSET(o)), (o)-ZSTD_REP_MOVE)
+#define STORED_REPCODE(o) (assert(STORED_IS_REPCODE(o)), (o)+1) /* returns ID 1,2,3 */
+#define STORED_TO_OFFBASE(o) ((o)+1)
+#define OFFBASE_TO_STORED(o) ((o)-1)
+
/*! ZSTD_storeSeq() :
- * Store a sequence (litlen, litPtr, offCode and mlBase) into seqStore_t.
- * `offCode` : distance to match + ZSTD_REP_MOVE (values <= ZSTD_REP_MOVE are repCodes).
- * `mlBase` : matchLength - MINMATCH
+ * Store a sequence (litlen, litPtr, offCode and matchLength) into seqStore_t.
+ * @offBase_minus1 : Users should use employ macros STORE_REPCODE_X and STORE_OFFSET().
+ * @matchLength : must be >= MINMATCH
* Allowed to overread literals up to litLimit.
*/
-HINT_INLINE UNUSED_ATTR
-void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, const BYTE* litLimit, U32 offCode, size_t mlBase)
+HINT_INLINE UNUSED_ATTR void
+ZSTD_storeSeq(seqStore_t* seqStorePtr,
+ size_t litLength, const BYTE* literals, const BYTE* litLimit,
+ U32 offBase_minus1,
+ size_t matchLength)
{
BYTE const* const litLimit_w = litLimit - WILDCOPY_OVERLENGTH;
BYTE const* const litEnd = literals + litLength;
@@ -595,7 +609,7 @@ void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* litera
if (g_start==NULL) g_start = (const BYTE*)literals; /* note : index only works for compression within a single segment */
{ U32 const pos = (U32)((const BYTE*)literals - g_start);
DEBUGLOG(6, "Cpos%7u :%3u literals, match%4u bytes at offCode%7u",
- pos, (U32)litLength, (U32)mlBase+MINMATCH, (U32)offCode);
+ pos, (U32)litLength, (U32)matchLength, (U32)offBase_minus1);
}
#endif
assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq);
@@ -626,19 +640,59 @@ void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* litera
seqStorePtr->sequences[0].litLength = (U16)litLength;
/* match offset */
- seqStorePtr->sequences[0].offset = offCode + 1;
+ seqStorePtr->sequences[0].offBase = STORED_TO_OFFBASE(offBase_minus1);
/* match Length */
- if (mlBase>0xFFFF) {
- assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
- seqStorePtr->longLengthType = ZSTD_llt_matchLength;
- seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
+ assert(matchLength >= MINMATCH);
+ { size_t const mlBase = matchLength - MINMATCH;
+ if (mlBase>0xFFFF) {
+ assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
+ seqStorePtr->longLengthType = ZSTD_llt_matchLength;
+ seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
+ }
+ seqStorePtr->sequences[0].mlBase = (U16)mlBase;
}
- seqStorePtr->sequences[0].matchLength = (U16)mlBase;
seqStorePtr->sequences++;
}
+/* ZSTD_updateRep() :
+ * updates in-place @rep (array of repeat offsets)
+ * @offBase_minus1 : sum-type, with same numeric representation as ZSTD_storeSeq()
+ */
+MEM_STATIC void
+ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const offBase_minus1, U32 const ll0)
+{
+ if (STORED_IS_OFFSET(offBase_minus1)) { /* full offset */
+ rep[2] = rep[1];
+ rep[1] = rep[0];
+ rep[0] = STORED_OFFSET(offBase_minus1);
+ } else { /* repcode */
+ U32 const repCode = STORED_REPCODE(offBase_minus1) - 1 + ll0;
+ if (repCode > 0) { /* note : if repCode==0, no change */
+ U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
+ rep[2] = (repCode >= 2) ? rep[1] : rep[2];
+ rep[1] = rep[0];
+ rep[0] = currentOffset;
+ } else { /* repCode == 0 */
+ /* nothing to do */
+ }
+ }
+}
+
+typedef struct repcodes_s {
+ U32 rep[3];
+} repcodes_t;
+
+MEM_STATIC repcodes_t
+ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase_minus1, U32 const ll0)
+{
+ repcodes_t newReps;
+ ZSTD_memcpy(&newReps, rep, sizeof(newReps));
+ ZSTD_updateRep(newReps.rep, offBase_minus1, ll0);
+ return newReps;
+}
+
/*-*************************************
* Match length counter
@@ -651,8 +705,14 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
# if STATIC_BMI2
return _tzcnt_u64(val) >> 3;
# else
- unsigned long r = 0;
- return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0;
+ if (val != 0) {
+ unsigned long r;
+ _BitScanForward64(&r, (U64)val);
+ return (unsigned)(r >> 3);
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
# endif
# elif defined(__GNUC__) && (__GNUC__ >= 4)
return (__builtin_ctzll((U64)val) >> 3);
@@ -669,8 +729,14 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
# endif
} else { /* 32 bits */
# if defined(_MSC_VER)
- unsigned long r=0;
- return _BitScanForward( &r, (U32)val ) ? (unsigned)(r >> 3) : 0;
+ if (val != 0) {
+ unsigned long r;
+ _BitScanForward(&r, (U32)val);
+ return (unsigned)(r >> 3);
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
# elif defined(__GNUC__) && (__GNUC__ >= 3)
return (__builtin_ctz((U32)val) >> 3);
# else
@@ -687,8 +753,14 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
# if STATIC_BMI2
return _lzcnt_u64(val) >> 3;
# else
- unsigned long r = 0;
- return _BitScanReverse64(&r, (U64)val) ? (unsigned)(r >> 3) : 0;
+ if (val != 0) {
+ unsigned long r;
+ _BitScanReverse64(&r, (U64)val);
+ return (unsigned)(r >> 3);
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
# endif
# elif defined(__GNUC__) && (__GNUC__ >= 4)
return (__builtin_clzll(val) >> 3);
@@ -702,8 +774,14 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
# endif
} else { /* 32 bits */
# if defined(_MSC_VER)
- unsigned long r = 0;
- return _BitScanReverse( &r, (unsigned long)val ) ? (unsigned)(r >> 3) : 0;
+ if (val != 0) {
+ unsigned long r;
+ _BitScanReverse(&r, (unsigned long)val);
+ return (unsigned)(r >> 3);
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
# elif defined(__GNUC__) && (__GNUC__ >= 3)
return (__builtin_clz((U32)val) >> 3);
# else
@@ -884,9 +962,9 @@ MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window)
MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window)
{
- return window.dictLimit == 1 &&
- window.lowLimit == 1 &&
- (window.nextSrc - window.base) == 1;
+ return window.dictLimit == ZSTD_WINDOW_START_INDEX &&
+ window.lowLimit == ZSTD_WINDOW_START_INDEX &&
+ (window.nextSrc - window.base) == ZSTD_WINDOW_START_INDEX;
}
/**
@@ -937,7 +1015,9 @@ MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window,
{
U32 const cycleSize = 1u << cycleLog;
U32 const curr = (U32)((BYTE const*)src - window.base);
- U32 const minIndexToOverflowCorrect = cycleSize + MAX(maxDist, cycleSize);
+ U32 const minIndexToOverflowCorrect = cycleSize
+ + MAX(maxDist, cycleSize)
+ + ZSTD_WINDOW_START_INDEX;
/* Adjust the min index to backoff the overflow correction frequency,
* so we don't waste too much CPU in overflow correction. If this
@@ -1012,10 +1092,14 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
U32 const cycleSize = 1u << cycleLog;
U32 const cycleMask = cycleSize - 1;
U32 const curr = (U32)((BYTE const*)src - window->base);
- U32 const currentCycle0 = curr & cycleMask;
- /* Exclude zero so that newCurrent - maxDist >= 1. */
- U32 const currentCycle1 = currentCycle0 == 0 ? cycleSize : currentCycle0;
- U32 const newCurrent = currentCycle1 + MAX(maxDist, cycleSize);
+ U32 const currentCycle = curr & cycleMask;
+ /* Ensure newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX. */
+ U32 const currentCycleCorrection = currentCycle < ZSTD_WINDOW_START_INDEX
+ ? MAX(cycleSize, ZSTD_WINDOW_START_INDEX)
+ : 0;
+ U32 const newCurrent = currentCycle
+ + currentCycleCorrection
+ + MAX(maxDist, cycleSize);
U32 const correction = curr - newCurrent;
/* maxDist must be a power of two so that:
* (newCurrent & cycleMask) == (curr & cycleMask)
@@ -1031,14 +1115,20 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
window->base += correction;
window->dictBase += correction;
- if (window->lowLimit <= correction) window->lowLimit = 1;
- else window->lowLimit -= correction;
- if (window->dictLimit <= correction) window->dictLimit = 1;
- else window->dictLimit -= correction;
+ if (window->lowLimit < correction + ZSTD_WINDOW_START_INDEX) {
+ window->lowLimit = ZSTD_WINDOW_START_INDEX;
+ } else {
+ window->lowLimit -= correction;
+ }
+ if (window->dictLimit < correction + ZSTD_WINDOW_START_INDEX) {
+ window->dictLimit = ZSTD_WINDOW_START_INDEX;
+ } else {
+ window->dictLimit -= correction;
+ }
/* Ensure we can still reference the full window. */
assert(newCurrent >= maxDist);
- assert(newCurrent - maxDist >= 1);
+ assert(newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX);
/* Ensure that lowLimit and dictLimit didn't underflow. */
assert(window->lowLimit <= newCurrent);
assert(window->dictLimit <= newCurrent);
@@ -1149,11 +1239,12 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
ZSTD_memset(window, 0, sizeof(*window));
- window->base = (BYTE const*)"";
- window->dictBase = (BYTE const*)"";
- window->dictLimit = 1; /* start from 1, so that 1st position is valid */
- window->lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
- window->nextSrc = window->base + 1; /* see issue #1241 */
+ window->base = (BYTE const*)" ";
+ window->dictBase = (BYTE const*)" ";
+ ZSTD_STATIC_ASSERT(ZSTD_DUBT_UNSORTED_MARK < ZSTD_WINDOW_START_INDEX); /* Start above ZSTD_DUBT_UNSORTED_MARK */
+ window->dictLimit = ZSTD_WINDOW_START_INDEX; /* start from >0, so that 1st position is valid */
+ window->lowLimit = ZSTD_WINDOW_START_INDEX; /* it ensures first and later CCtx usages compress the same */
+ window->nextSrc = window->base + ZSTD_WINDOW_START_INDEX; /* see issue #1241 */
window->nbOverflowCorrections = 0;
}
@@ -1206,15 +1297,15 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
*/
MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
{
- U32 const maxDistance = 1U << windowLog;
- U32 const lowestValid = ms->window.lowLimit;
- U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
- U32 const isDictionary = (ms->loadedDictEnd != 0);
+ U32 const maxDistance = 1U << windowLog;
+ U32 const lowestValid = ms->window.lowLimit;
+ U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
+ U32 const isDictionary = (ms->loadedDictEnd != 0);
/* When using a dictionary the entire dictionary is valid if a single byte of the dictionary
* is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't
* valid for the entire block. So this check is sufficient to find the lowest valid match index.
*/
- U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
+ U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
return matchLowest;
}
diff --git a/thirdparty/zstd/compress/zstd_compress_literals.c b/thirdparty/zstd/compress/zstd_compress_literals.c
index 008337bb1b..52b0a8059a 100644
--- a/thirdparty/zstd/compress/zstd_compress_literals.c
+++ b/thirdparty/zstd/compress/zstd_compress_literals.c
@@ -73,7 +73,8 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
void* entropyWorkspace, size_t entropyWorkspaceSize,
- const int bmi2)
+ const int bmi2,
+ unsigned suspectUncompressible)
{
size_t const minGain = ZSTD_minGain(srcSize, strategy);
size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
@@ -105,11 +106,11 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
HUF_compress1X_repeat(
ostart+lhSize, dstCapacity-lhSize, src, srcSize,
HUF_SYMBOLVALUE_MAX, HUF_TABLELOG_DEFAULT, entropyWorkspace, entropyWorkspaceSize,
- (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2) :
+ (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2, suspectUncompressible) :
HUF_compress4X_repeat(
ostart+lhSize, dstCapacity-lhSize, src, srcSize,
HUF_SYMBOLVALUE_MAX, HUF_TABLELOG_DEFAULT, entropyWorkspace, entropyWorkspaceSize,
- (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
+ (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2, suspectUncompressible);
if (repeat != HUF_repeat_none) {
/* reused the existing table */
DEBUGLOG(5, "Reusing previous huffman table");
diff --git a/thirdparty/zstd/compress/zstd_compress_literals.h b/thirdparty/zstd/compress/zstd_compress_literals.h
index 9904c0cd30..9775fb97cb 100644
--- a/thirdparty/zstd/compress/zstd_compress_literals.h
+++ b/thirdparty/zstd/compress/zstd_compress_literals.h
@@ -18,12 +18,14 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src,
size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+/* If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */
size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
ZSTD_hufCTables_t* nextHuf,
ZSTD_strategy strategy, int disableLiteralCompression,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
void* entropyWorkspace, size_t entropyWorkspaceSize,
- const int bmi2);
+ const int bmi2,
+ unsigned suspectUncompressible);
#endif /* ZSTD_COMPRESS_LITERALS_H */
diff --git a/thirdparty/zstd/compress/zstd_compress_sequences.c b/thirdparty/zstd/compress/zstd_compress_sequences.c
index 611eabdcbb..f1e40af2ea 100644
--- a/thirdparty/zstd/compress/zstd_compress_sequences.c
+++ b/thirdparty/zstd/compress/zstd_compress_sequences.c
@@ -275,10 +275,11 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
assert(nbSeq_1 > 1);
assert(entropyWorkspaceSize >= sizeof(ZSTD_BuildCTableWksp));
(void)entropyWorkspaceSize;
- FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
- { size_t const NCountSize = FSE_writeNCount(op, oend - op, wksp->norm, max, tableLog); /* overflow protected */
+ FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "FSE_normalizeCount failed");
+ assert(oend >= op);
+ { size_t const NCountSize = FSE_writeNCount(op, (size_t)(oend - op), wksp->norm, max, tableLog); /* overflow protected */
FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
- FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "");
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "FSE_buildCTable_wksp failed");
return NCountSize;
}
}
@@ -312,19 +313,19 @@ ZSTD_encodeSequences_body(
FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]);
BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
if (MEM_32bits()) BIT_flushBits(&blockStream);
- BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
+ BIT_addBits(&blockStream, sequences[nbSeq-1].mlBase, ML_bits[mlCodeTable[nbSeq-1]]);
if (MEM_32bits()) BIT_flushBits(&blockStream);
if (longOffsets) {
U32 const ofBits = ofCodeTable[nbSeq-1];
unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
if (extraBits) {
- BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, extraBits);
BIT_flushBits(&blockStream);
}
- BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offBase >> extraBits,
ofBits - extraBits);
} else {
- BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, ofCodeTable[nbSeq-1]);
}
BIT_flushBits(&blockStream);
@@ -338,8 +339,8 @@ ZSTD_encodeSequences_body(
U32 const mlBits = ML_bits[mlCode];
DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
(unsigned)sequences[n].litLength,
- (unsigned)sequences[n].matchLength + MINMATCH,
- (unsigned)sequences[n].offset);
+ (unsigned)sequences[n].mlBase + MINMATCH,
+ (unsigned)sequences[n].offBase);
/* 32b*/ /* 64b*/
/* (7)*/ /* (7)*/
FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
@@ -350,18 +351,18 @@ ZSTD_encodeSequences_body(
BIT_flushBits(&blockStream); /* (7)*/
BIT_addBits(&blockStream, sequences[n].litLength, llBits);
if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
- BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
+ BIT_addBits(&blockStream, sequences[n].mlBase, mlBits);
if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);
if (longOffsets) {
unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
if (extraBits) {
- BIT_addBits(&blockStream, sequences[n].offset, extraBits);
+ BIT_addBits(&blockStream, sequences[n].offBase, extraBits);
BIT_flushBits(&blockStream); /* (7)*/
}
- BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
+ BIT_addBits(&blockStream, sequences[n].offBase >> extraBits,
ofBits - extraBits); /* 31 */
} else {
- BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */
+ BIT_addBits(&blockStream, sequences[n].offBase, ofBits); /* 31 */
}
BIT_flushBits(&blockStream); /* (7)*/
DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr));
@@ -398,7 +399,7 @@ ZSTD_encodeSequences_default(
#if DYNAMIC_BMI2
-static TARGET_ATTRIBUTE("bmi2") size_t
+static BMI2_TARGET_ATTRIBUTE size_t
ZSTD_encodeSequences_bmi2(
void* dst, size_t dstCapacity,
FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
diff --git a/thirdparty/zstd/compress/zstd_compress_superblock.c b/thirdparty/zstd/compress/zstd_compress_superblock.c
index e4e45069bc..10e3378577 100644
--- a/thirdparty/zstd/compress/zstd_compress_superblock.c
+++ b/thirdparty/zstd/compress/zstd_compress_superblock.c
@@ -132,6 +132,7 @@ static size_t ZSTD_seqDecompressedSize(seqStore_t const* seqStore, const seqDef*
const seqDef* sp = sstart;
size_t matchLengthSum = 0;
size_t litLengthSum = 0;
+ (void)(litLengthSum); /* suppress unused variable warning on some environments */
while (send-sp > 0) {
ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp);
litLengthSum += seqLen.litLength;
@@ -324,7 +325,7 @@ static size_t ZSTD_estimateSubBlockSize_literal(const BYTE* literals, size_t lit
static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type,
const BYTE* codeTable, unsigned maxCode,
size_t nbSeq, const FSE_CTable* fseCTable,
- const U32* additionalBits,
+ const U8* additionalBits,
short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
void* workspace, size_t wkspSize)
{
@@ -474,7 +475,7 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
/* I think there is an optimization opportunity here.
* Calling ZSTD_estimateSubBlockSize for every sequence can be wasteful
* since it recalculates estimate from scratch.
- * For example, it would recount literal distribution and symbol codes everytime.
+ * For example, it would recount literal distribution and symbol codes every time.
*/
cBlockSizeEstimate = ZSTD_estimateSubBlockSize(lp, litSize, ofCodePtr, llCodePtr, mlCodePtr, seqCount,
&nextCBlock->entropy, entropyMetadata,
@@ -538,7 +539,7 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
repcodes_t rep;
ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep));
for (seq = sstart; seq < sp; ++seq) {
- rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0);
+ ZSTD_updateRep(rep.rep, seq->offBase - 1, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0);
}
ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep));
}
diff --git a/thirdparty/zstd/compress/zstd_cwksp.h b/thirdparty/zstd/compress/zstd_cwksp.h
index 2656d26ca2..dc3f40c80c 100644
--- a/thirdparty/zstd/compress/zstd_cwksp.h
+++ b/thirdparty/zstd/compress/zstd_cwksp.h
@@ -219,7 +219,7 @@ MEM_STATIC size_t ZSTD_cwksp_aligned_alloc_size(size_t size) {
MEM_STATIC size_t ZSTD_cwksp_slack_space_required(void) {
/* For alignment, the wksp will always allocate an additional n_1=[1, 64] bytes
* to align the beginning of tables section, as well as another n_2=[0, 63] bytes
- * to align the beginning of the aligned secion.
+ * to align the beginning of the aligned section.
*
* n_1 + n_2 == 64 bytes if the cwksp is freshly allocated, due to tables and
* aligneds being sized in multiples of 64 bytes.
@@ -243,12 +243,14 @@ MEM_STATIC size_t ZSTD_cwksp_bytes_to_align_ptr(void* ptr, const size_t alignByt
/**
* Internal function. Do not use directly.
- * Reserves the given number of bytes within the aligned/buffer segment of the wksp, which
- * counts from the end of the wksp. (as opposed to the object/table segment)
+ * Reserves the given number of bytes within the aligned/buffer segment of the wksp,
+ * which counts from the end of the wksp (as opposed to the object/table segment).
*
* Returns a pointer to the beginning of that space.
*/
-MEM_STATIC void* ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp* ws, size_t const bytes) {
+MEM_STATIC void*
+ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp* ws, size_t const bytes)
+{
void* const alloc = (BYTE*)ws->allocStart - bytes;
void* const bottom = ws->tableEnd;
DEBUGLOG(5, "cwksp: reserving %p %zd bytes, %zd bytes remaining",
@@ -260,6 +262,8 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp* ws, size_t
ws->allocFailed = 1;
return NULL;
}
+ /* the area is reserved from the end of wksp.
+ * If it overlaps with tableValidEnd, it voids guarantees on values' range */
if (alloc < ws->tableValidEnd) {
ws->tableValidEnd = alloc;
}
@@ -269,10 +273,12 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp* ws, size_t
/**
* Moves the cwksp to the next phase, and does any necessary allocations.
+ * cwksp initialization must necessarily go through each phase in order.
* Returns a 0 on success, or zstd error
*/
-MEM_STATIC size_t ZSTD_cwksp_internal_advance_phase(
- ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase) {
+MEM_STATIC size_t
+ZSTD_cwksp_internal_advance_phase(ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase)
+{
assert(phase >= ws->phase);
if (phase > ws->phase) {
/* Going from allocating objects to allocating buffers */
@@ -295,15 +301,15 @@ MEM_STATIC size_t ZSTD_cwksp_internal_advance_phase(
{ /* Align the start of the tables to 64 bytes. Use [0, 63] bytes */
void* const alloc = ws->objectEnd;
size_t const bytesToAlign = ZSTD_cwksp_bytes_to_align_ptr(alloc, ZSTD_CWKSP_ALIGNMENT_BYTES);
- void* const end = (BYTE*)alloc + bytesToAlign;
+ void* const objectEnd = (BYTE*)alloc + bytesToAlign;
DEBUGLOG(5, "reserving table alignment addtl space: %zu", bytesToAlign);
- RETURN_ERROR_IF(end > ws->workspaceEnd, memory_allocation,
+ RETURN_ERROR_IF(objectEnd > ws->workspaceEnd, memory_allocation,
"table phase - alignment initial allocation failed!");
- ws->objectEnd = end;
- ws->tableEnd = end;
- ws->tableValidEnd = end;
- }
- }
+ ws->objectEnd = objectEnd;
+ ws->tableEnd = objectEnd; /* table area starts being empty */
+ if (ws->tableValidEnd < ws->tableEnd) {
+ ws->tableValidEnd = ws->tableEnd;
+ } } }
ws->phase = phase;
ZSTD_cwksp_assert_internal_consistency(ws);
}
@@ -313,15 +319,17 @@ MEM_STATIC size_t ZSTD_cwksp_internal_advance_phase(
/**
* Returns whether this object/buffer/etc was allocated in this workspace.
*/
-MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr) {
+MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr)
+{
return (ptr != NULL) && (ws->workspace <= ptr) && (ptr <= ws->workspaceEnd);
}
/**
* Internal function. Do not use directly.
*/
-MEM_STATIC void* ZSTD_cwksp_reserve_internal(
- ZSTD_cwksp* ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase) {
+MEM_STATIC void*
+ZSTD_cwksp_reserve_internal(ZSTD_cwksp* ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase)
+{
void* alloc;
if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase)) || bytes == 0) {
return NULL;
@@ -351,14 +359,16 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal(
/**
* Reserves and returns unaligned memory.
*/
-MEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes) {
+MEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes)
+{
return (BYTE*)ZSTD_cwksp_reserve_internal(ws, bytes, ZSTD_cwksp_alloc_buffers);
}
/**
* Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes).
*/
-MEM_STATIC void* ZSTD_cwksp_reserve_aligned(ZSTD_cwksp* ws, size_t bytes) {
+MEM_STATIC void* ZSTD_cwksp_reserve_aligned(ZSTD_cwksp* ws, size_t bytes)
+{
void* ptr = ZSTD_cwksp_reserve_internal(ws, ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES),
ZSTD_cwksp_alloc_aligned);
assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1))== 0);
@@ -370,7 +380,8 @@ MEM_STATIC void* ZSTD_cwksp_reserve_aligned(ZSTD_cwksp* ws, size_t bytes) {
* their values remain constrained, allowing us to re-use them without
* memset()-ing them.
*/
-MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) {
+MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes)
+{
const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned;
void* alloc;
void* end;
@@ -408,9 +419,11 @@ MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) {
/**
* Aligned on sizeof(void*).
+ * Note : should happen only once, at workspace first initialization
*/
-MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
- size_t roundedBytes = ZSTD_cwksp_align(bytes, sizeof(void*));
+MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes)
+{
+ size_t const roundedBytes = ZSTD_cwksp_align(bytes, sizeof(void*));
void* alloc = ws->objectEnd;
void* end = (BYTE*)alloc + roundedBytes;
@@ -419,15 +432,15 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
#endif
- DEBUGLOG(5,
+ DEBUGLOG(4,
"cwksp: reserving %p object %zd bytes (rounded to %zd), %zd bytes remaining",
alloc, bytes, roundedBytes, ZSTD_cwksp_available_space(ws) - roundedBytes);
- assert(((size_t)alloc & (sizeof(void*)-1)) == 0);
- assert((bytes & (sizeof(void*)-1)) == 0);
+ assert((size_t)alloc % ZSTD_ALIGNOF(void*) == 0);
+ assert(bytes % ZSTD_ALIGNOF(void*) == 0);
ZSTD_cwksp_assert_internal_consistency(ws);
/* we must be in the first phase, no advance is possible */
if (ws->phase != ZSTD_cwksp_alloc_objects || end > ws->workspaceEnd) {
- DEBUGLOG(4, "cwksp: object alloc failed!");
+ DEBUGLOG(3, "cwksp: object alloc failed!");
ws->allocFailed = 1;
return NULL;
}
@@ -438,7 +451,7 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
/* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
* either size. */
- alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
+ alloc = (BYTE*)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
__asan_unpoison_memory_region(alloc, bytes);
}
@@ -447,7 +460,8 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
return alloc;
}
-MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) {
+MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws)
+{
DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty");
#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
diff --git a/thirdparty/zstd/compress/zstd_double_fast.c b/thirdparty/zstd/compress/zstd_double_fast.c
index d0d3a784dd..76933dea26 100644
--- a/thirdparty/zstd/compress/zstd_double_fast.c
+++ b/thirdparty/zstd/compress/zstd_double_fast.c
@@ -48,10 +48,216 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,
FORCE_INLINE_TEMPLATE
-size_t ZSTD_compressBlock_doubleFast_generic(
+size_t ZSTD_compressBlock_doubleFast_noDict_generic(
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
+ void const* src, size_t srcSize, U32 const mls /* template */)
+{
+ ZSTD_compressionParameters const* cParams = &ms->cParams;
+ U32* const hashLong = ms->hashTable;
+ const U32 hBitsL = cParams->hashLog;
+ U32* const hashSmall = ms->chainTable;
+ const U32 hBitsS = cParams->chainLog;
+ const BYTE* const base = ms->window.base;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* anchor = istart;
+ const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
+ /* presumes that, if there is a dictionary, it must be using Attach mode */
+ const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog);
+ const BYTE* const prefixLowest = base + prefixLowestIndex;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
+ U32 offset_1=rep[0], offset_2=rep[1];
+ U32 offsetSaved = 0;
+
+ size_t mLength;
+ U32 offset;
+ U32 curr;
+
+ /* how many positions to search before increasing step size */
+ const size_t kStepIncr = 1 << kSearchStrength;
+ /* the position at which to increment the step size if no match is found */
+ const BYTE* nextStep;
+ size_t step; /* the current step size */
+
+ size_t hl0; /* the long hash at ip */
+ size_t hl1; /* the long hash at ip1 */
+
+ U32 idxl0; /* the long match index for ip */
+ U32 idxl1; /* the long match index for ip1 */
+
+ const BYTE* matchl0; /* the long match for ip */
+ const BYTE* matchs0; /* the short match for ip */
+ const BYTE* matchl1; /* the long match for ip1 */
+
+ const BYTE* ip = istart; /* the current position */
+ const BYTE* ip1; /* the next position */
+
+ DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_noDict_generic");
+
+ /* init */
+ ip += ((ip - prefixLowest) == 0);
+ {
+ U32 const current = (U32)(ip - base);
+ U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog);
+ U32 const maxRep = current - windowLow;
+ if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
+ if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
+ }
+
+ /* Outer Loop: one iteration per match found and stored */
+ while (1) {
+ step = 1;
+ nextStep = ip + kStepIncr;
+ ip1 = ip + step;
+
+ if (ip1 > ilimit) {
+ goto _cleanup;
+ }
+
+ hl0 = ZSTD_hashPtr(ip, hBitsL, 8);
+ idxl0 = hashLong[hl0];
+ matchl0 = base + idxl0;
+
+ /* Inner Loop: one iteration per search / position */
+ do {
+ const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls);
+ const U32 idxs0 = hashSmall[hs0];
+ curr = (U32)(ip-base);
+ matchs0 = base + idxs0;
+
+ hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */
+
+ /* check noDict repcode */
+ if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
+ mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
+ ip++;
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_REPCODE_1, mLength);
+ goto _match_stored;
+ }
+
+ hl1 = ZSTD_hashPtr(ip1, hBitsL, 8);
+
+ if (idxl0 > prefixLowestIndex) {
+ /* check prefix long match */
+ if (MEM_read64(matchl0) == MEM_read64(ip)) {
+ mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8;
+ offset = (U32)(ip-matchl0);
+ while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */
+ goto _match_found;
+ }
+ }
+
+ idxl1 = hashLong[hl1];
+ matchl1 = base + idxl1;
+
+ if (idxs0 > prefixLowestIndex) {
+ /* check prefix short match */
+ if (MEM_read32(matchs0) == MEM_read32(ip)) {
+ goto _search_next_long;
+ }
+ }
+
+ if (ip1 >= nextStep) {
+ PREFETCH_L1(ip1 + 64);
+ PREFETCH_L1(ip1 + 128);
+ step++;
+ nextStep += kStepIncr;
+ }
+ ip = ip1;
+ ip1 += step;
+
+ hl0 = hl1;
+ idxl0 = idxl1;
+ matchl0 = matchl1;
+ #if defined(__aarch64__)
+ PREFETCH_L1(ip+256);
+ #endif
+ } while (ip1 <= ilimit);
+
+_cleanup:
+ /* save reps for next block */
+ rep[0] = offset_1 ? offset_1 : offsetSaved;
+ rep[1] = offset_2 ? offset_2 : offsetSaved;
+
+ /* Return the last literals size */
+ return (size_t)(iend - anchor);
+
+_search_next_long:
+
+ /* check prefix long +1 match */
+ if (idxl1 > prefixLowestIndex) {
+ if (MEM_read64(matchl1) == MEM_read64(ip1)) {
+ ip = ip1;
+ mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8;
+ offset = (U32)(ip-matchl1);
+ while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */
+ goto _match_found;
+ }
+ }
+
+ /* if no long +1 match, explore the short match we found */
+ mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4;
+ offset = (U32)(ip - matchs0);
+ while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */
+
+ /* fall-through */
+
+_match_found: /* requires ip, offset, mLength */
+ offset_2 = offset_1;
+ offset_1 = offset;
+
+ if (step < 4) {
+ /* It is unsafe to write this value back to the hashtable when ip1 is
+ * greater than or equal to the new ip we will have after we're done
+ * processing this match. Rather than perform that test directly
+ * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler
+ * more predictable test. The minmatch even if we take a short match is
+ * 4 bytes, so as long as step, the distance between ip and ip1
+ * (initially) is less than 4, we know ip1 < new ip. */
+ hashLong[hl1] = (U32)(ip1 - base);
+ }
+
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
+
+_match_stored:
+ /* match found */
+ ip += mLength;
+ anchor = ip;
+
+ if (ip <= ilimit) {
+ /* Complementary insertion */
+ /* done after iLimit test, as candidates could be > iend-8 */
+ { U32 const indexToInsert = curr+2;
+ hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
+ hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
+ hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
+ hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
+ }
+
+ /* check immediate repcode */
+ while ( (ip <= ilimit)
+ && ( (offset_2>0)
+ & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
+ /* store sequence */
+ size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
+ U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
+ hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, STORE_REPCODE_1, rLength);
+ ip += rLength;
+ anchor = ip;
+ continue; /* faster when present ... (?) */
+ }
+ }
+ }
+}
+
+
+FORCE_INLINE_TEMPLATE
+size_t ZSTD_compressBlock_doubleFast_dictMatchState_generic(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize,
- U32 const mls /* template */, ZSTD_dictMode_e const dictMode)
+ U32 const mls /* template */)
{
ZSTD_compressionParameters const* cParams = &ms->cParams;
U32* const hashLong = ms->hashTable;
@@ -72,54 +278,30 @@ size_t ZSTD_compressBlock_doubleFast_generic(
U32 offsetSaved = 0;
const ZSTD_matchState_t* const dms = ms->dictMatchState;
- const ZSTD_compressionParameters* const dictCParams =
- dictMode == ZSTD_dictMatchState ?
- &dms->cParams : NULL;
- const U32* const dictHashLong = dictMode == ZSTD_dictMatchState ?
- dms->hashTable : NULL;
- const U32* const dictHashSmall = dictMode == ZSTD_dictMatchState ?
- dms->chainTable : NULL;
- const U32 dictStartIndex = dictMode == ZSTD_dictMatchState ?
- dms->window.dictLimit : 0;
- const BYTE* const dictBase = dictMode == ZSTD_dictMatchState ?
- dms->window.base : NULL;
- const BYTE* const dictStart = dictMode == ZSTD_dictMatchState ?
- dictBase + dictStartIndex : NULL;
- const BYTE* const dictEnd = dictMode == ZSTD_dictMatchState ?
- dms->window.nextSrc : NULL;
- const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ?
- prefixLowestIndex - (U32)(dictEnd - dictBase) :
- 0;
- const U32 dictHBitsL = dictMode == ZSTD_dictMatchState ?
- dictCParams->hashLog : hBitsL;
- const U32 dictHBitsS = dictMode == ZSTD_dictMatchState ?
- dictCParams->chainLog : hBitsS;
+ const ZSTD_compressionParameters* const dictCParams = &dms->cParams;
+ const U32* const dictHashLong = dms->hashTable;
+ const U32* const dictHashSmall = dms->chainTable;
+ const U32 dictStartIndex = dms->window.dictLimit;
+ const BYTE* const dictBase = dms->window.base;
+ const BYTE* const dictStart = dictBase + dictStartIndex;
+ const BYTE* const dictEnd = dms->window.nextSrc;
+ const U32 dictIndexDelta = prefixLowestIndex - (U32)(dictEnd - dictBase);
+ const U32 dictHBitsL = dictCParams->hashLog;
+ const U32 dictHBitsS = dictCParams->chainLog;
const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictStart));
- DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_generic");
-
- assert(dictMode == ZSTD_noDict || dictMode == ZSTD_dictMatchState);
+ DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_dictMatchState_generic");
/* if a dictionary is attached, it must be within window range */
- if (dictMode == ZSTD_dictMatchState) {
- assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex);
- }
+ assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex);
/* init */
ip += (dictAndPrefixLength == 0);
- if (dictMode == ZSTD_noDict) {
- U32 const curr = (U32)(ip - base);
- U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog);
- U32 const maxRep = curr - windowLow;
- if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
- if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
- }
- if (dictMode == ZSTD_dictMatchState) {
- /* dictMatchState repCode checks don't currently handle repCode == 0
- * disabling. */
- assert(offset_1 <= dictAndPrefixLength);
- assert(offset_2 <= dictAndPrefixLength);
- }
+
+ /* dictMatchState repCode checks don't currently handle repCode == 0
+ * disabling. */
+ assert(offset_1 <= dictAndPrefixLength);
+ assert(offset_2 <= dictAndPrefixLength);
/* Main Search Loop */
while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
@@ -135,29 +317,18 @@ size_t ZSTD_compressBlock_doubleFast_generic(
const BYTE* matchLong = base + matchIndexL;
const BYTE* match = base + matchIndexS;
const U32 repIndex = curr + 1 - offset_1;
- const BYTE* repMatch = (dictMode == ZSTD_dictMatchState
- && repIndex < prefixLowestIndex) ?
+ const BYTE* repMatch = (repIndex < prefixLowestIndex) ?
dictBase + (repIndex - dictIndexDelta) :
base + repIndex;
hashLong[h2] = hashSmall[h] = curr; /* update hash tables */
- /* check dictMatchState repcode */
- if (dictMode == ZSTD_dictMatchState
- && ((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
+ /* check repcode */
+ if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
ip++;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
- goto _match_stored;
- }
-
- /* check noDict repcode */
- if ( dictMode == ZSTD_noDict
- && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {
- mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
- ip++;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_REPCODE_1, mLength);
goto _match_stored;
}
@@ -169,7 +340,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
goto _match_found;
}
- } else if (dictMode == ZSTD_dictMatchState) {
+ } else {
/* check dictMatchState long match */
U32 const dictMatchIndexL = dictHashLong[dictHL];
const BYTE* dictMatchL = dictBase + dictMatchIndexL;
@@ -187,7 +358,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
if (MEM_read32(match) == MEM_read32(ip)) {
goto _search_next_long;
}
- } else if (dictMode == ZSTD_dictMatchState) {
+ } else {
/* check dictMatchState short match */
U32 const dictMatchIndexS = dictHashSmall[dictHS];
match = dictBase + dictMatchIndexS;
@@ -220,7 +391,7 @@ _search_next_long:
while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */
goto _match_found;
}
- } else if (dictMode == ZSTD_dictMatchState) {
+ } else {
/* check dict long +1 match */
U32 const dictMatchIndexL3 = dictHashLong[dictHLNext];
const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3;
@@ -234,7 +405,7 @@ _search_next_long:
} } }
/* if no long +1 match, explore the short match we found */
- if (dictMode == ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) {
+ if (matchIndexS < prefixLowestIndex) {
mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4;
offset = (U32)(curr - matchIndexS);
while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
@@ -244,13 +415,11 @@ _search_next_long:
while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
}
- /* fall-through */
-
_match_found:
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
_match_stored:
/* match found */
@@ -268,43 +437,27 @@ _match_stored:
}
/* check immediate repcode */
- if (dictMode == ZSTD_dictMatchState) {
- while (ip <= ilimit) {
- U32 const current2 = (U32)(ip-base);
- U32 const repIndex2 = current2 - offset_2;
- const BYTE* repMatch2 = dictMode == ZSTD_dictMatchState
- && repIndex2 < prefixLowestIndex ?
- dictBase + repIndex2 - dictIndexDelta :
- base + repIndex2;
- if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)
- && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
- const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend;
- size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4;
- U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
- ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH);
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
- hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
- ip += repLength2;
- anchor = ip;
- continue;
- }
- break;
- } }
-
- if (dictMode == ZSTD_noDict) {
- while ( (ip <= ilimit)
- && ( (offset_2>0)
- & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
- /* store sequence */
- size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
- U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
- hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
- ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH);
- ip += rLength;
+ while (ip <= ilimit) {
+ U32 const current2 = (U32)(ip-base);
+ U32 const repIndex2 = current2 - offset_2;
+ const BYTE* repMatch2 = repIndex2 < prefixLowestIndex ?
+ dictBase + repIndex2 - dictIndexDelta :
+ base + repIndex2;
+ if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
+ const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend;
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4;
+ U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, STORE_REPCODE_1, repLength2);
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
+ hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
+ ip += repLength2;
anchor = ip;
- continue; /* faster when present ... (?) */
- } } }
+ continue;
+ }
+ break;
+ }
+ }
} /* while (ip < ilimit) */
/* save reps for next block */
@@ -315,6 +468,24 @@ _match_stored:
return (size_t)(iend - anchor);
}
+#define ZSTD_GEN_DFAST_FN(dictMode, mls) \
+ static size_t ZSTD_compressBlock_doubleFast_##dictMode##_##mls( \
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \
+ void const* src, size_t srcSize) \
+ { \
+ return ZSTD_compressBlock_doubleFast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls); \
+ }
+
+ZSTD_GEN_DFAST_FN(noDict, 4)
+ZSTD_GEN_DFAST_FN(noDict, 5)
+ZSTD_GEN_DFAST_FN(noDict, 6)
+ZSTD_GEN_DFAST_FN(noDict, 7)
+
+ZSTD_GEN_DFAST_FN(dictMatchState, 4)
+ZSTD_GEN_DFAST_FN(dictMatchState, 5)
+ZSTD_GEN_DFAST_FN(dictMatchState, 6)
+ZSTD_GEN_DFAST_FN(dictMatchState, 7)
+
size_t ZSTD_compressBlock_doubleFast(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -325,13 +496,13 @@ size_t ZSTD_compressBlock_doubleFast(
{
default: /* includes case 3 */
case 4 :
- return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 4, ZSTD_noDict);
+ return ZSTD_compressBlock_doubleFast_noDict_4(ms, seqStore, rep, src, srcSize);
case 5 :
- return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 5, ZSTD_noDict);
+ return ZSTD_compressBlock_doubleFast_noDict_5(ms, seqStore, rep, src, srcSize);
case 6 :
- return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 6, ZSTD_noDict);
+ return ZSTD_compressBlock_doubleFast_noDict_6(ms, seqStore, rep, src, srcSize);
case 7 :
- return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 7, ZSTD_noDict);
+ return ZSTD_compressBlock_doubleFast_noDict_7(ms, seqStore, rep, src, srcSize);
}
}
@@ -345,13 +516,13 @@ size_t ZSTD_compressBlock_doubleFast_dictMatchState(
{
default: /* includes case 3 */
case 4 :
- return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 4, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_doubleFast_dictMatchState_4(ms, seqStore, rep, src, srcSize);
case 5 :
- return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 5, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_doubleFast_dictMatchState_5(ms, seqStore, rep, src, srcSize);
case 6 :
- return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 6, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_doubleFast_dictMatchState_6(ms, seqStore, rep, src, srcSize);
case 7 :
- return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 7, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_doubleFast_dictMatchState_7(ms, seqStore, rep, src, srcSize);
}
}
@@ -387,7 +558,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
/* if extDict is invalidated due to maxDistance, switch to "regular" variant */
if (prefixStartIndex == dictStartIndex)
- return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, mls, ZSTD_noDict);
+ return ZSTD_compressBlock_doubleFast(ms, seqStore, rep, src, srcSize);
/* Search Loop */
while (ip < ilimit) { /* < instead of <=, because (ip+1) */
@@ -409,12 +580,12 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */
if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */
- & (offset_1 < curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */
+ & (offset_1 <= curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
ip++;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_REPCODE_1, mLength);
} else {
if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend;
@@ -425,7 +596,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
} else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) {
size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
@@ -450,7 +621,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
}
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
} else {
ip += ((ip-anchor) >> kSearchStrength) + 1;
@@ -477,12 +648,12 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
U32 const repIndex2 = current2 - offset_2;
const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) /* intentional overflow : ensure repIndex2 doesn't overlap dict + prefix */
- & (offset_2 < current2 - dictStartIndex))
+ & (offset_2 <= current2 - dictStartIndex))
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
- ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH);
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, STORE_REPCODE_1, repLength2);
hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
ip += repLength2;
@@ -500,6 +671,10 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
return (size_t)(iend - anchor);
}
+ZSTD_GEN_DFAST_FN(extDict, 4)
+ZSTD_GEN_DFAST_FN(extDict, 5)
+ZSTD_GEN_DFAST_FN(extDict, 6)
+ZSTD_GEN_DFAST_FN(extDict, 7)
size_t ZSTD_compressBlock_doubleFast_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -510,12 +685,12 @@ size_t ZSTD_compressBlock_doubleFast_extDict(
{
default: /* includes case 3 */
case 4 :
- return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 4);
+ return ZSTD_compressBlock_doubleFast_extDict_4(ms, seqStore, rep, src, srcSize);
case 5 :
- return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 5);
+ return ZSTD_compressBlock_doubleFast_extDict_5(ms, seqStore, rep, src, srcSize);
case 6 :
- return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 6);
+ return ZSTD_compressBlock_doubleFast_extDict_6(ms, seqStore, rep, src, srcSize);
case 7 :
- return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 7);
+ return ZSTD_compressBlock_doubleFast_extDict_7(ms, seqStore, rep, src, srcSize);
}
}
diff --git a/thirdparty/zstd/compress/zstd_fast.c b/thirdparty/zstd/compress/zstd_fast.c
index 4edc04dccd..802fc31579 100644
--- a/thirdparty/zstd/compress/zstd_fast.c
+++ b/thirdparty/zstd/compress/zstd_fast.c
@@ -43,145 +43,294 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
}
+/**
+ * If you squint hard enough (and ignore repcodes), the search operation at any
+ * given position is broken into 4 stages:
+ *
+ * 1. Hash (map position to hash value via input read)
+ * 2. Lookup (map hash val to index via hashtable read)
+ * 3. Load (map index to value at that position via input read)
+ * 4. Compare
+ *
+ * Each of these steps involves a memory read at an address which is computed
+ * from the previous step. This means these steps must be sequenced and their
+ * latencies are cumulative.
+ *
+ * Rather than do 1->2->3->4 sequentially for a single position before moving
+ * onto the next, this implementation interleaves these operations across the
+ * next few positions:
+ *
+ * R = Repcode Read & Compare
+ * H = Hash
+ * T = Table Lookup
+ * M = Match Read & Compare
+ *
+ * Pos | Time -->
+ * ----+-------------------
+ * N | ... M
+ * N+1 | ... TM
+ * N+2 | R H T M
+ * N+3 | H TM
+ * N+4 | R H T M
+ * N+5 | H ...
+ * N+6 | R ...
+ *
+ * This is very much analogous to the pipelining of execution in a CPU. And just
+ * like a CPU, we have to dump the pipeline when we find a match (i.e., take a
+ * branch).
+ *
+ * When this happens, we throw away our current state, and do the following prep
+ * to re-enter the loop:
+ *
+ * Pos | Time -->
+ * ----+-------------------
+ * N | H T
+ * N+1 | H
+ *
+ * This is also the work we do at the beginning to enter the loop initially.
+ */
FORCE_INLINE_TEMPLATE size_t
-ZSTD_compressBlock_fast_generic(
+ZSTD_compressBlock_fast_noDict_generic(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize,
- U32 const mls)
+ U32 const mls, U32 const hasStep)
{
const ZSTD_compressionParameters* const cParams = &ms->cParams;
U32* const hashTable = ms->hashTable;
U32 const hlog = cParams->hashLog;
/* support stepSize of 0 */
- size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1;
+ size_t const stepSize = hasStep ? (cParams->targetLength + !(cParams->targetLength) + 1) : 2;
const BYTE* const base = ms->window.base;
const BYTE* const istart = (const BYTE*)src;
- /* We check ip0 (ip + 0) and ip1 (ip + 1) each loop */
- const BYTE* ip0 = istart;
- const BYTE* ip1;
- const BYTE* anchor = istart;
const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
const U32 prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog);
const BYTE* const prefixStart = base + prefixStartIndex;
const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - HASH_READ_SIZE;
- U32 offset_1=rep[0], offset_2=rep[1];
+
+ const BYTE* anchor = istart;
+ const BYTE* ip0 = istart;
+ const BYTE* ip1;
+ const BYTE* ip2;
+ const BYTE* ip3;
+ U32 current0;
+
+ U32 rep_offset1 = rep[0];
+ U32 rep_offset2 = rep[1];
U32 offsetSaved = 0;
- /* init */
+ size_t hash0; /* hash for ip0 */
+ size_t hash1; /* hash for ip1 */
+ U32 idx; /* match idx for ip0 */
+ U32 mval; /* src value at match idx */
+
+ U32 offcode;
+ const BYTE* match0;
+ size_t mLength;
+
+ /* ip0 and ip1 are always adjacent. The targetLength skipping and
+ * uncompressibility acceleration is applied to every other position,
+ * matching the behavior of #1562. step therefore represents the gap
+ * between pairs of positions, from ip0 to ip2 or ip1 to ip3. */
+ size_t step;
+ const BYTE* nextStep;
+ const size_t kStepIncr = (1 << (kSearchStrength - 1));
+
DEBUGLOG(5, "ZSTD_compressBlock_fast_generic");
ip0 += (ip0 == prefixStart);
- ip1 = ip0 + 1;
{ U32 const curr = (U32)(ip0 - base);
U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog);
U32 const maxRep = curr - windowLow;
- if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
- if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
+ if (rep_offset2 > maxRep) offsetSaved = rep_offset2, rep_offset2 = 0;
+ if (rep_offset1 > maxRep) offsetSaved = rep_offset1, rep_offset1 = 0;
}
- /* Main Search Loop */
-#ifdef __INTEL_COMPILER
- /* From intel 'The vector pragma indicates that the loop should be
- * vectorized if it is legal to do so'. Can be used together with
- * #pragma ivdep (but have opted to exclude that because intel
- * warns against using it).*/
- #pragma vector always
-#endif
- while (ip1 < ilimit) { /* < instead of <=, because check at ip0+2 */
- size_t mLength;
- BYTE const* ip2 = ip0 + 2;
- size_t const h0 = ZSTD_hashPtr(ip0, hlog, mls);
- U32 const val0 = MEM_read32(ip0);
- size_t const h1 = ZSTD_hashPtr(ip1, hlog, mls);
- U32 const val1 = MEM_read32(ip1);
- U32 const current0 = (U32)(ip0-base);
- U32 const current1 = (U32)(ip1-base);
- U32 const matchIndex0 = hashTable[h0];
- U32 const matchIndex1 = hashTable[h1];
- BYTE const* repMatch = ip2 - offset_1;
- const BYTE* match0 = base + matchIndex0;
- const BYTE* match1 = base + matchIndex1;
- U32 offcode;
-
-#if defined(__aarch64__)
- PREFETCH_L1(ip0+256);
-#endif
-
- hashTable[h0] = current0; /* update hash table */
- hashTable[h1] = current1; /* update hash table */
-
- assert(ip0 + 1 == ip1);
-
- if ((offset_1 > 0) & (MEM_read32(repMatch) == MEM_read32(ip2))) {
- mLength = (ip2[-1] == repMatch[-1]) ? 1 : 0;
- ip0 = ip2 - mLength;
- match0 = repMatch - mLength;
+ /* start each op */
+_start: /* Requires: ip0 */
+
+ step = stepSize;
+ nextStep = ip0 + kStepIncr;
+
+ /* calculate positions, ip0 - anchor == 0, so we skip step calc */
+ ip1 = ip0 + 1;
+ ip2 = ip0 + step;
+ ip3 = ip2 + 1;
+
+ if (ip3 >= ilimit) {
+ goto _cleanup;
+ }
+
+ hash0 = ZSTD_hashPtr(ip0, hlog, mls);
+ hash1 = ZSTD_hashPtr(ip1, hlog, mls);
+
+ idx = hashTable[hash0];
+
+ do {
+ /* load repcode match for ip[2]*/
+ const U32 rval = MEM_read32(ip2 - rep_offset1);
+
+ /* write back hash table entry */
+ current0 = (U32)(ip0 - base);
+ hashTable[hash0] = current0;
+
+ /* check repcode at ip[2] */
+ if ((MEM_read32(ip2) == rval) & (rep_offset1 > 0)) {
+ ip0 = ip2;
+ match0 = ip0 - rep_offset1;
+ mLength = ip0[-1] == match0[-1];
+ ip0 -= mLength;
+ match0 -= mLength;
+ offcode = STORE_REPCODE_1;
mLength += 4;
- offcode = 0;
goto _match;
}
- if ((matchIndex0 > prefixStartIndex) && MEM_read32(match0) == val0) {
- /* found a regular match */
- goto _offset;
+
+ /* load match for ip[0] */
+ if (idx >= prefixStartIndex) {
+ mval = MEM_read32(base + idx);
+ } else {
+ mval = MEM_read32(ip0) ^ 1; /* guaranteed to not match. */
}
- if ((matchIndex1 > prefixStartIndex) && MEM_read32(match1) == val1) {
- /* found a regular match after one literal */
- ip0 = ip1;
- match0 = match1;
+
+ /* check match at ip[0] */
+ if (MEM_read32(ip0) == mval) {
+ /* found a match! */
goto _offset;
}
- { size_t const step = ((size_t)(ip0-anchor) >> (kSearchStrength - 1)) + stepSize;
- assert(step >= 2);
- ip0 += step;
- ip1 += step;
- continue;
+
+ /* lookup ip[1] */
+ idx = hashTable[hash1];
+
+ /* hash ip[2] */
+ hash0 = hash1;
+ hash1 = ZSTD_hashPtr(ip2, hlog, mls);
+
+ /* advance to next positions */
+ ip0 = ip1;
+ ip1 = ip2;
+ ip2 = ip3;
+
+ /* write back hash table entry */
+ current0 = (U32)(ip0 - base);
+ hashTable[hash0] = current0;
+
+ /* load match for ip[0] */
+ if (idx >= prefixStartIndex) {
+ mval = MEM_read32(base + idx);
+ } else {
+ mval = MEM_read32(ip0) ^ 1; /* guaranteed to not match. */
}
-_offset: /* Requires: ip0, match0 */
- /* Compute the offset code */
- offset_2 = offset_1;
- offset_1 = (U32)(ip0-match0);
- offcode = offset_1 + ZSTD_REP_MOVE;
- mLength = 4;
- /* Count the backwards match length */
- while (((ip0>anchor) & (match0>prefixStart))
- && (ip0[-1] == match0[-1])) { ip0--; match0--; mLength++; } /* catch up */
-_match: /* Requires: ip0, match0, offcode */
- /* Count the forward length */
- mLength += ZSTD_count(ip0+mLength, match0+mLength, iend);
- ZSTD_storeSeq(seqStore, (size_t)(ip0-anchor), anchor, iend, offcode, mLength-MINMATCH);
- /* match found */
- ip0 += mLength;
- anchor = ip0;
+ /* check match at ip[0] */
+ if (MEM_read32(ip0) == mval) {
+ /* found a match! */
+ goto _offset;
+ }
- if (ip0 <= ilimit) {
- /* Fill Table */
- assert(base+current0+2 > istart); /* check base overflow */
- hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */
- hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base);
-
- if (offset_2 > 0) { /* offset_2==0 means offset_2 is invalidated */
- while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - offset_2)) ) {
- /* store sequence */
- size_t const rLength = ZSTD_count(ip0+4, ip0+4-offset_2, iend) + 4;
- { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
- hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base);
- ip0 += rLength;
- ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, 0 /*offCode*/, rLength-MINMATCH);
- anchor = ip0;
- continue; /* faster when present (confirmed on gcc-8) ... (?) */
- } } }
- ip1 = ip0 + 1;
- }
+ /* lookup ip[1] */
+ idx = hashTable[hash1];
+
+ /* hash ip[2] */
+ hash0 = hash1;
+ hash1 = ZSTD_hashPtr(ip2, hlog, mls);
+
+ /* advance to next positions */
+ ip0 = ip1;
+ ip1 = ip2;
+ ip2 = ip0 + step;
+ ip3 = ip1 + step;
+
+ /* calculate step */
+ if (ip2 >= nextStep) {
+ step++;
+ PREFETCH_L1(ip1 + 64);
+ PREFETCH_L1(ip1 + 128);
+ nextStep += kStepIncr;
+ }
+ } while (ip3 < ilimit);
+
+_cleanup:
+ /* Note that there are probably still a couple positions we could search.
+ * However, it seems to be a meaningful performance hit to try to search
+ * them. So let's not. */
/* save reps for next block */
- rep[0] = offset_1 ? offset_1 : offsetSaved;
- rep[1] = offset_2 ? offset_2 : offsetSaved;
+ rep[0] = rep_offset1 ? rep_offset1 : offsetSaved;
+ rep[1] = rep_offset2 ? rep_offset2 : offsetSaved;
/* Return the last literals size */
return (size_t)(iend - anchor);
+
+_offset: /* Requires: ip0, idx */
+
+ /* Compute the offset code. */
+ match0 = base + idx;
+ rep_offset2 = rep_offset1;
+ rep_offset1 = (U32)(ip0-match0);
+ offcode = STORE_OFFSET(rep_offset1);
+ mLength = 4;
+
+ /* Count the backwards match length. */
+ while (((ip0>anchor) & (match0>prefixStart)) && (ip0[-1] == match0[-1])) {
+ ip0--;
+ match0--;
+ mLength++;
+ }
+
+_match: /* Requires: ip0, match0, offcode */
+
+ /* Count the forward length. */
+ mLength += ZSTD_count(ip0 + mLength, match0 + mLength, iend);
+
+ ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength);
+
+ ip0 += mLength;
+ anchor = ip0;
+
+ /* write next hash table entry */
+ if (ip1 < ip0) {
+ hashTable[hash1] = (U32)(ip1 - base);
+ }
+
+ /* Fill table and check for immediate repcode. */
+ if (ip0 <= ilimit) {
+ /* Fill Table */
+ assert(base+current0+2 > istart); /* check base overflow */
+ hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */
+ hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base);
+
+ if (rep_offset2 > 0) { /* rep_offset2==0 means rep_offset2 is invalidated */
+ while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - rep_offset2)) ) {
+ /* store sequence */
+ size_t const rLength = ZSTD_count(ip0+4, ip0+4-rep_offset2, iend) + 4;
+ { U32 const tmpOff = rep_offset2; rep_offset2 = rep_offset1; rep_offset1 = tmpOff; } /* swap rep_offset2 <=> rep_offset1 */
+ hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base);
+ ip0 += rLength;
+ ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, STORE_REPCODE_1, rLength);
+ anchor = ip0;
+ continue; /* faster when present (confirmed on gcc-8) ... (?) */
+ } } }
+
+ goto _start;
}
+#define ZSTD_GEN_FAST_FN(dictMode, mls, step) \
+ static size_t ZSTD_compressBlock_fast_##dictMode##_##mls##_##step( \
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \
+ void const* src, size_t srcSize) \
+ { \
+ return ZSTD_compressBlock_fast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls, step); \
+ }
+
+ZSTD_GEN_FAST_FN(noDict, 4, 1)
+ZSTD_GEN_FAST_FN(noDict, 5, 1)
+ZSTD_GEN_FAST_FN(noDict, 6, 1)
+ZSTD_GEN_FAST_FN(noDict, 7, 1)
+
+ZSTD_GEN_FAST_FN(noDict, 4, 0)
+ZSTD_GEN_FAST_FN(noDict, 5, 0)
+ZSTD_GEN_FAST_FN(noDict, 6, 0)
+ZSTD_GEN_FAST_FN(noDict, 7, 0)
size_t ZSTD_compressBlock_fast(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -189,24 +338,40 @@ size_t ZSTD_compressBlock_fast(
{
U32 const mls = ms->cParams.minMatch;
assert(ms->dictMatchState == NULL);
- switch(mls)
- {
- default: /* includes case 3 */
- case 4 :
- return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 4);
- case 5 :
- return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 5);
- case 6 :
- return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 6);
- case 7 :
- return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 7);
+ if (ms->cParams.targetLength > 1) {
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ return ZSTD_compressBlock_fast_noDict_4_1(ms, seqStore, rep, src, srcSize);
+ case 5 :
+ return ZSTD_compressBlock_fast_noDict_5_1(ms, seqStore, rep, src, srcSize);
+ case 6 :
+ return ZSTD_compressBlock_fast_noDict_6_1(ms, seqStore, rep, src, srcSize);
+ case 7 :
+ return ZSTD_compressBlock_fast_noDict_7_1(ms, seqStore, rep, src, srcSize);
+ }
+ } else {
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ return ZSTD_compressBlock_fast_noDict_4_0(ms, seqStore, rep, src, srcSize);
+ case 5 :
+ return ZSTD_compressBlock_fast_noDict_5_0(ms, seqStore, rep, src, srcSize);
+ case 6 :
+ return ZSTD_compressBlock_fast_noDict_6_0(ms, seqStore, rep, src, srcSize);
+ case 7 :
+ return ZSTD_compressBlock_fast_noDict_7_0(ms, seqStore, rep, src, srcSize);
+ }
+
}
}
FORCE_INLINE_TEMPLATE
size_t ZSTD_compressBlock_fast_dictMatchState_generic(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
- void const* src, size_t srcSize, U32 const mls)
+ void const* src, size_t srcSize, U32 const mls, U32 const hasStep)
{
const ZSTD_compressionParameters* const cParams = &ms->cParams;
U32* const hashTable = ms->hashTable;
@@ -242,6 +407,8 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
assert(endIndex - prefixStartIndex <= maxDistance);
(void)maxDistance; (void)endIndex; /* these variables are not used when assert() is disabled */
+ (void)hasStep; /* not currently specialized on whether it's accelerated */
+
/* ensure there will be no underflow
* when translating a dict index into a local index */
assert(prefixStartIndex >= (U32)(dictEnd - dictBase));
@@ -272,7 +439,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
ip++;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_REPCODE_1, mLength);
} else if ( (matchIndex <= prefixStartIndex) ) {
size_t const dictHash = ZSTD_hashPtr(ip, dictHLog, mls);
U32 const dictMatchIndex = dictHashTable[dictHash];
@@ -292,7 +459,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
} /* catch up */
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
}
} else if (MEM_read32(match) != MEM_read32(ip)) {
/* it's not a match, and we're not going to check the dictionary */
@@ -307,7 +474,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
&& (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
}
/* match found */
@@ -332,7 +499,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
- ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH);
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, STORE_REPCODE_1, repLength2);
hashTable[ZSTD_hashPtr(ip, hlog, mls)] = current2;
ip += repLength2;
anchor = ip;
@@ -351,6 +518,12 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
return (size_t)(iend - anchor);
}
+
+ZSTD_GEN_FAST_FN(dictMatchState, 4, 0)
+ZSTD_GEN_FAST_FN(dictMatchState, 5, 0)
+ZSTD_GEN_FAST_FN(dictMatchState, 6, 0)
+ZSTD_GEN_FAST_FN(dictMatchState, 7, 0)
+
size_t ZSTD_compressBlock_fast_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
@@ -361,20 +534,20 @@ size_t ZSTD_compressBlock_fast_dictMatchState(
{
default: /* includes case 3 */
case 4 :
- return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 4);
+ return ZSTD_compressBlock_fast_dictMatchState_4_0(ms, seqStore, rep, src, srcSize);
case 5 :
- return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 5);
+ return ZSTD_compressBlock_fast_dictMatchState_5_0(ms, seqStore, rep, src, srcSize);
case 6 :
- return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 6);
+ return ZSTD_compressBlock_fast_dictMatchState_6_0(ms, seqStore, rep, src, srcSize);
case 7 :
- return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 7);
+ return ZSTD_compressBlock_fast_dictMatchState_7_0(ms, seqStore, rep, src, srcSize);
}
}
static size_t ZSTD_compressBlock_fast_extDict_generic(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
- void const* src, size_t srcSize, U32 const mls)
+ void const* src, size_t srcSize, U32 const mls, U32 const hasStep)
{
const ZSTD_compressionParameters* const cParams = &ms->cParams;
U32* const hashTable = ms->hashTable;
@@ -398,11 +571,13 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
const BYTE* const ilimit = iend - 8;
U32 offset_1=rep[0], offset_2=rep[1];
+ (void)hasStep; /* not currently specialized on whether it's accelerated */
+
DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic (offset_1=%u)", offset_1);
/* switch to "regular" variant if extDict is invalidated due to maxDistance */
if (prefixStartIndex == dictStartIndex)
- return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls);
+ return ZSTD_compressBlock_fast(ms, seqStore, rep, src, srcSize);
/* Search Loop */
while (ip < ilimit) { /* < instead of <=, because (ip+1) */
@@ -418,12 +593,12 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
DEBUGLOG(7, "offset_1 = %u , curr = %u", offset_1, curr);
if ( ( ((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */
- & (offset_1 < curr+1 - dictStartIndex) ) /* note: we are searching at curr+1 */
+ & (offset_1 <= curr+1 - dictStartIndex) ) /* note: we are searching at curr+1 */
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
size_t const rLength = ZSTD_count_2segments(ip+1 +4, repMatch +4, iend, repMatchEnd, prefixStart) + 4;
ip++;
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, rLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_REPCODE_1, rLength);
ip += rLength;
anchor = ip;
} else {
@@ -439,7 +614,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
size_t mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
offset_2 = offset_1; offset_1 = offset; /* update offset history */
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
ip += mLength;
anchor = ip;
} }
@@ -453,12 +628,12 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
U32 const current2 = (U32)(ip-base);
U32 const repIndex2 = current2 - offset_2;
const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
- if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (offset_2 < curr - dictStartIndex)) /* intentional overflow */
+ if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (offset_2 <= curr - dictStartIndex)) /* intentional overflow */
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
{ U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; } /* swap offset_2 <=> offset_1 */
- ZSTD_storeSeq(seqStore, 0 /*litlen*/, anchor, iend, 0 /*offcode*/, repLength2-MINMATCH);
+ ZSTD_storeSeq(seqStore, 0 /*litlen*/, anchor, iend, STORE_REPCODE_1, repLength2);
hashTable[ZSTD_hashPtr(ip, hlog, mls)] = current2;
ip += repLength2;
anchor = ip;
@@ -475,6 +650,10 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
return (size_t)(iend - anchor);
}
+ZSTD_GEN_FAST_FN(extDict, 4, 0)
+ZSTD_GEN_FAST_FN(extDict, 5, 0)
+ZSTD_GEN_FAST_FN(extDict, 6, 0)
+ZSTD_GEN_FAST_FN(extDict, 7, 0)
size_t ZSTD_compressBlock_fast_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -485,12 +664,12 @@ size_t ZSTD_compressBlock_fast_extDict(
{
default: /* includes case 3 */
case 4 :
- return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 4);
+ return ZSTD_compressBlock_fast_extDict_4_0(ms, seqStore, rep, src, srcSize);
case 5 :
- return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 5);
+ return ZSTD_compressBlock_fast_extDict_5_0(ms, seqStore, rep, src, srcSize);
case 6 :
- return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 6);
+ return ZSTD_compressBlock_fast_extDict_6_0(ms, seqStore, rep, src, srcSize);
case 7 :
- return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 7);
+ return ZSTD_compressBlock_fast_extDict_7_0(ms, seqStore, rep, src, srcSize);
}
}
diff --git a/thirdparty/zstd/compress/zstd_lazy.c b/thirdparty/zstd/compress/zstd_lazy.c
index 3d523e8472..2e38dcb46d 100644
--- a/thirdparty/zstd/compress/zstd_lazy.c
+++ b/thirdparty/zstd/compress/zstd_lazy.c
@@ -61,7 +61,7 @@ ZSTD_updateDUBT(ZSTD_matchState_t* ms,
* assumption : curr >= btlow == (curr - btmask)
* doesn't fail */
static void
-ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
+ZSTD_insertDUBT1(const ZSTD_matchState_t* ms,
U32 curr, const BYTE* inputEnd,
U32 nbCompares, U32 btLow,
const ZSTD_dictMode_e dictMode)
@@ -93,7 +93,7 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
assert(curr >= btLow);
assert(ip < iend); /* condition for ZSTD_count */
- while (nbCompares-- && (matchIndex > windowLow)) {
+ for (; nbCompares && (matchIndex > windowLow); --nbCompares) {
U32* const nextPtr = bt + 2*(matchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
assert(matchIndex < curr);
@@ -151,7 +151,7 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
static size_t
ZSTD_DUBT_findBetterDictMatch (
- ZSTD_matchState_t* ms,
+ const ZSTD_matchState_t* ms,
const BYTE* const ip, const BYTE* const iend,
size_t* offsetPtr,
size_t bestLength,
@@ -185,7 +185,7 @@ ZSTD_DUBT_findBetterDictMatch (
(void)dictMode;
assert(dictMode == ZSTD_dictMatchState);
- while (nbCompares-- && (dictMatchIndex > dictLowLimit)) {
+ for (; nbCompares && (dictMatchIndex > dictLowLimit); --nbCompares) {
U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
const BYTE* match = dictBase + dictMatchIndex;
@@ -197,8 +197,8 @@ ZSTD_DUBT_findBetterDictMatch (
U32 matchIndex = dictMatchIndex + dictIndexDelta;
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) {
DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)",
- curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, ZSTD_REP_MOVE + curr - matchIndex, dictMatchIndex, matchIndex);
- bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
+ curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, STORE_OFFSET(curr - matchIndex), dictMatchIndex, matchIndex);
+ bestLength = matchLength, *offsetPtr = STORE_OFFSET(curr - matchIndex);
}
if (ip+matchLength == iend) { /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */
break; /* drop, to guarantee consistency (miss a little bit of compression) */
@@ -218,7 +218,7 @@ ZSTD_DUBT_findBetterDictMatch (
}
if (bestLength >= MINMATCH) {
- U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
+ U32 const mIndex = curr - (U32)STORED_OFFSET(*offsetPtr); (void)mIndex;
DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
curr, (U32)bestLength, (U32)*offsetPtr, mIndex);
}
@@ -309,7 +309,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
matchIndex = hashTable[h];
hashTable[h] = curr; /* Update Hash Table */
- while (nbCompares-- && (matchIndex > windowLow)) {
+ for (; nbCompares && (matchIndex > windowLow); --nbCompares) {
U32* const nextPtr = bt + 2*(matchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
const BYTE* match;
@@ -328,7 +328,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
if (matchLength > matchEndIdx - matchIndex)
matchEndIdx = matchIndex + (U32)matchLength;
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
- bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
+ bestLength = matchLength, *offsetPtr = STORE_OFFSET(curr - matchIndex);
if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
if (dictMode == ZSTD_dictMatchState) {
nbCompares = 0; /* in addition to avoiding checking any
@@ -357,6 +357,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
*smallerPtr = *largerPtr = 0;
+ assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
if (dictMode == ZSTD_dictMatchState && nbCompares) {
bestLength = ZSTD_DUBT_findBetterDictMatch(
ms, ip, iend,
@@ -367,7 +368,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
assert(matchEndIdx > curr+8); /* ensure nextToUpdate is increased */
ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
if (bestLength >= MINMATCH) {
- U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
+ U32 const mIndex = curr - (U32)STORED_OFFSET(*offsetPtr); (void)mIndex;
DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
curr, (U32)bestLength, (U32)*offsetPtr, mIndex);
}
@@ -390,54 +391,6 @@ ZSTD_BtFindBestMatch( ZSTD_matchState_t* ms,
return ZSTD_DUBT_findBestMatch(ms, ip, iLimit, offsetPtr, mls, dictMode);
}
-
-static size_t
-ZSTD_BtFindBestMatch_selectMLS ( ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- switch(ms->cParams.minMatch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_noDict);
- case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_noDict);
- case 7 :
- case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_noDict);
- }
-}
-
-
-static size_t ZSTD_BtFindBestMatch_dictMatchState_selectMLS (
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- switch(ms->cParams.minMatch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState);
- case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState);
- case 7 :
- case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState);
- }
-}
-
-
-static size_t ZSTD_BtFindBestMatch_extDict_selectMLS (
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- switch(ms->cParams.minMatch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_extDict);
- case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_extDict);
- case 7 :
- case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_extDict);
- }
-}
-
/***********************************
* Dedicated dict search
***********************************/
@@ -450,7 +403,7 @@ void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const B
U32* const chainTable = ms->chainTable;
U32 const chainSize = 1 << ms->cParams.chainLog;
U32 idx = ms->nextToUpdate;
- U32 const minChain = chainSize < target ? target - chainSize : idx;
+ U32 const minChain = chainSize < target - idx ? target - chainSize : idx;
U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG;
U32 const cacheSize = bucketSize - 1;
U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize;
@@ -464,7 +417,7 @@ void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const B
U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG;
U32* const tmpHashTable = hashTable;
U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog);
- U32 const tmpChainSize = ((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog;
+ U32 const tmpChainSize = (U32)((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog;
U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx;
U32 hashIdx;
@@ -608,7 +561,7 @@ size_t ZSTD_dedicatedDictSearch_lazy_search(size_t* offsetPtr, size_t ml, U32 nb
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
- *offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
+ *offsetPtr = STORE_OFFSET(curr - (matchIndex + ddsIndexDelta));
if (ip+currentMl == iLimit) {
/* best possible, avoids read overflow on next attempt */
return ml;
@@ -645,7 +598,7 @@ size_t ZSTD_dedicatedDictSearch_lazy_search(size_t* offsetPtr, size_t ml, U32 nb
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
- *offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
+ *offsetPtr = STORE_OFFSET(curr - (matchIndex + ddsIndexDelta));
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
}
@@ -692,7 +645,7 @@ U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) {
/* inlining is important to hardwire a hot branch (template emulation) */
FORCE_INLINE_TEMPLATE
-size_t ZSTD_HcFindBestMatch_generic (
+size_t ZSTD_HcFindBestMatch(
ZSTD_matchState_t* ms,
const BYTE* const ip, const BYTE* const iLimit,
size_t* offsetPtr,
@@ -750,7 +703,7 @@ size_t ZSTD_HcFindBestMatch_generic (
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
- *offsetPtr = curr - matchIndex + ZSTD_REP_MOVE;
+ *offsetPtr = STORE_OFFSET(curr - matchIndex);
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
@@ -758,6 +711,7 @@ size_t ZSTD_HcFindBestMatch_generic (
matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
}
+ assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
if (dictMode == ZSTD_dedicatedDictSearch) {
ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts, dms,
ip, iLimit, prefixStart, curr, dictLimit, ddsIdx);
@@ -784,7 +738,8 @@ size_t ZSTD_HcFindBestMatch_generic (
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
- *offsetPtr = curr - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;
+ assert(curr > matchIndex + dmsIndexDelta);
+ *offsetPtr = STORE_OFFSET(curr - (matchIndex + dmsIndexDelta));
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
@@ -797,310 +752,80 @@ size_t ZSTD_HcFindBestMatch_generic (
return ml;
}
-
-FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_selectMLS (
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- switch(ms->cParams.minMatch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_noDict);
- case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_noDict);
- case 7 :
- case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_noDict);
- }
-}
-
-
-static size_t ZSTD_HcFindBestMatch_dictMatchState_selectMLS (
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- switch(ms->cParams.minMatch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState);
- case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState);
- case 7 :
- case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState);
- }
-}
-
-
-static size_t ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS (
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- switch(ms->cParams.minMatch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dedicatedDictSearch);
- case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dedicatedDictSearch);
- case 7 :
- case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dedicatedDictSearch);
- }
-}
-
-
-FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- switch(ms->cParams.minMatch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_extDict);
- case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_extDict);
- case 7 :
- case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_extDict);
- }
-}
-
/* *********************************
* (SIMD) Row-based matchfinder
***********************************/
/* Constants for row-based hash */
-#define ZSTD_ROW_HASH_TAG_OFFSET 1 /* byte offset of hashes in the match state's tagTable from the beginning of a row */
-#define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */
+#define ZSTD_ROW_HASH_TAG_OFFSET 16 /* byte offset of hashes in the match state's tagTable from the beginning of a row */
+#define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */
#define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1)
+#define ZSTD_ROW_HASH_MAX_ENTRIES 64 /* absolute maximum number of entries per row, for all configurations */
#define ZSTD_ROW_HASH_CACHE_MASK (ZSTD_ROW_HASH_CACHE_SIZE - 1)
-typedef U32 ZSTD_VecMask; /* Clarifies when we are interacting with a U32 representing a mask of matches */
-
-#if !defined(ZSTD_NO_INTRINSICS) && defined(__SSE2__) /* SIMD SSE version */
-
-#include <emmintrin.h>
-typedef __m128i ZSTD_Vec128;
-
-/* Returns a 128-bit container with 128-bits from src */
-static ZSTD_Vec128 ZSTD_Vec128_read(const void* const src) {
- return _mm_loadu_si128((ZSTD_Vec128 const*)src);
-}
-
-/* Returns a ZSTD_Vec128 with the byte "val" packed 16 times */
-static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) {
- return _mm_set1_epi8((char)val);
-}
-
-/* Do byte-by-byte comparison result of x and y. Then collapse 128-bit resultant mask
- * into a 32-bit mask that is the MSB of each byte.
- * */
-static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) {
- return (ZSTD_VecMask)_mm_movemask_epi8(_mm_cmpeq_epi8(x, y));
-}
-
-typedef struct {
- __m128i fst;
- __m128i snd;
-} ZSTD_Vec256;
-
-static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) {
- ZSTD_Vec256 v;
- v.fst = ZSTD_Vec128_read(ptr);
- v.snd = ZSTD_Vec128_read((ZSTD_Vec128 const*)ptr + 1);
- return v;
-}
-
-static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) {
- ZSTD_Vec256 v;
- v.fst = ZSTD_Vec128_set8(val);
- v.snd = ZSTD_Vec128_set8(val);
- return v;
-}
-
-static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) {
- ZSTD_VecMask fstMask;
- ZSTD_VecMask sndMask;
- fstMask = ZSTD_Vec128_cmpMask8(x.fst, y.fst);
- sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd);
- return fstMask | (sndMask << 16);
-}
-
-#elif !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) /* SIMD ARM NEON Version */
-
-#include <arm_neon.h>
-typedef uint8x16_t ZSTD_Vec128;
-
-static ZSTD_Vec128 ZSTD_Vec128_read(const void* const src) {
- return vld1q_u8((const BYTE* const)src);
-}
-
-static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) {
- return vdupq_n_u8(val);
-}
-
-/* Mimics '_mm_movemask_epi8()' from SSE */
-static U32 ZSTD_vmovmaskq_u8(ZSTD_Vec128 val) {
- /* Shift out everything but the MSB bits in each byte */
- uint16x8_t highBits = vreinterpretq_u16_u8(vshrq_n_u8(val, 7));
- /* Merge the even lanes together with vsra (right shift and add) */
- uint32x4_t paired16 = vreinterpretq_u32_u16(vsraq_n_u16(highBits, highBits, 7));
- uint64x2_t paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14));
- uint8x16_t paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28));
- /* Extract the low 8 bits from each lane, merge */
- return vgetq_lane_u8(paired64, 0) | ((U32)vgetq_lane_u8(paired64, 8) << 8);
-}
-
-static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) {
- return (ZSTD_VecMask)ZSTD_vmovmaskq_u8(vceqq_u8(x, y));
-}
-
-typedef struct {
- uint8x16_t fst;
- uint8x16_t snd;
-} ZSTD_Vec256;
-
-static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) {
- ZSTD_Vec256 v;
- v.fst = ZSTD_Vec128_read(ptr);
- v.snd = ZSTD_Vec128_read((ZSTD_Vec128 const*)ptr + 1);
- return v;
-}
-
-static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) {
- ZSTD_Vec256 v;
- v.fst = ZSTD_Vec128_set8(val);
- v.snd = ZSTD_Vec128_set8(val);
- return v;
-}
-
-static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) {
- ZSTD_VecMask fstMask;
- ZSTD_VecMask sndMask;
- fstMask = ZSTD_Vec128_cmpMask8(x.fst, y.fst);
- sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd);
- return fstMask | (sndMask << 16);
-}
-
-#else /* Scalar fallback version */
-
-#define VEC128_NB_SIZE_T (16 / sizeof(size_t))
-typedef struct {
- size_t vec[VEC128_NB_SIZE_T];
-} ZSTD_Vec128;
-
-static ZSTD_Vec128 ZSTD_Vec128_read(const void* const src) {
- ZSTD_Vec128 ret;
- ZSTD_memcpy(ret.vec, src, VEC128_NB_SIZE_T*sizeof(size_t));
- return ret;
-}
-
-static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) {
- ZSTD_Vec128 ret = { {0} };
- int startBit = sizeof(size_t) * 8 - 8;
- for (;startBit >= 0; startBit -= 8) {
- unsigned j = 0;
- for (;j < VEC128_NB_SIZE_T; ++j) {
- ret.vec[j] |= ((size_t)val << startBit);
- }
- }
- return ret;
-}
-
-/* Compare x to y, byte by byte, generating a "matches" bitfield */
-static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) {
- ZSTD_VecMask res = 0;
- unsigned i = 0;
- unsigned l = 0;
- for (; i < VEC128_NB_SIZE_T; ++i) {
- const size_t cmp1 = x.vec[i];
- const size_t cmp2 = y.vec[i];
- unsigned j = 0;
- for (; j < sizeof(size_t); ++j, ++l) {
- if (((cmp1 >> j*8) & 0xFF) == ((cmp2 >> j*8) & 0xFF)) {
- res |= ((U32)1 << (j+i*sizeof(size_t)));
- }
- }
- }
- return res;
-}
-
-#define VEC256_NB_SIZE_T 2*VEC128_NB_SIZE_T
-typedef struct {
- size_t vec[VEC256_NB_SIZE_T];
-} ZSTD_Vec256;
-
-static ZSTD_Vec256 ZSTD_Vec256_read(const void* const src) {
- ZSTD_Vec256 ret;
- ZSTD_memcpy(ret.vec, src, VEC256_NB_SIZE_T*sizeof(size_t));
- return ret;
-}
-
-static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) {
- ZSTD_Vec256 ret = { {0} };
- int startBit = sizeof(size_t) * 8 - 8;
- for (;startBit >= 0; startBit -= 8) {
- unsigned j = 0;
- for (;j < VEC256_NB_SIZE_T; ++j) {
- ret.vec[j] |= ((size_t)val << startBit);
- }
- }
- return ret;
-}
-
-/* Compare x to y, byte by byte, generating a "matches" bitfield */
-static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) {
- ZSTD_VecMask res = 0;
- unsigned i = 0;
- unsigned l = 0;
- for (; i < VEC256_NB_SIZE_T; ++i) {
- const size_t cmp1 = x.vec[i];
- const size_t cmp2 = y.vec[i];
- unsigned j = 0;
- for (; j < sizeof(size_t); ++j, ++l) {
- if (((cmp1 >> j*8) & 0xFF) == ((cmp2 >> j*8) & 0xFF)) {
- res |= ((U32)1 << (j+i*sizeof(size_t)));
- }
- }
- }
- return res;
-}
-
-#endif /* !defined(ZSTD_NO_INTRINSICS) && defined(__SSE2__) */
+typedef U64 ZSTD_VecMask; /* Clarifies when we are interacting with a U64 representing a mask of matches */
/* ZSTD_VecMask_next():
* Starting from the LSB, returns the idx of the next non-zero bit.
* Basically counting the nb of trailing zeroes.
*/
static U32 ZSTD_VecMask_next(ZSTD_VecMask val) {
-# if defined(_MSC_VER) /* Visual */
- unsigned long r=0;
- return _BitScanForward(&r, val) ? (U32)r : 0;
-# elif defined(__GNUC__) && (__GNUC__ >= 3)
- return (U32)__builtin_ctz(val);
+ assert(val != 0);
+# if defined(_MSC_VER) && defined(_WIN64)
+ if (val != 0) {
+ unsigned long r;
+ _BitScanForward64(&r, val);
+ return (U32)(r);
+ } else {
+ /* Should not reach this code path */
+ __assume(0);
+ }
+# elif (defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))
+ if (sizeof(size_t) == 4) {
+ U32 mostSignificantWord = (U32)(val >> 32);
+ U32 leastSignificantWord = (U32)val;
+ if (leastSignificantWord == 0) {
+ return 32 + (U32)__builtin_ctz(mostSignificantWord);
+ } else {
+ return (U32)__builtin_ctz(leastSignificantWord);
+ }
+ } else {
+ return (U32)__builtin_ctzll(val);
+ }
# else
- /* Software ctz version: http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup */
- static const U32 multiplyDeBruijnBitPosition[32] =
- {
- 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
- 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
- };
- return multiplyDeBruijnBitPosition[((U32)((v & -(int)v) * 0x077CB531U)) >> 27];
+ /* Software ctz version: http://aggregate.org/MAGIC/#Trailing%20Zero%20Count
+ * and: https://stackoverflow.com/questions/2709430/count-number-of-bits-in-a-64-bit-long-big-integer
+ */
+ val = ~val & (val - 1ULL); /* Lowest set bit mask */
+ val = val - ((val >> 1) & 0x5555555555555555);
+ val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
+ return (U32)((((val + (val >> 4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56);
# endif
}
-/* ZSTD_VecMask_rotateRight():
- * Rotates a bitfield to the right by "rotation" bits.
- * If the rotation is greater than totalBits, the returned mask is 0.
+/* ZSTD_rotateRight_*():
+ * Rotates a bitfield to the right by "count" bits.
+ * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts
*/
-FORCE_INLINE_TEMPLATE ZSTD_VecMask
-ZSTD_VecMask_rotateRight(ZSTD_VecMask mask, U32 const rotation, U32 const totalBits) {
- if (rotation == 0)
- return mask;
- switch (totalBits) {
- default:
- assert(0);
- case 16:
- return (mask >> rotation) | (U16)(mask << (16 - rotation));
- case 32:
- return (mask >> rotation) | (U32)(mask << (32 - rotation));
- }
+FORCE_INLINE_TEMPLATE
+U64 ZSTD_rotateRight_U64(U64 const value, U32 count) {
+ assert(count < 64);
+ count &= 0x3F; /* for fickle pattern recognition */
+ return (value >> count) | (U64)(value << ((0U - count) & 0x3F));
+}
+
+FORCE_INLINE_TEMPLATE
+U32 ZSTD_rotateRight_U32(U32 const value, U32 count) {
+ assert(count < 32);
+ count &= 0x1F; /* for fickle pattern recognition */
+ return (value >> count) | (U32)(value << ((0U - count) & 0x1F));
+}
+
+FORCE_INLINE_TEMPLATE
+U16 ZSTD_rotateRight_U16(U16 const value, U32 count) {
+ assert(count < 16);
+ count &= 0x0F; /* for fickle pattern recognition */
+ return (value >> count) | (U16)(value << ((0U - count) & 0x0F));
}
/* ZSTD_row_nextIndex():
@@ -1126,20 +851,24 @@ MEM_STATIC int ZSTD_isAligned(void const* ptr, size_t align) {
*/
FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, U16 const* tagTable, U32 const relRow, U32 const rowLog) {
PREFETCH_L1(hashTable + relRow);
- if (rowLog == 5) {
+ if (rowLog >= 5) {
PREFETCH_L1(hashTable + relRow + 16);
+ /* Note: prefetching more of the hash table does not appear to be beneficial for 128-entry rows */
}
PREFETCH_L1(tagTable + relRow);
- assert(rowLog == 4 || rowLog == 5);
+ if (rowLog == 6) {
+ PREFETCH_L1(tagTable + relRow + 32);
+ }
+ assert(rowLog == 4 || rowLog == 5 || rowLog == 6);
assert(ZSTD_isAligned(hashTable + relRow, 64)); /* prefetched hash row always 64-byte aligned */
- assert(ZSTD_isAligned(tagTable + relRow, (size_t)1 << rowLog)); /* prefetched tagRow sits on a multiple of 32 or 64 bytes */
+ assert(ZSTD_isAligned(tagTable + relRow, (size_t)1 << rowLog)); /* prefetched tagRow sits on correct multiple of bytes (32,64,128) */
}
/* ZSTD_row_fillHashCache():
* Fill up the hash cache starting at idx, prefetching up to ZSTD_ROW_HASH_CACHE_SIZE entries,
* but not beyond iLimit.
*/
-static void ZSTD_row_fillHashCache(ZSTD_matchState_t* ms, const BYTE* base,
+FORCE_INLINE_TEMPLATE void ZSTD_row_fillHashCache(ZSTD_matchState_t* ms, const BYTE* base,
U32 const rowLog, U32 const mls,
U32 idx, const BYTE* const iLimit)
{
@@ -1179,35 +908,65 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTab
}
}
-/* ZSTD_row_update_internal():
- * Inserts the byte at ip into the appropriate position in the hash table.
- * Determines the relative row, and the position within the {16, 32} entry row to insert at.
+/* ZSTD_row_update_internalImpl():
+ * Updates the hash table with positions starting from updateStartIdx until updateEndIdx.
*/
-FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const BYTE* ip,
- U32 const mls, U32 const rowLog,
- U32 const rowMask, U32 const useCache)
+FORCE_INLINE_TEMPLATE void ZSTD_row_update_internalImpl(ZSTD_matchState_t* ms,
+ U32 updateStartIdx, U32 const updateEndIdx,
+ U32 const mls, U32 const rowLog,
+ U32 const rowMask, U32 const useCache)
{
U32* const hashTable = ms->hashTable;
U16* const tagTable = ms->tagTable;
U32 const hashLog = ms->rowHashLog;
const BYTE* const base = ms->window.base;
- const U32 target = (U32)(ip - base);
- U32 idx = ms->nextToUpdate;
- DEBUGLOG(6, "ZSTD_row_update_internal(): nextToUpdate=%u, current=%u", idx, target);
- for (; idx < target; ++idx) {
- U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, idx, hashLog, rowLog, mls)
- : (U32)ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls);
+ DEBUGLOG(6, "ZSTD_row_update_internalImpl(): updateStartIdx=%u, updateEndIdx=%u", updateStartIdx, updateEndIdx);
+ for (; updateStartIdx < updateEndIdx; ++updateStartIdx) {
+ U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, updateStartIdx, hashLog, rowLog, mls)
+ : (U32)ZSTD_hashPtr(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls);
U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
U32* const row = hashTable + relRow;
BYTE* tagRow = (BYTE*)(tagTable + relRow); /* Though tagTable is laid out as a table of U16, each tag is only 1 byte.
Explicit cast allows us to get exact desired position within each row */
U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask);
- assert(hash == ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls));
+ assert(hash == ZSTD_hashPtr(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls));
((BYTE*)tagRow)[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK;
- row[pos] = idx;
+ row[pos] = updateStartIdx;
}
+}
+
+/* ZSTD_row_update_internal():
+ * Inserts the byte at ip into the appropriate position in the hash table, and updates ms->nextToUpdate.
+ * Skips sections of long matches as is necessary.
+ */
+FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const BYTE* ip,
+ U32 const mls, U32 const rowLog,
+ U32 const rowMask, U32 const useCache)
+{
+ U32 idx = ms->nextToUpdate;
+ const BYTE* const base = ms->window.base;
+ const U32 target = (U32)(ip - base);
+ const U32 kSkipThreshold = 384;
+ const U32 kMaxMatchStartPositionsToUpdate = 96;
+ const U32 kMaxMatchEndPositionsToUpdate = 32;
+
+ if (useCache) {
+ /* Only skip positions when using hash cache, i.e.
+ * if we are loading a dict, don't skip anything.
+ * If we decide to skip, then we only update a set number
+ * of positions at the beginning and end of the match.
+ */
+ if (UNLIKELY(target - idx > kSkipThreshold)) {
+ U32 const bound = idx + kMaxMatchStartPositionsToUpdate;
+ ZSTD_row_update_internalImpl(ms, idx, bound, mls, rowLog, rowMask, useCache);
+ idx = target - kMaxMatchEndPositionsToUpdate;
+ ZSTD_row_fillHashCache(ms, base, rowLog, mls, idx, ip+1);
+ }
+ }
+ assert(target >= idx);
+ ZSTD_row_update_internalImpl(ms, idx, target, mls, rowLog, rowMask, useCache);
ms->nextToUpdate = target;
}
@@ -1216,7 +975,7 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const
* processing.
*/
void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip) {
- const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5;
+ const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6);
const U32 rowMask = (1u << rowLog) - 1;
const U32 mls = MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */);
@@ -1224,26 +983,131 @@ void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip) {
ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 0 /* dont use cache */);
}
+#if defined(ZSTD_ARCH_X86_SSE2)
+FORCE_INLINE_TEMPLATE ZSTD_VecMask
+ZSTD_row_getSSEMask(int nbChunks, const BYTE* const src, const BYTE tag, const U32 head)
+{
+ const __m128i comparisonMask = _mm_set1_epi8((char)tag);
+ int matches[4] = {0};
+ int i;
+ assert(nbChunks == 1 || nbChunks == 2 || nbChunks == 4);
+ for (i=0; i<nbChunks; i++) {
+ const __m128i chunk = _mm_loadu_si128((const __m128i*)(const void*)(src + 16*i));
+ const __m128i equalMask = _mm_cmpeq_epi8(chunk, comparisonMask);
+ matches[i] = _mm_movemask_epi8(equalMask);
+ }
+ if (nbChunks == 1) return ZSTD_rotateRight_U16((U16)matches[0], head);
+ if (nbChunks == 2) return ZSTD_rotateRight_U32((U32)matches[1] << 16 | (U32)matches[0], head);
+ assert(nbChunks == 4);
+ return ZSTD_rotateRight_U64((U64)matches[3] << 48 | (U64)matches[2] << 32 | (U64)matches[1] << 16 | (U64)matches[0], head);
+}
+#endif
+
/* Returns a ZSTD_VecMask (U32) that has the nth bit set to 1 if the newly-computed "tag" matches
* the hash at the nth position in a row of the tagTable.
- */
-FORCE_INLINE_TEMPLATE
-ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 head, const U32 rowEntries) {
- ZSTD_VecMask matches = 0;
- if (rowEntries == 16) {
- ZSTD_Vec128 hashes = ZSTD_Vec128_read(tagRow + ZSTD_ROW_HASH_TAG_OFFSET);
- ZSTD_Vec128 expandedTags = ZSTD_Vec128_set8(tag);
- matches = ZSTD_Vec128_cmpMask8(hashes, expandedTags);
- } else if (rowEntries == 32) {
- ZSTD_Vec256 hashes = ZSTD_Vec256_read(tagRow + ZSTD_ROW_HASH_TAG_OFFSET);
- ZSTD_Vec256 expandedTags = ZSTD_Vec256_set8(tag);
- matches = ZSTD_Vec256_cmpMask8(hashes, expandedTags);
- } else {
- assert(0);
+ * Each row is a circular buffer beginning at the value of "head". So we must rotate the "matches" bitfield
+ * to match up with the actual layout of the entries within the hashTable */
+FORCE_INLINE_TEMPLATE ZSTD_VecMask
+ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 head, const U32 rowEntries)
+{
+ const BYTE* const src = tagRow + ZSTD_ROW_HASH_TAG_OFFSET;
+ assert((rowEntries == 16) || (rowEntries == 32) || rowEntries == 64);
+ assert(rowEntries <= ZSTD_ROW_HASH_MAX_ENTRIES);
+
+#if defined(ZSTD_ARCH_X86_SSE2)
+
+ return ZSTD_row_getSSEMask(rowEntries / 16, src, tag, head);
+
+#else /* SW or NEON-LE */
+
+# if defined(ZSTD_ARCH_ARM_NEON)
+ /* This NEON path only works for little endian - otherwise use SWAR below */
+ if (MEM_isLittleEndian()) {
+ if (rowEntries == 16) {
+ const uint8x16_t chunk = vld1q_u8(src);
+ const uint16x8_t equalMask = vreinterpretq_u16_u8(vceqq_u8(chunk, vdupq_n_u8(tag)));
+ const uint16x8_t t0 = vshlq_n_u16(equalMask, 7);
+ const uint32x4_t t1 = vreinterpretq_u32_u16(vsriq_n_u16(t0, t0, 14));
+ const uint64x2_t t2 = vreinterpretq_u64_u32(vshrq_n_u32(t1, 14));
+ const uint8x16_t t3 = vreinterpretq_u8_u64(vsraq_n_u64(t2, t2, 28));
+ const U16 hi = (U16)vgetq_lane_u8(t3, 8);
+ const U16 lo = (U16)vgetq_lane_u8(t3, 0);
+ return ZSTD_rotateRight_U16((hi << 8) | lo, head);
+ } else if (rowEntries == 32) {
+ const uint16x8x2_t chunk = vld2q_u16((const U16*)(const void*)src);
+ const uint8x16_t chunk0 = vreinterpretq_u8_u16(chunk.val[0]);
+ const uint8x16_t chunk1 = vreinterpretq_u8_u16(chunk.val[1]);
+ const uint8x16_t equalMask0 = vceqq_u8(chunk0, vdupq_n_u8(tag));
+ const uint8x16_t equalMask1 = vceqq_u8(chunk1, vdupq_n_u8(tag));
+ const int8x8_t pack0 = vqmovn_s16(vreinterpretq_s16_u8(equalMask0));
+ const int8x8_t pack1 = vqmovn_s16(vreinterpretq_s16_u8(equalMask1));
+ const uint8x8_t t0 = vreinterpret_u8_s8(pack0);
+ const uint8x8_t t1 = vreinterpret_u8_s8(pack1);
+ const uint8x8_t t2 = vsri_n_u8(t1, t0, 2);
+ const uint8x8x2_t t3 = vuzp_u8(t2, t0);
+ const uint8x8_t t4 = vsri_n_u8(t3.val[1], t3.val[0], 4);
+ const U32 matches = vget_lane_u32(vreinterpret_u32_u8(t4), 0);
+ return ZSTD_rotateRight_U32(matches, head);
+ } else { /* rowEntries == 64 */
+ const uint8x16x4_t chunk = vld4q_u8(src);
+ const uint8x16_t dup = vdupq_n_u8(tag);
+ const uint8x16_t cmp0 = vceqq_u8(chunk.val[0], dup);
+ const uint8x16_t cmp1 = vceqq_u8(chunk.val[1], dup);
+ const uint8x16_t cmp2 = vceqq_u8(chunk.val[2], dup);
+ const uint8x16_t cmp3 = vceqq_u8(chunk.val[3], dup);
+
+ const uint8x16_t t0 = vsriq_n_u8(cmp1, cmp0, 1);
+ const uint8x16_t t1 = vsriq_n_u8(cmp3, cmp2, 1);
+ const uint8x16_t t2 = vsriq_n_u8(t1, t0, 2);
+ const uint8x16_t t3 = vsriq_n_u8(t2, t2, 4);
+ const uint8x8_t t4 = vshrn_n_u16(vreinterpretq_u16_u8(t3), 4);
+ const U64 matches = vget_lane_u64(vreinterpret_u64_u8(t4), 0);
+ return ZSTD_rotateRight_U64(matches, head);
+ }
}
- /* Each row is a circular buffer beginning at the value of "head". So we must rotate the "matches" bitfield
- to match up with the actual layout of the entries within the hashTable */
- return ZSTD_VecMask_rotateRight(matches, head, rowEntries);
+# endif /* ZSTD_ARCH_ARM_NEON */
+ /* SWAR */
+ { const size_t chunkSize = sizeof(size_t);
+ const size_t shiftAmount = ((chunkSize * 8) - chunkSize);
+ const size_t xFF = ~((size_t)0);
+ const size_t x01 = xFF / 0xFF;
+ const size_t x80 = x01 << 7;
+ const size_t splatChar = tag * x01;
+ ZSTD_VecMask matches = 0;
+ int i = rowEntries - chunkSize;
+ assert((sizeof(size_t) == 4) || (sizeof(size_t) == 8));
+ if (MEM_isLittleEndian()) { /* runtime check so have two loops */
+ const size_t extractMagic = (xFF / 0x7F) >> chunkSize;
+ do {
+ size_t chunk = MEM_readST(&src[i]);
+ chunk ^= splatChar;
+ chunk = (((chunk | x80) - x01) | chunk) & x80;
+ matches <<= chunkSize;
+ matches |= (chunk * extractMagic) >> shiftAmount;
+ i -= chunkSize;
+ } while (i >= 0);
+ } else { /* big endian: reverse bits during extraction */
+ const size_t msb = xFF ^ (xFF >> 1);
+ const size_t extractMagic = (msb / 0x1FF) | msb;
+ do {
+ size_t chunk = MEM_readST(&src[i]);
+ chunk ^= splatChar;
+ chunk = (((chunk | x80) - x01) | chunk) & x80;
+ matches <<= chunkSize;
+ matches |= ((chunk >> 7) * extractMagic) >> shiftAmount;
+ i -= chunkSize;
+ } while (i >= 0);
+ }
+ matches = ~matches;
+ if (rowEntries == 16) {
+ return ZSTD_rotateRight_U16((U16)matches, head);
+ } else if (rowEntries == 32) {
+ return ZSTD_rotateRight_U32((U32)matches, head);
+ } else {
+ return ZSTD_rotateRight_U64((U64)matches, head);
+ }
+ }
+#endif
}
/* The high-level approach of the SIMD row based match finder is as follows:
@@ -1262,7 +1126,7 @@ ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, con
* - Pick the longest match.
*/
FORCE_INLINE_TEMPLATE
-size_t ZSTD_RowFindBestMatch_generic (
+size_t ZSTD_RowFindBestMatch(
ZSTD_matchState_t* ms,
const BYTE* const ip, const BYTE* const iLimit,
size_t* offsetPtr,
@@ -1293,11 +1157,13 @@ size_t ZSTD_RowFindBestMatch_generic (
/* DMS/DDS variables that may be referenced laster */
const ZSTD_matchState_t* const dms = ms->dictMatchState;
- size_t ddsIdx;
- U32 ddsExtraAttempts; /* cctx hash tables are limited in searches, but allow extra searches into DDS */
- U32 dmsTag;
- U32* dmsRow;
- BYTE* dmsTagRow;
+
+ /* Initialize the following variables to satisfy static analyzer */
+ size_t ddsIdx = 0;
+ U32 ddsExtraAttempts = 0; /* cctx hash tables are limited in searches, but allow extra searches into DDS */
+ U32 dmsTag = 0;
+ U32* dmsRow = NULL;
+ BYTE* dmsTagRow = NULL;
if (dictMode == ZSTD_dedicatedDictSearch) {
const U32 ddsHashLog = dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG;
@@ -1329,7 +1195,7 @@ size_t ZSTD_RowFindBestMatch_generic (
U32* const row = hashTable + relRow;
BYTE* tagRow = (BYTE*)(tagTable + relRow);
U32 const head = *tagRow & rowMask;
- U32 matchBuffer[32 /* maximum nb entries per row */];
+ U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES];
size_t numMatches = 0;
size_t currMatch = 0;
ZSTD_VecMask matches = ZSTD_row_getMatchMask(tagRow, (BYTE)tag, head, rowEntries);
@@ -1379,12 +1245,13 @@ size_t ZSTD_RowFindBestMatch_generic (
/* Save best solution */
if (currentMl > ml) {
ml = currentMl;
- *offsetPtr = curr - matchIndex + ZSTD_REP_MOVE;
+ *offsetPtr = STORE_OFFSET(curr - matchIndex);
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
}
}
+ assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
if (dictMode == ZSTD_dedicatedDictSearch) {
ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts + ddsExtraAttempts, dms,
ip, iLimit, prefixStart, curr, dictLimit, ddsIdx);
@@ -1397,7 +1264,7 @@ size_t ZSTD_RowFindBestMatch_generic (
const U32 dmsIndexDelta = dictLimit - dmsSize;
{ U32 const head = *dmsTagRow & rowMask;
- U32 matchBuffer[32 /* maximum nb row entries */];
+ U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES];
size_t numMatches = 0;
size_t currMatch = 0;
ZSTD_VecMask matches = ZSTD_row_getMatchMask(dmsTagRow, (BYTE)dmsTag, head, rowEntries);
@@ -1426,7 +1293,8 @@ size_t ZSTD_RowFindBestMatch_generic (
if (currentMl > ml) {
ml = currentMl;
- *offsetPtr = curr - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;
+ assert(curr > matchIndex + dmsIndexDelta);
+ *offsetPtr = STORE_OFFSET(curr - (matchIndex + dmsIndexDelta));
if (ip+currentMl == iLimit) break;
}
}
@@ -1435,84 +1303,175 @@ size_t ZSTD_RowFindBestMatch_generic (
return ml;
}
-/* Inlining is important to hardwire a hot branch (template emulation) */
-FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_selectMLS (
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- const ZSTD_dictMode_e dictMode, size_t* offsetPtr, const U32 rowLog)
-{
- switch(ms->cParams.minMatch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_RowFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, dictMode, rowLog);
- case 5 : return ZSTD_RowFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, dictMode, rowLog);
- case 7 :
- case 6 : return ZSTD_RowFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, dictMode, rowLog);
- }
-}
-FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_selectRowLog (
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5);
- switch(cappedSearchLog)
- {
- default :
- case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 4);
- case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 5);
+typedef size_t (*searchMax_f)(
+ ZSTD_matchState_t* ms,
+ const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
+
+/**
+ * This struct contains the functions necessary for lazy to search.
+ * Currently, that is only searchMax. However, it is still valuable to have the
+ * VTable because this makes it easier to add more functions to the VTable later.
+ *
+ * TODO: The start of the search function involves loading and calculating a
+ * bunch of constants from the ZSTD_matchState_t. These computations could be
+ * done in an initialization function, and saved somewhere in the match state.
+ * Then we could pass a pointer to the saved state instead of the match state,
+ * and avoid duplicate computations.
+ *
+ * TODO: Move the match re-winding into searchMax. This improves compression
+ * ratio, and unlocks further simplifications with the next TODO.
+ *
+ * TODO: Try moving the repcode search into searchMax. After the re-winding
+ * and repcode search are in searchMax, there is no more logic in the match
+ * finder loop that requires knowledge about the dictMode. So we should be
+ * able to avoid force inlining it, and we can join the extDict loop with
+ * the single segment loop. It should go in searchMax instead of its own
+ * function to avoid having multiple virtual function calls per search.
+ */
+typedef struct {
+ searchMax_f searchMax;
+} ZSTD_LazyVTable;
+
+#define GEN_ZSTD_BT_VTABLE(dictMode, mls) \
+ static size_t ZSTD_BtFindBestMatch_##dictMode##_##mls( \
+ ZSTD_matchState_t* ms, \
+ const BYTE* ip, const BYTE* const iLimit, \
+ size_t* offsetPtr) \
+ { \
+ assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
+ return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \
+ } \
+ static const ZSTD_LazyVTable ZSTD_BtVTable_##dictMode##_##mls = { \
+ ZSTD_BtFindBestMatch_##dictMode##_##mls \
+ };
+
+#define GEN_ZSTD_HC_VTABLE(dictMode, mls) \
+ static size_t ZSTD_HcFindBestMatch_##dictMode##_##mls( \
+ ZSTD_matchState_t* ms, \
+ const BYTE* ip, const BYTE* const iLimit, \
+ size_t* offsetPtr) \
+ { \
+ assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
+ return ZSTD_HcFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \
+ } \
+ static const ZSTD_LazyVTable ZSTD_HcVTable_##dictMode##_##mls = { \
+ ZSTD_HcFindBestMatch_##dictMode##_##mls \
+ };
+
+#define GEN_ZSTD_ROW_VTABLE(dictMode, mls, rowLog) \
+ static size_t ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog( \
+ ZSTD_matchState_t* ms, \
+ const BYTE* ip, const BYTE* const iLimit, \
+ size_t* offsetPtr) \
+ { \
+ assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
+ assert(MAX(4, MIN(6, ms->cParams.searchLog)) == rowLog); \
+ return ZSTD_RowFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode, rowLog); \
+ } \
+ static const ZSTD_LazyVTable ZSTD_RowVTable_##dictMode##_##mls##_##rowLog = { \
+ ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog \
+ };
+
+#define ZSTD_FOR_EACH_ROWLOG(X, dictMode, mls) \
+ X(dictMode, mls, 4) \
+ X(dictMode, mls, 5) \
+ X(dictMode, mls, 6)
+
+#define ZSTD_FOR_EACH_MLS_ROWLOG(X, dictMode) \
+ ZSTD_FOR_EACH_ROWLOG(X, dictMode, 4) \
+ ZSTD_FOR_EACH_ROWLOG(X, dictMode, 5) \
+ ZSTD_FOR_EACH_ROWLOG(X, dictMode, 6)
+
+#define ZSTD_FOR_EACH_MLS(X, dictMode) \
+ X(dictMode, 4) \
+ X(dictMode, 5) \
+ X(dictMode, 6)
+
+#define ZSTD_FOR_EACH_DICT_MODE(X, ...) \
+ X(__VA_ARGS__, noDict) \
+ X(__VA_ARGS__, extDict) \
+ X(__VA_ARGS__, dictMatchState) \
+ X(__VA_ARGS__, dedicatedDictSearch)
+
+/* Generate Row VTables for each combination of (dictMode, mls, rowLog) */
+ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS_ROWLOG, GEN_ZSTD_ROW_VTABLE)
+/* Generate Binary Tree VTables for each combination of (dictMode, mls) */
+ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_BT_VTABLE)
+/* Generate Hash Chain VTables for each combination of (dictMode, mls) */
+ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_HC_VTABLE)
+
+#define GEN_ZSTD_BT_VTABLE_ARRAY(dictMode) \
+ { \
+ &ZSTD_BtVTable_##dictMode##_4, \
+ &ZSTD_BtVTable_##dictMode##_5, \
+ &ZSTD_BtVTable_##dictMode##_6 \
}
-}
-FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_dictMatchState_selectRowLog(
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5);
- switch(cappedSearchLog)
- {
- default :
- case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 4);
- case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 5);
+#define GEN_ZSTD_HC_VTABLE_ARRAY(dictMode) \
+ { \
+ &ZSTD_HcVTable_##dictMode##_4, \
+ &ZSTD_HcVTable_##dictMode##_5, \
+ &ZSTD_HcVTable_##dictMode##_6 \
}
-}
-FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_dedicatedDictSearch_selectRowLog(
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5);
- switch(cappedSearchLog)
- {
- default :
- case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 4);
- case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 5);
+#define GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, mls) \
+ { \
+ &ZSTD_RowVTable_##dictMode##_##mls##_4, \
+ &ZSTD_RowVTable_##dictMode##_##mls##_5, \
+ &ZSTD_RowVTable_##dictMode##_##mls##_6 \
}
-}
-FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_extDict_selectRowLog (
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr)
-{
- const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5);
- switch(cappedSearchLog)
- {
- default :
- case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 4);
- case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 5);
+#define GEN_ZSTD_ROW_VTABLE_ARRAY(dictMode) \
+ { \
+ GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, 4), \
+ GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, 5), \
+ GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, 6) \
}
-}
+#define GEN_ZSTD_VTABLE_ARRAY(X) \
+ { \
+ X(noDict), \
+ X(extDict), \
+ X(dictMatchState), \
+ X(dedicatedDictSearch) \
+ }
/* *******************************
* Common parser - lazy strategy
*********************************/
typedef enum { search_hashChain=0, search_binaryTree=1, search_rowHash=2 } searchMethod_e;
+/**
+ * This table is indexed first by the four ZSTD_dictMode_e values, and then
+ * by the two searchMethod_e values. NULLs are placed for configurations
+ * that should never occur (extDict modes go to the other implementation
+ * below and there is no DDSS for binary tree search yet).
+ */
+
+static ZSTD_LazyVTable const*
+ZSTD_selectLazyVTable(ZSTD_matchState_t const* ms, searchMethod_e searchMethod, ZSTD_dictMode_e dictMode)
+{
+ /* Fill the Hc/Bt VTable arrays with the right functions for the (dictMode, mls) combination. */
+ ZSTD_LazyVTable const* const hcVTables[4][3] = GEN_ZSTD_VTABLE_ARRAY(GEN_ZSTD_HC_VTABLE_ARRAY);
+ ZSTD_LazyVTable const* const btVTables[4][3] = GEN_ZSTD_VTABLE_ARRAY(GEN_ZSTD_BT_VTABLE_ARRAY);
+ /* Fill the Row VTable array with the right functions for the (dictMode, mls, rowLog) combination. */
+ ZSTD_LazyVTable const* const rowVTables[4][3][3] = GEN_ZSTD_VTABLE_ARRAY(GEN_ZSTD_ROW_VTABLE_ARRAY);
+
+ U32 const mls = MAX(4, MIN(6, ms->cParams.minMatch));
+ U32 const rowLog = MAX(4, MIN(6, ms->cParams.searchLog));
+ switch (searchMethod) {
+ case search_hashChain:
+ return hcVTables[dictMode][mls - 4];
+ case search_binaryTree:
+ return btVTables[dictMode][mls - 4];
+ case search_rowHash:
+ return rowVTables[dictMode][mls - 4][rowLog - 4];
+ default:
+ return NULL;
+ }
+}
+
FORCE_INLINE_TEMPLATE size_t
ZSTD_compressBlock_lazy_generic(
ZSTD_matchState_t* ms, seqStore_t* seqStore,
@@ -1525,46 +1484,12 @@ ZSTD_compressBlock_lazy_generic(
const BYTE* ip = istart;
const BYTE* anchor = istart;
const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = searchMethod == search_rowHash ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8;
+ const BYTE* const ilimit = (searchMethod == search_rowHash) ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8;
const BYTE* const base = ms->window.base;
const U32 prefixLowestIndex = ms->window.dictLimit;
const BYTE* const prefixLowest = base + prefixLowestIndex;
- const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5;
- typedef size_t (*searchMax_f)(
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
-
- /**
- * This table is indexed first by the four ZSTD_dictMode_e values, and then
- * by the two searchMethod_e values. NULLs are placed for configurations
- * that should never occur (extDict modes go to the other implementation
- * below and there is no DDSS for binary tree search yet).
- */
- const searchMax_f searchFuncs[4][3] = {
- {
- ZSTD_HcFindBestMatch_selectMLS,
- ZSTD_BtFindBestMatch_selectMLS,
- ZSTD_RowFindBestMatch_selectRowLog
- },
- {
- NULL,
- NULL,
- NULL
- },
- {
- ZSTD_HcFindBestMatch_dictMatchState_selectMLS,
- ZSTD_BtFindBestMatch_dictMatchState_selectMLS,
- ZSTD_RowFindBestMatch_dictMatchState_selectRowLog
- },
- {
- ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS,
- NULL,
- ZSTD_RowFindBestMatch_dedicatedDictSearch_selectRowLog
- }
- };
-
- searchMax_f const searchMax = searchFuncs[dictMode][(int)searchMethod];
+ searchMax_f const searchMax = ZSTD_selectLazyVTable(ms, searchMethod, dictMode)->searchMax;
U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
const int isDMS = dictMode == ZSTD_dictMatchState;
@@ -1599,6 +1524,7 @@ ZSTD_compressBlock_lazy_generic(
}
if (searchMethod == search_rowHash) {
+ const U32 rowLog = MAX(4, MIN(6, ms->cParams.searchLog));
ZSTD_row_fillHashCache(ms, base, rowLog,
MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */),
ms->nextToUpdate, ilimit);
@@ -1613,8 +1539,9 @@ ZSTD_compressBlock_lazy_generic(
#endif
while (ip < ilimit) {
size_t matchLength=0;
- size_t offset=0;
+ size_t offcode=STORE_REPCODE_1;
const BYTE* start=ip+1;
+ DEBUGLOG(7, "search baseline (depth 0)");
/* check repCode */
if (isDxS) {
@@ -1640,7 +1567,7 @@ ZSTD_compressBlock_lazy_generic(
{ size_t offsetFound = 999999999;
size_t const ml2 = searchMax(ms, ip, iend, &offsetFound);
if (ml2 > matchLength)
- matchLength = ml2, start = ip, offset=offsetFound;
+ matchLength = ml2, start = ip, offcode=offsetFound;
}
if (matchLength < 4) {
@@ -1651,14 +1578,15 @@ ZSTD_compressBlock_lazy_generic(
/* let's try to find a better solution */
if (depth>=1)
while (ip<ilimit) {
+ DEBUGLOG(7, "search depth 1");
ip ++;
if ( (dictMode == ZSTD_noDict)
- && (offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
+ && (offcode) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
int const gain2 = (int)(mlRep * 3);
- int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
+ int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 1);
if ((mlRep >= 4) && (gain2 > gain1))
- matchLength = mlRep, offset = 0, start = ip;
+ matchLength = mlRep, offcode = STORE_REPCODE_1, start = ip;
}
if (isDxS) {
const U32 repIndex = (U32)(ip - base) - offset_1;
@@ -1670,30 +1598,31 @@ ZSTD_compressBlock_lazy_generic(
const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
int const gain2 = (int)(mlRep * 3);
- int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
+ int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 1);
if ((mlRep >= 4) && (gain2 > gain1))
- matchLength = mlRep, offset = 0, start = ip;
+ matchLength = mlRep, offcode = STORE_REPCODE_1, start = ip;
}
}
{ size_t offset2=999999999;
size_t const ml2 = searchMax(ms, ip, iend, &offset2);
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 4);
if ((ml2 >= 4) && (gain2 > gain1)) {
- matchLength = ml2, offset = offset2, start = ip;
+ matchLength = ml2, offcode = offset2, start = ip;
continue; /* search a better one */
} }
/* let's find an even better one */
if ((depth==2) && (ip<ilimit)) {
+ DEBUGLOG(7, "search depth 2");
ip ++;
if ( (dictMode == ZSTD_noDict)
- && (offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
+ && (offcode) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
int const gain2 = (int)(mlRep * 4);
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 1);
if ((mlRep >= 4) && (gain2 > gain1))
- matchLength = mlRep, offset = 0, start = ip;
+ matchLength = mlRep, offcode = STORE_REPCODE_1, start = ip;
}
if (isDxS) {
const U32 repIndex = (U32)(ip - base) - offset_1;
@@ -1705,46 +1634,45 @@ ZSTD_compressBlock_lazy_generic(
const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
int const gain2 = (int)(mlRep * 4);
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 1);
if ((mlRep >= 4) && (gain2 > gain1))
- matchLength = mlRep, offset = 0, start = ip;
+ matchLength = mlRep, offcode = STORE_REPCODE_1, start = ip;
}
}
{ size_t offset2=999999999;
size_t const ml2 = searchMax(ms, ip, iend, &offset2);
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 7);
if ((ml2 >= 4) && (gain2 > gain1)) {
- matchLength = ml2, offset = offset2, start = ip;
+ matchLength = ml2, offcode = offset2, start = ip;
continue;
} } }
break; /* nothing found : store previous solution */
}
/* NOTE:
- * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior.
- * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which
- * overflows the pointer, which is undefined behavior.
+ * Pay attention that `start[-value]` can lead to strange undefined behavior
+ * notably if `value` is unsigned, resulting in a large positive `-value`.
*/
/* catch up */
- if (offset) {
+ if (STORED_IS_OFFSET(offcode)) {
if (dictMode == ZSTD_noDict) {
- while ( ((start > anchor) & (start - (offset-ZSTD_REP_MOVE) > prefixLowest))
- && (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) ) /* only search for offset within prefix */
+ while ( ((start > anchor) & (start - STORED_OFFSET(offcode) > prefixLowest))
+ && (start[-1] == (start-STORED_OFFSET(offcode))[-1]) ) /* only search for offset within prefix */
{ start--; matchLength++; }
}
if (isDxS) {
- U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
+ U32 const matchIndex = (U32)((size_t)(start-base) - STORED_OFFSET(offcode));
const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex;
const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest;
while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
}
- offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
+ offset_2 = offset_1; offset_1 = (U32)STORED_OFFSET(offcode);
}
/* store sequence */
_storeSequence:
- { size_t const litLength = start - anchor;
- ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offset, matchLength-MINMATCH);
+ { size_t const litLength = (size_t)(start - anchor);
+ ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offcode, matchLength);
anchor = ip = start + matchLength;
}
@@ -1760,8 +1688,8 @@ _storeSequence:
&& (MEM_read32(repMatch) == MEM_read32(ip)) ) {
const BYTE* const repEnd2 = repIndex < prefixLowestIndex ? dictEnd : iend;
matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd2, prefixLowest) + 4;
- offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset_2 <=> offset_1 */
- ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, matchLength-MINMATCH);
+ offcode = offset_2; offset_2 = offset_1; offset_1 = (U32)offcode; /* swap offset_2 <=> offset_1 */
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, STORE_REPCODE_1, matchLength);
ip += matchLength;
anchor = ip;
continue;
@@ -1775,8 +1703,8 @@ _storeSequence:
&& (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
/* store sequence */
matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
- offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
- ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, matchLength-MINMATCH);
+ offcode = offset_2; offset_2 = offset_1; offset_1 = (U32)offcode; /* swap repcodes */
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, STORE_REPCODE_1, matchLength);
ip += matchLength;
anchor = ip;
continue; /* faster when present ... (?) */
@@ -1955,15 +1883,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
const U32 windowLog = ms->cParams.windowLog;
const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5;
- typedef size_t (*searchMax_f)(
- ZSTD_matchState_t* ms,
- const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
- const searchMax_f searchFuncs[3] = {
- ZSTD_HcFindBestMatch_extDict_selectMLS,
- ZSTD_BtFindBestMatch_extDict_selectMLS,
- ZSTD_RowFindBestMatch_extDict_selectRowLog
- };
- searchMax_f searchMax = searchFuncs[(int)searchMethod];
+ searchMax_f const searchMax = ZSTD_selectLazyVTable(ms, searchMethod, ZSTD_extDict)->searchMax;
U32 offset_1 = rep[0], offset_2 = rep[1];
DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod);
@@ -1985,7 +1905,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
#endif
while (ip < ilimit) {
size_t matchLength=0;
- size_t offset=0;
+ size_t offcode=STORE_REPCODE_1;
const BYTE* start=ip+1;
U32 curr = (U32)(ip-base);
@@ -1995,7 +1915,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
- & (offset_1 < curr+1 - windowLow) ) /* note: we are searching at curr+1 */
+ & (offset_1 <= curr+1 - windowLow) ) /* note: we are searching at curr+1 */
if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
/* repcode detected we should take it */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
@@ -2007,10 +1927,10 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
{ size_t offsetFound = 999999999;
size_t const ml2 = searchMax(ms, ip, iend, &offsetFound);
if (ml2 > matchLength)
- matchLength = ml2, start = ip, offset=offsetFound;
+ matchLength = ml2, start = ip, offcode=offsetFound;
}
- if (matchLength < 4) {
+ if (matchLength < 4) {
ip += ((ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */
continue;
}
@@ -2021,30 +1941,30 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
ip ++;
curr++;
/* check repCode */
- if (offset) {
+ if (offcode) {
const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
const U32 repIndex = (U32)(curr - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */
- & (offset_1 < curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
+ & (offset_1 <= curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
if (MEM_read32(ip) == MEM_read32(repMatch)) {
/* repcode detected */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
int const gain2 = (int)(repLength * 3);
- int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
+ int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 1);
if ((repLength >= 4) && (gain2 > gain1))
- matchLength = repLength, offset = 0, start = ip;
+ matchLength = repLength, offcode = STORE_REPCODE_1, start = ip;
} }
/* search match, depth 1 */
{ size_t offset2=999999999;
size_t const ml2 = searchMax(ms, ip, iend, &offset2);
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 4);
if ((ml2 >= 4) && (gain2 > gain1)) {
- matchLength = ml2, offset = offset2, start = ip;
+ matchLength = ml2, offcode = offset2, start = ip;
continue; /* search a better one */
} }
@@ -2053,48 +1973,48 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
ip ++;
curr++;
/* check repCode */
- if (offset) {
+ if (offcode) {
const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
const U32 repIndex = (U32)(curr - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */
- & (offset_1 < curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
+ & (offset_1 <= curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
if (MEM_read32(ip) == MEM_read32(repMatch)) {
/* repcode detected */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
int const gain2 = (int)(repLength * 4);
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 1);
if ((repLength >= 4) && (gain2 > gain1))
- matchLength = repLength, offset = 0, start = ip;
+ matchLength = repLength, offcode = STORE_REPCODE_1, start = ip;
} }
/* search match, depth 2 */
{ size_t offset2=999999999;
size_t const ml2 = searchMax(ms, ip, iend, &offset2);
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 7);
if ((ml2 >= 4) && (gain2 > gain1)) {
- matchLength = ml2, offset = offset2, start = ip;
+ matchLength = ml2, offcode = offset2, start = ip;
continue;
} } }
break; /* nothing found : store previous solution */
}
/* catch up */
- if (offset) {
- U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
+ if (STORED_IS_OFFSET(offcode)) {
+ U32 const matchIndex = (U32)((size_t)(start-base) - STORED_OFFSET(offcode));
const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
- offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
+ offset_2 = offset_1; offset_1 = (U32)STORED_OFFSET(offcode);
}
/* store sequence */
_storeSequence:
- { size_t const litLength = start - anchor;
- ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offset, matchLength-MINMATCH);
+ { size_t const litLength = (size_t)(start - anchor);
+ ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offcode, matchLength);
anchor = ip = start + matchLength;
}
@@ -2106,13 +2026,13 @@ _storeSequence:
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */
- & (offset_2 < repCurrent - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
+ & (offset_2 <= repCurrent - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
if (MEM_read32(ip) == MEM_read32(repMatch)) {
/* repcode detected we should take it */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
- offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset history */
- ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, matchLength-MINMATCH);
+ offcode = offset_2; offset_2 = offset_1; offset_1 = (U32)offcode; /* swap offset history */
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, STORE_REPCODE_1, matchLength);
ip += matchLength;
anchor = ip;
continue; /* faster when present ... (?) */
diff --git a/thirdparty/zstd/compress/zstd_ldm.c b/thirdparty/zstd/compress/zstd_ldm.c
index fa4ebeabd7..f662b2546e 100644
--- a/thirdparty/zstd/compress/zstd_ldm.c
+++ b/thirdparty/zstd/compress/zstd_ldm.c
@@ -159,12 +159,12 @@ size_t ZSTD_ldm_getTableSize(ldmParams_t params)
size_t const ldmBucketSize = ((size_t)1) << (params.hashLog - ldmBucketSizeLog);
size_t const totalSize = ZSTD_cwksp_alloc_size(ldmBucketSize)
+ ZSTD_cwksp_alloc_size(ldmHSize * sizeof(ldmEntry_t));
- return params.enableLdm ? totalSize : 0;
+ return params.enableLdm == ZSTD_ps_enable ? totalSize : 0;
}
size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize)
{
- return params.enableLdm ? (maxChunkSize / params.minMatchLength) : 0;
+ return params.enableLdm == ZSTD_ps_enable ? (maxChunkSize / params.minMatchLength) : 0;
}
/** ZSTD_ldm_getBucket() :
@@ -478,7 +478,7 @@ static size_t ZSTD_ldm_generateSequences_internal(
*/
if (anchor > ip + hashed) {
ZSTD_ldm_gear_reset(&hashState, anchor - minMatchLength, minMatchLength);
- /* Continue the outter loop at anchor (ip + hashed == anchor). */
+ /* Continue the outer loop at anchor (ip + hashed == anchor). */
ip = anchor - hashed;
break;
}
@@ -579,7 +579,9 @@ size_t ZSTD_ldm_generateSequences(
return 0;
}
-void ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize, U32 const minMatch) {
+void
+ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize, U32 const minMatch)
+{
while (srcSize > 0 && rawSeqStore->pos < rawSeqStore->size) {
rawSeq* seq = rawSeqStore->seq + rawSeqStore->pos;
if (srcSize <= seq->litLength) {
@@ -657,7 +659,7 @@ void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
- ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
+ ZSTD_paramSwitch_e useRowMatchFinder,
void const* src, size_t srcSize)
{
const ZSTD_compressionParameters* const cParams = &ms->cParams;
@@ -709,8 +711,8 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
rep[0] = sequence.offset;
/* Store the sequence */
ZSTD_storeSeq(seqStore, newLitLength, ip - newLitLength, iend,
- sequence.offset + ZSTD_REP_MOVE,
- sequence.matchLength - MINMATCH);
+ STORE_OFFSET(sequence.offset),
+ sequence.matchLength);
ip += sequence.matchLength;
}
}
diff --git a/thirdparty/zstd/compress/zstd_ldm.h b/thirdparty/zstd/compress/zstd_ldm.h
index 393466fa9f..4e68dbf52e 100644
--- a/thirdparty/zstd/compress/zstd_ldm.h
+++ b/thirdparty/zstd/compress/zstd_ldm.h
@@ -66,7 +66,7 @@ size_t ZSTD_ldm_generateSequences(
*/
size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
- ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
+ ZSTD_paramSwitch_e useRowMatchFinder,
void const* src, size_t srcSize);
/**
diff --git a/thirdparty/zstd/compress/zstd_ldm_geartab.h b/thirdparty/zstd/compress/zstd_ldm_geartab.h
index e5c24d856b..647f865be2 100644
--- a/thirdparty/zstd/compress/zstd_ldm_geartab.h
+++ b/thirdparty/zstd/compress/zstd_ldm_geartab.h
@@ -11,7 +11,10 @@
#ifndef ZSTD_LDM_GEARTAB_H
#define ZSTD_LDM_GEARTAB_H
-static U64 ZSTD_ldm_gearTab[256] = {
+#include "../common/compiler.h" /* UNUSED_ATTR */
+#include "../common/mem.h" /* U64 */
+
+static UNUSED_ATTR const U64 ZSTD_ldm_gearTab[256] = {
0xf5b8f72c5f77775c, 0x84935f266b7ac412, 0xb647ada9ca730ccc,
0xb065bb4b114fb1de, 0x34584e7e8c3a9fd0, 0x4e97e17c6ae26b05,
0x3a03d743bc99a604, 0xcecd042422c4044f, 0x76de76c58524259e,
diff --git a/thirdparty/zstd/compress/zstd_opt.c b/thirdparty/zstd/compress/zstd_opt.c
index 402a7e5c76..1b1ddad428 100644
--- a/thirdparty/zstd/compress/zstd_opt.c
+++ b/thirdparty/zstd/compress/zstd_opt.c
@@ -14,7 +14,6 @@
#define ZSTD_LITFREQ_ADD 2 /* scaling factor for litFreq, so that frequencies adapt faster to new stats */
-#define ZSTD_FREQ_DIV 4 /* log factor when using previous stats to init next stats */
#define ZSTD_MAX_PRICE (1<<30)
#define ZSTD_PREDEF_THRESHOLD 1024 /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */
@@ -24,11 +23,11 @@
* Price functions for optimal parser
***************************************/
-#if 0 /* approximation at bit level */
+#if 0 /* approximation at bit level (for tests) */
# define BITCOST_ACCURACY 0
# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
-# define WEIGHT(stat) ((void)opt, ZSTD_bitWeight(stat))
-#elif 0 /* fractional bit accuracy */
+# define WEIGHT(stat, opt) ((void)opt, ZSTD_bitWeight(stat))
+#elif 0 /* fractional bit accuracy (for tests) */
# define BITCOST_ACCURACY 8
# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
# define WEIGHT(stat,opt) ((void)opt, ZSTD_fracWeight(stat))
@@ -66,7 +65,7 @@ MEM_STATIC double ZSTD_fCost(U32 price)
static int ZSTD_compressedLiterals(optState_t const* const optPtr)
{
- return optPtr->literalCompressionMode != ZSTD_lcm_uncompressed;
+ return optPtr->literalCompressionMode != ZSTD_ps_disable;
}
static void ZSTD_setBasePrices(optState_t* optPtr, int optLevel)
@@ -79,25 +78,46 @@ static void ZSTD_setBasePrices(optState_t* optPtr, int optLevel)
}
-/* ZSTD_downscaleStat() :
- * reduce all elements in table by a factor 2^(ZSTD_FREQ_DIV+malus)
- * return the resulting sum of elements */
-static U32 ZSTD_downscaleStat(unsigned* table, U32 lastEltIndex, int malus)
+static U32 sum_u32(const unsigned table[], size_t nbElts)
+{
+ size_t n;
+ U32 total = 0;
+ for (n=0; n<nbElts; n++) {
+ total += table[n];
+ }
+ return total;
+}
+
+static U32 ZSTD_downscaleStats(unsigned* table, U32 lastEltIndex, U32 shift)
{
U32 s, sum=0;
- DEBUGLOG(5, "ZSTD_downscaleStat (nbElts=%u)", (unsigned)lastEltIndex+1);
- assert(ZSTD_FREQ_DIV+malus > 0 && ZSTD_FREQ_DIV+malus < 31);
+ DEBUGLOG(5, "ZSTD_downscaleStats (nbElts=%u, shift=%u)", (unsigned)lastEltIndex+1, (unsigned)shift);
+ assert(shift < 30);
for (s=0; s<lastEltIndex+1; s++) {
- table[s] = 1 + (table[s] >> (ZSTD_FREQ_DIV+malus));
+ table[s] = 1 + (table[s] >> shift);
sum += table[s];
}
return sum;
}
+/* ZSTD_scaleStats() :
+ * reduce all elements in table is sum too large
+ * return the resulting sum of elements */
+static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget)
+{
+ U32 const prevsum = sum_u32(table, lastEltIndex+1);
+ U32 const factor = prevsum >> logTarget;
+ DEBUGLOG(5, "ZSTD_scaleStats (nbElts=%u, target=%u)", (unsigned)lastEltIndex+1, (unsigned)logTarget);
+ assert(logTarget < 30);
+ if (factor <= 1) return prevsum;
+ return ZSTD_downscaleStats(table, lastEltIndex, ZSTD_highbit32(factor));
+}
+
/* ZSTD_rescaleFreqs() :
* if first block (detected by optPtr->litLengthSum == 0) : init statistics
* take hints from dictionary if there is one
- * or init from zero, using src for literals stats, or flat 1 for match symbols
+ * and init from zero if there is none,
+ * using src for literals stats, and baseline stats for sequence symbols
* otherwise downscale existing stats, to be used as seed for next block.
*/
static void
@@ -126,7 +146,7 @@ ZSTD_rescaleFreqs(optState_t* const optPtr,
optPtr->litSum = 0;
for (lit=0; lit<=MaxLit; lit++) {
U32 const scaleLog = 11; /* scale to 2K */
- U32 const bitCost = HUF_getNbBits(optPtr->symbolCosts->huf.CTable, lit);
+ U32 const bitCost = HUF_getNbBitsFromCTable(optPtr->symbolCosts->huf.CTable, lit);
assert(bitCost <= scaleLog);
optPtr->litFreq[lit] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;
optPtr->litSum += optPtr->litFreq[lit];
@@ -174,14 +194,19 @@ ZSTD_rescaleFreqs(optState_t* const optPtr,
if (compressedLiterals) {
unsigned lit = MaxLit;
HIST_count_simple(optPtr->litFreq, &lit, src, srcSize); /* use raw first block to init statistics */
- optPtr->litSum = ZSTD_downscaleStat(optPtr->litFreq, MaxLit, 1);
+ optPtr->litSum = ZSTD_downscaleStats(optPtr->litFreq, MaxLit, 8);
}
- { unsigned ll;
- for (ll=0; ll<=MaxLL; ll++)
- optPtr->litLengthFreq[ll] = 1;
+ { unsigned const baseLLfreqs[MaxLL+1] = {
+ 4, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1
+ };
+ ZSTD_memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs));
+ optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1);
}
- optPtr->litLengthSum = MaxLL+1;
{ unsigned ml;
for (ml=0; ml<=MaxML; ml++)
@@ -189,21 +214,26 @@ ZSTD_rescaleFreqs(optState_t* const optPtr,
}
optPtr->matchLengthSum = MaxML+1;
- { unsigned of;
- for (of=0; of<=MaxOff; of++)
- optPtr->offCodeFreq[of] = 1;
+ { unsigned const baseOFCfreqs[MaxOff+1] = {
+ 6, 2, 1, 1, 2, 3, 4, 4,
+ 4, 3, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1
+ };
+ ZSTD_memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs));
+ optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1);
}
- optPtr->offCodeSum = MaxOff+1;
+
}
} else { /* new block : re-use previous statistics, scaled down */
if (compressedLiterals)
- optPtr->litSum = ZSTD_downscaleStat(optPtr->litFreq, MaxLit, 1);
- optPtr->litLengthSum = ZSTD_downscaleStat(optPtr->litLengthFreq, MaxLL, 0);
- optPtr->matchLengthSum = ZSTD_downscaleStat(optPtr->matchLengthFreq, MaxML, 0);
- optPtr->offCodeSum = ZSTD_downscaleStat(optPtr->offCodeFreq, MaxOff, 0);
+ optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 12);
+ optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 11);
+ optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 11);
+ optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 11);
}
ZSTD_setBasePrices(optPtr, optLevel);
@@ -239,7 +269,16 @@ static U32 ZSTD_rawLiteralsCost(const BYTE* const literals, U32 const litLength,
* cost of literalLength symbol */
static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optPtr, int optLevel)
{
- if (optPtr->priceType == zop_predef) return WEIGHT(litLength, optLevel);
+ assert(litLength <= ZSTD_BLOCKSIZE_MAX);
+ if (optPtr->priceType == zop_predef)
+ return WEIGHT(litLength, optLevel);
+ /* We can't compute the litLength price for sizes >= ZSTD_BLOCKSIZE_MAX
+ * because it isn't representable in the zstd format. So instead just
+ * call it 1 bit more than ZSTD_BLOCKSIZE_MAX - 1. In this case the block
+ * would be all literals.
+ */
+ if (litLength == ZSTD_BLOCKSIZE_MAX)
+ return BITCOST_MULTIPLIER + ZSTD_litLengthPrice(ZSTD_BLOCKSIZE_MAX - 1, optPtr, optLevel);
/* dynamic statistics */
{ U32 const llCode = ZSTD_LLcode(litLength);
@@ -252,15 +291,17 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP
/* ZSTD_getMatchPrice() :
* Provides the cost of the match part (offset + matchLength) of a sequence
* Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence.
- * optLevel: when <2, favors small offset for decompression speed (improved cache efficiency) */
+ * @offcode : expects a scale where 0,1,2 are repcodes 1-3, and 3+ are real_offsets+2
+ * @optLevel: when <2, favors small offset for decompression speed (improved cache efficiency)
+ */
FORCE_INLINE_TEMPLATE U32
-ZSTD_getMatchPrice(U32 const offset,
+ZSTD_getMatchPrice(U32 const offcode,
U32 const matchLength,
const optState_t* const optPtr,
int const optLevel)
{
U32 price;
- U32 const offCode = ZSTD_highbit32(offset+1);
+ U32 const offCode = ZSTD_highbit32(STORED_TO_OFFBASE(offcode));
U32 const mlBase = matchLength - MINMATCH;
assert(matchLength >= MINMATCH);
@@ -303,8 +344,8 @@ static void ZSTD_updateStats(optState_t* const optPtr,
optPtr->litLengthSum++;
}
- /* match offset code (0-2=>repCode; 3+=>offset+2) */
- { U32 const offCode = ZSTD_highbit32(offsetCode+1);
+ /* offset code : expected to follow storeSeq() numeric representation */
+ { U32 const offCode = ZSTD_highbit32(STORED_TO_OFFBASE(offsetCode));
assert(offCode <= MaxOff);
optPtr->offCodeFreq[offCode]++;
optPtr->offCodeSum++;
@@ -338,7 +379,7 @@ MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
/* Update hashTable3 up to ip (excluded)
Assumption : always within prefix (i.e. not within extDict) */
-static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms,
+static U32 ZSTD_insertAndFindFirstIndexHash3 (const ZSTD_matchState_t* ms,
U32* nextToUpdate3,
const BYTE* const ip)
{
@@ -364,11 +405,13 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms,
* Binary Tree search
***************************************/
/** ZSTD_insertBt1() : add one or multiple positions to tree.
- * ip : assumed <= iend-8 .
+ * @param ip assumed <= iend-8 .
+ * @param target The target of ZSTD_updateTree_internal() - we are filling to this position
* @return : nb of positions added */
static U32 ZSTD_insertBt1(
- ZSTD_matchState_t* ms,
+ const ZSTD_matchState_t* ms,
const BYTE* const ip, const BYTE* const iend,
+ U32 const target,
U32 const mls, const int extDict)
{
const ZSTD_compressionParameters* const cParams = &ms->cParams;
@@ -391,7 +434,10 @@ static U32 ZSTD_insertBt1(
U32* smallerPtr = bt + 2*(curr&btMask);
U32* largerPtr = smallerPtr + 1;
U32 dummy32; /* to be nullified at the end */
- U32 const windowLow = ms->window.lowLimit;
+ /* windowLow is based on target because
+ * we only need positions that will be in the window at the end of the tree update.
+ */
+ U32 const windowLow = ZSTD_getLowestMatchIndex(ms, target, cParams->windowLog);
U32 matchEndIdx = curr+8+1;
size_t bestLength = 8;
U32 nbCompares = 1U << cParams->searchLog;
@@ -404,11 +450,12 @@ static U32 ZSTD_insertBt1(
DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr);
+ assert(curr <= target);
assert(ip <= iend-8); /* required for h calculation */
hashTable[h] = curr; /* Update Hash Table */
assert(windowLow > 0);
- while (nbCompares-- && (matchIndex >= windowLow)) {
+ for (; nbCompares && (matchIndex >= windowLow); --nbCompares) {
U32* const nextPtr = bt + 2*(matchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
assert(matchIndex < curr);
@@ -492,7 +539,7 @@ void ZSTD_updateTree_internal(
idx, target, dictMode);
while(idx < target) {
- U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, mls, dictMode == ZSTD_extDict);
+ U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, target, mls, dictMode == ZSTD_extDict);
assert(idx < (U32)(idx + forward));
idx += forward;
}
@@ -597,7 +644,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
DEBUGLOG(8, "found repCode %u (ll0:%u, offset:%u) of length %u",
repCode, ll0, repOffset, repLen);
bestLength = repLen;
- matches[mnum].off = repCode - ll0;
+ matches[mnum].off = STORE_REPCODE(repCode - ll0 + 1); /* expect value between 1 and 3 */
matches[mnum].len = (U32)repLen;
mnum++;
if ( (repLen > sufficient_len)
@@ -626,7 +673,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
bestLength = mlen;
assert(curr > matchIndex3);
assert(mnum==0); /* no prior solution */
- matches[0].off = (curr - matchIndex3) + ZSTD_REP_MOVE;
+ matches[0].off = STORE_OFFSET(curr - matchIndex3);
matches[0].len = (U32)mlen;
mnum = 1;
if ( (mlen > sufficient_len) |
@@ -635,11 +682,11 @@ U32 ZSTD_insertBtAndGetAllMatches (
return 1;
} } }
/* no dictMatchState lookup: dicts don't have a populated HC3 table */
- }
+ } /* if (mls == 3) */
hashTable[h] = curr; /* Update Hash Table */
- while (nbCompares-- && (matchIndex >= matchLow)) {
+ for (; nbCompares && (matchIndex >= matchLow); --nbCompares) {
U32* const nextPtr = bt + 2*(matchIndex & btMask);
const BYTE* match;
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
@@ -660,20 +707,19 @@ U32 ZSTD_insertBtAndGetAllMatches (
if (matchLength > bestLength) {
DEBUGLOG(8, "found match of length %u at distance %u (offCode=%u)",
- (U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE);
+ (U32)matchLength, curr - matchIndex, STORE_OFFSET(curr - matchIndex));
assert(matchEndIdx > matchIndex);
if (matchLength > matchEndIdx - matchIndex)
matchEndIdx = matchIndex + (U32)matchLength;
bestLength = matchLength;
- matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE;
+ matches[mnum].off = STORE_OFFSET(curr - matchIndex);
matches[mnum].len = (U32)matchLength;
mnum++;
if ( (matchLength > ZSTD_OPT_NUM)
| (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {
if (dictMode == ZSTD_dictMatchState) nbCompares = 0; /* break should also skip searching dms */
break; /* drop, to preserve bt consistency (miss a little bit of compression) */
- }
- }
+ } }
if (match[matchLength] < ip[matchLength]) {
/* match smaller than current */
@@ -692,12 +738,13 @@ U32 ZSTD_insertBtAndGetAllMatches (
*smallerPtr = *largerPtr = 0;
+ assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
if (dictMode == ZSTD_dictMatchState && nbCompares) {
size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls);
U32 dictMatchIndex = dms->hashTable[dmsH];
const U32* const dmsBt = dms->chainTable;
commonLengthSmaller = commonLengthLarger = 0;
- while (nbCompares-- && (dictMatchIndex > dmsLowLimit)) {
+ for (; nbCompares && (dictMatchIndex > dmsLowLimit); --nbCompares) {
const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
const BYTE* match = dmsBase + dictMatchIndex;
@@ -708,18 +755,17 @@ U32 ZSTD_insertBtAndGetAllMatches (
if (matchLength > bestLength) {
matchIndex = dictMatchIndex + dmsIndexDelta;
DEBUGLOG(8, "found dms match of length %u at distance %u (offCode=%u)",
- (U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE);
+ (U32)matchLength, curr - matchIndex, STORE_OFFSET(curr - matchIndex));
if (matchLength > matchEndIdx - matchIndex)
matchEndIdx = matchIndex + (U32)matchLength;
bestLength = matchLength;
- matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE;
+ matches[mnum].off = STORE_OFFSET(curr - matchIndex);
matches[mnum].len = (U32)matchLength;
mnum++;
if ( (matchLength > ZSTD_OPT_NUM)
| (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {
break; /* drop, to guarantee consistency (miss a little bit of compression) */
- }
- }
+ } }
if (dictMatchIndex <= dmsBtLow) { break; } /* beyond tree size, stop the search */
if (match[matchLength] < ip[matchLength]) {
@@ -729,39 +775,91 @@ U32 ZSTD_insertBtAndGetAllMatches (
/* match is larger than current */
commonLengthLarger = matchLength;
dictMatchIndex = nextPtr[0];
- }
- }
- }
+ } } } /* if (dictMode == ZSTD_dictMatchState) */
assert(matchEndIdx > curr+8);
ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
return mnum;
}
-
-FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
- ZSTD_match_t* matches, /* store result (match found, increasing size) in this table */
- ZSTD_matchState_t* ms,
- U32* nextToUpdate3,
- const BYTE* ip, const BYTE* const iHighLimit, const ZSTD_dictMode_e dictMode,
- const U32 rep[ZSTD_REP_NUM],
- U32 const ll0,
- U32 const lengthToBeat)
+typedef U32 (*ZSTD_getAllMatchesFn)(
+ ZSTD_match_t*,
+ ZSTD_matchState_t*,
+ U32*,
+ const BYTE*,
+ const BYTE*,
+ const U32 rep[ZSTD_REP_NUM],
+ U32 const ll0,
+ U32 const lengthToBeat);
+
+FORCE_INLINE_TEMPLATE U32 ZSTD_btGetAllMatches_internal(
+ ZSTD_match_t* matches,
+ ZSTD_matchState_t* ms,
+ U32* nextToUpdate3,
+ const BYTE* ip,
+ const BYTE* const iHighLimit,
+ const U32 rep[ZSTD_REP_NUM],
+ U32 const ll0,
+ U32 const lengthToBeat,
+ const ZSTD_dictMode_e dictMode,
+ const U32 mls)
{
- const ZSTD_compressionParameters* const cParams = &ms->cParams;
- U32 const matchLengthSearch = cParams->minMatch;
- DEBUGLOG(8, "ZSTD_BtGetAllMatches");
- if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */
- ZSTD_updateTree_internal(ms, ip, iHighLimit, matchLengthSearch, dictMode);
- switch(matchLengthSearch)
- {
- case 3 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 3);
- default :
- case 4 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 4);
- case 5 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 5);
- case 7 :
- case 6 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 6);
+ assert(BOUNDED(3, ms->cParams.minMatch, 6) == mls);
+ DEBUGLOG(8, "ZSTD_BtGetAllMatches(dictMode=%d, mls=%u)", (int)dictMode, mls);
+ if (ip < ms->window.base + ms->nextToUpdate)
+ return 0; /* skipped area */
+ ZSTD_updateTree_internal(ms, ip, iHighLimit, mls, dictMode);
+ return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, mls);
+}
+
+#define ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls) ZSTD_btGetAllMatches_##dictMode##_##mls
+
+#define GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, mls) \
+ static U32 ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls)( \
+ ZSTD_match_t* matches, \
+ ZSTD_matchState_t* ms, \
+ U32* nextToUpdate3, \
+ const BYTE* ip, \
+ const BYTE* const iHighLimit, \
+ const U32 rep[ZSTD_REP_NUM], \
+ U32 const ll0, \
+ U32 const lengthToBeat) \
+ { \
+ return ZSTD_btGetAllMatches_internal( \
+ matches, ms, nextToUpdate3, ip, iHighLimit, \
+ rep, ll0, lengthToBeat, ZSTD_##dictMode, mls); \
+ }
+
+#define GEN_ZSTD_BT_GET_ALL_MATCHES(dictMode) \
+ GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 3) \
+ GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 4) \
+ GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 5) \
+ GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 6)
+
+GEN_ZSTD_BT_GET_ALL_MATCHES(noDict)
+GEN_ZSTD_BT_GET_ALL_MATCHES(extDict)
+GEN_ZSTD_BT_GET_ALL_MATCHES(dictMatchState)
+
+#define ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMode) \
+ { \
+ ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 3), \
+ ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 4), \
+ ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 5), \
+ ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 6) \
}
+
+static ZSTD_getAllMatchesFn
+ZSTD_selectBtGetAllMatches(ZSTD_matchState_t const* ms, ZSTD_dictMode_e const dictMode)
+{
+ ZSTD_getAllMatchesFn const getAllMatchesFns[3][4] = {
+ ZSTD_BT_GET_ALL_MATCHES_ARRAY(noDict),
+ ZSTD_BT_GET_ALL_MATCHES_ARRAY(extDict),
+ ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMatchState)
+ };
+ U32 const mls = BOUNDED(3, ms->cParams.minMatch, 6);
+ assert((U32)dictMode < 3);
+ assert(mls - 3 < 4);
+ return getAllMatchesFns[(int)dictMode][mls - 3];
}
/*************************
@@ -770,16 +868,18 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
/* Struct containing info needed to make decision about ldm inclusion */
typedef struct {
- rawSeqStore_t seqStore; /* External match candidates store for this block */
- U32 startPosInBlock; /* Start position of the current match candidate */
- U32 endPosInBlock; /* End position of the current match candidate */
- U32 offset; /* Offset of the match candidate */
+ rawSeqStore_t seqStore; /* External match candidates store for this block */
+ U32 startPosInBlock; /* Start position of the current match candidate */
+ U32 endPosInBlock; /* End position of the current match candidate */
+ U32 offset; /* Offset of the match candidate */
} ZSTD_optLdm_t;
/* ZSTD_optLdm_skipRawSeqStoreBytes():
- * Moves forward in rawSeqStore by nbBytes, which will update the fields 'pos' and 'posInSequence'.
+ * Moves forward in @rawSeqStore by @nbBytes,
+ * which will update the fields 'pos' and 'posInSequence'.
*/
-static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
+static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes)
+{
U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes);
while (currPos && rawSeqStore->pos < rawSeqStore->size) {
rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
@@ -800,8 +900,10 @@ static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t
* Calculates the beginning and end of the next match in the current block.
* Updates 'pos' and 'posInSequence' of the ldmSeqStore.
*/
-static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock,
- U32 blockBytesRemaining) {
+static void
+ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock,
+ U32 blockBytesRemaining)
+{
rawSeq currSeq;
U32 currBlockEndPos;
U32 literalsBytesRemaining;
@@ -813,8 +915,8 @@ static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 cu
optLdm->endPosInBlock = UINT_MAX;
return;
}
- /* Calculate appropriate bytes left in matchLength and litLength after adjusting
- based on ldmSeqStore->posInSequence */
+ /* Calculate appropriate bytes left in matchLength and litLength
+ * after adjusting based on ldmSeqStore->posInSequence */
currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos];
assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength);
currBlockEndPos = currPosInBlock + blockBytesRemaining;
@@ -850,15 +952,16 @@ static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 cu
}
/* ZSTD_optLdm_maybeAddMatch():
- * Adds a match if it's long enough, based on it's 'matchStartPosInBlock'
- * and 'matchEndPosInBlock', into 'matches'. Maintains the correct ordering of 'matches'
+ * Adds a match if it's long enough,
+ * based on it's 'matchStartPosInBlock' and 'matchEndPosInBlock',
+ * into 'matches'. Maintains the correct ordering of 'matches'.
*/
static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
- ZSTD_optLdm_t* optLdm, U32 currPosInBlock) {
- U32 posDiff = currPosInBlock - optLdm->startPosInBlock;
+ const ZSTD_optLdm_t* optLdm, U32 currPosInBlock)
+{
+ U32 const posDiff = currPosInBlock - optLdm->startPosInBlock;
/* Note: ZSTD_match_t actually contains offCode and matchLength (before subtracting MINMATCH) */
- U32 candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff;
- U32 candidateOffCode = optLdm->offset + ZSTD_REP_MOVE;
+ U32 const candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff;
/* Ensure that current block position is not outside of the match */
if (currPosInBlock < optLdm->startPosInBlock
@@ -868,6 +971,7 @@ static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
}
if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) {
+ U32 const candidateOffCode = STORE_OFFSET(optLdm->offset);
DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offCode: %u matchLength %u) at block position=%u",
candidateOffCode, candidateMatchLength, currPosInBlock);
matches[*nbMatches].len = candidateMatchLength;
@@ -879,8 +983,11 @@ static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
/* ZSTD_optLdm_processMatchCandidate():
* Wrapper function to update ldm seq store and call ldm functions as necessary.
*/
-static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_t* matches, U32* nbMatches,
- U32 currPosInBlock, U32 remainingBytes) {
+static void
+ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm,
+ ZSTD_match_t* matches, U32* nbMatches,
+ U32 currPosInBlock, U32 remainingBytes)
+{
if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
return;
}
@@ -891,19 +998,19 @@ static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_
* at the end of a match from the ldm seq store, and will often be some bytes
* over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots"
*/
- U32 posOvershoot = currPosInBlock - optLdm->endPosInBlock;
+ U32 const posOvershoot = currPosInBlock - optLdm->endPosInBlock;
ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot);
- }
+ }
ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes);
}
ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock);
}
+
/*-*******************************
* Optimal parser
*********************************/
-
static U32 ZSTD_totalLen(ZSTD_optimal_t sol)
{
return sol.litlen + sol.mlen;
@@ -944,6 +1051,8 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
const BYTE* const prefixStart = base + ms->window.dictLimit;
const ZSTD_compressionParameters* const cParams = &ms->cParams;
+ ZSTD_getAllMatchesFn getAllMatches = ZSTD_selectBtGetAllMatches(ms, dictMode);
+
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4;
U32 nextToUpdate3 = ms->nextToUpdate;
@@ -971,7 +1080,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
/* find first match */
{ U32 const litlen = (U32)(ip - anchor);
U32 const ll0 = !litlen;
- U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);
+ U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, ip, iend, rep, ll0, minMatch);
ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
(U32)(ip-istart), (U32)(iend - ip));
if (!nbMatches) { ip++; continue; }
@@ -985,18 +1094,18 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
* in every price. We include the literal length to avoid negative
* prices when we subtract the previous literal length.
*/
- opt[0].price = ZSTD_litLengthPrice(litlen, optStatePtr, optLevel);
+ opt[0].price = (int)ZSTD_litLengthPrice(litlen, optStatePtr, optLevel);
/* large match -> immediate encoding */
{ U32 const maxML = matches[nbMatches-1].len;
- U32 const maxOffset = matches[nbMatches-1].off;
+ U32 const maxOffcode = matches[nbMatches-1].off;
DEBUGLOG(6, "found %u matches of maxLength=%u and maxOffCode=%u at cPos=%u => start new series",
- nbMatches, maxML, maxOffset, (U32)(ip-prefixStart));
+ nbMatches, maxML, maxOffcode, (U32)(ip-prefixStart));
if (maxML > sufficient_len) {
lastSequence.litlen = litlen;
lastSequence.mlen = maxML;
- lastSequence.off = maxOffset;
+ lastSequence.off = maxOffcode;
DEBUGLOG(6, "large match (%u>%u), immediate encoding",
maxML, sufficient_len);
cur = 0;
@@ -1005,24 +1114,25 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
} }
/* set prices for first matches starting position == 0 */
- { U32 const literalsPrice = opt[0].price + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
+ assert(opt[0].price >= 0);
+ { U32 const literalsPrice = (U32)opt[0].price + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
U32 pos;
U32 matchNb;
for (pos = 1; pos < minMatch; pos++) {
opt[pos].price = ZSTD_MAX_PRICE; /* mlen, litlen and price will be fixed during forward scanning */
}
for (matchNb = 0; matchNb < nbMatches; matchNb++) {
- U32 const offset = matches[matchNb].off;
+ U32 const offcode = matches[matchNb].off;
U32 const end = matches[matchNb].len;
for ( ; pos <= end ; pos++ ) {
- U32 const matchPrice = ZSTD_getMatchPrice(offset, pos, optStatePtr, optLevel);
+ U32 const matchPrice = ZSTD_getMatchPrice(offcode, pos, optStatePtr, optLevel);
U32 const sequencePrice = literalsPrice + matchPrice;
DEBUGLOG(7, "rPos:%u => set initial price : %.2f",
pos, ZSTD_fCost(sequencePrice));
opt[pos].mlen = pos;
- opt[pos].off = offset;
+ opt[pos].off = offcode;
opt[pos].litlen = litlen;
- opt[pos].price = sequencePrice;
+ opt[pos].price = (int)sequencePrice;
} }
last_pos = pos-1;
}
@@ -1037,9 +1147,9 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
/* Fix current position with one literal if cheaper */
{ U32 const litlen = (opt[cur-1].mlen == 0) ? opt[cur-1].litlen + 1 : 1;
int const price = opt[cur-1].price
- + ZSTD_rawLiteralsCost(ip+cur-1, 1, optStatePtr, optLevel)
- + ZSTD_litLengthPrice(litlen, optStatePtr, optLevel)
- - ZSTD_litLengthPrice(litlen-1, optStatePtr, optLevel);
+ + (int)ZSTD_rawLiteralsCost(ip+cur-1, 1, optStatePtr, optLevel)
+ + (int)ZSTD_litLengthPrice(litlen, optStatePtr, optLevel)
+ - (int)ZSTD_litLengthPrice(litlen-1, optStatePtr, optLevel);
assert(price < 1000000000); /* overflow check */
if (price <= opt[cur].price) {
DEBUGLOG(7, "cPos:%zi==rPos:%u : better price (%.2f<=%.2f) using literal (ll==%u) (hist:%u,%u,%u)",
@@ -1065,7 +1175,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
assert(cur >= opt[cur].mlen);
if (opt[cur].mlen != 0) {
U32 const prev = cur - opt[cur].mlen;
- repcodes_t newReps = ZSTD_updateRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0);
+ repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0);
ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t));
} else {
ZSTD_memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t));
@@ -1082,11 +1192,12 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
continue; /* skip unpromising positions; about ~+6% speed, -0.01 ratio */
}
+ assert(opt[cur].price >= 0);
{ U32 const ll0 = (opt[cur].mlen != 0);
U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
- U32 const previousPrice = opt[cur].price;
+ U32 const previousPrice = (U32)opt[cur].price;
U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
- U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);
+ U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, inr, iend, opt[cur].rep, ll0, minMatch);
U32 matchNb;
ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
@@ -1124,7 +1235,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
for (mlen = lastML; mlen >= startML; mlen--) { /* scan downward */
U32 const pos = cur + mlen;
- int const price = basePrice + ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel);
+ int const price = (int)basePrice + (int)ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel);
if ((pos > last_pos) || (price < opt[pos].price)) {
DEBUGLOG(7, "rPos:%u (ml=%2u) => new better price (%.2f<%.2f)",
@@ -1154,7 +1265,7 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
* update them while traversing the sequences.
*/
if (lastSequence.mlen != 0) {
- repcodes_t reps = ZSTD_updateRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0);
+ repcodes_t const reps = ZSTD_newRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0);
ZSTD_memcpy(rep, &reps, sizeof(reps));
} else {
ZSTD_memcpy(rep, opt[cur].rep, sizeof(repcodes_t));
@@ -1198,7 +1309,7 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
assert(anchor + llen <= iend);
ZSTD_updateStats(optStatePtr, llen, anchor, offCode, mlen);
- ZSTD_storeSeq(seqStore, llen, anchor, iend, offCode, mlen-MINMATCH);
+ ZSTD_storeSeq(seqStore, llen, anchor, iend, offCode, mlen);
anchor += advance;
ip = anchor;
} }
@@ -1210,38 +1321,30 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
return (size_t)(iend - anchor);
}
+static size_t ZSTD_compressBlock_opt0(
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
+ const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode)
+{
+ return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /* optLevel */, dictMode);
+}
+
+static size_t ZSTD_compressBlock_opt2(
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
+ const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode)
+{
+ return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /* optLevel */, dictMode);
+}
size_t ZSTD_compressBlock_btopt(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
const void* src, size_t srcSize)
{
DEBUGLOG(5, "ZSTD_compressBlock_btopt");
- return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_noDict);
+ return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_noDict);
}
-/* used in 2-pass strategy */
-static U32 ZSTD_upscaleStat(unsigned* table, U32 lastEltIndex, int bonus)
-{
- U32 s, sum=0;
- assert(ZSTD_FREQ_DIV+bonus >= 0);
- for (s=0; s<lastEltIndex+1; s++) {
- table[s] <<= ZSTD_FREQ_DIV+bonus;
- table[s]--;
- sum += table[s];
- }
- return sum;
-}
-/* used in 2-pass strategy */
-MEM_STATIC void ZSTD_upscaleStats(optState_t* optPtr)
-{
- if (ZSTD_compressedLiterals(optPtr))
- optPtr->litSum = ZSTD_upscaleStat(optPtr->litFreq, MaxLit, 0);
- optPtr->litLengthSum = ZSTD_upscaleStat(optPtr->litLengthFreq, MaxLL, 0);
- optPtr->matchLengthSum = ZSTD_upscaleStat(optPtr->matchLengthFreq, MaxML, 0);
- optPtr->offCodeSum = ZSTD_upscaleStat(optPtr->offCodeFreq, MaxOff, 0);
-}
/* ZSTD_initStats_ultra():
* make a first compression pass, just to seed stats with more accurate starting values.
@@ -1263,7 +1366,7 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
assert(ms->window.dictLimit == ms->window.lowLimit); /* no dictionary */
assert(ms->window.dictLimit - ms->nextToUpdate <= 1); /* no prefix (note: intentional overflow, defined as 2-complement) */
- ZSTD_compressBlock_opt_generic(ms, seqStore, tmpRep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict); /* generate stats into ms->opt*/
+ ZSTD_compressBlock_opt2(ms, seqStore, tmpRep, src, srcSize, ZSTD_noDict); /* generate stats into ms->opt*/
/* invalidate first scan from history */
ZSTD_resetSeqStore(seqStore);
@@ -1272,8 +1375,6 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
ms->window.lowLimit = ms->window.dictLimit;
ms->nextToUpdate = ms->window.dictLimit;
- /* re-inforce weight of collected statistics */
- ZSTD_upscaleStats(&ms->opt);
}
size_t ZSTD_compressBlock_btultra(
@@ -1281,7 +1382,7 @@ size_t ZSTD_compressBlock_btultra(
const void* src, size_t srcSize)
{
DEBUGLOG(5, "ZSTD_compressBlock_btultra (srcSize=%zu)", srcSize);
- return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict);
+ return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict);
}
size_t ZSTD_compressBlock_btultra2(
@@ -1309,35 +1410,35 @@ size_t ZSTD_compressBlock_btultra2(
ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize);
}
- return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict);
+ return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict);
}
size_t ZSTD_compressBlock_btopt_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
const void* src, size_t srcSize)
{
- return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_btultra_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
const void* src, size_t srcSize)
{
- return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_btopt_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
const void* src, size_t srcSize)
{
- return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_extDict);
+ return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_extDict);
}
size_t ZSTD_compressBlock_btultra_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
const void* src, size_t srcSize)
{
- return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_extDict);
+ return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_extDict);
}
/* note : no btultra2 variant for extDict nor dictMatchState,
diff --git a/thirdparty/zstd/compress/zstdmt_compress.c b/thirdparty/zstd/compress/zstdmt_compress.c
index 22aa3e1245..6bc14b035e 100644
--- a/thirdparty/zstd/compress/zstdmt_compress.c
+++ b/thirdparty/zstd/compress/zstdmt_compress.c
@@ -102,9 +102,8 @@ typedef struct ZSTDMT_bufferPool_s {
buffer_t bTable[1]; /* variable size */
} ZSTDMT_bufferPool;
-static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned nbWorkers, ZSTD_customMem cMem)
+static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_customMem cMem)
{
- unsigned const maxNbBuffers = 2*nbWorkers + 3;
ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_customCalloc(
sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem);
if (bufPool==NULL) return NULL;
@@ -160,9 +159,8 @@ static void ZSTDMT_setBufferSize(ZSTDMT_bufferPool* const bufPool, size_t const
}
-static ZSTDMT_bufferPool* ZSTDMT_expandBufferPool(ZSTDMT_bufferPool* srcBufPool, U32 nbWorkers)
+static ZSTDMT_bufferPool* ZSTDMT_expandBufferPool(ZSTDMT_bufferPool* srcBufPool, unsigned maxNbBuffers)
{
- unsigned const maxNbBuffers = 2*nbWorkers + 3;
if (srcBufPool==NULL) return NULL;
if (srcBufPool->totalBuffers >= maxNbBuffers) /* good enough */
return srcBufPool;
@@ -171,7 +169,7 @@ static ZSTDMT_bufferPool* ZSTDMT_expandBufferPool(ZSTDMT_bufferPool* srcBufPool,
size_t const bSize = srcBufPool->bufferSize; /* forward parameters */
ZSTDMT_bufferPool* newBufPool;
ZSTDMT_freeBufferPool(srcBufPool);
- newBufPool = ZSTDMT_createBufferPool(nbWorkers, cMem);
+ newBufPool = ZSTDMT_createBufferPool(maxNbBuffers, cMem);
if (newBufPool==NULL) return newBufPool;
ZSTDMT_setBufferSize(newBufPool, bSize);
return newBufPool;
@@ -263,6 +261,16 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
ZSTD_customFree(buf.start, bufPool->cMem);
}
+/* We need 2 output buffers per worker since each dstBuff must be flushed after it is released.
+ * The 3 additional buffers are as follows:
+ * 1 buffer for input loading
+ * 1 buffer for "next input" when submitting current one
+ * 1 buffer stuck in queue */
+#define BUF_POOL_MAX_NB_BUFFERS(nbWorkers) 2*nbWorkers + 3
+
+/* After a worker releases its rawSeqStore, it is immediately ready for reuse.
+ * So we only need one seq buffer per worker. */
+#define SEQ_POOL_MAX_NB_BUFFERS(nbWorkers) nbWorkers
/* ===== Seq Pool Wrapper ====== */
@@ -316,7 +324,7 @@ static void ZSTDMT_setNbSeq(ZSTDMT_seqPool* const seqPool, size_t const nbSeq)
static ZSTDMT_seqPool* ZSTDMT_createSeqPool(unsigned nbWorkers, ZSTD_customMem cMem)
{
- ZSTDMT_seqPool* const seqPool = ZSTDMT_createBufferPool(nbWorkers, cMem);
+ ZSTDMT_seqPool* const seqPool = ZSTDMT_createBufferPool(SEQ_POOL_MAX_NB_BUFFERS(nbWorkers), cMem);
if (seqPool == NULL) return NULL;
ZSTDMT_setNbSeq(seqPool, 0);
return seqPool;
@@ -329,7 +337,7 @@ static void ZSTDMT_freeSeqPool(ZSTDMT_seqPool* seqPool)
static ZSTDMT_seqPool* ZSTDMT_expandSeqPool(ZSTDMT_seqPool* pool, U32 nbWorkers)
{
- return ZSTDMT_expandBufferPool(pool, nbWorkers);
+ return ZSTDMT_expandBufferPool(pool, SEQ_POOL_MAX_NB_BUFFERS(nbWorkers));
}
@@ -467,7 +475,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
ZSTD_dictContentType_e dictContentType)
{
/* Adjust parameters */
- if (params.ldmParams.enableLdm) {
+ if (params.ldmParams.enableLdm == ZSTD_ps_enable) {
DEBUGLOG(4, "LDM window size = %u KB", (1U << params.cParams.windowLog) >> 10);
ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);
assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
@@ -478,7 +486,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
serialState->nextJobID = 0;
if (params.fParams.checksumFlag)
XXH64_reset(&serialState->xxhState, 0);
- if (params.ldmParams.enableLdm) {
+ if (params.ldmParams.enableLdm == ZSTD_ps_enable) {
ZSTD_customMem cMem = params.customMem;
unsigned const hashLog = params.ldmParams.hashLog;
size_t const hashSize = ((size_t)1 << hashLog) * sizeof(ldmEntry_t);
@@ -564,7 +572,7 @@ static void ZSTDMT_serialState_update(serialState_t* serialState,
/* A future job may error and skip our job */
if (serialState->nextJobID == jobID) {
/* It is now our turn, do any processing necessary */
- if (serialState->params.ldmParams.enableLdm) {
+ if (serialState->params.ldmParams.enableLdm == ZSTD_ps_enable) {
size_t error;
assert(seqStore.seq != NULL && seqStore.pos == 0 &&
seqStore.size == 0 && seqStore.capacity > 0);
@@ -594,7 +602,7 @@ static void ZSTDMT_serialState_update(serialState_t* serialState,
if (seqStore.size > 0) {
size_t const err = ZSTD_referenceExternalSequences(
jobCCtx, seqStore.seq, seqStore.size);
- assert(serialState->params.ldmParams.enableLdm);
+ assert(serialState->params.ldmParams.enableLdm == ZSTD_ps_enable);
assert(!ZSTD_isError(err));
(void)err;
}
@@ -672,7 +680,7 @@ static void ZSTDMT_compressionJob(void* jobDescription)
if (dstBuff.start==NULL) JOB_ERROR(ERROR(memory_allocation));
job->dstBuff = dstBuff; /* this value can be read in ZSTDMT_flush, when it copies the whole job */
}
- if (jobParams.ldmParams.enableLdm && rawSeqStore.seq == NULL)
+ if (jobParams.ldmParams.enableLdm == ZSTD_ps_enable && rawSeqStore.seq == NULL)
JOB_ERROR(ERROR(memory_allocation));
/* Don't compute the checksum for chunks, since we compute it externally,
@@ -680,7 +688,7 @@ static void ZSTDMT_compressionJob(void* jobDescription)
*/
if (job->jobID != 0) jobParams.fParams.checksumFlag = 0;
/* Don't run LDM for the chunks, since we handle it externally */
- jobParams.ldmParams.enableLdm = 0;
+ jobParams.ldmParams.enableLdm = ZSTD_ps_disable;
/* Correct nbWorkers to 0. */
jobParams.nbWorkers = 0;
@@ -807,6 +815,15 @@ typedef struct {
static const roundBuff_t kNullRoundBuff = {NULL, 0, 0};
#define RSYNC_LENGTH 32
+/* Don't create chunks smaller than the zstd block size.
+ * This stops us from regressing compression ratio too much,
+ * and ensures our output fits in ZSTD_compressBound().
+ *
+ * If this is shrunk < ZSTD_BLOCKSIZELOG_MIN then
+ * ZSTD_COMPRESSBOUND() will need to be updated.
+ */
+#define RSYNC_MIN_BLOCK_LOG ZSTD_BLOCKSIZELOG_MAX
+#define RSYNC_MIN_BLOCK_SIZE (1<<RSYNC_MIN_BLOCK_LOG)
typedef struct {
U64 hash;
@@ -927,7 +944,7 @@ MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers,
mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, cMem);
assert(nbJobs > 0); assert((nbJobs & (nbJobs - 1)) == 0); /* ensure nbJobs is a power of 2 */
mtctx->jobIDMask = nbJobs - 1;
- mtctx->bufPool = ZSTDMT_createBufferPool(nbWorkers, cMem);
+ mtctx->bufPool = ZSTDMT_createBufferPool(BUF_POOL_MAX_NB_BUFFERS(nbWorkers), cMem);
mtctx->cctxPool = ZSTDMT_createCCtxPool(nbWorkers, cMem);
mtctx->seqPool = ZSTDMT_createSeqPool(nbWorkers, cMem);
initError = ZSTDMT_serialState_init(&mtctx->serial);
@@ -1030,7 +1047,7 @@ static size_t ZSTDMT_resize(ZSTDMT_CCtx* mtctx, unsigned nbWorkers)
{
if (POOL_resize(mtctx->factory, nbWorkers)) return ERROR(memory_allocation);
FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbWorkers) , "");
- mtctx->bufPool = ZSTDMT_expandBufferPool(mtctx->bufPool, nbWorkers);
+ mtctx->bufPool = ZSTDMT_expandBufferPool(mtctx->bufPool, BUF_POOL_MAX_NB_BUFFERS(nbWorkers));
if (mtctx->bufPool == NULL) return ERROR(memory_allocation);
mtctx->cctxPool = ZSTDMT_expandCCtxPool(mtctx->cctxPool, nbWorkers);
if (mtctx->cctxPool == NULL) return ERROR(memory_allocation);
@@ -1135,7 +1152,7 @@ size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)
static unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params* params)
{
unsigned jobLog;
- if (params->ldmParams.enableLdm) {
+ if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
/* In Long Range Mode, the windowLog is typically oversized.
* In which case, it's preferable to determine the jobSize
* based on cycleLog instead. */
@@ -1179,7 +1196,7 @@ static size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params* params)
int const overlapRLog = 9 - ZSTDMT_overlapLog(params->overlapLog, params->cParams.strategy);
int ovLog = (overlapRLog >= 8) ? 0 : (params->cParams.windowLog - overlapRLog);
assert(0 <= overlapRLog && overlapRLog <= 8);
- if (params->ldmParams.enableLdm) {
+ if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
/* In Long Range Mode, the windowLog is typically oversized.
* In which case, it's preferable to determine the jobSize
* based on chainLog instead.
@@ -1252,6 +1269,9 @@ size_t ZSTDMT_initCStream_internal(
/* Aim for the targetsectionSize as the average job size. */
U32 const jobSizeKB = (U32)(mtctx->targetSectionSize >> 10);
U32 const rsyncBits = (assert(jobSizeKB >= 1), ZSTD_highbit32(jobSizeKB) + 10);
+ /* We refuse to create jobs < RSYNC_MIN_BLOCK_SIZE bytes, so make sure our
+ * expected job size is at least 4x larger. */
+ assert(rsyncBits >= RSYNC_MIN_BLOCK_LOG + 2);
DEBUGLOG(4, "rsyncLog = %u", rsyncBits);
mtctx->rsync.hash = 0;
mtctx->rsync.hitMask = (1ULL << rsyncBits) - 1;
@@ -1263,7 +1283,7 @@ size_t ZSTDMT_initCStream_internal(
ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(mtctx->targetSectionSize));
{
/* If ldm is enabled we need windowSize space. */
- size_t const windowSize = mtctx->params.ldmParams.enableLdm ? (1U << mtctx->params.cParams.windowLog) : 0;
+ size_t const windowSize = mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable ? (1U << mtctx->params.cParams.windowLog) : 0;
/* Two buffers of slack, plus extra space for the overlap
* This is the minimum slack that LDM works with. One extra because
* flush might waste up to targetSectionSize-1 bytes. Another extra
@@ -1538,17 +1558,21 @@ static range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)
static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
{
BYTE const* const bufferStart = (BYTE const*)buffer.start;
- BYTE const* const bufferEnd = bufferStart + buffer.capacity;
BYTE const* const rangeStart = (BYTE const*)range.start;
- BYTE const* const rangeEnd = range.size != 0 ? rangeStart + range.size : rangeStart;
if (rangeStart == NULL || bufferStart == NULL)
return 0;
- /* Empty ranges cannot overlap */
- if (bufferStart == bufferEnd || rangeStart == rangeEnd)
- return 0;
- return bufferStart < rangeEnd && rangeStart < bufferEnd;
+ {
+ BYTE const* const bufferEnd = bufferStart + buffer.capacity;
+ BYTE const* const rangeEnd = rangeStart + range.size;
+
+ /* Empty ranges cannot overlap */
+ if (bufferStart == bufferEnd || rangeStart == rangeEnd)
+ return 0;
+
+ return bufferStart < rangeEnd && rangeStart < bufferEnd;
+ }
}
static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)
@@ -1575,7 +1599,7 @@ static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)
static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, buffer_t buffer)
{
- if (mtctx->params.ldmParams.enableLdm) {
+ if (mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable) {
ZSTD_pthread_mutex_t* mutex = &mtctx->serial.ldmWindowMutex;
DEBUGLOG(5, "ZSTDMT_waitForLdmComplete");
DEBUGLOG(5, "source [0x%zx, 0x%zx)",
@@ -1678,6 +1702,11 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
if (!mtctx->params.rsyncable)
/* Rsync is disabled. */
return syncPoint;
+ if (mtctx->inBuff.filled + input.size - input.pos < RSYNC_MIN_BLOCK_SIZE)
+ /* We don't emit synchronization points if it would produce too small blocks.
+ * We don't have enough input to find a synchronization point, so don't look.
+ */
+ return syncPoint;
if (mtctx->inBuff.filled + syncPoint.toLoad < RSYNC_LENGTH)
/* Not enough to compute the hash.
* We will miss any synchronization points in this RSYNC_LENGTH byte
@@ -1688,10 +1717,28 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
*/
return syncPoint;
/* Initialize the loop variables. */
- if (mtctx->inBuff.filled >= RSYNC_LENGTH) {
- /* We have enough bytes buffered to initialize the hash.
+ if (mtctx->inBuff.filled < RSYNC_MIN_BLOCK_SIZE) {
+ /* We don't need to scan the first RSYNC_MIN_BLOCK_SIZE positions
+ * because they can't possibly be a sync point. So we can start
+ * part way through the input buffer.
+ */
+ pos = RSYNC_MIN_BLOCK_SIZE - mtctx->inBuff.filled;
+ if (pos >= RSYNC_LENGTH) {
+ prev = istart + pos - RSYNC_LENGTH;
+ hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH);
+ } else {
+ assert(mtctx->inBuff.filled >= RSYNC_LENGTH);
+ prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH;
+ hash = ZSTD_rollingHash_compute(prev + pos, (RSYNC_LENGTH - pos));
+ hash = ZSTD_rollingHash_append(hash, istart, pos);
+ }
+ } else {
+ /* We have enough bytes buffered to initialize the hash,
+ * and are have processed enough bytes to find a sync point.
* Start scanning at the beginning of the input.
*/
+ assert(mtctx->inBuff.filled >= RSYNC_MIN_BLOCK_SIZE);
+ assert(RSYNC_MIN_BLOCK_SIZE >= RSYNC_LENGTH);
pos = 0;
prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH;
hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH);
@@ -1705,16 +1752,6 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
syncPoint.flush = 1;
return syncPoint;
}
- } else {
- /* We don't have enough bytes buffered to initialize the hash, but
- * we know we have at least RSYNC_LENGTH bytes total.
- * Start scanning after the first RSYNC_LENGTH bytes less the bytes
- * already buffered.
- */
- pos = RSYNC_LENGTH - mtctx->inBuff.filled;
- prev = (BYTE const*)mtctx->inBuff.buffer.start - pos;
- hash = ZSTD_rollingHash_compute(mtctx->inBuff.buffer.start, mtctx->inBuff.filled);
- hash = ZSTD_rollingHash_append(hash, istart, pos);
}
/* Starting with the hash of the previous RSYNC_LENGTH bytes, roll
* through the input. If we hit a synchronization point, then cut the
@@ -1726,8 +1763,9 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
*/
for (; pos < syncPoint.toLoad; ++pos) {
BYTE const toRemove = pos < RSYNC_LENGTH ? prev[pos] : istart[pos - RSYNC_LENGTH];
- /* if (pos >= RSYNC_LENGTH) assert(ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash); */
+ assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash);
hash = ZSTD_rollingHash_rotate(hash, toRemove, istart[pos], primePower);
+ assert(mtctx->inBuff.filled + pos >= RSYNC_MIN_BLOCK_SIZE);
if ((hash & hitMask) == hitMask) {
syncPoint.toLoad = pos + 1;
syncPoint.flush = 1;
diff --git a/thirdparty/zstd/compress/zstdmt_compress.h b/thirdparty/zstd/compress/zstdmt_compress.h
index 2fee2ec745..271eb1ac71 100644
--- a/thirdparty/zstd/compress/zstdmt_compress.h
+++ b/thirdparty/zstd/compress/zstdmt_compress.h
@@ -65,8 +65,11 @@ size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx);
* Private use only. Init streaming operation.
* expects params to be valid.
* must receive dict, or cdict, or none, but not both.
+ * mtctx can be freshly constructed or reused from a prior compression.
+ * If mtctx is reused, memory allocations from the prior compression may not be freed,
+ * even if they are not needed for the current compression.
* @return : 0, or an error code */
-size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
+size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* mtctx,
const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType,
const ZSTD_CDict* cdict,
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
diff --git a/thirdparty/zstd/decompress/huf_decompress.c b/thirdparty/zstd/decompress/huf_decompress.c
index b93c9a003b..2027188255 100644
--- a/thirdparty/zstd/decompress/huf_decompress.c
+++ b/thirdparty/zstd/decompress/huf_decompress.c
@@ -22,6 +22,13 @@
#define HUF_STATIC_LINKING_ONLY
#include "../common/huf.h"
#include "../common/error_private.h"
+#include "../common/zstd_internal.h"
+
+/* **************************************************************
+* Constants
+****************************************************************/
+
+#define HUF_DECODER_FAST_TABLELOG 11
/* **************************************************************
* Macros
@@ -36,6 +43,30 @@
#error "Cannot force the use of the X1 and X2 decoders at the same time!"
#endif
+#if ZSTD_ENABLE_ASM_X86_64_BMI2 && DYNAMIC_BMI2
+# define HUF_ASM_X86_64_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE
+#else
+# define HUF_ASM_X86_64_BMI2_ATTRS
+#endif
+
+#ifdef __cplusplus
+# define HUF_EXTERN_C extern "C"
+#else
+# define HUF_EXTERN_C
+#endif
+#define HUF_ASM_DECL HUF_EXTERN_C
+
+#if DYNAMIC_BMI2 || (ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__))
+# define HUF_NEED_BMI2_FUNCTION 1
+#else
+# define HUF_NEED_BMI2_FUNCTION 0
+#endif
+
+#if !(ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__))
+# define HUF_NEED_DEFAULT_FUNCTION 1
+#else
+# define HUF_NEED_DEFAULT_FUNCTION 0
+#endif
/* **************************************************************
* Error Management
@@ -65,7 +96,7 @@
return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \
} \
\
- static TARGET_ATTRIBUTE("bmi2") size_t fn##_bmi2( \
+ static BMI2_TARGET_ATTRIBUTE size_t fn##_bmi2( \
void* dst, size_t dstSize, \
const void* cSrc, size_t cSrcSize, \
const HUF_DTable* DTable) \
@@ -107,13 +138,147 @@ static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
return dtd;
}
+#if ZSTD_ENABLE_ASM_X86_64_BMI2
+
+static size_t HUF_initDStream(BYTE const* ip) {
+ BYTE const lastByte = ip[7];
+ size_t const bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
+ size_t const value = MEM_readLEST(ip) | 1;
+ assert(bitsConsumed <= 8);
+ return value << bitsConsumed;
+}
+typedef struct {
+ BYTE const* ip[4];
+ BYTE* op[4];
+ U64 bits[4];
+ void const* dt;
+ BYTE const* ilimit;
+ BYTE* oend;
+ BYTE const* iend[4];
+} HUF_DecompressAsmArgs;
+
+/**
+ * Initializes args for the asm decoding loop.
+ * @returns 0 on success
+ * 1 if the fallback implementation should be used.
+ * Or an error code on failure.
+ */
+static size_t HUF_DecompressAsmArgs_init(HUF_DecompressAsmArgs* args, void* dst, size_t dstSize, void const* src, size_t srcSize, const HUF_DTable* DTable)
+{
+ void const* dt = DTable + 1;
+ U32 const dtLog = HUF_getDTableDesc(DTable).tableLog;
+
+ const BYTE* const ilimit = (const BYTE*)src + 6 + 8;
+
+ BYTE* const oend = (BYTE*)dst + dstSize;
+
+ /* The following condition is false on x32 platform,
+ * but HUF_asm is not compatible with this ABI */
+ if (!(MEM_isLittleEndian() && !MEM_32bits())) return 1;
+
+ /* strict minimum : jump table + 1 byte per stream */
+ if (srcSize < 10)
+ return ERROR(corruption_detected);
+
+ /* Must have at least 8 bytes per stream because we don't handle initializing smaller bit containers.
+ * If table log is not correct at this point, fallback to the old decoder.
+ * On small inputs we don't have enough data to trigger the fast loop, so use the old decoder.
+ */
+ if (dtLog != HUF_DECODER_FAST_TABLELOG)
+ return 1;
+
+ /* Read the jump table. */
+ {
+ const BYTE* const istart = (const BYTE*)src;
+ size_t const length1 = MEM_readLE16(istart);
+ size_t const length2 = MEM_readLE16(istart+2);
+ size_t const length3 = MEM_readLE16(istart+4);
+ size_t const length4 = srcSize - (length1 + length2 + length3 + 6);
+ args->iend[0] = istart + 6; /* jumpTable */
+ args->iend[1] = args->iend[0] + length1;
+ args->iend[2] = args->iend[1] + length2;
+ args->iend[3] = args->iend[2] + length3;
+
+ /* HUF_initDStream() requires this, and this small of an input
+ * won't benefit from the ASM loop anyways.
+ * length1 must be >= 16 so that ip[0] >= ilimit before the loop
+ * starts.
+ */
+ if (length1 < 16 || length2 < 8 || length3 < 8 || length4 < 8)
+ return 1;
+ if (length4 > srcSize) return ERROR(corruption_detected); /* overflow */
+ }
+ /* ip[] contains the position that is currently loaded into bits[]. */
+ args->ip[0] = args->iend[1] - sizeof(U64);
+ args->ip[1] = args->iend[2] - sizeof(U64);
+ args->ip[2] = args->iend[3] - sizeof(U64);
+ args->ip[3] = (BYTE const*)src + srcSize - sizeof(U64);
+
+ /* op[] contains the output pointers. */
+ args->op[0] = (BYTE*)dst;
+ args->op[1] = args->op[0] + (dstSize+3)/4;
+ args->op[2] = args->op[1] + (dstSize+3)/4;
+ args->op[3] = args->op[2] + (dstSize+3)/4;
+
+ /* No point to call the ASM loop for tiny outputs. */
+ if (args->op[3] >= oend)
+ return 1;
+
+ /* bits[] is the bit container.
+ * It is read from the MSB down to the LSB.
+ * It is shifted left as it is read, and zeros are
+ * shifted in. After the lowest valid bit a 1 is
+ * set, so that CountTrailingZeros(bits[]) can be used
+ * to count how many bits we've consumed.
+ */
+ args->bits[0] = HUF_initDStream(args->ip[0]);
+ args->bits[1] = HUF_initDStream(args->ip[1]);
+ args->bits[2] = HUF_initDStream(args->ip[2]);
+ args->bits[3] = HUF_initDStream(args->ip[3]);
+
+ /* If ip[] >= ilimit, it is guaranteed to be safe to
+ * reload bits[]. It may be beyond its section, but is
+ * guaranteed to be valid (>= istart).
+ */
+ args->ilimit = ilimit;
+
+ args->oend = oend;
+ args->dt = dt;
+
+ return 0;
+}
+
+static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressAsmArgs const* args, int stream, BYTE* segmentEnd)
+{
+ /* Validate that we haven't overwritten. */
+ if (args->op[stream] > segmentEnd)
+ return ERROR(corruption_detected);
+ /* Validate that we haven't read beyond iend[].
+ * Note that ip[] may be < iend[] because the MSB is
+ * the next bit to read, and we may have consumed 100%
+ * of the stream, so down to iend[i] - 8 is valid.
+ */
+ if (args->ip[stream] < args->iend[stream] - 8)
+ return ERROR(corruption_detected);
+
+ /* Construct the BIT_DStream_t. */
+ bit->bitContainer = MEM_readLE64(args->ip[stream]);
+ bit->bitsConsumed = ZSTD_countTrailingZeros((size_t)args->bits[stream]);
+ bit->start = (const char*)args->iend[0];
+ bit->limitPtr = bit->start + sizeof(size_t);
+ bit->ptr = (const char*)args->ip[stream];
+
+ return 0;
+}
+#endif
+
#ifndef HUF_FORCE_DECOMPRESS_X2
/*-***************************/
/* single-symbol decoding */
/*-***************************/
-typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1; /* single-symbol decoding */
+typedef struct { BYTE nbBits; BYTE byte; } HUF_DEltX1; /* single-symbol decoding */
/**
* Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at
@@ -122,14 +287,44 @@ typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1; /* single-symbol decodi
static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) {
U64 D4;
if (MEM_isLittleEndian()) {
- D4 = symbol + (nbBits << 8);
- } else {
D4 = (symbol << 8) + nbBits;
+ } else {
+ D4 = symbol + (nbBits << 8);
}
D4 *= 0x0001000100010001ULL;
return D4;
}
+/**
+ * Increase the tableLog to targetTableLog and rescales the stats.
+ * If tableLog > targetTableLog this is a no-op.
+ * @returns New tableLog
+ */
+static U32 HUF_rescaleStats(BYTE* huffWeight, U32* rankVal, U32 nbSymbols, U32 tableLog, U32 targetTableLog)
+{
+ if (tableLog > targetTableLog)
+ return tableLog;
+ if (tableLog < targetTableLog) {
+ U32 const scale = targetTableLog - tableLog;
+ U32 s;
+ /* Increase the weight for all non-zero probability symbols by scale. */
+ for (s = 0; s < nbSymbols; ++s) {
+ huffWeight[s] += (BYTE)((huffWeight[s] == 0) ? 0 : scale);
+ }
+ /* Update rankVal to reflect the new weights.
+ * All weights except 0 get moved to weight + scale.
+ * Weights [1, scale] are empty.
+ */
+ for (s = targetTableLog; s > scale; --s) {
+ rankVal[s] = rankVal[s - scale];
+ }
+ for (s = scale; s > 0; --s) {
+ rankVal[s] = 0;
+ }
+ }
+ return targetTableLog;
+}
+
typedef struct {
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1];
@@ -162,8 +357,12 @@ size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t sr
iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), bmi2);
if (HUF_isError(iSize)) return iSize;
+
/* Table header */
{ DTableDesc dtd = HUF_getDTableDesc(DTable);
+ U32 const maxTableLog = dtd.maxTableLog + 1;
+ U32 const targetTableLog = MIN(maxTableLog, HUF_DECODER_FAST_TABLELOG);
+ tableLog = HUF_rescaleStats(wksp->huffWeight, wksp->rankVal, nbSymbols, tableLog, targetTableLog);
if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */
dtd.tableType = 0;
dtd.tableLog = (BYTE)tableLog;
@@ -207,7 +406,7 @@ size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t sr
/* fill DTable
* We fill all entries of each weight in order.
- * That way length is a constant for each iteration of the outter loop.
+ * That way length is a constant for each iteration of the outer loop.
* We can switch based on the length to a different inner loop which is
* optimized for that particular case.
*/
@@ -304,11 +503,15 @@ HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, cons
BYTE* const pStart = p;
/* up to 4 symbols at a time */
- while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) {
- HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
- HUF_DECODE_SYMBOLX1_1(p, bitDPtr);
- HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
- HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
+ if ((pEnd - p) > 3) {
+ while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) {
+ HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
+ HUF_DECODE_SYMBOLX1_1(p, bitDPtr);
+ HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
+ HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
+ }
+ } else {
+ BIT_reloadDStream(bitDPtr);
}
/* [0-3] symbols remaining */
@@ -388,33 +591,36 @@ HUF_decompress4X1_usingDTable_internal_body(
U32 endSignal = 1;
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
+ if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */
CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
/* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */
- for ( ; (endSignal) & (op4 < olimit) ; ) {
- HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
- HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
- HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
- HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
- HUF_DECODE_SYMBOLX1_1(op1, &bitD1);
- HUF_DECODE_SYMBOLX1_1(op2, &bitD2);
- HUF_DECODE_SYMBOLX1_1(op3, &bitD3);
- HUF_DECODE_SYMBOLX1_1(op4, &bitD4);
- HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
- HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
- HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
- HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
- HUF_DECODE_SYMBOLX1_0(op1, &bitD1);
- HUF_DECODE_SYMBOLX1_0(op2, &bitD2);
- HUF_DECODE_SYMBOLX1_0(op3, &bitD3);
- HUF_DECODE_SYMBOLX1_0(op4, &bitD4);
- endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
- endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
- endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
- endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
+ if ((size_t)(oend - op4) >= sizeof(size_t)) {
+ for ( ; (endSignal) & (op4 < olimit) ; ) {
+ HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX1_1(op1, &bitD1);
+ HUF_DECODE_SYMBOLX1_1(op2, &bitD2);
+ HUF_DECODE_SYMBOLX1_1(op3, &bitD3);
+ HUF_DECODE_SYMBOLX1_1(op4, &bitD4);
+ HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX1_0(op1, &bitD1);
+ HUF_DECODE_SYMBOLX1_0(op2, &bitD2);
+ HUF_DECODE_SYMBOLX1_0(op3, &bitD3);
+ HUF_DECODE_SYMBOLX1_0(op4, &bitD4);
+ endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
+ }
}
/* check corruption */
@@ -440,6 +646,79 @@ HUF_decompress4X1_usingDTable_internal_body(
}
}
+#if HUF_NEED_BMI2_FUNCTION
+static BMI2_TARGET_ATTRIBUTE
+size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc,
+ size_t cSrcSize, HUF_DTable const* DTable) {
+ return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
+}
+#endif
+
+#if HUF_NEED_DEFAULT_FUNCTION
+static
+size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc,
+ size_t cSrcSize, HUF_DTable const* DTable) {
+ return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
+}
+#endif
+
+#if ZSTD_ENABLE_ASM_X86_64_BMI2
+
+HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args) ZSTDLIB_HIDDEN;
+
+static HUF_ASM_X86_64_BMI2_ATTRS
+size_t
+HUF_decompress4X1_usingDTable_internal_bmi2_asm(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ void const* dt = DTable + 1;
+ const BYTE* const iend = (const BYTE*)cSrc + 6;
+ BYTE* const oend = (BYTE*)dst + dstSize;
+ HUF_DecompressAsmArgs args;
+ {
+ size_t const ret = HUF_DecompressAsmArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
+ FORWARD_IF_ERROR(ret, "Failed to init asm args");
+ if (ret != 0)
+ return HUF_decompress4X1_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
+ }
+
+ assert(args.ip[0] >= args.ilimit);
+ HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop(&args);
+
+ /* Our loop guarantees that ip[] >= ilimit and that we haven't
+ * overwritten any op[].
+ */
+ assert(args.ip[0] >= iend);
+ assert(args.ip[1] >= iend);
+ assert(args.ip[2] >= iend);
+ assert(args.ip[3] >= iend);
+ assert(args.op[3] <= oend);
+ (void)iend;
+
+ /* finish bit streams one by one. */
+ {
+ size_t const segmentSize = (dstSize+3) / 4;
+ BYTE* segmentEnd = (BYTE*)dst;
+ int i;
+ for (i = 0; i < 4; ++i) {
+ BIT_DStream_t bit;
+ if (segmentSize <= (size_t)(oend - segmentEnd))
+ segmentEnd += segmentSize;
+ else
+ segmentEnd = oend;
+ FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
+ /* Decompress and validate that we've produced exactly the expected length. */
+ args.op[i] += HUF_decodeStreamX1(args.op[i], &bit, segmentEnd, (HUF_DEltX1 const*)dt, HUF_DECODER_FAST_TABLELOG);
+ if (args.op[i] != segmentEnd) return ERROR(corruption_detected);
+ }
+ }
+
+ /* decoded size */
+ return dstSize;
+}
+#endif /* ZSTD_ENABLE_ASM_X86_64_BMI2 */
typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize,
const void *cSrc,
@@ -447,8 +726,28 @@ typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize,
const HUF_DTable *DTable);
HUF_DGEN(HUF_decompress1X1_usingDTable_internal)
-HUF_DGEN(HUF_decompress4X1_usingDTable_internal)
+static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
+ size_t cSrcSize, HUF_DTable const* DTable, int bmi2)
+{
+#if DYNAMIC_BMI2
+ if (bmi2) {
+# if ZSTD_ENABLE_ASM_X86_64_BMI2
+ return HUF_decompress4X1_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
+# else
+ return HUF_decompress4X1_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
+# endif
+ }
+#else
+ (void)bmi2;
+#endif
+
+#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
+ return HUF_decompress4X1_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
+#else
+ return HUF_decompress4X1_usingDTable_internal_default(dst, dstSize, cSrc, cSrcSize, DTable);
+#endif
+}
size_t HUF_decompress1X1_usingDTable(
@@ -518,106 +817,226 @@ size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
/* *************************/
typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2; /* double-symbols decoding */
-typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
+typedef struct { BYTE symbol; } sortedSymbol_t;
typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1];
typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX];
+/**
+ * Constructs a HUF_DEltX2 in a U32.
+ */
+static U32 HUF_buildDEltX2U32(U32 symbol, U32 nbBits, U32 baseSeq, int level)
+{
+ U32 seq;
+ DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, sequence) == 0);
+ DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, nbBits) == 2);
+ DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, length) == 3);
+ DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U32));
+ if (MEM_isLittleEndian()) {
+ seq = level == 1 ? symbol : (baseSeq + (symbol << 8));
+ return seq + (nbBits << 16) + ((U32)level << 24);
+ } else {
+ seq = level == 1 ? (symbol << 8) : ((baseSeq << 8) + symbol);
+ return (seq << 16) + (nbBits << 8) + (U32)level;
+ }
+}
-/* HUF_fillDTableX2Level2() :
- * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
-static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 consumed,
- const U32* rankValOrigin, const int minWeight,
- const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
- U32 nbBitsBaseline, U16 baseSeq, U32* wksp, size_t wkspSize)
+/**
+ * Constructs a HUF_DEltX2.
+ */
+static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level)
{
HUF_DEltX2 DElt;
- U32* rankVal = wksp;
+ U32 const val = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
+ DEBUG_STATIC_ASSERT(sizeof(DElt) == sizeof(val));
+ ZSTD_memcpy(&DElt, &val, sizeof(val));
+ return DElt;
+}
- assert(wkspSize >= HUF_TABLELOG_MAX + 1);
- (void)wkspSize;
- /* get pre-calculated rankVal */
- ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1));
+/**
+ * Constructs 2 HUF_DEltX2s and packs them into a U64.
+ */
+static U64 HUF_buildDEltX2U64(U32 symbol, U32 nbBits, U16 baseSeq, int level)
+{
+ U32 DElt = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
+ return (U64)DElt + ((U64)DElt << 32);
+}
- /* fill skipped values */
- if (minWeight>1) {
- U32 i, skipSize = rankVal[minWeight];
- MEM_writeLE16(&(DElt.sequence), baseSeq);
- DElt.nbBits = (BYTE)(consumed);
- DElt.length = 1;
- for (i = 0; i < skipSize; i++)
- DTable[i] = DElt;
+/**
+ * Fills the DTable rank with all the symbols from [begin, end) that are each
+ * nbBits long.
+ *
+ * @param DTableRank The start of the rank in the DTable.
+ * @param begin The first symbol to fill (inclusive).
+ * @param end The last symbol to fill (exclusive).
+ * @param nbBits Each symbol is nbBits long.
+ * @param tableLog The table log.
+ * @param baseSeq If level == 1 { 0 } else { the first level symbol }
+ * @param level The level in the table. Must be 1 or 2.
+ */
+static void HUF_fillDTableX2ForWeight(
+ HUF_DEltX2* DTableRank,
+ sortedSymbol_t const* begin, sortedSymbol_t const* end,
+ U32 nbBits, U32 tableLog,
+ U16 baseSeq, int const level)
+{
+ U32 const length = 1U << ((tableLog - nbBits) & 0x1F /* quiet static-analyzer */);
+ const sortedSymbol_t* ptr;
+ assert(level >= 1 && level <= 2);
+ switch (length) {
+ case 1:
+ for (ptr = begin; ptr != end; ++ptr) {
+ HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
+ *DTableRank++ = DElt;
+ }
+ break;
+ case 2:
+ for (ptr = begin; ptr != end; ++ptr) {
+ HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
+ DTableRank[0] = DElt;
+ DTableRank[1] = DElt;
+ DTableRank += 2;
+ }
+ break;
+ case 4:
+ for (ptr = begin; ptr != end; ++ptr) {
+ U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
+ ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
+ DTableRank += 4;
+ }
+ break;
+ case 8:
+ for (ptr = begin; ptr != end; ++ptr) {
+ U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
+ ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
+ DTableRank += 8;
+ }
+ break;
+ default:
+ for (ptr = begin; ptr != end; ++ptr) {
+ U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
+ HUF_DEltX2* const DTableRankEnd = DTableRank + length;
+ for (; DTableRank != DTableRankEnd; DTableRank += 8) {
+ ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
+ }
+ }
+ break;
}
+}
- /* fill DTable */
- { U32 s; for (s=0; s<sortedListSize; s++) { /* note : sortedSymbols already skipped */
- const U32 symbol = sortedSymbols[s].symbol;
- const U32 weight = sortedSymbols[s].weight;
- const U32 nbBits = nbBitsBaseline - weight;
- const U32 length = 1 << (sizeLog-nbBits);
- const U32 start = rankVal[weight];
- U32 i = start;
- const U32 end = start + length;
-
- MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
- DElt.nbBits = (BYTE)(nbBits + consumed);
- DElt.length = 2;
- do { DTable[i++] = DElt; } while (i<end); /* since length >= 1 */
+/* HUF_fillDTableX2Level2() :
+ * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
+static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 targetLog, const U32 consumedBits,
+ const U32* rankVal, const int minWeight, const int maxWeight1,
+ const sortedSymbol_t* sortedSymbols, U32 const* rankStart,
+ U32 nbBitsBaseline, U16 baseSeq)
+{
+ /* Fill skipped values (all positions up to rankVal[minWeight]).
+ * These are positions only get a single symbol because the combined weight
+ * is too large.
+ */
+ if (minWeight>1) {
+ U32 const length = 1U << ((targetLog - consumedBits) & 0x1F /* quiet static-analyzer */);
+ U64 const DEltX2 = HUF_buildDEltX2U64(baseSeq, consumedBits, /* baseSeq */ 0, /* level */ 1);
+ int const skipSize = rankVal[minWeight];
+ assert(length > 1);
+ assert((U32)skipSize < length);
+ switch (length) {
+ case 2:
+ assert(skipSize == 1);
+ ZSTD_memcpy(DTable, &DEltX2, sizeof(DEltX2));
+ break;
+ case 4:
+ assert(skipSize <= 4);
+ ZSTD_memcpy(DTable + 0, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTable + 2, &DEltX2, sizeof(DEltX2));
+ break;
+ default:
+ {
+ int i;
+ for (i = 0; i < skipSize; i += 8) {
+ ZSTD_memcpy(DTable + i + 0, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTable + i + 2, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTable + i + 4, &DEltX2, sizeof(DEltX2));
+ ZSTD_memcpy(DTable + i + 6, &DEltX2, sizeof(DEltX2));
+ }
+ }
+ }
+ }
- rankVal[weight] += length;
- } }
+ /* Fill each of the second level symbols by weight. */
+ {
+ int w;
+ for (w = minWeight; w < maxWeight1; ++w) {
+ int const begin = rankStart[w];
+ int const end = rankStart[w+1];
+ U32 const nbBits = nbBitsBaseline - w;
+ U32 const totalBits = nbBits + consumedBits;
+ HUF_fillDTableX2ForWeight(
+ DTable + rankVal[w],
+ sortedSymbols + begin, sortedSymbols + end,
+ totalBits, targetLog,
+ baseSeq, /* level */ 2);
+ }
+ }
}
-
static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
- const sortedSymbol_t* sortedList, const U32 sortedListSize,
+ const sortedSymbol_t* sortedList,
const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
- const U32 nbBitsBaseline, U32* wksp, size_t wkspSize)
+ const U32 nbBitsBaseline)
{
- U32* rankVal = wksp;
+ U32* const rankVal = rankValOrigin[0];
const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
const U32 minBits = nbBitsBaseline - maxWeight;
- U32 s;
-
- assert(wkspSize >= HUF_TABLELOG_MAX + 1);
- wksp += HUF_TABLELOG_MAX + 1;
- wkspSize -= HUF_TABLELOG_MAX + 1;
-
- ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1));
-
- /* fill DTable */
- for (s=0; s<sortedListSize; s++) {
- const U16 symbol = sortedList[s].symbol;
- const U32 weight = sortedList[s].weight;
- const U32 nbBits = nbBitsBaseline - weight;
- const U32 start = rankVal[weight];
- const U32 length = 1 << (targetLog-nbBits);
-
- if (targetLog-nbBits >= minBits) { /* enough room for a second symbol */
- U32 sortedRank;
+ int w;
+ int const wEnd = (int)maxWeight + 1;
+
+ /* Fill DTable in order of weight. */
+ for (w = 1; w < wEnd; ++w) {
+ int const begin = (int)rankStart[w];
+ int const end = (int)rankStart[w+1];
+ U32 const nbBits = nbBitsBaseline - w;
+
+ if (targetLog-nbBits >= minBits) {
+ /* Enough room for a second symbol. */
+ int start = rankVal[w];
+ U32 const length = 1U << ((targetLog - nbBits) & 0x1F /* quiet static-analyzer */);
int minWeight = nbBits + scaleLog;
+ int s;
if (minWeight < 1) minWeight = 1;
- sortedRank = rankStart[minWeight];
- HUF_fillDTableX2Level2(DTable+start, targetLog-nbBits, nbBits,
- rankValOrigin[nbBits], minWeight,
- sortedList+sortedRank, sortedListSize-sortedRank,
- nbBitsBaseline, symbol, wksp, wkspSize);
+ /* Fill the DTable for every symbol of weight w.
+ * These symbols get at least 1 second symbol.
+ */
+ for (s = begin; s != end; ++s) {
+ HUF_fillDTableX2Level2(
+ DTable + start, targetLog, nbBits,
+ rankValOrigin[nbBits], minWeight, wEnd,
+ sortedList, rankStart,
+ nbBitsBaseline, sortedList[s].symbol);
+ start += length;
+ }
} else {
- HUF_DEltX2 DElt;
- MEM_writeLE16(&(DElt.sequence), symbol);
- DElt.nbBits = (BYTE)(nbBits);
- DElt.length = 1;
- { U32 const end = start + length;
- U32 u;
- for (u = start; u < end; u++) DTable[u] = DElt;
- } }
- rankVal[weight] += length;
+ /* Only a single symbol. */
+ HUF_fillDTableX2ForWeight(
+ DTable + rankVal[w],
+ sortedList + begin, sortedList + end,
+ nbBits, targetLog,
+ /* baseSeq */ 0, /* level */ 1);
+ }
}
}
typedef struct {
rankValCol_t rankVal[HUF_TABLELOG_MAX];
U32 rankStats[HUF_TABLELOG_MAX + 1];
- U32 rankStart0[HUF_TABLELOG_MAX + 2];
+ U32 rankStart0[HUF_TABLELOG_MAX + 3];
sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
@@ -627,9 +1046,16 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
const void* src, size_t srcSize,
void* workSpace, size_t wkspSize)
{
- U32 tableLog, maxW, sizeOfSort, nbSymbols;
+ return HUF_readDTableX2_wksp_bmi2(DTable, src, srcSize, workSpace, wkspSize, /* bmi2 */ 0);
+}
+
+size_t HUF_readDTableX2_wksp_bmi2(HUF_DTable* DTable,
+ const void* src, size_t srcSize,
+ void* workSpace, size_t wkspSize, int bmi2)
+{
+ U32 tableLog, maxW, nbSymbols;
DTableDesc dtd = HUF_getDTableDesc(DTable);
- U32 const maxTableLog = dtd.maxTableLog;
+ U32 maxTableLog = dtd.maxTableLog;
size_t iSize;
void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */
HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
@@ -647,11 +1073,12 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
/* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
- iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), /* bmi2 */ 0);
+ iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), bmi2);
if (HUF_isError(iSize)) return iSize;
/* check result */
if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
+ if (tableLog <= HUF_DECODER_FAST_TABLELOG && maxTableLog > HUF_DECODER_FAST_TABLELOG) maxTableLog = HUF_DECODER_FAST_TABLELOG;
/* find maxWeight */
for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
@@ -664,7 +1091,7 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
rankStart[w] = curr;
}
rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
- sizeOfSort = nextRankStart;
+ rankStart[maxW+1] = nextRankStart;
}
/* sort symbols by weight */
@@ -673,7 +1100,6 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
U32 const w = wksp->weightList[s];
U32 const r = rankStart[w]++;
wksp->sortedSymbol[r].symbol = (BYTE)s;
- wksp->sortedSymbol[r].weight = (BYTE)w;
}
rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
}
@@ -698,10 +1124,9 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
} } } }
HUF_fillDTableX2(dt, maxTableLog,
- wksp->sortedSymbol, sizeOfSort,
+ wksp->sortedSymbol,
wksp->rankStart0, wksp->rankVal, maxW,
- tableLog+1,
- wksp->calleeWksp, sizeof(wksp->calleeWksp) / sizeof(U32));
+ tableLog+1);
dtd.tableLog = (BYTE)maxTableLog;
dtd.tableType = 1;
@@ -714,7 +1139,7 @@ FORCE_INLINE_TEMPLATE U32
HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
{
size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
- ZSTD_memcpy(op, dt+val, 2);
+ ZSTD_memcpy(op, &dt[val].sequence, 2);
BIT_skipBits(DStream, dt[val].nbBits);
return dt[val].length;
}
@@ -723,15 +1148,17 @@ FORCE_INLINE_TEMPLATE U32
HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
{
size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
- ZSTD_memcpy(op, dt+val, 1);
- if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
- else {
+ ZSTD_memcpy(op, &dt[val].sequence, 1);
+ if (dt[val].length==1) {
+ BIT_skipBits(DStream, dt[val].nbBits);
+ } else {
if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
BIT_skipBits(DStream, dt[val].nbBits);
if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
/* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);
- } }
+ }
+ }
return 1;
}
@@ -753,19 +1180,37 @@ HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd,
BYTE* const pStart = p;
/* up to 8 symbols at a time */
- while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
- HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
- HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
- HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
- HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+ if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) {
+ if (dtLog <= 11 && MEM_64bits()) {
+ /* up to 10 symbols at a time */
+ while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-9)) {
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+ }
+ } else {
+ /* up to 8 symbols at a time */
+ while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
+ HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+ }
+ }
+ } else {
+ BIT_reloadDStream(bitDPtr);
}
/* closer to end : up to 2 symbols at a time */
- while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
- HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+ if ((size_t)(pEnd - p) >= 2) {
+ while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
- while (p <= pEnd-2)
- HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */
+ while (p <= pEnd-2)
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */
+ }
if (p < pEnd)
p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog);
@@ -799,7 +1244,6 @@ HUF_decompress1X2_usingDTable_internal_body(
/* decoded size */
return dstSize;
}
-
FORCE_INLINE_TEMPLATE size_t
HUF_decompress4X2_usingDTable_internal_body(
void* dst, size_t dstSize,
@@ -841,57 +1285,60 @@ HUF_decompress4X2_usingDTable_internal_body(
U32 const dtLog = dtd.tableLog;
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
+ if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */
CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
/* 16-32 symbols per loop (4-8 symbols per stream) */
- for ( ; (endSignal) & (op4 < olimit); ) {
+ if ((size_t)(oend - op4) >= sizeof(size_t)) {
+ for ( ; (endSignal) & (op4 < olimit); ) {
#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
- HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
- HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
- HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
- HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
- HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
- HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
- HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
- HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
- endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
- endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
- HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
- HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
- HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
- HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
- HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
- HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
- HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
- HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
- endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
- endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
+ HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
+ endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
+ HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
+ endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
#else
- HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
- HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
- HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
- HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
- HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
- HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
- HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
- HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
- HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
- HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
- HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
- HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
- HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
- HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
- HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
- HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
- endSignal = (U32)LIKELY(
- (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished)
- & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished)
- & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished)
- & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished));
+ HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
+ endSignal = (U32)LIKELY((U32)
+ (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished)
+ & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished)
+ & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished)
+ & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished));
#endif
+ }
}
/* check corruption */
@@ -915,8 +1362,99 @@ HUF_decompress4X2_usingDTable_internal_body(
}
}
+#if HUF_NEED_BMI2_FUNCTION
+static BMI2_TARGET_ATTRIBUTE
+size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc,
+ size_t cSrcSize, HUF_DTable const* DTable) {
+ return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
+}
+#endif
+
+#if HUF_NEED_DEFAULT_FUNCTION
+static
+size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc,
+ size_t cSrcSize, HUF_DTable const* DTable) {
+ return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
+}
+#endif
+
+#if ZSTD_ENABLE_ASM_X86_64_BMI2
+
+HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args) ZSTDLIB_HIDDEN;
+
+static HUF_ASM_X86_64_BMI2_ATTRS size_t
+HUF_decompress4X2_usingDTable_internal_bmi2_asm(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable) {
+ void const* dt = DTable + 1;
+ const BYTE* const iend = (const BYTE*)cSrc + 6;
+ BYTE* const oend = (BYTE*)dst + dstSize;
+ HUF_DecompressAsmArgs args;
+ {
+ size_t const ret = HUF_DecompressAsmArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
+ FORWARD_IF_ERROR(ret, "Failed to init asm args");
+ if (ret != 0)
+ return HUF_decompress4X2_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
+ }
+
+ assert(args.ip[0] >= args.ilimit);
+ HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop(&args);
+
+ /* note : op4 already verified within main loop */
+ assert(args.ip[0] >= iend);
+ assert(args.ip[1] >= iend);
+ assert(args.ip[2] >= iend);
+ assert(args.ip[3] >= iend);
+ assert(args.op[3] <= oend);
+ (void)iend;
+
+ /* finish bitStreams one by one */
+ {
+ size_t const segmentSize = (dstSize+3) / 4;
+ BYTE* segmentEnd = (BYTE*)dst;
+ int i;
+ for (i = 0; i < 4; ++i) {
+ BIT_DStream_t bit;
+ if (segmentSize <= (size_t)(oend - segmentEnd))
+ segmentEnd += segmentSize;
+ else
+ segmentEnd = oend;
+ FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
+ args.op[i] += HUF_decodeStreamX2(args.op[i], &bit, segmentEnd, (HUF_DEltX2 const*)dt, HUF_DECODER_FAST_TABLELOG);
+ if (args.op[i] != segmentEnd)
+ return ERROR(corruption_detected);
+ }
+ }
+
+ /* decoded size */
+ return dstSize;
+}
+#endif /* ZSTD_ENABLE_ASM_X86_64_BMI2 */
+
+static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
+ size_t cSrcSize, HUF_DTable const* DTable, int bmi2)
+{
+#if DYNAMIC_BMI2
+ if (bmi2) {
+# if ZSTD_ENABLE_ASM_X86_64_BMI2
+ return HUF_decompress4X2_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
+# else
+ return HUF_decompress4X2_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
+# endif
+ }
+#else
+ (void)bmi2;
+#endif
+
+#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
+ return HUF_decompress4X2_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
+#else
+ return HUF_decompress4X2_usingDTable_internal_default(dst, dstSize, cSrc, cSrcSize, DTable);
+#endif
+}
+
HUF_DGEN(HUF_decompress1X2_usingDTable_internal)
-HUF_DGEN(HUF_decompress4X2_usingDTable_internal)
size_t HUF_decompress1X2_usingDTable(
void* dst, size_t dstSize,
@@ -1025,25 +1563,25 @@ size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize,
#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
-static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
+static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] =
{
/* single, double, quad */
- {{0,0}, {1,1}, {2,2}}, /* Q==0 : impossible */
- {{0,0}, {1,1}, {2,2}}, /* Q==1 : impossible */
- {{ 38,130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */
- {{ 448,128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */
- {{ 556,128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */
- {{ 714,128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */
- {{ 883,128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */
- {{ 897,128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */
- {{ 926,128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */
- {{ 947,128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */
- {{1107,128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */
- {{1177,128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */
- {{1242,128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */
- {{1349,128}, {2644,106}, {5260,106}}, /* Q ==13 : 81-87% */
- {{1455,128}, {2422,124}, {4174,124}}, /* Q ==14 : 87-93% */
- {{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */
+ {{0,0}, {1,1}}, /* Q==0 : impossible */
+ {{0,0}, {1,1}}, /* Q==1 : impossible */
+ {{ 150,216}, { 381,119}}, /* Q == 2 : 12-18% */
+ {{ 170,205}, { 514,112}}, /* Q == 3 : 18-25% */
+ {{ 177,199}, { 539,110}}, /* Q == 4 : 25-32% */
+ {{ 197,194}, { 644,107}}, /* Q == 5 : 32-38% */
+ {{ 221,192}, { 735,107}}, /* Q == 6 : 38-44% */
+ {{ 256,189}, { 881,106}}, /* Q == 7 : 44-50% */
+ {{ 359,188}, {1167,109}}, /* Q == 8 : 50-56% */
+ {{ 582,187}, {1570,114}}, /* Q == 9 : 56-62% */
+ {{ 688,187}, {1712,122}}, /* Q ==10 : 62-69% */
+ {{ 825,186}, {1965,136}}, /* Q ==11 : 69-75% */
+ {{ 976,185}, {2131,150}}, /* Q ==12 : 75-81% */
+ {{1180,186}, {2070,175}}, /* Q ==13 : 81-87% */
+ {{1377,185}, {1731,202}}, /* Q ==14 : 87-93% */
+ {{1412,185}, {1695,202}}, /* Q ==15 : 93-99% */
};
#endif
@@ -1070,7 +1608,7 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
U32 const D256 = (U32)(dstSize >> 8);
U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
- DTime1 += DTime1 >> 3; /* advantage to algorithm using less memory, to reduce cache eviction */
+ DTime1 += DTime1 >> 5; /* small advantage to algorithm using less memory, to reduce cache eviction */
return DTime1 < DTime0;
}
#endif
diff --git a/thirdparty/zstd/decompress/huf_decompress_amd64.S b/thirdparty/zstd/decompress/huf_decompress_amd64.S
new file mode 100644
index 0000000000..49589cb611
--- /dev/null
+++ b/thirdparty/zstd/decompress/huf_decompress_amd64.S
@@ -0,0 +1,585 @@
+/*
+ * Copyright (c) Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+#include "../common/portability_macros.h"
+
+/* Stack marking
+ * ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart
+ */
+#if defined(__ELF__) && defined(__GNUC__)
+.section .note.GNU-stack,"",%progbits
+#endif
+
+#if ZSTD_ENABLE_ASM_X86_64_BMI2
+
+/* Calling convention:
+ *
+ * %rdi contains the first argument: HUF_DecompressAsmArgs*.
+ * %rbp isn't maintained (no frame pointer).
+ * %rsp contains the stack pointer that grows down.
+ * No red-zone is assumed, only addresses >= %rsp are used.
+ * All register contents are preserved.
+ *
+ * TODO: Support Windows calling convention.
+ */
+
+ZSTD_HIDE_ASM_FUNCTION(HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop)
+ZSTD_HIDE_ASM_FUNCTION(HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop)
+ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop)
+ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop)
+.global HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop
+.global HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop
+.global _HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop
+.global _HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop
+.text
+
+/* Sets up register mappings for clarity.
+ * op[], bits[], dtable & ip[0] each get their own register.
+ * ip[1,2,3] & olimit alias var[].
+ * %rax is a scratch register.
+ */
+
+#define op0 rsi
+#define op1 rbx
+#define op2 rcx
+#define op3 rdi
+
+#define ip0 r8
+#define ip1 r9
+#define ip2 r10
+#define ip3 r11
+
+#define bits0 rbp
+#define bits1 rdx
+#define bits2 r12
+#define bits3 r13
+#define dtable r14
+#define olimit r15
+
+/* var[] aliases ip[1,2,3] & olimit
+ * ip[1,2,3] are saved every iteration.
+ * olimit is only used in compute_olimit.
+ */
+#define var0 r15
+#define var1 r9
+#define var2 r10
+#define var3 r11
+
+/* 32-bit var registers */
+#define vard0 r15d
+#define vard1 r9d
+#define vard2 r10d
+#define vard3 r11d
+
+/* Calls X(N) for each stream 0, 1, 2, 3. */
+#define FOR_EACH_STREAM(X) \
+ X(0); \
+ X(1); \
+ X(2); \
+ X(3)
+
+/* Calls X(N, idx) for each stream 0, 1, 2, 3. */
+#define FOR_EACH_STREAM_WITH_INDEX(X, idx) \
+ X(0, idx); \
+ X(1, idx); \
+ X(2, idx); \
+ X(3, idx)
+
+/* Define both _HUF_* & HUF_* symbols because MacOS
+ * C symbols are prefixed with '_' & Linux symbols aren't.
+ */
+_HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop:
+HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop:
+ /* Save all registers - even if they are callee saved for simplicity. */
+ push %rax
+ push %rbx
+ push %rcx
+ push %rdx
+ push %rbp
+ push %rsi
+ push %rdi
+ push %r8
+ push %r9
+ push %r10
+ push %r11
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ /* Read HUF_DecompressAsmArgs* args from %rax */
+ movq %rdi, %rax
+ movq 0(%rax), %ip0
+ movq 8(%rax), %ip1
+ movq 16(%rax), %ip2
+ movq 24(%rax), %ip3
+ movq 32(%rax), %op0
+ movq 40(%rax), %op1
+ movq 48(%rax), %op2
+ movq 56(%rax), %op3
+ movq 64(%rax), %bits0
+ movq 72(%rax), %bits1
+ movq 80(%rax), %bits2
+ movq 88(%rax), %bits3
+ movq 96(%rax), %dtable
+ push %rax /* argument */
+ push 104(%rax) /* ilimit */
+ push 112(%rax) /* oend */
+ push %olimit /* olimit space */
+
+ subq $24, %rsp
+
+.L_4X1_compute_olimit:
+ /* Computes how many iterations we can do safely
+ * %r15, %rax may be clobbered
+ * rbx, rdx must be saved
+ * op3 & ip0 mustn't be clobbered
+ */
+ movq %rbx, 0(%rsp)
+ movq %rdx, 8(%rsp)
+
+ movq 32(%rsp), %rax /* rax = oend */
+ subq %op3, %rax /* rax = oend - op3 */
+
+ /* r15 = (oend - op3) / 5 */
+ movabsq $-3689348814741910323, %rdx
+ mulq %rdx
+ movq %rdx, %r15
+ shrq $2, %r15
+
+ movq %ip0, %rax /* rax = ip0 */
+ movq 40(%rsp), %rdx /* rdx = ilimit */
+ subq %rdx, %rax /* rax = ip0 - ilimit */
+ movq %rax, %rbx /* rbx = ip0 - ilimit */
+
+ /* rdx = (ip0 - ilimit) / 7 */
+ movabsq $2635249153387078803, %rdx
+ mulq %rdx
+ subq %rdx, %rbx
+ shrq %rbx
+ addq %rbx, %rdx
+ shrq $2, %rdx
+
+ /* r15 = min(%rdx, %r15) */
+ cmpq %rdx, %r15
+ cmova %rdx, %r15
+
+ /* r15 = r15 * 5 */
+ leaq (%r15, %r15, 4), %r15
+
+ /* olimit = op3 + r15 */
+ addq %op3, %olimit
+
+ movq 8(%rsp), %rdx
+ movq 0(%rsp), %rbx
+
+ /* If (op3 + 20 > olimit) */
+ movq %op3, %rax /* rax = op3 */
+ addq $20, %rax /* rax = op3 + 20 */
+ cmpq %rax, %olimit /* op3 + 20 > olimit */
+ jb .L_4X1_exit
+
+ /* If (ip1 < ip0) go to exit */
+ cmpq %ip0, %ip1
+ jb .L_4X1_exit
+
+ /* If (ip2 < ip1) go to exit */
+ cmpq %ip1, %ip2
+ jb .L_4X1_exit
+
+ /* If (ip3 < ip2) go to exit */
+ cmpq %ip2, %ip3
+ jb .L_4X1_exit
+
+/* Reads top 11 bits from bits[n]
+ * Loads dt[bits[n]] into var[n]
+ */
+#define GET_NEXT_DELT(n) \
+ movq $53, %var##n; \
+ shrxq %var##n, %bits##n, %var##n; \
+ movzwl (%dtable,%var##n,2),%vard##n
+
+/* var[n] must contain the DTable entry computed with GET_NEXT_DELT
+ * Moves var[n] to %rax
+ * bits[n] <<= var[n] & 63
+ * op[n][idx] = %rax >> 8
+ * %ah is a way to access bits [8, 16) of %rax
+ */
+#define DECODE_FROM_DELT(n, idx) \
+ movq %var##n, %rax; \
+ shlxq %var##n, %bits##n, %bits##n; \
+ movb %ah, idx(%op##n)
+
+/* Assumes GET_NEXT_DELT has been called.
+ * Calls DECODE_FROM_DELT then GET_NEXT_DELT
+ */
+#define DECODE_AND_GET_NEXT(n, idx) \
+ DECODE_FROM_DELT(n, idx); \
+ GET_NEXT_DELT(n) \
+
+/* // ctz & nbBytes is stored in bits[n]
+ * // nbBits is stored in %rax
+ * ctz = CTZ[bits[n]]
+ * nbBits = ctz & 7
+ * nbBytes = ctz >> 3
+ * op[n] += 5
+ * ip[n] -= nbBytes
+ * // Note: x86-64 is little-endian ==> no bswap
+ * bits[n] = MEM_readST(ip[n]) | 1
+ * bits[n] <<= nbBits
+ */
+#define RELOAD_BITS(n) \
+ bsfq %bits##n, %bits##n; \
+ movq %bits##n, %rax; \
+ andq $7, %rax; \
+ shrq $3, %bits##n; \
+ leaq 5(%op##n), %op##n; \
+ subq %bits##n, %ip##n; \
+ movq (%ip##n), %bits##n; \
+ orq $1, %bits##n; \
+ shlx %rax, %bits##n, %bits##n
+
+ /* Store clobbered variables on the stack */
+ movq %olimit, 24(%rsp)
+ movq %ip1, 0(%rsp)
+ movq %ip2, 8(%rsp)
+ movq %ip3, 16(%rsp)
+
+ /* Call GET_NEXT_DELT for each stream */
+ FOR_EACH_STREAM(GET_NEXT_DELT)
+
+ .p2align 6
+
+.L_4X1_loop_body:
+ /* Decode 5 symbols in each of the 4 streams (20 total)
+ * Must have called GET_NEXT_DELT for each stream
+ */
+ FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 0)
+ FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 1)
+ FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 2)
+ FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 3)
+ FOR_EACH_STREAM_WITH_INDEX(DECODE_FROM_DELT, 4)
+
+ /* Load ip[1,2,3] from stack (var[] aliases them)
+ * ip[] is needed for RELOAD_BITS
+ * Each will be stored back to the stack after RELOAD
+ */
+ movq 0(%rsp), %ip1
+ movq 8(%rsp), %ip2
+ movq 16(%rsp), %ip3
+
+ /* Reload each stream & fetch the next table entry
+ * to prepare for the next iteration
+ */
+ RELOAD_BITS(0)
+ GET_NEXT_DELT(0)
+
+ RELOAD_BITS(1)
+ movq %ip1, 0(%rsp)
+ GET_NEXT_DELT(1)
+
+ RELOAD_BITS(2)
+ movq %ip2, 8(%rsp)
+ GET_NEXT_DELT(2)
+
+ RELOAD_BITS(3)
+ movq %ip3, 16(%rsp)
+ GET_NEXT_DELT(3)
+
+ /* If op3 < olimit: continue the loop */
+ cmp %op3, 24(%rsp)
+ ja .L_4X1_loop_body
+
+ /* Reload ip[1,2,3] from stack */
+ movq 0(%rsp), %ip1
+ movq 8(%rsp), %ip2
+ movq 16(%rsp), %ip3
+
+ /* Re-compute olimit */
+ jmp .L_4X1_compute_olimit
+
+#undef GET_NEXT_DELT
+#undef DECODE_FROM_DELT
+#undef DECODE
+#undef RELOAD_BITS
+.L_4X1_exit:
+ addq $24, %rsp
+
+ /* Restore stack (oend & olimit) */
+ pop %rax /* olimit */
+ pop %rax /* oend */
+ pop %rax /* ilimit */
+ pop %rax /* arg */
+
+ /* Save ip / op / bits */
+ movq %ip0, 0(%rax)
+ movq %ip1, 8(%rax)
+ movq %ip2, 16(%rax)
+ movq %ip3, 24(%rax)
+ movq %op0, 32(%rax)
+ movq %op1, 40(%rax)
+ movq %op2, 48(%rax)
+ movq %op3, 56(%rax)
+ movq %bits0, 64(%rax)
+ movq %bits1, 72(%rax)
+ movq %bits2, 80(%rax)
+ movq %bits3, 88(%rax)
+
+ /* Restore registers */
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %r11
+ pop %r10
+ pop %r9
+ pop %r8
+ pop %rdi
+ pop %rsi
+ pop %rbp
+ pop %rdx
+ pop %rcx
+ pop %rbx
+ pop %rax
+ ret
+
+_HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop:
+HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop:
+ /* Save all registers - even if they are callee saved for simplicity. */
+ push %rax
+ push %rbx
+ push %rcx
+ push %rdx
+ push %rbp
+ push %rsi
+ push %rdi
+ push %r8
+ push %r9
+ push %r10
+ push %r11
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ movq %rdi, %rax
+ movq 0(%rax), %ip0
+ movq 8(%rax), %ip1
+ movq 16(%rax), %ip2
+ movq 24(%rax), %ip3
+ movq 32(%rax), %op0
+ movq 40(%rax), %op1
+ movq 48(%rax), %op2
+ movq 56(%rax), %op3
+ movq 64(%rax), %bits0
+ movq 72(%rax), %bits1
+ movq 80(%rax), %bits2
+ movq 88(%rax), %bits3
+ movq 96(%rax), %dtable
+ push %rax /* argument */
+ push %rax /* olimit */
+ push 104(%rax) /* ilimit */
+
+ movq 112(%rax), %rax
+ push %rax /* oend3 */
+
+ movq %op3, %rax
+ push %rax /* oend2 */
+
+ movq %op2, %rax
+ push %rax /* oend1 */
+
+ movq %op1, %rax
+ push %rax /* oend0 */
+
+ /* Scratch space */
+ subq $8, %rsp
+
+.L_4X2_compute_olimit:
+ /* Computes how many iterations we can do safely
+ * %r15, %rax may be clobbered
+ * rdx must be saved
+ * op[1,2,3,4] & ip0 mustn't be clobbered
+ */
+ movq %rdx, 0(%rsp)
+
+ /* We can consume up to 7 input bytes each iteration. */
+ movq %ip0, %rax /* rax = ip0 */
+ movq 40(%rsp), %rdx /* rdx = ilimit */
+ subq %rdx, %rax /* rax = ip0 - ilimit */
+ movq %rax, %r15 /* r15 = ip0 - ilimit */
+
+ /* rdx = rax / 7 */
+ movabsq $2635249153387078803, %rdx
+ mulq %rdx
+ subq %rdx, %r15
+ shrq %r15
+ addq %r15, %rdx
+ shrq $2, %rdx
+
+ /* r15 = (ip0 - ilimit) / 7 */
+ movq %rdx, %r15
+
+ movabsq $-3689348814741910323, %rdx
+ movq 8(%rsp), %rax /* rax = oend0 */
+ subq %op0, %rax /* rax = oend0 - op0 */
+ mulq %rdx
+ shrq $3, %rdx /* rdx = rax / 10 */
+
+ /* r15 = min(%rdx, %r15) */
+ cmpq %rdx, %r15
+ cmova %rdx, %r15
+
+ movabsq $-3689348814741910323, %rdx
+ movq 16(%rsp), %rax /* rax = oend1 */
+ subq %op1, %rax /* rax = oend1 - op1 */
+ mulq %rdx
+ shrq $3, %rdx /* rdx = rax / 10 */
+
+ /* r15 = min(%rdx, %r15) */
+ cmpq %rdx, %r15
+ cmova %rdx, %r15
+
+ movabsq $-3689348814741910323, %rdx
+ movq 24(%rsp), %rax /* rax = oend2 */
+ subq %op2, %rax /* rax = oend2 - op2 */
+ mulq %rdx
+ shrq $3, %rdx /* rdx = rax / 10 */
+
+ /* r15 = min(%rdx, %r15) */
+ cmpq %rdx, %r15
+ cmova %rdx, %r15
+
+ movabsq $-3689348814741910323, %rdx
+ movq 32(%rsp), %rax /* rax = oend3 */
+ subq %op3, %rax /* rax = oend3 - op3 */
+ mulq %rdx
+ shrq $3, %rdx /* rdx = rax / 10 */
+
+ /* r15 = min(%rdx, %r15) */
+ cmpq %rdx, %r15
+ cmova %rdx, %r15
+
+ /* olimit = op3 + 5 * r15 */
+ movq %r15, %rax
+ leaq (%op3, %rax, 4), %olimit
+ addq %rax, %olimit
+
+ movq 0(%rsp), %rdx
+
+ /* If (op3 + 10 > olimit) */
+ movq %op3, %rax /* rax = op3 */
+ addq $10, %rax /* rax = op3 + 10 */
+ cmpq %rax, %olimit /* op3 + 10 > olimit */
+ jb .L_4X2_exit
+
+ /* If (ip1 < ip0) go to exit */
+ cmpq %ip0, %ip1
+ jb .L_4X2_exit
+
+ /* If (ip2 < ip1) go to exit */
+ cmpq %ip1, %ip2
+ jb .L_4X2_exit
+
+ /* If (ip3 < ip2) go to exit */
+ cmpq %ip2, %ip3
+ jb .L_4X2_exit
+
+#define DECODE(n, idx) \
+ movq %bits##n, %rax; \
+ shrq $53, %rax; \
+ movzwl 0(%dtable,%rax,4),%r8d; \
+ movzbl 2(%dtable,%rax,4),%r15d; \
+ movzbl 3(%dtable,%rax,4),%eax; \
+ movw %r8w, (%op##n); \
+ shlxq %r15, %bits##n, %bits##n; \
+ addq %rax, %op##n
+
+#define RELOAD_BITS(n) \
+ bsfq %bits##n, %bits##n; \
+ movq %bits##n, %rax; \
+ shrq $3, %bits##n; \
+ andq $7, %rax; \
+ subq %bits##n, %ip##n; \
+ movq (%ip##n), %bits##n; \
+ orq $1, %bits##n; \
+ shlxq %rax, %bits##n, %bits##n
+
+
+ movq %olimit, 48(%rsp)
+
+ .p2align 6
+
+.L_4X2_loop_body:
+ /* We clobber r8, so store it on the stack */
+ movq %r8, 0(%rsp)
+
+ /* Decode 5 symbols from each of the 4 streams (20 symbols total). */
+ FOR_EACH_STREAM_WITH_INDEX(DECODE, 0)
+ FOR_EACH_STREAM_WITH_INDEX(DECODE, 1)
+ FOR_EACH_STREAM_WITH_INDEX(DECODE, 2)
+ FOR_EACH_STREAM_WITH_INDEX(DECODE, 3)
+ FOR_EACH_STREAM_WITH_INDEX(DECODE, 4)
+
+ /* Reload r8 */
+ movq 0(%rsp), %r8
+
+ FOR_EACH_STREAM(RELOAD_BITS)
+
+ cmp %op3, 48(%rsp)
+ ja .L_4X2_loop_body
+ jmp .L_4X2_compute_olimit
+
+#undef DECODE
+#undef RELOAD_BITS
+.L_4X2_exit:
+ addq $8, %rsp
+ /* Restore stack (oend & olimit) */
+ pop %rax /* oend0 */
+ pop %rax /* oend1 */
+ pop %rax /* oend2 */
+ pop %rax /* oend3 */
+ pop %rax /* ilimit */
+ pop %rax /* olimit */
+ pop %rax /* arg */
+
+ /* Save ip / op / bits */
+ movq %ip0, 0(%rax)
+ movq %ip1, 8(%rax)
+ movq %ip2, 16(%rax)
+ movq %ip3, 24(%rax)
+ movq %op0, 32(%rax)
+ movq %op1, 40(%rax)
+ movq %op2, 48(%rax)
+ movq %op3, 56(%rax)
+ movq %bits0, 64(%rax)
+ movq %bits1, 72(%rax)
+ movq %bits2, 80(%rax)
+ movq %bits3, 88(%rax)
+
+ /* Restore registers */
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %r11
+ pop %r10
+ pop %r9
+ pop %r8
+ pop %rdi
+ pop %rsi
+ pop %rbp
+ pop %rdx
+ pop %rcx
+ pop %rbx
+ pop %rax
+ ret
+
+#endif
diff --git a/thirdparty/zstd/decompress/zstd_decompress.c b/thirdparty/zstd/decompress/zstd_decompress.c
index 910bc034c0..0031e98cfb 100644
--- a/thirdparty/zstd/decompress/zstd_decompress.c
+++ b/thirdparty/zstd/decompress/zstd_decompress.c
@@ -56,7 +56,6 @@
* Dependencies
*********************************************************/
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
-#include "../common/cpu.h" /* bmi2 */
#include "../common/mem.h" /* low level memory routines */
#define FSE_STATIC_LINKING_ONLY
#include "../common/fse.h"
@@ -177,12 +176,15 @@ static const ZSTD_DDict* ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet* hashSet,
static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) {
ZSTD_DDictHashSet* ret = (ZSTD_DDictHashSet*)ZSTD_customMalloc(sizeof(ZSTD_DDictHashSet), customMem);
DEBUGLOG(4, "Allocating new hash set");
+ if (!ret)
+ return NULL;
ret->ddictPtrTable = (const ZSTD_DDict**)ZSTD_customCalloc(DDICT_HASHSET_TABLE_BASE_SIZE * sizeof(ZSTD_DDict*), customMem);
- ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE;
- ret->ddictPtrCount = 0;
- if (!ret || !ret->ddictPtrTable) {
+ if (!ret->ddictPtrTable) {
+ ZSTD_customFree(ret, customMem);
return NULL;
}
+ ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE;
+ ret->ddictPtrCount = 0;
return ret;
}
@@ -255,11 +257,15 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
dctx->inBuffSize = 0;
dctx->outBuffSize = 0;
dctx->streamStage = zdss_init;
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
dctx->legacyContext = NULL;
dctx->previousLegacyVersion = 0;
+#endif
dctx->noForwardProgress = 0;
dctx->oversizedDuration = 0;
- dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
+#if DYNAMIC_BMI2
+ dctx->bmi2 = ZSTD_cpuSupportsBmi2();
+#endif
dctx->ddictSet = NULL;
ZSTD_DCtx_resetParameters(dctx);
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
@@ -280,8 +286,7 @@ ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
return dctx;
}
-ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
-{
+static ZSTD_DCtx* ZSTD_createDCtx_internal(ZSTD_customMem customMem) {
if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
{ ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem);
@@ -292,10 +297,15 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
}
}
+ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
+{
+ return ZSTD_createDCtx_internal(customMem);
+}
+
ZSTD_DCtx* ZSTD_createDCtx(void)
{
DEBUGLOG(3, "ZSTD_createDCtx");
- return ZSTD_createDCtx_advanced(ZSTD_defaultCMem);
+ return ZSTD_createDCtx_internal(ZSTD_defaultCMem);
}
static void ZSTD_clearDict(ZSTD_DCtx* dctx)
@@ -380,6 +390,19 @@ unsigned ZSTD_isFrame(const void* buffer, size_t size)
return 0;
}
+/*! ZSTD_isSkippableFrame() :
+ * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame.
+ * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
+ */
+unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size)
+{
+ if (size < ZSTD_FRAMEIDSIZE) return 0;
+ { U32 const magic = MEM_readLE32(buffer);
+ if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
+ }
+ return 0;
+}
+
/** ZSTD_frameHeaderSize_internal() :
* srcSize must be large enough to reach header size fields.
* note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless.
@@ -466,7 +489,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
}
switch(dictIDSizeCode)
{
- default: assert(0); /* impossible */
+ default:
+ assert(0); /* impossible */
+ ZSTD_FALLTHROUGH;
case 0 : break;
case 1 : dictID = ip[pos]; pos++; break;
case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
@@ -474,7 +499,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
}
switch(fcsID)
{
- default: assert(0); /* impossible */
+ default:
+ assert(0); /* impossible */
+ ZSTD_FALLTHROUGH;
case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
@@ -503,7 +530,6 @@ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t src
return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1);
}
-
/** ZSTD_getFrameContentSize() :
* compatible with legacy mode
* @return : decompressed size of the single frame pointed to be `src` if known, otherwise
@@ -544,6 +570,37 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize)
}
}
+/*! ZSTD_readSkippableFrame() :
+ * Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer.
+ *
+ * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
+ * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
+ * in the magicVariant.
+ *
+ * Returns an error if destination buffer is not large enough, or if the frame is not skippable.
+ *
+ * @return : number of bytes written or a ZSTD error.
+ */
+ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant,
+ const void* src, size_t srcSize)
+{
+ U32 const magicNumber = MEM_readLE32(src);
+ size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
+ size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
+
+ /* check input validity */
+ RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
+ RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
+ RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
+
+ /* deliver payload */
+ if (skippableContentSize > 0 && dst != NULL)
+ ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize);
+ if (magicVariant != NULL)
+ *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START;
+ return skippableContentSize;
+}
+
/** ZSTD_findDecompressedSize() :
* compatible with legacy mode
* `srcSize` must be the exact length of some number of ZSTD compressed and/or
@@ -858,7 +915,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
switch(blockProperties.blockType)
{
case bt_compressed:
- decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1);
+ decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1, not_streaming);
break;
case bt_raw :
decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
@@ -1009,7 +1066,7 @@ static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)
switch (dctx->dictUses) {
default:
assert(0 /* Impossible */);
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case ZSTD_dont_use:
ZSTD_clearDict(dctx);
return NULL;
@@ -1031,7 +1088,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
{
#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1)
size_t regenSize;
- ZSTD_DCtx* const dctx = ZSTD_createDCtx();
+ ZSTD_DCtx* const dctx = ZSTD_createDCtx_internal(ZSTD_defaultCMem);
RETURN_ERROR_IF(dctx==NULL, memory_allocation, "NULL pointer!");
regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
ZSTD_freeDCtx(dctx);
@@ -1065,7 +1122,7 @@ static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx* dctx, size_t
return dctx->expected;
if (dctx->bType != bt_raw)
return dctx->expected;
- return MIN(MAX(inputSize, 1), dctx->expected);
+ return BOUNDED(1, inputSize, dctx->expected);
}
ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
@@ -1073,7 +1130,9 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
{
default: /* should not happen */
assert(0);
+ ZSTD_FALLTHROUGH;
case ZSTDds_getFrameHeaderSize:
+ ZSTD_FALLTHROUGH;
case ZSTDds_decodeFrameHeader:
return ZSTDnit_frameHeader;
case ZSTDds_decodeBlockHeader:
@@ -1085,6 +1144,7 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
case ZSTDds_checkChecksum:
return ZSTDnit_checksum;
case ZSTDds_decodeSkippableHeader:
+ ZSTD_FALLTHROUGH;
case ZSTDds_skipFrame:
return ZSTDnit_skippableFrame;
}
@@ -1168,7 +1228,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
{
case bt_compressed:
DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed");
- rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1);
+ rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1, is_streaming);
dctx->expected = 0; /* Streaming not supported */
break;
case bt_raw :
@@ -1493,7 +1553,7 @@ size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
ZSTD_DStream* ZSTD_createDStream(void)
{
DEBUGLOG(3, "ZSTD_createDStream");
- return ZSTD_createDStream_advanced(ZSTD_defaultCMem);
+ return ZSTD_createDCtx_internal(ZSTD_defaultCMem);
}
ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize)
@@ -1503,7 +1563,7 @@ ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize)
ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
{
- return ZSTD_createDCtx_advanced(customMem);
+ return ZSTD_createDCtx_internal(customMem);
}
size_t ZSTD_freeDStream(ZSTD_DStream* zds)
@@ -1763,7 +1823,8 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx)
size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
{
size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
- unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);
+ /* space is needed to store the litbuffer after the output of a given block without stomping the extDict of a previous run, as well as to cover both windows against wildcopy*/
+ unsigned long long const neededRBSize = windowSize + blockSize + ZSTD_BLOCKSIZE_MAX + (WILDCOPY_OVERLENGTH * 2);
unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
size_t const minRBSize = (size_t) neededSize;
RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
@@ -1897,10 +1958,12 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
DEBUGLOG(5, "stage zdss_init => transparent reset ");
zds->streamStage = zdss_loadHeader;
zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
zds->legacyVersion = 0;
+#endif
zds->hostageByte = 0;
zds->expectedOutBuffer = *output;
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case zdss_loadHeader :
DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
@@ -2038,7 +2101,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
zds->outBuffSize = neededOutBuffSize;
} } }
zds->streamStage = zdss_read;
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case zdss_read:
DEBUGLOG(5, "stage zdss_read");
@@ -2057,7 +2120,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
} }
if (ip==iend) { someMoreWork = 0; break; } /* no more input */
zds->streamStage = zdss_load;
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case zdss_load:
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.c b/thirdparty/zstd/decompress/zstd_decompress_block.c
index 349dcdc333..2e44d30d2f 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_block.c
+++ b/thirdparty/zstd/decompress/zstd_decompress_block.c
@@ -69,15 +69,56 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
}
}
+/* Allocate buffer for literals, either overlapping current dst, or split between dst and litExtraBuffer, or stored entirely within litExtraBuffer */
+static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize,
+ const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately)
+{
+ if (streaming == not_streaming && dstCapacity > ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH)
+ {
+ /* room for litbuffer to fit without read faulting */
+ dctx->litBuffer = (BYTE*)dst + ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH;
+ dctx->litBufferEnd = dctx->litBuffer + litSize;
+ dctx->litBufferLocation = ZSTD_in_dst;
+ }
+ else if (litSize > ZSTD_LITBUFFEREXTRASIZE)
+ {
+ /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */
+ if (splitImmediately) {
+ /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */
+ dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
+ dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE;
+ }
+ else {
+ /* initially this will be stored entirely in dst during huffman decoding, it will partially shifted to litExtraBuffer after */
+ dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize;
+ dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize;
+ }
+ dctx->litBufferLocation = ZSTD_split;
+ }
+ else
+ {
+ /* fits entirely within litExtraBuffer, so no split is necessary */
+ dctx->litBuffer = dctx->litExtraBuffer;
+ dctx->litBufferEnd = dctx->litBuffer + litSize;
+ dctx->litBufferLocation = ZSTD_not_in_dst;
+ }
+}
/* Hidden declaration for fullbench */
size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
- const void* src, size_t srcSize);
+ const void* src, size_t srcSize,
+ void* dst, size_t dstCapacity, const streaming_operation streaming);
/*! ZSTD_decodeLiteralsBlock() :
+ * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored
+ * in the dstBuffer. If there is room to do so, it will be stored in full in the excess dst space after where the current
+ * block will be output. Otherwise it will be stored at the end of the current dst blockspace, with a small portion being
+ * stored in dctx->litExtraBuffer to help keep it "ahead" of the current output write.
+ *
* @return : nb of bytes read from src (< srcSize )
* note : symbol not declared but exposed for fullbench */
size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
- const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
+ const void* src, size_t srcSize, /* note : srcSize < BLOCKSIZE */
+ void* dst, size_t dstCapacity, const streaming_operation streaming)
{
DEBUGLOG(5, "ZSTD_decodeLiteralsBlock");
RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, "");
@@ -90,7 +131,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
case set_repeat:
DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");
RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, "");
- /* fall-through */
+ ZSTD_FALLTHROUGH;
case set_compressed:
RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3");
@@ -99,6 +140,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
U32 const lhlCode = (istart[0] >> 2) & 3;
U32 const lhc = MEM_readLE32(istart);
size_t hufSuccess;
+ size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
switch(lhlCode)
{
case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
@@ -121,8 +163,11 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
litCSize = (lhc >> 22) + ((size_t)istart[4] << 10);
break;
}
+ RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, "");
+ RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, "");
+ ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0);
/* prefetch huffman table if cold */
if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) {
@@ -133,11 +178,11 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
if (singleStream) {
hufSuccess = HUF_decompress1X_usingDTable_bmi2(
dctx->litBuffer, litSize, istart+lhSize, litCSize,
- dctx->HUFptr, dctx->bmi2);
+ dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx));
} else {
hufSuccess = HUF_decompress4X_usingDTable_bmi2(
dctx->litBuffer, litSize, istart+lhSize, litCSize,
- dctx->HUFptr, dctx->bmi2);
+ dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx));
}
} else {
if (singleStream) {
@@ -150,15 +195,22 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
hufSuccess = HUF_decompress1X1_DCtx_wksp_bmi2(
dctx->entropy.hufTable, dctx->litBuffer, litSize,
istart+lhSize, litCSize, dctx->workspace,
- sizeof(dctx->workspace), dctx->bmi2);
+ sizeof(dctx->workspace), ZSTD_DCtx_get_bmi2(dctx));
#endif
} else {
hufSuccess = HUF_decompress4X_hufOnly_wksp_bmi2(
dctx->entropy.hufTable, dctx->litBuffer, litSize,
istart+lhSize, litCSize, dctx->workspace,
- sizeof(dctx->workspace), dctx->bmi2);
+ sizeof(dctx->workspace), ZSTD_DCtx_get_bmi2(dctx));
}
}
+ if (dctx->litBufferLocation == ZSTD_split)
+ {
+ ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
+ ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE);
+ dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
+ dctx->litBufferEnd -= WILDCOPY_OVERLENGTH;
+ }
RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, "");
@@ -166,13 +218,13 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
dctx->litSize = litSize;
dctx->litEntropy = 1;
if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;
- ZSTD_memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
return litCSize + lhSize;
}
case set_basic:
{ size_t litSize, lhSize;
U32 const lhlCode = ((istart[0]) >> 2) & 3;
+ size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
switch(lhlCode)
{
case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
@@ -189,23 +241,36 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
break;
}
+ RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
+ RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
+ ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, "");
- ZSTD_memcpy(dctx->litBuffer, istart+lhSize, litSize);
+ if (dctx->litBufferLocation == ZSTD_split)
+ {
+ ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize - ZSTD_LITBUFFEREXTRASIZE);
+ ZSTD_memcpy(dctx->litExtraBuffer, istart + lhSize + litSize - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
+ }
+ else
+ {
+ ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize);
+ }
dctx->litPtr = dctx->litBuffer;
dctx->litSize = litSize;
- ZSTD_memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
return lhSize+litSize;
}
/* direct reference into compressed stream */
dctx->litPtr = istart+lhSize;
dctx->litSize = litSize;
+ dctx->litBufferEnd = dctx->litPtr + litSize;
+ dctx->litBufferLocation = ZSTD_not_in_dst;
return lhSize+litSize;
}
case set_rle:
{ U32 const lhlCode = ((istart[0]) >> 2) & 3;
size_t litSize, lhSize;
+ size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
switch(lhlCode)
{
case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
@@ -222,8 +287,19 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4");
break;
}
+ RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
- ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
+ RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
+ ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
+ if (dctx->litBufferLocation == ZSTD_split)
+ {
+ ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize - ZSTD_LITBUFFEREXTRASIZE);
+ ZSTD_memset(dctx->litExtraBuffer, istart[lhSize], ZSTD_LITBUFFEREXTRASIZE);
+ }
+ else
+ {
+ ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize);
+ }
dctx->litPtr = dctx->litBuffer;
dctx->litSize = litSize;
return lhSize+1;
@@ -343,7 +419,7 @@ static const ZSTD_seqSymbol ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
}; /* ML_defaultDTable */
-static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U32 nbAddBits)
+static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U8 nbAddBits)
{
void* ptr = dt;
ZSTD_seqSymbol_header* const DTableH = (ZSTD_seqSymbol_header*)ptr;
@@ -355,7 +431,7 @@ static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U32 nbAddB
cell->nbBits = 0;
cell->nextState = 0;
assert(nbAddBits < 255);
- cell->nbAdditionalBits = (BYTE)nbAddBits;
+ cell->nbAdditionalBits = nbAddBits;
cell->baseValue = baseValue;
}
@@ -367,7 +443,7 @@ static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U32 nbAddB
FORCE_INLINE_TEMPLATE
void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
const short* normalizedCounter, unsigned maxSymbolValue,
- const U32* baseValue, const U32* nbAdditionalBits,
+ const U32* baseValue, const U8* nbAdditionalBits,
unsigned tableLog, void* wksp, size_t wkspSize)
{
ZSTD_seqSymbol* const tableDecode = dt+1;
@@ -478,7 +554,7 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) );
tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
assert(nbAdditionalBits[symbol] < 255);
- tableDecode[u].nbAdditionalBits = (BYTE)nbAdditionalBits[symbol];
+ tableDecode[u].nbAdditionalBits = nbAdditionalBits[symbol];
tableDecode[u].baseValue = baseValue[symbol];
}
}
@@ -487,7 +563,7 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
/* Avoids the FORCE_INLINE of the _body() function. */
static void ZSTD_buildFSETable_body_default(ZSTD_seqSymbol* dt,
const short* normalizedCounter, unsigned maxSymbolValue,
- const U32* baseValue, const U32* nbAdditionalBits,
+ const U32* baseValue, const U8* nbAdditionalBits,
unsigned tableLog, void* wksp, size_t wkspSize)
{
ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue,
@@ -495,9 +571,9 @@ static void ZSTD_buildFSETable_body_default(ZSTD_seqSymbol* dt,
}
#if DYNAMIC_BMI2
-TARGET_ATTRIBUTE("bmi2") static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* dt,
+BMI2_TARGET_ATTRIBUTE static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* dt,
const short* normalizedCounter, unsigned maxSymbolValue,
- const U32* baseValue, const U32* nbAdditionalBits,
+ const U32* baseValue, const U8* nbAdditionalBits,
unsigned tableLog, void* wksp, size_t wkspSize)
{
ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue,
@@ -507,7 +583,7 @@ TARGET_ATTRIBUTE("bmi2") static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol
void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
const short* normalizedCounter, unsigned maxSymbolValue,
- const U32* baseValue, const U32* nbAdditionalBits,
+ const U32* baseValue, const U8* nbAdditionalBits,
unsigned tableLog, void* wksp, size_t wkspSize, int bmi2)
{
#if DYNAMIC_BMI2
@@ -529,7 +605,7 @@ void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymbol** DTablePtr,
symbolEncodingType_e type, unsigned max, U32 maxLog,
const void* src, size_t srcSize,
- const U32* baseValue, const U32* nbAdditionalBits,
+ const U32* baseValue, const U8* nbAdditionalBits,
const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable,
int ddictIsCold, int nbSeq, U32* wksp, size_t wkspSize,
int bmi2)
@@ -541,7 +617,7 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb
RETURN_ERROR_IF((*(const BYTE*)src) > max, corruption_detected, "");
{ U32 const symbol = *(const BYTE*)src;
U32 const baseline = baseValue[symbol];
- U32 const nbBits = nbAdditionalBits[symbol];
+ U8 const nbBits = nbAdditionalBits[symbol];
ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits);
}
*DTablePtr = DTableSpace;
@@ -620,7 +696,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
LL_defaultDTable, dctx->fseEntropy,
dctx->ddictIsCold, nbSeq,
dctx->workspace, sizeof(dctx->workspace),
- dctx->bmi2);
+ ZSTD_DCtx_get_bmi2(dctx));
RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed");
ip += llhSize;
}
@@ -632,7 +708,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
OF_defaultDTable, dctx->fseEntropy,
dctx->ddictIsCold, nbSeq,
dctx->workspace, sizeof(dctx->workspace),
- dctx->bmi2);
+ ZSTD_DCtx_get_bmi2(dctx));
RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed");
ip += ofhSize;
}
@@ -644,7 +720,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
ML_defaultDTable, dctx->fseEntropy,
dctx->ddictIsCold, nbSeq,
dctx->workspace, sizeof(dctx->workspace),
- dctx->bmi2);
+ ZSTD_DCtx_get_bmi2(dctx));
RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed");
ip += mlhSize;
}
@@ -713,7 +789,7 @@ HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) {
* - ZSTD_overlap_src_before_dst: The src and dst may overlap and may be any distance apart.
* The src buffer must be before the dst buffer.
*/
-static void ZSTD_safecopy(BYTE* op, BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) {
+static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) {
ptrdiff_t const diff = op - ip;
BYTE* const oend = op + length;
@@ -729,6 +805,7 @@ static void ZSTD_safecopy(BYTE* op, BYTE* const oend_w, BYTE const* ip, ptrdiff_
/* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */
assert(length >= 8);
ZSTD_overlapCopy8(&op, &ip, diff);
+ length -= 8;
assert(op - ip >= 8);
assert(op <= oend);
}
@@ -743,12 +820,35 @@ static void ZSTD_safecopy(BYTE* op, BYTE* const oend_w, BYTE const* ip, ptrdiff_
assert(oend > oend_w);
ZSTD_wildcopy(op, ip, oend_w - op, ovtype);
ip += oend_w - op;
- op = oend_w;
+ op += oend_w - op;
}
/* Handle the leftovers. */
while (op < oend) *op++ = *ip++;
}
+/* ZSTD_safecopyDstBeforeSrc():
+ * This version allows overlap with dst before src, or handles the non-overlap case with dst after src
+ * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */
+static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length) {
+ ptrdiff_t const diff = op - ip;
+ BYTE* const oend = op + length;
+
+ if (length < 8 || diff > -8) {
+ /* Handle short lengths, close overlaps, and dst not before src. */
+ while (op < oend) *op++ = *ip++;
+ return;
+ }
+
+ if (op <= oend - WILDCOPY_OVERLENGTH && diff < -WILDCOPY_VECLEN) {
+ ZSTD_wildcopy(op, ip, oend - WILDCOPY_OVERLENGTH - op, ZSTD_no_overlap);
+ ip += oend - WILDCOPY_OVERLENGTH - op;
+ op += oend - WILDCOPY_OVERLENGTH - op;
+ }
+
+ /* Handle the leftovers. */
+ while (op < oend) *op++ = *ip++;
+}
+
/* ZSTD_execSequenceEnd():
* This version handles cases that are near the end of the output buffer. It requires
* more careful checks to make sure there is no overflow. By separating out these hard
@@ -759,9 +859,9 @@ static void ZSTD_safecopy(BYTE* op, BYTE* const oend_w, BYTE const* ip, ptrdiff_
*/
FORCE_NOINLINE
size_t ZSTD_execSequenceEnd(BYTE* op,
- BYTE* const oend, seq_t sequence,
- const BYTE** litPtr, const BYTE* const litLimit,
- const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
+ BYTE* const oend, seq_t sequence,
+ const BYTE** litPtr, const BYTE* const litLimit,
+ const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
{
BYTE* const oLitEnd = op + sequence.litLength;
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
@@ -784,27 +884,76 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
/* offset beyond prefix */
RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, "");
- match = dictEnd - (prefixStart-match);
+ match = dictEnd - (prefixStart - match);
if (match + sequence.matchLength <= dictEnd) {
ZSTD_memmove(oLitEnd, match, sequence.matchLength);
return sequenceLength;
}
/* span extDict & currentPrefixSegment */
{ size_t const length1 = dictEnd - match;
- ZSTD_memmove(oLitEnd, match, length1);
- op = oLitEnd + length1;
- sequence.matchLength -= length1;
- match = prefixStart;
- } }
+ ZSTD_memmove(oLitEnd, match, length1);
+ op = oLitEnd + length1;
+ sequence.matchLength -= length1;
+ match = prefixStart;
+ }
+ }
+ ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
+ return sequenceLength;
+}
+
+/* ZSTD_execSequenceEndSplitLitBuffer():
+ * This version is intended to be used during instances where the litBuffer is still split. It is kept separate to avoid performance impact for the good case.
+ */
+FORCE_NOINLINE
+size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
+ BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
+ const BYTE** litPtr, const BYTE* const litLimit,
+ const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
+{
+ BYTE* const oLitEnd = op + sequence.litLength;
+ size_t const sequenceLength = sequence.litLength + sequence.matchLength;
+ const BYTE* const iLitEnd = *litPtr + sequence.litLength;
+ const BYTE* match = oLitEnd - sequence.offset;
+
+
+ /* bounds checks : careful of address space overflow in 32-bit mode */
+ RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer");
+ RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer");
+ assert(op < op + sequenceLength);
+ assert(oLitEnd < op + sequenceLength);
+
+ /* copy literals */
+ RETURN_ERROR_IF(op > *litPtr && op < *litPtr + sequence.litLength, dstSize_tooSmall, "output should not catch up to and overwrite literal buffer");
+ ZSTD_safecopyDstBeforeSrc(op, *litPtr, sequence.litLength);
+ op = oLitEnd;
+ *litPtr = iLitEnd;
+
+ /* copy Match */
+ if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
+ /* offset beyond prefix */
+ RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, "");
+ match = dictEnd - (prefixStart - match);
+ if (match + sequence.matchLength <= dictEnd) {
+ ZSTD_memmove(oLitEnd, match, sequence.matchLength);
+ return sequenceLength;
+ }
+ /* span extDict & currentPrefixSegment */
+ { size_t const length1 = dictEnd - match;
+ ZSTD_memmove(oLitEnd, match, length1);
+ op = oLitEnd + length1;
+ sequence.matchLength -= length1;
+ match = prefixStart;
+ }
+ }
ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
return sequenceLength;
}
HINT_INLINE
size_t ZSTD_execSequence(BYTE* op,
- BYTE* const oend, seq_t sequence,
- const BYTE** litPtr, const BYTE* const litLimit,
- const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
+ BYTE* const oend, seq_t sequence,
+ const BYTE** litPtr, const BYTE* const litLimit,
+ const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
{
BYTE* const oLitEnd = op + sequence.litLength;
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
@@ -821,10 +970,102 @@ size_t ZSTD_execSequence(BYTE* op,
* - 32-bit mode and the match length overflows
*/
if (UNLIKELY(
+ iLitEnd > litLimit ||
+ oMatchEnd > oend_w ||
+ (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH)))
+ return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
+
+ /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */
+ assert(op <= oLitEnd /* No overflow */);
+ assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */);
+ assert(oMatchEnd <= oend /* No underflow */);
+ assert(iLitEnd <= litLimit /* Literal length is in bounds */);
+ assert(oLitEnd <= oend_w /* Can wildcopy literals */);
+ assert(oMatchEnd <= oend_w /* Can wildcopy matches */);
+
+ /* Copy Literals:
+ * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9.
+ * We likely don't need the full 32-byte wildcopy.
+ */
+ assert(WILDCOPY_OVERLENGTH >= 16);
+ ZSTD_copy16(op, (*litPtr));
+ if (UNLIKELY(sequence.litLength > 16)) {
+ ZSTD_wildcopy(op + 16, (*litPtr) + 16, sequence.litLength - 16, ZSTD_no_overlap);
+ }
+ op = oLitEnd;
+ *litPtr = iLitEnd; /* update for next sequence */
+
+ /* Copy Match */
+ if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
+ /* offset beyond prefix -> go into extDict */
+ RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, "");
+ match = dictEnd + (match - prefixStart);
+ if (match + sequence.matchLength <= dictEnd) {
+ ZSTD_memmove(oLitEnd, match, sequence.matchLength);
+ return sequenceLength;
+ }
+ /* span extDict & currentPrefixSegment */
+ { size_t const length1 = dictEnd - match;
+ ZSTD_memmove(oLitEnd, match, length1);
+ op = oLitEnd + length1;
+ sequence.matchLength -= length1;
+ match = prefixStart;
+ }
+ }
+ /* Match within prefix of 1 or more bytes */
+ assert(op <= oMatchEnd);
+ assert(oMatchEnd <= oend_w);
+ assert(match >= prefixStart);
+ assert(sequence.matchLength >= 1);
+
+ /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy
+ * without overlap checking.
+ */
+ if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) {
+ /* We bet on a full wildcopy for matches, since we expect matches to be
+ * longer than literals (in general). In silesia, ~10% of matches are longer
+ * than 16 bytes.
+ */
+ ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap);
+ return sequenceLength;
+ }
+ assert(sequence.offset < WILDCOPY_VECLEN);
+
+ /* Copy 8 bytes and spread the offset to be >= 8. */
+ ZSTD_overlapCopy8(&op, &match, sequence.offset);
+
+ /* If the match length is > 8 bytes, then continue with the wildcopy. */
+ if (sequence.matchLength > 8) {
+ assert(op < oMatchEnd);
+ ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8, ZSTD_overlap_src_before_dst);
+ }
+ return sequenceLength;
+}
+
+HINT_INLINE
+size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
+ BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
+ const BYTE** litPtr, const BYTE* const litLimit,
+ const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
+{
+ BYTE* const oLitEnd = op + sequence.litLength;
+ size_t const sequenceLength = sequence.litLength + sequence.matchLength;
+ BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
+ const BYTE* const iLitEnd = *litPtr + sequence.litLength;
+ const BYTE* match = oLitEnd - sequence.offset;
+
+ assert(op != NULL /* Precondition */);
+ assert(oend_w < oend /* No underflow */);
+ /* Handle edge cases in a slow path:
+ * - Read beyond end of literals
+ * - Match end is within WILDCOPY_OVERLIMIT of oend
+ * - 32-bit mode and the match length overflows
+ */
+ if (UNLIKELY(
iLitEnd > litLimit ||
oMatchEnd > oend_w ||
(MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH)))
- return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
+ return ZSTD_execSequenceEndSplitLitBuffer(op, oend, oend_w, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
/* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */
assert(op <= oLitEnd /* No overflow */);
@@ -892,6 +1133,7 @@ size_t ZSTD_execSequence(BYTE* op,
return sequenceLength;
}
+
static void
ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt)
{
@@ -905,20 +1147,10 @@ ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqS
}
FORCE_INLINE_TEMPLATE void
-ZSTD_updateFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD)
-{
- ZSTD_seqSymbol const DInfo = DStatePtr->table[DStatePtr->state];
- U32 const nbBits = DInfo.nbBits;
- size_t const lowBits = BIT_readBits(bitD, nbBits);
- DStatePtr->state = DInfo.nextState + lowBits;
-}
-
-FORCE_INLINE_TEMPLATE void
-ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, ZSTD_seqSymbol const DInfo)
+ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16 nextState, U32 nbBits)
{
- U32 const nbBits = DInfo.nbBits;
size_t const lowBits = BIT_readBits(bitD, nbBits);
- DStatePtr->state = DInfo.nextState + lowBits;
+ DStatePtr->state = nextState + lowBits;
}
/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
@@ -937,102 +1169,100 @@ FORCE_INLINE_TEMPLATE seq_t
ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
{
seq_t seq;
- ZSTD_seqSymbol const llDInfo = seqState->stateLL.table[seqState->stateLL.state];
- ZSTD_seqSymbol const mlDInfo = seqState->stateML.table[seqState->stateML.state];
- ZSTD_seqSymbol const ofDInfo = seqState->stateOffb.table[seqState->stateOffb.state];
- U32 const llBase = llDInfo.baseValue;
- U32 const mlBase = mlDInfo.baseValue;
- U32 const ofBase = ofDInfo.baseValue;
- BYTE const llBits = llDInfo.nbAdditionalBits;
- BYTE const mlBits = mlDInfo.nbAdditionalBits;
- BYTE const ofBits = ofDInfo.nbAdditionalBits;
- BYTE const totalBits = llBits+mlBits+ofBits;
-
- /* sequence */
- { size_t offset;
- if (ofBits > 1) {
- ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
- ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
- assert(ofBits <= MaxOff);
- if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) {
- U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed);
- offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
- BIT_reloadDStream(&seqState->DStream);
- if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
- assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */
- } else {
- offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
- }
- seqState->prevOffset[2] = seqState->prevOffset[1];
- seqState->prevOffset[1] = seqState->prevOffset[0];
- seqState->prevOffset[0] = offset;
- } else {
- U32 const ll0 = (llBase == 0);
- if (LIKELY((ofBits == 0))) {
- if (LIKELY(!ll0))
- offset = seqState->prevOffset[0];
- else {
- offset = seqState->prevOffset[1];
- seqState->prevOffset[1] = seqState->prevOffset[0];
- seqState->prevOffset[0] = offset;
+ const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state;
+ const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state;
+ const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state;
+ seq.matchLength = mlDInfo->baseValue;
+ seq.litLength = llDInfo->baseValue;
+ { U32 const ofBase = ofDInfo->baseValue;
+ BYTE const llBits = llDInfo->nbAdditionalBits;
+ BYTE const mlBits = mlDInfo->nbAdditionalBits;
+ BYTE const ofBits = ofDInfo->nbAdditionalBits;
+ BYTE const totalBits = llBits+mlBits+ofBits;
+
+ U16 const llNext = llDInfo->nextState;
+ U16 const mlNext = mlDInfo->nextState;
+ U16 const ofNext = ofDInfo->nextState;
+ U32 const llnbBits = llDInfo->nbBits;
+ U32 const mlnbBits = mlDInfo->nbBits;
+ U32 const ofnbBits = ofDInfo->nbBits;
+ /*
+ * As gcc has better branch and block analyzers, sometimes it is only
+ * valuable to mark likelyness for clang, it gives around 3-4% of
+ * performance.
+ */
+
+ /* sequence */
+ { size_t offset;
+ #if defined(__clang__)
+ if (LIKELY(ofBits > 1)) {
+ #else
+ if (ofBits > 1) {
+ #endif
+ ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
+ ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
+ assert(ofBits <= MaxOff);
+ if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) {
+ U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed);
+ offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
+ BIT_reloadDStream(&seqState->DStream);
+ if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
+ assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */
+ } else {
+ offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
}
+ seqState->prevOffset[2] = seqState->prevOffset[1];
+ seqState->prevOffset[1] = seqState->prevOffset[0];
+ seqState->prevOffset[0] = offset;
} else {
- offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
- { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
- temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
- if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
- seqState->prevOffset[1] = seqState->prevOffset[0];
- seqState->prevOffset[0] = offset = temp;
- } } }
- seq.offset = offset;
- }
-
- seq.matchLength = mlBase;
- if (mlBits > 0)
- seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/);
-
- if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
- BIT_reloadDStream(&seqState->DStream);
- if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
- BIT_reloadDStream(&seqState->DStream);
- /* Ensure there are enough bits to read the rest of data in 64-bit mode. */
- ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
-
- seq.litLength = llBase;
- if (llBits > 0)
- seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/);
-
- if (MEM_32bits())
- BIT_reloadDStream(&seqState->DStream);
-
- DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
- (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
-
- /* ANS state update
- * gcc-9.0.0 does 2.5% worse with ZSTD_updateFseStateWithDInfo().
- * clang-9.2.0 does 7% worse with ZSTD_updateFseState().
- * Naturally it seems like ZSTD_updateFseStateWithDInfo() should be the
- * better option, so it is the default for other compilers. But, if you
- * measure that it is worse, please put up a pull request.
- */
- {
-#if defined(__GNUC__) && !defined(__clang__)
- const int kUseUpdateFseState = 1;
-#else
- const int kUseUpdateFseState = 0;
-#endif
- if (kUseUpdateFseState) {
- ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
- ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
- ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
- } else {
- ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llDInfo); /* <= 9 bits */
- ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlDInfo); /* <= 9 bits */
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
- ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofDInfo); /* <= 8 bits */
+ U32 const ll0 = (llDInfo->baseValue == 0);
+ if (LIKELY((ofBits == 0))) {
+ offset = seqState->prevOffset[ll0];
+ seqState->prevOffset[1] = seqState->prevOffset[!ll0];
+ seqState->prevOffset[0] = offset;
+ } else {
+ offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
+ { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
+ temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
+ if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
+ seqState->prevOffset[1] = seqState->prevOffset[0];
+ seqState->prevOffset[0] = offset = temp;
+ } } }
+ seq.offset = offset;
}
+
+ #if defined(__clang__)
+ if (UNLIKELY(mlBits > 0))
+ #else
+ if (mlBits > 0)
+ #endif
+ seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/);
+
+ if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
+ BIT_reloadDStream(&seqState->DStream);
+ if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
+ BIT_reloadDStream(&seqState->DStream);
+ /* Ensure there are enough bits to read the rest of data in 64-bit mode. */
+ ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
+
+ #if defined(__clang__)
+ if (UNLIKELY(llBits > 0))
+ #else
+ if (llBits > 0)
+ #endif
+ seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/);
+
+ if (MEM_32bits())
+ BIT_reloadDStream(&seqState->DStream);
+
+ DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
+ (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
+
+ ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */
+ ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
+ ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */
}
return seq;
@@ -1085,9 +1315,11 @@ MEM_STATIC void ZSTD_assertValidSequence(
#endif
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
+
+
FORCE_INLINE_TEMPLATE size_t
DONT_VECTORIZE
-ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
+ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
const ZSTD_longOffset_e isLongOffset,
@@ -1099,11 +1331,11 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
BYTE* const oend = ostart + maxDstSize;
BYTE* op = ostart;
const BYTE* litPtr = dctx->litPtr;
- const BYTE* const litEnd = litPtr + dctx->litSize;
+ const BYTE* litBufferEnd = dctx->litBufferEnd;
const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
- DEBUGLOG(5, "ZSTD_decompressSequences_body");
+ DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer");
(void)frame;
/* Regen sequences */
@@ -1124,55 +1356,237 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
BIT_DStream_endOfBuffer < BIT_DStream_completed &&
BIT_DStream_completed < BIT_DStream_overflow);
+ /* decompress without overrunning litPtr begins */
+ {
+ seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
+ /* Align the decompression loop to 32 + 16 bytes.
+ *
+ * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression
+ * speed swings based on the alignment of the decompression loop. This
+ * performance swing is caused by parts of the decompression loop falling
+ * out of the DSB. The entire decompression loop should fit in the DSB,
+ * when it can't we get much worse performance. You can measure if you've
+ * hit the good case or the bad case with this perf command for some
+ * compressed file test.zst:
+ *
+ * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \
+ * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst
+ *
+ * If you see most cycles served out of the MITE you've hit the bad case.
+ * If you see most cycles served out of the DSB you've hit the good case.
+ * If it is pretty even then you may be in an okay case.
+ *
+ * This issue has been reproduced on the following CPUs:
+ * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9
+ * Use Instruments->Counters to get DSB/MITE cycles.
+ * I never got performance swings, but I was able to
+ * go from the good case of mostly DSB to half of the
+ * cycles served from MITE.
+ * - Coffeelake: Intel i9-9900k
+ * - Coffeelake: Intel i7-9700k
+ *
+ * I haven't been able to reproduce the instability or DSB misses on any
+ * of the following CPUS:
+ * - Haswell
+ * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH
+ * - Skylake
+ *
+ * Alignment is done for each of the three major decompression loops:
+ * - ZSTD_decompressSequences_bodySplitLitBuffer - presplit section of the literal buffer
+ * - ZSTD_decompressSequences_bodySplitLitBuffer - postsplit section of the literal buffer
+ * - ZSTD_decompressSequences_body
+ * Alignment choices are made to minimize large swings on bad cases and influence on performance
+ * from changes external to this code, rather than to overoptimize on the current commit.
+ *
+ * If you are seeing performance stability this script can help test.
+ * It tests on 4 commits in zstd where I saw performance change.
+ *
+ * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4
+ */
#if defined(__GNUC__) && defined(__x86_64__)
- /* Align the decompression loop to 32 + 16 bytes.
- *
- * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression
- * speed swings based on the alignment of the decompression loop. This
- * performance swing is caused by parts of the decompression loop falling
- * out of the DSB. The entire decompression loop should fit in the DSB,
- * when it can't we get much worse performance. You can measure if you've
- * hit the good case or the bad case with this perf command for some
- * compressed file test.zst:
- *
- * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \
- * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst
- *
- * If you see most cycles served out of the MITE you've hit the bad case.
- * If you see most cycles served out of the DSB you've hit the good case.
- * If it is pretty even then you may be in an okay case.
- *
- * This issue has been reproduced on the following CPUs:
- * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9
- * Use Instruments->Counters to get DSB/MITE cycles.
- * I never got performance swings, but I was able to
- * go from the good case of mostly DSB to half of the
- * cycles served from MITE.
- * - Coffeelake: Intel i9-9900k
- * - Coffeelake: Intel i7-9700k
- *
- * I haven't been able to reproduce the instability or DSB misses on any
- * of the following CPUS:
- * - Haswell
- * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH
- * - Skylake
- *
- * If you are seeing performance stability this script can help test.
- * It tests on 4 commits in zstd where I saw performance change.
- *
- * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4
- */
- __asm__(".p2align 6");
- __asm__("nop");
- __asm__(".p2align 5");
- __asm__("nop");
-# if __GNUC__ >= 9
- /* better for gcc-9 and gcc-10, worse for clang and gcc-8 */
- __asm__(".p2align 3");
+ __asm__(".p2align 6");
+# if __GNUC__ >= 7
+ /* good for gcc-7, gcc-9, and gcc-11 */
+ __asm__("nop");
+ __asm__(".p2align 5");
+ __asm__("nop");
+ __asm__(".p2align 4");
+# if __GNUC__ == 8 || __GNUC__ == 10
+ /* good for gcc-8 and gcc-10 */
+ __asm__("nop");
+ __asm__(".p2align 3");
+# endif
+# endif
+#endif
+
+ /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */
+ for (; litPtr + sequence.litLength <= dctx->litBufferEnd; ) {
+ size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
+#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
+#endif
+ if (UNLIKELY(ZSTD_isError(oneSeqSize)))
+ return oneSeqSize;
+ DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
+ op += oneSeqSize;
+ if (UNLIKELY(!--nbSeq))
+ break;
+ BIT_reloadDStream(&(seqState.DStream));
+ sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
+ }
+
+ /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */
+ if (nbSeq > 0) {
+ const size_t leftoverLit = dctx->litBufferEnd - litPtr;
+ if (leftoverLit)
+ {
+ RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
+ ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
+ sequence.litLength -= leftoverLit;
+ op += leftoverLit;
+ }
+ litPtr = dctx->litExtraBuffer;
+ litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
+ dctx->litBufferLocation = ZSTD_not_in_dst;
+ {
+ size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
+#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
+#endif
+ if (UNLIKELY(ZSTD_isError(oneSeqSize)))
+ return oneSeqSize;
+ DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
+ op += oneSeqSize;
+ if (--nbSeq)
+ BIT_reloadDStream(&(seqState.DStream));
+ }
+ }
+ }
+
+ if (nbSeq > 0) /* there is remaining lit from extra buffer */
+ {
+
+#if defined(__GNUC__) && defined(__x86_64__)
+ __asm__(".p2align 6");
+ __asm__("nop");
+# if __GNUC__ != 7
+ /* worse for gcc-7 better for gcc-8, gcc-9, and gcc-10 and clang */
+ __asm__(".p2align 4");
+ __asm__("nop");
+ __asm__(".p2align 3");
+# elif __GNUC__ >= 11
+ __asm__(".p2align 3");
+# else
+ __asm__(".p2align 5");
+ __asm__("nop");
+ __asm__(".p2align 3");
+# endif
+#endif
+
+ for (; ; ) {
+ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
+ size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
+#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
+#endif
+ if (UNLIKELY(ZSTD_isError(oneSeqSize)))
+ return oneSeqSize;
+ DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
+ op += oneSeqSize;
+ if (UNLIKELY(!--nbSeq))
+ break;
+ BIT_reloadDStream(&(seqState.DStream));
+ }
+ }
+
+ /* check if reached exact end */
+ DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq);
+ RETURN_ERROR_IF(nbSeq, corruption_detected, "");
+ RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, "");
+ /* save reps for next block */
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
+ }
+
+ /* last literal segment */
+ if (dctx->litBufferLocation == ZSTD_split) /* split hasn't been reached yet, first get dst then copy litExtraBuffer */
+ {
+ size_t const lastLLSize = litBufferEnd - litPtr;
+ RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
+ if (op != NULL) {
+ ZSTD_memmove(op, litPtr, lastLLSize);
+ op += lastLLSize;
+ }
+ litPtr = dctx->litExtraBuffer;
+ litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
+ dctx->litBufferLocation = ZSTD_not_in_dst;
+ }
+ { size_t const lastLLSize = litBufferEnd - litPtr;
+ RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
+ if (op != NULL) {
+ ZSTD_memcpy(op, litPtr, lastLLSize);
+ op += lastLLSize;
+ }
+ }
+
+ return op-ostart;
+}
+
+FORCE_INLINE_TEMPLATE size_t
+DONT_VECTORIZE
+ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
+ void* dst, size_t maxDstSize,
+ const void* seqStart, size_t seqSize, int nbSeq,
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
+{
+ const BYTE* ip = (const BYTE*)seqStart;
+ const BYTE* const iend = ip + seqSize;
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ostart + maxDstSize : dctx->litBuffer;
+ BYTE* op = ostart;
+ const BYTE* litPtr = dctx->litPtr;
+ const BYTE* const litEnd = litPtr + dctx->litSize;
+ const BYTE* const prefixStart = (const BYTE*)(dctx->prefixStart);
+ const BYTE* const vBase = (const BYTE*)(dctx->virtualStart);
+ const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd);
+ DEBUGLOG(5, "ZSTD_decompressSequences_body");
+ (void)frame;
+
+ /* Regen sequences */
+ if (nbSeq) {
+ seqState_t seqState;
+ dctx->fseEntropy = 1;
+ { U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
+ RETURN_ERROR_IF(
+ ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend - ip)),
+ corruption_detected, "");
+ ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
+ ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
+ ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
+ assert(dst != NULL);
+
+ ZSTD_STATIC_ASSERT(
+ BIT_DStream_unfinished < BIT_DStream_completed &&
+ BIT_DStream_endOfBuffer < BIT_DStream_completed &&
+ BIT_DStream_completed < BIT_DStream_overflow);
+
+#if defined(__GNUC__) && defined(__x86_64__)
+ __asm__(".p2align 6");
+ __asm__("nop");
+# if __GNUC__ >= 7
+ __asm__(".p2align 5");
+ __asm__("nop");
+ __asm__(".p2align 3");
# else
- __asm__(".p2align 4");
+ __asm__(".p2align 4");
+ __asm__("nop");
+ __asm__(".p2align 3");
# endif
#endif
+
for ( ; ; ) {
seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
@@ -1218,6 +1632,16 @@ ZSTD_decompressSequences_default(ZSTD_DCtx* dctx,
{
return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
+
+static size_t
+ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx,
+ void* dst, size_t maxDstSize,
+ const void* seqStart, size_t seqSize, int nbSeq,
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
+{
+ return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
+}
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
@@ -1250,10 +1674,10 @@ ZSTD_decompressSequencesLong_body(
const BYTE* ip = (const BYTE*)seqStart;
const BYTE* const iend = ip + seqSize;
BYTE* const ostart = (BYTE*)dst;
- BYTE* const oend = ostart + maxDstSize;
+ BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ostart + maxDstSize;
BYTE* op = ostart;
const BYTE* litPtr = dctx->litPtr;
- const BYTE* const litEnd = litPtr + dctx->litSize;
+ const BYTE* litBufferEnd = dctx->litBufferEnd;
const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
@@ -1289,32 +1713,94 @@ ZSTD_decompressSequencesLong_body(
}
RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, "");
- /* decode and decompress */
- for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb<nbSeq) ; seqNb++) {
- seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
- size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);
+ /* decompress without stomping litBuffer */
+ for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb < nbSeq); seqNb++) {
+ seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
+ size_t oneSeqSize;
+
+ if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd)
+ {
+ /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
+ const size_t leftoverLit = dctx->litBufferEnd - litPtr;
+ if (leftoverLit)
+ {
+ RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
+ ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
+ sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit;
+ op += leftoverLit;
+ }
+ litPtr = dctx->litExtraBuffer;
+ litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
+ dctx->litBufferLocation = ZSTD_not_in_dst;
+ oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
- assert(!ZSTD_isError(oneSeqSize));
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
#endif
- if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
- prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
- sequences[seqNb & STORED_SEQS_MASK] = sequence;
- op += oneSeqSize;
+ prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
+ sequences[seqNb & STORED_SEQS_MASK] = sequence;
+ op += oneSeqSize;
+ }
+ else
+ {
+ /* lit buffer is either wholly contained in first or second split, or not split at all*/
+ oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
+ ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) :
+ ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
+#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
+#endif
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
+
+ prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
+ sequences[seqNb & STORED_SEQS_MASK] = sequence;
+ op += oneSeqSize;
+ }
}
RETURN_ERROR_IF(seqNb<nbSeq, corruption_detected, "");
/* finish queue */
seqNb -= seqAdvance;
for ( ; seqNb<nbSeq ; seqNb++) {
- size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[seqNb&STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);
+ seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
+ if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd)
+ {
+ const size_t leftoverLit = dctx->litBufferEnd - litPtr;
+ if (leftoverLit)
+ {
+ RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
+ ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
+ sequence->litLength -= leftoverLit;
+ op += leftoverLit;
+ }
+ litPtr = dctx->litExtraBuffer;
+ litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
+ dctx->litBufferLocation = ZSTD_not_in_dst;
+ {
+ size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
- assert(!ZSTD_isError(oneSeqSize));
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
#endif
- if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
- op += oneSeqSize;
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
+ op += oneSeqSize;
+ }
+ }
+ else
+ {
+ size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
+ ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence->litLength - WILDCOPY_OVERLENGTH, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) :
+ ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
+#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
+#endif
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
+ op += oneSeqSize;
+ }
}
/* save reps for next block */
@@ -1322,10 +1808,21 @@ ZSTD_decompressSequencesLong_body(
}
/* last literal segment */
- { size_t const lastLLSize = litEnd - litPtr;
+ if (dctx->litBufferLocation == ZSTD_split) /* first deplete literal buffer in dst, then copy litExtraBuffer */
+ {
+ size_t const lastLLSize = litBufferEnd - litPtr;
+ RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
+ if (op != NULL) {
+ ZSTD_memmove(op, litPtr, lastLLSize);
+ op += lastLLSize;
+ }
+ litPtr = dctx->litExtraBuffer;
+ litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
+ }
+ { size_t const lastLLSize = litBufferEnd - litPtr;
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
if (op != NULL) {
- ZSTD_memcpy(op, litPtr, lastLLSize);
+ ZSTD_memmove(op, litPtr, lastLLSize);
op += lastLLSize;
}
}
@@ -1349,7 +1846,7 @@ ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,
#if DYNAMIC_BMI2
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
-static TARGET_ATTRIBUTE("bmi2") size_t
+static BMI2_TARGET_ATTRIBUTE size_t
DONT_VECTORIZE
ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
@@ -1359,10 +1856,20 @@ ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
{
return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
+static BMI2_TARGET_ATTRIBUTE size_t
+DONT_VECTORIZE
+ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx,
+ void* dst, size_t maxDstSize,
+ const void* seqStart, size_t seqSize, int nbSeq,
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
+{
+ return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
+}
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
-static TARGET_ATTRIBUTE("bmi2") size_t
+static BMI2_TARGET_ATTRIBUTE size_t
ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
@@ -1391,11 +1898,25 @@ ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
{
DEBUGLOG(5, "ZSTD_decompressSequences");
#if DYNAMIC_BMI2
- if (dctx->bmi2) {
+ if (ZSTD_DCtx_get_bmi2(dctx)) {
return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif
- return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
+ return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
+}
+static size_t
+ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
+ const void* seqStart, size_t seqSize, int nbSeq,
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
+{
+ DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer");
+#if DYNAMIC_BMI2
+ if (ZSTD_DCtx_get_bmi2(dctx)) {
+ return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
+ }
+#endif
+ return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
@@ -1415,7 +1936,7 @@ ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
{
DEBUGLOG(5, "ZSTD_decompressSequencesLong");
#if DYNAMIC_BMI2
- if (dctx->bmi2) {
+ if (ZSTD_DCtx_get_bmi2(dctx)) {
return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif
@@ -1456,7 +1977,7 @@ ZSTD_getLongOffsetsShare(const ZSTD_seqSymbol* offTable)
size_t
ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity,
- const void* src, size_t srcSize, const int frame)
+ const void* src, size_t srcSize, const int frame, const streaming_operation streaming)
{ /* blockType == blockCompressed */
const BYTE* ip = (const BYTE*)src;
/* isLongOffset must be true if there are long offsets.
@@ -1471,7 +1992,7 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
RETURN_ERROR_IF(srcSize >= ZSTD_BLOCKSIZE_MAX, srcSize_wrong, "");
/* Decode literals section */
- { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
+ { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming);
DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : %u", (U32)litCSize);
if (ZSTD_isError(litCSize)) return litCSize;
ip += litCSize;
@@ -1519,7 +2040,10 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
/* else */
- return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
+ if (dctx->litBufferLocation == ZSTD_split)
+ return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
+ else
+ return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
#endif
}
}
@@ -1542,7 +2066,7 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
{
size_t dSize;
ZSTD_checkContinuity(dctx, dst, dstCapacity);
- dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0);
+ dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0, not_streaming);
dctx->previousDstEnd = (char*)dst + dSize;
return dSize;
}
diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.h b/thirdparty/zstd/decompress/zstd_decompress_block.h
index 049a0cd84c..c61a9d0c4b 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_block.h
+++ b/thirdparty/zstd/decompress/zstd_decompress_block.h
@@ -33,6 +33,12 @@
*/
+ /* Streaming state is used to inform allocation of the literal buffer */
+typedef enum {
+ not_streaming = 0,
+ is_streaming = 1
+} streaming_operation;
+
/* ZSTD_decompressBlock_internal() :
* decompress block, starting at `src`,
* into destination buffer `dst`.
@@ -41,7 +47,7 @@
*/
size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity,
- const void* src, size_t srcSize, const int frame);
+ const void* src, size_t srcSize, const int frame, const streaming_operation streaming);
/* ZSTD_buildFSETable() :
* generate FSE decoding table for one symbol (ll, ml or off)
@@ -54,7 +60,7 @@ size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
*/
void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
const short* normalizedCounter, unsigned maxSymbolValue,
- const U32* baseValue, const U32* nbAdditionalBits,
+ const U32* baseValue, const U8* nbAdditionalBits,
unsigned tableLog, void* wksp, size_t wkspSize,
int bmi2);
diff --git a/thirdparty/zstd/decompress/zstd_decompress_internal.h b/thirdparty/zstd/decompress/zstd_decompress_internal.h
index ebda0c9031..2b5a53850a 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_internal.h
+++ b/thirdparty/zstd/decompress/zstd_decompress_internal.h
@@ -20,7 +20,7 @@
* Dependencies
*********************************************************/
#include "../common/mem.h" /* BYTE, U16, U32 */
-#include "../common/zstd_internal.h" /* ZSTD_seqSymbol */
+#include "../common/zstd_internal.h" /* constants : MaxLL, MaxML, MaxOff, LLFSELog, etc. */
@@ -40,7 +40,7 @@ static UNUSED_ATTR const U32 OF_base[MaxOff+1] = {
0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
-static UNUSED_ATTR const U32 OF_bits[MaxOff+1] = {
+static UNUSED_ATTR const U8 OF_bits[MaxOff+1] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
@@ -106,6 +106,22 @@ typedef struct {
size_t ddictPtrCount;
} ZSTD_DDictHashSet;
+#ifndef ZSTD_DECODER_INTERNAL_BUFFER
+# define ZSTD_DECODER_INTERNAL_BUFFER (1 << 16)
+#endif
+
+#define ZSTD_LBMIN 64
+#define ZSTD_LBMAX (128 << 10)
+
+/* extra buffer, compensates when dst is not large enough to store litBuffer */
+#define ZSTD_LITBUFFEREXTRASIZE BOUNDED(ZSTD_LBMIN, ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX)
+
+typedef enum {
+ ZSTD_not_in_dst = 0, /* Stored entirely within litExtraBuffer */
+ ZSTD_in_dst = 1, /* Stored entirely within dst (in memory after current output write) */
+ ZSTD_split = 2 /* Split between litExtraBuffer and dst */
+} ZSTD_litLocation_e;
+
struct ZSTD_DCtx_s
{
const ZSTD_seqSymbol* LLTptr;
@@ -136,7 +152,9 @@ struct ZSTD_DCtx_s
size_t litSize;
size_t rleSize;
size_t staticSize;
+#if DYNAMIC_BMI2 != 0
int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */
+#endif
/* dictionary */
ZSTD_DDict* ddictLocal;
@@ -158,16 +176,21 @@ struct ZSTD_DCtx_s
size_t outStart;
size_t outEnd;
size_t lhSize;
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
void* legacyContext;
U32 previousLegacyVersion;
U32 legacyVersion;
+#endif
U32 hostageByte;
int noForwardProgress;
ZSTD_bufferMode_e outBufferMode;
ZSTD_outBuffer expectedOutBuffer;
/* workspace */
- BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
+ BYTE* litBuffer;
+ const BYTE* litBufferEnd;
+ ZSTD_litLocation_e litBufferLocation;
+ BYTE litExtraBuffer[ZSTD_LITBUFFEREXTRASIZE + WILDCOPY_OVERLENGTH]; /* literal buffer can be split between storage within dst and within this scratch buffer */
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
size_t oversizedDuration;
@@ -183,6 +206,14 @@ struct ZSTD_DCtx_s
#endif
}; /* typedef'd to ZSTD_DCtx within "zstd.h" */
+MEM_STATIC int ZSTD_DCtx_get_bmi2(const struct ZSTD_DCtx_s *dctx) {
+#if DYNAMIC_BMI2 != 0
+ return dctx->bmi2;
+#else
+ (void)dctx;
+ return 0;
+#endif
+}
/*-*******************************************************
* Shared internal functions
diff --git a/thirdparty/zstd/zstd.h b/thirdparty/zstd/zstd.h
index 4651e6c4dc..a88ae7bf8e 100644
--- a/thirdparty/zstd/zstd.h
+++ b/thirdparty/zstd/zstd.h
@@ -20,19 +20,21 @@ extern "C" {
/* ===== ZSTDLIB_API : control library symbols visibility ===== */
-#ifndef ZSTDLIB_VISIBILITY
-# if defined(__GNUC__) && (__GNUC__ >= 4)
-# define ZSTDLIB_VISIBILITY __attribute__ ((visibility ("default")))
+#ifndef ZSTDLIB_VISIBLE
+# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
+# define ZSTDLIB_VISIBLE __attribute__ ((visibility ("default")))
+# define ZSTDLIB_HIDDEN __attribute__ ((visibility ("hidden")))
# else
-# define ZSTDLIB_VISIBILITY
+# define ZSTDLIB_VISIBLE
+# define ZSTDLIB_HIDDEN
# endif
#endif
#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
-# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBILITY
+# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBLE
#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
-# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
+# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
#else
-# define ZSTDLIB_API ZSTDLIB_VISIBILITY
+# define ZSTDLIB_API ZSTDLIB_VISIBLE
#endif
@@ -72,7 +74,7 @@ extern "C" {
/*------ Version ------*/
#define ZSTD_VERSION_MAJOR 1
#define ZSTD_VERSION_MINOR 5
-#define ZSTD_VERSION_RELEASE 0
+#define ZSTD_VERSION_RELEASE 2
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
/*! ZSTD_versionNumber() :
@@ -247,7 +249,7 @@ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx,
*
* It's possible to reset all parameters to "default" using ZSTD_CCtx_reset().
*
- * This API supercedes all other "advanced" API entry points in the experimental section.
+ * This API supersedes all other "advanced" API entry points in the experimental section.
* In the future, we expect to remove from experimental API entry points which are redundant with this API.
*/
@@ -417,7 +419,7 @@ typedef enum {
* ZSTD_c_stableOutBuffer
* ZSTD_c_blockDelimiters
* ZSTD_c_validateSequences
- * ZSTD_c_splitBlocks
+ * ZSTD_c_useBlockSplitter
* ZSTD_c_useRowMatchFinder
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
* note : never ever use experimentalParam? names directly;
@@ -932,7 +934,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
* Advanced dictionary and prefix API (Requires v1.4.0+)
*
* This API allows dictionaries to be used with ZSTD_compress2(),
- * ZSTD_compressStream2(), and ZSTD_decompress(). Dictionaries are sticky, and
+ * ZSTD_compressStream2(), and ZSTD_decompressDCtx(). Dictionaries are sticky, and
* only reset with the context is reset with ZSTD_reset_parameters or
* ZSTD_reset_session_and_parameters. Prefixes are single-use.
******************************************************************************/
@@ -1073,25 +1075,36 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY)
#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY
+/* This can be overridden externally to hide static symbols. */
+#ifndef ZSTDLIB_STATIC_API
+# if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
+# define ZSTDLIB_STATIC_API __declspec(dllexport) ZSTDLIB_VISIBLE
+# elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
+# define ZSTDLIB_STATIC_API __declspec(dllimport) ZSTDLIB_VISIBLE
+# else
+# define ZSTDLIB_STATIC_API ZSTDLIB_VISIBLE
+# endif
+#endif
+
/* Deprecation warnings :
* Should these warnings be a problem, it is generally possible to disable them,
* typically with -Wno-deprecated-declarations for gcc or _CRT_SECURE_NO_WARNINGS in Visual.
* Otherwise, it's also possible to define ZSTD_DISABLE_DEPRECATE_WARNINGS.
*/
#ifdef ZSTD_DISABLE_DEPRECATE_WARNINGS
-# define ZSTD_DEPRECATED(message) ZSTDLIB_API /* disable deprecation warnings */
+# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API /* disable deprecation warnings */
#else
# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
-# define ZSTD_DEPRECATED(message) [[deprecated(message)]] ZSTDLIB_API
+# define ZSTD_DEPRECATED(message) [[deprecated(message)]] ZSTDLIB_STATIC_API
# elif (defined(GNUC) && (GNUC > 4 || (GNUC == 4 && GNUC_MINOR >= 5))) || defined(__clang__)
-# define ZSTD_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated(message)))
+# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API __attribute__((deprecated(message)))
# elif defined(__GNUC__) && (__GNUC__ >= 3)
-# define ZSTD_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated))
+# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API __attribute__((deprecated))
# elif defined(_MSC_VER)
-# define ZSTD_DEPRECATED(message) ZSTDLIB_API __declspec(deprecated(message))
+# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API __declspec(deprecated(message))
# else
# pragma message("WARNING: You need to implement ZSTD_DEPRECATED for this compiler")
-# define ZSTD_DEPRECATED(message) ZSTDLIB_API
+# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API
# endif
#endif /* ZSTD_DISABLE_DEPRECATE_WARNINGS */
@@ -1157,9 +1170,6 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
#define ZSTD_SRCSIZEHINT_MIN 0
#define ZSTD_SRCSIZEHINT_MAX INT_MAX
-/* internal */
-#define ZSTD_HASHLOG3_MAX 17
-
/* --- Advanced types --- */
@@ -1302,10 +1312,14 @@ typedef enum {
} ZSTD_literalCompressionMode_e;
typedef enum {
- ZSTD_urm_auto = 0, /* Automatically determine whether or not we use row matchfinder */
- ZSTD_urm_disableRowMatchFinder = 1, /* Never use row matchfinder */
- ZSTD_urm_enableRowMatchFinder = 2 /* Always use row matchfinder when applicable */
-} ZSTD_useRowMatchFinderMode_e;
+ /* Note: This enum controls features which are conditionally beneficial. Zstd typically will make a final
+ * decision on whether or not to enable the feature (ZSTD_ps_auto), but setting the switch to ZSTD_ps_enable
+ * or ZSTD_ps_disable allow for a force enable/disable the feature.
+ */
+ ZSTD_ps_auto = 0, /* Let the library automatically determine whether the feature shall be enabled */
+ ZSTD_ps_enable = 1, /* Force-enable the feature */
+ ZSTD_ps_disable = 2 /* Do not use the feature */
+} ZSTD_paramSwitch_e;
/***************************************
* Frame size functions
@@ -1332,7 +1346,7 @@ typedef enum {
* note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to
* read each contained frame header. This is fast as most of the data is skipped,
* however it does mean that all frame data must be present and valid. */
-ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
+ZSTDLIB_STATIC_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
/*! ZSTD_decompressBound() :
* `src` should point to the start of a series of ZSTD encoded and/or skippable frames
@@ -1347,13 +1361,13 @@ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t
* note 3 : when the decompressed size field isn't available, the upper-bound for that frame is calculated by:
* upper-bound = # blocks * min(128 KB, Window_Size)
*/
-ZSTDLIB_API unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize);
+ZSTDLIB_STATIC_API unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize);
/*! ZSTD_frameHeaderSize() :
* srcSize must be >= ZSTD_FRAMEHEADERSIZE_PREFIX.
* @return : size of the Frame Header,
* or an error code (if srcSize is too small) */
-ZSTDLIB_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize);
+ZSTDLIB_STATIC_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize);
typedef enum {
ZSTD_sf_noBlockDelimiters = 0, /* Representation of ZSTD_Sequence has no block delimiters, sequences only */
@@ -1376,7 +1390,7 @@ typedef enum {
* @return : number of sequences generated
*/
-ZSTDLIB_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
+ZSTDLIB_STATIC_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
size_t outSeqsSize, const void* src, size_t srcSize);
/*! ZSTD_mergeBlockDelimiters() :
@@ -1390,7 +1404,7 @@ ZSTDLIB_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
* setting of ZSTD_c_blockDelimiters as ZSTD_sf_noBlockDelimiters
* @return : number of sequences left after merging
*/
-ZSTDLIB_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize);
+ZSTDLIB_STATIC_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize);
/*! ZSTD_compressSequences() :
* Compress an array of ZSTD_Sequence, generated from the original source buffer, into dst.
@@ -1420,7 +1434,7 @@ ZSTDLIB_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t se
* and cannot emit an RLE block that disagrees with the repcode history
* @return : final compressed size or a ZSTD error.
*/
-ZSTDLIB_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstSize,
+ZSTDLIB_STATIC_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstSize,
const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
const void* src, size_t srcSize);
@@ -1438,9 +1452,29 @@ ZSTDLIB_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size
*
* @return : number of bytes written or a ZSTD error.
*/
-ZSTDLIB_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
+ZSTDLIB_STATIC_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
const void* src, size_t srcSize, unsigned magicVariant);
+/*! ZSTD_readSkippableFrame() :
+ * Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer.
+ *
+ * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
+ * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
+ * in the magicVariant.
+ *
+ * Returns an error if destination buffer is not large enough, or if the frame is not skippable.
+ *
+ * @return : number of bytes written or a ZSTD error.
+ */
+ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant,
+ const void* src, size_t srcSize);
+
+/*! ZSTD_isSkippableFrame() :
+ * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame.
+ */
+ZSTDLIB_API unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size);
+
+
/***************************************
* Memory management
@@ -1469,10 +1503,10 @@ ZSTDLIB_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
* Note 2 : only single-threaded compression is supported.
* ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1.
*/
-ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
-ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams);
-ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params);
-ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateDCtxSize(void);
/*! ZSTD_estimateCStreamSize() :
* ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one.
@@ -1487,20 +1521,20 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
* Note : if streaming is init with function ZSTD_init?Stream_usingDict(),
* an internal ?Dict will be created, which additional size is not estimated here.
* In this case, get total size by adding ZSTD_estimate?DictSize */
-ZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel);
-ZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams);
-ZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params);
-ZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize);
-ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize(int compressionLevel);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize(size_t windowSize);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
/*! ZSTD_estimate?DictSize() :
* ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
* ZSTD_estimateCDictSize_advanced() makes it possible to control compression parameters precisely, like ZSTD_createCDict_advanced().
* Note : dictionaries created by reference (`ZSTD_dlm_byRef`) are logically smaller.
*/
-ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
-ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod);
-ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod);
/*! ZSTD_initStatic*() :
* Initialize an object using a pre-allocated fixed-size buffer.
@@ -1523,20 +1557,20 @@ ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e
* Limitation 2 : static cctx currently not compatible with multi-threading.
* Limitation 3 : static dctx is incompatible with legacy support.
*/
-ZSTDLIB_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize);
-ZSTDLIB_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticCCtx() */
+ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize);
+ZSTDLIB_STATIC_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticCCtx() */
-ZSTDLIB_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize);
-ZSTDLIB_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticDCtx() */
+ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize);
+ZSTDLIB_STATIC_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticDCtx() */
-ZSTDLIB_API const ZSTD_CDict* ZSTD_initStaticCDict(
+ZSTDLIB_STATIC_API const ZSTD_CDict* ZSTD_initStaticCDict(
void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType,
ZSTD_compressionParameters cParams);
-ZSTDLIB_API const ZSTD_DDict* ZSTD_initStaticDDict(
+ZSTDLIB_STATIC_API const ZSTD_DDict* ZSTD_initStaticDDict(
void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
@@ -1557,44 +1591,44 @@ __attribute__((__unused__))
#endif
ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
-ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
-ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
-ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
-ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
+ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
+ZSTDLIB_STATIC_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
+ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
+ZSTDLIB_STATIC_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
-ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
+ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType,
ZSTD_compressionParameters cParams,
ZSTD_customMem customMem);
-/* ! Thread pool :
- * These prototypes make it possible to share a thread pool among multiple compression contexts.
- * This can limit resources for applications with multiple threads where each one uses
- * a threaded compression mode (via ZSTD_c_nbWorkers parameter).
- * ZSTD_createThreadPool creates a new thread pool with a given number of threads.
- * Note that the lifetime of such pool must exist while being used.
- * ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value
- * to use an internal thread pool).
- * ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer.
+/*! Thread pool :
+ * These prototypes make it possible to share a thread pool among multiple compression contexts.
+ * This can limit resources for applications with multiple threads where each one uses
+ * a threaded compression mode (via ZSTD_c_nbWorkers parameter).
+ * ZSTD_createThreadPool creates a new thread pool with a given number of threads.
+ * Note that the lifetime of such pool must exist while being used.
+ * ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value
+ * to use an internal thread pool).
+ * ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer.
*/
typedef struct POOL_ctx_s ZSTD_threadPool;
-ZSTDLIB_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads);
-ZSTDLIB_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); /* accept NULL pointer */
-ZSTDLIB_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool);
+ZSTDLIB_STATIC_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads);
+ZSTDLIB_STATIC_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); /* accept NULL pointer */
+ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool);
/*
* This API is temporary and is expected to change or disappear in the future!
*/
-ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2(
+ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced2(
const void* dict, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType,
const ZSTD_CCtx_params* cctxParams,
ZSTD_customMem customMem);
-ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(
+ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_advanced(
const void* dict, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType,
@@ -1611,22 +1645,22 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(
* As a consequence, `dictBuffer` **must** outlive CDict,
* and its content must remain unmodified throughout the lifetime of CDict.
* note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */
-ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
+ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
* `estimatedSrcSize` value is optional, select 0 if not known */
-ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
/*! ZSTD_getParams() :
* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`.
* All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 */
-ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+ZSTDLIB_STATIC_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
/*! ZSTD_checkCParams() :
* Ensure param values remain within authorized range.
* @return 0 on success, or an error code (can be checked with ZSTD_isError()) */
-ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
+ZSTDLIB_STATIC_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
/*! ZSTD_adjustCParams() :
* optimize params for a given `srcSize` and `dictSize`.
@@ -1634,7 +1668,7 @@ ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
* `dictSize` must be `0` when there is no dictionary.
* cPar can be invalid : all parameters will be clamped within valid range in the @return struct.
* This function never fails (wide contract) */
-ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
+ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
/*! ZSTD_compress_advanced() :
* Note : this function is now DEPRECATED.
@@ -1662,18 +1696,18 @@ size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
/*! ZSTD_CCtx_loadDictionary_byReference() :
* Same as ZSTD_CCtx_loadDictionary(), but dictionary content is referenced, instead of being copied into CCtx.
* It saves some memory, but also requires that `dict` outlives its usage within `cctx` */
-ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
+ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
/*! ZSTD_CCtx_loadDictionary_advanced() :
* Same as ZSTD_CCtx_loadDictionary(), but gives finer control over
* how to load the dictionary (by copy ? by reference ?)
* and how to interpret it (automatic ? force raw mode ? full mode only ?) */
-ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);
+ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);
/*! ZSTD_CCtx_refPrefix_advanced() :
* Same as ZSTD_CCtx_refPrefix(), but gives finer control over
* how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */
-ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);
+ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);
/* === experimental parameters === */
/* these parameters can be used with ZSTD_setParameter()
@@ -1712,9 +1746,15 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
* See the comments on that enum for an explanation of the feature. */
#define ZSTD_c_forceAttachDict ZSTD_c_experimentalParam4
-/* Controls how the literals are compressed (default is auto).
- * The value must be of type ZSTD_literalCompressionMode_e.
- * See ZSTD_literalCompressionMode_e enum definition for details.
+/* Controlled with ZSTD_paramSwitch_e enum.
+ * Default is ZSTD_ps_auto.
+ * Set to ZSTD_ps_disable to never compress literals.
+ * Set to ZSTD_ps_enable to always compress literals. (Note: uncompressed literals
+ * may still be emitted if huffman is not beneficial to use.)
+ *
+ * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use
+ * literals compression based on the compression parameters - specifically,
+ * negative compression levels do not use literal compression.
*/
#define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5
@@ -1777,7 +1817,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
*
* Note that this means that the CDict tables can no longer be copied into the
* CCtx, so the dict attachment mode ZSTD_dictForceCopy will no longer be
- * useable. The dictionary can only be attached or reloaded.
+ * usable. The dictionary can only be attached or reloaded.
*
* In general, you should expect compression to be faster--sometimes very much
* so--and CDict creation to be slightly slower. Eventually, we will probably
@@ -1866,23 +1906,26 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
*/
#define ZSTD_c_validateSequences ZSTD_c_experimentalParam12
-/* ZSTD_c_splitBlocks
- * Default is 0 == disabled. Set to 1 to enable block splitting.
+/* ZSTD_c_useBlockSplitter
+ * Controlled with ZSTD_paramSwitch_e enum.
+ * Default is ZSTD_ps_auto.
+ * Set to ZSTD_ps_disable to never use block splitter.
+ * Set to ZSTD_ps_enable to always use block splitter.
*
- * Will attempt to split blocks in order to improve compression ratio at the cost of speed.
+ * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use
+ * block splitting based on the compression parameters.
*/
-#define ZSTD_c_splitBlocks ZSTD_c_experimentalParam13
+#define ZSTD_c_useBlockSplitter ZSTD_c_experimentalParam13
/* ZSTD_c_useRowMatchFinder
- * Default is ZSTD_urm_auto.
- * Controlled with ZSTD_useRowMatchFinderMode_e enum.
+ * Controlled with ZSTD_paramSwitch_e enum.
+ * Default is ZSTD_ps_auto.
+ * Set to ZSTD_ps_disable to never use row-based matchfinder.
+ * Set to ZSTD_ps_enable to force usage of row-based matchfinder.
*
- * By default, in ZSTD_urm_auto, when finalizing the compression parameters, the library
- * will decide at runtime whether to use the row-based matchfinder based on support for SIMD
- * instructions as well as the windowLog.
- *
- * Set to ZSTD_urm_disableRowMatchFinder to never use row-based matchfinder.
- * Set to ZSTD_urm_enableRowMatchFinder to force usage of row-based matchfinder.
+ * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use
+ * the row-based matchfinder based on support for SIMD instructions and the window log.
+ * Note that this only pertains to compression strategies: greedy, lazy, and lazy2
*/
#define ZSTD_c_useRowMatchFinder ZSTD_c_experimentalParam14
@@ -1911,7 +1954,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
* and store it into int* value.
* @return : 0, or an error code (which can be tested with ZSTD_isError()).
*/
-ZSTDLIB_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);
+ZSTDLIB_STATIC_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);
/*! ZSTD_CCtx_params :
@@ -1931,25 +1974,25 @@ ZSTDLIB_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter
* This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams()
* for static allocation of CCtx for single-threaded compression.
*/
-ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
-ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); /* accept NULL pointer */
+ZSTDLIB_STATIC_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
+ZSTDLIB_STATIC_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); /* accept NULL pointer */
/*! ZSTD_CCtxParams_reset() :
* Reset params to default values.
*/
-ZSTDLIB_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params);
+ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params);
/*! ZSTD_CCtxParams_init() :
* Initializes the compression parameters of cctxParams according to
* compression level. All other parameters are reset to their default values.
*/
-ZSTDLIB_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel);
+ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel);
/*! ZSTD_CCtxParams_init_advanced() :
* Initializes the compression and frame parameters of cctxParams according to
* params. All other parameters are reset to their default values.
*/
-ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
+ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
/*! ZSTD_CCtxParams_setParameter() : Requires v1.4.0+
* Similar to ZSTD_CCtx_setParameter.
@@ -1959,14 +2002,14 @@ ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, Z
* @result : a code representing success or failure (which can be tested with
* ZSTD_isError()).
*/
-ZSTDLIB_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value);
+ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value);
/*! ZSTD_CCtxParams_getParameter() :
* Similar to ZSTD_CCtx_getParameter.
* Get the requested value of one compression parameter, selected by enum ZSTD_cParameter.
* @result : 0, or an error code (which can be tested with ZSTD_isError()).
*/
-ZSTDLIB_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value);
+ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value);
/*! ZSTD_CCtx_setParametersUsingCCtxParams() :
* Apply a set of ZSTD_CCtx_params to the compression context.
@@ -1975,7 +2018,7 @@ ZSTDLIB_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params,
* if nbWorkers>=1, new parameters will be picked up at next job,
* with a few restrictions (windowLog, pledgedSrcSize, nbWorkers, jobSize, and overlapLog are not updated).
*/
-ZSTDLIB_API size_t ZSTD_CCtx_setParametersUsingCCtxParams(
+ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParametersUsingCCtxParams(
ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
/*! ZSTD_compressStream2_simpleArgs() :
@@ -1984,7 +2027,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_setParametersUsingCCtxParams(
* This variant might be helpful for binders from dynamic languages
* which have troubles handling structures containing memory pointers.
*/
-ZSTDLIB_API size_t ZSTD_compressStream2_simpleArgs (
+ZSTDLIB_STATIC_API size_t ZSTD_compressStream2_simpleArgs (
ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, size_t* dstPos,
const void* src, size_t srcSize, size_t* srcPos,
@@ -2000,33 +2043,33 @@ ZSTDLIB_API size_t ZSTD_compressStream2_simpleArgs (
* Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
* Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
* Note 3 : Skippable Frame Identifiers are considered valid. */
-ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size);
+ZSTDLIB_STATIC_API unsigned ZSTD_isFrame(const void* buffer, size_t size);
/*! ZSTD_createDDict_byReference() :
* Create a digested dictionary, ready to start decompression operation without startup delay.
* Dictionary content is referenced, and therefore stays in dictBuffer.
* It is important that dictBuffer outlives DDict,
* it must remain read accessible throughout the lifetime of DDict */
-ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
+ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
/*! ZSTD_DCtx_loadDictionary_byReference() :
* Same as ZSTD_DCtx_loadDictionary(),
* but references `dict` content instead of copying it into `dctx`.
* This saves memory if `dict` remains around.,
* However, it's imperative that `dict` remains accessible (and unmodified) while being used, so it must outlive decompression. */
-ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
+ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
/*! ZSTD_DCtx_loadDictionary_advanced() :
* Same as ZSTD_DCtx_loadDictionary(),
* but gives direct control over
* how to load the dictionary (by copy ? by reference ?)
* and how to interpret it (automatic ? force raw mode ? full mode only ?). */
-ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);
+ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);
/*! ZSTD_DCtx_refPrefix_advanced() :
* Same as ZSTD_DCtx_refPrefix(), but gives finer control over
* how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */
-ZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);
+ZSTDLIB_STATIC_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);
/*! ZSTD_DCtx_setMaxWindowSize() :
* Refuses allocating internal buffers for frames requiring a window size larger than provided limit.
@@ -2035,14 +2078,14 @@ ZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* pre
* By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT)
* @return : 0, or an error code (which can be tested using ZSTD_isError()).
*/
-ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize);
+ZSTDLIB_STATIC_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize);
/*! ZSTD_DCtx_getParameter() :
* Get the requested decompression parameter value, selected by enum ZSTD_dParameter,
* and store it into int* value.
* @return : 0, or an error code (which can be tested with ZSTD_isError()).
*/
-ZSTDLIB_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value);
+ZSTDLIB_STATIC_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value);
/* ZSTD_d_format
* experimental parameter,
@@ -2131,7 +2174,7 @@ size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);
* This can be helpful for binders from dynamic languages
* which have troubles handling structures containing memory pointers.
*/
-ZSTDLIB_API size_t ZSTD_decompressStream_simpleArgs (
+ZSTDLIB_STATIC_API size_t ZSTD_decompressStream_simpleArgs (
ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity, size_t* dstPos,
const void* src, size_t srcSize, size_t* srcPos);
@@ -2205,7 +2248,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
* This function is DEPRECATED, and equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* ZSTD_CCtx_refCDict(zcs, cdict);
- *
+ *
* note : cdict will just be referenced, and must outlive compression session
* This prototype will generate compilation warnings.
*/
@@ -2270,7 +2313,7 @@ typedef struct {
* Note : (ingested - consumed) is amount of input data buffered internally, not yet compressed.
* Aggregates progression inside active worker threads.
*/
-ZSTDLIB_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx);
+ZSTDLIB_STATIC_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx);
/*! ZSTD_toFlushNow() :
* Tell how many bytes are ready to be flushed immediately.
@@ -2285,7 +2328,7 @@ ZSTDLIB_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx
* therefore flush speed is limited by production speed of oldest job
* irrespective of the speed of concurrent (and newer) jobs.
*/
-ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx);
+ZSTDLIB_STATIC_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx);
/*===== Advanced Streaming decompression functions =====*/
@@ -2299,7 +2342,7 @@ ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx);
* note: no dictionary will be used if dict == NULL or dictSize < 8
* Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
*/
-ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
+ZSTDLIB_STATIC_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
/*!
* This function is deprecated, and is equivalent to:
@@ -2310,7 +2353,7 @@ ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dic
* note : ddict is referenced, it must outlive decompression session
* Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
*/
-ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);
+ZSTDLIB_STATIC_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);
/*!
* This function is deprecated, and is equivalent to:
@@ -2320,7 +2363,7 @@ ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDi
* re-use decompression parameters from previous init; saves dictionary loading
* Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
*/
-ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
+ZSTDLIB_STATIC_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
/*********************************************************************
@@ -2362,13 +2405,13 @@ ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
*/
/*===== Buffer-less streaming compression functions =====*/
-ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
-ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
-ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */
-ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */
+ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
+ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
+ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */
+ZSTDLIB_STATIC_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */
-ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_STATIC_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_STATIC_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
/* The ZSTD_compressBegin_advanced() and ZSTD_compressBegin_usingCDict_advanced() are now DEPRECATED and will generate a compiler warning */
ZSTD_DEPRECATED("use advanced API to access custom parameters")
@@ -2465,24 +2508,24 @@ typedef struct {
* @return : 0, `zfhPtr` is correctly filled,
* >0, `srcSize` is too small, value is wanted `srcSize` amount,
* or an error code, which can be tested using ZSTD_isError() */
-ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); /**< doesn't consume input */
+ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); /**< doesn't consume input */
/*! ZSTD_getFrameHeader_advanced() :
* same as ZSTD_getFrameHeader(),
* with added capability to select a format (like ZSTD_f_zstd1_magicless) */
-ZSTDLIB_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format);
-ZSTDLIB_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */
+ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format);
+ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */
-ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
-ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
-ZSTDLIB_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
+ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
+ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
+ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
-ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
-ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_STATIC_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
+ZSTDLIB_STATIC_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
/* misc */
-ZSTDLIB_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
+ZSTDLIB_STATIC_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
-ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
+ZSTDLIB_STATIC_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
@@ -2519,10 +2562,10 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
*/
/*===== Raw zstd block functions =====*/
-ZSTDLIB_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx);
-ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-ZSTDLIB_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */
+ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx);
+ZSTDLIB_STATIC_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_STATIC_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */
#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */